Line data Source code
1 : /* gpgme.c - GnuPG Made Easy.
2 : Copyright (C) 2000 Werner Koch (dd9jn)
3 : Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012,
4 : 2014, 2015 g10 Code GmbH
5 :
6 : This file is part of GPGME.
7 :
8 : GPGME is free software; you can redistribute it and/or modify it
9 : under the terms of the GNU Lesser General Public License as
10 : published by the Free Software Foundation; either version 2.1 of
11 : the License, or (at your option) any later version.
12 :
13 : GPGME is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : Lesser General Public License for more details.
17 :
18 : You should have received a copy of the GNU Lesser General Public
19 : License along with this program; if not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #if HAVE_CONFIG_H
23 : #include <config.h>
24 : #endif
25 : #include <stdio.h>
26 : #include <stdlib.h>
27 : #include <string.h>
28 : #include <assert.h>
29 : #include <errno.h>
30 : #ifdef HAVE_LOCALE_H
31 : #include <locale.h>
32 : #endif
33 :
34 : #include "util.h"
35 : #include "context.h"
36 : #include "ops.h"
37 : #include "wait.h"
38 : #include "debug.h"
39 : #include "priv-io.h"
40 : #include "sys-util.h"
41 :
42 :
43 : /* The default locale. */
44 : DEFINE_STATIC_LOCK (def_lc_lock);
45 : static char *def_lc_ctype;
46 : static char *def_lc_messages;
47 :
48 :
49 : gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL;
50 :
51 : /* Protects all reference counters in result structures. All other
52 : accesses to a result structure are read only. */
53 : DEFINE_STATIC_LOCK (result_ref_lock);
54 :
55 :
56 : /* Set the global flag NAME to VALUE. Return 0 on success. Note that
57 : this function does not use gpgme_error and thus a non-zero return
58 : value merely means "error". Certain flags may be set before
59 : gpgme_check_version is called. See the manual for a description of
60 : supported flags. The caller must assure that this function is
61 : called only by one thread at a time. */
62 : int
63 0 : gpgme_set_global_flag (const char *name, const char *value)
64 : {
65 0 : if (!name || !value)
66 0 : return -1;
67 0 : else if (!strcmp (name, "debug"))
68 0 : return _gpgme_debug_set_debug_envvar (value);
69 0 : else if (!strcmp (name, "disable-gpgconf"))
70 : {
71 0 : _gpgme_dirinfo_disable_gpgconf ();
72 0 : return 0;
73 : }
74 0 : else if (!strcmp (name, "gpgconf-name"))
75 0 : return _gpgme_set_default_gpgconf_name (value);
76 0 : else if (!strcmp (name, "gpg-name"))
77 0 : return _gpgme_set_default_gpg_name (value);
78 0 : else if (!strcmp (name, "w32-inst-dir"))
79 0 : return _gpgme_set_override_inst_dir (value);
80 : else
81 0 : return -1;
82 : }
83 :
84 :
85 :
86 : /* Create a new context as an environment for GPGME crypto
87 : operations. */
88 : gpgme_error_t
89 118 : gpgme_new (gpgme_ctx_t *r_ctx)
90 : {
91 : gpgme_error_t err;
92 : gpgme_ctx_t ctx;
93 118 : TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
94 :
95 118 : if (_gpgme_selftest)
96 0 : return TRACE_ERR (_gpgme_selftest);
97 :
98 118 : if (!r_ctx)
99 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
100 :
101 118 : ctx = calloc (1, sizeof *ctx);
102 118 : if (!ctx)
103 0 : return TRACE_ERR (gpg_error_from_syserror ());
104 :
105 118 : INIT_LOCK (ctx->lock);
106 :
107 118 : err = _gpgme_engine_info_copy (&ctx->engine_info);
108 118 : if (!err && !ctx->engine_info)
109 0 : err = gpg_error (GPG_ERR_NO_ENGINE);
110 118 : if (err)
111 : {
112 0 : free (ctx);
113 0 : return TRACE_ERR (err);
114 : }
115 :
116 118 : ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
117 118 : ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
118 118 : ctx->protocol = GPGME_PROTOCOL_OpenPGP;
119 118 : ctx->sub_protocol = GPGME_PROTOCOL_DEFAULT;
120 118 : _gpgme_fd_table_init (&ctx->fdt);
121 :
122 118 : LOCK (def_lc_lock);
123 118 : if (def_lc_ctype)
124 : {
125 118 : ctx->lc_ctype = strdup (def_lc_ctype);
126 118 : if (!ctx->lc_ctype)
127 : {
128 0 : int saved_err = gpg_error_from_syserror ();
129 0 : UNLOCK (def_lc_lock);
130 0 : _gpgme_engine_info_release (ctx->engine_info);
131 0 : free (ctx);
132 0 : return TRACE_ERR (saved_err);
133 : }
134 : }
135 : else
136 0 : def_lc_ctype = NULL;
137 :
138 118 : if (def_lc_messages)
139 : {
140 118 : ctx->lc_messages = strdup (def_lc_messages);
141 118 : if (!ctx->lc_messages)
142 : {
143 0 : int saved_err = gpg_error_from_syserror ();
144 0 : UNLOCK (def_lc_lock);
145 0 : if (ctx->lc_ctype)
146 0 : free (ctx->lc_ctype);
147 0 : _gpgme_engine_info_release (ctx->engine_info);
148 0 : free (ctx);
149 0 : return TRACE_ERR (saved_err);
150 : }
151 : }
152 : else
153 0 : def_lc_messages = NULL;
154 118 : UNLOCK (def_lc_lock);
155 :
156 118 : *r_ctx = ctx;
157 :
158 118 : return TRACE_SUC1 ("ctx=%p", ctx);
159 : }
160 :
161 :
162 : gpgme_error_t
163 2 : _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err,
164 : gpg_error_t op_err)
165 : {
166 : gpgme_error_t err;
167 : struct gpgme_io_event_done_data data;
168 :
169 2 : TRACE_BEG2 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i, op_err=%i",
170 : ctx_err, op_err);
171 :
172 2 : if (ctx_err)
173 : {
174 2 : err = _gpgme_engine_cancel (ctx->engine);
175 2 : if (err)
176 0 : return TRACE_ERR (err);
177 : }
178 : else
179 : {
180 0 : err = _gpgme_engine_cancel_op (ctx->engine);
181 0 : if (err)
182 0 : return TRACE_ERR (err);
183 : }
184 :
185 2 : data.err = ctx_err;
186 2 : data.op_err = op_err;
187 :
188 2 : _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data);
189 :
190 2 : return TRACE_ERR (0);
191 : }
192 :
193 :
194 : /* Cancel a pending asynchronous operation. */
195 : gpgme_error_t
196 0 : gpgme_cancel (gpgme_ctx_t ctx)
197 : {
198 : gpg_error_t err;
199 :
200 0 : TRACE_BEG (DEBUG_CTX, "gpgme_cancel", ctx);
201 :
202 0 : if (!ctx)
203 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
204 :
205 0 : err = _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED), 0);
206 :
207 0 : return TRACE_ERR (err);
208 : }
209 :
210 :
211 : /* Cancel a pending operation asynchronously. */
212 : gpgme_error_t
213 0 : gpgme_cancel_async (gpgme_ctx_t ctx)
214 : {
215 0 : TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx);
216 :
217 0 : if (!ctx)
218 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
219 :
220 0 : LOCK (ctx->lock);
221 0 : ctx->canceled = 1;
222 0 : UNLOCK (ctx->lock);
223 :
224 0 : return TRACE_ERR (0);
225 : }
226 :
227 :
228 : /* Release all resources associated with the given context. */
229 : void
230 117 : gpgme_release (gpgme_ctx_t ctx)
231 : {
232 117 : TRACE (DEBUG_CTX, "gpgme_release", ctx);
233 :
234 117 : if (!ctx)
235 117 : return;
236 :
237 117 : _gpgme_engine_release (ctx->engine);
238 117 : ctx->engine = NULL;
239 117 : _gpgme_fd_table_deinit (&ctx->fdt);
240 117 : _gpgme_release_result (ctx);
241 117 : _gpgme_signers_clear (ctx);
242 117 : _gpgme_sig_notation_clear (ctx);
243 117 : if (ctx->signers)
244 1 : free (ctx->signers);
245 117 : if (ctx->lc_ctype)
246 117 : free (ctx->lc_ctype);
247 117 : if (ctx->lc_messages)
248 117 : free (ctx->lc_messages);
249 117 : _gpgme_engine_info_release (ctx->engine_info);
250 117 : ctx->engine_info = NULL;
251 117 : DESTROY_LOCK (ctx->lock);
252 117 : free (ctx);
253 : }
254 :
255 :
256 : void
257 0 : gpgme_result_ref (void *result)
258 : {
259 : struct ctx_op_data *data;
260 :
261 0 : if (! result)
262 0 : return;
263 :
264 0 : data = (void*)((char*)result - sizeof (struct ctx_op_data));
265 :
266 0 : assert (data->magic == CTX_OP_DATA_MAGIC);
267 :
268 0 : LOCK (result_ref_lock);
269 0 : data->references++;
270 0 : UNLOCK (result_ref_lock);
271 : }
272 :
273 :
274 : void
275 177 : gpgme_result_unref (void *result)
276 : {
277 : struct ctx_op_data *data;
278 :
279 177 : if (! result)
280 0 : return;
281 :
282 177 : data = (void*)((char*)result - sizeof (struct ctx_op_data));
283 :
284 177 : assert (data->magic == CTX_OP_DATA_MAGIC);
285 :
286 177 : LOCK (result_ref_lock);
287 177 : if (--data->references)
288 : {
289 0 : UNLOCK (result_ref_lock);
290 0 : return;
291 : }
292 177 : UNLOCK (result_ref_lock);
293 :
294 177 : if (data->cleanup)
295 175 : (*data->cleanup) (data->hook);
296 177 : free (data);
297 : }
298 :
299 :
300 : void
301 255 : _gpgme_release_result (gpgme_ctx_t ctx)
302 : {
303 255 : struct ctx_op_data *data = ctx->op_data;
304 :
305 687 : while (data)
306 : {
307 177 : struct ctx_op_data *next_data = data->next;
308 177 : data->next = NULL;
309 177 : gpgme_result_unref (data->hook);
310 177 : data = next_data;
311 : }
312 255 : ctx->op_data = NULL;
313 255 : }
314 :
315 :
316 : gpgme_error_t
317 59 : gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
318 : {
319 59 : TRACE_BEG2 (DEBUG_CTX, "gpgme_set_protocol", ctx, "protocol=%i (%s)",
320 : protocol, gpgme_get_protocol_name (protocol)
321 : ? gpgme_get_protocol_name (protocol) : "invalid");
322 :
323 59 : if (protocol != GPGME_PROTOCOL_OpenPGP
324 8 : && protocol != GPGME_PROTOCOL_CMS
325 0 : && protocol != GPGME_PROTOCOL_GPGCONF
326 0 : && protocol != GPGME_PROTOCOL_ASSUAN
327 0 : && protocol != GPGME_PROTOCOL_G13
328 0 : && protocol != GPGME_PROTOCOL_UISERVER
329 0 : && protocol != GPGME_PROTOCOL_SPAWN)
330 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
331 :
332 59 : if (!ctx)
333 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
334 :
335 59 : if (ctx->protocol != protocol)
336 : {
337 : /* Shut down the engine when switching protocols. */
338 8 : if (ctx->engine)
339 : {
340 0 : TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
341 0 : _gpgme_engine_release (ctx->engine);
342 0 : ctx->engine = NULL;
343 : }
344 :
345 8 : ctx->protocol = protocol;
346 : }
347 59 : return TRACE_ERR (0);
348 : }
349 :
350 :
351 : gpgme_protocol_t
352 52 : gpgme_get_protocol (gpgme_ctx_t ctx)
353 : {
354 52 : TRACE2 (DEBUG_CTX, "gpgme_get_protocol", ctx,
355 : "ctx->protocol=%i (%s)", ctx->protocol,
356 : gpgme_get_protocol_name (ctx->protocol)
357 : ? gpgme_get_protocol_name (ctx->protocol) : "invalid");
358 :
359 52 : return ctx->protocol;
360 : }
361 :
362 :
363 : gpgme_error_t
364 0 : gpgme_set_sub_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
365 : {
366 0 : TRACE2 (DEBUG_CTX, "gpgme_set_sub_protocol", ctx, "protocol=%i (%s)",
367 : protocol, gpgme_get_protocol_name (protocol)
368 : ? gpgme_get_protocol_name (protocol) : "invalid");
369 :
370 0 : if (!ctx)
371 0 : return gpg_error (GPG_ERR_INV_VALUE);
372 :
373 0 : ctx->sub_protocol = protocol;
374 0 : return 0;
375 : }
376 :
377 :
378 : gpgme_protocol_t
379 0 : gpgme_get_sub_protocol (gpgme_ctx_t ctx)
380 : {
381 0 : TRACE2 (DEBUG_CTX, "gpgme_get_sub_protocol", ctx,
382 : "ctx->sub_protocol=%i (%s)", ctx->sub_protocol,
383 : gpgme_get_protocol_name (ctx->sub_protocol)
384 : ? gpgme_get_protocol_name (ctx->sub_protocol) : "invalid");
385 :
386 0 : return ctx->sub_protocol;
387 : }
388 :
389 :
390 : const char *
391 326 : gpgme_get_protocol_name (gpgme_protocol_t protocol)
392 : {
393 326 : switch (protocol)
394 : {
395 : case GPGME_PROTOCOL_OpenPGP:
396 306 : return "OpenPGP";
397 :
398 : case GPGME_PROTOCOL_CMS:
399 20 : return "CMS";
400 :
401 : case GPGME_PROTOCOL_GPGCONF:
402 0 : return "GPGCONF";
403 :
404 : case GPGME_PROTOCOL_ASSUAN:
405 0 : return "Assuan";
406 :
407 : case GPGME_PROTOCOL_G13:
408 0 : return "G13";
409 :
410 : case GPGME_PROTOCOL_UISERVER:
411 0 : return "UIServer";
412 :
413 : case GPGME_PROTOCOL_SPAWN:
414 0 : return "Spawn";
415 :
416 : case GPGME_PROTOCOL_DEFAULT:
417 0 : return "default";
418 :
419 : case GPGME_PROTOCOL_UNKNOWN:
420 0 : return "unknown";
421 :
422 : default:
423 0 : return NULL;
424 : }
425 : }
426 :
427 : /* Enable or disable the use of an ascii armor for all output. */
428 : void
429 33 : gpgme_set_armor (gpgme_ctx_t ctx, int use_armor)
430 : {
431 33 : TRACE2 (DEBUG_CTX, "gpgme_set_armor", ctx, "use_armor=%i (%s)",
432 : use_armor, use_armor ? "yes" : "no");
433 :
434 33 : if (!ctx)
435 33 : return;
436 :
437 33 : ctx->use_armor = use_armor;
438 : }
439 :
440 :
441 : /* Return the state of the armor flag. */
442 : int
443 0 : gpgme_get_armor (gpgme_ctx_t ctx)
444 : {
445 0 : TRACE2 (DEBUG_CTX, "gpgme_get_armor", ctx, "ctx->use_armor=%i (%s)",
446 : ctx->use_armor, ctx->use_armor ? "yes" : "no");
447 0 : return ctx->use_armor;
448 : }
449 :
450 :
451 : /* Enable or disable the use of the special textmode. Textmode is for
452 : example used for the RFC2015 signatures; note that the updated RFC
453 : 3156 mandates that the MUA does some preparations so that textmode
454 : is not needed anymore. */
455 : void
456 4 : gpgme_set_textmode (gpgme_ctx_t ctx, int use_textmode)
457 : {
458 4 : TRACE2 (DEBUG_CTX, "gpgme_set_textmode", ctx, "use_textmode=%i (%s)",
459 : use_textmode, use_textmode ? "yes" : "no");
460 :
461 4 : if (!ctx)
462 4 : return;
463 :
464 4 : ctx->use_textmode = use_textmode;
465 : }
466 :
467 : /* Return the state of the textmode flag. */
468 : int
469 0 : gpgme_get_textmode (gpgme_ctx_t ctx)
470 : {
471 0 : TRACE2 (DEBUG_CTX, "gpgme_get_textmode", ctx, "ctx->use_textmode=%i (%s)",
472 : ctx->use_textmode, ctx->use_textmode ? "yes" : "no");
473 0 : return ctx->use_textmode;
474 : }
475 :
476 :
477 : /* Enable offline mode for this context. In offline mode dirmngr
478 : will be disabled. */
479 : void
480 0 : gpgme_set_offline (gpgme_ctx_t ctx, int offline)
481 : {
482 0 : TRACE2 (DEBUG_CTX, "gpgme_set_offline", ctx, "offline=%i (%s)",
483 : offline, offline ? "yes" : "no");
484 :
485 0 : if (!ctx)
486 0 : return;
487 :
488 0 : ctx->offline = offline;
489 : }
490 :
491 : /* Return the state of the offline flag. */
492 : int
493 0 : gpgme_get_offline (gpgme_ctx_t ctx)
494 : {
495 0 : TRACE2 (DEBUG_CTX, "gpgme_get_offline", ctx, "ctx->offline=%i (%s)",
496 : ctx->offline, ctx->offline ? "yes" : "no");
497 0 : return ctx->offline;
498 : }
499 :
500 :
501 : /* Set the number of certifications to include in an S/MIME message.
502 : The default is GPGME_INCLUDE_CERTS_DEFAULT. -1 means all certs,
503 : and -2 means all certs except the root cert. */
504 : void
505 0 : gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs)
506 : {
507 0 : if (!ctx)
508 0 : return;
509 :
510 0 : if (nr_of_certs == GPGME_INCLUDE_CERTS_DEFAULT)
511 0 : ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
512 0 : else if (nr_of_certs < -2)
513 0 : ctx->include_certs = -2;
514 : else
515 0 : ctx->include_certs = nr_of_certs;
516 :
517 0 : TRACE2 (DEBUG_CTX, "gpgme_set_include_certs", ctx, "nr_of_certs=%i%s",
518 : nr_of_certs, nr_of_certs == ctx->include_certs ? "" : " (-2)");
519 : }
520 :
521 :
522 : /* Get the number of certifications to include in an S/MIME
523 : message. */
524 : int
525 0 : gpgme_get_include_certs (gpgme_ctx_t ctx)
526 : {
527 0 : TRACE1 (DEBUG_CTX, "gpgme_get_include_certs", ctx, "ctx->include_certs=%i",
528 : ctx->include_certs);
529 0 : return ctx->include_certs;
530 : }
531 :
532 :
533 : /* This function changes the default behaviour of the keylisting
534 : functions. MODE is a bitwise-OR of the GPGME_KEYLIST_* flags. The
535 : default mode is GPGME_KEYLIST_MODE_LOCAL. */
536 : gpgme_error_t
537 53 : gpgme_set_keylist_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
538 : {
539 53 : TRACE1 (DEBUG_CTX, "gpgme_set_keylist_mode", ctx, "keylist_mode=0x%x",
540 : mode);
541 :
542 53 : if (!ctx)
543 0 : return gpg_error (GPG_ERR_INV_VALUE);
544 :
545 53 : ctx->keylist_mode = mode;
546 53 : return 0;
547 : }
548 :
549 : /* This function returns the default behaviour of the keylisting
550 : functions. */
551 : gpgme_keylist_mode_t
552 53 : gpgme_get_keylist_mode (gpgme_ctx_t ctx)
553 : {
554 53 : TRACE1 (DEBUG_CTX, "gpgme_get_keylist_mode", ctx,
555 : "ctx->keylist_mode=0x%x", ctx->keylist_mode);
556 53 : return ctx->keylist_mode;
557 : }
558 :
559 :
560 : /* Set the pinentry mode for CTX to MODE. */
561 : gpgme_error_t
562 0 : gpgme_set_pinentry_mode (gpgme_ctx_t ctx, gpgme_pinentry_mode_t mode)
563 : {
564 0 : TRACE1 (DEBUG_CTX, "gpgme_set_pinentry_mode", ctx, "pinentry_mode=%u",
565 : (unsigned int)mode);
566 :
567 0 : if (!ctx)
568 0 : return gpg_error (GPG_ERR_INV_VALUE);
569 :
570 0 : switch (mode)
571 : {
572 : case GPGME_PINENTRY_MODE_DEFAULT:
573 : case GPGME_PINENTRY_MODE_ASK:
574 : case GPGME_PINENTRY_MODE_CANCEL:
575 : case GPGME_PINENTRY_MODE_ERROR:
576 : case GPGME_PINENTRY_MODE_LOOPBACK:
577 0 : break;
578 : default:
579 0 : return gpg_error (GPG_ERR_INV_VALUE);
580 : }
581 :
582 0 : ctx->pinentry_mode = mode;
583 0 : return 0;
584 : }
585 :
586 :
587 : /* Get the pinentry mode of CTX. */
588 : gpgme_pinentry_mode_t
589 0 : gpgme_get_pinentry_mode (gpgme_ctx_t ctx)
590 : {
591 0 : TRACE1 (DEBUG_CTX, "gpgme_get_pinentry_mode", ctx,
592 : "ctx->pinentry_mode=%u", (unsigned int)ctx->pinentry_mode);
593 0 : return ctx->pinentry_mode;
594 : }
595 :
596 :
597 : /* This function sets a callback function to be used to pass a
598 : passphrase to gpg. */
599 : void
600 29 : gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
601 : void *cb_value)
602 : {
603 29 : TRACE2 (DEBUG_CTX, "gpgme_set_passphrase_cb", ctx,
604 : "passphrase_cb=%p/%p", cb, cb_value);
605 :
606 29 : if (!ctx)
607 29 : return;
608 :
609 29 : ctx->passphrase_cb = cb;
610 29 : ctx->passphrase_cb_value = cb_value;
611 : }
612 :
613 :
614 : /* This function returns the callback function to be used to pass a
615 : passphrase to the crypto engine. */
616 : void
617 0 : gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *r_cb,
618 : void **r_cb_value)
619 : {
620 0 : TRACE2 (DEBUG_CTX, "gpgme_get_passphrase_cb", ctx,
621 : "ctx->passphrase_cb=%p/%p",
622 : ctx->passphrase_cb, ctx->passphrase_cb_value);
623 0 : if (r_cb)
624 0 : *r_cb = ctx->passphrase_cb;
625 0 : if (r_cb_value)
626 0 : *r_cb_value = ctx->passphrase_cb_value;
627 0 : }
628 :
629 :
630 : /* This function sets a callback function to be used as a progress
631 : indicator. */
632 : void
633 1 : gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb, void *cb_value)
634 : {
635 1 : TRACE2 (DEBUG_CTX, "gpgme_set_progress_cb", ctx, "progress_cb=%p/%p",
636 : cb, cb_value);
637 :
638 1 : if (!ctx)
639 1 : return;
640 :
641 1 : ctx->progress_cb = cb;
642 1 : ctx->progress_cb_value = cb_value;
643 : }
644 :
645 :
646 : /* This function returns the callback function to be used as a
647 : progress indicator. */
648 : void
649 0 : gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
650 : void **r_cb_value)
651 : {
652 0 : TRACE2 (DEBUG_CTX, "gpgme_get_progress_cb", ctx, "ctx->progress_cb=%p/%p",
653 : ctx->progress_cb, ctx->progress_cb_value);
654 0 : if (r_cb)
655 0 : *r_cb = ctx->progress_cb;
656 0 : if (r_cb_value)
657 0 : *r_cb_value = ctx->progress_cb_value;
658 0 : }
659 :
660 :
661 : /* This function sets a callback function to be used as a status
662 : message forwarder. */
663 : void
664 0 : gpgme_set_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t cb, void *cb_value)
665 : {
666 0 : TRACE2 (DEBUG_CTX, "gpgme_set_status_cb", ctx, "status_cb=%p/%p",
667 : cb, cb_value);
668 :
669 0 : if (!ctx)
670 0 : return;
671 :
672 0 : ctx->status_cb = cb;
673 0 : ctx->status_cb_value = cb_value;
674 : }
675 :
676 :
677 : /* This function returns the callback function to be used as a
678 : status message forwarder. */
679 : void
680 0 : gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *r_cb,
681 : void **r_cb_value)
682 : {
683 0 : TRACE2 (DEBUG_CTX, "gpgme_get_status_cb", ctx, "ctx->status_cb=%p/%p",
684 : ctx ? ctx->status_cb : NULL, ctx ? ctx->status_cb_value : NULL);
685 :
686 0 : if (r_cb)
687 0 : *r_cb = NULL;
688 :
689 0 : if (r_cb_value)
690 0 : *r_cb_value = NULL;
691 :
692 0 : if (!ctx || !ctx->status_cb)
693 0 : return;
694 :
695 0 : if (r_cb)
696 0 : *r_cb = ctx->status_cb;
697 0 : if (r_cb_value)
698 0 : *r_cb_value = ctx->status_cb_value;
699 : }
700 :
701 :
702 : /* Set the I/O callback functions for CTX to IO_CBS. */
703 : void
704 1 : gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
705 : {
706 1 : if (!ctx)
707 1 : return;
708 :
709 1 : if (io_cbs)
710 : {
711 1 : TRACE6 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
712 : "io_cbs=%p (add=%p/%p, remove=%p, event=%p/%p",
713 : io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
714 : io_cbs->event, io_cbs->event_priv);
715 1 : ctx->io_cbs = *io_cbs;
716 : }
717 : else
718 : {
719 0 : TRACE1 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
720 : "io_cbs=%p (default)", io_cbs);
721 0 : ctx->io_cbs.add = NULL;
722 0 : ctx->io_cbs.add_priv = NULL;
723 0 : ctx->io_cbs.remove = NULL;
724 0 : ctx->io_cbs.event = NULL;
725 0 : ctx->io_cbs.event_priv = NULL;
726 : }
727 : }
728 :
729 :
730 : /* This function provides access to the internal read function; it is
731 : normally not used. */
732 : gpgme_ssize_t
733 0 : gpgme_io_read (int fd, void *buffer, size_t count)
734 : {
735 : int ret;
736 0 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_read", fd,
737 : "buffer=%p, count=%u", buffer, count);
738 :
739 0 : ret = _gpgme_io_read (fd, buffer, count);
740 :
741 0 : return TRACE_SYSRES (ret);
742 : }
743 :
744 :
745 : /* This function provides access to the internal write function. It
746 : is to be used by user callbacks to return data to gpgme. See
747 : gpgme_passphrase_cb_t and gpgme_edit_cb_t. */
748 : gpgme_ssize_t
749 14 : gpgme_io_write (int fd, const void *buffer, size_t count)
750 : {
751 : int ret;
752 14 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_write", fd,
753 : "buffer=%p, count=%u", buffer, count);
754 :
755 14 : ret = _gpgme_io_write (fd, buffer, count);
756 :
757 14 : return TRACE_SYSRES (ret);
758 : }
759 :
760 : /* This function provides access to the internal write function. It
761 : is to be used by user callbacks to return data to gpgme. See
762 : gpgme_passphrase_cb_t and gpgme_edit_cb_t. Note that this is a
763 : variant of gpgme_io_write which guarantees that all COUNT bytes are
764 : written or an error is return. Returns: 0 on success or -1 on
765 : error and the sets errno. */
766 : int
767 0 : gpgme_io_writen (int fd, const void *buffer_arg, size_t count)
768 : {
769 0 : const char *buffer = buffer_arg;
770 0 : int ret = 0;
771 0 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_writen", fd,
772 : "buffer=%p, count=%u", buffer, count);
773 0 : while (count)
774 : {
775 0 : ret = _gpgme_io_write (fd, buffer, count);
776 0 : if (ret < 0)
777 0 : break;
778 0 : buffer += ret;
779 0 : count -= ret;
780 0 : ret = 0;
781 : }
782 0 : return TRACE_SYSRES (ret);
783 : }
784 :
785 :
786 : /* This function returns the callback function for I/O. */
787 : void
788 0 : gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
789 : {
790 0 : TRACE6 (DEBUG_CTX, "gpgme_get_io_cbs", ctx,
791 : "io_cbs=%p, ctx->io_cbs.add=%p/%p, .remove=%p, .event=%p/%p",
792 : io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
793 : io_cbs->event, io_cbs->event_priv);
794 :
795 0 : *io_cbs = ctx->io_cbs;
796 0 : }
797 :
798 :
799 : /* This function sets the locale for the context CTX, or the default
800 : locale if CTX is a null pointer. */
801 : gpgme_error_t
802 94 : gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
803 : {
804 94 : int failed = 0;
805 94 : char *new_lc_ctype = NULL;
806 94 : char *new_lc_messages = NULL;
807 :
808 94 : TRACE_BEG2 (DEBUG_CTX, "gpgme_set_locale", ctx,
809 : "category=%i, value=%s", category, value ? value : "(null)");
810 :
811 : #define PREPARE_ONE_LOCALE(lcat, ucat) \
812 : if (!failed && value \
813 : && (category == LC_ALL || category == LC_ ## ucat)) \
814 : { \
815 : new_lc_ ## lcat = strdup (value); \
816 : if (!new_lc_ ## lcat) \
817 : failed = 1; \
818 : }
819 :
820 : #ifdef LC_CTYPE
821 94 : PREPARE_ONE_LOCALE (ctype, CTYPE);
822 : #endif
823 : #ifdef LC_MESSAGES
824 94 : PREPARE_ONE_LOCALE (messages, MESSAGES);
825 : #endif
826 :
827 94 : if (failed)
828 : {
829 0 : int saved_err = gpg_error_from_syserror ();
830 :
831 0 : if (new_lc_ctype)
832 0 : free (new_lc_ctype);
833 0 : if (new_lc_messages)
834 0 : free (new_lc_messages);
835 :
836 0 : return TRACE_ERR (saved_err);
837 : }
838 :
839 : #define SET_ONE_LOCALE(lcat, ucat) \
840 : if (category == LC_ALL || category == LC_ ## ucat) \
841 : { \
842 : if (ctx) \
843 : { \
844 : if (ctx->lc_ ## lcat) \
845 : free (ctx->lc_ ## lcat); \
846 : ctx->lc_ ## lcat = new_lc_ ## lcat; \
847 : } \
848 : else \
849 : { \
850 : if (def_lc_ ## lcat) \
851 : free (def_lc_ ## lcat); \
852 : def_lc_ ## lcat = new_lc_ ## lcat; \
853 : } \
854 : }
855 :
856 94 : if (!ctx)
857 94 : LOCK (def_lc_lock);
858 : #ifdef LC_CTYPE
859 94 : SET_ONE_LOCALE (ctype, CTYPE);
860 : #endif
861 : #ifdef LC_MESSAGES
862 94 : SET_ONE_LOCALE (messages, MESSAGES);
863 : #endif
864 94 : if (!ctx)
865 94 : UNLOCK (def_lc_lock);
866 :
867 94 : return TRACE_ERR (0);
868 : }
869 :
870 :
871 : /* Get the information about the configured engines. A pointer to the
872 : first engine in the statically allocated linked list is returned.
873 : The returned data is valid until the next gpgme_ctx_set_engine_info. */
874 : gpgme_engine_info_t
875 52 : gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
876 : {
877 52 : TRACE1 (DEBUG_CTX, "gpgme_ctx_get_engine_info", ctx,
878 : "ctx->engine_info=%p", ctx->engine_info);
879 52 : return ctx->engine_info;
880 : }
881 :
882 :
883 : /* Set the engine info for the context CTX, protocol PROTO, to the
884 : file name FILE_NAME and the home directory HOME_DIR. */
885 : gpgme_error_t
886 52 : gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
887 : const char *file_name, const char *home_dir)
888 : {
889 : gpgme_error_t err;
890 52 : TRACE_BEG4 (DEBUG_CTX, "gpgme_ctx_set_engine_info", ctx,
891 : "protocol=%i (%s), file_name=%s, home_dir=%s",
892 : proto, gpgme_get_protocol_name (proto)
893 : ? gpgme_get_protocol_name (proto) : "unknown",
894 : file_name ? file_name : "(default)",
895 : home_dir ? home_dir : "(default)");
896 :
897 52 : if (!ctx)
898 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
899 :
900 : /* Shut down the engine when changing engine info. */
901 52 : if (ctx->engine)
902 : {
903 0 : TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
904 0 : _gpgme_engine_release (ctx->engine);
905 0 : ctx->engine = NULL;
906 : }
907 52 : err = _gpgme_set_engine_info (ctx->engine_info, proto,
908 : file_name, home_dir);
909 52 : return TRACE_ERR (err);
910 : }
911 :
912 :
913 : /* Clear all notation data from the context. */
914 : void
915 117 : _gpgme_sig_notation_clear (gpgme_ctx_t ctx)
916 : {
917 : gpgme_sig_notation_t notation;
918 :
919 117 : if (!ctx)
920 117 : return;
921 :
922 117 : notation = ctx->sig_notations;
923 237 : while (notation)
924 : {
925 3 : gpgme_sig_notation_t next_notation = notation->next;
926 3 : _gpgme_sig_notation_free (notation);
927 3 : notation = next_notation;
928 : }
929 117 : ctx->sig_notations = NULL;
930 : }
931 :
932 : void
933 0 : gpgme_sig_notation_clear (gpgme_ctx_t ctx)
934 : {
935 0 : TRACE (DEBUG_CTX, "gpgme_sig_notation_clear", ctx);
936 :
937 0 : if (!ctx)
938 0 : return;
939 :
940 0 : _gpgme_sig_notation_clear (ctx);
941 : }
942 :
943 :
944 : /* Add the human-readable notation data with name NAME and value VALUE
945 : to the context CTX, using the flags FLAGS. If NAME is NULL, then
946 : VALUE should be a policy URL. The flag
947 : GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
948 : data, and false for policy URLs. */
949 : gpgme_error_t
950 3 : gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
951 : const char *value, gpgme_sig_notation_flags_t flags)
952 : {
953 : gpgme_error_t err;
954 : gpgme_sig_notation_t notation;
955 : gpgme_sig_notation_t *lastp;
956 :
957 3 : TRACE_BEG3 (DEBUG_CTX, "gpgme_sig_notation_add", ctx,
958 : "name=%s, value=%s, flags=0x%x",
959 : name ? name : "(null)", value ? value : "(null)",
960 : flags);
961 :
962 3 : if (!ctx)
963 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
964 :
965 3 : if (name)
966 2 : flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
967 : else
968 1 : flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
969 :
970 6 : err = _gpgme_sig_notation_create (¬ation, name, name ? strlen (name) : 0,
971 3 : value, value ? strlen (value) : 0, flags);
972 3 : if (err)
973 0 : return TRACE_ERR (err);
974 :
975 3 : lastp = &ctx->sig_notations;
976 9 : while (*lastp)
977 3 : lastp = &(*lastp)->next;
978 :
979 3 : *lastp = notation;
980 3 : return TRACE_ERR (0);
981 : }
982 :
983 :
984 : /* Get the sig notations for this context. */
985 : gpgme_sig_notation_t
986 9 : gpgme_sig_notation_get (gpgme_ctx_t ctx)
987 : {
988 9 : if (!ctx)
989 : {
990 0 : TRACE (DEBUG_CTX, "gpgme_sig_notation_get", ctx);
991 0 : return NULL;
992 : }
993 9 : TRACE1 (DEBUG_CTX, "gpgme_sig_notation_get", ctx,
994 : "ctx->sig_notations=%p", ctx->sig_notations);
995 :
996 9 : return ctx->sig_notations;
997 : }
998 :
999 :
1000 :
1001 : /* Return a public key algorithm string made of the algorithm and size
1002 : or the curve name. May return NULL on error. Caller must free the
1003 : result using gpgme_free. */
1004 : char *
1005 0 : gpgme_pubkey_algo_string (gpgme_subkey_t subkey)
1006 : {
1007 0 : const char *prefix = NULL;
1008 : char *result;
1009 :
1010 0 : if (!subkey)
1011 : {
1012 0 : gpg_err_set_errno (EINVAL);
1013 0 : return NULL;
1014 : }
1015 :
1016 0 : switch (subkey->pubkey_algo)
1017 : {
1018 : case GPGME_PK_RSA:
1019 : case GPGME_PK_RSA_E:
1020 0 : case GPGME_PK_RSA_S: prefix = "rsa"; break;
1021 0 : case GPGME_PK_ELG_E: prefix = "elg"; break;
1022 0 : case GPGME_PK_DSA: prefix = "dsa"; break;
1023 0 : case GPGME_PK_ELG: prefix = "xxx"; break;
1024 : case GPGME_PK_ECC:
1025 : case GPGME_PK_ECDH:
1026 : case GPGME_PK_ECDSA:
1027 0 : case GPGME_PK_EDDSA: prefix = ""; break;
1028 : }
1029 :
1030 0 : if (prefix && *prefix)
1031 0 : {
1032 : char buffer[40];
1033 0 : snprintf (buffer, sizeof buffer, "%s%u", prefix, subkey->length);
1034 0 : result = strdup (buffer);
1035 : }
1036 0 : else if (prefix && subkey->curve && *subkey->curve)
1037 0 : result = strdup (subkey->curve);
1038 0 : else if (prefix)
1039 0 : result = strdup ("E_error");
1040 : else
1041 0 : result = strdup ("unknown");
1042 :
1043 0 : return result;
1044 : }
1045 :
1046 :
1047 : const char *
1048 7 : gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
1049 : {
1050 7 : switch (algo)
1051 : {
1052 1 : case GPGME_PK_RSA: return "RSA";
1053 0 : case GPGME_PK_RSA_E: return "RSA-E";
1054 0 : case GPGME_PK_RSA_S: return "RSA-S";
1055 0 : case GPGME_PK_ELG_E: return "ELG-E";
1056 4 : case GPGME_PK_DSA: return "DSA";
1057 0 : case GPGME_PK_ECC: return "ECC";
1058 0 : case GPGME_PK_ELG: return "ELG";
1059 0 : case GPGME_PK_ECDSA: return "ECDSA";
1060 0 : case GPGME_PK_ECDH: return "ECDH";
1061 0 : case GPGME_PK_EDDSA: return "EdDSA";
1062 2 : default: return NULL;
1063 : }
1064 : }
1065 :
1066 :
1067 : const char *
1068 7 : gpgme_hash_algo_name (gpgme_hash_algo_t algo)
1069 : {
1070 7 : switch (algo)
1071 : {
1072 : case GPGME_MD_MD5:
1073 0 : return "MD5";
1074 :
1075 : case GPGME_MD_SHA1:
1076 5 : return "SHA1";
1077 :
1078 : case GPGME_MD_RMD160:
1079 0 : return "RIPEMD160";
1080 :
1081 : case GPGME_MD_MD2:
1082 0 : return "MD2";
1083 :
1084 : case GPGME_MD_TIGER:
1085 0 : return "TIGER192";
1086 :
1087 : case GPGME_MD_HAVAL:
1088 0 : return "HAVAL";
1089 :
1090 : case GPGME_MD_SHA256:
1091 0 : return "SHA256";
1092 :
1093 : case GPGME_MD_SHA384:
1094 0 : return "SHA384";
1095 :
1096 : case GPGME_MD_SHA512:
1097 0 : return "SHA512";
1098 :
1099 : case GPGME_MD_SHA224:
1100 0 : return "SHA224";
1101 :
1102 : case GPGME_MD_MD4:
1103 0 : return "MD4";
1104 :
1105 : case GPGME_MD_CRC32:
1106 0 : return "CRC32";
1107 :
1108 : case GPGME_MD_CRC32_RFC1510:
1109 0 : return "CRC32RFC1510";
1110 :
1111 : case GPGME_MD_CRC24_RFC2440:
1112 0 : return "CRC24RFC2440";
1113 :
1114 : default:
1115 2 : return NULL;
1116 : }
1117 : }
|