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

Annotation of /trunk/MyGPGME/gpgme.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File MIME type: text/plain
File size: 14364 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26