39 |
|
|
40 |
static int gpgme_init(void); |
static int gpgme_init(void); |
41 |
static char *gpg_sign(char *); |
static char *gpg_sign(char *); |
42 |
static char *gpg_encrypt_to_users(char *); |
static char *gpg_encrypt(char *); |
43 |
|
static char *gpg_sign_encrypt(char *); |
44 |
static void gpgme_debug_info(GpgmeCtx); |
static void gpgme_debug_info(GpgmeCtx); |
45 |
|
|
46 |
#define EXTRA_GPG_BUF 4096 |
#define EXTRA_GPG_BUF 4096 |
59 |
puts(s); |
puts(s); |
60 |
free(s); |
free(s); |
61 |
} |
} |
|
return; |
|
62 |
} |
} |
63 |
|
|
64 |
#define GPGME_REQ_VERSION "0.3.12" /* GPGME 0.3.12 or later */ |
#define GPGME_REQ_VERSION "0.3.12" /* GPGME 0.3.12 or later */ |
98 |
GpgmeError err = 0; |
GpgmeError err = 0; |
99 |
GpgmeData in, out; |
GpgmeData in, out; |
100 |
GpgmeKey key; |
GpgmeKey key; |
|
|
|
101 |
char buf[256]; |
char buf[256]; |
102 |
char *signed_data; |
char *p, *signed_data; |
103 |
int size; |
int size; |
104 |
size_t nread; |
size_t nread; |
105 |
|
|
120 |
topt |= T_ERROR; |
topt |= T_ERROR; |
121 |
} |
} |
122 |
} |
} |
123 |
gpgme_set_passphrase_cb(ctx, (GpgmePassphraseCb)passphrase_cb, 0); |
|
124 |
|
p = getenv("GPG_AGENT_INFO"); |
125 |
|
if (!(p && strchr (p, ':'))) |
126 |
|
gpgme_set_passphrase_cb(ctx, |
127 |
|
(GpgmePassphraseCb)passphrase_cb, 0); |
128 |
gpgme_set_textmode(ctx, 1); |
gpgme_set_textmode(ctx, 1); |
129 |
gpgme_set_armor(ctx, 1); |
gpgme_set_armor(ctx, 1); |
130 |
|
|
167 |
} |
} |
168 |
|
|
169 |
static char * |
static char * |
170 |
gpg_encrypt_to_users(char *gpg_data) |
gpg_encrypt(char *gpg_data) |
171 |
{ |
{ |
172 |
GpgmeCtx ctx; |
GpgmeCtx ctx; |
173 |
GpgmeError err = 0; |
GpgmeError err = 0; |
187 |
|
|
188 |
fail_if_err(gpgme_new(&ctx)); |
fail_if_err(gpgme_new(&ctx)); |
189 |
gpgme_set_armor(ctx, 1); |
gpgme_set_armor(ctx, 1); |
190 |
|
|
191 |
fail_if_err(gpgme_data_new_from_mem(&in, gpg_data, strlen(gpg_data), 0)); |
fail_if_err(gpgme_data_new_from_mem(&in, gpg_data, strlen(gpg_data), 0)); |
192 |
fail_if_err(gpgme_data_new(&out)); |
fail_if_err(gpgme_data_new(&out)); |
193 |
fail_if_err(gpgme_recipients_new(&rset)); |
fail_if_err(gpgme_recipients_new(&rset)); |
242 |
return encrypted_data; |
return encrypted_data; |
243 |
} |
} |
244 |
|
|
245 |
|
static char * |
246 |
|
gpg_sign_encrypt(char *gpg_data) |
247 |
|
{ |
248 |
|
GpgmeCtx ctx; |
249 |
|
GpgmeError err = 0; |
250 |
|
GpgmeData in, out; |
251 |
|
GpgmeKey key; |
252 |
|
GpgmeRecipients rset; |
253 |
|
char current_key[100]; |
254 |
|
char buf[256]; |
255 |
|
char *p, *se_data; /* Signed-Encrypted Data */ |
256 |
|
int i, j = 0; |
257 |
|
int len, size; |
258 |
|
size_t nread; |
259 |
|
|
260 |
|
size = strlen(gpg_data) + EXTRA_GPG_BUF; |
261 |
|
se_data = (char *)xmalloc(size); |
262 |
|
memset(buf, 0, sizeof(buf)); |
263 |
|
memset(current_key, 0, sizeof(current_key)); |
264 |
|
|
265 |
|
fail_if_err(gpgme_new(&ctx)); |
266 |
|
|
267 |
|
if (gpg.keys) { |
268 |
|
err = gpgme_op_keylist_start(ctx, gpg.keys, 0); |
269 |
|
if (!err) { |
270 |
|
while ((err = gpgme_op_keylist_next(ctx, &key)) == 0) |
271 |
|
err = gpgme_signers_add(ctx, key); |
272 |
|
} |
273 |
|
if (err && err != GPGME_EOF) { |
274 |
|
anubis_error(HARD, _("GPGME: cannot list keys: %s"), |
275 |
|
gpgme_strerror(err)); |
276 |
|
topt |= T_ERROR; |
277 |
|
} |
278 |
|
} |
279 |
|
|
280 |
|
p = getenv("GPG_AGENT_INFO"); |
281 |
|
if (!(p && strchr (p, ':'))) |
282 |
|
gpgme_set_passphrase_cb(ctx, |
283 |
|
(GpgmePassphraseCb)passphrase_cb, 0); |
284 |
|
gpgme_set_armor(ctx, 1); |
285 |
|
|
286 |
|
fail_if_err(gpgme_data_new_from_mem(&in, gpg_data, strlen(gpg_data), 0)); |
287 |
|
fail_if_err(gpgme_data_new(&out)); |
288 |
|
fail_if_err(gpgme_recipients_new(&rset)); |
289 |
|
|
290 |
|
len = strlen(gpg.keys); |
291 |
|
for (i = 0; i <= len; i++) |
292 |
|
{ |
293 |
|
if (gpg.keys[i] == ',') { /* comma found, so add KEY-ID */ |
294 |
|
fail_if_err(gpgme_recipients_add_name_with_validity(rset, |
295 |
|
current_key, GPGME_VALIDITY_FULL)); |
296 |
|
memset(current_key, 0, sizeof(current_key)); |
297 |
|
j = 0; |
298 |
|
} |
299 |
|
else /* it is not a comma, so add char to KEY_ID string */ |
300 |
|
current_key[j++] = gpg.keys[i]; |
301 |
|
} |
302 |
|
fail_if_err(gpgme_op_encrypt_sign(ctx, rset, in, out)); |
303 |
|
fail_if_err(gpgme_data_rewind(out)); |
304 |
|
|
305 |
|
if (options.termlevel == DEBUG) |
306 |
|
gpgme_debug_info(ctx); |
307 |
|
|
308 |
|
if (topt & T_ERROR) { |
309 |
|
gpgme_recipients_release(rset); |
310 |
|
gpgme_release(ctx); |
311 |
|
free(se_data); |
312 |
|
return 0; |
313 |
|
} |
314 |
|
|
315 |
|
while (!(err = gpgme_data_read(out, buf, sizeof(buf), &nread))) |
316 |
|
{ |
317 |
|
if (size > nread) { |
318 |
|
strncat(se_data, buf, nread); |
319 |
|
size -= nread; |
320 |
|
} |
321 |
|
else { |
322 |
|
size = EXTRA_GPG_BUF; |
323 |
|
se_data = (char *)xrealloc((char *)se_data, |
324 |
|
strlen(se_data) + size); |
325 |
|
strncat(se_data, buf, nread); |
326 |
|
size -= nread; |
327 |
|
} |
328 |
|
memset(buf, 0, sizeof(buf)); |
329 |
|
} |
330 |
|
if (err != GPGME_EOF) |
331 |
|
fail_if_err(err); |
332 |
|
|
333 |
|
gpgme_recipients_release(rset); |
334 |
|
gpgme_data_release(in); |
335 |
|
gpgme_data_release(out); |
336 |
|
gpgme_release(ctx); |
337 |
|
return se_data; |
338 |
|
} |
339 |
|
|
340 |
void |
void |
341 |
gpg_proc(MESSAGE *msg, char *(*proc)(char *input)) |
gpg_proc(MESSAGE *msg, char *(*proc)(char *input)) |
361 |
#if defined(HAVE_SETENV) || defined(HAVE_PUTENV) |
#if defined(HAVE_SETENV) || defined(HAVE_PUTENV) |
362 |
setenv("HOME", homedir_s, 1); |
setenv("HOME", homedir_s, 1); |
363 |
#endif /* HAVE_SETENV or HAVE_PUTENV */ |
#endif /* HAVE_SETENV or HAVE_PUTENV */ |
|
|
|
|
return; |
|
364 |
} |
} |
365 |
|
|
366 |
void |
void |
376 |
#define KW_GPG_PASSPHRASE 1 |
#define KW_GPG_PASSPHRASE 1 |
377 |
#define KW_GPG_ENCRYPT 2 |
#define KW_GPG_ENCRYPT 2 |
378 |
#define KW_GPG_SIGN 3 |
#define KW_GPG_SIGN 3 |
379 |
#define KW_GPG_HOME 4 |
#define KW_GPG_SIGN_ENCRYPT 4 |
380 |
|
#define KW_GPG_HOME 5 |
381 |
|
|
382 |
int |
int |
383 |
gpg_parser(int method, int key, LIST *arglist, |
gpg_parser(int method, int key, LIST *arglist, |
400 |
strcat(gpg.keys, ","); |
strcat(gpg.keys, ","); |
401 |
if (gpg.inited == 0 && gpgme_init()) |
if (gpg.inited == 0 && gpgme_init()) |
402 |
break; |
break; |
403 |
gpg_proc(msg, gpg_encrypt_to_users); |
gpg_proc(msg, gpg_encrypt); |
404 |
break; |
break; |
405 |
|
|
406 |
case KW_GPG_SIGN: |
case KW_GPG_SIGN: |
413 |
gpg_proc(msg, gpg_sign); |
gpg_proc(msg, gpg_sign); |
414 |
} |
} |
415 |
break; |
break; |
416 |
|
|
417 |
|
case KW_GPG_SIGN_ENCRYPT: |
418 |
|
xfree(gpg.keys); |
419 |
|
gpg.keys = allocbuf(arg, 0); |
420 |
|
gpg.keys = xrealloc(gpg.keys, strlen(gpg.keys) + 2); |
421 |
|
strcat(gpg.keys, ","); |
422 |
|
if (gpg.inited == 0 && gpgme_init()) |
423 |
|
break; |
424 |
|
gpg_proc(msg, gpg_sign_encrypt); |
425 |
|
break; |
426 |
|
|
427 |
case KW_GPG_HOME: |
case KW_GPG_HOME: |
428 |
setenv("GNUPGHOME", arg, 1); |
setenv("GNUPGHOME", arg, 1); |
429 |
break; |
break; |
436 |
|
|
437 |
|
|
438 |
struct rc_kwdef gpg_kw[] = { |
struct rc_kwdef gpg_kw[] = { |
439 |
{ "gpg-passphrase", KW_GPG_PASSPHRASE }, |
{ "gpg-passphrase", KW_GPG_PASSPHRASE }, |
440 |
{ "gpg-encrypt", KW_GPG_ENCRYPT }, |
{ "gpg-encrypt", KW_GPG_ENCRYPT }, |
441 |
{ "gpg-sign", KW_GPG_SIGN }, |
{ "gpg-sign", KW_GPG_SIGN }, |
442 |
{ "gpg-home", KW_GPG_HOME }, |
{ "gpg-sign-encrypt", KW_GPG_SIGN_ENCRYPT }, |
443 |
|
{ "gpg-home", KW_GPG_HOME }, |
444 |
{ NULL }, |
{ NULL }, |
445 |
}; |
}; |
446 |
|
|