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

Annotation of /trunk/MyGPGME/gpgme.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide 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 twoaday 2 /* 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 twoaday 7 if (!c->comment)
185     c->out_of_core = 1;
186 twoaday 2 }
187    
188    
189 twoaday 7 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 twoaday 2 /**
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 twoaday 7 "%sgpgme%s.%u", path, input? "IN" : "OUT", getpid() );
441 twoaday 2 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 twoaday 7 gpgme_wipe_t erase = wipe_fnc? wipe_fnc: (gpgme_wipe_t)_gpgme_unlink;
456 twoaday 2
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 twoaday 7 while ((p = strsep (&buf, " ")) != NULL) {
512 twoaday 2 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 twoaday 7 util_cleanup ();
589 twoaday 2 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26