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