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

Contents of /trunk/MyGPGME/gpgme.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Mon Apr 4 07:01:43 2005 UTC (19 years, 10 months ago) by twoaday
File MIME type: text/plain
File size: 14327 byte(s)
2005-03-22  Timo Schulz  <twoaday@freakmail.de>
                                                                                
        * editcard.c: Support new status-fd entries SC_OP_SUCCESS
        and SC_OP_FAILURE.
        * editkey.c (cmd_addrev_handler): Check if context != NULL.
        * import.c (import_command_handler): Wrong function signature.
        Noted by Kurt Fitzner.
        * types.h: Fixed encrypt_result_s. Noted by Kurt.
        * gpgme.h (gpgme_editkey_addrev_set): Changed return type.
        Kudos to Kurt.
        * key.c: Removed some unreachable code. By Kurt.
                                                                                


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 if (!c->comment)
185 c->out_of_core = 1;
186 }
187
188
189 void
190 gpgme_set_homedir (gpgme_ctx_t c, const char *homedir)
191 {
192 if (!c)
193 return;
194 safe_free (c->homedir);
195 c->homedir = strdup (homedir);
196 if (!c->homedir)
197 c->out_of_core = 1;
198 }
199
200
201 /**
202 * gpgme_control:
203 * @c: the context
204 * @cmd: command to set
205 * @val: the value for the command.
206 *
207 * This is a replace for gpgme_set_xxx because in a DLL it's better to
208 * reduce the amount of functions.
209 **/
210 void *
211 gpgme_control( gpgme_ctx_t c, int cmd, int val )
212 {
213 if( !c )
214 return 0;
215
216 if( val == -1 ) {
217 switch( cmd ) {
218 case GPGME_CTRL_ARMOR: return (int *)c->use_armor;
219 case GPGME_CTRL_FPR: return c->keygen_fpr;
220 default: return NULL;
221 }
222 }
223
224 switch( cmd ) {
225
226 case GPGME_CTRL_S2K:
227 /* Pass S2K options down to GPG (no=0, yes=1) */
228 c->s2k.used = val;
229 break;
230
231 case GPGME_CTRL_S2K_MODE:
232 c->s2k.mode = val;
233 break;
234
235 case GPGME_CTRL_S2K_HASH:
236 c->s2k.digest_algo = val;
237 break;
238
239 case GPGME_CTRL_TEXTMODE:
240 /* Enable or disable the use of the special textmode. Textmode is for example
241 used for MIME (RFC2015) signatures. */
242 c->use_textmode = val;
243 break;
244
245 case GPGME_CTRL_LISTMODE:
246 /* This function changes the default behaviour of the keylisting functions.
247 Defines values for @mode are: %0 = normal, %1 = fast listing without
248 information about key validity. */
249 c->keylist_mode |= val;
250 break;
251
252 case GPGME_CTRL_NO_COMPR:
253 c->no_compress = val;
254 c->force_mdc = val == 1? 1 : 0;
255 break;
256
257 case GPGME_CTRL_CIPHER:
258 if (val == -1) { /* disable it */
259 c->cipher_algo = -1;
260 break;
261 }
262 if (val < 1 || val > 7) {
263 c->cipher_algo = GPGME_CIPHER_CAST5;
264 break;
265 }
266 c->cipher_algo = val;
267 break;
268
269 case GPGME_CTRL_TMPFILES: c->use_tmpfiles = val; break;
270 case GPGME_CTRL_WITH_SECRET_KEY: c->with_secret_key = val; break;
271 case GPGME_CTRL_FORCETRUST: c->force_trust = val; break;
272 case GPGME_CTRL_FORCEOPT: c->force_opt = val; break;
273 case GPGME_CTRL_FILE: c->use_file = val; break;
274 case GPGME_CTRL_THROWKEYID: c->use_throwkeyid = val; break;
275 case GPGME_CTRL_ARMOR: c->use_armor = val; break;
276 case GPGME_CTRL_INTERACTIVE: c->interactive = val; break;
277 case GPGME_CTRL_PIPEMODE: c->pipemode = val; break;
278 case GPGME_CTRL_LOGGING: c->use_logging = val; break;
279 case GPGME_CTRL_CB_VAL: c->cb.progress_value_int = val; break;
280 }
281
282 return NULL;
283 }
284
285 /**
286 * gpgme_set_passphrase_cb:
287 * @c: the context
288 * @cb: A callback function
289 * @cb_value: The value passed to the callback function
290 *
291 * This function sets a callback function to be used to pass a passphrase
292 * to gpg. The preferred way to handle this is by using the gpg-agent, but
293 * because that beast is not ready for real use, you can use this passphrase
294 * thing.
295 *
296 * The callback function is defined as:
297 * <literal>
298 * typedef const char *(*gpgme_passphrase_cb_t)(void*cb_value,
299 * const char *desc,
300 * void *r_hd);
301 * </literal>
302 * and called whenever gpgme needs a passphrase. DESC will have a nice
303 * text, to be used to prompt for the passphrase and R_HD is just a parameter
304 * to be used by the callback it self. Becuase the callback returns a const
305 * string, the callback might want to know when it can release resources
306 * assocated with that returned string; gpgme helps here by calling this
307 * passphrase callback with an DESC of %NULL as soon as it does not need
308 * the returned string anymore. The callback function might then choose
309 * to release resources depending on R_HD.
310 *
311 **/
312 void
313 gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
314 void * cb_value)
315 {
316 if (!ctx)
317 return;
318 ctx->cb.passphrase = cb;
319 ctx->cb.passphrase_value = cb_value;
320 } /* gpgme_set_passphrase_cb */
321
322
323 void
324 gpgme_set_interactive_cb (gpgme_ctx_t ctx, gpgme_interactive_cb_t cb,
325 void * cb_value)
326 {
327 if (!ctx)
328 return;
329 ctx->cb.interactiv = cb;
330 ctx->cb.interactiv_value = cb_value;
331 } /* gpgme_set_inteactive_cb */
332
333
334 /**
335 * gpgme_set_pprogress_cb:
336 * @c: the context
337 * @cb: A callback function
338 * @cb_value: The value passed to the callback function
339 *
340 * This function sets a callback function to be used as a progress indicator.
341 *
342 * The callback function is defined as:
343 * <literal>
344 * typedef void (*gpgme_progress_cb_t) (void * cb_value,
345 * const char * what, int type,
346 * int curretn, int total);
347 * </literal>
348 * For details on the progress events, see the entry for the PROGRESS
349 * status in the file doc/DETAILS of the GnuPG distribution.
350 **/
351 void
352 gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb,
353 void * cb_value)
354 {
355 if (!ctx)
356 return;
357 ctx->cb.progress = cb;
358 ctx->cb.progress_value = cb_value;
359 } /* gpgme_set_progress_cb */
360
361
362 void
363 gpgme_set_edit_ctx( gpgme_ctx_t ctx, void * edit_ctx, int edit_id )
364 {
365 if( !ctx )
366 return;
367 ctx->edit_opaque = edit_ctx;
368 ctx->edit_cmd = edit_id;
369 } /* gpgme_set_edit_ctx */
370
371
372 void
373 gpgme_set_list_options (gpgme_ctx_t ctx, int optid)
374 {
375 if (!ctx)
376 return;
377 ctx->list_opts |= optid;
378 }
379
380
381 void
382 gpgme_set_cache_ctx (gpgme_ctx_t ctx, void * cache_ctx)
383 {
384 if( ctx )
385 ctx->key_lookup = cache_ctx;
386 } /* gpgme_set_cache_ctx */
387
388
389 void
390 gpgme_set_passphrase( gpgme_ctx_t ctx, const char * passphrase )
391 {
392 if( !ctx )
393 return;
394 ctx->passphrase_value = passphrase;
395 ctx->use_pass_fd = 1;
396 } /* gpgme_set_passphrase */
397
398
399 gpgme_error_t
400 _gpgme_add_passphrase( gpgme_ctx_t ctx )
401 {
402 gpgme_error_t err;
403 gpgme_data_t passphrase_fd;
404
405 if( !ctx )
406 return mk_error( Invalid_Value );
407 if( !ctx->passphrase_value || !ctx->use_pass_fd )
408 return mk_error( General_Error );
409
410 err = gpgme_data_new_from_mem( &passphrase_fd, ctx->passphrase_value,
411 strlen( ctx->passphrase_value ), 0 );
412 if( err )
413 return err;
414 _gpgme_data_set_mode( passphrase_fd, GPGME_DATA_MODE_OUT );
415 _gpgme_gpg_add_arg( ctx->gpg, "--passphrase-fd" );
416 _gpgme_gpg_add_data( ctx->gpg, passphrase_fd, -2 );
417
418 return 0;
419 } /* _gpgme_add_passphrase */
420
421
422 void
423 gpgme_set_debug_mode( int val )
424 {
425 if( val )
426 putenv( "GPGME_DEBUG=5:gpgme.dbg" );
427 else
428 putenv( "GPGME_DEBUG=" );
429 } /* gpgme_set_debug_mode */
430
431
432 const char*
433 _gpgme_get_tmpfile( int input )
434 {
435 static char tmpfile[384];
436 char path[256];
437
438 GetTempPath( sizeof path -1, path );
439 _snprintf( tmpfile, sizeof tmpfile -1,
440 "%sgpgme%s.%u", path, input? "IN" : "OUT", getpid() );
441 return tmpfile;
442 } /* _gpgme_get_tmpfile */
443
444
445 static int
446 _gpgme_unlink( const char * file, int arg )
447 {
448 return unlink( file );
449 } /* _gpgme_unlink */
450
451
452 void
453 _gpgme_del_tmpfiles( gpgme_wipe_t wipe_fnc )
454 {
455 gpgme_wipe_t erase = wipe_fnc? wipe_fnc: (gpgme_wipe_t)_gpgme_unlink;
456
457 erase( _gpgme_get_tmpfile( 0 ), 1 );
458 erase( _gpgme_get_tmpfile( 1 ), 1 );
459 } /* _gpgme_del_tmpfiles */
460
461 void
462 gpgme_set_wipe_fnc( gpgme_ctx_t ctx, gpgme_wipe_t fnc )
463 {
464 if( ctx )
465 ctx->wipe_fnc = fnc;
466 } /* gpgme_set_wipe_fnc */
467
468
469 void
470 gpgme_set_local_user( gpgme_ctx_t ctx, const char * name )
471 {
472 if( ctx && name ) {
473 safe_free (ctx->locusr);
474 ctx->locusr = strdup( name );
475 }
476 } /* gpgme_set_local_user */
477
478
479 int
480 gpgme_get_process_rc (gpgme_ctx_t ctx)
481 {
482 if (!ctx)
483 return -1;
484 return (int)ctx->proc_rc;
485 } /* gpgme_get_process_rc */
486
487
488 void
489 _gpgme_progress_handler (gpgme_ctx_t ctx, char * args)
490 {
491 const char * name = args;
492 char * buf, * p;
493 char * what = NULL;
494 unsigned curr, total, i=0;
495
496 /* what */
497 p = strchr (args, '?');
498 if (!p)
499 return;
500 what = malloc (p-args+2);
501 if (!what) {
502 ctx->out_of_core = 1;
503 return;
504 }
505 while (name && *name != '?')
506 what[i++] = *name++;
507 what[i] = '\0';
508 /* XXX remove space at the end */
509 i = 0;
510 buf = args + (p-args);
511 while ((p = strsep (&buf, " ")) != NULL) {
512 switch (i) {
513 case 0:
514 break; /* type */
515 case 1:
516 curr = strtoul (p, NULL, 10);
517 break; /* current offset */
518 case 2:
519 total = strtoul (p, NULL, 10);
520 break; /* total */
521 }
522 i++;
523 }
524 if (what) {
525 ctx->cb.progress (ctx->cb.progress_value, what, 0, curr, total);
526 safe_free (what);
527 }
528 } /* _gpgme_progress_handler */
529
530
531 void
532 _gpgme_add_comment (gpgme_ctx_t ctx)
533 {
534 char * p;
535
536 if (ctx->comment)
537 {
538 p = calloc (1, strlen (ctx->comment)+2);
539 if (!p)
540 {
541 ctx->out_of_core = 1;
542 return;
543 }
544 _gpgme_gpg_add_arg (ctx->gpg, "--comment");
545 p[0] = '"';
546 strcpy (p+1, ctx->comment);
547 strcat (p, "\"");
548 _gpgme_gpg_add_arg (ctx->gpg, p);
549 safe_free (p);
550 }
551 }
552
553
554 gpgme_error_t
555 gpgme_check_logging (gpgme_ctx_t ctx)
556 {
557 char * buf;
558
559 if (!ctx)
560 return mk_error (Invalid_Value);
561 buf = gpgme_get_logging (ctx);
562 if (!buf)
563 return mk_error (No_Error);
564
565 /* XXX: this only works for English GPG output!!! */
566 if (strstr (buf, "gpg.conf:") && strstr (buf, "invalid option"))
567 return mk_error (Conf_InvOption);
568
569 free (buf);
570 return 0;
571 }
572
573
574 gpgme_error_t
575 gpgme_lib_init (void)
576 {
577 return 0;
578 }
579
580
581 void
582 gpgme_lib_cleanup (void)
583 {
584 debug_cleanup ();
585 rungpg_cleanup ();
586 io_cleanup ();
587 wait_cleanup ();
588 util_cleanup ();
589 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26