/[winpt]/trunk/MyGPGME/gpgme.c
ViewVC logotype

Contents of /trunk/MyGPGME/gpgme.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File MIME type: text/plain
File size: 14036 byte(s)
WinPT initial checkin.


1 /* gpgme.c - My GnuPG Made Easy
2 * Copyright (C) 2000 Werner Koch (dd9jn)
3 * Copyright (C) 2001-2004 Timo Schulz
4 *
5 * This file is part of MyGPGME.
6 *
7 * MyGPGME is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * MyGPGME is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <assert.h>
25 #include <windows.h>
26 #include <process.h>
27
28 #include "util.h"
29 #include "context.h"
30 #include "ops.h"
31
32 /**
33 * gpgme_new:
34 * @r_ctx: Returns the new context
35 *
36 * Create a new context to be used with most of the other GPGME
37 * functions. Use gpgme_release_contect() to release all resources
38 *
39 * Return value: An error code
40 **/
41 gpgme_error_t
42 gpgme_new (gpgme_ctx_t * r_ctx)
43 {
44 gpgme_ctx_t ctx;
45
46 if (!r_ctx)
47 return mk_error (Invalid_Value);
48 *r_ctx = NULL;
49 ctx = calloc (1, sizeof *ctx);
50 if (!ctx)
51 return mk_error (Out_Of_Core);
52 ctx->cipher_algo = GPGME_CIPHER_CAST5;
53 ctx->s2k.digest_algo = GPGME_MD_SHA1;
54 ctx->s2k.mode = GPGME_S2K_ITERSALTED;
55 *r_ctx = ctx;
56 return 0;
57 }
58
59 /**
60 * gpgme_release:
61 * @c: Context to be released.
62 *
63 * Release all resources associated with the given context.
64 **/
65 void
66 gpgme_release (gpgme_ctx_t ctx)
67 {
68 if (!ctx)
69 return;
70 _gpgme_gpg_release (&ctx->gpg);
71 _gpgme_release_result (ctx);
72 gpgme_key_release (ctx->tmp_key);
73 gpgme_data_release (ctx->help_data_1);
74 gpgme_data_release (ctx->notation);
75 gpgme_data_release (ctx->logging);
76 gpgme_signers_clear (ctx);
77 safe_free (ctx->signers);
78 safe_free (ctx->keygen_fpr);
79 safe_free (ctx->locusr);
80 safe_free (ctx->comment);
81 /* fixme: release the key_queue */
82 safe_free (ctx);
83 } /* gpgme_release */
84
85
86 void
87 _gpgme_release_result (gpgme_ctx_t c)
88 {
89 assert (c);
90 switch (c->result_type) {
91 case RESULT_TYPE_NONE:
92 break;
93
94 case RESULT_TYPE_EDITKEY:
95 _gpgme_release_editkey_result (c->result.editk);
96 break;
97
98 case RESULT_TYPE_ENCRYPT:
99 _gpgme_release_encrypt_result( c->result.encrypt );
100 break;
101
102 case RESULT_TYPE_VERIFY:
103 _gpgme_release_verify_result ( c->result.verify );
104 break;
105
106 case RESULT_TYPE_DECRYPT:
107 _gpgme_release_decrypt_result ( c->result.decrypt );
108 break;
109
110 case RESULT_TYPE_SIGN:
111 _gpgme_release_sign_result ( c->result.sign );
112 break;
113
114 case RESULT_TYPE_SIGN_ENCRYPT:
115 _gpgme_release_sign_encrypt_result( c->result.sign_enc );
116 break;
117
118 case RESULT_TYPE_IMPORT:
119 _gpgme_release_import_result( c->result.import );
120 break;
121
122 case RESULT_TYPE_SYMENC:
123 _gpgme_release_symenc_result( c->result.symenc );
124 break;
125 }
126
127 c->result.verify = NULL;
128 c->result_type = RESULT_TYPE_NONE;
129 } /* _gpgme_release_result */
130
131
132 /**
133 * gpgme_cancel:
134 * @c: the context
135 *
136 * Cancel the current operation. It is not guaranteed that it will work for
137 * all kinds of operations. It is especially useful in a passphrase callback
138 * to stop the system from asking another time for the passphrase.
139 **/
140 void
141 gpgme_cancel (gpgme_ctx_t c)
142 {
143 return_if_fail (c);
144 c->cancel = 1;
145 c->pending = 0;
146 } /* gpgme_cancel */
147
148
149 /**
150 * gpgme_get_notation:
151 * @c: the context
152 *
153 * If there is notation data available from the last signature check, this
154 * function may be used to return this notation data as a string. The string
155 * is a represantaton of that data embedded in a %<notation> container.
156 *
157 * Return value: An string or NULL if no notation data is available.
158 **/
159 char *
160 gpgme_get_notation (gpgme_ctx_t c)
161 {
162 if (!c || !c->notation)
163 return NULL;
164 return _gpgme_data_get_as_string (c->notation);
165 } /* gpgme_get_notation */
166
167
168 char *
169 gpgme_get_logging (gpgme_ctx_t c)
170 {
171 if (!c || !c->logging)
172 return NULL;
173 return _gpgme_data_get_as_string (c->logging);
174 }
175
176
177 void
178 gpgme_set_comment (gpgme_ctx_t c, const char * text)
179 {
180 if (!c)
181 return;
182 safe_free (c->comment);
183 c->comment = strdup (text);
184 }
185
186
187 /**
188 * gpgme_control:
189 * @c: the context
190 * @cmd: command to set
191 * @val: the value for the command.
192 *
193 * This is a replace for gpgme_set_xxx because in a DLL it's better to
194 * reduce the amount of functions.
195 **/
196 void *
197 gpgme_control( gpgme_ctx_t c, int cmd, int val )
198 {
199 if( !c )
200 return 0;
201
202 if( val == -1 ) {
203 switch( cmd ) {
204 case GPGME_CTRL_ARMOR: return (int *)c->use_armor;
205 case GPGME_CTRL_FPR: return c->keygen_fpr;
206 default: return NULL;
207 }
208 }
209
210 switch( cmd ) {
211
212 case GPGME_CTRL_S2K:
213 /* Pass S2K options down to GPG (no=0, yes=1) */
214 c->s2k.used = val;
215 break;
216
217 case GPGME_CTRL_S2K_MODE:
218 c->s2k.mode = val;
219 break;
220
221 case GPGME_CTRL_S2K_HASH:
222 c->s2k.digest_algo = val;
223 break;
224
225 case GPGME_CTRL_TEXTMODE:
226 /* Enable or disable the use of the special textmode. Textmode is for example
227 used for MIME (RFC2015) signatures. */
228 c->use_textmode = val;
229 break;
230
231 case GPGME_CTRL_LISTMODE:
232 /* This function changes the default behaviour of the keylisting functions.
233 Defines values for @mode are: %0 = normal, %1 = fast listing without
234 information about key validity. */
235 c->keylist_mode |= val;
236 break;
237
238 case GPGME_CTRL_NO_COMPR:
239 c->no_compress = val;
240 c->force_mdc = val == 1? 1 : 0;
241 break;
242
243 case GPGME_CTRL_CIPHER:
244 if (val == -1) { /* disable it */
245 c->cipher_algo = -1;
246 break;
247 }
248 if (val < 1 || val > 7) {
249 c->cipher_algo = GPGME_CIPHER_CAST5;
250 break;
251 }
252 c->cipher_algo = val;
253 break;
254
255 case GPGME_CTRL_TMPFILES: c->use_tmpfiles = val; break;
256 case GPGME_CTRL_WITH_SECRET_KEY: c->with_secret_key = val; break;
257 case GPGME_CTRL_FORCETRUST: c->force_trust = val; break;
258 case GPGME_CTRL_FORCEOPT: c->force_opt = val; break;
259 case GPGME_CTRL_FILE: c->use_file = val; break;
260 case GPGME_CTRL_THROWKEYID: c->use_throwkeyid = val; break;
261 case GPGME_CTRL_ARMOR: c->use_armor = val; break;
262 case GPGME_CTRL_INTERACTIVE: c->interactive = val; break;
263 case GPGME_CTRL_PIPEMODE: c->pipemode = val; break;
264 case GPGME_CTRL_LOGGING: c->use_logging = val; break;
265 case GPGME_CTRL_CB_VAL: c->cb.progress_value_int = val; break;
266 }
267
268 return NULL;
269 }
270
271 /**
272 * gpgme_set_passphrase_cb:
273 * @c: the context
274 * @cb: A callback function
275 * @cb_value: The value passed to the callback function
276 *
277 * This function sets a callback function to be used to pass a passphrase
278 * to gpg. The preferred way to handle this is by using the gpg-agent, but
279 * because that beast is not ready for real use, you can use this passphrase
280 * thing.
281 *
282 * The callback function is defined as:
283 * <literal>
284 * typedef const char *(*gpgme_passphrase_cb_t)(void*cb_value,
285 * const char *desc,
286 * void *r_hd);
287 * </literal>
288 * and called whenever gpgme needs a passphrase. DESC will have a nice
289 * text, to be used to prompt for the passphrase and R_HD is just a parameter
290 * to be used by the callback it self. Becuase the callback returns a const
291 * string, the callback might want to know when it can release resources
292 * assocated with that returned string; gpgme helps here by calling this
293 * passphrase callback with an DESC of %NULL as soon as it does not need
294 * the returned string anymore. The callback function might then choose
295 * to release resources depending on R_HD.
296 *
297 **/
298 void
299 gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
300 void * cb_value)
301 {
302 if (!ctx)
303 return;
304 ctx->cb.passphrase = cb;
305 ctx->cb.passphrase_value = cb_value;
306 } /* gpgme_set_passphrase_cb */
307
308
309 void
310 gpgme_set_interactive_cb (gpgme_ctx_t ctx, gpgme_interactive_cb_t cb,
311 void * cb_value)
312 {
313 if (!ctx)
314 return;
315 ctx->cb.interactiv = cb;
316 ctx->cb.interactiv_value = cb_value;
317 } /* gpgme_set_inteactive_cb */
318
319
320 /**
321 * gpgme_set_pprogress_cb:
322 * @c: the context
323 * @cb: A callback function
324 * @cb_value: The value passed to the callback function
325 *
326 * This function sets a callback function to be used as a progress indicator.
327 *
328 * The callback function is defined as:
329 * <literal>
330 * typedef void (*gpgme_progress_cb_t) (void * cb_value,
331 * const char * what, int type,
332 * int curretn, int total);
333 * </literal>
334 * For details on the progress events, see the entry for the PROGRESS
335 * status in the file doc/DETAILS of the GnuPG distribution.
336 **/
337 void
338 gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb,
339 void * cb_value)
340 {
341 if (!ctx)
342 return;
343 ctx->cb.progress = cb;
344 ctx->cb.progress_value = cb_value;
345 } /* gpgme_set_progress_cb */
346
347
348 void
349 gpgme_set_edit_ctx( gpgme_ctx_t ctx, void * edit_ctx, int edit_id )
350 {
351 if( !ctx )
352 return;
353 ctx->edit_opaque = edit_ctx;
354 ctx->edit_cmd = edit_id;
355 } /* gpgme_set_edit_ctx */
356
357
358 void
359 gpgme_set_list_options (gpgme_ctx_t ctx, int optid)
360 {
361 if (!ctx)
362 return;
363 ctx->list_opts |= optid;
364 }
365
366
367 void
368 gpgme_set_cache_ctx (gpgme_ctx_t ctx, void * cache_ctx)
369 {
370 if( ctx )
371 ctx->key_lookup = cache_ctx;
372 } /* gpgme_set_cache_ctx */
373
374
375 void
376 gpgme_set_passphrase( gpgme_ctx_t ctx, const char * passphrase )
377 {
378 if( !ctx )
379 return;
380 ctx->passphrase_value = passphrase;
381 ctx->use_pass_fd = 1;
382 } /* gpgme_set_passphrase */
383
384
385 gpgme_error_t
386 _gpgme_add_passphrase( gpgme_ctx_t ctx )
387 {
388 gpgme_error_t err;
389 gpgme_data_t passphrase_fd;
390
391 if( !ctx )
392 return mk_error( Invalid_Value );
393 if( !ctx->passphrase_value || !ctx->use_pass_fd )
394 return mk_error( General_Error );
395
396 err = gpgme_data_new_from_mem( &passphrase_fd, ctx->passphrase_value,
397 strlen( ctx->passphrase_value ), 0 );
398 if( err )
399 return err;
400 _gpgme_data_set_mode( passphrase_fd, GPGME_DATA_MODE_OUT );
401 _gpgme_gpg_add_arg( ctx->gpg, "--passphrase-fd" );
402 _gpgme_gpg_add_data( ctx->gpg, passphrase_fd, -2 );
403
404 return 0;
405 } /* _gpgme_add_passphrase */
406
407
408 void
409 gpgme_set_debug_mode( int val )
410 {
411 if( val )
412 putenv( "GPGME_DEBUG=5:gpgme.dbg" );
413 else
414 putenv( "GPGME_DEBUG=" );
415 } /* gpgme_set_debug_mode */
416
417
418 const char*
419 _gpgme_get_tmpfile( int input )
420 {
421 static char tmpfile[384];
422 char path[256];
423
424 GetTempPath( sizeof path -1, path );
425 _snprintf( tmpfile, sizeof tmpfile -1,
426 "%sgpgme%s.%u", path, input? "IN" : "OUT", _getpid() );
427 return tmpfile;
428 } /* _gpgme_get_tmpfile */
429
430
431 static int
432 _gpgme_unlink( const char * file, int arg )
433 {
434 return unlink( file );
435 } /* _gpgme_unlink */
436
437
438 void
439 _gpgme_del_tmpfiles( gpgme_wipe_t wipe_fnc )
440 {
441 gpgme_wipe_t erase = wipe_fnc? wipe_fnc: _gpgme_unlink;
442
443 erase( _gpgme_get_tmpfile( 0 ), 1 );
444 erase( _gpgme_get_tmpfile( 1 ), 1 );
445 } /* _gpgme_del_tmpfiles */
446
447 void
448 gpgme_set_wipe_fnc( gpgme_ctx_t ctx, gpgme_wipe_t fnc )
449 {
450 if( ctx )
451 ctx->wipe_fnc = fnc;
452 } /* gpgme_set_wipe_fnc */
453
454
455 void
456 gpgme_set_local_user( gpgme_ctx_t ctx, const char * name )
457 {
458 if( ctx && name ) {
459 safe_free (ctx->locusr);
460 ctx->locusr = strdup( name );
461 }
462 } /* gpgme_set_local_user */
463
464
465 int
466 gpgme_get_process_rc (gpgme_ctx_t ctx)
467 {
468 if (!ctx)
469 return -1;
470 return (int)ctx->proc_rc;
471 } /* gpgme_get_process_rc */
472
473
474 void
475 _gpgme_progress_handler (gpgme_ctx_t ctx, char * args)
476 {
477 const char * name = args;
478 char * buf, * p;
479 char * what = NULL;
480 unsigned curr, total, i=0;
481
482 /* what */
483 p = strchr (args, '?');
484 if (!p)
485 return;
486 what = malloc (p-args+2);
487 if (!what) {
488 ctx->out_of_core = 1;
489 return;
490 }
491 while (name && *name != '?')
492 what[i++] = *name++;
493 what[i] = '\0';
494 /* XXX remove space at the end */
495 i = 0;
496 buf = args + (p-args);
497 while ((p = strsep (&buf, " "))) {
498 switch (i) {
499 case 0:
500 break; /* type */
501 case 1:
502 curr = strtoul (p, NULL, 10);
503 break; /* current offset */
504 case 2:
505 total = strtoul (p, NULL, 10);
506 break; /* total */
507 }
508 i++;
509 }
510 if (what) {
511 ctx->cb.progress (ctx->cb.progress_value, what, 0, curr, total);
512 safe_free (what);
513 }
514 } /* _gpgme_progress_handler */
515
516
517 void
518 _gpgme_add_comment (gpgme_ctx_t ctx)
519 {
520 char * p;
521
522 if (ctx->comment)
523 {
524 p = calloc (1, strlen (ctx->comment)+2);
525 if (!p)
526 {
527 ctx->out_of_core = 1;
528 return;
529 }
530 _gpgme_gpg_add_arg (ctx->gpg, "--comment");
531 p[0] = '"';
532 strcpy (p+1, ctx->comment);
533 strcat (p, "\"");
534 _gpgme_gpg_add_arg (ctx->gpg, p);
535 safe_free (p);
536 }
537 }
538
539
540 gpgme_error_t
541 gpgme_check_logging (gpgme_ctx_t ctx)
542 {
543 char * buf;
544
545 if (!ctx)
546 return mk_error (Invalid_Value);
547 buf = gpgme_get_logging (ctx);
548 if (!buf)
549 return mk_error (No_Error);
550
551 /* XXX: this only works for English GPG output!!! */
552 if (strstr (buf, "gpg.conf:") && strstr (buf, "invalid option"))
553 return mk_error (Conf_InvOption);
554
555 free (buf);
556 return 0;
557 }
558
559
560 gpgme_error_t
561 gpgme_lib_init (void)
562 {
563 return 0;
564 }
565
566
567 void
568 gpgme_lib_cleanup (void)
569 {
570 debug_cleanup ();
571 rungpg_cleanup ();
572 io_cleanup ();
573 wait_cleanup ();
574 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26