diff options
Diffstat (limited to '')
| -rw-r--r-- | src/ChangeLog | 19 | ||||
| -rw-r--r-- | src/gpgme-tool.c | 237 | 
2 files changed, 210 insertions, 46 deletions
| diff --git a/src/ChangeLog b/src/ChangeLog index 0843a939..27fcd7c3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,24 @@  2010-06-09  Marcus Brinkmann  <[email protected]> +	* gpgme-tool.c (result_add_timestamp): Add missing NULL argument. +	(result_sign_to_xml): Protect against NULL fingerprint. +	(struct server): New members input_fd, input_filename, +	input_stream output_fd, output_filename, output_stream, +	message_filename, message_stream. +	(server_reset_fds): Deallocate those. +	(server_parse_fd): New function. +	(server_data_obj): Take optional filename argument and direction +	argument.  Also take new argument to return a filestream that +	needs to be closed after destroying the data object. +	Change all callers, too. +	(input_notify, output_notify): Removed. +	(cmd_input, cmd_output): New functions. +	(gpgme_server): Do not register input and output notifier. +	(register_commands): Use cmd_input and cmd_output. +	(cmd_message): Rewritten to use server_parse_fd. +	(cmd_delete, cmd_keylist): Fix inverted option check. +	(main) [HAVE_W32CE_SYSTEM]: Sleep a bit to work around bug in ssh. +  	* genkey.c (gpgme_op_genkey): Return err with TRACE_ERR.  2010-05-12  Marcus Brinkmann  <[email protected]> diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c index 0f16aac2..c435d747 100644 --- a/src/gpgme-tool.c +++ b/src/gpgme-tool.c @@ -746,7 +746,7 @@ result_add_timestamp (struct result_xml_state *state, char *name,    char code[20];    snprintf (code, sizeof (code) - 1, "%ui", timestamp); -  result_xml_tag_start (state, name, "unix", code); +  result_xml_tag_start (state, name, "unix", code, NULL);    result_xml_tag_end (state);    return 0;  } @@ -937,7 +937,8 @@ result_sign_to_xml (gpgme_ctx_t ctx, int indent,  	  result_add_pubkey_algo (&state, "pubkey-algo", new_sig->pubkey_algo);  	  result_add_hash_algo (&state, "hash-algo", new_sig->hash_algo);  	  result_add_timestamp (&state, "timestamp", new_sig->timestamp); -	  result_add_fpr (&state, "fpr", new_sig->fpr); +	  if (new_sig->fpr) +	    result_add_fpr (&state, "fpr", new_sig->fpr);  	  result_add_value (&state, "sig-class", new_sig->sig_class);  	  result_xml_tag_end (&state); @@ -1835,7 +1836,15 @@ struct server    gpgme_data_encoding_t input_enc;    gpgme_data_encoding_t output_enc; +  assuan_fd_t input_fd; +  char *input_filename; +  FILE *input_stream; +  assuan_fd_t output_fd; +  char *output_filename; +  FILE *output_stream;    assuan_fd_t message_fd; +  char *message_filename; +  FILE *message_stream;    gpgme_data_encoding_t message_enc;  }; @@ -1856,6 +1865,30 @@ server_write_data (void *hook, const void *buf, size_t len)  } + +static gpg_error_t +server_parse_fd (assuan_context_t ctx, char *line, assuan_fd_t *rfd, +		 char **filename) +{ +  *rfd = ASSUAN_INVALID_FD; +  *filename = NULL; + +  if (! strncasecmp (line, "file=", 5)) +    { +      char *term; +      *filename = strdup (line + 5); +      if (!*filename) +	return gpg_error_from_syserror(); +      term = strchr (*filename, ' '); +      if (term) +	*term = '\0'; +      return 0; +    } +  else +    return assuan_command_parse_fd (ctx, line, rfd); +} +     +  static gpgme_data_encoding_t  server_data_encoding (const char *line)  { @@ -1876,13 +1909,24 @@ server_data_encoding (const char *line)  static gpgme_error_t -server_data_obj (assuan_fd_t fd, gpgme_data_encoding_t encoding, -		 gpgme_data_t *data) +server_data_obj (assuan_fd_t fd, char *fn, int out, +		 gpgme_data_encoding_t encoding, +		 gpgme_data_t *data, FILE **fs)  {    gpgme_error_t err; -  /* For now... */ -  err = gpgme_data_new_from_fd (data, (int) fd); +  *fs = NULL; +  if (fn) +    { +      *fs = fopen (fn, out ? "wb" : "rb"); +      if (!*fs) +	return gpg_error_from_syserror (); + +      err = gpgme_data_new_from_stream (data, *fs); +    } +  else +    err = gpgme_data_new_from_fd (data, (int) fd); +    if (err)      return err;    return gpgme_data_set_encoding (*data, encoding); @@ -1907,6 +1951,37 @@ server_reset_fds (struct server *server)  #endif        server->message_fd = ASSUAN_INVALID_FD;      } +  if (server->input_filename) +    { +      free (server->input_filename); +      server->input_filename = NULL; +    } +  if (server->output_filename) +    { +      free (server->output_filename); +      server->output_filename = NULL; +    } +  if (server->message_filename) +    { +      free (server->message_filename); +      server->message_filename = NULL; +    } +  if (server->input_stream) +    { +      fclose (server->input_stream); +      server->input_stream = NULL; +    } +  if (server->output_stream) +    { +      fclose (server->output_stream); +      server->output_stream = NULL; +    } +  if (server->message_stream) +    { +      fclose (server->message_stream); +      server->message_stream = NULL; +    } +    server->input_enc = GPGME_DATA_ENCODING_NONE;    server->output_enc = GPGME_DATA_ENCODING_NONE;    server->message_enc = GPGME_DATA_ENCODING_NONE; @@ -1922,6 +1997,7 @@ reset_notify (assuan_context_t ctx, char *line)    return 0;  } +  static const char hlp_version[] =     "VERSION [<string>]\n"    "\n" @@ -2065,18 +2141,36 @@ cmd_keylist_mode (assuan_context_t ctx, char *line)  static gpg_error_t -input_notify (assuan_context_t ctx, char *line) +cmd_input (assuan_context_t ctx, char *line)  {    struct server *server = assuan_get_pointer (ctx); +  gpg_error_t err; +  assuan_fd_t sysfd; +  char *filename; + +  err = server_parse_fd (ctx, line, &sysfd, &filename); +  if (err) +    return err; +  server->input_fd = sysfd; +  server->input_filename = filename;    server->input_enc = server_data_encoding (line);    return 0;  }  static gpg_error_t -output_notify (assuan_context_t ctx, char *line) +cmd_output (assuan_context_t ctx, char *line)  {    struct server *server = assuan_get_pointer (ctx); +  gpg_error_t err; +  assuan_fd_t sysfd; +  char *filename; + +  err = server_parse_fd (ctx, line, &sysfd, &filename); +  if (err) +    return err; +  server->output_fd = sysfd; +  server->output_filename = filename;    server->output_enc = server_data_encoding (line);    return 0;  } @@ -2088,11 +2182,13 @@ cmd_message (assuan_context_t ctx, char *line)    struct server *server = assuan_get_pointer (ctx);    gpg_error_t err;    assuan_fd_t sysfd; +  char *filename; -  err = assuan_command_parse_fd (ctx, line, &sysfd); +  err = server_parse_fd (ctx, line, &sysfd, &filename);    if (err)      return err;    server->message_fd = sysfd; +  server->message_filename = filename;    server->message_enc = server_data_encoding (line);    return 0;  } @@ -2131,21 +2227,27 @@ _cmd_decrypt_verify (assuan_context_t ctx, char *line, int verify)    struct server *server = assuan_get_pointer (ctx);    gpg_error_t err;    assuan_fd_t inp_fd; +  char *inp_fn;    assuan_fd_t out_fd; +  char *out_fn;    gpgme_data_t inp_data;    gpgme_data_t out_data;    inp_fd = assuan_get_input_fd (ctx); -  if (inp_fd == ASSUAN_INVALID_FD) +  inp_fn = server->input_filename; +  if (inp_fd == ASSUAN_INVALID_FD && !inp_fn)      return GPG_ERR_ASS_NO_INPUT;    out_fd = assuan_get_output_fd (ctx); -  if (out_fd == ASSUAN_INVALID_FD) +  out_fn = server->output_filename; +  if (out_fd == ASSUAN_INVALID_FD && !out_fn)      return GPG_ERR_ASS_NO_OUTPUT; -  err = server_data_obj (inp_fd, server->input_enc, &inp_data); +  err = server_data_obj (inp_fd, inp_fn, 0, server->input_enc, &inp_data, +			 &server->input_stream);    if (err)      return err; -  err = server_data_obj (out_fd, server->output_enc, &out_data); +  err = server_data_obj (out_fd, out_fn, 1, server->output_enc, &out_data, +			 &server->output_stream);    if (err)      {        gpgme_data_release (inp_data); @@ -2183,7 +2285,9 @@ _cmd_sign_encrypt (assuan_context_t ctx, char *line, int sign)    struct server *server = assuan_get_pointer (ctx);    gpg_error_t err;    assuan_fd_t inp_fd; +  char *inp_fn;    assuan_fd_t out_fd; +  char *out_fn;    gpgme_data_t inp_data = NULL;    gpgme_data_t out_data = NULL;    gpgme_encrypt_flags_t flags = 0; @@ -2198,16 +2302,20 @@ _cmd_sign_encrypt (assuan_context_t ctx, char *line, int sign)      flags |= GPGME_ENCRYPT_EXPECT_SIGN;    inp_fd = assuan_get_input_fd (ctx); +  inp_fn = server->input_filename;    out_fd = assuan_get_output_fd (ctx); -  if (inp_fd != ASSUAN_INVALID_FD) +  out_fn = server->output_filename; +  if (inp_fd != ASSUAN_INVALID_FD || inp_fn)      { -      err = server_data_obj (inp_fd, server->input_enc, &inp_data); +      err = server_data_obj (inp_fd, inp_fn, 0, server->input_enc, &inp_data, +			     &server->input_stream);        if (err)  	return err;      } -  if (out_fd != ASSUAN_INVALID_FD) +  if (out_fd != ASSUAN_INVALID_FD || out_fn)      { -      err = server_data_obj (out_fd, server->output_enc, &out_data); +      err = server_data_obj (out_fd, out_fn, 1, server->output_enc, &out_data, +			     &server->output_stream);        if (err)  	{  	  gpgme_data_release (inp_data); @@ -2246,7 +2354,9 @@ cmd_sign (assuan_context_t ctx, char *line)    struct server *server = assuan_get_pointer (ctx);    gpg_error_t err;    assuan_fd_t inp_fd; +  char *inp_fn;    assuan_fd_t out_fd; +  char *out_fn;    gpgme_data_t inp_data;    gpgme_data_t out_data;    gpgme_sig_mode_t mode = GPGME_SIG_MODE_NORMAL; @@ -2257,16 +2367,20 @@ cmd_sign (assuan_context_t ctx, char *line)      mode = GPGME_SIG_MODE_DETACH;    inp_fd = assuan_get_input_fd (ctx); -  if (inp_fd == ASSUAN_INVALID_FD) +  inp_fn = server->input_filename; +  if (inp_fd == ASSUAN_INVALID_FD && !inp_fn)      return GPG_ERR_ASS_NO_INPUT;    out_fd = assuan_get_output_fd (ctx); -  if (out_fd == ASSUAN_INVALID_FD) +  out_fn = server->output_filename; +  if (out_fd == ASSUAN_INVALID_FD && !out_fn)      return GPG_ERR_ASS_NO_OUTPUT; -  err = server_data_obj (inp_fd, server->input_enc, &inp_data); +  err = server_data_obj (inp_fd, inp_fn, 0, server->input_enc, &inp_data, +			 &server->input_stream);    if (err)      return err; -  err = server_data_obj (out_fd, server->output_enc, &out_data); +  err = server_data_obj (out_fd, out_fn, 1, server->output_enc, &out_data, +			 &server->output_stream);    if (err)      {        gpgme_data_release (inp_data); @@ -2291,31 +2405,40 @@ cmd_verify (assuan_context_t ctx, char *line)    assuan_fd_t inp_fd;    assuan_fd_t msg_fd;    assuan_fd_t out_fd; +  char *inp_fn; +  char *msg_fn; +  char *out_fn;    gpgme_data_t inp_data;    gpgme_data_t msg_data = NULL;    gpgme_data_t out_data = NULL;    inp_fd = assuan_get_input_fd (ctx); -  if (inp_fd == ASSUAN_INVALID_FD) +  inp_fn = server->input_filename; +  if (inp_fd == ASSUAN_INVALID_FD && !inp_fn)      return GPG_ERR_ASS_NO_INPUT;    msg_fd = server->message_fd; +  msg_fn = server->message_filename;    out_fd = assuan_get_output_fd (ctx); -   -  err = server_data_obj (inp_fd, server->input_enc, &inp_data); +  out_fn = server->output_filename; + +  err = server_data_obj (inp_fd, inp_fn, 0, server->input_enc, &inp_data, +			 &server->input_stream);    if (err)      return err; -  if (msg_fd != ASSUAN_INVALID_FD) +  if (msg_fd != ASSUAN_INVALID_FD || msg_fn)      { -      err = server_data_obj (msg_fd, server->message_enc, &msg_data); +      err = server_data_obj (msg_fd, msg_fn, 0, server->message_enc, &msg_data, +			     &server->message_stream);        if (err)  	{  	  gpgme_data_release (inp_data);  	  return err;  	}      } -  if (out_fd != ASSUAN_INVALID_FD) +  if (out_fd != ASSUAN_INVALID_FD || out_fn)      { -      err = server_data_obj (out_fd, server->output_enc, &out_data); +      err = server_data_obj (out_fd, out_fn, 1, server->output_enc, &out_data, +			     &server->output_stream);        if (err)  	{  	  gpgme_data_release (inp_data); @@ -2353,13 +2476,16 @@ cmd_import (assuan_context_t ctx, char *line)      {        gpg_error_t err;        assuan_fd_t inp_fd; +      char *inp_fn;        gpgme_data_t inp_data;        inp_fd = assuan_get_input_fd (ctx); -      if (inp_fd == ASSUAN_INVALID_FD) +      inp_fn = server->input_filename; +      if (inp_fd == ASSUAN_INVALID_FD && !inp_fn)  	return GPG_ERR_ASS_NO_INPUT; -      err = server_data_obj (inp_fd, server->input_enc, &inp_data); +      err = server_data_obj (inp_fd, inp_fn, 0, server->input_enc, &inp_data, +			     &server->input_stream);        if (err)  	return err; @@ -2384,14 +2510,17 @@ cmd_export (assuan_context_t ctx, char *line)    struct server *server = assuan_get_pointer (ctx);    gpg_error_t err;    assuan_fd_t out_fd; +  char *out_fn;    gpgme_data_t out_data;    gpgme_export_mode_t mode = 0;    const char *pattern[2];    out_fd = assuan_get_output_fd (ctx); -  if (out_fd == ASSUAN_INVALID_FD) +  out_fn = server->output_filename; +  if (out_fd == ASSUAN_INVALID_FD && !out_fn)      return GPG_ERR_ASS_NO_OUTPUT; -  err = server_data_obj (out_fd, server->output_enc, &out_data); +  err = server_data_obj (out_fd, out_fn, 1, server->output_enc, &out_data, +			 &server->output_stream);    if (err)      return err; @@ -2438,23 +2567,29 @@ cmd_genkey (assuan_context_t ctx, char *line)    struct server *server = assuan_get_pointer (ctx);    gpg_error_t err;    assuan_fd_t inp_fd; +  char *inp_fn;    assuan_fd_t out_fd; +  char *out_fn;    gpgme_data_t inp_data;    gpgme_data_t out_data = NULL;    gpgme_data_t parms_data = NULL;    const char *parms;    inp_fd = assuan_get_input_fd (ctx); -  if (inp_fd == ASSUAN_INVALID_FD) +  inp_fn = server->input_filename; +  if (inp_fd == ASSUAN_INVALID_FD && !inp_fn)      return GPG_ERR_ASS_NO_INPUT;    out_fd = assuan_get_output_fd (ctx); +  out_fn = server->output_filename; -  err = server_data_obj (inp_fd, server->input_enc, &inp_data); +  err = server_data_obj (inp_fd, inp_fn, 0, server->input_enc, &inp_data, +			 &server->input_stream);    if (err)      return err; -  if (out_fd != ASSUAN_INVALID_FD) +  if (out_fd != ASSUAN_INVALID_FD || out_fn)      { -      err = server_data_obj (out_fd, server->output_enc, &out_data); +      err = server_data_obj (out_fd, out_fn, 1, server->output_enc, &out_data, +			     &server->output_stream);        if (err)  	{  	  gpgme_data_release (inp_data); @@ -2514,12 +2649,14 @@ cmd_delete (assuan_context_t ctx, char *line)  {    struct server *server = assuan_get_pointer (ctx);    int allow_secret = 0; -  const char optstr[] = "--allow-secret "; +  const char optstr[] = "--allow-secret"; -  if (strncasecmp (line, optstr, strlen (optstr))) +  if (!strncasecmp (line, optstr, strlen (optstr)))      {        allow_secret = 1;        line += strlen (optstr); +      while (*line && !spacep (line)) +	line++;      }    return gt_delete (server->gt, line, allow_secret);  } @@ -2532,12 +2669,14 @@ cmd_keylist (assuan_context_t ctx, char *line)    gpg_error_t err;    int secret_only = 0;    const char *pattern[2]; -  const char optstr[] = "--secret-only "; +  const char optstr[] = "--secret-only"; -  if (strncasecmp (line, optstr, strlen (optstr))) +  if (!strncasecmp (line, optstr, strlen (optstr)))      {        secret_only = 1;        line += strlen (optstr); +      while (*line && !spacep (line)) +	line++;      }    pattern[0] = line;    pattern[1] = NULL; @@ -2580,13 +2719,16 @@ cmd_getauditlog (assuan_context_t ctx, char *line)    struct server *server = assuan_get_pointer (ctx);    gpg_error_t err;    assuan_fd_t out_fd; +  char *out_fn;    gpgme_data_t out_data;    unsigned int flags = 0;    out_fd = assuan_get_output_fd (ctx); -  if (out_fd == ASSUAN_INVALID_FD) +  out_fn = server->output_filename; +  if (out_fd == ASSUAN_INVALID_FD && !out_fn)      return GPG_ERR_ASS_NO_OUTPUT; -  err = server_data_obj (out_fd, server->output_enc, &out_data); +  err = server_data_obj (out_fd, out_fn, 1, server->output_enc, &out_data, +			 &server->output_stream);    if (err)      return err; @@ -2722,8 +2864,8 @@ register_commands (assuan_context_t ctx)      { "TEXTMODE", cmd_textmode },      { "INCLUDE_CERTS", cmd_include_certs },      { "KEYLIST_MODE", cmd_keylist_mode }, -    { "INPUT", NULL },  -    { "OUTPUT", NULL },  +    { "INPUT", cmd_input },  +    { "OUTPUT", cmd_output },       { "MESSAGE", cmd_message },      { "RECIPIENT", cmd_recipient },      { "SIGNER", cmd_signer }, @@ -2815,8 +2957,6 @@ gpgme_server (gpgme_tool_t gt)    assuan_set_hello_line (server.assuan_ctx, hello);    assuan_register_reset_notify (server.assuan_ctx, reset_notify); -  assuan_register_input_notify (server.assuan_ctx, input_notify); -  assuan_register_output_notify (server.assuan_ctx, output_notify);  #define DBG_ASSUAN 0    if (DBG_ASSUAN) @@ -2936,6 +3076,11 @@ main (int argc, char *argv[])    gpgme_release (gt.ctx); +#ifdef HAVE_W32CE_SYSTEM +  /* Give the buggy ssh server time to flush the output buffers.  */ +  Sleep (300); +#endif +    return 0;  } | 
