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
5 This file is part of GPGME.
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.
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.
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/>.
35 #include "engine-backend.h"
40 struct engine_ops *ops;
45 static struct engine_ops *engine_ops[] =
47 &_gpgme_engine_ops_gpg, /* OpenPGP. */
49 &_gpgme_engine_ops_gpgsm, /* CMS. */
54 &_gpgme_engine_ops_gpgconf, /* gpg-conf. */
59 &_gpgme_engine_ops_assuan, /* Low-Level Assuan. */
64 &_gpgme_engine_ops_g13, /* Crypto VFS. */
68 #ifdef ENABLE_UISERVER
69 &_gpgme_engine_ops_uiserver /* UI-Server. */
76 /* The engine info. */
77 static gpgme_engine_info_t engine_info;
78 DEFINE_STATIC_LOCK (engine_info_lock);
81 /* Get the file name of the engine for PROTOCOL. */
83 engine_get_file_name (gpgme_protocol_t proto)
85 if (proto > DIM (engine_ops))
88 if (engine_ops[proto] && engine_ops[proto]->get_file_name)
89 return (*engine_ops[proto]->get_file_name) ();
95 /* Get the standard home dir of the engine for PROTOCOL. */
97 engine_get_home_dir (gpgme_protocol_t proto)
99 if (proto > DIM (engine_ops))
102 if (engine_ops[proto] && engine_ops[proto]->get_home_dir)
103 return (*engine_ops[proto]->get_home_dir) ();
109 /* Get a malloced string containing the version number of the engine
112 engine_get_version (gpgme_protocol_t proto, const char *file_name)
114 if (proto > DIM (engine_ops))
117 if (engine_ops[proto] && engine_ops[proto]->get_version)
118 return (*engine_ops[proto]->get_version) (file_name);
124 /* Get the required version number of the engine for PROTOCOL. */
126 engine_get_req_version (gpgme_protocol_t proto)
128 if (proto > DIM (engine_ops))
131 if (engine_ops[proto] && engine_ops[proto]->get_req_version)
132 return (*engine_ops[proto]->get_req_version) ();
138 /* Verify the version requirement for the engine for PROTOCOL. */
140 gpgme_engine_check_version (gpgme_protocol_t proto)
143 gpgme_engine_info_t info;
146 LOCK (engine_info_lock);
150 /* Make sure it is initialized. */
151 UNLOCK (engine_info_lock);
152 err = gpgme_get_engine_info (&info);
156 LOCK (engine_info_lock);
159 while (info && info->protocol != proto)
165 result = _gpgme_compare_versions (info->version,
168 UNLOCK (engine_info_lock);
169 return result ? 0 : gpg_error (GPG_ERR_INV_ENGINE);
173 /* Release the engine info INFO. */
175 _gpgme_engine_info_release (gpgme_engine_info_t info)
179 gpgme_engine_info_t next_info = info->next;
181 assert (info->file_name);
182 free (info->file_name);
184 free (info->home_dir);
186 free (info->version);
193 /* Get the information about the configured and installed engines. A
194 pointer to the first engine in the statically allocated linked list
195 is returned in *INFO. If an error occurs, it is returned. The
196 returned data is valid until the next gpgme_set_engine_info. */
198 gpgme_get_engine_info (gpgme_engine_info_t *info)
200 LOCK (engine_info_lock);
203 gpgme_engine_info_t *lastp = &engine_info;
204 gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
206 GPGME_PROTOCOL_GPGCONF,
207 GPGME_PROTOCOL_ASSUAN,
209 GPGME_PROTOCOL_UISERVER };
212 for (proto = 0; proto < DIM (proto_list); proto++)
214 const char *ofile_name = engine_get_file_name (proto_list[proto]);
215 const char *ohome_dir = engine_get_home_dir (proto_list[proto]);
222 file_name = strdup (ofile_name);
223 home_dir = ohome_dir? strdup (ohome_dir): NULL;
225 *lastp = malloc (sizeof (*engine_info));
226 if (!*lastp || !file_name)
228 int saved_errno = errno;
230 _gpgme_engine_info_release (engine_info);
238 UNLOCK (engine_info_lock);
239 return gpg_error_from_errno (saved_errno);
242 (*lastp)->protocol = proto_list[proto];
243 (*lastp)->file_name = file_name;
244 (*lastp)->home_dir = home_dir;
245 (*lastp)->version = engine_get_version (proto_list[proto], NULL);
246 (*lastp)->req_version = engine_get_req_version (proto_list[proto]);
247 (*lastp)->next = NULL;
248 lastp = &(*lastp)->next;
253 UNLOCK (engine_info_lock);
258 /* Get a deep copy of the engine info and return it in INFO. */
260 _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
262 gpgme_error_t err = 0;
263 gpgme_engine_info_t info;
264 gpgme_engine_info_t new_info;
265 gpgme_engine_info_t *lastp;
267 LOCK (engine_info_lock);
271 /* Make sure it is initialized. */
272 UNLOCK (engine_info_lock);
273 err = gpgme_get_engine_info (&info);
277 LOCK (engine_info_lock);
289 assert (info->file_name);
290 file_name = strdup (info->file_name);
294 home_dir = strdup (info->home_dir);
296 err = gpg_error_from_errno (errno);
303 version = strdup (info->version);
305 err = gpg_error_from_errno (errno);
310 *lastp = malloc (sizeof (*engine_info));
311 if (!*lastp || !file_name || err)
313 int saved_errno = errno;
315 _gpgme_engine_info_release (new_info);
324 UNLOCK (engine_info_lock);
325 return gpg_error_from_errno (saved_errno);
328 (*lastp)->protocol = info->protocol;
329 (*lastp)->file_name = file_name;
330 (*lastp)->home_dir = home_dir;
331 (*lastp)->version = version;
332 (*lastp)->req_version = info->req_version;
333 (*lastp)->next = NULL;
334 lastp = &(*lastp)->next;
340 UNLOCK (engine_info_lock);
345 /* Set the engine info for the info list INFO, protocol PROTO, to the
346 file name FILE_NAME and the home directory HOME_DIR. */
348 _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto,
349 const char *file_name, const char *home_dir)
354 /* FIXME: Use some PROTO_MAX definition. */
355 if (proto > DIM (engine_ops))
356 return gpg_error (GPG_ERR_INV_VALUE);
358 while (info && info->protocol != proto)
362 return gpg_error (GPG_ERR_INV_ENGINE);
364 /* Prepare new members. */
366 new_file_name = strdup (file_name);
369 const char *ofile_name = engine_get_file_name (proto);
371 new_file_name = strdup (ofile_name);
374 return gpg_error_from_errno (errno);
378 new_home_dir = strdup (home_dir);
381 free (new_file_name);
382 return gpg_error_from_errno (errno);
387 const char *ohome_dir = engine_get_home_dir (proto);
390 new_home_dir = strdup (ohome_dir);
393 free (new_file_name);
394 return gpg_error_from_errno (errno);
401 /* Remove the old members. */
402 assert (info->file_name);
403 free (info->file_name);
405 free (info->home_dir);
407 free (info->version);
409 /* Install the new members. */
410 info->file_name = new_file_name;
411 info->home_dir = new_home_dir;
412 info->version = engine_get_version (proto, new_file_name);
418 /* Set the default engine info for the protocol PROTO to the file name
419 FILE_NAME and the home directory HOME_DIR. */
421 gpgme_set_engine_info (gpgme_protocol_t proto,
422 const char *file_name, const char *home_dir)
425 gpgme_engine_info_t info;
427 LOCK (engine_info_lock);
431 /* Make sure it is initialized. */
432 UNLOCK (engine_info_lock);
433 err = gpgme_get_engine_info (&info);
437 LOCK (engine_info_lock);
440 err = _gpgme_set_engine_info (info, proto, file_name, home_dir);
441 UNLOCK (engine_info_lock);
447 _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine)
451 if (!info->file_name || !info->version)
452 return gpg_error (GPG_ERR_INV_ENGINE);
454 engine = calloc (1, sizeof *engine);
456 return gpg_error_from_errno (errno);
458 engine->ops = engine_ops[info->protocol];
459 if (engine->ops->new)
462 err = (*engine->ops->new) (&engine->engine,
463 info->file_name, info->home_dir);
471 engine->engine = NULL;
479 _gpgme_engine_reset (engine_t engine)
482 return gpg_error (GPG_ERR_INV_VALUE);
484 if (!engine->ops->reset)
485 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
487 return (*engine->ops->reset) (engine->engine);
492 _gpgme_engine_release (engine_t engine)
497 if (engine->ops->release)
498 (*engine->ops->release) (engine->engine);
504 _gpgme_engine_set_status_handler (engine_t engine,
505 engine_status_handler_t fnc, void *fnc_value)
510 if (engine->ops->set_status_handler)
511 (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
516 _gpgme_engine_set_command_handler (engine_t engine,
517 engine_command_handler_t fnc,
519 gpgme_data_t linked_data)
522 return gpg_error (GPG_ERR_INV_VALUE);
524 if (!engine->ops->set_command_handler)
525 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
527 return (*engine->ops->set_command_handler) (engine->engine,
528 fnc, fnc_value, linked_data);
532 _gpgme_engine_set_colon_line_handler (engine_t engine,
533 engine_colon_line_handler_t fnc,
537 return gpg_error (GPG_ERR_INV_VALUE);
539 if (!engine->ops->set_colon_line_handler)
540 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
542 return (*engine->ops->set_colon_line_handler) (engine->engine,
547 _gpgme_engine_set_locale (engine_t engine, int category,
551 return gpg_error (GPG_ERR_INV_VALUE);
553 if (!engine->ops->set_locale)
554 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
556 return (*engine->ops->set_locale) (engine->engine, category, value);
561 _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
564 return gpg_error (GPG_ERR_INV_VALUE);
566 if (!engine->ops->set_protocol)
567 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
569 return (*engine->ops->set_protocol) (engine->engine, protocol);
574 _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
578 return gpg_error (GPG_ERR_INV_VALUE);
580 if (!engine->ops->decrypt)
581 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
583 return (*engine->ops->decrypt) (engine->engine, ciph, plain);
588 _gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
592 return gpg_error (GPG_ERR_INV_VALUE);
594 if (!engine->ops->decrypt_verify)
595 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
597 return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain);
602 _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
606 return gpg_error (GPG_ERR_INV_VALUE);
608 if (!engine->ops->delete)
609 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
611 return (*engine->ops->delete) (engine->engine, key, allow_secret);
616 _gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
617 gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */)
620 return gpg_error (GPG_ERR_INV_VALUE);
622 if (!engine->ops->edit)
623 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
625 return (*engine->ops->edit) (engine->engine, type, key, out, ctx);
630 _gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
631 gpgme_encrypt_flags_t flags,
632 gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
635 return gpg_error (GPG_ERR_INV_VALUE);
637 if (!engine->ops->encrypt)
638 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
640 return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
646 _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
647 gpgme_encrypt_flags_t flags,
648 gpgme_data_t plain, gpgme_data_t ciph,
649 int use_armor, gpgme_ctx_t ctx /* FIXME */)
652 return gpg_error (GPG_ERR_INV_VALUE);
654 if (!engine->ops->encrypt_sign)
655 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
657 return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
658 plain, ciph, use_armor, ctx);
663 _gpgme_engine_op_export (engine_t engine, const char *pattern,
664 gpgme_export_mode_t mode, gpgme_data_t keydata,
668 return gpg_error (GPG_ERR_INV_VALUE);
670 if (!engine->ops->export)
671 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
673 return (*engine->ops->export) (engine->engine, pattern, mode,
679 _gpgme_engine_op_export_ext (engine_t engine, const char *pattern[],
680 unsigned int reserved, gpgme_data_t keydata,
684 return gpg_error (GPG_ERR_INV_VALUE);
686 if (!engine->ops->export_ext)
687 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
689 return (*engine->ops->export_ext) (engine->engine, pattern, reserved,
695 _gpgme_engine_op_genkey (engine_t engine, gpgme_data_t help_data,
696 int use_armor, gpgme_data_t pubkey,
700 return gpg_error (GPG_ERR_INV_VALUE);
702 if (!engine->ops->genkey)
703 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
705 return (*engine->ops->genkey) (engine->engine, help_data, use_armor,
711 _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
712 gpgme_key_t *keyarray)
715 return gpg_error (GPG_ERR_INV_VALUE);
717 if (!engine->ops->import)
718 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
720 return (*engine->ops->import) (engine->engine, keydata, keyarray);
725 _gpgme_engine_op_keylist (engine_t engine, const char *pattern,
726 int secret_only, gpgme_keylist_mode_t mode)
729 return gpg_error (GPG_ERR_INV_VALUE);
731 if (!engine->ops->keylist)
732 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
734 return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode);
739 _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
740 int secret_only, int reserved,
741 gpgme_keylist_mode_t mode)
744 return gpg_error (GPG_ERR_INV_VALUE);
746 if (!engine->ops->keylist_ext)
747 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
749 return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
755 _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
756 gpgme_sig_mode_t mode, int use_armor,
757 int use_textmode, int include_certs,
758 gpgme_ctx_t ctx /* FIXME */)
761 return gpg_error (GPG_ERR_INV_VALUE);
763 if (!engine->ops->sign)
764 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
766 return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
767 use_textmode, include_certs, ctx);
772 _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
775 return gpg_error (GPG_ERR_INV_VALUE);
777 if (!engine->ops->trustlist)
778 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
780 return (*engine->ops->trustlist) (engine->engine, pattern);
785 _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
786 gpgme_data_t signed_text, gpgme_data_t plaintext)
789 return gpg_error (GPG_ERR_INV_VALUE);
791 if (!engine->ops->verify)
792 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
794 return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
799 _gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output,
803 return gpg_error (GPG_ERR_INV_VALUE);
805 if (!engine->ops->getauditlog)
806 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
808 return (*engine->ops->getauditlog) (engine->engine, output, flags);
813 _gpgme_engine_op_assuan_transact (engine_t engine,
815 gpgme_assuan_data_cb_t data_cb,
817 gpgme_assuan_inquire_cb_t inq_cb,
819 gpgme_assuan_status_cb_t status_cb,
820 void *status_cb_value)
823 return gpg_error (GPG_ERR_INV_VALUE);
825 if (!engine->ops->opassuan_transact)
826 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
828 return (*engine->ops->opassuan_transact) (engine->engine,
830 data_cb, data_cb_value,
831 inq_cb, inq_cb_value,
832 status_cb, status_cb_value);
837 _gpgme_engine_op_conf_load (engine_t engine, gpgme_conf_comp_t *conf_p)
840 return gpg_error (GPG_ERR_INV_VALUE);
842 if (!engine->ops->conf_load)
843 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
845 return (*engine->ops->conf_load) (engine->engine, conf_p);
850 _gpgme_engine_op_conf_save (engine_t engine, gpgme_conf_comp_t conf)
853 return gpg_error (GPG_ERR_INV_VALUE);
855 if (!engine->ops->conf_save)
856 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
858 return (*engine->ops->conf_save) (engine->engine, conf);
863 _gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
868 (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
873 _gpgme_engine_io_event (engine_t engine,
874 gpgme_event_io_t type, void *type_data)
879 (*engine->ops->io_event) (engine->engine, type, type_data);
883 /* Cancel the session and the pending operation if any. */
885 _gpgme_engine_cancel (engine_t engine)
888 return gpg_error (GPG_ERR_INV_VALUE);
890 if (!engine->ops->cancel)
891 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
893 return (*engine->ops->cancel) (engine->engine);
897 /* Cancel the pending operation, but not the complete session. */
899 _gpgme_engine_cancel_op (engine_t engine)
902 return gpg_error (GPG_ERR_INV_VALUE);
904 if (!engine->ops->cancel_op)
907 return (*engine->ops->cancel_op) (engine->engine);
911 /* Change the passphrase for KEY. */
913 _gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
917 return gpg_error (GPG_ERR_INV_VALUE);
919 if (!engine->ops->passwd)
920 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
922 return (*engine->ops->passwd) (engine->engine, key, flags);