Line data Source code
1 : /* engine.c - GPGME engine support.
2 : Copyright (C) 2000 Werner Koch (dd9jn)
3 : Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009, 2010 g10 Code GmbH
4 :
5 : This file is part of GPGME.
6 :
7 : GPGME is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU Lesser General Public License as
9 : published by the Free Software Foundation; either version 2.1 of
10 : the License, or (at your option) any later version.
11 :
12 : GPGME is distributed in the hope that it will be useful, but
13 : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : Lesser General Public License for more details.
16 :
17 : You should have received a copy of the GNU Lesser General Public
18 : License along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : #include <config.h>
23 : #endif
24 : #include <stdlib.h>
25 : #include <string.h>
26 : #include <errno.h>
27 : #include <assert.h>
28 :
29 : #include "gpgme.h"
30 : #include "util.h"
31 : #include "sema.h"
32 : #include "ops.h"
33 : #include "debug.h"
34 :
35 : #include "engine.h"
36 : #include "engine-backend.h"
37 :
38 :
39 : struct engine
40 : {
41 : struct engine_ops *ops;
42 : void *engine;
43 : };
44 :
45 :
46 : static struct engine_ops *engine_ops[] =
47 : {
48 : &_gpgme_engine_ops_gpg, /* OpenPGP. */
49 : &_gpgme_engine_ops_gpgsm, /* CMS. */
50 : &_gpgme_engine_ops_gpgconf, /* gpg-conf. */
51 : &_gpgme_engine_ops_assuan, /* Low-Level Assuan. */
52 : &_gpgme_engine_ops_g13, /* Crypto VFS. */
53 : #ifdef ENABLE_UISERVER
54 : &_gpgme_engine_ops_uiserver, /* UI-Server. */
55 : #else
56 : NULL,
57 : #endif
58 : &_gpgme_engine_ops_spawn
59 : };
60 :
61 :
62 : /* The engine info. */
63 : static gpgme_engine_info_t engine_info;
64 : DEFINE_STATIC_LOCK (engine_info_lock);
65 :
66 :
67 : /* Get the file name of the engine for PROTOCOL. */
68 : static const char *
69 196 : engine_get_file_name (gpgme_protocol_t proto)
70 : {
71 196 : if (proto > DIM (engine_ops))
72 0 : return NULL;
73 :
74 196 : if (engine_ops[proto] && engine_ops[proto]->get_file_name)
75 196 : return (*engine_ops[proto]->get_file_name) ();
76 : else
77 0 : return NULL;
78 : }
79 :
80 :
81 : /* Get the standard home dir of the engine for PROTOCOL. */
82 : static const char *
83 248 : engine_get_home_dir (gpgme_protocol_t proto)
84 : {
85 248 : if (proto > DIM (engine_ops))
86 0 : return NULL;
87 :
88 248 : if (engine_ops[proto] && engine_ops[proto]->get_home_dir)
89 28 : return (*engine_ops[proto]->get_home_dir) ();
90 : else
91 220 : return NULL;
92 : }
93 :
94 :
95 : /* Get a malloced string containing the version number of the engine
96 : for PROTOCOL. */
97 : static char *
98 220 : engine_get_version (gpgme_protocol_t proto, const char *file_name)
99 : {
100 220 : if (proto > DIM (engine_ops))
101 0 : return NULL;
102 :
103 220 : if (engine_ops[proto] && engine_ops[proto]->get_version)
104 220 : return (*engine_ops[proto]->get_version) (file_name);
105 : else
106 0 : return NULL;
107 : }
108 :
109 :
110 : /* Get the required version number of the engine for PROTOCOL. */
111 : static const char *
112 168 : engine_get_req_version (gpgme_protocol_t proto)
113 : {
114 168 : if (proto > DIM (engine_ops))
115 0 : return NULL;
116 :
117 168 : if (engine_ops[proto] && engine_ops[proto]->get_req_version)
118 168 : return (*engine_ops[proto]->get_req_version) ();
119 : else
120 0 : return NULL;
121 : }
122 :
123 :
124 : /* Verify the version requirement for the engine for PROTOCOL. */
125 : gpgme_error_t
126 48 : gpgme_engine_check_version (gpgme_protocol_t proto)
127 : {
128 : gpgme_error_t err;
129 : gpgme_engine_info_t info;
130 : int result;
131 :
132 48 : LOCK (engine_info_lock);
133 48 : info = engine_info;
134 48 : if (!info)
135 : {
136 : /* Make sure it is initialized. */
137 27 : UNLOCK (engine_info_lock);
138 27 : err = gpgme_get_engine_info (&info);
139 27 : if (err)
140 0 : return err;
141 :
142 27 : LOCK (engine_info_lock);
143 : }
144 :
145 103 : while (info && info->protocol != proto)
146 7 : info = info->next;
147 :
148 48 : if (!info)
149 0 : result = 0;
150 : else
151 48 : result = _gpgme_compare_versions (info->version,
152 48 : info->req_version);
153 :
154 48 : UNLOCK (engine_info_lock);
155 48 : return result ? 0 : trace_gpg_error (GPG_ERR_INV_ENGINE);
156 : }
157 :
158 :
159 : /* Release the engine info INFO. */
160 : void
161 118 : _gpgme_engine_info_release (gpgme_engine_info_t info)
162 : {
163 944 : while (info)
164 : {
165 708 : gpgme_engine_info_t next_info = info->next;
166 :
167 708 : assert (info->file_name);
168 708 : free (info->file_name);
169 708 : if (info->home_dir)
170 118 : free (info->home_dir);
171 708 : if (info->version)
172 708 : free (info->version);
173 708 : free (info);
174 708 : info = next_info;
175 : }
176 118 : }
177 :
178 :
179 : /* Get the information about the configured and installed engines. A
180 : pointer to the first engine in the statically allocated linked list
181 : is returned in *INFO. If an error occurs, it is returned. The
182 : returned data is valid until the next gpgme_set_engine_info. */
183 : gpgme_error_t
184 28 : gpgme_get_engine_info (gpgme_engine_info_t *info)
185 : {
186 : gpgme_error_t err;
187 :
188 28 : LOCK (engine_info_lock);
189 28 : if (!engine_info)
190 : {
191 28 : gpgme_engine_info_t *lastp = &engine_info;
192 28 : gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
193 : GPGME_PROTOCOL_CMS,
194 : GPGME_PROTOCOL_GPGCONF,
195 : GPGME_PROTOCOL_ASSUAN,
196 : GPGME_PROTOCOL_G13,
197 : GPGME_PROTOCOL_UISERVER,
198 : GPGME_PROTOCOL_SPAWN };
199 : unsigned int proto;
200 :
201 28 : err = 0;
202 224 : for (proto = 0; proto < DIM (proto_list); proto++)
203 : {
204 196 : const char *ofile_name = engine_get_file_name (proto_list[proto]);
205 196 : const char *ohome_dir = engine_get_home_dir (proto_list[proto]);
206 : char *file_name;
207 : char *home_dir;
208 :
209 196 : if (!ofile_name)
210 28 : continue;
211 :
212 168 : file_name = strdup (ofile_name);
213 168 : if (!file_name)
214 0 : err = gpg_error_from_syserror ();
215 :
216 168 : if (ohome_dir)
217 : {
218 28 : home_dir = strdup (ohome_dir);
219 28 : if (!home_dir && !err)
220 0 : err = gpg_error_from_syserror ();
221 : }
222 : else
223 140 : home_dir = NULL;
224 :
225 168 : *lastp = malloc (sizeof (*engine_info));
226 168 : if (!*lastp && !err)
227 0 : err = gpg_error_from_syserror ();
228 :
229 168 : if (err)
230 : {
231 0 : _gpgme_engine_info_release (engine_info);
232 0 : engine_info = NULL;
233 :
234 0 : if (file_name)
235 0 : free (file_name);
236 0 : if (home_dir)
237 0 : free (home_dir);
238 :
239 0 : UNLOCK (engine_info_lock);
240 0 : return err;
241 : }
242 :
243 168 : (*lastp)->protocol = proto_list[proto];
244 168 : (*lastp)->file_name = file_name;
245 168 : (*lastp)->home_dir = home_dir;
246 168 : (*lastp)->version = engine_get_version (proto_list[proto], NULL);
247 168 : (*lastp)->req_version = engine_get_req_version (proto_list[proto]);
248 168 : (*lastp)->next = NULL;
249 168 : lastp = &(*lastp)->next;
250 : }
251 : }
252 :
253 28 : *info = engine_info;
254 28 : UNLOCK (engine_info_lock);
255 28 : return 0;
256 : }
257 :
258 :
259 : /* Get a deep copy of the engine info and return it in INFO. */
260 : gpgme_error_t
261 118 : _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
262 : {
263 118 : gpgme_error_t err = 0;
264 : gpgme_engine_info_t info;
265 : gpgme_engine_info_t new_info;
266 : gpgme_engine_info_t *lastp;
267 :
268 118 : LOCK (engine_info_lock);
269 118 : info = engine_info;
270 118 : if (!info)
271 : {
272 : /* Make sure it is initialized. */
273 0 : UNLOCK (engine_info_lock);
274 0 : err = gpgme_get_engine_info (&info);
275 0 : if (err)
276 0 : return err;
277 :
278 0 : LOCK (engine_info_lock);
279 : }
280 :
281 118 : new_info = NULL;
282 118 : lastp = &new_info;
283 :
284 944 : while (info)
285 : {
286 : char *file_name;
287 : char *home_dir;
288 : char *version;
289 :
290 708 : assert (info->file_name);
291 708 : file_name = strdup (info->file_name);
292 708 : if (!file_name)
293 0 : err = gpg_error_from_syserror ();
294 :
295 708 : if (info->home_dir)
296 : {
297 118 : home_dir = strdup (info->home_dir);
298 118 : if (!home_dir && !err)
299 0 : err = gpg_error_from_syserror ();
300 : }
301 : else
302 590 : home_dir = NULL;
303 :
304 708 : if (info->version)
305 : {
306 708 : version = strdup (info->version);
307 708 : if (!version && !err)
308 0 : err = gpg_error_from_syserror ();
309 : }
310 : else
311 0 : version = NULL;
312 :
313 708 : *lastp = malloc (sizeof (*engine_info));
314 708 : if (!*lastp && !err)
315 0 : err = gpg_error_from_syserror ();
316 :
317 708 : if (err)
318 : {
319 0 : _gpgme_engine_info_release (new_info);
320 0 : if (file_name)
321 0 : free (file_name);
322 0 : if (home_dir)
323 0 : free (home_dir);
324 0 : if (version)
325 0 : free (version);
326 :
327 0 : UNLOCK (engine_info_lock);
328 0 : return err;
329 : }
330 :
331 708 : (*lastp)->protocol = info->protocol;
332 708 : (*lastp)->file_name = file_name;
333 708 : (*lastp)->home_dir = home_dir;
334 708 : (*lastp)->version = version;
335 708 : (*lastp)->req_version = info->req_version;
336 708 : (*lastp)->next = NULL;
337 708 : lastp = &(*lastp)->next;
338 :
339 708 : info = info->next;
340 : }
341 :
342 118 : *r_info = new_info;
343 118 : UNLOCK (engine_info_lock);
344 118 : return 0;
345 : }
346 :
347 :
348 : /* Set the engine info for the info list INFO, protocol PROTO, to the
349 : file name FILE_NAME and the home directory HOME_DIR. */
350 : gpgme_error_t
351 52 : _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto,
352 : const char *file_name, const char *home_dir)
353 : {
354 : char *new_file_name;
355 : char *new_home_dir;
356 :
357 : /* FIXME: Use some PROTO_MAX definition. */
358 52 : if (proto > DIM (engine_ops))
359 0 : return gpg_error (GPG_ERR_INV_VALUE);
360 :
361 105 : while (info && info->protocol != proto)
362 1 : info = info->next;
363 :
364 52 : if (!info)
365 0 : return trace_gpg_error (GPG_ERR_INV_ENGINE);
366 :
367 : /* Prepare new members. */
368 52 : if (file_name)
369 52 : new_file_name = strdup (file_name);
370 : else
371 : {
372 0 : const char *ofile_name = engine_get_file_name (proto);
373 0 : assert (ofile_name);
374 0 : new_file_name = strdup (ofile_name);
375 : }
376 52 : if (!new_file_name)
377 0 : return gpg_error_from_syserror ();
378 :
379 52 : if (home_dir)
380 : {
381 0 : new_home_dir = strdup (home_dir);
382 0 : if (!new_home_dir)
383 : {
384 0 : free (new_file_name);
385 0 : return gpg_error_from_syserror ();
386 : }
387 : }
388 : else
389 : {
390 52 : const char *ohome_dir = engine_get_home_dir (proto);
391 52 : if (ohome_dir)
392 : {
393 0 : new_home_dir = strdup (ohome_dir);
394 0 : if (!new_home_dir)
395 : {
396 0 : free (new_file_name);
397 0 : return gpg_error_from_syserror ();
398 : }
399 : }
400 : else
401 52 : new_home_dir = NULL;
402 : }
403 :
404 : /* Remove the old members. */
405 52 : assert (info->file_name);
406 52 : free (info->file_name);
407 52 : if (info->home_dir)
408 0 : free (info->home_dir);
409 52 : if (info->version)
410 52 : free (info->version);
411 :
412 : /* Install the new members. */
413 52 : info->file_name = new_file_name;
414 52 : info->home_dir = new_home_dir;
415 52 : info->version = engine_get_version (proto, new_file_name);
416 :
417 52 : return 0;
418 : }
419 :
420 :
421 : /* Set the default engine info for the protocol PROTO to the file name
422 : FILE_NAME and the home directory HOME_DIR. */
423 : gpgme_error_t
424 0 : gpgme_set_engine_info (gpgme_protocol_t proto,
425 : const char *file_name, const char *home_dir)
426 : {
427 : gpgme_error_t err;
428 : gpgme_engine_info_t info;
429 :
430 0 : LOCK (engine_info_lock);
431 0 : info = engine_info;
432 0 : if (!info)
433 : {
434 : /* Make sure it is initialized. */
435 0 : UNLOCK (engine_info_lock);
436 0 : err = gpgme_get_engine_info (&info);
437 0 : if (err)
438 0 : return err;
439 :
440 0 : LOCK (engine_info_lock);
441 : }
442 :
443 0 : err = _gpgme_set_engine_info (info, proto, file_name, home_dir);
444 0 : UNLOCK (engine_info_lock);
445 0 : return err;
446 : }
447 :
448 :
449 : gpgme_error_t
450 133 : _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine)
451 : {
452 : engine_t engine;
453 :
454 133 : if (!info->file_name || !info->version)
455 0 : return trace_gpg_error (GPG_ERR_INV_ENGINE);
456 :
457 133 : engine = calloc (1, sizeof *engine);
458 133 : if (!engine)
459 0 : return gpg_error_from_syserror ();
460 :
461 133 : engine->ops = engine_ops[info->protocol];
462 133 : if (engine->ops->new)
463 : {
464 : gpgme_error_t err;
465 266 : err = (*engine->ops->new) (&engine->engine,
466 133 : info->file_name, info->home_dir);
467 133 : if (err)
468 : {
469 0 : free (engine);
470 0 : return err;
471 : }
472 : }
473 : else
474 0 : engine->engine = NULL;
475 :
476 133 : *r_engine = engine;
477 133 : return 0;
478 : }
479 :
480 :
481 : gpgme_error_t
482 19 : _gpgme_engine_reset (engine_t engine)
483 : {
484 19 : if (!engine)
485 0 : return gpg_error (GPG_ERR_INV_VALUE);
486 :
487 19 : if (!engine->ops->reset)
488 15 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
489 :
490 4 : return (*engine->ops->reset) (engine->engine);
491 : }
492 :
493 :
494 : void
495 133 : _gpgme_engine_release (engine_t engine)
496 : {
497 133 : if (!engine)
498 133 : return;
499 :
500 133 : if (engine->ops->release)
501 133 : (*engine->ops->release) (engine->engine);
502 133 : free (engine);
503 : }
504 :
505 :
506 : void
507 139 : _gpgme_engine_set_status_handler (engine_t engine,
508 : engine_status_handler_t fnc, void *fnc_value)
509 : {
510 139 : if (!engine)
511 139 : return;
512 :
513 139 : if (engine->ops->set_status_handler)
514 139 : (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
515 : }
516 :
517 :
518 : gpgme_error_t
519 35 : _gpgme_engine_set_command_handler (engine_t engine,
520 : engine_command_handler_t fnc,
521 : void *fnc_value,
522 : gpgme_data_t linked_data)
523 : {
524 35 : if (!engine)
525 0 : return gpg_error (GPG_ERR_INV_VALUE);
526 :
527 35 : if (!engine->ops->set_command_handler)
528 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
529 :
530 35 : return (*engine->ops->set_command_handler) (engine->engine,
531 : fnc, fnc_value, linked_data);
532 : }
533 :
534 : gpgme_error_t
535 58 : _gpgme_engine_set_colon_line_handler (engine_t engine,
536 : engine_colon_line_handler_t fnc,
537 : void *fnc_value)
538 : {
539 58 : if (!engine)
540 0 : return gpg_error (GPG_ERR_INV_VALUE);
541 :
542 58 : if (!engine->ops->set_colon_line_handler)
543 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
544 :
545 58 : return (*engine->ops->set_colon_line_handler) (engine->engine,
546 : fnc, fnc_value);
547 : }
548 :
549 : gpgme_error_t
550 274 : _gpgme_engine_set_locale (engine_t engine, int category,
551 : const char *value)
552 : {
553 274 : if (!engine)
554 0 : return gpg_error (GPG_ERR_INV_VALUE);
555 :
556 274 : if (!engine->ops->set_locale)
557 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
558 :
559 274 : return (*engine->ops->set_locale) (engine->engine, category, value);
560 : }
561 :
562 :
563 : gpgme_error_t
564 0 : _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
565 : {
566 0 : if (!engine)
567 0 : return gpg_error (GPG_ERR_INV_VALUE);
568 :
569 0 : if (!engine->ops->set_protocol)
570 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
571 :
572 0 : return (*engine->ops->set_protocol) (engine->engine, protocol);
573 : }
574 :
575 :
576 : gpgme_error_t
577 24 : _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
578 : gpgme_data_t plain)
579 : {
580 24 : if (!engine)
581 0 : return gpg_error (GPG_ERR_INV_VALUE);
582 :
583 24 : if (!engine->ops->decrypt)
584 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
585 :
586 24 : return (*engine->ops->decrypt) (engine->engine, ciph, plain);
587 : }
588 :
589 :
590 : gpgme_error_t
591 1 : _gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
592 : gpgme_data_t plain)
593 : {
594 1 : if (!engine)
595 0 : return gpg_error (GPG_ERR_INV_VALUE);
596 :
597 1 : if (!engine->ops->decrypt_verify)
598 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
599 :
600 1 : return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain);
601 : }
602 :
603 :
604 : gpgme_error_t
605 0 : _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
606 : int allow_secret)
607 : {
608 0 : if (!engine)
609 0 : return gpg_error (GPG_ERR_INV_VALUE);
610 :
611 0 : if (!engine->ops->delete)
612 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
613 :
614 0 : return (*engine->ops->delete) (engine->engine, key, allow_secret);
615 : }
616 :
617 :
618 : gpgme_error_t
619 1 : _gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
620 : gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */)
621 : {
622 1 : if (!engine)
623 0 : return gpg_error (GPG_ERR_INV_VALUE);
624 :
625 1 : if (!engine->ops->edit)
626 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
627 :
628 1 : return (*engine->ops->edit) (engine->engine, type, key, out, ctx);
629 : }
630 :
631 :
632 : gpgme_error_t
633 26 : _gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
634 : gpgme_encrypt_flags_t flags,
635 : gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
636 : {
637 26 : if (!engine)
638 0 : return gpg_error (GPG_ERR_INV_VALUE);
639 :
640 26 : if (!engine->ops->encrypt)
641 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
642 :
643 26 : return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
644 : use_armor);
645 : }
646 :
647 :
648 : gpgme_error_t
649 2 : _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
650 : gpgme_encrypt_flags_t flags,
651 : gpgme_data_t plain, gpgme_data_t ciph,
652 : int use_armor, gpgme_ctx_t ctx /* FIXME */)
653 : {
654 2 : if (!engine)
655 0 : return gpg_error (GPG_ERR_INV_VALUE);
656 :
657 2 : if (!engine->ops->encrypt_sign)
658 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
659 :
660 2 : return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
661 : plain, ciph, use_armor, ctx);
662 : }
663 :
664 :
665 : gpgme_error_t
666 0 : _gpgme_engine_op_export (engine_t engine, const char *pattern,
667 : gpgme_export_mode_t mode, gpgme_data_t keydata,
668 : int use_armor)
669 : {
670 0 : if (!engine)
671 0 : return gpg_error (GPG_ERR_INV_VALUE);
672 :
673 0 : if (!engine->ops->export)
674 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
675 :
676 0 : return (*engine->ops->export) (engine->engine, pattern, mode,
677 : keydata, use_armor);
678 : }
679 :
680 :
681 : gpgme_error_t
682 4 : _gpgme_engine_op_export_ext (engine_t engine, const char *pattern[],
683 : unsigned int reserved, gpgme_data_t keydata,
684 : int use_armor)
685 : {
686 4 : if (!engine)
687 0 : return gpg_error (GPG_ERR_INV_VALUE);
688 :
689 4 : if (!engine->ops->export_ext)
690 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
691 :
692 4 : return (*engine->ops->export_ext) (engine->engine, pattern, reserved,
693 : keydata, use_armor);
694 : }
695 :
696 :
697 : gpgme_error_t
698 0 : _gpgme_engine_op_genkey (engine_t engine, gpgme_data_t help_data,
699 : int use_armor, gpgme_data_t pubkey,
700 : gpgme_data_t seckey)
701 : {
702 0 : if (!engine)
703 0 : return gpg_error (GPG_ERR_INV_VALUE);
704 :
705 0 : if (!engine->ops->genkey)
706 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
707 :
708 0 : return (*engine->ops->genkey) (engine->engine, help_data, use_armor,
709 : pubkey, seckey);
710 : }
711 :
712 :
713 : gpgme_error_t
714 4 : _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
715 : gpgme_key_t *keyarray)
716 : {
717 4 : if (!engine)
718 0 : return gpg_error (GPG_ERR_INV_VALUE);
719 :
720 4 : if (!engine->ops->import)
721 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
722 :
723 4 : return (*engine->ops->import) (engine->engine, keydata, keyarray);
724 : }
725 :
726 :
727 : gpgme_error_t
728 57 : _gpgme_engine_op_keylist (engine_t engine, const char *pattern,
729 : int secret_only, gpgme_keylist_mode_t mode,
730 : int engine_flags)
731 : {
732 57 : if (!engine)
733 0 : return gpg_error (GPG_ERR_INV_VALUE);
734 :
735 57 : if (!engine->ops->keylist)
736 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
737 :
738 57 : return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode,
739 : engine_flags);
740 : }
741 :
742 :
743 : gpgme_error_t
744 0 : _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
745 : int secret_only, int reserved,
746 : gpgme_keylist_mode_t mode, int engine_flags)
747 : {
748 0 : if (!engine)
749 0 : return gpg_error (GPG_ERR_INV_VALUE);
750 :
751 0 : if (!engine->ops->keylist_ext)
752 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
753 :
754 0 : return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
755 : reserved, mode, engine_flags);
756 : }
757 :
758 :
759 : gpgme_error_t
760 9 : _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
761 : gpgme_sig_mode_t mode, int use_armor,
762 : int use_textmode, int include_certs,
763 : gpgme_ctx_t ctx /* FIXME */)
764 : {
765 9 : if (!engine)
766 0 : return gpg_error (GPG_ERR_INV_VALUE);
767 :
768 9 : if (!engine->ops->sign)
769 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
770 :
771 9 : return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
772 : use_textmode, include_certs, ctx);
773 : }
774 :
775 :
776 : gpgme_error_t
777 1 : _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
778 : {
779 1 : if (!engine)
780 0 : return gpg_error (GPG_ERR_INV_VALUE);
781 :
782 1 : if (!engine->ops->trustlist)
783 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
784 :
785 1 : return (*engine->ops->trustlist) (engine->engine, pattern);
786 : }
787 :
788 :
789 : gpgme_error_t
790 8 : _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
791 : gpgme_data_t signed_text, gpgme_data_t plaintext)
792 : {
793 8 : if (!engine)
794 0 : return gpg_error (GPG_ERR_INV_VALUE);
795 :
796 8 : if (!engine->ops->verify)
797 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
798 :
799 8 : return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
800 : }
801 :
802 :
803 : gpgme_error_t
804 2 : _gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output,
805 : unsigned int flags)
806 : {
807 2 : if (!engine)
808 0 : return gpg_error (GPG_ERR_INV_VALUE);
809 :
810 2 : if (!engine->ops->getauditlog)
811 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
812 :
813 2 : return (*engine->ops->getauditlog) (engine->engine, output, flags);
814 : }
815 :
816 :
817 : gpgme_error_t
818 0 : _gpgme_engine_op_assuan_transact (engine_t engine,
819 : const char *command,
820 : gpgme_assuan_data_cb_t data_cb,
821 : void *data_cb_value,
822 : gpgme_assuan_inquire_cb_t inq_cb,
823 : void *inq_cb_value,
824 : gpgme_assuan_status_cb_t status_cb,
825 : void *status_cb_value)
826 : {
827 0 : if (!engine)
828 0 : return gpg_error (GPG_ERR_INV_VALUE);
829 :
830 0 : if (!engine->ops->opassuan_transact)
831 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
832 :
833 0 : return (*engine->ops->opassuan_transact) (engine->engine,
834 : command,
835 : data_cb, data_cb_value,
836 : inq_cb, inq_cb_value,
837 : status_cb, status_cb_value);
838 : }
839 :
840 :
841 : gpgme_error_t
842 0 : _gpgme_engine_op_conf_load (engine_t engine, gpgme_conf_comp_t *conf_p)
843 : {
844 0 : if (!engine)
845 0 : return gpg_error (GPG_ERR_INV_VALUE);
846 :
847 0 : if (!engine->ops->conf_load)
848 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
849 :
850 0 : return (*engine->ops->conf_load) (engine->engine, conf_p);
851 : }
852 :
853 :
854 : gpgme_error_t
855 0 : _gpgme_engine_op_conf_save (engine_t engine, gpgme_conf_comp_t conf)
856 : {
857 0 : if (!engine)
858 0 : return gpg_error (GPG_ERR_INV_VALUE);
859 :
860 0 : if (!engine->ops->conf_save)
861 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
862 :
863 0 : return (*engine->ops->conf_save) (engine->engine, conf);
864 : }
865 :
866 :
867 : void
868 139 : _gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
869 : {
870 139 : if (!engine)
871 139 : return;
872 :
873 139 : (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
874 : }
875 :
876 :
877 : void
878 279 : _gpgme_engine_io_event (engine_t engine,
879 : gpgme_event_io_t type, void *type_data)
880 : {
881 279 : if (!engine)
882 279 : return;
883 :
884 279 : (*engine->ops->io_event) (engine->engine, type, type_data);
885 : }
886 :
887 :
888 : /* Cancel the session and the pending operation if any. */
889 : gpgme_error_t
890 2 : _gpgme_engine_cancel (engine_t engine)
891 : {
892 2 : if (!engine)
893 0 : return gpg_error (GPG_ERR_INV_VALUE);
894 :
895 2 : if (!engine->ops->cancel)
896 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
897 :
898 2 : return (*engine->ops->cancel) (engine->engine);
899 : }
900 :
901 :
902 : /* Cancel the pending operation, but not the complete session. */
903 : gpgme_error_t
904 0 : _gpgme_engine_cancel_op (engine_t engine)
905 : {
906 0 : if (!engine)
907 0 : return gpg_error (GPG_ERR_INV_VALUE);
908 :
909 0 : if (!engine->ops->cancel_op)
910 0 : return 0;
911 :
912 0 : return (*engine->ops->cancel_op) (engine->engine);
913 : }
914 :
915 :
916 : /* Change the passphrase for KEY. */
917 : gpgme_error_t
918 0 : _gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
919 : unsigned int flags)
920 : {
921 0 : if (!engine)
922 0 : return gpg_error (GPG_ERR_INV_VALUE);
923 :
924 0 : if (!engine->ops->passwd)
925 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
926 :
927 0 : return (*engine->ops->passwd) (engine->engine, key, flags);
928 : }
929 :
930 :
931 : /* Set the pinentry mode for ENGINE to MODE. */
932 : gpgme_error_t
933 137 : _gpgme_engine_set_pinentry_mode (engine_t engine, gpgme_pinentry_mode_t mode)
934 : {
935 137 : if (!engine)
936 0 : return gpg_error (GPG_ERR_INV_VALUE);
937 :
938 137 : if (!engine->ops->set_pinentry_mode)
939 12 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
940 :
941 125 : return (*engine->ops->set_pinentry_mode) (engine->engine, mode);
942 : }
943 :
944 :
945 : gpgme_error_t
946 0 : _gpgme_engine_op_spawn (engine_t engine,
947 : const char *file, const char *argv[],
948 : gpgme_data_t datain,
949 : gpgme_data_t dataout, gpgme_data_t dataerr,
950 : unsigned int flags)
951 : {
952 0 : if (!engine)
953 0 : return gpg_error (GPG_ERR_INV_VALUE);
954 :
955 0 : if (!engine->ops->opspawn)
956 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
957 :
958 0 : return (*engine->ops->opspawn) (engine->engine, file, argv,
959 : datain, dataout, dataerr, flags);
960 : }
|