添付ファイルSAMPLE2.zipはWindows環境でgpgファイルをdrag and drop で復号する簡単なプログラムが入っています。 これにはセッションキーを使った復号にも対応するコードが含まれています。 Drop-GPG.exeと同じディレクトリにSessionkeys.dbを入れてDrop-GPG.exeを ダブルクリックして起動してください。 2つウィンドウが生成されて小さい方にgpgファイルをドロップしてください。 自分の公開鍵で暗号化させていればパスフレーズをつかって復号できるはずです。 そうでなければdbを検索してセッションキーで復号します。 公開鍵が登録されているのなら、Sessionkeys.dbは必要ありません。 gpgファイルと同じディレクトリに復号したファイルが生成されます。 コンパイルするにはCygwin環境では gcc-3で-mno-cygwinするか、 gcc-4でクロスコンパイルでターゲットをMingW32にしてください。 どちらもMingW32環境のsqlite3のライブラリが必要です。 ソースファイルは以下の通りです。 #include <stdio.h> #include <string.h> #include <sqlite3.h> #include <windows.h> /* gcc-3 -O4 -Wall -mno-cygwin -mwindows -mconsole -o Drop-GPG Drop-GPG.c /usr/i686-pc-mingw32/sys-root/mingw/lib/libsqlite3.a */ #undef _MY_SARAMI (1) TCHAR fnameWithPath[MAX_PATH] ; const char *dbname="Sessionkeys.db"; char sessionkey[128]; char *db_search(char *file) { char *SQL=NULL, *errmsg=NULL, **result=NULL, *RET=sessionkey; int rc = -1, rows=-1, cols=-1; ; sqlite3 *db = NULL; rc = sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READONLY, 0); if ( SQLITE_OK == rc ) { } else { printf("DBがひらけません。%s\n", dbname); puts("何かキーを押して終了してください。"); getch(); exit(1); } SQL=sqlite3_mprintf("select * from sKey where filename = %Q;", file); rc = sqlite3_get_table(db, SQL, &result, &rows, &cols, &errmsg ); if ( SQLITE_OK != rc || NULL != errmsg ) { fprintf( stderr, "%s(%d)\n", errmsg, sqlite3_errcode( db ) ); goto err; } if ( (NULL != result) && ( rows == 1) ) { strcpy(RET, result[rows*cols+1]); } else { RET=NULL; } err: sqlite3_free(SQL); sqlite3_free(errmsg); sqlite3_free_table(result); rc = sqlite3_close( db ); if ( SQLITE_OK != rc ) { fprintf(stderr, "%s(%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); RET= NULL; } return RET; } void processing( char *fileNameWithPath ) { char tmp[2048]; char *ret; #ifdef _MY_SARAMI char file[2048]; strcpy(file, fileNameWithPath); *strrchr(file, '.')='\x00'; sprintf(tmp,"gpg -o \"X:/0tmp/%s\" \"%s\"", /* strrchr(fileNameWithPath,'\\')+1, strchr(file,'/')+1);*/ strrchr(file,'\\')+1, fileNameWithPath); puts(tmp); #else sprintf(tmp,"gpg \"%s\"", fileNameWithPath); #endif if (system(tmp) >1 ) { printf("ファイルがGPGファイルでないか、\n" "公開鍵が登録されていない時点で暗号化されています。\n"); if ((ret= db_search(strrchr(fileNameWithPath, '\\')+1)) !=NULL) { printf("DBにセッションキーがありました。\n" "セッションキーで復号します。\n"); #ifdef _MY_SARAMI sprintf(tmp, "gpg -o \"X:/0tmp/%s\" " "--override-session-key \"%s\" \"%s\"", strrchr(file,'\\')+1, ret, fileNameWithPath); #else puts(ret); sprintf(tmp, "gpg --override-session-key \"%s\" \"%s\"", ret,fileNameWithPath); #endif system(tmp); } else { puts("DBにセッションキーがありません。\n" "何かキーを押して終了してください。"); getch(); } } printf("\n** 処理おわり **\n"); } //////////////////////////////////////////////////////////////////////////////// // ウィンドウプログラム部 // HWND は、対象ウィンドウを特定するハンドル (Window ID) LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch( message ) { case WM_CREATE: DragAcceptFiles(hWnd, TRUE); // Drag & Drop操作を有効 (enable WM_DROPFILES) break; case WM_DROPFILES: SetForegroundWindow(hWnd); // 他のスレッドよりも若干高い優先順位を割り当て {register int i, max; for( i=0, max=DragQueryFile( (HDROP)wParam, -1, NULL, 0 ); i<max; i++ ) { DragQueryFile( (HDROP)wParam, i, fnameWithPath, sizeof(fnameWithPath) ) ; processing( fnameWithPath ) ; } } DragFinish((HDROP)wParam); break; /* major events case WM_LBUTTONDOWN: break; case WM_RBUTTONDOWN: break; case WM_MOUSEMOVE: break; case WM_KEYDOWN: // MessageBox(hWnd, "WM_KEYDOWN", "キーイベントの発生", MB_OK); break; case WM_SIZE: // ウィンドウサイズ調整 break; // Send(If it's necessary) PostMessage(hWnd,WM_PAINT,0,0) or No break; case WM_PAINT: // (再)描画処理 {PAINTSTRUCT ps ; hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); } break; */ case WM_CLOSE: // 必要な確認処理後、DestroyWindow関数を呼び出す DestroyWindow( hWnd ) ; break; case WM_DESTROY: // ウィンドウを破棄した後に送られるメッセージ PostQuitMessage( 0 ) ; break; default: return DefWindowProc( hWnd, message, wParam, lParam ) ; } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd ; WNDCLASSEX wc ; MSG message ; int returnedValue ; // BOOL が本来の正しい型 const char *ClassName = "Canvas", *title = "drag and drop" ; // ウィンドウクラスの情報を設定 wc.cbSize = sizeof(WNDCLASSEX) ; // 構造体のサイズ wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // スタイルの設定 wc.lpfnWndProc = WindowProcedure; // ウィンドウプロシージャ wc.cbClsExtra = 0; // 構造体が使用する extra メモリサイズ wc.cbWndExtra = 0; // ウィンドウが使用する extra メモリサイズ wc.hInstance = hInstance; // インスタンスハンドル wc.hIcon = LoadIcon(hInstance, "PRGICON") ; // アイコン wc.hCursor = LoadCursor(NULL, IDC_ARROW) ; // マウスカーソル wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH) ; // ウィンドウ背景 wc.lpszMenuName = NULL, // メニュー名 wc.lpszClassName = TEXT(ClassName) ; // ウィンドウクラス名 wc.hIconSm = LoadIcon(hInstance, "PRGICON") ; // 子アイコン if( RegisterClassEx( &wc ) == 0 ) return 1; // ウィンドウクラスの登録 if( (hWnd = CreateWindow( // ウィンドウの生成 wc.lpszClassName, // ウィンドウクラス名 TEXT(title), // タイトルバーに表示する文字列 WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, // ウィンドウの種類 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, // ウィンドウを表示する位置(X座標) CW_USEDEFAULT, CW_USEDEFAULT, // ウィンドウを表示する位置(Y座標) CW_USEDEFAULT, 256, // ウィンドウの幅 DEFAULT ⇒ MAIN_LX_SIZE, 128, // ウィンドウの高さ DEFAULT ⇒ MAIN_LY_SIZE, NULL, // 親ウィンドウのウィンドウハンドル NULL, // メニューハンドル hInstance, // インスタンスハンドル NULL // その他の作成データ ) ) == NULL ) return 1; ShowWindow( hWnd, SW_SHOW ) ; // ウィンドウを表示 UpdateWindow( hWnd ) ; // ウィンドウの更新 // メニューの有効無効設定は、WindowProcedure の WM_CREATE で行うので、 // 現時点において、hWnd でのアクセスは失敗する。 while( (returnedValue = GetMessage(&message, NULL, 0, 0)) != 0 ) { // メインループ if( returnedValue == -1 ) return -1; // GetMessage() が失敗(-1)なら終了する TranslateMessage( &message ) ; DispatchMessage( &message ) ; } return 0; } |