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

Contents of /trunk/src/OEPassphraseCBDlg.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (show annotations)
Thu Apr 13 07:41:30 2006 UTC (19 years ago) by twoaday
File MIME type: text/plain
File size: 7086 byte(s)
Prepare 0.8.1 release.


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 SetDlgItemText (dlg, IDC_DECRYPT_HIDE, _("&Hide typing"));
159 SetWindowText (dlg, _("Decryption"));
160 SetForegroundWindow (dlg);
161 center_window (dlg, ctx->main_wnd);
162 break;
163
164 case WM_COMMAND:
165 if (HIWORD (wparam) == BN_CLICKED &&
166 LOWORD (wparam) == IDC_DECRYPT_HIDE) {
167 HWND hwnd;
168 hwnd = GetDlgItem (dlg, IDC_DECRYPT_PWD);
169 SendMessage (hwnd, EM_SETPASSWORDCHAR,
170 IsDlgButtonChecked (dlg, IDC_DECRYPT_HIDE)? '*' : 0, 0);
171 SetFocus (hwnd);
172 break;
173 }
174
175 switch (LOWORD (wparam)) {
176 case IDCANCEL:
177 ctx->cancel = 1;
178 free_if_alloc (ctx->pass);
179 EndDialog (dlg, FALSE);
180 break;
181
182 case IDOK:
183 if (ctx->prev_was_bad)
184 SetDlgItemText (dlg, IDC_DECRYPT_PWDINFO,
185 _("Invalid passphrase; please enter your passphrase again"));
186 else
187 SetDlgItemText (dlg, IDC_DECRYPT_PWDINFO,
188 _("Please enter your passphrase"));
189 n = SendDlgItemMessage (dlg, IDC_DECRYPT_PWD,
190 WM_GETTEXTLENGTH, 0, 0);
191 if (n < 1) {
192 MessageBox (dlg, _("Please enter your passphrase"),
193 _("GPG Plug-in Info"), MB_ICONINFORMATION|MB_OK);
194 return FALSE;
195 }
196 ctx->cancel = 0;
197 ctx->pass = xcalloc (1, n+2);
198 GetDlgItemText (dlg, IDC_DECRYPT_PWD, ctx->pass, n+1);
199
200 /*passphrase_put (&the_cache, ctx->keyid, ctx->pass);*/
201 EndDialog (dlg, TRUE);
202 break;
203 }
204 break;
205 }
206 return FALSE;
207 }
208
209
210 /* GPGME compatible passphrase callback. */
211 gpgme_error_t
212 passphrase_cb (void *hook,
213 const char *uid_hint,
214 const char *passphrase_info,
215 int prev_was_bad, int fd)
216 {
217 pass_cb_t cb = (pass_cb_t)hook;
218 HANDLE fp = (HANDLE)fd;
219 const char *pass;
220 DWORD nwritten = 0;
221
222 cb->prev_was_bad = prev_was_bad;
223 if (prev_was_bad && !cb->cancel) {
224 wipememory (cb->pass, strlen (cb->pass));
225 free_if_alloc (cb->pass);
226 }
227 if (!cb->pass && !cb->cancel) {
228 cb->uid_hint = uid_hint;
229 cb->passphrase_info = passphrase_info;
230 memset (cb->keyid, 0, sizeof (cb->keyid));
231 memcpy (cb->keyid, cb->passphrase_info+8, 8);
232
233 if (the_cache && (pass=passphrase_get (the_cache, cb->keyid)))
234 cb->pass = xstrdup (pass);
235 else
236 DialogBoxParam (mod_hinst_dll, (LPCTSTR)IDD_DECRYPT,
237 cb->main_wnd, pass_cb_dlg_proc, (LPARAM)cb);
238 }
239 if (cb->cancel)
240 WriteFile (fp, "\n", 1, &nwritten, NULL);
241 else if (cb->pass != NULL) {
242 WriteFile (fp, cb->pass, strlen (cb->pass), &nwritten, NULL);
243 WriteFile (fp, "\n", 1, &nwritten, NULL);
244 }
245 return 0;
246 }
247
248
249 /* Allocate new passphrase callback context. */
250 pass_cb_t
251 new_pass_cb (HWND main)
252 {
253 pass_cb_t cb_val;
254
255 cb_val = xcalloc (1, sizeof *cb_val);
256 cb_val->main_wnd = main;
257 return cb_val;
258 }
259
260
261
262 /* Free passphrase callback context. */
263 void
264 free_pass_cb (pass_cb_t cb)
265 {
266 if (!cb)
267 return;
268 if (cb->pass) {
269 wipememory (cb->pass, strlen (cb->pass));
270 free_if_alloc (cb->pass);
271 }
272 free_if_alloc (cb);
273 }
274
275
276 int
277 pass_cb_cancelled (pass_cb_t cb)
278 {
279 return cb->cancel;
280 }
281
282
283 /* Release the passphrase cache. */
284 void
285 free_pass_cache (void)
286 {
287 invalidate_cache (the_cache);
288 the_cache = NULL;
289 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26