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 362 : gpgme_new (gpgme_ctx_t *r_ctx)
93 : {
94 : gpgme_error_t err;
95 : gpgme_ctx_t ctx;
96 362 : TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
97 :
98 362 : if (_gpgme_selftest)
99 0 : return TRACE_ERR (_gpgme_selftest);
100 :
101 362 : if (!r_ctx)
102 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
103 :
104 362 : ctx = calloc (1, sizeof *ctx);
105 362 : if (!ctx)
106 0 : return TRACE_ERR (gpg_error_from_syserror ());
107 :
108 362 : INIT_LOCK (ctx->lock);
109 :
110 362 : err = _gpgme_engine_info_copy (&ctx->engine_info);
111 360 : if (!err && !ctx->engine_info)
112 0 : err = gpg_error (GPG_ERR_NO_ENGINE);
113 361 : if (err)
114 : {
115 0 : free (ctx);
116 0 : return TRACE_ERR (err);
117 : }
118 :
119 361 : ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
120 361 : ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
121 361 : ctx->protocol = GPGME_PROTOCOL_OpenPGP;
122 361 : ctx->sub_protocol = GPGME_PROTOCOL_DEFAULT;
123 361 : _gpgme_fd_table_init (&ctx->fdt);
124 :
125 360 : LOCK (def_lc_lock);
126 360 : if (def_lc_ctype)
127 : {
128 167 : ctx->lc_ctype = strdup (def_lc_ctype);
129 167 : 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 193 : def_lc_ctype = NULL;
140 :
141 360 : if (def_lc_messages)
142 : {
143 167 : ctx->lc_messages = strdup (def_lc_messages);
144 167 : 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 193 : def_lc_messages = NULL;
157 360 : UNLOCK (def_lc_lock);
158 :
159 360 : *r_ctx = ctx;
160 :
161 360 : return TRACE_SUC1 ("ctx=%p", ctx);
162 : }
163 :
164 :
165 : gpgme_error_t
166 28 : _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 28 : TRACE_BEG2 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i, op_err=%i",
173 : ctx_err, op_err);
174 :
175 28 : if (ctx_err)
176 : {
177 24 : err = _gpgme_engine_cancel (ctx->engine);
178 24 : if (err)
179 0 : return TRACE_ERR (err);
180 : }
181 : else
182 : {
183 4 : err = _gpgme_engine_cancel_op (ctx->engine);
184 4 : if (err)
185 0 : return TRACE_ERR (err);
186 : }
187 :
188 28 : data.err = ctx_err;
189 28 : data.op_err = op_err;
190 :
191 28 : _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data);
192 :
193 28 : 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 14 : gpgme_cancel_async (gpgme_ctx_t ctx)
217 : {
218 14 : TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx);
219 :
220 14 : if (!ctx)
221 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
222 :
223 14 : LOCK (ctx->lock);
224 14 : ctx->canceled = 1;
225 14 : UNLOCK (ctx->lock);
226 :
227 14 : return TRACE_ERR (0);
228 : }
229 :
230 :
231 : /* Release all resources associated with the given context. */
232 : void
233 405 : gpgme_release (gpgme_ctx_t ctx)
234 : {
235 405 : TRACE (DEBUG_CTX, "gpgme_release", ctx);
236 :
237 405 : if (!ctx)
238 406 : return;
239 :
240 405 : _gpgme_engine_release (ctx->engine);
241 404 : ctx->engine = NULL;
242 404 : _gpgme_fd_table_deinit (&ctx->fdt);
243 404 : _gpgme_release_result (ctx);
244 404 : _gpgme_signers_clear (ctx);
245 404 : _gpgme_sig_notation_clear (ctx);
246 404 : free (ctx->sender);
247 404 : free (ctx->signers);
248 404 : free (ctx->lc_ctype);
249 404 : free (ctx->lc_messages);
250 404 : free (ctx->override_session_key);
251 404 : _gpgme_engine_info_release (ctx->engine_info);
252 404 : ctx->engine_info = NULL;
253 404 : DESTROY_LOCK (ctx->lock);
254 406 : 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 671 : gpgme_result_unref (void *result)
278 : {
279 : struct ctx_op_data *data;
280 :
281 671 : if (! result)
282 0 : return;
283 :
284 671 : data = (void*)((char*)result - sizeof (struct ctx_op_data));
285 :
286 671 : assert (data->magic == CTX_OP_DATA_MAGIC);
287 :
288 671 : LOCK (result_ref_lock);
289 671 : if (--data->references)
290 : {
291 0 : UNLOCK (result_ref_lock);
292 0 : return;
293 : }
294 671 : UNLOCK (result_ref_lock);
295 :
296 671 : if (data->cleanup)
297 637 : (*data->cleanup) (data->hook);
298 671 : free (data);
299 : }
300 :
301 :
302 : void
303 895 : _gpgme_release_result (gpgme_ctx_t ctx)
304 : {
305 895 : struct ctx_op_data *data = ctx->op_data;
306 :
307 2461 : while (data)
308 : {
309 671 : struct ctx_op_data *next_data = data->next;
310 671 : data->next = NULL;
311 671 : gpgme_result_unref (data->hook);
312 671 : data = next_data;
313 : }
314 895 : ctx->op_data = NULL;
315 895 : }
316 :
317 :
318 : gpgme_error_t
319 251 : gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
320 : {
321 251 : 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 251 : if (protocol != GPGME_PROTOCOL_OpenPGP
326 10 : && protocol != GPGME_PROTOCOL_CMS
327 2 : && protocol != GPGME_PROTOCOL_GPGCONF
328 2 : && 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 251 : if (!ctx)
335 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
336 :
337 251 : if (ctx->protocol != protocol)
338 : {
339 : /* Shut down the engine when switching protocols. */
340 10 : if (ctx->engine)
341 : {
342 0 : TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
343 0 : _gpgme_engine_release (ctx->engine);
344 0 : ctx->engine = NULL;
345 : }
346 :
347 10 : ctx->protocol = protocol;
348 : }
349 251 : return TRACE_ERR (0);
350 : }
351 :
352 :
353 : gpgme_protocol_t
354 127 : gpgme_get_protocol (gpgme_ctx_t ctx)
355 : {
356 127 : 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 127 : 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 986 : gpgme_get_protocol_name (gpgme_protocol_t protocol)
394 : {
395 986 : switch (protocol)
396 : {
397 : case GPGME_PROTOCOL_OpenPGP:
398 962 : 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 4 : 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 149 : gpgme_set_armor (gpgme_ctx_t ctx, int use_armor)
468 : {
469 149 : TRACE2 (DEBUG_CTX, "gpgme_set_armor", ctx, "use_armor=%i (%s)",
470 : use_armor, use_armor ? "yes" : "no");
471 :
472 149 : if (!ctx)
473 149 : return;
474 :
475 149 : 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, "full-status"))
512 : {
513 4 : ctx->full_status = abool;
514 : }
515 0 : else if (!strcmp (name, "raw-description"))
516 : {
517 0 : ctx->raw_description = abool;
518 : }
519 0 : else if (!strcmp (name, "export-session-key"))
520 : {
521 0 : ctx->export_session_keys = abool;
522 : }
523 0 : else if (!strcmp (name, "override-session-key"))
524 : {
525 0 : free (ctx->override_session_key);
526 0 : ctx->override_session_key = strdup (value);
527 0 : if (!ctx->override_session_key)
528 0 : err = gpg_error_from_syserror ();
529 : }
530 : else
531 0 : err = gpg_error (GPG_ERR_UNKNOWN_NAME);
532 :
533 4 : return err;
534 : }
535 :
536 :
537 : /* Get the context flag named NAME. See gpgme_set_ctx_flag for a list
538 : * of valid names. If the NAME is unknown NULL is returned. For a
539 : * boolean flag an empty string is returned for False and the string
540 : * "1" for True; thus either atoi or a simple string test can be
541 : * used. */
542 : const char *
543 0 : gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
544 : {
545 0 : if (!ctx || !name)
546 0 : return NULL;
547 0 : else if (!strcmp (name, "full-status"))
548 : {
549 0 : return ctx->full_status? "1":"";
550 : }
551 0 : else if (!strcmp (name, "raw-description"))
552 : {
553 0 : return ctx->raw_description? "1":"";
554 : }
555 0 : else if (!strcmp (name, "export-session-key"))
556 : {
557 0 : return ctx->export_session_keys? "1":"";
558 : }
559 0 : else if (!strcmp (name, "override-session-key"))
560 : {
561 0 : return ctx->override_session_key? ctx->override_session_key : "";
562 : }
563 : else
564 0 : return NULL;
565 : }
566 :
567 :
568 : /* Enable or disable the use of the special textmode. Textmode is for
569 : example used for the RFC2015 signatures; note that the updated RFC
570 : 3156 mandates that the MUA does some preparations so that textmode
571 : is not needed anymore. */
572 : void
573 108 : gpgme_set_textmode (gpgme_ctx_t ctx, int use_textmode)
574 : {
575 108 : TRACE2 (DEBUG_CTX, "gpgme_set_textmode", ctx, "use_textmode=%i (%s)",
576 : use_textmode, use_textmode ? "yes" : "no");
577 :
578 108 : if (!ctx)
579 108 : return;
580 :
581 108 : ctx->use_textmode = !!use_textmode;
582 : }
583 :
584 : /* Return the state of the textmode flag. */
585 : int
586 0 : gpgme_get_textmode (gpgme_ctx_t ctx)
587 : {
588 0 : TRACE2 (DEBUG_CTX, "gpgme_get_textmode", ctx, "ctx->use_textmode=%i (%s)",
589 : ctx->use_textmode, ctx->use_textmode ? "yes" : "no");
590 0 : return ctx->use_textmode;
591 : }
592 :
593 :
594 : /* Enable offline mode for this context. In offline mode dirmngr
595 : will be disabled. */
596 : void
597 87 : gpgme_set_offline (gpgme_ctx_t ctx, int offline)
598 : {
599 87 : TRACE2 (DEBUG_CTX, "gpgme_set_offline", ctx, "offline=%i (%s)",
600 : offline, offline ? "yes" : "no");
601 :
602 87 : if (!ctx)
603 87 : return;
604 :
605 87 : ctx->offline = !!offline;
606 : }
607 :
608 : /* Return the state of the offline flag. */
609 : int
610 0 : gpgme_get_offline (gpgme_ctx_t ctx)
611 : {
612 0 : TRACE2 (DEBUG_CTX, "gpgme_get_offline", ctx, "ctx->offline=%i (%s)",
613 : ctx->offline, ctx->offline ? "yes" : "no");
614 0 : return ctx->offline;
615 : }
616 :
617 :
618 : /* Set the number of certifications to include in an S/MIME message.
619 : The default is GPGME_INCLUDE_CERTS_DEFAULT. -1 means all certs,
620 : and -2 means all certs except the root cert. */
621 : void
622 0 : gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs)
623 : {
624 0 : if (!ctx)
625 0 : return;
626 :
627 0 : if (nr_of_certs == GPGME_INCLUDE_CERTS_DEFAULT)
628 0 : ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
629 0 : else if (nr_of_certs < -2)
630 0 : ctx->include_certs = -2;
631 : else
632 0 : ctx->include_certs = nr_of_certs;
633 :
634 0 : TRACE2 (DEBUG_CTX, "gpgme_set_include_certs", ctx, "nr_of_certs=%i%s",
635 : nr_of_certs, nr_of_certs == ctx->include_certs ? "" : " (-2)");
636 : }
637 :
638 :
639 : /* Get the number of certifications to include in an S/MIME
640 : message. */
641 : int
642 0 : gpgme_get_include_certs (gpgme_ctx_t ctx)
643 : {
644 0 : TRACE1 (DEBUG_CTX, "gpgme_get_include_certs", ctx, "ctx->include_certs=%i",
645 : ctx->include_certs);
646 0 : return ctx->include_certs;
647 : }
648 :
649 :
650 : /* This function changes the default behaviour of the keylisting
651 : functions. MODE is a bitwise-OR of the GPGME_KEYLIST_* flags. The
652 : default mode is GPGME_KEYLIST_MODE_LOCAL. */
653 : gpgme_error_t
654 136 : gpgme_set_keylist_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
655 : {
656 136 : TRACE1 (DEBUG_CTX, "gpgme_set_keylist_mode", ctx, "keylist_mode=0x%x",
657 : mode);
658 :
659 136 : if (!ctx)
660 0 : return gpg_error (GPG_ERR_INV_VALUE);
661 :
662 136 : ctx->keylist_mode = mode;
663 136 : return 0;
664 : }
665 :
666 : /* This function returns the default behaviour of the keylisting
667 : functions. */
668 : gpgme_keylist_mode_t
669 129 : gpgme_get_keylist_mode (gpgme_ctx_t ctx)
670 : {
671 129 : TRACE1 (DEBUG_CTX, "gpgme_get_keylist_mode", ctx,
672 : "ctx->keylist_mode=0x%x", ctx->keylist_mode);
673 129 : return ctx->keylist_mode;
674 : }
675 :
676 :
677 : /* Set the pinentry mode for CTX to MODE. */
678 : gpgme_error_t
679 128 : gpgme_set_pinentry_mode (gpgme_ctx_t ctx, gpgme_pinentry_mode_t mode)
680 : {
681 128 : TRACE1 (DEBUG_CTX, "gpgme_set_pinentry_mode", ctx, "pinentry_mode=%u",
682 : (unsigned int)mode);
683 :
684 128 : if (!ctx)
685 0 : return gpg_error (GPG_ERR_INV_VALUE);
686 :
687 128 : switch (mode)
688 : {
689 : case GPGME_PINENTRY_MODE_DEFAULT:
690 : case GPGME_PINENTRY_MODE_ASK:
691 : case GPGME_PINENTRY_MODE_CANCEL:
692 : case GPGME_PINENTRY_MODE_ERROR:
693 : case GPGME_PINENTRY_MODE_LOOPBACK:
694 128 : break;
695 : default:
696 0 : return gpg_error (GPG_ERR_INV_VALUE);
697 : }
698 :
699 128 : ctx->pinentry_mode = mode;
700 128 : return 0;
701 : }
702 :
703 :
704 : /* Get the pinentry mode of CTX. */
705 : gpgme_pinentry_mode_t
706 8 : gpgme_get_pinentry_mode (gpgme_ctx_t ctx)
707 : {
708 8 : TRACE1 (DEBUG_CTX, "gpgme_get_pinentry_mode", ctx,
709 : "ctx->pinentry_mode=%u", (unsigned int)ctx->pinentry_mode);
710 8 : return ctx->pinentry_mode;
711 : }
712 :
713 :
714 : /* This function sets a callback function to be used to pass a
715 : passphrase to gpg. */
716 : void
717 160 : gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
718 : void *cb_value)
719 : {
720 160 : TRACE2 (DEBUG_CTX, "gpgme_set_passphrase_cb", ctx,
721 : "passphrase_cb=%p/%p", cb, cb_value);
722 :
723 160 : if (!ctx)
724 160 : return;
725 :
726 160 : ctx->passphrase_cb = cb;
727 160 : ctx->passphrase_cb_value = cb_value;
728 : }
729 :
730 :
731 : /* This function returns the callback function to be used to pass a
732 : passphrase to the crypto engine. */
733 : void
734 0 : gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *r_cb,
735 : void **r_cb_value)
736 : {
737 0 : TRACE2 (DEBUG_CTX, "gpgme_get_passphrase_cb", ctx,
738 : "ctx->passphrase_cb=%p/%p",
739 : ctx->passphrase_cb, ctx->passphrase_cb_value);
740 0 : if (r_cb)
741 0 : *r_cb = ctx->passphrase_cb;
742 0 : if (r_cb_value)
743 0 : *r_cb_value = ctx->passphrase_cb_value;
744 0 : }
745 :
746 :
747 : /* This function sets a callback function to be used as a progress
748 : indicator. */
749 : void
750 120 : gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb, void *cb_value)
751 : {
752 120 : TRACE2 (DEBUG_CTX, "gpgme_set_progress_cb", ctx, "progress_cb=%p/%p",
753 : cb, cb_value);
754 :
755 120 : if (!ctx)
756 120 : return;
757 :
758 120 : ctx->progress_cb = cb;
759 120 : ctx->progress_cb_value = cb_value;
760 : }
761 :
762 :
763 : /* This function returns the callback function to be used as a
764 : progress indicator. */
765 : void
766 0 : gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
767 : void **r_cb_value)
768 : {
769 0 : TRACE2 (DEBUG_CTX, "gpgme_get_progress_cb", ctx, "ctx->progress_cb=%p/%p",
770 : ctx->progress_cb, ctx->progress_cb_value);
771 0 : if (r_cb)
772 0 : *r_cb = ctx->progress_cb;
773 0 : if (r_cb_value)
774 0 : *r_cb_value = ctx->progress_cb_value;
775 0 : }
776 :
777 :
778 : /* This function sets a callback function to be used as a status
779 : message forwarder. */
780 : void
781 83 : gpgme_set_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t cb, void *cb_value)
782 : {
783 83 : TRACE2 (DEBUG_CTX, "gpgme_set_status_cb", ctx, "status_cb=%p/%p",
784 : cb, cb_value);
785 :
786 83 : if (!ctx)
787 83 : return;
788 :
789 83 : ctx->status_cb = cb;
790 83 : ctx->status_cb_value = cb_value;
791 : }
792 :
793 :
794 : /* This function returns the callback function to be used as a
795 : status message forwarder. */
796 : void
797 0 : gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *r_cb,
798 : void **r_cb_value)
799 : {
800 0 : TRACE2 (DEBUG_CTX, "gpgme_get_status_cb", ctx, "ctx->status_cb=%p/%p",
801 : ctx ? ctx->status_cb : NULL, ctx ? ctx->status_cb_value : NULL);
802 :
803 0 : if (r_cb)
804 0 : *r_cb = NULL;
805 :
806 0 : if (r_cb_value)
807 0 : *r_cb_value = NULL;
808 :
809 0 : if (!ctx || !ctx->status_cb)
810 0 : return;
811 :
812 0 : if (r_cb)
813 0 : *r_cb = ctx->status_cb;
814 0 : if (r_cb_value)
815 0 : *r_cb_value = ctx->status_cb_value;
816 : }
817 :
818 :
819 : /* Set the I/O callback functions for CTX to IO_CBS. */
820 : void
821 1 : gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
822 : {
823 1 : if (!ctx)
824 1 : return;
825 :
826 1 : if (io_cbs)
827 : {
828 1 : TRACE6 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
829 : "io_cbs=%p (add=%p/%p, remove=%p, event=%p/%p",
830 : io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
831 : io_cbs->event, io_cbs->event_priv);
832 1 : ctx->io_cbs = *io_cbs;
833 : }
834 : else
835 : {
836 0 : TRACE1 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
837 : "io_cbs=%p (default)", io_cbs);
838 0 : ctx->io_cbs.add = NULL;
839 0 : ctx->io_cbs.add_priv = NULL;
840 0 : ctx->io_cbs.remove = NULL;
841 0 : ctx->io_cbs.event = NULL;
842 0 : ctx->io_cbs.event_priv = NULL;
843 : }
844 : }
845 :
846 :
847 : /* This function provides access to the internal read function; it is
848 : normally not used. */
849 : gpgme_ssize_t
850 0 : gpgme_io_read (int fd, void *buffer, size_t count)
851 : {
852 : int ret;
853 0 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_read", fd,
854 : "buffer=%p, count=%u", buffer, count);
855 :
856 0 : ret = _gpgme_io_read (fd, buffer, count);
857 :
858 0 : return TRACE_SYSRES (ret);
859 : }
860 :
861 :
862 : /* This function provides access to the internal write function. It
863 : is to be used by user callbacks to return data to gpgme. See
864 : gpgme_passphrase_cb_t and gpgme_edit_cb_t. */
865 : gpgme_ssize_t
866 22 : gpgme_io_write (int fd, const void *buffer, size_t count)
867 : {
868 : int ret;
869 22 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_write", fd,
870 : "buffer=%p, count=%u", buffer, count);
871 :
872 22 : ret = _gpgme_io_write (fd, buffer, count);
873 :
874 22 : return TRACE_SYSRES (ret);
875 : }
876 :
877 : /* This function provides access to the internal write function. It
878 : is to be used by user callbacks to return data to gpgme. See
879 : gpgme_passphrase_cb_t and gpgme_edit_cb_t. Note that this is a
880 : variant of gpgme_io_write which guarantees that all COUNT bytes are
881 : written or an error is return. Returns: 0 on success or -1 on
882 : error and the sets errno. */
883 : int
884 14 : gpgme_io_writen (int fd, const void *buffer_arg, size_t count)
885 : {
886 14 : const char *buffer = buffer_arg;
887 14 : int ret = 0;
888 14 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_writen", fd,
889 : "buffer=%p, count=%u", buffer, count);
890 42 : while (count)
891 : {
892 14 : ret = _gpgme_io_write (fd, buffer, count);
893 14 : if (ret < 0)
894 0 : break;
895 14 : buffer += ret;
896 14 : count -= ret;
897 14 : ret = 0;
898 : }
899 14 : return TRACE_SYSRES (ret);
900 : }
901 :
902 :
903 : /* This function returns the callback function for I/O. */
904 : void
905 0 : gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
906 : {
907 0 : TRACE6 (DEBUG_CTX, "gpgme_get_io_cbs", ctx,
908 : "io_cbs=%p, ctx->io_cbs.add=%p/%p, .remove=%p, .event=%p/%p",
909 : io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
910 : io_cbs->event, io_cbs->event_priv);
911 :
912 0 : *io_cbs = ctx->io_cbs;
913 0 : }
914 :
915 :
916 : /* This function sets the locale for the context CTX, or the default
917 : locale if CTX is a null pointer. */
918 : gpgme_error_t
919 96 : gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
920 : {
921 96 : int failed = 0;
922 96 : char *new_lc_ctype = NULL;
923 96 : char *new_lc_messages = NULL;
924 :
925 96 : TRACE_BEG2 (DEBUG_CTX, "gpgme_set_locale", ctx,
926 : "category=%i, value=%s", category, value ? value : "(null)");
927 :
928 : #define PREPARE_ONE_LOCALE(lcat, ucat) \
929 : if (!failed && value \
930 : && (category == LC_ALL || category == LC_ ## ucat)) \
931 : { \
932 : new_lc_ ## lcat = strdup (value); \
933 : if (!new_lc_ ## lcat) \
934 : failed = 1; \
935 : }
936 :
937 : #ifdef LC_CTYPE
938 96 : PREPARE_ONE_LOCALE (ctype, CTYPE);
939 : #endif
940 : #ifdef LC_MESSAGES
941 96 : PREPARE_ONE_LOCALE (messages, MESSAGES);
942 : #endif
943 :
944 96 : if (failed)
945 : {
946 0 : int saved_err = gpg_error_from_syserror ();
947 :
948 0 : if (new_lc_ctype)
949 0 : free (new_lc_ctype);
950 0 : if (new_lc_messages)
951 0 : free (new_lc_messages);
952 :
953 0 : return TRACE_ERR (saved_err);
954 : }
955 :
956 : #define SET_ONE_LOCALE(lcat, ucat) \
957 : if (category == LC_ALL || category == LC_ ## ucat) \
958 : { \
959 : if (ctx) \
960 : { \
961 : if (ctx->lc_ ## lcat) \
962 : free (ctx->lc_ ## lcat); \
963 : ctx->lc_ ## lcat = new_lc_ ## lcat; \
964 : } \
965 : else \
966 : { \
967 : if (def_lc_ ## lcat) \
968 : free (def_lc_ ## lcat); \
969 : def_lc_ ## lcat = new_lc_ ## lcat; \
970 : } \
971 : }
972 :
973 96 : if (!ctx)
974 96 : LOCK (def_lc_lock);
975 : #ifdef LC_CTYPE
976 96 : SET_ONE_LOCALE (ctype, CTYPE);
977 : #endif
978 : #ifdef LC_MESSAGES
979 96 : SET_ONE_LOCALE (messages, MESSAGES);
980 : #endif
981 96 : if (!ctx)
982 96 : UNLOCK (def_lc_lock);
983 :
984 96 : return TRACE_ERR (0);
985 : }
986 :
987 :
988 : /* Get the information about the configured engines. A pointer to the
989 : first engine in the statically allocated linked list is returned.
990 : The returned data is valid until the next gpgme_ctx_set_engine_info. */
991 : gpgme_engine_info_t
992 118 : gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
993 : {
994 118 : TRACE1 (DEBUG_CTX, "gpgme_ctx_get_engine_info", ctx,
995 : "ctx->engine_info=%p", ctx->engine_info);
996 118 : return ctx->engine_info;
997 : }
998 :
999 :
1000 : /* Set the engine info for the context CTX, protocol PROTO, to the
1001 : file name FILE_NAME and the home directory HOME_DIR. */
1002 : gpgme_error_t
1003 114 : gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
1004 : const char *file_name, const char *home_dir)
1005 : {
1006 : gpgme_error_t err;
1007 114 : TRACE_BEG4 (DEBUG_CTX, "gpgme_ctx_set_engine_info", ctx,
1008 : "protocol=%i (%s), file_name=%s, home_dir=%s",
1009 : proto, gpgme_get_protocol_name (proto)
1010 : ? gpgme_get_protocol_name (proto) : "unknown",
1011 : file_name ? file_name : "(default)",
1012 : home_dir ? home_dir : "(default)");
1013 :
1014 114 : if (!ctx)
1015 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1016 :
1017 : /* Shut down the engine when changing engine info. */
1018 114 : if (ctx->engine)
1019 : {
1020 0 : TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
1021 0 : _gpgme_engine_release (ctx->engine);
1022 0 : ctx->engine = NULL;
1023 : }
1024 114 : err = _gpgme_set_engine_info (ctx->engine_info, proto,
1025 : file_name, home_dir);
1026 116 : return TRACE_ERR (err);
1027 : }
1028 :
1029 :
1030 : /* Clear all notation data from the context. */
1031 : void
1032 405 : _gpgme_sig_notation_clear (gpgme_ctx_t ctx)
1033 : {
1034 : gpgme_sig_notation_t notation;
1035 :
1036 405 : if (!ctx)
1037 405 : return;
1038 :
1039 405 : notation = ctx->sig_notations;
1040 819 : while (notation)
1041 : {
1042 9 : gpgme_sig_notation_t next_notation = notation->next;
1043 9 : _gpgme_sig_notation_free (notation);
1044 9 : notation = next_notation;
1045 : }
1046 405 : ctx->sig_notations = NULL;
1047 : }
1048 :
1049 : void
1050 0 : gpgme_sig_notation_clear (gpgme_ctx_t ctx)
1051 : {
1052 0 : TRACE (DEBUG_CTX, "gpgme_sig_notation_clear", ctx);
1053 :
1054 0 : if (!ctx)
1055 0 : return;
1056 :
1057 0 : _gpgme_sig_notation_clear (ctx);
1058 : }
1059 :
1060 :
1061 : /* Add the human-readable notation data with name NAME and value VALUE
1062 : to the context CTX, using the flags FLAGS. If NAME is NULL, then
1063 : VALUE should be a policy URL. The flag
1064 : GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
1065 : data, and false for policy URLs. */
1066 : gpgme_error_t
1067 9 : gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
1068 : const char *value, gpgme_sig_notation_flags_t flags)
1069 : {
1070 : gpgme_error_t err;
1071 : gpgme_sig_notation_t notation;
1072 : gpgme_sig_notation_t *lastp;
1073 :
1074 9 : TRACE_BEG3 (DEBUG_CTX, "gpgme_sig_notation_add", ctx,
1075 : "name=%s, value=%s, flags=0x%x",
1076 : name ? name : "(null)", value ? value : "(null)",
1077 : flags);
1078 :
1079 9 : if (!ctx)
1080 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1081 :
1082 9 : if (name)
1083 6 : flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
1084 : else
1085 3 : flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
1086 :
1087 18 : err = _gpgme_sig_notation_create (¬ation, name, name ? strlen (name) : 0,
1088 9 : value, value ? strlen (value) : 0, flags);
1089 9 : if (err)
1090 0 : return TRACE_ERR (err);
1091 :
1092 9 : lastp = &ctx->sig_notations;
1093 27 : while (*lastp)
1094 9 : lastp = &(*lastp)->next;
1095 :
1096 9 : *lastp = notation;
1097 9 : return TRACE_ERR (0);
1098 : }
1099 :
1100 :
1101 : /* Get the sig notations for this context. */
1102 : gpgme_sig_notation_t
1103 58 : gpgme_sig_notation_get (gpgme_ctx_t ctx)
1104 : {
1105 58 : if (!ctx)
1106 : {
1107 0 : TRACE (DEBUG_CTX, "gpgme_sig_notation_get", ctx);
1108 0 : return NULL;
1109 : }
1110 58 : TRACE1 (DEBUG_CTX, "gpgme_sig_notation_get", ctx,
1111 : "ctx->sig_notations=%p", ctx->sig_notations);
1112 :
1113 58 : return ctx->sig_notations;
1114 : }
1115 :
1116 :
1117 :
1118 : /* Return a public key algorithm string made of the algorithm and size
1119 : or the curve name. May return NULL on error. Caller must free the
1120 : result using gpgme_free. */
1121 : char *
1122 0 : gpgme_pubkey_algo_string (gpgme_subkey_t subkey)
1123 : {
1124 0 : const char *prefix = NULL;
1125 : char *result;
1126 :
1127 0 : if (!subkey)
1128 : {
1129 0 : gpg_err_set_errno (EINVAL);
1130 0 : return NULL;
1131 : }
1132 :
1133 0 : switch (subkey->pubkey_algo)
1134 : {
1135 : case GPGME_PK_RSA:
1136 : case GPGME_PK_RSA_E:
1137 0 : case GPGME_PK_RSA_S: prefix = "rsa"; break;
1138 0 : case GPGME_PK_ELG_E: prefix = "elg"; break;
1139 0 : case GPGME_PK_DSA: prefix = "dsa"; break;
1140 0 : case GPGME_PK_ELG: prefix = "xxx"; break;
1141 : case GPGME_PK_ECC:
1142 : case GPGME_PK_ECDH:
1143 : case GPGME_PK_ECDSA:
1144 0 : case GPGME_PK_EDDSA: prefix = ""; break;
1145 : }
1146 :
1147 0 : if (prefix && *prefix)
1148 0 : {
1149 : char buffer[40];
1150 0 : snprintf (buffer, sizeof buffer, "%s%u", prefix, subkey->length);
1151 0 : result = strdup (buffer);
1152 : }
1153 0 : else if (prefix && subkey->curve && *subkey->curve)
1154 0 : result = strdup (subkey->curve);
1155 0 : else if (prefix)
1156 0 : result = strdup ("E_error");
1157 : else
1158 0 : result = strdup ("unknown");
1159 :
1160 0 : return result;
1161 : }
1162 :
1163 :
1164 : const char *
1165 99 : gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
1166 : {
1167 99 : switch (algo)
1168 : {
1169 2 : case GPGME_PK_RSA: return "RSA";
1170 1 : case GPGME_PK_RSA_E: return "RSA-E";
1171 1 : case GPGME_PK_RSA_S: return "RSA-S";
1172 1 : case GPGME_PK_ELG_E: return "ELG-E";
1173 83 : case GPGME_PK_DSA: return "DSA";
1174 1 : case GPGME_PK_ECC: return "ECC";
1175 1 : case GPGME_PK_ELG: return "ELG";
1176 1 : case GPGME_PK_ECDSA: return "ECDSA";
1177 1 : case GPGME_PK_ECDH: return "ECDH";
1178 1 : case GPGME_PK_EDDSA: return "EdDSA";
1179 6 : default: return NULL;
1180 : }
1181 : }
1182 :
1183 :
1184 : const char *
1185 89 : gpgme_hash_algo_name (gpgme_hash_algo_t algo)
1186 : {
1187 89 : switch (algo)
1188 : {
1189 : case GPGME_MD_MD5:
1190 0 : return "MD5";
1191 :
1192 : case GPGME_MD_SHA1:
1193 83 : return "SHA1";
1194 :
1195 : case GPGME_MD_RMD160:
1196 0 : return "RIPEMD160";
1197 :
1198 : case GPGME_MD_MD2:
1199 0 : return "MD2";
1200 :
1201 : case GPGME_MD_TIGER:
1202 0 : return "TIGER192";
1203 :
1204 : case GPGME_MD_HAVAL:
1205 0 : return "HAVAL";
1206 :
1207 : case GPGME_MD_SHA256:
1208 0 : return "SHA256";
1209 :
1210 : case GPGME_MD_SHA384:
1211 0 : return "SHA384";
1212 :
1213 : case GPGME_MD_SHA512:
1214 0 : return "SHA512";
1215 :
1216 : case GPGME_MD_SHA224:
1217 0 : return "SHA224";
1218 :
1219 : case GPGME_MD_MD4:
1220 0 : return "MD4";
1221 :
1222 : case GPGME_MD_CRC32:
1223 0 : return "CRC32";
1224 :
1225 : case GPGME_MD_CRC32_RFC1510:
1226 0 : return "CRC32RFC1510";
1227 :
1228 : case GPGME_MD_CRC24_RFC2440:
1229 0 : return "CRC24RFC2440";
1230 :
1231 : default:
1232 6 : return NULL;
1233 : }
1234 : }
|