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

Annotation of /trunk/MyGPGME/gpgme.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide 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 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     }
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