/[gpgoe]/trunk/src/OEPassphraseCBDlg.c
ViewVC logotype

Contents of /trunk/src/OEPassphraseCBDlg.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (show annotations)
Tue Apr 11 06:56:23 2006 UTC (19 years ago) by twoaday
File MIME type: text/plain
File size: 6960 byte(s)


1 /* OEPassphraseDLG.cpp - GPGME Passphrase Callback
2 * Copyright (C) 2001, 2002, 2006 Timo Schulz
3 *
4 * This file is part of GPGOE.
5 *
6 * GPGOE is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * GPGOE is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with GPGOE; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA7 USA
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <windows.h>
25 #include <assert.h>
26 #include "resource.h"
27 #include "gpgme.h"
28 #include "GPGOE.h"
29
30
31 /* Structure for the passphrase cache. */
32 struct pass_cache_s {
33 struct pass_cache_s *next;
34 char *keyid;
35 char *pass;
36 };
37 typedef struct pass_cache_s *pass_cache_t;
38
39 /* Structure for the passphrase callback. */
40 struct pass_cb_s {
41 const char *uid_hint;
42 const char *passphrase_info;
43 char keyid[8+2];
44 char *pass;
45 pass_cache_t cache;
46 HWND main_wnd;
47 int cancel;
48 int prev_was_bad;
49 };
50
51
52 /* Global passphrase cache. */
53 static pass_cache_t the_cache = NULL;
54
55
56 /* Release the passphrase cache @ctx and invalidate all passphrases. */
57 static void
58 invalidate_cache (pass_cache_t ctx)
59 {
60 pass_cache_t c;
61
62 while (ctx) {
63 c = ctx->next;
64 free_if_alloc (ctx->keyid);
65 wipememory (ctx->pass, strlen (ctx->pass));
66 free_if_alloc (ctx->pass);
67 ctx = c;
68 }
69 }
70
71 /* Put the passphrase @pass into the passphrase cache @ctx. */
72 static void
73 passphrase_put (pass_cache_t *ctx, const char *keyid, const char *pass)
74 {
75 pass_cache_t c, n;
76
77 /* check if the item is already present. */
78 for (n = *ctx; n; n = n->next) {
79 if (!strcmp (n->keyid, keyid))
80 return;
81 }
82
83 c = xcalloc (1, sizeof *c);
84 c->keyid = xstrdup (keyid);
85 c->pass = xstrdup (pass);
86
87 if (!*ctx)
88 *ctx = c;
89 else {
90 for (n = *ctx; n->next; n = n->next)
91 ;
92 n->next = c;
93 }
94 }
95
96
97 /* Return the passphrase for the key with the keyid @keyid
98 or NULL if the passphrase was not cached for this key. */
99 static const char*
100 passphrase_get (pass_cache_t ctx, const char *keyid)
101 {
102 pass_cache_t c;
103
104 for (c = ctx; c; c = c->next) {
105 if (!strcmp (c->keyid, keyid))
106 return c->pass;
107 }
108 return NULL;
109 }
110
111
112
113
114 /* Extract public key algorithm from passwd info. */
115 const char*
116 get_pubkey_algo (const char *passphrase_info)
117 {
118 size_t pos = 16+1+16+1;
119
120 /* AA6F7AB7DD3B4A21 E71D9BC8C93A8529 1 0 */
121 assert (strlen (passphrase_info) > pos);
122 switch (atol (passphrase_info+pos)) {
123 case 1: return "RSA";
124 case 17: return "DSA";
125 case 16: return "ELG";
126 }
127 return "???";
128 }
129
130
131 /* Passphrase callback dialog box procedure. */
132 BOOL CALLBACK
133 pass_cb_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
134 {
135 static pass_cb_t ctx;
136 char *info;
137 int n;
138
139 switch (msg) {
140 case WM_INITDIALOG:
141 ctx = (pass_cb_t)lparam;
142 assert (ctx);
143 if (ctx->uid_hint && ctx->passphrase_info) {
144 char *utf8_uid = utf8_to_native (ctx->uid_hint+17);
145 info = xcalloc (1, strlen (utf8_uid) + strlen (ctx->keyid) + 32);
146 sprintf (info, _("%s\n%s key, ID %s"), utf8_uid,
147 get_pubkey_algo (ctx->passphrase_info), ctx->keyid);
148 SetDlgItemText (dlg, IDC_DECRYPT_MSG, info);
149 free_if_alloc (utf8_uid);
150 free_if_alloc (info);
151 }
152 SetDlgItemText (dlg, IDOK, _("&OK"));
153 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
154 SetDlgItemText (dlg, IDC_DECRYPT_PWDINFO, _("Please enter your passphrase"));
155 SendDlgItemMessage (dlg, IDC_DECRYPT_PWD, EM_SETPASSWORDCHAR,
156 (WPARAM)(UINT)'*', 0);
157 CheckDlgButton (dlg, IDC_DECRYPT_HIDE, BST_CHECKED);
158 SetWindowText (dlg, _("Decryption"));
159 SetForegroundWindow (dlg);
160 center_window (dlg, ctx->main_wnd);
161 break;
162
163 case WM_COMMAND:
164 if (HIWORD (wparam) == BN_CLICKED &&
165 LOWORD (wparam) == IDC_DECRYPT_HIDE) {
166 HWND hwnd;
167 hwnd = GetDlgItem (dlg, IDC_DECRYPT_PWD);
168 SendMessage (hwnd, EM_SETPASSWORDCHAR,
169 IsDlgButtonChecked (dlg, IDC_DECRYPT_HIDE)? '*' : 0, 0);
170 SetFocus (hwnd);
171 break;
172 }
173
174 switch (LOWORD (wparam)) {
175 case IDCANCEL:
176 ctx->cancel = 1;
177 free_if_alloc (ctx->pass);
178 EndDialog (dlg, FALSE);
179 break;
180
181 case IDOK:
182 if (ctx->prev_was_bad)
183 SetDlgItemText (dlg, IDC_DECRYPT_PWDINFO,
184 _("Invalid passphrase; please enter your passphrase again"));
185 else
186 SetDlgItemText (dlg, IDC_DECRYPT_PWDINFO,
187 _("Please enter your passphrase"));
188 n = SendDlgItemMessage (dlg, IDC_DECRYPT_PWD,
189 WM_GETTEXTLENGTH, 0, 0);
190 if (n < 1) {
191 MessageBox (dlg, _("Please enter your passphrase"),
192 _("GPG Plug-in Info"), MB_ICONINFORMATION|MB_OK);
193 return FALSE;
194 }
195 ctx->cancel = 0;
196 ctx->pass = xcalloc (1, n+2);
197 GetDlgItemText (dlg, IDC_DECRYPT_PWD, ctx->pass, n+1);
198
199 /*passphrase_put (&the_cache, ctx->keyid, ctx->pass);*/
200 EndDialog (dlg, TRUE);
201 break;
202 }
203 break;
204 }
205 return FALSE;
206 }
207
208
209 /* GPGME compatible passphrase callback. */
210 gpgme_error_t
211 passphrase_cb (void *hook,
212 const char *uid_hint,
213 const char *passphrase_info,
214 int prev_was_bad, int fd)
215 {
216 pass_cb_t cb = (pass_cb_t)hook;
217 HANDLE fp = (HANDLE)fd;
218 const char *pass;
219 DWORD nwritten = 0;
220
221 cb->prev_was_bad = prev_was_bad;
222 if (prev_was_bad && !cb->cancel) {
223 wipememory (cb->pass, strlen (cb->pass));
224 free_if_alloc (cb->pass);
225 }
226 if (!cb->pass && !cb->cancel) {
227 cb->uid_hint = uid_hint;
228 cb->passphrase_info = passphrase_info;
229 memset (cb->keyid, 0, sizeof (cb->keyid));
230 memcpy (cb->keyid, cb->passphrase_info+8, 8);
231
232 if (the_cache && (pass=passphrase_get (the_cache, cb->keyid)))
233 cb->pass = xstrdup (pass);
234 else
235 DialogBoxParam (mod_hinst_dll, (LPCTSTR)IDD_DECRYPT,
236 cb->main_wnd, pass_cb_dlg_proc, (LPARAM)cb);
237 }
238 if (cb->cancel)
239 WriteFile (fp, "\n", 1, &nwritten, NULL);
240 else if (cb->pass != NULL) {
241 WriteFile (fp, cb->pass, strlen (cb->pass), &nwritten, NULL);
242 WriteFile (fp, "\n", 1, &nwritten, NULL);
243 }
244 return 0;
245 }
246
247
248 /* Allocate new passphrase callback context. */
249 pass_cb_t
250 new_pass_cb (HWND main)
251 {
252 pass_cb_t cb_val;
253
254 cb_val = xcalloc (1, sizeof *cb_val);
255 cb_val->main_wnd = main;
256 return cb_val;
257 }
258
259
260
261 /* Free passphrase callback context. */
262 void
263 free_pass_cb (pass_cb_t cb)
264 {
265 if (!cb)
266 return;
267 if (cb->pass) {
268 wipememory (cb->pass, strlen (cb->pass));
269 free_if_alloc (cb->pass);
270 }
271 free_if_alloc (cb);
272 }
273
274
275 /* Release the passphrase cache. */
276 void
277 free_pass_cache (void)
278 {
279 invalidate_cache (the_cache);
280 the_cache = NULL;
281 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26