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