diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-16 16:06:07 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-16 16:06:07 -0600 |
commit | be0ca741fd12897337408d1d7a7d8f5f18e1fac9 (patch) | |
tree | b9fa3458193a17180d8773a0204ee05ae206cd99 /libkdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c | |
parent | bbb7afdb6da2969535e7f05715e2cb95cfdc917c (diff) | |
download | tdepim-be0ca741fd12897337408d1d7a7d8f5f18e1fac9.tar.gz tdepim-be0ca741fd12897337408d1d7a7d8f5f18e1fac9.zip |
Finish rename from prior commit
Diffstat (limited to 'libkdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c')
-rw-r--r-- | libkdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c | 1750 |
1 files changed, 0 insertions, 1750 deletions
diff --git a/libkdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c b/libkdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c deleted file mode 100644 index 7ad8dc6f2..000000000 --- a/libkdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c +++ /dev/null @@ -1,1750 +0,0 @@ -/* engine-gpgsm.c - GpgSM engine. - Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH - - This file is part of GPGME. - - GPGME is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - GPGME is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#if HAVE_CONFIG_H -#include <config.h> -#endif - -#ifndef HAVE_W32_SYSTEM - -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <assert.h> -#include <unistd.h> -#include <locale.h> -#include <fcntl.h> /* FIXME */ -#include <errno.h> - -#include "gpgme.h" -#include "util.h" -#include "ops.h" -#include "wait.h" -#include "priv-io.h" -#include "sema.h" - -#include "assuan.h" -#include "status-table.h" -#include "debug.h" - -#include "engine-backend.h" - - -typedef struct -{ - int fd; /* FD we talk about. */ - int server_fd; /* Server FD for this connection. */ - int dir; /* Inbound/Outbound, maybe given implicit? */ - void *data; /* Handler-specific data. */ - void *tag; /* ID from the user for gpgme_remove_io_callback. */ -} iocb_data_t; - - -struct engine_gpgsm -{ - assuan_context_t assuan_ctx; - - int lc_ctype_set; - int lc_messages_set; - - iocb_data_t status_cb; - - /* Input, output etc are from the servers perspective. */ - iocb_data_t input_cb; - - iocb_data_t output_cb; - - iocb_data_t message_cb; - - struct - { - engine_status_handler_t fnc; - void *fnc_value; - } status; - - struct - { - engine_colon_line_handler_t fnc; - void *fnc_value; - struct - { - char *line; - int linesize; - int linelen; - } attic; - int any; /* any data line seen */ - } colon; - - struct gpgme_io_cbs io_cbs; -}; - -typedef struct engine_gpgsm *engine_gpgsm_t; - - -static char * -gpgsm_get_version (const char *file_name) -{ - return _gpgme_get_program_version (file_name ? file_name - : _gpgme_get_gpgsm_path ()); -} - - -static const char * -gpgsm_get_req_version (void) -{ - return NEED_GPGSM_VERSION; -} - - -static void -close_notify_handler (int fd, void *opaque) -{ - engine_gpgsm_t gpgsm = opaque; - - assert (fd != -1); - if (gpgsm->status_cb.fd == fd) - { - if (gpgsm->status_cb.tag) - (*gpgsm->io_cbs.remove) (gpgsm->status_cb.tag); - gpgsm->status_cb.fd = -1; - gpgsm->status_cb.tag = NULL; - } - else if (gpgsm->input_cb.fd == fd) - { - if (gpgsm->input_cb.tag) - (*gpgsm->io_cbs.remove) (gpgsm->input_cb.tag); - gpgsm->input_cb.fd = -1; - gpgsm->input_cb.tag = NULL; - } - else if (gpgsm->output_cb.fd == fd) - { - if (gpgsm->output_cb.tag) - (*gpgsm->io_cbs.remove) (gpgsm->output_cb.tag); - gpgsm->output_cb.fd = -1; - gpgsm->output_cb.tag = NULL; - } - else if (gpgsm->message_cb.fd == fd) - { - if (gpgsm->message_cb.tag) - (*gpgsm->io_cbs.remove) (gpgsm->message_cb.tag); - gpgsm->message_cb.fd = -1; - gpgsm->message_cb.tag = NULL; - } -} - - -static gpgme_error_t -map_assuan_error (gpg_error_t err) -{ - if (!err) - return 0; - - if (err == -1) - return gpg_error (GPG_ERR_INV_ENGINE); - - /* New code will use gpg_error_t values. */ - if (gpg_err_source (err)) - return (gpgme_error_t) err; - - /* Legacy code will use old values. */ - switch (err) - { - case ASSUAN_No_Error: - return gpg_error (GPG_ERR_NO_ERROR); - case ASSUAN_General_Error: - return gpg_error (GPG_ERR_GENERAL); - case ASSUAN_Out_Of_Core: - return gpg_error (GPG_ERR_ENOMEM); - case ASSUAN_Invalid_Value: - return gpg_error (GPG_ERR_INV_VALUE); - case ASSUAN_Timeout: - return gpg_error (GPG_ERR_ETIMEDOUT); - case ASSUAN_Read_Error: - return gpg_error (GPG_ERR_GENERAL); - case ASSUAN_Write_Error: - return gpg_error (GPG_ERR_GENERAL); - - case ASSUAN_Problem_Starting_Server: - case ASSUAN_Not_A_Server: - case ASSUAN_Not_A_Client: - case ASSUAN_Nested_Commands: - case ASSUAN_No_Data_Callback: - case ASSUAN_No_Inquire_Callback: - case ASSUAN_Connect_Failed: - case ASSUAN_Accept_Failed: - case ASSUAN_Invalid_Command: - case ASSUAN_Unknown_Command: - case ASSUAN_Syntax_Error: - case ASSUAN_Parameter_Error: - case ASSUAN_Parameter_Conflict: - case ASSUAN_No_Input: - case ASSUAN_No_Output: - case ASSUAN_No_Data_Available: - case ASSUAN_Too_Much_Data: - case ASSUAN_Inquire_Unknown: - case ASSUAN_Inquire_Error: - case ASSUAN_Invalid_Option: - case ASSUAN_Unexpected_tqStatus: - case ASSUAN_Unexpected_Data: - case ASSUAN_Invalid_tqStatus: - return gpg_error (GPG_ERR_ASSUAN); - - case ASSUAN_Invalid_Response: - return gpg_error (GPG_ERR_INV_RESPONSE); - - case ASSUAN_Not_Implemented: - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - case ASSUAN_Line_Too_Long: - return gpg_error (GPG_ERR_LINE_TOO_LONG); - case ASSUAN_Line_Not_Terminated: - return gpg_error (GPG_ERR_INCOMPLETE_LINE); - case ASSUAN_Canceled: - return gpg_error (GPG_ERR_CANCELED); - - case ASSUAN_Unsupported_Algorithm: - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - case ASSUAN_Server_Resource_Problem: - return gpg_error (GPG_ERR_RESOURCE_LIMIT); - case ASSUAN_Server_IO_Error: - return gpg_error (GPG_ERR_GENERAL); - case ASSUAN_Server_Bug: - return gpg_error (GPG_ERR_BUG); - case ASSUAN_Invalid_Data: - return gpg_error (GPG_ERR_INV_DATA); - case ASSUAN_Invalid_Index: - return gpg_error (GPG_ERR_INV_INDEX); - case ASSUAN_Not_Confirmed: - return gpg_error (GPG_ERR_NOT_CONFIRMED); - case ASSUAN_Bad_Certificate: - return gpg_error (GPG_ERR_BAD_CERT); - case ASSUAN_Bad_Certificate_Chain: - return gpg_error (GPG_ERR_BAD_CERT_CHAIN); - case ASSUAN_Missing_Certificate: - return gpg_error (GPG_ERR_MISSING_CERT); - case ASSUAN_Bad_Signature: - return gpg_error (GPG_ERR_BAD_SIGNATURE); - case ASSUAN_No_Agent: - return gpg_error (GPG_ERR_NO_AGENT); - case ASSUAN_Agent_Error: - return gpg_error (GPG_ERR_AGENT); - case ASSUAN_No_Public_Key: - return gpg_error (GPG_ERR_NO_PUBKEY); - case ASSUAN_No_Secret_Key: - return gpg_error (GPG_ERR_NO_SECKEY); - case ASSUAN_Invalid_Name: - return gpg_error (GPG_ERR_INV_NAME); - - case ASSUAN_Cert_Revoked: - return gpg_error (GPG_ERR_CERT_REVOKED); - case ASSUAN_No_CRL_For_Cert: - return gpg_error (GPG_ERR_NO_CRL_KNOWN); - case ASSUAN_CRL_Too_Old: - return gpg_error (GPG_ERR_CRL_TOO_OLD); - case ASSUAN_Not_Trusted: - return gpg_error (GPG_ERR_NOT_TRUSTED); - - case ASSUAN_Card_Error: - return gpg_error (GPG_ERR_CARD); - case ASSUAN_Invalid_Card: - return gpg_error (GPG_ERR_INV_CARD); - case ASSUAN_No_PKCS15_App: - return gpg_error (GPG_ERR_NO_PKCS15_APP); - case ASSUAN_Card_Not_Present: - return gpg_error (GPG_ERR_CARD_NOT_PRESENT); - case ASSUAN_Invalid_Id: - return gpg_error (GPG_ERR_INV_ID); - default: - return gpg_error (GPG_ERR_GENERAL); - } -} - - -static gpgme_error_t -gpgsm_cancel (void *engine) -{ - engine_gpgsm_t gpgsm = engine; - - if (!gpgsm) - return gpg_error (GPG_ERR_INV_VALUE); - - if (gpgsm->status_cb.fd != -1) - _gpgme_io_close (gpgsm->status_cb.fd); - if (gpgsm->input_cb.fd != -1) - _gpgme_io_close (gpgsm->input_cb.fd); - if (gpgsm->output_cb.fd != -1) - _gpgme_io_close (gpgsm->output_cb.fd); - if (gpgsm->message_cb.fd != -1) - _gpgme_io_close (gpgsm->message_cb.fd); - - if (gpgsm->assuan_ctx) - { - assuan_disconnect (gpgsm->assuan_ctx); - gpgsm->assuan_ctx = NULL; - } - - return 0; -} - - -static void -gpgsm_release (void *engine) -{ - engine_gpgsm_t gpgsm = engine; - - if (!gpgsm) - return; - - gpgsm_cancel (engine); - - free (gpgsm->colon.attic.line); - free (gpgsm); -} - - -static gpgme_error_t -gpgsm_new (void **engine, const char *file_name, const char *home_dir) -{ - gpgme_error_t err = 0; - engine_gpgsm_t gpgsm; - const char *argv[5]; - int argc; -#if !USE_DESCRIPTOR_PASSING - int fds[2]; - int child_fds[4]; -#endif - char *dft_display = NULL; - char dft_ttyname[64]; - char *dft_ttytype = NULL; - char *optstr; - - gpgsm = calloc (1, sizeof *gpgsm); - if (!gpgsm) - return gpg_error_from_errno (errno); - - gpgsm->status_cb.fd = -1; - gpgsm->status_cb.dir = 1; - gpgsm->status_cb.tag = 0; - gpgsm->status_cb.data = gpgsm; - - gpgsm->input_cb.fd = -1; - gpgsm->input_cb.dir = 0; - gpgsm->input_cb.tag = 0; - gpgsm->input_cb.server_fd = -1; - gpgsm->output_cb.fd = -1; - gpgsm->output_cb.dir = 1; - gpgsm->output_cb.tag = 0; - gpgsm->output_cb.server_fd = -1; - gpgsm->message_cb.fd = -1; - gpgsm->message_cb.dir = 0; - gpgsm->message_cb.tag = 0; - gpgsm->message_cb.server_fd = -1; - - gpgsm->status.fnc = 0; - gpgsm->colon.fnc = 0; - gpgsm->colon.attic.line = 0; - gpgsm->colon.attic.linesize = 0; - gpgsm->colon.attic.linelen = 0; - gpgsm->colon.any = 0; - - gpgsm->io_cbs.add = NULL; - gpgsm->io_cbs.add_priv = NULL; - gpgsm->io_cbs.remove = NULL; - gpgsm->io_cbs.event = NULL; - gpgsm->io_cbs.event_priv = NULL; - -#if !USE_DESCRIPTOR_PASSING - if (_gpgme_io_pipe (fds, 0) < 0) - { - err = gpg_error_from_errno (errno); - goto leave; - } - gpgsm->input_cb.fd = fds[1]; - gpgsm->input_cb.server_fd = fds[0]; - - if (_gpgme_io_pipe (fds, 1) < 0) - { - err = gpg_error_from_errno (errno); - goto leave; - } - gpgsm->output_cb.fd = fds[0]; - gpgsm->output_cb.server_fd = fds[1]; - - if (_gpgme_io_pipe (fds, 0) < 0) - { - err = gpg_error_from_errno (errno); - goto leave; - } - gpgsm->message_cb.fd = fds[1]; - gpgsm->message_cb.server_fd = fds[0]; - - child_fds[0] = gpgsm->input_cb.server_fd; - child_fds[1] = gpgsm->output_cb.server_fd; - child_fds[2] = gpgsm->message_cb.server_fd; - child_fds[3] = -1; -#endif - - argc = 0; - argv[argc++] = "gpgsm"; - if (home_dir) - { - argv[argc++] = "--homedir"; - argv[argc++] = home_dir; - } - argv[argc++] = "--server"; - argv[argc++] = NULL; - -#if USE_DESCRIPTOR_PASSING - err = assuan_pipe_connect_ext - (&gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (), - argv, NULL, NULL, NULL, 1); -#else - err = assuan_pipe_connect - (&gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (), - argv, child_fds); -#endif - if (err) - goto leave; - - err = _gpgme_getenv ("DISPLAY", &dft_display); - if (err) - goto leave; - if (dft_display) - { - if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0) - { - free (dft_display); - err = gpg_error_from_errno (errno); - goto leave; - } - free (dft_display); - - err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, - NULL, NULL, NULL); - free (optstr); - if (err) - { - err = map_assuan_error (err); - goto leave; - } - } - - if (isatty (1)) - { - if (ttyname_r (1, dft_ttyname, sizeof (dft_ttyname))) - { - err = gpg_error_from_errno (errno); - goto leave; - } - else - { - if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) - { - err = gpg_error_from_errno (errno); - goto leave; - } - err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, - NULL, NULL, NULL); - free (optstr); - if (err) - { - err = map_assuan_error (err); - goto leave; - } - - err = _gpgme_getenv ("TERM", &dft_ttytype); - if (err) - goto leave; - if (dft_ttytype) - { - if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0) - { - free (dft_ttytype); - err = gpg_error_from_errno (errno); - goto leave; - } - free (dft_ttytype); - - err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, - NULL, NULL, NULL, NULL); - free (optstr); - if (err) - { - err = map_assuan_error (err); - goto leave; - } - } - } - } - -#if !USE_DESCRIPTOR_PASSING - if (!err - && (_gpgme_io_set_close_notify (gpgsm->input_cb.fd, - close_notify_handler, gpgsm) - || _gpgme_io_set_close_notify (gpgsm->output_cb.fd, - close_notify_handler, gpgsm) - || _gpgme_io_set_close_notify (gpgsm->message_cb.fd, - close_notify_handler, gpgsm))) - { - err = gpg_error (GPG_ERR_GENERAL); - goto leave; - } -#endif - - leave: - /* Close the server ends of the pipes. Our ends are closed in - gpgsm_release(). */ -#if !USE_DESCRIPTOR_PASSING - if (gpgsm->input_cb.server_fd != -1) - _gpgme_io_close (gpgsm->input_cb.server_fd); - if (gpgsm->output_cb.server_fd != -1) - _gpgme_io_close (gpgsm->output_cb.server_fd); - if (gpgsm->message_cb.server_fd != -1) - _gpgme_io_close (gpgsm->message_cb.server_fd); -#endif - - if (err) - gpgsm_release (gpgsm); - else - *engine = gpgsm; - - return err; -} - - -static gpgme_error_t -gpgsm_set_locale (void *engine, int category, const char *value) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err; - char *optstr; - char *catstr; - - /* FIXME: If value is NULL, we need to reset the option to default. - But we can't do this. So we error out here. GPGSM needs support - for this. */ - if (category == LC_CTYPE) - { - catstr = "lc-ctype"; - if (!value && gpgsm->lc_ctype_set) - return gpg_error (GPG_ERR_INV_VALUE); - if (value) - gpgsm->lc_ctype_set = 1; - } -#ifdef LC_MESSAGES - else if (category == LC_MESSAGES) - { - catstr = "lc-messages"; - if (!value && gpgsm->lc_messages_set) - return gpg_error (GPG_ERR_INV_VALUE); - if (value) - gpgsm->lc_messages_set = 1; - } -#endif /* LC_MESSAGES */ - else - return gpg_error (GPG_ERR_INV_VALUE); - - if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) - err = gpg_error_from_errno (errno); - else - { - err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, - NULL, NULL, NULL, NULL); - free (optstr); - if (err) - err = map_assuan_error (err); - } - return err; -} - - -/* Forward declaration. */ -static gpgme_status_code_t parse_status (const char *name); - -static gpgme_error_t -gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd, - engine_status_handler_t status_fnc, - void *status_fnc_value) -{ - gpg_error_t err; - char *line; - size_t linelen; - - err = assuan_write_line (ctx, cmd); - if (err) - return map_assuan_error (err); - - do - { - err = assuan_read_line (ctx, &line, &linelen); - if (err) - return map_assuan_error (err); - - if (*line == '#' || !linelen) - continue; - - if (linelen >= 2 - && line[0] == 'O' && line[1] == 'K' - && (line[2] == '\0' || line[2] == ' ')) - return 0; - else if (linelen >= 4 - && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' - && line[3] == ' ') - err = map_assuan_error (atoi (&line[4])); - else if (linelen >= 2 - && line[0] == 'S' && line[1] == ' ') - { - char *rest; - gpgme_status_code_t r; - - rest = strchr (line + 2, ' '); - if (!rest) - rest = line + linelen; /* set to an empty string */ - else - *(rest++) = 0; - - r = parse_status (line + 2); - - if (r >= 0 && status_fnc) - err = status_fnc (status_fnc_value, r, rest); - else - err = gpg_error (GPG_ERR_GENERAL); - } - else - err = gpg_error (GPG_ERR_GENERAL); - } - while (!err); - - return err; -} - - -typedef enum { INPUT_FD, OUTPUT_FD, MESSAGE_FD } fd_type_t; - -static void -gpgsm_clear_fd (engine_gpgsm_t gpgsm, fd_type_t fd_type) -{ -#if !USE_DESCRIPTOR_PASSING - switch (fd_type) - { - case INPUT_FD: - _gpgme_io_close (gpgsm->input_cb.fd); - break; - case OUTPUT_FD: - _gpgme_io_close (gpgsm->output_cb.fd); - break; - case MESSAGE_FD: - _gpgme_io_close (gpgsm->message_cb.fd); - break; - } -#endif -} - -#define COMMANDLINELEN 40 -static gpgme_error_t -gpgsm_set_fd (engine_gpgsm_t gpgsm, fd_type_t fd_type, const char *opt) -{ - gpg_error_t err = 0; - char line[COMMANDLINELEN]; - char *which; - iocb_data_t *iocb_data; - int dir; - int fd; - - switch (fd_type) - { - case INPUT_FD: - which = "INPUT"; - iocb_data = &gpgsm->input_cb; - break; - - case OUTPUT_FD: - which = "OUTPUT"; - iocb_data = &gpgsm->output_cb; - break; - - case MESSAGE_FD: - which = "MESSAGE"; - iocb_data = &gpgsm->message_cb; - break; - - default: - return gpg_error (GPG_ERR_INV_VALUE); - } - - dir = iocb_data->dir; - -#if USE_DESCRIPTOR_PASSING - /* We try to short-cut the communication by giving GPGSM direct - access to the file descriptor, rather than using a pipe. */ - iocb_data->server_fd = _gpgme_data_get_fd (iocb_data->data); - if (iocb_data->server_fd < 0) - { - int fds[2]; - - if (_gpgme_io_pipe (fds, 0) < 0) - return gpg_error_from_errno (errno); - - iocb_data->fd = dir ? fds[0] : fds[1]; - iocb_data->server_fd = dir ? fds[1] : fds[0]; - - if (_gpgme_io_set_close_notify (iocb_data->fd, - close_notify_handler, gpgsm)) - { - err = gpg_error (GPG_ERR_GENERAL); - goto leave_set_fd; - } - } -#endif - - fd = iocb_data->server_fd; - -#if USE_DESCRIPTOR_PASSING - err = assuan_sendfd (gpgsm->assuan_ctx, fd); - if (err) - goto leave_set_fd; - - _gpgme_io_close (fd); - - if (opt) - snprintf (line, COMMANDLINELEN, "%s FD %s", which, opt); - else - snprintf (line, COMMANDLINELEN, "%s FD", which); -#else - if (opt) - snprintf (line, COMMANDLINELEN, "%s FD=%i %s", which, fd, opt); - else - snprintf (line, COMMANDLINELEN, "%s FD=%i", which, fd); -#endif - - err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL); - -#if USE_DESCRIPTOR_PASSING - leave_set_fd: - if (err) - { - _gpgme_io_close (iocb_data->fd); - _gpgme_io_close (iocb_data->server_fd); - iocb_data->fd = -1; - iocb_data->server_fd = -1; - } -#endif - - return err; -} - - -static const char * -map_input_enc (gpgme_data_t d) -{ - switch (gpgme_data_get_encoding (d)) - { - case GPGME_DATA_ENCODING_NONE: - break; - case GPGME_DATA_ENCODING_BINARY: - return "--binary"; - case GPGME_DATA_ENCODING_BASE64: - return "--base64"; - case GPGME_DATA_ENCODING_ARMOR: - return "--armor"; - default: - break; - } - return NULL; -} - - -static int -status_cmp (const void *ap, const void *bp) -{ - const struct status_table_s *a = ap; - const struct status_table_s *b = bp; - - return strcmp (a->name, b->name); -} - - -static gpgme_status_code_t -parse_status (const char *name) -{ - struct status_table_s t, *r; - t.name = name; - r = bsearch (&t, status_table, DIM(status_table) - 1, - sizeof t, status_cmp); - return r ? r->code : -1; -} - - -static gpgme_error_t -status_handler (void *opaque, int fd) -{ - gpg_error_t assuan_err; - gpgme_error_t err = 0; - engine_gpgsm_t gpgsm = opaque; - char *line; - size_t linelen; - - do - { - assuan_err = assuan_read_line (gpgsm->assuan_ctx, &line, &linelen); - if (assuan_err) - { - /* Try our best to terminate the connection friendly. */ - /* assuan_write_line (gpgsm->assuan_ctx, "BYE"); */ - err = map_assuan_error (assuan_err); - DEBUG3 ("fd %d: error from assuan (%d) getting status line : %s \n", - fd, assuan_err, gpg_strerror (err)); - } - else if (linelen >= 3 - && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' - && (line[3] == '\0' || line[3] == ' ')) - { - if (line[3] == ' ') - err = map_assuan_error (atoi (&line[4])); - else - err = gpg_error (GPG_ERR_GENERAL); - DEBUG2 ("fd %d: ERR line - mapped to: %s\n", - fd, err? gpg_strerror (err):"ok"); - } - else if (linelen >= 2 - && line[0] == 'O' && line[1] == 'K' - && (line[2] == '\0' || line[2] == ' ')) - { - if (gpgsm->status.fnc) - err = gpgsm->status.fnc (gpgsm->status.fnc_value, - GPGME_STATUS_EOF, ""); - - if (!err && gpgsm->colon.fnc && gpgsm->colon.any ) - { - /* We must tell a colon function about the EOF. We do - this only when we have seen any data lines. Note - that this inlined use of colon data lines will - eventually be changed into using a regular data - channel. */ - gpgsm->colon.any = 0; - err = gpgsm->colon.fnc (gpgsm->colon.fnc_value, NULL); - } - _gpgme_io_close (gpgsm->status_cb.fd); - DEBUG2 ("fd %d: OK line - final status: %s\n", - fd, err? gpg_strerror (err):"ok"); - return err; - } - else if (linelen > 2 - && line[0] == 'D' && line[1] == ' ' - && gpgsm->colon.fnc) - { - /* We are using the colon handler even for plain inline data - - strange name for that function but for historic reasons - we keep it. */ - /* FIXME We can't use this for binary data because we - assume this is a string. For the current usage of colon - output it is correct. */ - char *src = line + 2; - char *end = line + linelen; - char *dst; - char **aline = &gpgsm->colon.attic.line; - int *alinelen = &gpgsm->colon.attic.linelen; - - if (gpgsm->colon.attic.linesize - < *alinelen + linelen + 1) - { - char *newline = realloc (*aline, *alinelen + linelen + 1); - if (!newline) - err = gpg_error_from_errno (errno); - else - { - *aline = newline; - gpgsm->colon.attic.linesize += linelen + 1; - } - } - if (!err) - { - dst = *aline + *alinelen; - - while (!err && src < end) - { - if (*src == '%' && src + 2 < end) - { - /* Handle escaped characters. */ - ++src; - *dst = _gpgme_hextobyte (src); - (*alinelen)++; - src += 2; - } - else - { - *dst = *src++; - (*alinelen)++; - } - - if (*dst == '\n') - { - /* Terminate the pending line, pass it to the colon - handler and reset it. */ - - gpgsm->colon.any = 1; - if (*alinelen > 1 && *(dst - 1) == '\r') - dst--; - *dst = '\0'; - - /* FIXME How should we handle the return code? */ - err = gpgsm->colon.fnc (gpgsm->colon.fnc_value, *aline); - if (!err) - { - dst = *aline; - *alinelen = 0; - } - } - else - dst++; - } - } - DEBUG2 ("fd %d: D line; final status: %s\n", - fd, err? gpg_strerror (err):"ok"); - } - else if (linelen > 2 - && line[0] == 'S' && line[1] == ' ') - { - char *rest; - gpgme_status_code_t r; - - rest = strchr (line + 2, ' '); - if (!rest) - rest = line + linelen; /* set to an empty string */ - else - *(rest++) = 0; - - r = parse_status (line + 2); - - if (r >= 0) - { - if (gpgsm->status.fnc) - err = gpgsm->status.fnc (gpgsm->status.fnc_value, r, rest); - } - else - fprintf (stderr, "[UNKNOWN STATUS]%s %s", line + 2, rest); - DEBUG3 ("fd %d: S line (%s) - final status: %s\n", - fd, line+2, err? gpg_strerror (err):"ok"); - } - } - while (!err && assuan_pending_line (gpgsm->assuan_ctx)); - - return err; -} - - -static gpgme_error_t -add_io_cb (engine_gpgsm_t gpgsm, iocb_data_t *iocbd, gpgme_io_cb_t handler) -{ - gpgme_error_t err; - - err = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv, - iocbd->fd, iocbd->dir, - handler, iocbd->data, &iocbd->tag); - if (err) - return err; - if (!iocbd->dir) - /* FIXME Kludge around poll() problem. */ - err = _gpgme_io_set_nonblocking (iocbd->fd); - return err; -} - - -static gpgme_error_t -start (engine_gpgsm_t gpgsm, const char *command) -{ - gpgme_error_t err; - int fdlist[5]; - int nfds; - - /* We need to know the fd used by assuan for reads. We do this by - using the assumption that the first returned fd from - assuan_get_active_fds() is always this one. */ - nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */, - fdlist, DIM (fdlist)); - if (nfds < 1) - return gpg_error (GPG_ERR_GENERAL); /* FIXME */ - - /* We duplicate the file descriptor, so we can close it without - disturbing assuan. Alternatively, we could special case - status_fd and register/unregister it manually as needed, but this - increases code duplication and is more complicated as we can not - use the close notifications etc. */ - gpgsm->status_cb.fd = dup (fdlist[0]); - if (gpgsm->status_cb.fd < 0) - return gpg_error_from_syserror (); - - if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd, - close_notify_handler, gpgsm)) - { - close (gpgsm->status_cb.fd); - gpgsm->status_cb.fd = -1; - return gpg_error (GPG_ERR_GENERAL); - } - - err = add_io_cb (gpgsm, &gpgsm->status_cb, status_handler); - if (!err && gpgsm->input_cb.fd != -1) - err = add_io_cb (gpgsm, &gpgsm->input_cb, _gpgme_data_outbound_handler); - if (!err && gpgsm->output_cb.fd != -1) - err = add_io_cb (gpgsm, &gpgsm->output_cb, _gpgme_data_inbound_handler); - if (!err && gpgsm->message_cb.fd != -1) - err = add_io_cb (gpgsm, &gpgsm->message_cb, _gpgme_data_outbound_handler); - - if (!err) - err = map_assuan_error (assuan_write_line (gpgsm->assuan_ctx, command)); - - if (!err) - (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, GPGME_EVENT_START, NULL); - - return err; -} - - -#if USE_DESCRIPTOR_PASSING -static gpgme_error_t -gpgsm_reset (void *engine) -{ - engine_gpgsm_t gpgsm = engine; - - /* We must send a reset because we need to reset the list of - signers. Note that RESET does not reset OPTION commands. */ - return gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET", NULL, NULL); -} -#endif - - -static gpgme_error_t -gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err; - - if (!gpgsm) - return gpg_error (GPG_ERR_INV_VALUE); - - gpgsm->input_cb.data = ciph; - err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data)); - if (err) - return gpg_error (GPG_ERR_GENERAL); /* FIXME */ - gpgsm->output_cb.data = plain; - err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0); - if (err) - return gpg_error (GPG_ERR_GENERAL); /* FIXME */ - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (engine, "DECRYPT"); - return err; -} - - -static gpgme_error_t -gpgsm_delete (void *engine, gpgme_key_t key, int allow_secret) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err; - char *fpr = key->subkeys ? key->subkeys->fpr : NULL; - char *linep = fpr; - char *line; - int length = 8; /* "DELKEYS " */ - - if (!fpr) - return gpg_error (GPG_ERR_INV_VALUE); - - while (*linep) - { - length++; - if (*linep == '%' || *linep == ' ' || *linep == '+') - length += 2; - linep++; - } - length++; - - line = malloc (length); - if (!line) - return gpg_error_from_errno (errno); - - strcpy (line, "DELKEYS "); - linep = &line[8]; - - while (*fpr) - { - switch (*fpr) - { - case '%': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = '5'; - break; - case ' ': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = '0'; - break; - case '+': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = 'B'; - break; - default: - *(linep++) = *fpr; - break; - } - fpr++; - } - *linep = '\0'; - - gpgsm_clear_fd (gpgsm, OUTPUT_FD); - gpgsm_clear_fd (gpgsm, INPUT_FD); - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (gpgsm, line); - free (line); - - return err; -} - - -static gpgme_error_t -set_recipients (engine_gpgsm_t gpgsm, gpgme_key_t recp[]) -{ - gpgme_error_t err = 0; - assuan_context_t ctx = gpgsm->assuan_ctx; - char *line; - int linelen; - int invalid_recipients = 0; - int i = 0; - - linelen = 10 + 40 + 1; /* "RECIPIENT " + guess + '\0'. */ - line = malloc (10 + 40 + 1); - if (!line) - return gpg_error_from_errno (errno); - strcpy (line, "RECIPIENT "); - while (!err && recp[i]) - { - char *fpr; - int newlen; - - if (!recp[i]->subkeys || !recp[i]->subkeys->fpr) - { - invalid_recipients++; - continue; - } - fpr = recp[i]->subkeys->fpr; - - newlen = 11 + strlen (fpr); - if (linelen < newlen) - { - char *newline = realloc (line, newlen); - if (! newline) - { - int saved_errno = errno; - free (line); - return gpg_error_from_errno (saved_errno); - } - line = newline; - linelen = newlen; - } - strcpy (&line[10], fpr); - - err = gpgsm_assuan_simple_command (ctx, line, gpgsm->status.fnc, - gpgsm->status.fnc_value); - /* FIXME: This requires more work. */ - if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY) - invalid_recipients++; - else if (err) - { - free (line); - return err; - } - i++; - } - free (line); - return gpg_error (invalid_recipients - ? GPG_ERR_UNUSABLE_PUBKEY : GPG_ERR_NO_ERROR); -} - - -static gpgme_error_t -gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, - gpgme_data_t plain, gpgme_data_t ciph, int use_armor) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err; - - if (!gpgsm) - return gpg_error (GPG_ERR_INV_VALUE); - if (!recp) - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - - gpgsm->input_cb.data = plain; - err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data)); - if (err) - return err; - gpgsm->output_cb.data = ciph; - err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0); - if (err) - return err; - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = set_recipients (gpgsm, recp); - - if (!err) - err = start (gpgsm, "ENCRYPT"); - - return err; -} - - -static gpgme_error_t -gpgsm_export (void *engine, const char *pattern, unsigned int reserved, - gpgme_data_t keydata, int use_armor) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err = 0; - char *cmd; - - if (!gpgsm || reserved) - return gpg_error (GPG_ERR_INV_VALUE); - - if (!pattern) - pattern = ""; - - cmd = malloc (7 + strlen (pattern) + 1); - if (!cmd) - return gpg_error_from_errno (errno); - strcpy (cmd, "EXPORT "); - strcpy (&cmd[7], pattern); - - gpgsm->output_cb.data = keydata; - err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0); - if (err) - return err; - gpgsm_clear_fd (gpgsm, INPUT_FD); - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (gpgsm, cmd); - free (cmd); - return err; -} - - -static gpgme_error_t -gpgsm_export_ext (void *engine, const char *pattern[], unsigned int reserved, - gpgme_data_t keydata, int use_armor) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err = 0; - char *line; - /* Length is "EXPORT " + p + '\0'. */ - int length = 7 + 1; - char *linep; - - if (!gpgsm || reserved) - return gpg_error (GPG_ERR_INV_VALUE); - - if (pattern && *pattern) - { - const char **pat = pattern; - - while (*pat) - { - const char *patlet = *pat; - - while (*patlet) - { - length++; - if (*patlet == '%' || *patlet == ' ' || *patlet == '+') - length += 2; - patlet++; - } - pat++; - length++; - } - } - line = malloc (length); - if (!line) - return gpg_error_from_errno (errno); - - strcpy (line, "EXPORT "); - linep = &line[7]; - - if (pattern && *pattern) - { - while (*pattern) - { - const char *patlet = *pattern; - - while (*patlet) - { - switch (*patlet) - { - case '%': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = '5'; - break; - case ' ': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = '0'; - break; - case '+': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = 'B'; - break; - default: - *(linep++) = *patlet; - break; - } - patlet++; - } - pattern++; - if (*pattern) - *linep++ = ' '; - } - } - *linep = '\0'; - - gpgsm->output_cb.data = keydata; - err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0); - if (err) - return err; - gpgsm_clear_fd (gpgsm, INPUT_FD); - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (gpgsm, line); - free (line); - return err; -} - - -static gpgme_error_t -gpgsm_genkey (void *engine, gpgme_data_t help_data, int use_armor, - gpgme_data_t pubkey, gpgme_data_t seckey) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err; - - if (!gpgsm || !pubkey || seckey) - return gpg_error (GPG_ERR_INV_VALUE); - - gpgsm->input_cb.data = help_data; - err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data)); - if (err) - return err; - gpgsm->output_cb.data = pubkey; - err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0); - if (err) - return err; - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (gpgsm, "GENKEY"); - return err; -} - - -static gpgme_error_t -gpgsm_import (void *engine, gpgme_data_t keydata) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err; - - if (!gpgsm) - return gpg_error (GPG_ERR_INV_VALUE); - - gpgsm->input_cb.data = keydata; - err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data)); - if (err) - return err; - gpgsm_clear_fd (gpgsm, OUTPUT_FD); - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (gpgsm, "IMPORT"); - return err; -} - - -static gpgme_error_t -gpgsm_keylist (void *engine, const char *pattern, int secret_only, - gpgme_keylist_mode_t mode) -{ - engine_gpgsm_t gpgsm = engine; - char *line; - gpgme_error_t err; - int list_mode = 0; - - if (mode & GPGME_KEYLIST_MODE_LOCAL) - list_mode |= 1; - if (mode & GPGME_KEYLIST_MODE_EXTERN) - list_mode |= 2; - - if (!pattern) - pattern = ""; - - /* Always send list-mode option because RESET does not reset it. */ - if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) - return gpg_error_from_errno (errno); - err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL); - free (line); - if (err) - return err; - - - /* Always send key validation because RESET does not reset it. */ - - /* Use the validation mode if required. We don't check for an error - yet because this is a pretty fresh gpgsm features. */ - gpgsm_assuan_simple_command (gpgsm->assuan_ctx, - (mode & GPGME_KEYLIST_MODE_VALIDATE)? - "OPTION with-validation=1": - "OPTION with-validation=0" , - NULL, NULL); - - - /* Length is "LISTSECRETKEYS " + p + '\0'. */ - line = malloc (15 + strlen (pattern) + 1); - if (!line) - return gpg_error_from_errno (errno); - if (secret_only) - { - strcpy (line, "LISTSECRETKEYS "); - strcpy (&line[15], pattern); - } - else - { - strcpy (line, "LISTKEYS "); - strcpy (&line[9], pattern); - } - - gpgsm_clear_fd (gpgsm, INPUT_FD); - gpgsm_clear_fd (gpgsm, OUTPUT_FD); - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (gpgsm, line); - free (line); - return err; -} - - -static gpgme_error_t -gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only, - int reserved, gpgme_keylist_mode_t mode) -{ - engine_gpgsm_t gpgsm = engine; - char *line; - gpgme_error_t err; - /* Length is "LISTSECRETKEYS " + p + '\0'. */ - int length = 15 + 1; - char *linep; - int any_pattern = 0; - int list_mode = 0; - - if (reserved) - return gpg_error (GPG_ERR_INV_VALUE); - - if (mode & GPGME_KEYLIST_MODE_LOCAL) - list_mode |= 1; - if (mode & GPGME_KEYLIST_MODE_EXTERN) - list_mode |= 2; - - /* Always send list-mode option because RESET does not reset it. */ - if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) - return gpg_error_from_errno (errno); - err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL); - free (line); - if (err) - return err; - - /* Always send key validation because RESET does not reset it. */ - /* Use the validation mode if required. We don't check for an error - yet because this is a pretty fresh gpgsm features. */ - gpgsm_assuan_simple_command (gpgsm->assuan_ctx, - (mode & GPGME_KEYLIST_MODE_VALIDATE)? - "OPTION with-validation=1": - "OPTION with-validation=0" , - NULL, NULL); - - - if (pattern && *pattern) - { - const char **pat = pattern; - - while (*pat) - { - const char *patlet = *pat; - - while (*patlet) - { - length++; - if (*patlet == '%' || *patlet == ' ' || *patlet == '+') - length += 2; - patlet++; - } - pat++; - length++; - } - } - line = malloc (length); - if (!line) - return gpg_error_from_errno (errno); - if (secret_only) - { - strcpy (line, "LISTSECRETKEYS "); - linep = &line[15]; - } - else - { - strcpy (line, "LISTKEYS "); - linep = &line[9]; - } - - if (pattern && *pattern) - { - while (*pattern) - { - const char *patlet = *pattern; - - while (*patlet) - { - switch (*patlet) - { - case '%': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = '5'; - break; - case ' ': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = '0'; - break; - case '+': - *(linep++) = '%'; - *(linep++) = '2'; - *(linep++) = 'B'; - break; - default: - *(linep++) = *patlet; - break; - } - patlet++; - } - any_pattern = 1; - *linep++ = ' '; - pattern++; - } - } - if (any_pattern) - linep--; - *linep = '\0'; - - gpgsm_clear_fd (gpgsm, INPUT_FD); - gpgsm_clear_fd (gpgsm, OUTPUT_FD); - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (gpgsm, line); - free (line); - return err; -} - - -static gpgme_error_t -gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out, - gpgme_sig_mode_t mode, int use_armor, int use_textmode, - int include_certs, gpgme_ctx_t ctx /* FIXME */) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err; - char *assuan_cmd; - int i; - gpgme_key_t key; - - if (!gpgsm) - return gpg_error (GPG_ERR_INV_VALUE); - - /* FIXME: This does not work as RESET does not reset it so we can't - revert back to default. */ - if (include_certs != GPGME_INCLUDE_CERTS_DEFAULT) - { - /* FIXME: Make sure that if we run multiple operations, that we - can reset any previously set value in case the default is - requested. */ - - if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0) - return gpg_error_from_errno (errno); - err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, assuan_cmd, - NULL, NULL); - free (assuan_cmd); - if (err) - return err; - } - - for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++) - { - const char *s = key->subkeys ? key->subkeys->fpr : NULL; - if (s && strlen (s) < 80) - { - char buf[100]; - - strcpy (stpcpy (buf, "SIGNER "), s); - err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, buf, - NULL, NULL); - } - else - err = gpg_error (GPG_ERR_INV_VALUE); - gpgme_key_unref (key); - if (err) - return err; - } - - gpgsm->input_cb.data = in; - err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data)); - if (err) - return err; - gpgsm->output_cb.data = out; - err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0); - if (err) - return err; - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - - err = start (gpgsm, mode == GPGME_SIG_MODE_DETACH - ? "SIGN --detached" : "SIGN"); - return err; -} - - -static gpgme_error_t -gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, - gpgme_data_t plaintext) -{ - engine_gpgsm_t gpgsm = engine; - gpgme_error_t err; - - if (!gpgsm) - return gpg_error (GPG_ERR_INV_VALUE); - - gpgsm->input_cb.data = sig; - err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data)); - if (err) - return err; - if (plaintext) - { - /* Normal or cleartext signature. */ - gpgsm->output_cb.data = plaintext; - err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0); - gpgsm_clear_fd (gpgsm, MESSAGE_FD); - } - else - { - /* Detached signature. */ - gpgsm->message_cb.data = signed_text; - err = gpgsm_set_fd (gpgsm, MESSAGE_FD, 0); - gpgsm_clear_fd (gpgsm, OUTPUT_FD); - } - - if (!err) - err = start (gpgsm, "VERIFY"); - - return err; -} - - -static void -gpgsm_set_status_handler (void *engine, engine_status_handler_t fnc, - void *fnc_value) -{ - engine_gpgsm_t gpgsm = engine; - - gpgsm->status.fnc = fnc; - gpgsm->status.fnc_value = fnc_value; -} - - -static gpgme_error_t -gpgsm_set_colon_line_handler (void *engine, engine_colon_line_handler_t fnc, - void *fnc_value) -{ - engine_gpgsm_t gpgsm = engine; - - gpgsm->colon.fnc = fnc; - gpgsm->colon.fnc_value = fnc_value; - gpgsm->colon.any = 0; - return 0; -} - - -static void -gpgsm_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs) -{ - engine_gpgsm_t gpgsm = engine; - gpgsm->io_cbs = *io_cbs; -} - - -static void -gpgsm_io_event (void *engine, gpgme_event_io_t type, void *type_data) -{ - engine_gpgsm_t gpgsm = engine; - - if (gpgsm->io_cbs.event) - (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, type, type_data); -} - - -struct engine_ops _gpgme_engine_ops_gpgsm = - { - /* Static functions. */ - _gpgme_get_gpgsm_path, - gpgsm_get_version, - gpgsm_get_req_version, - gpgsm_new, - - /* Member functions. */ - gpgsm_release, -#if USE_DESCRIPTOR_PASSING - gpgsm_reset, -#else - NULL, /* reset */ -#endif - gpgsm_set_status_handler, - NULL, /* set_command_handler */ - gpgsm_set_colon_line_handler, - gpgsm_set_locale, - gpgsm_decrypt, - gpgsm_delete, - NULL, /* edit */ - gpgsm_encrypt, - NULL, /* encrypt_sign */ - gpgsm_export, - gpgsm_export_ext, - gpgsm_genkey, - gpgsm_import, - gpgsm_keylist, - gpgsm_keylist_ext, - gpgsm_sign, - NULL, /* trustlist */ - gpgsm_verify, - gpgsm_set_io_cbs, - gpgsm_io_event, - gpgsm_cancel - }; - -#endif /*!HAVE_W32_SYSTEM*/ |