From e776d52ba5d24a22f0148e9dbd162055be6aa521 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Wed, 26 Jan 2005 22:25:36 +0000 Subject: added missing file --- agent/command-ssh.c | 2327 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2327 insertions(+) create mode 100644 agent/command-ssh.c (limited to 'agent/command-ssh.c') diff --git a/agent/command-ssh.c b/agent/command-ssh.c new file mode 100644 index 000000000..a76bbfff7 --- /dev/null +++ b/agent/command-ssh.c @@ -0,0 +1,2327 @@ +/* command-ssh.c - gpg-agent's ssh-agent emulation layer + * Copyright (C) 2004, 2005 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" + +#include + +#include "estream.h" + + + +/* Request types. */ +#define SSH_REQUEST_REQUEST_IDENTITIES 11 +#define SSH_REQUEST_SIGN_REQUEST 13 +#define SSH_REQUEST_ADD_IDENTITY 17 +#define SSH_REQUEST_REMOVE_IDENTITY 18 +#define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19 +#define SSH_REQUEST_LOCK 22 +#define SSH_REQUEST_UNLOCK 23 +#define SSH_REQUEST_ADD_ID_CONSTRAINED 25 + +/* Options. */ +#define SSH_OPT_CONSTRAIN_LIFETIME 1 +#define SSH_OPT_CONSTRAIN_CONFIRM 2 + +/* Response types. */ +#define SSH_RESPONSE_SUCCESS 6 +#define SSH_RESPONSE_FAILURE 5 +#define SSH_RESPONSE_IDENTITIES_ANSWER 12 +#define SSH_RESPONSE_SIGN_RESPONSE 14 + + + + +/* Basic types. */ + +/* A "byte". */ +typedef unsigned char byte_t; + +typedef int (*ssh_request_handler_t) (ctrl_t ctrl, + estream_t request, estream_t response); + +typedef struct ssh_request_spec +{ + byte_t type; + ssh_request_handler_t handler; +} ssh_request_spec_t; + +typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems, gcry_mpi_t *mpis); +typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob, + gcry_mpi_t *mpis); + +typedef struct ssh_key_type_spec +{ + const char *ssh_identifier; + const char *identifier; + const char *elems_key_secret; + const char *elems_key_public; + const char *elems_secret; + const char *elems_signature; + const char *elems_sexp_order; + ssh_key_modifier_t key_modifier; + ssh_signature_encoder_t signature_encoder; + unsigned int flags; +} ssh_key_type_spec_t; + + + +static uint32_t lifetime_default; + +/* General utility functions. */ + +static void * +realloc_secure (void *a, size_t n) +{ + void *p; + + if (a) + p = gcry_realloc (a, n); + else + p = gcry_malloc_secure (n); + + return p; +} + +/* Primitive I/O functions. */ + +static gpg_error_t +es_read_byte (estream_t stream, byte_t *b) +{ + gpg_error_t err; + int ret; + + ret = es_fgetc (stream); + if (ret == EOF) + { + if (es_ferror (stream)) + err = gpg_error_from_errno (errno); + else + err = gpg_error (GPG_ERR_EOF); + } + else + { + *b = ret & 0xFF; + err = 0; + } + + return err; +} + +static gpg_error_t +es_write_byte (estream_t stream, byte_t b) +{ + gpg_error_t err; + int ret; + + ret = es_fputc (b, stream); + if (ret == EOF) + err = gpg_error_from_errno (errno); + else + err = 0; + + return err; +} + +static gpg_error_t +es_read_uint32 (estream_t stream, uint32_t *uint32) +{ + unsigned char buffer[4]; + size_t bytes_read; + gpg_error_t err; + int ret; + + ret = es_read (stream, buffer, sizeof (buffer), &bytes_read); + if (ret) + err = gpg_error_from_errno (errno); + else + { + if (bytes_read != sizeof (buffer)) + err = gpg_error (GPG_ERR_EOF); + else + { + uint32_t n; + + n = (0 + | ((uint32_t) (buffer[0] << 24)) + | ((uint32_t) (buffer[1] << 16)) + | ((uint32_t) (buffer[2] << 8)) + | ((uint32_t) (buffer[3] << 0))); + *uint32 = n; + err = 0; + } + } + + return err; +} + +static gpg_error_t +es_write_uint32 (estream_t stream, uint32_t uint32) +{ + unsigned char buffer[4]; + gpg_error_t err; + int ret; + + buffer[0] = (uint32 >> 24) & 0xFF; + buffer[1] = (uint32 >> 16) & 0xFF; + buffer[2] = (uint32 >> 8) & 0xFF; + buffer[3] = (uint32 >> 0) & 0xFF; + + ret = es_write (stream, buffer, sizeof (buffer), NULL); + if (ret) + err = gpg_error_from_errno (errno); + else + err = 0; + + return err; +} + +static gpg_error_t +es_read_data (estream_t stream, unsigned char *buffer, size_t size) +{ + gpg_error_t err; + size_t bytes_read; + int ret; + + ret = es_read (stream, buffer, size, &bytes_read); + if (ret) + err = gpg_error_from_errno (errno); + else + { + if (bytes_read != size) + err = gpg_error (GPG_ERR_EOF); + else + err = 0; + } + + return err; +} + +static gpg_error_t +es_write_data (estream_t stream, const unsigned char *buffer, size_t size) +{ + gpg_error_t err; + int ret; + + ret = es_write (stream, buffer, size, NULL); + if (ret) + err = gpg_error_from_errno (errno); + else + err = 0; + + return err; +} + +static gpg_error_t +es_read_string (estream_t stream, unsigned int secure, + unsigned char **string, uint32_t *string_size) +{ + gpg_error_t err; + unsigned char *buffer; + uint32_t length; + + buffer = NULL; + + /* Read string length. */ + err = es_read_uint32 (stream, &length); + if (err) + goto out; + + /* Allocate space. */ + if (secure) + buffer = xtrymalloc_secure (length + 1); + else + buffer = xtrymalloc (length + 1); + if (! buffer) + { + /* FIXME: xtrymalloc_secure does not set errno, does it? */ + err = gpg_error_from_errno (errno); + abort (); + goto out; + } + + /* Read data. */ + err = es_read_data (stream, buffer, length); + if (err) + goto out; + + /* Finalize string object. */ + buffer[length] = 0; + *string = buffer; + if (string_size) + *string_size = length; + + out: + + if (err) + xfree (buffer); + + return err; +} + +static gpg_error_t +es_read_cstring (estream_t stream, char **string) +{ + unsigned char *buffer; + gpg_error_t err; + + err = es_read_string (stream, 0, &buffer, NULL); + if (err) + goto out; + + *string = (char *) buffer; + + out: + + return err; +} + +static gpg_error_t +es_write_string (estream_t stream, + const unsigned char *string, uint32_t string_n) +{ + gpg_error_t err; + + err = es_write_uint32 (stream, string_n); + if (err) + goto out; + + err = es_write_data (stream, string, string_n); + + out: + + return err; +} + +static gpg_error_t +es_write_cstring (estream_t stream, const char *string) +{ + gpg_error_t err; + + err = es_write_string (stream, + (const unsigned char *) string, strlen (string)); + + return err; +} + +static gpg_error_t +es_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint) +{ + unsigned char *mpi_data; + uint32_t mpi_data_size; + gpg_error_t err; + gcry_mpi_t mpi; + + mpi_data = NULL; + + err = es_read_string (stream, secure, &mpi_data, &mpi_data_size); + if (err) + goto out; + + err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL); + if (err) + goto out; + + *mpint = mpi; + + out: + + xfree (mpi_data); + + return err; +} + +static gpg_error_t +es_write_mpi (estream_t stream, gcry_mpi_t mpint) +{ + unsigned char *mpi_buffer; + size_t mpi_buffer_n; + gpg_error_t err; + + mpi_buffer = NULL; + + err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint); + if (err) + goto out; + + err = es_write_string (stream, mpi_buffer, mpi_buffer_n); + + out: + + xfree (mpi_buffer); + + return err; +} + +static gpg_error_t +es_read_file (const char *filename, unsigned char **buffer, size_t *buffer_n) +{ + unsigned char *buffer_new; + struct stat statbuf; + estream_t stream; + gpg_error_t err; + int ret; + + buffer_new = NULL; + err = 0; + + stream = es_fopen (filename, "r"); + if (! stream) + { + err = gpg_error_from_errno (errno); + goto out; + } + + ret = fstat (es_fileno (stream), &statbuf); + if (ret) + { + err = gpg_error_from_errno (errno); + goto out; + } + + buffer_new = xtrymalloc (statbuf.st_size); + if (! buffer_new) + { + err = gpg_error_from_errno (errno); + goto out; + } + + err = es_read_data (stream, buffer_new, statbuf.st_size); + if (err) + goto out; + + *buffer = buffer_new; + *buffer_n = statbuf.st_size; + + out: + + if (stream) + es_fclose (stream); + + if (err) + xfree (buffer_new); + + return err; +} + +static gpg_error_t +es_copy (estream_t dst, estream_t src) +{ + char buffer[BUFSIZ]; + size_t bytes_read; + gpg_error_t err; + int ret; + + err = 0; + while (1) + { + ret = es_read (src, buffer, sizeof (buffer), &bytes_read); + if (ret || (! bytes_read)) + { + if (ret) + err = gpg_error_from_errno (errno); + break; + } + ret = es_write (dst, buffer, bytes_read, NULL); + if (ret) + { + err = gpg_error_from_errno (errno); + break; + } + } + + return err; +} + + + +/* MPI lists. */ + +static void +mpint_list_free (gcry_mpi_t *mpi_list) +{ + if (mpi_list) + { + unsigned int i; + + for (i = 0; mpi_list[i]; i++) + gcry_mpi_release (mpi_list[i]); + xfree (mpi_list); + } +} + +static gpg_error_t +ssh_receive_mpint_list (estream_t stream, int secret, + ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list) +{ + const char *elems_secret; + const char *elems; + unsigned int elems_n; + gcry_mpi_t *mpis; + unsigned int i; + gpg_error_t err; + int elem_is_secret; + + mpis = NULL; + err = 0; + + if (secret) + { + elems = key_spec.elems_key_secret; + elems_secret = key_spec.elems_secret; + } + else + { + elems = key_spec.elems_key_public; + elems_secret = ""; + } + elems_n = strlen (elems); + + mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1)); + if (! mpis) + { + err = gpg_error_from_errno (errno); + goto out; + } + + memset (mpis, 0, sizeof (*mpis) * (elems_n + 1)); + + for (i = 0; i < elems_n; i++) + { + elem_is_secret = strchr (elems_secret, elems[i]) ? 1 : 0; + err = es_read_mpi (stream, elem_is_secret, &mpis[i]); + if (err) + break; + } + if (err) + goto out; + + *mpi_list = mpis; + + out: + + if (err) + mpint_list_free (mpis); + + return err; +} + + + +static gpg_error_t +ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis) +{ + gcry_mpi_t p; + gcry_mpi_t q; + gcry_mpi_t u; + + if (strcmp (elems, "nedupq")) + /* Modifying only necessary for secret keys. */ + goto out; + + u = mpis[3]; + p = mpis[4]; + q = mpis[5]; + + if (gcry_mpi_cmp (p, q) > 0) + { + /* P shall be smaller then Q! Swap primes. iqmp becomes u. */ + gcry_mpi_t tmp; + + tmp = mpis[4]; + mpis[4] = mpis[5]; + mpis[5] = tmp; + } + else + /* U needs to be recomputed. */ + gcry_mpi_invm (u, p, q); + + out: + + return 0; +} + +static gpg_error_t +ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis) +{ + unsigned char *data; + size_t data_n; + gpg_error_t err; + gcry_mpi_t s; + + s = mpis[0]; + + err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s); + if (err) + goto out; + + err = es_write_string (signature_blob, data, data_n); + xfree (data); + + out: + + return err; +} + +#define SSH_DSA_SIGNATURE_PADDING 20 +#define SSH_DSA_SIGNATURE_ELEMS 2 + +static gpg_error_t +ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) +{ + unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS]; + unsigned char *data; + size_t data_n; + gpg_error_t err; + int i; + + data = NULL; + + for (i = 0; i < 2; i++) + { + err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]); + if (err) + break; + + if (data_n > SSH_DSA_SIGNATURE_PADDING) + { + err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ + break; + } + + memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0, + SSH_DSA_SIGNATURE_PADDING - data_n); + memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING) + + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n); + + xfree (data); + data = NULL; + } + if (err) + goto out; + + err = es_write_string (signature_blob, buffer, sizeof (buffer)); + + out: + + xfree (data); + + return err; +} + +#define SPEC_FLAG_USE_PKCS1V2 (1 << 0) + + +/* Table holding key type specifications. */ +static ssh_key_type_spec_t ssh_key_types[] = + { + { + "ssh-rsa", "rsa", "nedupq", "en", "dupq", "s", "nedpqu", + ssh_key_modifier_rsa, ssh_signature_encoder_rsa, + SPEC_FLAG_USE_PKCS1V2 + }, + { + "ssh-dss", "dsa", "pqgyx", "pqgy", "x", "rs", "pqgyx", + NULL, ssh_signature_encoder_dsa, + 0 + }, + }; + + + +/* S-Expressions. */ + +static gpg_error_t +ssh_sexp_construct (gcry_sexp_t *sexp, + ssh_key_type_spec_t key_spec, int secret, + gcry_mpi_t *mpis, const char *comment) +{ + gcry_sexp_t sexp_new; + char *sexp_template; + size_t sexp_template_n; + gpg_error_t err; + const char *elems; + size_t elems_n; + unsigned int i; + unsigned int j; + void **arg_list; + + err = 0; + sexp_new = NULL; + arg_list = NULL; + if (secret) + elems = key_spec.elems_sexp_order; + else + elems = key_spec.elems_key_public; + elems_n = strlen (elems); + + sexp_template_n = 33 + strlen (key_spec.identifier) + (elems_n * 6) - (! secret); + sexp_template = xtrymalloc (sexp_template_n); + if (! sexp_template) + { + err = gpg_error_from_errno (errno); + goto out; + } + + arg_list = xtrymalloc (sizeof (*arg_list) * (elems_n + 1)); + if (! arg_list) + { + err = gpg_error_from_errno (errno); + goto out; + } + + sprintf (sexp_template, "(%s-key (%s ", + secret ? "private" : "public", key_spec.identifier); + for (i = 0; i < elems_n; i++) + { + sprintf (strchr (sexp_template, 0), "(%c %%m)", elems[i]); + if (secret) + { + for (j = 0; j < elems_n; j++) + if (key_spec.elems_key_secret[j] == elems[i]) + break; + } + else + j = i; + arg_list[i] = &mpis[j]; + } + arg_list[i] = &comment; + sprintf (strchr (sexp_template, 0), ") (comment %%s))"); + + err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list); + if (err) + goto out; + + *sexp = sexp_new; + + out: + + xfree (arg_list); + xfree (sexp_template); + + return err; +} + +static gpg_error_t +ssh_sexp_extract (gcry_sexp_t sexp, + ssh_key_type_spec_t key_spec, int *secret, + gcry_mpi_t **mpis, const char **comment) +{ + gpg_error_t err; + gcry_sexp_t value_list; + gcry_sexp_t value_pair; + gcry_sexp_t comment_list; + unsigned int i; + char *comment_new; + const char *data; + size_t data_n; + int is_secret; + size_t elems_n; + const char *elems; + gcry_mpi_t *mpis_new; + gcry_mpi_t mpi; + + err = 0; + value_list = NULL; + value_pair = NULL; + comment_list = NULL; + comment_new = NULL; + mpis_new = NULL; + + data = gcry_sexp_nth_data (sexp, 0, &data_n); + if (! data) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + if ((data_n == 10) && (! strncmp (data, "public-key", 10))) + { + is_secret = 0; + elems = key_spec.elems_key_public; + } + else if (((data_n == 11) && (! strncmp (data, "private-key", 11))) + || ((data_n == 21) && (! strncmp (data, "protected-private-key", 21)))) + { + is_secret = 1; + elems = key_spec.elems_key_secret; + } + else + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + elems_n = strlen (elems); + mpis_new = xtrymalloc (sizeof (*mpis_new) * (elems_n + 1)); + if (! mpis_new) + { + err = gpg_error_from_errno (errno); /* FIXME, xtrymalloc+errno. */ + goto out; + } + memset (mpis_new, 0, sizeof (*mpis_new) * (elems_n + 1)); + + value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0); + if (! value_list) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + for (i = 0; i < elems_n; i++) + { + value_pair = gcry_sexp_find_token (value_list, elems + i, 1); + if (! value_pair) + { + err = gpg_error (GPG_ERR_INV_SEXP); + break; + } + + mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_USG); + if (! mpi) + { + err = gpg_error (GPG_ERR_INV_SEXP); + break; + } + mpis_new[i] = mpi; + gcry_sexp_release (value_pair); + value_pair = NULL; + } + if (err) + goto out; + + /* We do not require a comment sublist to be present here. */ + data = NULL; + data_n = 0; + + comment_list = gcry_sexp_find_token (sexp, "comment", 0); + if (comment_list) + data = gcry_sexp_nth_data (comment_list, 1, &data_n); + if (! data) + { + data = "(none)"; + data_n = 6; + } + + comment_new = xtrymalloc (data_n + 1); + if (! comment_new) + { + err = gpg_error_from_errno (errno); + goto out; + } + strncpy (comment_new, data, data_n); + comment_new[data_n] = 0; + + if (secret) + *secret = is_secret; + *mpis = mpis_new; + *comment = comment_new; + + out: + + gcry_sexp_release (value_list); + gcry_sexp_release (value_pair); + gcry_sexp_release (comment_list); + + if (err) + { + xfree (comment_new); + mpint_list_free (mpis_new); + } + + return err; +} + +static gpg_error_t +ssh_sexp_extract_key_type (gcry_sexp_t sexp, const char **key_type) +{ + gcry_sexp_t sublist; + char *key_type_new; + const char *data; + size_t data_n; + gpg_error_t err; + + err = 0; + key_type_new = NULL; + + sublist = gcry_sexp_nth (sexp, 1); + if (! sublist) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + data = gcry_sexp_nth_data (sublist, 0, &data_n); + if (! data) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + key_type_new = xtrymalloc (data_n + 1); + if (! key_type_new) + { + err = gpg_error_from_errno (errno); + goto out; + } + + strncpy (key_type_new, data, data_n); + key_type_new[data_n] = 0; + *key_type = key_type_new; + + out: + + gcry_sexp_release (sublist); + + return err; +} + + + +/* Key I/O. */ + +static gpg_error_t +ssh_key_type_lookup (const char *ssh_name, const char *name, + ssh_key_type_spec_t *spec) +{ + gpg_error_t err; + unsigned int i; + + for (i = 0; i < DIM (ssh_key_types); i++) + if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier))) + || (name && (! strcmp (name, ssh_key_types[i].identifier)))) + break; + + if (i == DIM (ssh_key_types)) + err = gpg_error (GPG_ERR_NOT_FOUND); + else + { + *spec = ssh_key_types[i]; + err = 0; + } + + return err; +} + +static gpg_error_t +ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, int read_comment, + ssh_key_type_spec_t *key_spec) +{ + gpg_error_t err; + char *key_type; + char *comment; + gcry_sexp_t key; + ssh_key_type_spec_t spec; + gcry_mpi_t *mpi_list; + const char *elems; + + mpi_list = NULL; + key_type = NULL; + comment = ""; + key = NULL; + + err = es_read_cstring (stream, &key_type); + if (err) + goto out; + + err = ssh_key_type_lookup (key_type, NULL, &spec); + if (err) + goto out; + + err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list); + if (err) + goto out; + + if (read_comment) + { + err = es_read_cstring (stream, &comment); + if (err) + goto out; + } + + if (secret) + elems = spec.elems_key_secret; + else + elems = spec.elems_key_public; + + if (spec.key_modifier) + { + err = (*spec.key_modifier) (elems, mpi_list); + if (err) + goto out; + } + + err = ssh_sexp_construct (&key, spec, secret, mpi_list, comment); + if (err) + goto out; + + if (key_spec) + *key_spec = spec; + *key_new = key; + + out: + + mpint_list_free (mpi_list); + xfree (key_type); + if (read_comment) + xfree (comment); + + return err; +} + +static gpg_error_t +ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, + const char *type, gcry_mpi_t *mpis) +{ + unsigned char *blob_new; + long int blob_size_new; + estream_t stream; + gpg_error_t err; + unsigned int i; + + blob_new = NULL; + stream = NULL; + err = 0; + + stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! stream) + { + err = gpg_error_from_errno (errno); + goto out; + } + + err = es_write_cstring (stream, type); + if (err) + goto out; + + for (i = 0; mpis[i] && (! err); i++) + err = es_write_mpi (stream, mpis[i]); + if (err) + goto out; + + blob_size_new = es_ftell (stream); + if (blob_size_new == -1) + { + err = gpg_error_from_errno (errno); + goto out; + } + + err = es_fseek (stream, 0, SEEK_SET); + if (err) + goto out; + + blob_new = xtrymalloc (blob_size_new); + if (! blob_new) + { + err = gpg_error_from_errno (errno); + goto out; + } + + err = es_read_data (stream, blob_new, blob_size_new); + if (err) + goto out; + + *blob = blob_new; + *blob_size = blob_size_new; + + out: + + if (stream) + es_fclose (stream); + if (err) + xfree (blob_new); + + return err; +} + + +static gpg_error_t +ssh_send_key_public (estream_t stream, gcry_sexp_t key_public) +{ + ssh_key_type_spec_t spec; + gcry_mpi_t *mpi_list; + const char *key_type; + const char *comment; + unsigned char *blob; + size_t blob_n; + gpg_error_t err; + + key_type = NULL; + mpi_list = NULL; + comment = NULL; + blob = NULL; + + err = ssh_sexp_extract_key_type (key_public, &key_type); + if (err) + goto out; + + err = ssh_key_type_lookup (NULL, key_type, &spec); + if (err) + goto out; + + err = ssh_sexp_extract (key_public, spec, NULL, &mpi_list, &comment); + if (err) + goto out; + + err = ssh_convert_key_to_blob (&blob, &blob_n, spec.ssh_identifier, mpi_list); + if (err) + goto out; + + err = es_write_string (stream, blob, blob_n); + if (err) + goto out; + + err = es_write_cstring (stream, comment); + + out: + + mpint_list_free (mpi_list); + xfree ((void *) key_type); + xfree ((void *) comment); + xfree (blob); + + return err; +} + +static gpg_error_t +ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size, + gcry_sexp_t *key_public, + ssh_key_type_spec_t *key_spec) +{ + estream_t blob_stream; + gpg_error_t err; + + err = 0; + + blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! blob_stream) + { + err = gpg_error_from_errno (errno); + goto out; + } + + err = es_write_data (blob_stream, blob, blob_size); + if (err) + goto out; + + err = es_fseek (blob_stream, 0, SEEK_SET); + if (err) + goto out; + + err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec); + + out: + + if (blob_stream) + es_fclose (blob_stream); + + return err; +} + + + +static gpg_error_t +key_secret_to_public (gcry_sexp_t *key_public, + ssh_key_type_spec_t spec, gcry_sexp_t key_secret) +{ + gpg_error_t err; + gcry_sexp_t value_pair; + unsigned int i; + gcry_mpi_t *mpis; + gcry_mpi_t mpi; + void **arglist; + size_t elems_n; + char *template; + size_t template_n; + const char *elems; + char *comment; + const char *data; + size_t data_n; + + err = 0; + mpis = NULL; + arglist = NULL; + comment = NULL; + template = NULL; + value_pair = NULL; + + elems = spec.elems_key_public; + elems_n = strlen (elems); + + data = NULL; + value_pair = gcry_sexp_find_token (key_secret, "comment", 0); + if (value_pair) + data = gcry_sexp_nth_data (value_pair, 1, &data_n); + if (! data) + { + data = ""; + data_n = 0; + } + + comment = xtrymalloc (data_n + 1); + if (! comment) + { + err = gpg_error_from_errno (errno); + goto out; + } + strncpy (comment, data, data_n); + comment[data_n] = 0; + + gcry_sexp_release (value_pair); + value_pair = NULL; + + template_n = 29 + strlen (spec.identifier) + (elems_n * 7) + 1; + template = xtrymalloc (template_n); + if (! template) + { + err = gpg_error_from_errno (errno); + goto out; + } + + mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1)); + if (! mpis) + { + err = gpg_error_from_errno (errno); /* FIXME: errno. */ + goto out; + } + memset (mpis, 0, sizeof (*mpis) * (elems_n + 1)); + + arglist = xtrymalloc (sizeof (*arglist) * (elems_n + 1)); + if (! arglist) + { + err = gpg_error_from_errno (errno); + goto out; + } + + for (i = 0; i < elems_n; i++) + { + value_pair = gcry_sexp_find_token (key_secret, elems + i, 1); + if (! value_pair) + { + err = gpg_error (GPG_ERR_INV_SEXP); + break; + } + mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_USG); + if (! mpi) + { + err = gpg_error (GPG_ERR_INV_SEXP); + break; + } + gcry_sexp_release (value_pair); + value_pair = NULL; + + mpis[i] = mpi; + arglist[i] = &mpis[i]; + mpi = NULL; + } + if (err) + goto out; + + sprintf (template, "(public-key (%s", spec.identifier); + for (i = 0; i < elems_n; i++) + sprintf (strchr (template, 0)," (%c %%m)", elems[i]); + sprintf (strchr (template, 0), ") (comment %%s))"); + arglist[i] = &comment; + + err = gcry_sexp_build_array (key_public, NULL, template, arglist); + + out: + + gcry_sexp_release (value_pair); + xfree (template); + mpint_list_free (mpis); + xfree (arglist); + xfree (comment); + + return err; +} + + + +static char * +make_cstring (const char *data, size_t data_n) +{ + char *s; + + s = xtrymalloc (data_n + 1); + if (s) + { + strncpy (s, data, data_n); + s[data_n] = 0; + } + + return s; +} + + + +/* Request handler. */ + +static int +ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t response) +{ + const char *key_type; + ssh_key_type_spec_t spec; + struct dirent *dir_entry; + char *key_directory; + size_t key_directory_n; + char *key_path; + unsigned char *buffer; + size_t buffer_n; + uint32_t key_counter; + estream_t key_blobs; + gcry_sexp_t key_secret; + gcry_sexp_t key_public; + DIR *dir; + gpg_error_t err; + int ret; + int bad; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] request identities\n"); + + /* Prepare buffer stream. */ + + key_directory = NULL; + key_secret = NULL; + key_public = NULL; + key_type = NULL; + key_path = NULL; + key_counter = 0; + buffer = NULL; + dir = NULL; + bad = 0; + err = 0; + + key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! key_blobs) + { + err = gpg_error_from_errno (errno); + goto out; + } + + /* Open key directory. */ + key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL); + if (! key_directory) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + key_directory_n = strlen (key_directory); + + key_path = xtrymalloc (key_directory_n + 46); + if (! key_path) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + + sprintf (key_path, "%s/", key_directory); + sprintf (key_path + key_directory_n + 41, ".key"); + + dir = opendir (key_directory); + if (! dir) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + + /* Iterate over key files. */ + + /* FIXME: make sure that buffer gets deallocated properly. */ + + while (1) + { + dir_entry = readdir (dir); + if (dir_entry) + { + if ((strlen (dir_entry->d_name) == 44) + && (! strncmp (dir_entry->d_name + 40, ".key", 4))) + { + strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40); + + /* Read file content. */ + err = es_read_file (key_path, &buffer, &buffer_n); + if (err) + break; + + err = gcry_sexp_sscan (&key_secret, NULL, buffer, buffer_n); + if (err) + break; + + xfree (buffer); + buffer = NULL; + + err = ssh_sexp_extract_key_type (key_secret, &key_type); + if (err) + break; + + err = ssh_key_type_lookup (NULL, key_type, &spec); + if (err) + break; + + xfree ((void *) key_type); + key_type = NULL; + + err = key_secret_to_public (&key_public, spec, key_secret); + if (err) + break; + + gcry_sexp_release (key_secret); + key_secret = NULL; + + err = ssh_send_key_public (key_blobs, key_public); + if (err) + break; + + gcry_sexp_release (key_public); + key_public = NULL; + + key_counter++; + } + } + else + break; + } + if (err) + goto out; + + ret = es_fseek (key_blobs, 0, SEEK_SET); + if (ret) + { + err = gpg_error_from_errno (errno); + goto out; + } + + out: + + /* Send response. */ + + gcry_sexp_release (key_secret); + gcry_sexp_release (key_public); + + es_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER); + if (! es_ferror (response)) + es_write_uint32 (response, err ? 0 : key_counter); + if (! (err || es_ferror (response))) + es_copy (response, key_blobs); + + if (key_blobs) + es_fclose (key_blobs); + if (dir) + closedir (dir); + + free (key_directory); + xfree (key_path); + xfree (buffer); + xfree ((void *) key_type); /* FIXME? */ + + return bad; +} + +static gpg_error_t +data_hash (unsigned char *data, size_t data_n, + int md_algorithm, unsigned char *hash) +{ + gcry_md_hash_buffer (md_algorithm, hash, data, data_n); + + return 0; +} + +static gpg_error_t +data_sign (CTRL ctrl, ssh_signature_encoder_t sig_encoder, + unsigned char **sig, size_t *sig_n) +{ + char description[] = "Please provide the passphrase for key `%c':"; + gpg_error_t err; + gcry_sexp_t signature_sexp; + estream_t stream; + gcry_sexp_t valuelist; + gcry_sexp_t sublist; + gcry_mpi_t sig_value; + unsigned char *sig_blob; + size_t sig_blob_n; + const char *identifier; + const char *identifier_raw; + size_t identifier_n; + ssh_key_type_spec_t spec; + int ret; + unsigned int i; + const char *elems; + size_t elems_n; + gcry_mpi_t *mpis; + + signature_sexp = NULL; + identifier = NULL; + valuelist = NULL; + sublist = NULL; + sig_blob = NULL; + sig_blob_n = 0; + stream = NULL; + sig_value = NULL; + mpis = NULL; + + err = agent_pksign_do (ctrl, description, &signature_sexp, 0); + if (err) + goto out; + + valuelist = gcry_sexp_nth (signature_sexp, 1); + if (! valuelist) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! stream) + { + err = gpg_error_from_errno (errno); + goto out; + } + + identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n); + if (! identifier_raw) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + identifier = make_cstring (identifier_raw, identifier_n); + if (! identifier) + { + err = gpg_error_from_errno (errno); + goto out; + } + + err = ssh_key_type_lookup (NULL, identifier, &spec); + if (err) + goto out; + + err = es_write_cstring (stream, spec.ssh_identifier); + if (err) + goto out; + + elems = spec.elems_signature; + elems_n = strlen (elems); + + mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1)); + if (! mpis) + { + err = gpg_error_from_errno (errno); + goto out; + } + memset (mpis, 0, sizeof (*mpis) * (elems_n + 1)); + + for (i = 0; i < elems_n; i++) + { + sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1); + if (! sublist) + { + err = gpg_error (GPG_ERR_INV_SEXP); + break; + } + + sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG); + if (! sig_value) + { + err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ + break; + } + gcry_sexp_release (sublist); + sublist = NULL; + + mpis[i] = sig_value; + } + if (err) + goto out; + + err = (*sig_encoder) (stream, mpis); + if (err) + goto out; + + sig_blob_n = es_ftell (stream); + if (sig_blob_n == -1) + { + err = gpg_error_from_errno (errno); + goto out; + } + + sig_blob = xtrymalloc (sig_blob_n); + if (! sig_blob) + { + err = gpg_error_from_errno (errno); + goto out; + } + + ret = es_fseek (stream, 0, SEEK_SET); + if (ret) + { + err = gpg_error_from_errno (errno); + goto out; + } + + err = es_read_data (stream, sig_blob, sig_blob_n); + if (err) + goto out; + + *sig = (char *) sig_blob; + *sig_n = sig_blob_n; + + out: + + if (err) + xfree (sig_blob); + + if (stream) + es_fclose (stream); + gcry_sexp_release (valuelist); + gcry_sexp_release (signature_sexp); + gcry_sexp_release (sublist); + mpint_list_free (mpis); + xfree ((void *) identifier); + + return err; +} + +static int +ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) +{ + gcry_sexp_t key; + ssh_key_type_spec_t spec; + unsigned char hash[MAX_DIGEST_LEN]; + unsigned int hash_n; + unsigned char key_grip[20]; + unsigned char *key_blob; + uint32_t key_blob_size; + unsigned char *data; + unsigned char *sig; + size_t sig_n; + uint32_t data_size; + uint32_t flags; + const void *p; + gpg_error_t err; + int bad; + + key_blob = NULL; + data = NULL; + sig = NULL; + key = NULL; + bad = 0; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] sign request\n"); + + /* Receive key. */ + + err = es_read_string (request, 0, &key_blob, &key_blob_size); + if (err) + { + bad = 1; + goto out; + } + + err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec); + if (err) + { + bad = 1; + goto out; + } + + /* Receive data to sign. */ + err = es_read_string (request, 0, &data, &data_size); + if (err) + { + bad = 1; + goto out; + } + + /* FIXME? */ + err = es_read_uint32 (request, &flags); + if (err) + { + bad = 1; + goto out; + } + + /* Hash data. */ + hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1); + if (! hash_n) + { + err = gpg_error (GPG_ERR_INTERNAL); + goto out; + } + err = data_hash (data, data_size, GCRY_MD_SHA1, hash); + if (err) + goto out; + + /* Calculate key grip. */ + p = gcry_pk_get_keygrip (key, key_grip); + if (! p) + { + err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ + goto out; + } + + /* Sign data. */ + + ctrl->digest.algo = GCRY_MD_SHA1; + memcpy (ctrl->digest.value, hash, hash_n); + ctrl->digest.valuelen = hash_n; + ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2); + ctrl->have_keygrip = 1; + memcpy (ctrl->keygrip, key_grip, 20); + + err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n); + + out: + + if (! bad) + { + /* Done. */ + es_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE); + if (! es_ferror (response)) + { + if (! err) + es_write_string (response, sig, sig_n); + else + es_write_byte (response, SSH_RESPONSE_FAILURE); + } + } + + gcry_sexp_release (key); + xfree (key_blob); + xfree (data); + xfree (sig); + + return bad; +} + +static gpg_error_t +get_passphrase (const char *description, size_t passphrase_n, char *passphrase) +{ + struct pin_entry_info_s *pi; + gpg_error_t err; + + err = 0; + pi = gcry_calloc_secure (1, sizeof (*pi) + passphrase_n + 1); + if (! pi) + { + err = gpg_error (GPG_ERR_ENOMEM); + goto out; + } + + pi->min_digits = 0; /* We want a real passphrase. */ + pi->max_digits = 8; + pi->max_tries = 1; + pi->failed_tries = 0; + pi->check_cb = NULL; + pi->check_cb_arg = NULL; + pi->cb_errtext = NULL; + pi->max_length = 100; + + err = agent_askpin (NULL, description, NULL, pi); + if (err) + goto out; + + memcpy (passphrase, pi->pin, passphrase_n); + passphrase[passphrase_n] = 0; + + out: + + xfree (pi); + + return err; +} + +static gpg_error_t +ssh_key_extract_comment (gcry_sexp_t key, char **comment) +{ + gcry_sexp_t comment_list; + char *comment_new; + const char *data; + size_t data_n; + gpg_error_t err; + + comment_list = gcry_sexp_find_token (key, "comment", 0); + if (! comment_list) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + data = gcry_sexp_nth_data (comment_list, 1, &data_n); + if (! data) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + comment_new = xtrymalloc (data_n + 1); + if (! comment_new) + { + err = gpg_error_from_errno (errno); + goto out; + } + + strncpy (comment_new, data, data_n); + comment_new[data_n] = 0; + *comment = comment_new; + err = 0; + + out: + + gcry_sexp_release (comment_list); + + return err; +} + +static gpg_error_t +ssh_key_grip (gcry_sexp_t key, char *buffer) +{ + gpg_error_t err; + char *p; + + /* FIXME: unsigned vs. signed. */ + + p = gcry_pk_get_keygrip (key, buffer); + if (! p) + err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ + else + err = 0; + + return err; +} + +static gpg_error_t +ssh_key_to_buffer (gcry_sexp_t key, const char *passphrase, + unsigned char **buffer, size_t *buffer_n) +{ + unsigned char *buffer_new; + unsigned int buffer_new_n; + gpg_error_t err; + + err = 0; + buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0); + buffer_new = xtrymalloc (buffer_new_n); + /* FIXME: secmem? */ + if (! buffer_new) + { + err = gpg_error_from_errno (errno); + goto out; + } + + gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n); + /* FIXME: guarantee? */ + + err = agent_protect (buffer_new, passphrase, buffer, buffer_n); + + out: + + xfree (buffer_new); + + return err; +} + +static gpg_error_t +ssh_identity_register (gcry_sexp_t key, int ttl) +{ + unsigned char key_grip_raw[21]; + unsigned char *buffer; + unsigned int buffer_n; + char passphrase[100]; + size_t description_length; + char *description; + char key_grip[41]; + char *comment; + gpg_error_t err; + + int ret; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] registering identity `%s'\n", key_grip); + + description = NULL; + comment = NULL; + buffer = NULL; + + err = ssh_key_grip (key, key_grip_raw); + if (err) + goto out; + + key_grip_raw[sizeof (key_grip_raw) - 1] = 0; + ret = agent_key_available (key_grip_raw); + if (! ret) + goto out; + + err = ssh_key_extract_comment (key, &comment); + if (err) + goto out; + + description_length = 95 + (comment ? strlen (comment) : 0); + description = malloc (description_length); + if (! description) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + else + sprintf (description, + "Please provide the passphrase, which should be used " + "for protecting the received secret key `%s':", + comment ? comment : ""); + + err = get_passphrase (description, sizeof (passphrase), passphrase); + if (err) + goto out; + + err = ssh_key_to_buffer (key, passphrase, &buffer, &buffer_n); + if (err) + goto out; + + err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0); + if (err) + goto out; + + err = agent_put_cache (key_grip_raw, passphrase, ttl); + if (err) + goto out; + + out: + + xfree (buffer); + xfree (comment); + xfree (description); + /* FIXME: verify xfree vs free. */ + + return err; +} + +static gpg_error_t +ssh_identity_drop (gcry_sexp_t key) +{ + unsigned char key_grip[21] = { 0 }; + gpg_error_t err; + + err = ssh_key_grip (key, key_grip); + if (err) + goto out; + + key_grip[sizeof (key_grip) - 1] = 0; + + /* FIXME: What to do here - forgetting the passphrase or deleting + the key from key cache? */ + + if (DBG_COMMAND) + log_debug ("[ssh-agent] dropping identity `%s'\n", key_grip); + + out: + + return err; +} + +static int +ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) +{ + gpg_error_t err; + gcry_sexp_t key; + byte_t b; + int confirm; + int death; + int bad; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] add identity\n"); + + confirm = 0; + death = 0; + key = NULL; + bad = 0; + + /* FIXME? */ + err = ssh_receive_key (request, &key, 1, 1, NULL); + if (err) + { + bad = 1; + goto out; + } + + while (1) + { + err = es_read_byte (request, &b); + if (gpg_err_code (err) == GPG_ERR_EOF) + { + err = 0; + break; + } + + switch (b) + { + case SSH_OPT_CONSTRAIN_LIFETIME: + { + uint32_t n = 0; + + err = es_read_uint32 (request, &n); + if (! err) + death = time (NULL) + n; + break; + } + + case SSH_OPT_CONSTRAIN_CONFIRM: + { + confirm = 1; + break; + } + + default: + /* FIXME: log/bad? */ + break; + } + } + if (err) + goto out; + + if (lifetime_default && (! death)) + death = time (NULL) + lifetime_default; + + /* FIXME: are constraints used correctly? */ + + err = ssh_identity_register (key, death); + + out: + + gcry_sexp_release (key); + + if (! bad) + es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + + return bad; +} + +static int +ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, estream_t response) +{ + unsigned char *key_blob; + uint32_t key_blob_size; + gcry_sexp_t key; + gpg_error_t err; + int bad; + + /* Receive key. */ + + if (DBG_COMMAND) + log_debug ("[ssh-agent] remove identity\n"); + + key_blob = NULL; + key = NULL; + bad = 0; + + err = es_read_string (request, 0, &key_blob, &key_blob_size); + if (err) + { + bad = 1; + goto out; + } + + err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL); + if (err) + { + bad = 1; + goto out; + } + + err = ssh_identity_drop (key); + + out: + + xfree (key_blob); + gcry_sexp_release (key); + + if (! bad) + es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + + return bad; +} + +static gpg_error_t +ssh_identities_remove_all (void) +{ + gpg_error_t err; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] remove all identities\n"); + + err = 0; + + /* FIXME: shall we remove _all_ cache entries or only those + registered through the ssh emulation? */ + + return err; +} + +static int +ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request, estream_t response) +{ + gpg_error_t err; + + err = ssh_identities_remove_all (); + es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + + return 0; +} + +static gpg_error_t +ssh_lock (void) +{ + gpg_error_t err; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] lock\n"); + + err = 0; + + return err; +} + +static gpg_error_t +ssh_unlock (void) +{ + gpg_error_t err; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] unlock\n"); + + err = 0; + + return err; +} + +static int +ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response) +{ + gpg_error_t err; + + err = ssh_lock (); + es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + + return 0; +} + +static int +ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) +{ + gpg_error_t err; + + err = ssh_unlock (); + es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + + return 0; +} + + + +/* Associating request types with the corresponding request + handlers. */ + +static ssh_request_spec_t request_specs[] = + { + { SSH_REQUEST_REQUEST_IDENTITIES, ssh_handler_request_identities }, + { SSH_REQUEST_SIGN_REQUEST, ssh_handler_sign_request }, + { SSH_REQUEST_ADD_IDENTITY, ssh_handler_add_identity }, + { SSH_REQUEST_ADD_ID_CONSTRAINED, ssh_handler_add_identity }, + { SSH_REQUEST_REMOVE_IDENTITY, ssh_handler_remove_identity }, + { SSH_REQUEST_REMOVE_ALL_IDENTITIES, ssh_handler_remove_all_identities }, + { SSH_REQUEST_LOCK, ssh_handler_lock }, + { SSH_REQUEST_UNLOCK, ssh_handler_unlock }, + }; + + + +static gpg_error_t +ssh_request_process (ctrl_t ctrl, estream_t request, estream_t response) +{ + byte_t request_type; + gpg_error_t err; + unsigned int i; + int bad; + + err = es_read_byte (request, &request_type); + if (err) + goto out; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] request: %u\n", request_type); + + for (i = 0; i < DIM (request_specs); i++) + if (request_specs[i].type == request_type) + break; + if (i == DIM (request_specs)) + { + err = es_write_byte (response, SSH_RESPONSE_FAILURE); + goto out; + } + + + bad = (*request_specs[i].handler) (ctrl, request, response); + if (bad) + err = GPG_ERR_PROTOCOL_VIOLATION; + + out: + + return err; +} + +void +start_command_handler_ssh (int sock_client) +{ + struct server_control_s ctrl; + gpg_error_t err; + estream_t stream_response; + estream_t stream_request; + estream_t stream_sock; + unsigned char *request; + uint32_t request_size; + size_t size; + int ret; + + /* Setup control structure. */ + + if (DBG_COMMAND) + log_debug ("[ssh-agent] Starting command handler\n"); + + memset (&ctrl, 0, sizeof (ctrl)); + ctrl.connection_fd = sock_client; + + stream_response = NULL; + stream_request = NULL; + stream_sock = NULL; + request = NULL; + + stream_sock = es_fdopen (sock_client, "r+"); + if (! stream_sock) + { + err = gpg_error_from_errno (errno); + goto out; + } + ret = es_setvbuf (stream_sock, NULL, _IONBF, 0); + if (ret) + { + err = gpg_error_from_errno (errno); + goto out; + } + + while (1) + { + /* Create memory streams for request/response data. The entire + request will be stored in secure memory, since it might + contain secret key material. The response does not have to + be stored in secure memory, since we never give out secret + keys. FIXME: wrong place. */ + + /* Retrieve request. */ + err = es_read_string (stream_sock, 1, &request, &request_size); + if (err) + break; + + if (DBG_COMMAND) + log_debug ("[ssh-agent] Received request of length: %u\n", + request_size); + + stream_request = es_mopen (NULL, 0, 0, 1, + realloc_secure, gcry_free, "r+"); + if (! stream_request) + { + err = gpg_error_from_errno (errno); + break; + } + ret = es_setvbuf (stream_request, NULL, _IONBF, 0); + if (ret) + { + err = gpg_error_from_errno (errno); + break; + } + err = es_write_data (stream_request, request, request_size); + if (err) + break; + es_rewind (stream_request); + + stream_response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! stream_response) + { + err = gpg_error_from_errno (errno); + break; + } + + /* Process request. */ + err = ssh_request_process (&ctrl, stream_request, stream_response); + if (err) + break; + + /* Figure out size of response data. */ + size = es_ftell (stream_response); + err = es_fseek (stream_response, 0, SEEK_SET); + if (err) + break; + + /* Write response data to socket stream. */ + err = es_write_uint32 (stream_sock, size); + if (err) + break; + err = es_copy (stream_sock, stream_response); + if (err) + break; + + err = es_fflush (stream_sock); + if (err) + break; + + es_fclose (stream_request); + stream_request = NULL; + es_fclose (stream_response); + stream_response = NULL; + xfree (request); + request = NULL; + }; + + out: + + /* FIXME: logging. */ + + if (stream_sock) + es_fclose (stream_sock); + if (stream_request) + es_fclose (stream_request); + if (stream_response) + es_fclose (stream_response); + xfree (request); /* FIXME? */ + + if (DBG_COMMAND) + log_debug ("[ssh-agent] Leaving ssh command handler: %s\n", gpg_strerror (err)); +} -- cgit From 0cb7a855abde6df462c9333ac59d4675cdad790a Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Wed, 26 Jan 2005 22:33:11 +0000 Subject: 2005-01-26 Moritz Schulte * command-ssh.c (ssh_handler_sign_request): Confirm to agent protocol in case of failure. --- agent/ChangeLog | 4 ++++ agent/command-ssh.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 051ed911e..8c6444b25 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,6 +1,10 @@ 2005-01-26 Moritz Schulte + * command-ssh.c (ssh_handler_sign_request): Confirm to agent + protocol in case of failure. + * command-ssh.c: New file. + * Makefile.am (gpg_agent_SOURCES): New source file: command-ssh.c. * findkey.c (modify_description): New function. diff --git a/agent/command-ssh.c b/agent/command-ssh.c index a76bbfff7..4c13f5059 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1706,14 +1706,14 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) if (! bad) { /* Done. */ - es_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE); - if (! es_ferror (response)) + if (! err) { - if (! err) + es_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE); + if (! es_ferror (response)) es_write_string (response, sig, sig_n); - else - es_write_byte (response, SSH_RESPONSE_FAILURE); } + else + es_write_byte (response, SSH_RESPONSE_FAILURE); } gcry_sexp_release (key); -- cgit From 2b8e9bc5c542316aa9537d4846268d785a7787ae Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Fri, 28 Jan 2005 19:57:14 +0000 Subject: 2005-01-28 Moritz Schulte * command-ssh.c (ssh_handler_add_identity): Pass ctrl to ssh_identity_register(). (ssh_identity_register): New argument: ctrl; pass ctrl to get_passphrase(). (get_passphrase): Pass ctrl instead of NULL to agent_askpin(). (start_command_handler_ssh): Use agent_init_default_ctrl(); deallocate structure members, which might be dynamically allocated. (lifetime_default): Removed variable. (ssh_handler_add_identity): Fix ttl handling; renamed variable `death' to `ttl'. (ssh_identity_register): Fix key grip handling. --- agent/ChangeLog | 15 +++++++++++++++ agent/command-ssh.c | 38 ++++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 16 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 8c6444b25..1d0833a8e 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,18 @@ +2005-01-28 Moritz Schulte + + * command-ssh.c (ssh_handler_add_identity): Pass ctrl to + ssh_identity_register(). + (ssh_identity_register): New argument: ctrl; pass ctrl to + get_passphrase(). + (get_passphrase): Pass ctrl instead of NULL to agent_askpin(). + (start_command_handler_ssh): Use agent_init_default_ctrl(); + deallocate structure members, which might be dynamically + allocated. + (lifetime_default): Removed variable. + (ssh_handler_add_identity): Fix ttl handling; renamed variable + `death' to `ttl'. + (ssh_identity_register): Fix key grip handling. + 2005-01-26 Moritz Schulte * command-ssh.c (ssh_handler_sign_request): Confirm to agent diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 4c13f5059..9d1be4a8d 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -94,8 +94,6 @@ typedef struct ssh_key_type_spec -static uint32_t lifetime_default; - /* General utility functions. */ static void * @@ -1725,7 +1723,8 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) } static gpg_error_t -get_passphrase (const char *description, size_t passphrase_n, char *passphrase) +get_passphrase (ctrl_t ctrl, + const char *description, size_t passphrase_n, char *passphrase) { struct pin_entry_info_s *pi; gpg_error_t err; @@ -1747,7 +1746,7 @@ get_passphrase (const char *description, size_t passphrase_n, char *passphrase) pi->cb_errtext = NULL; pi->max_length = 100; - err = agent_askpin (NULL, description, NULL, pi); + err = agent_askpin (ctrl, description, NULL, pi); if (err) goto out; @@ -1851,7 +1850,7 @@ ssh_key_to_buffer (gcry_sexp_t key, const char *passphrase, } static gpg_error_t -ssh_identity_register (gcry_sexp_t key, int ttl) +ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) { unsigned char key_grip_raw[21]; unsigned char *buffer; @@ -1862,11 +1861,11 @@ ssh_identity_register (gcry_sexp_t key, int ttl) char key_grip[41]; char *comment; gpg_error_t err; - + unsigned int i; int ret; if (DBG_COMMAND) - log_debug ("[ssh-agent] registering identity `%s'\n", key_grip); + log_debug ("[ssh-agent] registering identity\n"); description = NULL; comment = NULL; @@ -1898,7 +1897,7 @@ ssh_identity_register (gcry_sexp_t key, int ttl) "for protecting the received secret key `%s':", comment ? comment : ""); - err = get_passphrase (description, sizeof (passphrase), passphrase); + err = get_passphrase (ctrl, description, sizeof (passphrase), passphrase); if (err) goto out; @@ -1910,7 +1909,10 @@ ssh_identity_register (gcry_sexp_t key, int ttl) if (err) goto out; - err = agent_put_cache (key_grip_raw, passphrase, ttl); + for (i = 0; i < 20; i++) + sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]); + + err = agent_put_cache (key_grip, passphrase, ttl); if (err) goto out; @@ -1954,15 +1956,15 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) gcry_sexp_t key; byte_t b; int confirm; - int death; + int ttl; int bad; if (DBG_COMMAND) log_debug ("[ssh-agent] add identity\n"); confirm = 0; - death = 0; key = NULL; + ttl = 0; bad = 0; /* FIXME? */ @@ -1990,7 +1992,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) err = es_read_uint32 (request, &n); if (! err) - death = time (NULL) + n; + ttl = n; break; } @@ -2008,12 +2010,9 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) if (err) goto out; - if (lifetime_default && (! death)) - death = time (NULL) + lifetime_default; - /* FIXME: are constraints used correctly? */ - err = ssh_identity_register (key, death); + err = ssh_identity_register (ctrl, key, ttl); out: @@ -2217,6 +2216,7 @@ start_command_handler_ssh (int sock_client) log_debug ("[ssh-agent] Starting command handler\n"); memset (&ctrl, 0, sizeof (ctrl)); + agent_init_default_ctrl (&ctrl); ctrl.connection_fd = sock_client; stream_response = NULL; @@ -2324,4 +2324,10 @@ start_command_handler_ssh (int sock_client) if (DBG_COMMAND) log_debug ("[ssh-agent] Leaving ssh command handler: %s\n", gpg_strerror (err)); + + free (ctrl.display); + free (ctrl.ttyname); + free (ctrl.ttytype); + free (ctrl.lc_ctype); + free (ctrl.lc_messages); } -- cgit From 5ba1e5cfb7ec1589a33a99dbab6d0071400b4112 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Sat, 29 Jan 2005 22:43:00 +0000 Subject: 2005-01-29 Moritz Schulte * command-ssh.c (ssh_handler_request_identities) (ssh_handler_sign_request, ssh_handler_add_identity) (ssh_handler_remove_identity, ssh_handler_remove_all_identities) (ssh_handler_lock, ssh_handler_unlock): Changed to return an error code instead of a boolean. (ssh_request_process): Changed to return a boolean instead of an error; adjust caller. (ssh_request_handle_t): Adjusted type. (ssh_request_spec): New member: identifier. (REQUEST_SPEC_DEFINE): New macro; use it for initialization of request_specs[]. (ssh_request_process): In debugging mode, log identifier of handler to execute. (start_command_handler_ssh): Moved most of the stream handling code ... (ssh_request_process): ... here. --- agent/ChangeLog | 19 +++ agent/command-ssh.c | 435 ++++++++++++++++++++++++++-------------------------- 2 files changed, 240 insertions(+), 214 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 1d0833a8e..bf3ffe824 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,22 @@ +2005-01-29 Moritz Schulte + + * command-ssh.c (ssh_handler_request_identities) + (ssh_handler_sign_request, ssh_handler_add_identity) + (ssh_handler_remove_identity, ssh_handler_remove_all_identities) + (ssh_handler_lock, ssh_handler_unlock): Changed to return an error + code instead of a boolean. + (ssh_request_process): Changed to return a boolean instead of an + error; adjust caller. + (ssh_request_handle_t): Adjusted type. + (ssh_request_spec): New member: identifier. + (REQUEST_SPEC_DEFINE): New macro; use it for initialization of + request_specs[]. + (ssh_request_process): In debugging mode, log identifier of + handler to execute. + (start_command_handler_ssh): Moved most of the stream handling + code ... + (ssh_request_process): ... here. + 2005-01-28 Moritz Schulte * command-ssh.c (ssh_handler_add_identity): Pass ctrl to diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 9d1be4a8d..db0e8daa9 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -19,6 +19,8 @@ * 02111-1307, USA */ +/* Only v2 of the ssh-agent protocol is implemented. */ + #include #include #include @@ -65,13 +67,15 @@ /* A "byte". */ typedef unsigned char byte_t; -typedef int (*ssh_request_handler_t) (ctrl_t ctrl, - estream_t request, estream_t response); +typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl, + estream_t request, + estream_t response); typedef struct ssh_request_spec { byte_t type; ssh_request_handler_t handler; + const char *identifier; } ssh_request_spec_t; typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems, gcry_mpi_t *mpis); @@ -105,7 +109,7 @@ realloc_secure (void *a, size_t n) p = gcry_realloc (a, n); else p = gcry_malloc_secure (n); - + return p; } @@ -1283,7 +1287,7 @@ make_cstring (const char *data, size_t data_n) /* Request handler. */ -static int +static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t response) { const char *key_type; @@ -1300,11 +1304,8 @@ ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t respon gcry_sexp_t key_public; DIR *dir; gpg_error_t err; + gpg_error_t ret_err; int ret; - int bad; - - if (DBG_COMMAND) - log_debug ("[ssh-agent] request identities\n"); /* Prepare buffer stream. */ @@ -1316,7 +1317,6 @@ ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t respon key_counter = 0; buffer = NULL; dir = NULL; - bad = 0; err = 0; key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); @@ -1426,11 +1426,25 @@ ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t respon gcry_sexp_release (key_secret); gcry_sexp_release (key_public); - es_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER); - if (! es_ferror (response)) - es_write_uint32 (response, err ? 0 : key_counter); - if (! (err || es_ferror (response))) - es_copy (response, key_blobs); + if (! err) + { + ret_err = es_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER); + if (ret_err) + goto leave; + ret_err = es_write_uint32 (response, key_counter); + if (ret_err) + goto leave; + ret_err = es_copy (response, key_blobs); + if (ret_err) + goto leave; + } + else + { + ret_err = es_write_byte (response, SSH_RESPONSE_FAILURE); + goto leave; + }; + + leave: if (key_blobs) es_fclose (key_blobs); @@ -1442,7 +1456,7 @@ ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t respon xfree (buffer); xfree ((void *) key_type); /* FIXME? */ - return bad; + return ret_err; } static gpg_error_t @@ -1609,7 +1623,7 @@ data_sign (CTRL ctrl, ssh_signature_encoder_t sig_encoder, return err; } -static int +static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) { gcry_sexp_t key; @@ -1626,48 +1640,32 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) uint32_t flags; const void *p; gpg_error_t err; - int bad; + gpg_error_t ret_err; key_blob = NULL; data = NULL; sig = NULL; key = NULL; - bad = 0; - - if (DBG_COMMAND) - log_debug ("[ssh-agent] sign request\n"); /* Receive key. */ err = es_read_string (request, 0, &key_blob, &key_blob_size); if (err) - { - bad = 1; - goto out; - } + goto out; err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec); if (err) - { - bad = 1; - goto out; - } + goto out; /* Receive data to sign. */ err = es_read_string (request, 0, &data, &data_size); if (err) - { - bad = 1; - goto out; - } + goto out; /* FIXME? */ err = es_read_uint32 (request, &flags); if (err) - { - bad = 1; - goto out; - } + goto out; /* Hash data. */ hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1); @@ -1701,25 +1699,32 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) out: - if (! bad) + /* Done. */ + + if (! err) { - /* Done. */ - if (! err) - { - es_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE); - if (! es_ferror (response)) - es_write_string (response, sig, sig_n); - } - else - es_write_byte (response, SSH_RESPONSE_FAILURE); + ret_err = es_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE); + if (ret_err) + goto leave; + ret_err = es_write_string (response, sig, sig_n); + if (ret_err) + goto leave; + } + else + { + ret_err = es_write_byte (response, SSH_RESPONSE_FAILURE); + if (ret_err) + goto leave; } + leave: + gcry_sexp_release (key); xfree (key_blob); xfree (data); xfree (sig); - return bad; + return ret_err; } static gpg_error_t @@ -1864,9 +1869,6 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) unsigned int i; int ret; - if (DBG_COMMAND) - log_debug ("[ssh-agent] registering identity\n"); - description = NULL; comment = NULL; buffer = NULL; @@ -1941,39 +1943,29 @@ ssh_identity_drop (gcry_sexp_t key) /* FIXME: What to do here - forgetting the passphrase or deleting the key from key cache? */ - if (DBG_COMMAND) - log_debug ("[ssh-agent] dropping identity `%s'\n", key_grip); - out: return err; } -static int +static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) { + gpg_error_t ret_err; gpg_error_t err; gcry_sexp_t key; byte_t b; int confirm; int ttl; - int bad; - if (DBG_COMMAND) - log_debug ("[ssh-agent] add identity\n"); - confirm = 0; key = NULL; ttl = 0; - bad = 0; /* FIXME? */ err = ssh_receive_key (request, &key, 1, 1, NULL); if (err) - { - bad = 1; - goto out; - } + goto out; while (1) { @@ -2018,43 +2010,33 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) gcry_sexp_release (key); - if (! bad) - es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + ret_err = es_write_byte (response, + err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); - return bad; + return ret_err; } -static int +static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, estream_t response) { unsigned char *key_blob; uint32_t key_blob_size; gcry_sexp_t key; + gpg_error_t ret_err; gpg_error_t err; - int bad; /* Receive key. */ - if (DBG_COMMAND) - log_debug ("[ssh-agent] remove identity\n"); - key_blob = NULL; key = NULL; - bad = 0; err = es_read_string (request, 0, &key_blob, &key_blob_size); if (err) - { - bad = 1; - goto out; - } + goto out; err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL); if (err) - { - bad = 1; - goto out; - } + goto out; err = ssh_identity_drop (key); @@ -2063,10 +2045,10 @@ ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, estream_t response) xfree (key_blob); gcry_sexp_release (key); - if (! bad) - es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + ret_err = es_write_byte (response, + err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); - return bad; + return ret_err; } static gpg_error_t @@ -2074,9 +2056,6 @@ ssh_identities_remove_all (void) { gpg_error_t err; - if (DBG_COMMAND) - log_debug ("[ssh-agent] remove all identities\n"); - err = 0; /* FIXME: shall we remove _all_ cache entries or only those @@ -2085,15 +2064,17 @@ ssh_identities_remove_all (void) return err; } -static int +static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request, estream_t response) { + gpg_error_t ret_err; gpg_error_t err; err = ssh_identities_remove_all (); - es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + ret_err = es_write_byte (response, + err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); - return 0; + return ret_err; } static gpg_error_t @@ -2101,9 +2082,8 @@ ssh_lock (void) { gpg_error_t err; - if (DBG_COMMAND) - log_debug ("[ssh-agent] lock\n"); - + /* FIXME */ + log_error ("[gpg-agent/ssh] lock command is not implemented\n"); err = 0; return err; @@ -2114,34 +2094,36 @@ ssh_unlock (void) { gpg_error_t err; - if (DBG_COMMAND) - log_debug ("[ssh-agent] unlock\n"); - + log_error ("[gpg-agent/ssh] unlock command is not implemented\n"); err = 0; return err; } -static int +static gpg_error_t ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response) { + gpg_error_t ret_err; gpg_error_t err; err = ssh_lock (); - es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + ret_err = es_write_byte (response, + err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); - return 0; + return ret_err; } -static int +static gpg_error_t ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) { + gpg_error_t ret_err; gpg_error_t err; - err = ssh_unlock (); - es_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + err = ssh_unlock (); + ret_err = es_write_byte (response, + err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); - return 0; + return ret_err; } @@ -2149,181 +2131,206 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) /* Associating request types with the corresponding request handlers. */ +#define REQUEST_SPEC_DEFINE(id, name) \ + { SSH_REQUEST_##id, ssh_handler_##name, #name } + static ssh_request_spec_t request_specs[] = { - { SSH_REQUEST_REQUEST_IDENTITIES, ssh_handler_request_identities }, - { SSH_REQUEST_SIGN_REQUEST, ssh_handler_sign_request }, - { SSH_REQUEST_ADD_IDENTITY, ssh_handler_add_identity }, - { SSH_REQUEST_ADD_ID_CONSTRAINED, ssh_handler_add_identity }, - { SSH_REQUEST_REMOVE_IDENTITY, ssh_handler_remove_identity }, - { SSH_REQUEST_REMOVE_ALL_IDENTITIES, ssh_handler_remove_all_identities }, - { SSH_REQUEST_LOCK, ssh_handler_lock }, - { SSH_REQUEST_UNLOCK, ssh_handler_unlock }, + REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities), + REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request), + REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity), + REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity), + REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity), + REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities), + REQUEST_SPEC_DEFINE (LOCK, lock), + REQUEST_SPEC_DEFINE (UNLOCK, unlock) }; -static gpg_error_t -ssh_request_process (ctrl_t ctrl, estream_t request, estream_t response) +static int +ssh_request_process (ctrl_t ctrl, estream_t stream_sock) { + estream_t response; + estream_t request; byte_t request_type; gpg_error_t err; unsigned int i; - int bad; + int send_err; + int ret; + unsigned char *request_data; + uint32_t request_data_size; + uint32_t response_size; - err = es_read_byte (request, &request_type); + request_data = NULL; + response = NULL; + request = NULL; + send_err = 0; + + /* Create memory streams for request/response data. The entire + request will be stored in secure memory, since it might contain + secret key material. The response does not have to be stored in + secure memory, since we never give out secret keys. */ + + /* Retrieve request. */ + err = es_read_string (stream_sock, 1, &request_data, &request_data_size); + if (err) + goto out; + + if (opt.verbose) + log_debug ("[gpg-agent/ssh] Received request of length: %u\n", + request_data_size); + + request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+"); + if (! request) + { + err = gpg_error_from_errno (errno); + goto out; + } + ret = es_setvbuf (request, NULL, _IONBF, 0); + if (ret) + { + err = gpg_error_from_errno (errno); + goto out; + } + err = es_write_data (request, request_data, request_data_size); if (err) goto out; + es_rewind (request); - if (DBG_COMMAND) - log_debug ("[ssh-agent] request: %u\n", request_type); + response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! response) + { + err = gpg_error_from_errno (errno); + goto out; + } + + err = es_read_byte (request, &request_type); + if (err) + { + send_err = 1; + goto out; + } for (i = 0; i < DIM (request_specs); i++) if (request_specs[i].type == request_type) break; if (i == DIM (request_specs)) { - err = es_write_byte (response, SSH_RESPONSE_FAILURE); + log_debug ("[gpg-agent/ssh] request %u is not supported\n", + request_type); + send_err = 1; goto out; } - - bad = (*request_specs[i].handler) (ctrl, request, response); - if (bad) - err = GPG_ERR_PROTOCOL_VIOLATION; + if (opt.verbose) + log_debug ("[gpg-agent/ssh] Executing request handler: %s (%u)\n", + request_specs[i].identifier, request_specs[i].type); + + err = (*request_specs[i].handler) (ctrl, request, response); + if (err) + { + send_err = 1; + goto out; + } + + response_size = es_ftell (response); + err = es_fseek (response, 0, SEEK_SET); + if (err) + { + send_err = 1; + goto out; + } + + err = es_write_uint32 (stream_sock, response_size); + if (err) + { + send_err = 1; + goto out; + } + + err = es_copy (stream_sock, response); + if (err) + goto out; + + err = es_fflush (stream_sock); + if (err) + goto out; out: - return err; + if (err && es_feof (stream_sock)) + log_error ("[gpg-agent/ssh] Error occured while processing request: %s\n", + gpg_strerror (err)); + + if (send_err) + { + err = es_write_uint32 (stream_sock, 1); + if (err) + goto leave; + err = es_write_byte (stream_sock, SSH_RESPONSE_FAILURE); + if (err) + goto leave; + } + + leave: + + if (request) + es_fclose (request); + if (response) + es_fclose (response); + xfree (request_data); /* FIXME? */ + + return !! err; } void start_command_handler_ssh (int sock_client) { struct server_control_s ctrl; - gpg_error_t err; - estream_t stream_response; - estream_t stream_request; estream_t stream_sock; - unsigned char *request; - uint32_t request_size; - size_t size; + gpg_error_t err; + int bad; int ret; /* Setup control structure. */ - if (DBG_COMMAND) - log_debug ("[ssh-agent] Starting command handler\n"); - memset (&ctrl, 0, sizeof (ctrl)); agent_init_default_ctrl (&ctrl); ctrl.connection_fd = sock_client; - stream_response = NULL; - stream_request = NULL; - stream_sock = NULL; - request = NULL; - + /* Create stream from socket. */ stream_sock = es_fdopen (sock_client, "r+"); if (! stream_sock) { err = gpg_error_from_errno (errno); + log_error ("[gpg-agent/ssh] Failed to create stream from socket: %s\n", + gpg_strerror (err)); goto out; } + /* We have to disable the estream buffering, because the estream + core doesn't know about secure memory. */ ret = es_setvbuf (stream_sock, NULL, _IONBF, 0); if (ret) { err = gpg_error_from_errno (errno); + log_error ("[gpg-agent/ssh] Failed to disable buffering " + "on socket stream: %s\n", gpg_strerror (err)); goto out; } while (1) { - /* Create memory streams for request/response data. The entire - request will be stored in secure memory, since it might - contain secret key material. The response does not have to - be stored in secure memory, since we never give out secret - keys. FIXME: wrong place. */ - - /* Retrieve request. */ - err = es_read_string (stream_sock, 1, &request, &request_size); - if (err) - break; - - if (DBG_COMMAND) - log_debug ("[ssh-agent] Received request of length: %u\n", - request_size); - - stream_request = es_mopen (NULL, 0, 0, 1, - realloc_secure, gcry_free, "r+"); - if (! stream_request) - { - err = gpg_error_from_errno (errno); - break; - } - ret = es_setvbuf (stream_request, NULL, _IONBF, 0); - if (ret) - { - err = gpg_error_from_errno (errno); - break; - } - err = es_write_data (stream_request, request, request_size); - if (err) - break; - es_rewind (stream_request); - - stream_response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); - if (! stream_response) - { - err = gpg_error_from_errno (errno); - break; - } - /* Process request. */ - err = ssh_request_process (&ctrl, stream_request, stream_response); - if (err) - break; - - /* Figure out size of response data. */ - size = es_ftell (stream_response); - err = es_fseek (stream_response, 0, SEEK_SET); - if (err) - break; - - /* Write response data to socket stream. */ - err = es_write_uint32 (stream_sock, size); - if (err) - break; - err = es_copy (stream_sock, stream_response); - if (err) + bad = ssh_request_process (&ctrl, stream_sock); + if (bad) break; - - err = es_fflush (stream_sock); - if (err) - break; - - es_fclose (stream_request); - stream_request = NULL; - es_fclose (stream_response); - stream_response = NULL; - xfree (request); - request = NULL; }; out: - /* FIXME: logging. */ - if (stream_sock) es_fclose (stream_sock); - if (stream_request) - es_fclose (stream_request); - if (stream_response) - es_fclose (stream_response); - xfree (request); /* FIXME? */ - - if (DBG_COMMAND) - log_debug ("[ssh-agent] Leaving ssh command handler: %s\n", gpg_strerror (err)); free (ctrl.display); free (ctrl.ttyname); -- cgit From b326996b784b561ab56af5b41037f60ae8a79849 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 3 Feb 2005 17:40:02 +0000 Subject: * AUTHORS: Copied from 1.4 and edited to refelct the changes in 1.9. * agent.h (agent_exit): Add JNLIB_GCC_A_NR to indicate that this function won't return. * gpg-agent.c (check_for_running_agent): Initialize pid to a default value if not needed. * command-ssh.c: Removed stdint.h. s/byte_t/unsigned char/, s/uint32/u32/ becuase that is what we have always used in GnuPG. (ssh_request_specs): Moved to top of file. (ssh_key_types): Ditto. (make_cstring): Ditto. (data_sign): Don't use a variable for the passphrase prompt, make it translatable. (ssh_request_process): * findkey.c (modify_description): Renamed arguments for clarity, polished documentation. Make comment a C-string. Fixed case of DESCRIPTION being just "%". (agent_key_from_file): Make sure comment string to a C-string. * gpg-agent.c (create_socket_name): Cleanup the implemntation, use DIMof, agent_exit, removed superflous args and return the allocated string as value. Documented. Changed callers. (create_server_socket): Cleanups similar to above. Changed callers. (cleanup_do): Renamed to .. (remove_socket): .. this. Changed caller. (handle_connections): The signals are to be handled in the select and not in the accept. Test all FDs after returning from a select. Remove the event tests from the accept calls. The select already assured that the accept won't block. --- AUTHORS | 140 +++++++++++++++++++ ChangeLog | 5 + agent/ChangeLog | 36 ++++- agent/agent.h | 30 ++-- agent/command-ssh.c | 351 ++++++++++++++++++++++++++++++----------------- agent/findkey.c | 200 +++++++++++++-------------- agent/gpg-agent.c | 383 ++++++++++++++++++++++++++++------------------------ common/estream.h | 3 +- 8 files changed, 729 insertions(+), 419 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/AUTHORS b/AUTHORS index e69de29bb..0de6a8662 100644 --- a/AUTHORS +++ b/AUTHORS @@ -0,0 +1,140 @@ +Program: GnuPG +Maintainer: Werner Koch +Bug reports: +Security related bug reports: + +Please note that this file is for the 1.9 branch of GnuPG. + + +Authors +======= + +Ales Nyakhaychyk Translations [be] + +Birger Langkjer Translations [da] + +Maxim Britov Translations [ru] + +Daniel Resare Translations [sv] +Per Tunedal Translations [sv] + +David Shaw Assigns past and future changes. + (all in keyserver/, + a lot of changes in g10/ see the ChangeLog, + bug fixes here and there) + +Dokianakis Theofanis Translations [el] + +Edmund GRIMLEY EVANS Translations [eo] + +Florian Weimer Assigns past and future changes + (changed:g10/parse-packet.c, include/iobuf.h, util/iobuf.c) + +g10 Code GmbH Assigns past and future changes + (all work since 2001 as indicated by mail addresses in ChangeLogs) + +Gaël Quéri Translations [fr] + (fixed a lot of typos) + +Gregory Steuck Translations [ru] + +Nagy Ferenc László Translations [hu] + +Ivo Timmermans Translations [nl] + +Jacobo Tarri'o Barreiro Translations [gl] + +Janusz Aleksander Urbanowicz Translations [po] + +Jedi Lin Translations [zh-tw] + +Jouni Hiltunen Translations [fi] +Tommi Vainikainen Translations [fi] + +Laurentiu Buzdugan Translations [ro] + +Magda Procha'zkova' Translations [cs] + +Michael Roth Assigns changes. + (wrote cipher/des.c., changes and bug fixes all over the place) + +Michal Majer Translations [sk] + +Marco d'Itri Translations [it] + +Marcus Brinkmann + (gpgconf and fixes all over the place) + +Matthew Skala Disclaimer + (wrote cipher/twofish.c) + +Moritz Schulte + (ssh support gpg-agent) + +Niklas Hernaeus Disclaimer + (weak key patches) + +Nilgun Belma Buguner Translations [tr] + +Nils Ellmenreich + Assigns past and future changes + (configure.in, cipher/rndlinux.c, FAQ) + +Paul Eggert + (configuration macros for LFS) + +Pavel I. Shajdo Translations [ru] + (man pages) + +Pedro Morais Translations [pt_PT] + +Rémi Guyomarch Assigns past and future changes. + (g10/compress.c, g10/encr-data.c, + g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c) + +Stefan Bellon Assigns past and future changes. + (All patches to support RISC OS) + +Timo Schulz Assigns past and future changes. + (util/w32reg.c, g10/passphrase.c, g10/hkp.c) + +Tedi Heriyanto Translations [id] + +Thiago Jung Bauermann Translations [pt_BR] +Rafael Caetano dos Santos Translations [pt_BR] + +Toomas Soome Translations [et] + +Urko Lusa Translations [es_ES] + +Walter Koch Translations [de] + +Werner Koch Assigns GNU Privacy Guard and future changes. + (started the whole thing, wrote the S/MIME extensions, the + smartcard daemon and the gpg-agent) + +Yosiaki IIDA Translations [ja] + + + +Other authors +============= + +The files common/libestream.[ch] are maintained as a separate project +by g10 Code GmbH. These files, as used here, are considered part of +GnuPG. + +The RPM specs file scripts/gnupg.spec has been contributed by +several people. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004, + 2005 Free Software Foundation, Inc. + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + diff --git a/ChangeLog b/ChangeLog index f878f60d8..2c86f42a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-02-03 Werner Koch + + * AUTHORS: Copied from 1.4 and edited to refelct the changes in + 1.9. + 2005-01-17 Werner Koch * configure.ac: Make --without-included-regex work as expected. diff --git a/agent/ChangeLog b/agent/ChangeLog index bf3ffe824..3bd779256 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,37 @@ +2005-02-03 Werner Koch + + * agent.h (agent_exit): Add JNLIB_GCC_A_NR to indicate that this + function won't return. + + * gpg-agent.c (check_for_running_agent): Initialize pid to a + default value if not needed. + + * command-ssh.c: Removed stdint.h. s/byte_t/unsigned char/, + s/uint32/u32/ becuase that is what we have always used in GnuPG. + (ssh_request_specs): Moved to top of file. + (ssh_key_types): Ditto. + (make_cstring): Ditto. + (data_sign): Don't use a variable for the passphrase prompt, make + it translatable. + (ssh_request_process): + + + * findkey.c (modify_description): Renamed arguments for clarity, + polished documentation. Make comment a C-string. Fixed case of + DESCRIPTION being just "%". + (agent_key_from_file): Make sure comment string to a C-string. + + * gpg-agent.c (create_socket_name): Cleanup the implemntation, use + DIMof, agent_exit, removed superflous args and return the + allocated string as value. Documented. Changed callers. + (create_server_socket): Cleanups similar to above. Changed callers. + (cleanup_do): Renamed to .. + (remove_socket): .. this. Changed caller. + (handle_connections): The signals are to be handled in the select + and not in the accept. Test all FDs after returning from a + select. Remove the event tests from the accept calls. The select + already assured that the accept won't block. + 2005-01-29 Moritz Schulte * command-ssh.c (ssh_handler_request_identities) @@ -67,7 +101,7 @@ and ssh-agent protocol. * agent.h (struct opt): New member: ssh_support. - Declare function: start_command_handler_ssh. + (start_command_handler_ssh): Add prototype. 2005-01-04 Werner Koch diff --git a/agent/agent.h b/agent/agent.h index 8afda6463..a1196bc0b 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -47,26 +47,28 @@ out_of_core (void) /* A large struct name "opt" to keep global flags */ struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int dry_run; /* don't change any persistent data */ - int batch; /* batch mode */ - const char *homedir; /* configuration directory name */ - const char *pinentry_program; - const char *scdaemon_program; - int no_grab; /* don't let the pinentry grab the keyboard */ + unsigned int debug; /* Debug flags (DBG_foo_VALUE) */ + int verbose; /* Verbosity level */ + int quiet; /* Be as quiet as possible */ + int dry_run; /* Don't change any persistent data */ + int batch; /* Batch mode */ + const char *homedir; /* Configuration directory name */ + const char *pinentry_program; /* Filename of the program to start as + pinentry. */ + const char *scdaemon_program; /* Filename of the program to handle + smartcard tasks. */ + int no_grab; /* Don't let the pinentry grab the keyboard */ unsigned long def_cache_ttl; unsigned long max_cache_ttl; - int running_detached; /* we are running detached from the tty. */ + int running_detached; /* We are running detached from the tty. */ int ignore_cache_for_signing; int allow_mark_trusted; int allow_preset_passphrase; - int keep_tty; /* don't switch the TTY (for pinentry) on request */ - int keep_display; /* don't switch the DISPLAY (for pinentry) on request */ - int ssh_support; /* Enable ssh-agent emulation. */ + int keep_tty; /* Don't switch the TTY (for pinentry) on request */ + int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */ + int ssh_support; /* Enable ssh-agent emulation. */ } opt; @@ -131,7 +133,7 @@ enum { }; /*-- gpg-agent.c --*/ -void agent_exit (int rc); /* also implemented in other tools */ +void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */ void agent_init_default_ctrl (struct server_control_s *ctrl); /*-- command.c --*/ diff --git a/agent/command-ssh.c b/agent/command-ssh.c index db0e8daa9..390bfe92a 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -22,7 +22,7 @@ /* Only v2 of the ssh-agent protocol is implemented. */ #include -#include + #include #include #include @@ -33,9 +33,8 @@ #include "agent.h" -#include - #include "estream.h" +#include "i18n.h" @@ -59,26 +58,31 @@ #define SSH_RESPONSE_IDENTITIES_ANSWER 12 #define SSH_RESPONSE_SIGN_RESPONSE 14 +/* Other constants. */ +#define SSH_DSA_SIGNATURE_PADDING 20 +#define SSH_DSA_SIGNATURE_ELEMS 2 +#define SPEC_FLAG_USE_PKCS1V2 (1 << 0) + + + /* Basic types. */ -/* A "byte". */ -typedef unsigned char byte_t; - typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl, estream_t request, estream_t response); typedef struct ssh_request_spec { - byte_t type; + unsigned char type; ssh_request_handler_t handler; const char *identifier; } ssh_request_spec_t; -typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems, gcry_mpi_t *mpis); +typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems, + gcry_mpi_t *mpis); typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob, gcry_mpi_t *mpis); @@ -96,10 +100,91 @@ typedef struct ssh_key_type_spec unsigned int flags; } ssh_key_type_spec_t; + +/* Prototypes. */ +static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_lock (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_unlock (ctrl_t ctrl, + estream_t request, + estream_t response); + +static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis); +static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob, + gcry_mpi_t *mpis); +static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob, + gcry_mpi_t *mpis); + + + +/* Global variables. */ + + +/* Associating request types with the corresponding request + handlers. */ + +#define REQUEST_SPEC_DEFINE(id, name) \ + { SSH_REQUEST_##id, ssh_handler_##name, #name } + +static ssh_request_spec_t request_specs[] = + { + REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities), + REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request), + REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity), + REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity), + REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity), + REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities), + REQUEST_SPEC_DEFINE (LOCK, lock), + REQUEST_SPEC_DEFINE (UNLOCK, unlock) + }; +#undef REQUEST_SPEC_DEFINE + + +/* Table holding key type specifications. */ +static ssh_key_type_spec_t ssh_key_types[] = + { + { + "ssh-rsa", "rsa", "nedupq", "en", "dupq", "s", "nedpqu", + ssh_key_modifier_rsa, ssh_signature_encoder_rsa, + SPEC_FLAG_USE_PKCS1V2 + }, + { + "ssh-dss", "dsa", "pqgyx", "pqgy", "x", "rs", "pqgyx", + NULL, ssh_signature_encoder_dsa, + 0 + }, + }; + + + + + + -/* General utility functions. */ +/* + General utility functions. + */ +/* A secure realloc, i.e. it amkese sure to allocate secure memory if + A is NULL. This is required becuase the standard gcry_realloc does + not know whether to allocate secure or normal if NULL is passed as + existing buffer. */ static void * realloc_secure (void *a, size_t n) { @@ -113,10 +198,39 @@ realloc_secure (void *a, size_t n) return p; } -/* Primitive I/O functions. */ + + +static char * +make_cstring (const char *data, size_t data_n) +{ + char *s; + + s = xtrymalloc (data_n + 1); + if (s) + { + strncpy (s, data, data_n); + s[data_n] = 0; + } + + return s; +} + + + + +/* + Primitive I/O functions. + + FIXME: Needs documentation. + + Why are all these functions prefixed with es_ ? They are not part + of libestream, thus they should not use this prefix. + + */ + static gpg_error_t -es_read_byte (estream_t stream, byte_t *b) +es_read_byte (estream_t stream, unsigned char *b) { gpg_error_t err; int ret; @@ -138,8 +252,9 @@ es_read_byte (estream_t stream, byte_t *b) return err; } + static gpg_error_t -es_write_byte (estream_t stream, byte_t b) +es_write_byte (estream_t stream, unsigned char b) { gpg_error_t err; int ret; @@ -153,8 +268,9 @@ es_write_byte (estream_t stream, byte_t b) return err; } + static gpg_error_t -es_read_uint32 (estream_t stream, uint32_t *uint32) +es_read_uint32 (estream_t stream, u32 *uint32) { unsigned char buffer[4]; size_t bytes_read; @@ -170,13 +286,20 @@ es_read_uint32 (estream_t stream, uint32_t *uint32) err = gpg_error (GPG_ERR_EOF); else { - uint32_t n; + u32 n; + + /* FIXME: For what is the cast good for? The proper way of + wrinting it - assuming an unsigned buffer - is: + n = (buffer[0]<< 24)|(buffer[0]<< 16)|(buffer[0]<<8)|(buffer[0]); + + -wk + */ n = (0 - | ((uint32_t) (buffer[0] << 24)) - | ((uint32_t) (buffer[1] << 16)) - | ((uint32_t) (buffer[2] << 8)) - | ((uint32_t) (buffer[3] << 0))); + | ((u32) (buffer[0] << 24)) + | ((u32) (buffer[1] << 16)) + | ((u32) (buffer[2] << 8)) + | ((u32) (buffer[3] << 0))); *uint32 = n; err = 0; } @@ -185,13 +308,15 @@ es_read_uint32 (estream_t stream, uint32_t *uint32) return err; } + static gpg_error_t -es_write_uint32 (estream_t stream, uint32_t uint32) +es_write_uint32 (estream_t stream, u32 uint32) { unsigned char buffer[4]; gpg_error_t err; int ret; + /* Fixme: The 0xFF mask is superfluous. */ buffer[0] = (uint32 >> 24) & 0xFF; buffer[1] = (uint32 >> 16) & 0xFF; buffer[2] = (uint32 >> 8) & 0xFF; @@ -206,6 +331,7 @@ es_write_uint32 (estream_t stream, uint32_t uint32) return err; } + static gpg_error_t es_read_data (estream_t stream, unsigned char *buffer, size_t size) { @@ -227,6 +353,7 @@ es_read_data (estream_t stream, unsigned char *buffer, size_t size) return err; } + static gpg_error_t es_write_data (estream_t stream, const unsigned char *buffer, size_t size) { @@ -242,13 +369,14 @@ es_write_data (estream_t stream, const unsigned char *buffer, size_t size) return err; } + static gpg_error_t es_read_string (estream_t stream, unsigned int secure, - unsigned char **string, uint32_t *string_size) + unsigned char **string, u32 *string_size) { gpg_error_t err; unsigned char *buffer; - uint32_t length; + u32 length; buffer = NULL; @@ -289,6 +417,7 @@ es_read_string (estream_t stream, unsigned int secure, return err; } + static gpg_error_t es_read_cstring (estream_t stream, char **string) { @@ -306,9 +435,11 @@ es_read_cstring (estream_t stream, char **string) return err; } + +/* FIXME: Needs documentation. */ static gpg_error_t es_write_string (estream_t stream, - const unsigned char *string, uint32_t string_n) + const unsigned char *string, u32 string_n) { gpg_error_t err; @@ -323,6 +454,7 @@ es_write_string (estream_t stream, return err; } + static gpg_error_t es_write_cstring (estream_t stream, const char *string) { @@ -334,11 +466,12 @@ es_write_cstring (estream_t stream, const char *string) return err; } + static gpg_error_t es_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint) { unsigned char *mpi_data; - uint32_t mpi_data_size; + u32 mpi_data_size; gpg_error_t err; gcry_mpi_t mpi; @@ -361,6 +494,7 @@ es_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint) return err; } + static gpg_error_t es_write_mpi (estream_t stream, gcry_mpi_t mpint) { @@ -383,6 +517,7 @@ es_write_mpi (estream_t stream, gcry_mpi_t mpint) return err; } + static gpg_error_t es_read_file (const char *filename, unsigned char **buffer, size_t *buffer_n) { @@ -434,6 +569,7 @@ es_read_file (const char *filename, unsigned char **buffer, size_t *buffer_n) return err; } + static gpg_error_t es_copy (estream_t dst, estream_t src) { @@ -463,9 +599,14 @@ es_copy (estream_t dst, estream_t src) return err; } + -/* MPI lists. */ +/* + + MPI lists. + + */ static void mpint_list_free (gcry_mpi_t *mpi_list) @@ -480,6 +621,7 @@ mpint_list_free (gcry_mpi_t *mpi_list) } } + static gpg_error_t ssh_receive_mpint_list (estream_t stream, int secret, ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list) @@ -593,8 +735,7 @@ ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis) return err; } -#define SSH_DSA_SIGNATURE_PADDING 20 -#define SSH_DSA_SIGNATURE_ELEMS 2 + static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) @@ -639,27 +780,9 @@ ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) return err; } -#define SPEC_FLAG_USE_PKCS1V2 (1 << 0) - - -/* Table holding key type specifications. */ -static ssh_key_type_spec_t ssh_key_types[] = - { - { - "ssh-rsa", "rsa", "nedupq", "en", "dupq", "s", "nedpqu", - ssh_key_modifier_rsa, ssh_signature_encoder_rsa, - SPEC_FLAG_USE_PKCS1V2 - }, - { - "ssh-dss", "dsa", "pqgyx", "pqgy", "x", "rs", "pqgyx", - NULL, ssh_signature_encoder_dsa, - 0 - }, - }; - - - -/* S-Expressions. */ +/* + S-Expressions. + */ static gpg_error_t ssh_sexp_construct (gcry_sexp_t *sexp, @@ -685,7 +808,9 @@ ssh_sexp_construct (gcry_sexp_t *sexp, elems = key_spec.elems_key_public; elems_n = strlen (elems); - sexp_template_n = 33 + strlen (key_spec.identifier) + (elems_n * 6) - (! secret); + /* FIXME: Why 33? -wk */ + sexp_template_n = (33 + strlen (key_spec.identifier) + + (elems_n * 6) - (!secret)); sexp_template = xtrymalloc (sexp_template_n); if (! sexp_template) { @@ -765,13 +890,13 @@ ssh_sexp_extract (gcry_sexp_t sexp, goto out; } - if ((data_n == 10) && (! strncmp (data, "public-key", 10))) + if (data_n == 10 && !strncmp (data, "public-key", 10)) { is_secret = 0; elems = key_spec.elems_key_public; } - else if (((data_n == 11) && (! strncmp (data, "private-key", 11))) - || ((data_n == 21) && (! strncmp (data, "protected-private-key", 21)))) + else if ((data_n == 11 && !strncmp (data, "private-key", 11)) + || (data_n == 21 && !strncmp (data, "protected-private-key", 21))) { is_secret = 1; elems = key_spec.elems_key_secret; @@ -934,8 +1059,8 @@ ssh_key_type_lookup (const char *ssh_name, const char *name, } static gpg_error_t -ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, int read_comment, - ssh_key_type_spec_t *key_spec) +ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, + int read_comment, ssh_key_type_spec_t *key_spec) { gpg_error_t err; char *key_type; @@ -1093,7 +1218,8 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public) if (err) goto out; - err = ssh_convert_key_to_blob (&blob, &blob_n, spec.ssh_identifier, mpi_list); + err = ssh_convert_key_to_blob (&blob, &blob_n, + spec.ssh_identifier, mpi_list); if (err) goto out; @@ -1268,27 +1394,13 @@ key_secret_to_public (gcry_sexp_t *key_public, -static char * -make_cstring (const char *data, size_t data_n) -{ - char *s; - - s = xtrymalloc (data_n + 1); - if (s) - { - strncpy (s, data, data_n); - s[data_n] = 0; - } - - return s; -} - - - -/* Request handler. */ +/* + Request handler. + */ static gpg_error_t -ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t response) +ssh_handler_request_identities (ctrl_t ctrl, + estream_t request, estream_t response) { const char *key_type; ssh_key_type_spec_t spec; @@ -1298,7 +1410,7 @@ ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t respon char *key_path; unsigned char *buffer; size_t buffer_n; - uint32_t key_counter; + u32 key_counter; estream_t key_blobs; gcry_sexp_t key_secret; gcry_sexp_t key_public; @@ -1468,11 +1580,11 @@ data_hash (unsigned char *data, size_t data_n, return 0; } + static gpg_error_t -data_sign (CTRL ctrl, ssh_signature_encoder_t sig_encoder, +data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, unsigned char **sig, size_t *sig_n) { - char description[] = "Please provide the passphrase for key `%c':"; gpg_error_t err; gcry_sexp_t signature_sexp; estream_t stream; @@ -1501,7 +1613,9 @@ data_sign (CTRL ctrl, ssh_signature_encoder_t sig_encoder, sig_value = NULL; mpis = NULL; - err = agent_pksign_do (ctrl, description, &signature_sexp, 0); + err = agent_pksign_do (ctrl, + _("Please provide the passphrase " + "for the ssh key `%c':"), &signature_sexp, 0); if (err) goto out; @@ -1632,12 +1746,12 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) unsigned int hash_n; unsigned char key_grip[20]; unsigned char *key_blob; - uint32_t key_blob_size; + u32 key_blob_size; unsigned char *data; unsigned char *sig; size_t sig_n; - uint32_t data_size; - uint32_t flags; + u32 data_size; + u32 flags; const void *p; gpg_error_t err; gpg_error_t ret_err; @@ -1886,6 +2000,11 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) if (err) goto out; + + /* FIXME: What the hell is that: Never have use sprintf in that way. + When marking a string translatbale you might get a buffer + overflow. We have never done this elsewhere. Using [x]asprintf + is the right way!! */ description_length = 95 + (comment ? strlen (comment) : 0); description = malloc (description_length); if (! description) @@ -1896,7 +2015,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) else sprintf (description, "Please provide the passphrase, which should be used " - "for protecting the received secret key `%s':", + "for protecting the received secret key `%s':", comment ? comment : ""); err = get_passphrase (ctrl, description, sizeof (passphrase), passphrase); @@ -1954,7 +2073,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) gpg_error_t ret_err; gpg_error_t err; gcry_sexp_t key; - byte_t b; + unsigned char b; int confirm; int ttl; @@ -1980,7 +2099,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) { case SSH_OPT_CONSTRAIN_LIFETIME: { - uint32_t n = 0; + u32 n = 0; err = es_read_uint32 (request, &n); if (! err) @@ -2017,10 +2136,11 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) } static gpg_error_t -ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, estream_t response) +ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, + estream_t response) { unsigned char *key_blob; - uint32_t key_blob_size; + u32 key_blob_size; gcry_sexp_t key; gpg_error_t ret_err; gpg_error_t err; @@ -2065,7 +2185,8 @@ ssh_identities_remove_all (void) } static gpg_error_t -ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request, estream_t response) +ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request, + estream_t response) { gpg_error_t ret_err; gpg_error_t err; @@ -2083,7 +2204,7 @@ ssh_lock (void) gpg_error_t err; /* FIXME */ - log_error ("[gpg-agent/ssh] lock command is not implemented\n"); + log_error (_("lock command is not implemented\n")); err = 0; return err; @@ -2094,7 +2215,7 @@ ssh_unlock (void) { gpg_error_t err; - log_error ("[gpg-agent/ssh] unlock command is not implemented\n"); + log_error (_("unlock command is not implemented\n")); err = 0; return err; @@ -2128,39 +2249,19 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) -/* Associating request types with the corresponding request - handlers. */ - -#define REQUEST_SPEC_DEFINE(id, name) \ - { SSH_REQUEST_##id, ssh_handler_##name, #name } - -static ssh_request_spec_t request_specs[] = - { - REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities), - REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request), - REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity), - REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity), - REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity), - REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities), - REQUEST_SPEC_DEFINE (LOCK, lock), - REQUEST_SPEC_DEFINE (UNLOCK, unlock) - }; - - - static int ssh_request_process (ctrl_t ctrl, estream_t stream_sock) { estream_t response; estream_t request; - byte_t request_type; + unsigned char request_type; gpg_error_t err; unsigned int i; int send_err; int ret; unsigned char *request_data; - uint32_t request_data_size; - uint32_t response_size; + u32 request_data_size; + u32 response_size; request_data = NULL; response = NULL; @@ -2170,15 +2271,22 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) /* Create memory streams for request/response data. The entire request will be stored in secure memory, since it might contain secret key material. The response does not have to be stored in - secure memory, since we never give out secret keys. */ + secure memory, since we never give out secret keys. + + FIXME: This is a pretty good DoS. We only have a limited amount + of secure memory, we can't trhow hin everything we get from a + client -wk */ /* Retrieve request. */ err = es_read_string (stream_sock, 1, &request_data, &request_data_size); if (err) goto out; - if (opt.verbose) - log_debug ("[gpg-agent/ssh] Received request of length: %u\n", + if (opt.verbose) /* FIXME: using log_debug is not good with + verbose. log_debug should only be used in + debugging mode or in sitattions which are + unexpected. */ + log_debug ("received request of length: %u\n", request_data_size); request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+"); @@ -2217,14 +2325,14 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) break; if (i == DIM (request_specs)) { - log_debug ("[gpg-agent/ssh] request %u is not supported\n", + log_debug ("request %u is not supported\n", request_type); send_err = 1; goto out; } if (opt.verbose) - log_debug ("[gpg-agent/ssh] Executing request handler: %s (%u)\n", + log_debug ("executing request handler: %s (%u)\n", request_specs[i].identifier, request_specs[i].type); err = (*request_specs[i].handler) (ctrl, request, response); @@ -2260,7 +2368,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) out: if (err && es_feof (stream_sock)) - log_error ("[gpg-agent/ssh] Error occured while processing request: %s\n", + log_error ("error occured while processing request: %s\n", gpg_strerror (err)); if (send_err) @@ -2301,10 +2409,10 @@ start_command_handler_ssh (int sock_client) /* Create stream from socket. */ stream_sock = es_fdopen (sock_client, "r+"); - if (! stream_sock) + if (!stream_sock) { err = gpg_error_from_errno (errno); - log_error ("[gpg-agent/ssh] Failed to create stream from socket: %s\n", + log_error (_("failed to create stream from socket: %s\n"), gpg_strerror (err)); goto out; } @@ -2314,14 +2422,13 @@ start_command_handler_ssh (int sock_client) if (ret) { err = gpg_error_from_errno (errno); - log_error ("[gpg-agent/ssh] Failed to disable buffering " - "on socket stream: %s\n", gpg_strerror (err)); + log_error (_("failed to disable buffering " + "on socket stream: %s\n"), gpg_strerror (err)); goto out; } while (1) { - /* Process request. */ bad = ssh_request_process (&ctrl, stream_sock); if (bad) break; diff --git a/agent/findkey.c b/agent/findkey.c index d39d3aae3..896cb880e 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -143,101 +143,79 @@ try_unprotect_cb (struct pin_entry_info_s *pi) /* Modify a Key description, replacing certain special format characters. List of currently supported replacements: - %% -> % - %c -> . */ -static int -modify_description (const char *description, - const char *comment, size_t comment_length, - char **description_modified) -{ - size_t description_length; - size_t description_new_length; - gpg_error_t err; - char *description_new; - unsigned int i, j; - unsigned int special; - - description_length = strlen (description); - description_new_length = description_length; - description_new = NULL; - - /* Calculate length. */ - special = 0; - for (i = 0; i < description_length; i++) - { - if (description[i] == '%') - special = 1; - else - { - if (special) - { - description_new_length -= 2; - switch (description[i]) - { - case 'c': - /* Comment. */ - description_new_length += comment_length; - break; - - case '%': - description_new_length += 1; - break; - } - special = 0; - } - } - } - - /* Allocate. */ - description_new = xtrymalloc (description_new_length + 1); - if (! description_new) - { - err = gpg_error_from_errno (errno); - goto out; - } + %% - Replaced by a single % + %c - Replaced by the content of COMMENT. - /* Fill. */ - for (i = j = 0; i < description_length; i++) + The functions returns 0 on success or an error code. On success a + newly allocated string is stored at the address of RESULT. + */ +static gpg_error_t +modify_description (const char *in, const char *comment, char **result) +{ + size_t comment_length; + size_t in_len; + size_t out_len; + char *out; + size_t i; + int special, pass; + + comment_length = strlen (comment); + in_len = strlen (in); + + /* First pass calculates the length, second pass does the actual + copying. */ + out = NULL; + out_len = 0; + for (pass=0; pass < 2; pass++) { - if (description[i] == '%') - special = 1; - else - { - if (special) - { - switch (description[i]) - { - case 'c': - /* Comment. */ - if (comment) - { - strncpy (description_new + j, comment, comment_length); - j += comment_length; - } - break; - - case '%': - description_new[j] = '%'; - j++; - break; - } - special = 0; - } - else - { - description_new[j] = description[i]; - j++; - } - } + special = 0; + for (i = 0; i < in_len; i++) + { + if (in[i] == '%') + special = 1; + else if (special) + { + special = 0; + switch (in[i]) + { + case '%': + out_len++; + if (out) + *out++ = '%'; + break; + + case 'c': /* Comment. */ + out_len += comment_length; + if (out && comment_length) + { + memcpy (out, comment, comment_length); + out += comment_length; + } + break; + + default: /* Invalid special sequences are ignored. */ + break; + } + } + else + { + out_len++; + if (out) + *out++ = in[i]; + } + } + + if (!pass) + { + *result = out = xtrymalloc (out_len + 1); + if (!out) + return gpg_error_from_errno (errno); + } } - description_new[j] = 0; - *description_modified = description_new; - err = 0; - - out: - - return err; + *out = 0; + assert (*result + out_len == out); + return 0; } @@ -398,35 +376,51 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, gcry_sexp_t comment_sexp; size_t comment_length; char *desc_text_final; - const char *comment; - + const char *comment = NULL; + + /* Note, that we will take the comment as a C styring for + display purposes; i.e. all stuff beyond a Nul character is + ignored. */ comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0); if (comment_sexp) comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length); - else + if (!comment) { - comment = NULL; + comment = ""; comment_length = 0; } + desc_text_final = NULL; if (desc_text) { - rc = modify_description (desc_text, - comment, comment_length, &desc_text_final); - if (rc) - log_error ("failed to modify description: %s\n", gpg_strerror (rc)); + if (comment[comment_length]) + { + /* Not a C-string; create one. We might here allocate + more than actually displayed but well, that + shouldn't be a problem. */ + char *tmp = xtrymalloc (comment_length+1); + if (!tmp) + rc = gpg_error_from_errno (errno); + else + { + memcpy (tmp, comment, comment_length); + tmp[comment_length] = 0; + rc = modify_description (desc_text, tmp, &desc_text_final); + xfree (tmp); + } + } + else + rc = modify_description (desc_text, comment, &desc_text_final); } - else - desc_text_final = NULL; - if (! rc) + if (!rc) { rc = unprotect (ctrl, desc_text_final, &buf, grip, ignore_cache); if (rc) log_error ("failed to unprotect the secret key: %s\n", gpg_strerror (rc)); } - + gcry_sexp_release (comment_sexp); xfree (desc_text_final); } diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 9f97fb6d7..d8b891e5f 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -51,6 +51,7 @@ #include "../jnlib/w32-afunix.h" #endif + enum cmd_and_opt_values { aNull = 0, oCsh = 'c', @@ -146,7 +147,7 @@ static ARGPARSE_OPTS opts[] = { N_("allow clients to mark keys as \"trusted\"")}, { oAllowPresetPassphrase, "allow-preset-passphrase", 0, N_("allow presetting passphrase")}, - { oSSHSupport, "ssh-support", 0, "Enable SSH-Agent emulation" }, + { oSSHSupport, "ssh-support", 0, N_("enable secure ssh-agent emulation") }, {0} }; @@ -163,7 +164,7 @@ static int shutdown_pending; /* It is possible that we are currently running under setuid permissions */ static int maybe_setuid = 1; -/* Name of the communication socket */ +/* Name of the communication socket used for native gpg-agent requests. */ static char *socket_name; /* Name of the communication socket used for ssh-agent-emulation. */ @@ -186,8 +187,15 @@ static const char *debug_level; the log file after a SIGHUP if it didn't changed. Malloced. */ static char *current_logfile; -/* Local prototypes. */ +/* + Local prototypes. + */ + +static char *create_socket_name (int use_standard_socket, + char *standard_name, char *template); +static int create_server_socket (int is_standard_name, const char *name); static void create_directories (void); + #ifdef USE_GNU_PTH static void handle_connections (int listen_fd, int listen_fd_ssh); /* Pth wrapper function definitions. */ @@ -198,6 +206,12 @@ static int check_for_running_agent (int); + +/* + Functions. + */ + + static const char * my_strusage (int level) { @@ -302,8 +316,9 @@ set_debug (void) } +/* Helper for cleanup to remove one socket with NAME. */ static void -cleanup_do (char *name) +remove_socket (char *name) { if (name && *name) { @@ -324,8 +339,8 @@ cleanup_do (char *name) static void cleanup (void) { - cleanup_do (socket_name); - cleanup_do (socket_name_ssh); + remove_socket (socket_name); + remove_socket (socket_name_ssh); } @@ -417,105 +432,6 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) } -static void -create_socket_name (char **name, int standard_socket, - struct sockaddr_un *serv_addr, - char *standard_identifier, char *identifier) -{ - char *p; - - if (standard_socket) - *name = make_filename (opt.homedir, standard_identifier, NULL); - else - { - *name = xstrdup (identifier); - p = strrchr (*name, '/'); - if (! p) - BUG (); - *p = 0; - if (!mkdtemp (*name)) - { - log_error (_("can't create directory `%s': %s\n"), - *name, strerror (errno)); - exit (1); - } - *p = '/'; - } - - if (strchr (*name, PATHSEP_C)) - { - log_error ("`%s' are not allowed in the socket name\n", PATHSEP_S); - exit (1); - } - if (strlen (*name) + 1 >= sizeof serv_addr->sun_path) - { - log_error ("name of socket too long\n"); - exit (1); - } -} - -static int -create_server_socket (struct sockaddr_un *serv_addr, - int standard_socket, const char *name) -{ - socklen_t len; - int fd; - int rc; - -#ifdef HAVE_W32_SYSTEM - fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0); -#else - fd = socket (AF_UNIX, SOCK_STREAM, 0); -#endif - if (fd == -1) - { - log_error ("can't create socket: %s\n", strerror (errno)); - exit (1); - } - - memset (serv_addr, 0, sizeof *serv_addr); - serv_addr->sun_family = AF_UNIX; - strcpy (serv_addr->sun_path, name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen (serv_addr->sun_path) + 1); - -#ifdef HAVE_W32_SYSTEM - rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len); - if ((rc == -1) && standard_socket) - { - remove (name); - rc = bind (fd, (struct sockaddr*) serv_addr, len); - } -#else - rc = bind (fd, (struct sockaddr*) serv_addr, len); - if ((rc == -1) && standard_socket && (errno == EADDRINUSE)) - { - remove (name); - rc = bind (fd, (struct sockaddr*) serv_addr, len); - } -#endif - if (rc == -1) - { - log_error ("error binding socket to `%s': %s\n", - serv_addr->sun_path, strerror (errno)); - close (fd); - exit (1); - } - - if (listen (fd, 5 ) == -1) - { - log_error ("listen() failed: %s\n", strerror (errno)); - close (fd); - exit (1); - } - - if (opt.verbose) - log_info ("listening on socket `%s'\n", socket_name); - - return fd; -} - - int main (int argc, char **argv ) { @@ -865,8 +781,6 @@ main (int argc, char **argv ) int fd; int fd_ssh; pid_t pid; - struct sockaddr_un serv_addr; - struct sockaddr_un serv_addr_ssh; /* Remove the DISPLAY variable so that a pinentry does not default to a specific display. There is still a default @@ -877,27 +791,27 @@ main (int argc, char **argv ) unsetenv ("DISPLAY"); #endif - /* Create the socket name . */ - create_socket_name (&socket_name, standard_socket, &serv_addr, - "S.gpg-agent", "/tmp/gpg-XXXXXX/S.gpg-agent"); + + /* Create the sockets. */ + socket_name = create_socket_name (standard_socket, + "S.gpg-agent", + "/tmp/gpg-XXXXXX/S.gpg-agent"); if (opt.ssh_support) - create_socket_name (&socket_name_ssh, standard_socket, &serv_addr_ssh, - "S.gpg-agent.ssh", "/tmp/gpg-XXXXXX/S.gpg-agent.ssh"); + socket_name_ssh = create_socket_name (standard_socket, + "S.gpg-agent.ssh", + "/tmp/gpg-XXXXXX/S.gpg-agent.ssh"); - fd = create_server_socket (&serv_addr, - standard_socket, socket_name); + fd = create_server_socket (standard_socket, socket_name); if (opt.ssh_support) - fd_ssh = create_server_socket (&serv_addr_ssh, - standard_socket, socket_name_ssh); + fd_ssh = create_server_socket (standard_socket, socket_name_ssh); else - /* Make the compiler happy. */ fd_ssh = -1; + fflush (NULL); #ifdef HAVE_W32_SYSTEM pid = getpid (); printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid); - printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid); #else /*!HAVE_W32_SYSTEM*/ pid = fork (); if (pid == (pid_t)-1) @@ -911,7 +825,7 @@ main (int argc, char **argv ) close (fd); - /* create the info string: :: */ + /* Create the info string: :: */ if (asprintf (&infostr, "GPG_AGENT_INFO=%s:%lu:1", socket_name, (ulong)pid ) < 0) { @@ -937,13 +851,14 @@ main (int argc, char **argv ) } } - *socket_name = 0; /* don't let cleanup() remove the socket - + *socket_name = 0; /* Don't let cleanup() remove the socket - the child should do this from now on */ if (opt.ssh_support) *socket_name_ssh = 0; + if (argc) - { /* run the program given on the commandline */ + { /* Run the program given on the commandline. */ if (putenv (infostr)) { log_error ("failed to set environment: %s\n", @@ -972,18 +887,18 @@ main (int argc, char **argv ) } else { - /* print the environment string, so that the caller can use + /* Print the environment string, so that the caller can use shell's eval to set it */ if (csh_style) { *strchr (infostr, '=') = ' '; - printf ( "setenv %s\n", infostr); + printf ("setenv %s\n", infostr); if (opt.ssh_support) { *strchr (infostr_ssh_sock, '=') = ' '; - printf ( "setenv %s\n", infostr_ssh_sock); + printf ("setenv %s\n", infostr_ssh_sock); *strchr (infostr_ssh_pid, '=') = ' '; - printf ( "setenv %s\n", infostr_ssh_pid); + printf ("setenv %s\n", infostr_ssh_pid); } } else @@ -991,10 +906,11 @@ main (int argc, char **argv ) printf ( "%s; export GPG_AGENT_INFO;\n", infostr); if (opt.ssh_support) { - printf ( "%s; export SSH_AUTH_SOCK;\n", infostr_ssh_sock); - printf ( "%s; export SSH_AGENT_PID;\n", infostr_ssh_pid); + printf ("%s; export SSH_AUTH_SOCK;\n", infostr_ssh_sock); + printf ("%s; export SSH_AGENT_PID;\n", infostr_ssh_pid); } } + /* Note: teh standard free is here correct. */ free (infostr); if (opt.ssh_support) { @@ -1003,8 +919,8 @@ main (int argc, char **argv ) } exit (0); } - /*NEVER REACHED*/ - } /* end parent */ + /*NOTREACHED*/ + } /* End parent */ /* This is the child @@ -1181,6 +1097,125 @@ reread_configuration (void) } + + +/* Create a name for the socket. With USE_STANDARD_SOCKET given as + true ising STANDARD_NAME in the home directory or if given has + false from the mkdir type name TEMPLATE. In the latter case a + unique name in a unique new directory will be created. In both + cases check for valid characters as well as against a maximum + allowed length for a unix domain socket is done. The function + terminates the process in case of an error. Retunrs: Pointer to an + allcoated string with the absolute name of the socket used. */ +static char * +create_socket_name (int use_standard_socket, + char *standard_name, char *template) +{ + char *name, *p; + + if (use_standard_socket) + name = make_filename (opt.homedir, standard_name, NULL); + else + { + name = xstrdup (template); + p = strrchr (name, '/'); + if (!p) + BUG (); + *p = 0; + if (!mkdtemp (name)) + { + log_error (_("can't create directory `%s': %s\n"), + name, strerror (errno)); + agent_exit (2); + } + *p = '/'; + } + + if (strchr (name, PATHSEP_C)) + { + log_error (("`%s' are not allowed in the socket name\n"), PATHSEP_S); + agent_exit (2); + } + if (strlen (name) + 1 >= DIMof (struct sockaddr_un, sun_path) ) + { + log_error (_("name of socket too long\n")); + agent_exit (2); + } + return name; +} + + + +/* Create a Unix domain socket with NAME. IS_STANDARD_NAME indicates + whether a non-random socket is used. Returns the filedescriptor or + terminates the process in case of an error. */ +static int +create_server_socket (int is_standard_name, const char *name) +{ + struct sockaddr_un *serv_addr; + socklen_t len; + int fd; + int rc; + +#ifdef HAVE_W32_SYSTEM + fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0); +#else + fd = socket (AF_UNIX, SOCK_STREAM, 0); +#endif + if (fd == -1) + { + log_error (_("can't create socket: %s\n"), strerror (errno)); + agent_exit (2); + } + + + memset (serv_addr, 0, sizeof *serv_addr); + serv_addr->sun_family = AF_UNIX; + assert (strlen (name) + 1 < sizeof (serv_addr->sun_path)); + strcpy (serv_addr->sun_path, name); + len = (offsetof (struct sockaddr_un, sun_path) + + strlen (serv_addr->sun_path) + 1); + +#ifdef HAVE_W32_SYSTEM + rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len); + if (is_standard_name && rc == -1 ) + { + remove (name); + rc = bind (fd, (struct sockaddr*) serv_addr, len); + } +#else + rc = bind (fd, (struct sockaddr*) serv_addr, len); + if (is_standard_name && rc == -1 && errno == EADDRINUSE) + { + remove (name); + rc = bind (fd, (struct sockaddr*) serv_addr, len); + } +#endif + if (rc == -1) + { + log_error (_("error binding socket to `%s': %s\n"), + serv_addr->sun_path, strerror (errno)); + close (fd); + agent_exit (2); + } + + if (listen (fd, 5 ) == -1) + { + log_error (_("listen() failed: %s\n"), strerror (errno)); + close (fd); + agent_exit (2); + } + + if (opt.verbose) + log_info (_("listening on socket `%s'\n"), serv_addr->sun_path); + + return fd; +} + + +/* Check that the directory for storing the private keys exists and + create it if not. This function won't fail as it is only a + convenience function and not strictly necessary. */ static void create_private_keys_directory (const char *home) { @@ -1218,7 +1253,7 @@ create_directories (void) const char *defhome = GNUPG_DEFAULT_HOMEDIR; char *home; - home = make_filename (opt.homedir, NULL); + home = make_filename (opt.homedir, NULL); if ( stat (home, &statbuf) ) { if (errno == ENOENT) @@ -1248,11 +1283,11 @@ create_directories (void) } } else - log_error ("error stat-ing `%s': %s\n", home, strerror (errno)); + log_error (_("stat() failed for `%s': %s\n"), home, strerror (errno)); } else if ( !S_ISDIR(statbuf.st_mode)) { - log_error ("can't use `%s' as home directory\n", home); + log_error (_("can't use `%s' as home directory\n"), home); } else /* exists and is a directory. */ { @@ -1315,13 +1350,14 @@ handle_signal (int signo) } +/* This is the standard connection thread's main function. */ static void * start_connection_thread (void *arg) { int fd = (int)arg; if (opt.verbose) - log_info ("handler for fd %d started\n", fd); + log_info (_("handler for fd %d started\n"), fd); /* FIXME: Move this housekeeping into a ticker function. Calling it for each connection should work but won't work anymore if our @@ -1330,31 +1366,33 @@ start_connection_thread (void *arg) start_command_handler (-1, fd); if (opt.verbose) - log_info ("handler for fd %d terminated\n", fd); + log_info (_("handler for fd %d terminated\n"), fd); return NULL; } + +/* This is the ssh connection thread's main function. */ static void * start_connection_thread_ssh (void *arg) { int fd = (int)arg; if (opt.verbose) - log_info ("ssh handler for fd %d started\n", fd); + log_info (_("ssh handler for fd %d started\n"), fd); - /* FIXME: Move this housekeeping into a ticker function. Calling it - for each connection should work but won't work anymore if our - cleints start to keep connections. */ agent_trustlist_housekeeping (); start_command_handler_ssh (fd); if (opt.verbose) - log_info ("ssh handler for fd %d terminated\n", fd); + log_info (_("ssh handler for fd %d terminated\n"), fd); return NULL; } + +/* Connection handler loop. Wait for coecntion requests and spawn a + thread after accepting a connection. */ static void handle_connections (int listen_fd, int listen_fd_ssh) { @@ -1363,7 +1401,7 @@ handle_connections (int listen_fd, int listen_fd_ssh) sigset_t sigs; int signo; struct sockaddr_un paddr; - socklen_t plen = sizeof ( paddr ); + socklen_t plen; fd_set fdset, read_fdset; int ret; int fd; @@ -1406,74 +1444,62 @@ handle_connections (int listen_fd, int listen_fd_ssh) continue; } + /* POSIX says that fd_set should be implemented as a structure, + thus a simple assignment is fine to copy the entire set. */ read_fdset = fdset; - ret = pth_select (FD_SETSIZE, &read_fdset, NULL, NULL, NULL); + + ret = pth_select_ev (FD_SETSIZE, &read_fdset, NULL, NULL, NULL, ev); if (ret == -1) { - log_error ("pth_select failed: %s - waiting 1s\n", - strerror (errno)); - pth_sleep (1); + log_error (_("pth_select failed: %s - waiting 1s\n"), + strerror (errno)); + pth_sleep (1); continue; } - + + if (pth_event_occurred (ev)) + { + handle_signal (signo); + } if (FD_ISSET (listen_fd, &read_fdset)) { - fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev); + plen = sizeof paddr; + fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen); if (fd == -1) { -#ifdef PTH_STATUS_OCCURRED /* This is Pth 2 */ - if (pth_event_status (ev) == PTH_STATUS_OCCURRED) -#else - if (pth_event_occurred (ev)) -#endif - { - handle_signal (signo); - continue; - } - log_error ("accept failed: %s - waiting 1s\n", strerror (errno)); - pth_sleep(1); - continue; + log_error ("accept failed: %s\n", strerror (errno)); } - - if (!pth_spawn (tattr, start_connection_thread, (void*)fd)) + else if (!pth_spawn (tattr, start_connection_thread, (void*)fd)) { log_error ("error spawning connection handler: %s\n", strerror (errno) ); close (fd); } + fd = -1; } - else if ((listen_fd_ssh != -1) && FD_ISSET (listen_fd_ssh, &read_fdset)) + + if (listen_fd_ssh != -1 && FD_ISSET (listen_fd_ssh, &read_fdset)) { - fd = pth_accept_ev (listen_fd_ssh, (struct sockaddr *)&paddr, &plen, ev); + plen = sizeof paddr; + fd = pth_accept (listen_fd_ssh, (struct sockaddr *)&paddr, &plen); if (fd == -1) { -#ifdef PTH_STATUS_OCCURRED /* This is Pth 2 */ - if (pth_event_status (ev) == PTH_STATUS_OCCURRED) -#else - if (pth_event_occurred (ev)) -#endif - { - handle_signal (signo); - continue; - } - log_error ("accept failed: %s - waiting 1s\n", strerror (errno)); - pth_sleep(1); - continue; + log_error ("accept failed for ssh: %s\n", strerror (errno)); } - - if (!pth_spawn (tattr, start_connection_thread_ssh, (void*)fd)) + else if (!pth_spawn (tattr, start_connection_thread_ssh, (void*)fd)) { - log_error ("error spawning connection handler: %s\n", + log_error ("error spawning ssh connection handler: %s\n", strerror (errno) ); close (fd); } + fd = -1; } } pth_event_free (ev, PTH_FREE_ALL); cleanup (); - log_info ("%s %s stopped\n", strusage(11), strusage(13)); + log_info (_("%s %s stopped\n"), strusage(11), strusage(13)); } #endif /*USE_GNU_PTH*/ @@ -1527,6 +1553,7 @@ check_for_running_agent (int mode) else /* MODE != 0 */ { infostr = make_filename (opt.homedir, "S.gpg-agent", NULL); + pid = (pid_t)(-1); } diff --git a/common/estream.h b/common/estream.h index 382b6da84..c201b666a 100644 --- a/common/estream.h +++ b/common/estream.h @@ -198,4 +198,5 @@ estream_t es_tmpfile (void); void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque); void *es_opaque_get (estream_t stream); -#endif +#endif /*ESTREAM_H*/ + -- cgit From c4b986c7315a3f288a177cbdc15912b4f5a9fce7 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Mon, 14 Feb 2005 20:07:01 +0000 Subject: 2005-02-14 Moritz Schulte * command-ssh.c (es_read_byte): Renamed to ... (stream_es_read_byte): ... this; changed callers. (es_write_byte): Renamed to ... (stream_write_byte): ... this; changed callers. (es_read_uint32): Renamed to ... (stream_read_uint32): ... this; changed callers. (es_write_uint32): Renamed to ... (stream_write_uint32): ... this; changed callers. (es_read_data): Renamed to ... (stream_read_data): ... this; changed callers. (es_write_data): Renamed to ... (stream_write_data): ... this; changed callers. (es_read_string): Renamed to ... (stream_read_string): ... this; changed callers. (es_read_cstring): Renamed to ... (stream_read_cstring): ... this; changed callers. (es_write_string): Renamed to ... (stream_write_string): ... this; changed callers. (es_write_cstring): Renamed to ... (stream_write_cstring): ... this; changed callers. (es_read_mpi): Renamed to ... (stream_read_mpi): ... this; changed callers. (es_write_mpi): Renamed to ... (stream_write_mpi): ... this; changed callers. (es_copy): Renamed to ... (stream_copy): ... this; changed callers. (es_read_file): Renamed to ... (file_to_buffer): ... this; changed callers. (ssh_identity_register): Removed variable description_length; changed code to use asprintf for description. (stream_write_uint32): Do not filter out the last byte of shift expression. --- agent/ChangeLog | 35 ++++++++ agent/command-ssh.c | 249 +++++++++++++++++++++++++--------------------------- 2 files changed, 156 insertions(+), 128 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 3bd779256..09cf0cdbc 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,38 @@ +2005-02-14 Moritz Schulte + + * command-ssh.c (es_read_byte): Renamed to ... + (stream_es_read_byte): ... this; changed callers. + (es_write_byte): Renamed to ... + (stream_write_byte): ... this; changed callers. + (es_read_uint32): Renamed to ... + (stream_read_uint32): ... this; changed callers. + (es_write_uint32): Renamed to ... + (stream_write_uint32): ... this; changed callers. + (es_read_data): Renamed to ... + (stream_read_data): ... this; changed callers. + (es_write_data): Renamed to ... + (stream_write_data): ... this; changed callers. + (es_read_string): Renamed to ... + (stream_read_string): ... this; changed callers. + (es_read_cstring): Renamed to ... + (stream_read_cstring): ... this; changed callers. + (es_write_string): Renamed to ... + (stream_write_string): ... this; changed callers. + (es_write_cstring): Renamed to ... + (stream_write_cstring): ... this; changed callers. + (es_read_mpi): Renamed to ... + (stream_read_mpi): ... this; changed callers. + (es_write_mpi): Renamed to ... + (stream_write_mpi): ... this; changed callers. + (es_copy): Renamed to ... + (stream_copy): ... this; changed callers. + (es_read_file): Renamed to ... + (file_to_buffer): ... this; changed callers. + (ssh_identity_register): Removed variable description_length; + changed code to use asprintf for description. + (stream_write_uint32): Do not filter out the last byte of shift + expression. + 2005-02-03 Werner Koch * agent.h (agent_exit): Add JNLIB_GCC_A_NR to indicate that this diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 390bfe92a..68cca909b 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -181,8 +181,8 @@ static ssh_key_type_spec_t ssh_key_types[] = General utility functions. */ -/* A secure realloc, i.e. it amkese sure to allocate secure memory if - A is NULL. This is required becuase the standard gcry_realloc does +/* A secure realloc, i.e. it makes sure to allocate secure memory if A + is NULL. This is required becuase the standard gcry_realloc does not know whether to allocate secure or normal if NULL is passed as existing buffer. */ static void * @@ -220,17 +220,12 @@ make_cstring (const char *data, size_t data_n) /* Primitive I/O functions. - - FIXME: Needs documentation. - - Why are all these functions prefixed with es_ ? They are not part - of libestream, thus they should not use this prefix. - */ +/* Read a byte from STREAM, store it in B. */ static gpg_error_t -es_read_byte (estream_t stream, unsigned char *b) +stream_read_byte (estream_t stream, unsigned char *b) { gpg_error_t err; int ret; @@ -252,9 +247,9 @@ es_read_byte (estream_t stream, unsigned char *b) return err; } - +/* Write the byte contained in B to STREAM. */ static gpg_error_t -es_write_byte (estream_t stream, unsigned char b) +stream_write_byte (estream_t stream, unsigned char b) { gpg_error_t err; int ret; @@ -268,9 +263,9 @@ es_write_byte (estream_t stream, unsigned char b) return err; } - +/* Read a uint32 from STREAM, store it in UINT32. */ static gpg_error_t -es_read_uint32 (estream_t stream, u32 *uint32) +stream_read_uint32 (estream_t stream, u32 *uint32) { unsigned char buffer[4]; size_t bytes_read; @@ -308,9 +303,9 @@ es_read_uint32 (estream_t stream, u32 *uint32) return err; } - +/* Write the uint32 contained in UINT32 to STREAM. */ static gpg_error_t -es_write_uint32 (estream_t stream, u32 uint32) +stream_write_uint32 (estream_t stream, u32 uint32) { unsigned char buffer[4]; gpg_error_t err; @@ -331,9 +326,9 @@ es_write_uint32 (estream_t stream, u32 uint32) return err; } - +/* Read SIZE bytes from STREAM into BUFFER. */ static gpg_error_t -es_read_data (estream_t stream, unsigned char *buffer, size_t size) +stream_read_data (estream_t stream, unsigned char *buffer, size_t size) { gpg_error_t err; size_t bytes_read; @@ -353,9 +348,9 @@ es_read_data (estream_t stream, unsigned char *buffer, size_t size) return err; } - +/* Write SIZE bytes from BUFFER to STREAM. */ static gpg_error_t -es_write_data (estream_t stream, const unsigned char *buffer, size_t size) +stream_write_data (estream_t stream, const unsigned char *buffer, size_t size) { gpg_error_t err; int ret; @@ -369,10 +364,12 @@ es_write_data (estream_t stream, const unsigned char *buffer, size_t size) return err; } - +/* Read a binary string from STREAM into STRING, store size of string + in STRING_SIZE; depending on SECURE use secure memory for + string. */ static gpg_error_t -es_read_string (estream_t stream, unsigned int secure, - unsigned char **string, u32 *string_size) +stream_read_string (estream_t stream, unsigned int secure, + unsigned char **string, u32 *string_size) { gpg_error_t err; unsigned char *buffer; @@ -381,7 +378,7 @@ es_read_string (estream_t stream, unsigned int secure, buffer = NULL; /* Read string length. */ - err = es_read_uint32 (stream, &length); + err = stream_read_uint32 (stream, &length); if (err) goto out; @@ -399,7 +396,7 @@ es_read_string (estream_t stream, unsigned int secure, } /* Read data. */ - err = es_read_data (stream, buffer, length); + err = stream_read_data (stream, buffer, length); if (err) goto out; @@ -417,14 +414,14 @@ es_read_string (estream_t stream, unsigned int secure, return err; } - +/* Read a C-string from STREAM, store copy in STRING. */ static gpg_error_t -es_read_cstring (estream_t stream, char **string) +stream_read_cstring (estream_t stream, char **string) { unsigned char *buffer; gpg_error_t err; - err = es_read_string (stream, 0, &buffer, NULL); + err = stream_read_string (stream, 0, &buffer, NULL); if (err) goto out; @@ -436,39 +433,40 @@ es_read_cstring (estream_t stream, char **string) } -/* FIXME: Needs documentation. */ +/* Write a binary string from STRING of size STRING_N to STREAM. */ static gpg_error_t -es_write_string (estream_t stream, - const unsigned char *string, u32 string_n) +stream_write_string (estream_t stream, + const unsigned char *string, u32 string_n) { gpg_error_t err; - err = es_write_uint32 (stream, string_n); + err = stream_write_uint32 (stream, string_n); if (err) goto out; - err = es_write_data (stream, string, string_n); + err = stream_write_data (stream, string, string_n); out: return err; } - +/* Write a C-string from STRING to STREAM. */ static gpg_error_t -es_write_cstring (estream_t stream, const char *string) +stream_write_cstring (estream_t stream, const char *string) { gpg_error_t err; - err = es_write_string (stream, - (const unsigned char *) string, strlen (string)); + err = stream_write_string (stream, + (const unsigned char *) string, strlen (string)); return err; } - +/* Read an MPI from STREAM, store it in MPINT. Depending on SECURE + use secure memory. */ static gpg_error_t -es_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint) +stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint) { unsigned char *mpi_data; u32 mpi_data_size; @@ -477,7 +475,7 @@ es_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint) mpi_data = NULL; - err = es_read_string (stream, secure, &mpi_data, &mpi_data_size); + err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size); if (err) goto out; @@ -494,9 +492,9 @@ es_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint) return err; } - +/* Write the MPI contained in MPINT to STREAM. */ static gpg_error_t -es_write_mpi (estream_t stream, gcry_mpi_t mpint) +stream_write_mpi (estream_t stream, gcry_mpi_t mpint) { unsigned char *mpi_buffer; size_t mpi_buffer_n; @@ -508,7 +506,7 @@ es_write_mpi (estream_t stream, gcry_mpi_t mpint) if (err) goto out; - err = es_write_string (stream, mpi_buffer, mpi_buffer_n); + err = stream_write_string (stream, mpi_buffer, mpi_buffer_n); out: @@ -517,9 +515,42 @@ es_write_mpi (estream_t stream, gcry_mpi_t mpint) return err; } +/* Copy data from SRC to DST until EOF is reached. */ +static gpg_error_t +stream_copy (estream_t dst, estream_t src) +{ + char buffer[BUFSIZ]; + size_t bytes_read; + gpg_error_t err; + int ret; + + err = 0; + while (1) + { + ret = es_read (src, buffer, sizeof (buffer), &bytes_read); + if (ret || (! bytes_read)) + { + if (ret) + err = gpg_error_from_errno (errno); + break; + } + ret = es_write (dst, buffer, bytes_read, NULL); + if (ret) + { + err = gpg_error_from_errno (errno); + break; + } + } + + return err; +} + +/* Read the content of the file specified by FILENAME into a newly + create buffer, which is to be stored in BUFFER; store length of + buffer in BUFFER_N. */ static gpg_error_t -es_read_file (const char *filename, unsigned char **buffer, size_t *buffer_n) +file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) { unsigned char *buffer_new; struct stat statbuf; @@ -551,7 +582,7 @@ es_read_file (const char *filename, unsigned char **buffer, size_t *buffer_n) goto out; } - err = es_read_data (stream, buffer_new, statbuf.st_size); + err = stream_read_data (stream, buffer_new, statbuf.st_size); if (err) goto out; @@ -570,36 +601,6 @@ es_read_file (const char *filename, unsigned char **buffer, size_t *buffer_n) } -static gpg_error_t -es_copy (estream_t dst, estream_t src) -{ - char buffer[BUFSIZ]; - size_t bytes_read; - gpg_error_t err; - int ret; - - err = 0; - while (1) - { - ret = es_read (src, buffer, sizeof (buffer), &bytes_read); - if (ret || (! bytes_read)) - { - if (ret) - err = gpg_error_from_errno (errno); - break; - } - ret = es_write (dst, buffer, bytes_read, NULL); - if (ret) - { - err = gpg_error_from_errno (errno); - break; - } - } - - return err; -} - - /* @@ -661,7 +662,7 @@ ssh_receive_mpint_list (estream_t stream, int secret, for (i = 0; i < elems_n; i++) { elem_is_secret = strchr (elems_secret, elems[i]) ? 1 : 0; - err = es_read_mpi (stream, elem_is_secret, &mpis[i]); + err = stream_read_mpi (stream, elem_is_secret, &mpis[i]); if (err) break; } @@ -727,7 +728,7 @@ ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis) if (err) goto out; - err = es_write_string (signature_blob, data, data_n); + err = stream_write_string (signature_blob, data, data_n); xfree (data); out: @@ -771,7 +772,7 @@ ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) if (err) goto out; - err = es_write_string (signature_blob, buffer, sizeof (buffer)); + err = stream_write_string (signature_blob, buffer, sizeof (buffer)); out: @@ -1075,7 +1076,7 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, comment = ""; key = NULL; - err = es_read_cstring (stream, &key_type); + err = stream_read_cstring (stream, &key_type); if (err) goto out; @@ -1089,7 +1090,7 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, if (read_comment) { - err = es_read_cstring (stream, &comment); + err = stream_read_cstring (stream, &comment); if (err) goto out; } @@ -1145,12 +1146,12 @@ ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, goto out; } - err = es_write_cstring (stream, type); + err = stream_write_cstring (stream, type); if (err) goto out; for (i = 0; mpis[i] && (! err); i++) - err = es_write_mpi (stream, mpis[i]); + err = stream_write_mpi (stream, mpis[i]); if (err) goto out; @@ -1172,7 +1173,7 @@ ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, goto out; } - err = es_read_data (stream, blob_new, blob_size_new); + err = stream_read_data (stream, blob_new, blob_size_new); if (err) goto out; @@ -1223,11 +1224,11 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public) if (err) goto out; - err = es_write_string (stream, blob, blob_n); + err = stream_write_string (stream, blob, blob_n); if (err) goto out; - err = es_write_cstring (stream, comment); + err = stream_write_cstring (stream, comment); out: @@ -1256,7 +1257,7 @@ ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size, goto out; } - err = es_write_data (blob_stream, blob, blob_size); + err = stream_write_data (blob_stream, blob, blob_size); if (err) goto out; @@ -1373,6 +1374,7 @@ key_secret_to_public (gcry_sexp_t *key_public, if (err) goto out; + /* FIXME: write better. */ sprintf (template, "(public-key (%s", spec.identifier); for (i = 0; i < elems_n; i++) sprintf (strchr (template, 0)," (%c %%m)", elems[i]); @@ -1479,7 +1481,7 @@ ssh_handler_request_identities (ctrl_t ctrl, strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40); /* Read file content. */ - err = es_read_file (key_path, &buffer, &buffer_n); + err = file_to_buffer (key_path, &buffer, &buffer_n); if (err) break; @@ -1540,19 +1542,19 @@ ssh_handler_request_identities (ctrl_t ctrl, if (! err) { - ret_err = es_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER); + ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER); if (ret_err) goto leave; - ret_err = es_write_uint32 (response, key_counter); + ret_err = stream_write_uint32 (response, key_counter); if (ret_err) goto leave; - ret_err = es_copy (response, key_blobs); + ret_err = stream_copy (response, key_blobs); if (ret_err) goto leave; } else { - ret_err = es_write_byte (response, SSH_RESPONSE_FAILURE); + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); goto leave; }; @@ -1651,7 +1653,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, if (err) goto out; - err = es_write_cstring (stream, spec.ssh_identifier); + err = stream_write_cstring (stream, spec.ssh_identifier); if (err) goto out; @@ -1714,7 +1716,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, goto out; } - err = es_read_data (stream, sig_blob, sig_blob_n); + err = stream_read_data (stream, sig_blob, sig_blob_n); if (err) goto out; @@ -1763,7 +1765,7 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) /* Receive key. */ - err = es_read_string (request, 0, &key_blob, &key_blob_size); + err = stream_read_string (request, 0, &key_blob, &key_blob_size); if (err) goto out; @@ -1772,12 +1774,12 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) goto out; /* Receive data to sign. */ - err = es_read_string (request, 0, &data, &data_size); + err = stream_read_string (request, 0, &data, &data_size); if (err) goto out; /* FIXME? */ - err = es_read_uint32 (request, &flags); + err = stream_read_uint32 (request, &flags); if (err) goto out; @@ -1817,16 +1819,16 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) if (! err) { - ret_err = es_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE); + ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE); if (ret_err) goto leave; - ret_err = es_write_string (response, sig, sig_n); + ret_err = stream_write_string (response, sig, sig_n); if (ret_err) goto leave; } else { - ret_err = es_write_byte (response, SSH_RESPONSE_FAILURE); + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); if (ret_err) goto leave; } @@ -1975,7 +1977,6 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) unsigned char *buffer; unsigned int buffer_n; char passphrase[100]; - size_t description_length; char *description; char key_grip[41]; char *comment; @@ -2000,23 +2001,15 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) if (err) goto out; - - /* FIXME: What the hell is that: Never have use sprintf in that way. - When marking a string translatbale you might get a buffer - overflow. We have never done this elsewhere. Using [x]asprintf - is the right way!! */ - description_length = 95 + (comment ? strlen (comment) : 0); - description = malloc (description_length); - if (! description) + ret = asprintf (&description, + "Please provide the passphrase, which should be used " + "for protecting the received secret key `%s':", + comment ? comment : ""); + if (ret < 0) { err = gpg_err_code_from_errno (errno); goto out; } - else - sprintf (description, - "Please provide the passphrase, which should be used " - "for protecting the received secret key `%s':", - comment ? comment : ""); err = get_passphrase (ctrl, description, sizeof (passphrase), passphrase); if (err) @@ -2041,7 +2034,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) xfree (buffer); xfree (comment); - xfree (description); + free (description); /* FIXME: verify xfree vs free. */ return err; @@ -2088,7 +2081,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) while (1) { - err = es_read_byte (request, &b); + err = stream_read_byte (request, &b); if (gpg_err_code (err) == GPG_ERR_EOF) { err = 0; @@ -2101,7 +2094,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) { u32 n = 0; - err = es_read_uint32 (request, &n); + err = stream_read_uint32 (request, &n); if (! err) ttl = n; break; @@ -2129,7 +2122,7 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) gcry_sexp_release (key); - ret_err = es_write_byte (response, + ret_err = stream_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); return ret_err; @@ -2150,7 +2143,7 @@ ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, key_blob = NULL; key = NULL; - err = es_read_string (request, 0, &key_blob, &key_blob_size); + err = stream_read_string (request, 0, &key_blob, &key_blob_size); if (err) goto out; @@ -2165,7 +2158,7 @@ ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, xfree (key_blob); gcry_sexp_release (key); - ret_err = es_write_byte (response, + ret_err = stream_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); return ret_err; @@ -2192,7 +2185,7 @@ ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request, gpg_error_t err; err = ssh_identities_remove_all (); - ret_err = es_write_byte (response, + ret_err = stream_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); return ret_err; @@ -2228,7 +2221,7 @@ ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response) gpg_error_t err; err = ssh_lock (); - ret_err = es_write_byte (response, + ret_err = stream_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); return ret_err; @@ -2241,7 +2234,7 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) gpg_error_t err; err = ssh_unlock (); - ret_err = es_write_byte (response, + ret_err = stream_write_byte (response, err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); return ret_err; @@ -2278,7 +2271,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) client -wk */ /* Retrieve request. */ - err = es_read_string (stream_sock, 1, &request_data, &request_data_size); + err = stream_read_string (stream_sock, 1, &request_data, &request_data_size); if (err) goto out; @@ -2301,7 +2294,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) err = gpg_error_from_errno (errno); goto out; } - err = es_write_data (request, request_data, request_data_size); + err = stream_write_data (request, request_data, request_data_size); if (err) goto out; es_rewind (request); @@ -2313,7 +2306,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) goto out; } - err = es_read_byte (request, &request_type); + err = stream_read_byte (request, &request_type); if (err) { send_err = 1; @@ -2350,14 +2343,14 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) goto out; } - err = es_write_uint32 (stream_sock, response_size); + err = stream_write_uint32 (stream_sock, response_size); if (err) { send_err = 1; goto out; } - err = es_copy (stream_sock, response); + err = stream_copy (stream_sock, response); if (err) goto out; @@ -2373,10 +2366,10 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) if (send_err) { - err = es_write_uint32 (stream_sock, 1); + err = stream_write_uint32 (stream_sock, 1); if (err) goto leave; - err = es_write_byte (stream_sock, SSH_RESPONSE_FAILURE); + err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE); if (err) goto leave; } -- cgit From fce56851f03794a2ce87057a5bf94be9ab1371c9 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Mon, 14 Feb 2005 20:44:22 +0000 Subject: 2005-02-14 Moritz Schulte * command-ssh.c (uint32_construct): New macro ... (stream_read_uint32): ... use it; removed unnecessary cast. --- agent/ChangeLog | 2 ++ agent/command-ssh.c | 29 ++++++++++++----------------- agent/gpg-agent.c | 2 +- 3 files changed, 15 insertions(+), 18 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 09cf0cdbc..7eb73e013 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -32,6 +32,8 @@ changed code to use asprintf for description. (stream_write_uint32): Do not filter out the last byte of shift expression. + (uint32_construct): New macro ... + (stream_read_uint32): ... use it; removed unnecessary cast. 2005-02-03 Werner Koch diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 68cca909b..d9e78c148 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -63,7 +63,14 @@ #define SSH_DSA_SIGNATURE_ELEMS 2 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0) + + +/* Macros. */ +/* Return a new uint32 with b0 being the most significant byte and b3 + being the least significant byte. */ +#define uint32_construct(b0, b1, b2, b3) \ + ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3) @@ -283,18 +290,7 @@ stream_read_uint32 (estream_t stream, u32 *uint32) { u32 n; - /* FIXME: For what is the cast good for? The proper way of - wrinting it - assuming an unsigned buffer - is: - - n = (buffer[0]<< 24)|(buffer[0]<< 16)|(buffer[0]<<8)|(buffer[0]); - - -wk - */ - n = (0 - | ((u32) (buffer[0] << 24)) - | ((u32) (buffer[1] << 16)) - | ((u32) (buffer[2] << 8)) - | ((u32) (buffer[3] << 0))); + n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]); *uint32 = n; err = 0; } @@ -311,11 +307,10 @@ stream_write_uint32 (estream_t stream, u32 uint32) gpg_error_t err; int ret; - /* Fixme: The 0xFF mask is superfluous. */ - buffer[0] = (uint32 >> 24) & 0xFF; - buffer[1] = (uint32 >> 16) & 0xFF; - buffer[2] = (uint32 >> 8) & 0xFF; - buffer[3] = (uint32 >> 0) & 0xFF; + buffer[0] = uint32 >> 24; + buffer[1] = uint32 >> 16; + buffer[2] = uint32 >> 8; + buffer[3] = uint32 >> 0; ret = es_write (stream, buffer, sizeof (buffer), NULL); if (ret) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index d8b891e5f..47488ee69 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1168,7 +1168,7 @@ create_server_socket (int is_standard_name, const char *name) agent_exit (2); } - + serv_addr = malloc (sizeof (*serv_addr)); /* FIXME. */ memset (serv_addr, 0, sizeof *serv_addr); serv_addr->sun_family = AF_UNIX; assert (strlen (name) + 1 < sizeof (serv_addr->sun_path)); -- cgit From cd42f5e45f63969b746580ab3c7e811b3d142289 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Fri, 18 Feb 2005 19:08:24 +0000 Subject: 2005-02-18 Moritz Schulte * command-ssh.c (ssh_sexp_construct): Rewritten generation of sexp template, clarified. (ssh_sexp_extract): Support shadowed-private-key-sexp; treat protected-private key and shadowed-private-key as public keys. (key_secret_to_public): Rewritten: simply use ssh_sexp_extract() and ssh_sexp_construct(). --- agent/ChangeLog | 9 ++++ agent/command-ssh.c | 150 ++++++++++++++-------------------------------------- 2 files changed, 48 insertions(+), 111 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index f0e19ad37..17641966a 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,12 @@ +2005-02-18 Moritz Schulte + + * command-ssh.c (ssh_sexp_construct): Rewritten generation of sexp + template, clarified. + (ssh_sexp_extract): Support shadowed-private-key-sexp; treat + protected-private key and shadowed-private-key as public keys. + (key_secret_to_public): Rewritten: simply use ssh_sexp_extract() + and ssh_sexp_construct(). + 2005-02-15 Werner Koch * findkey.c (modify_description): Don't increment OUT_LEN during diff --git a/agent/command-ssh.c b/agent/command-ssh.c index d9e78c148..2cb8ee8d7 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -780,11 +780,14 @@ ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) S-Expressions. */ + + static gpg_error_t ssh_sexp_construct (gcry_sexp_t *sexp, ssh_key_type_spec_t key_spec, int secret, gcry_mpi_t *mpis, const char *comment) { + const char *key_identifier[] = { "public-key", "private-key" }; gcry_sexp_t sexp_new; char *sexp_template; size_t sexp_template_n; @@ -804,9 +807,15 @@ ssh_sexp_construct (gcry_sexp_t *sexp, elems = key_spec.elems_key_public; elems_n = strlen (elems); - /* FIXME: Why 33? -wk */ - sexp_template_n = (33 + strlen (key_spec.identifier) - + (elems_n * 6) - (!secret)); + /* + Calculate size for sexp_template_n: + + "(%s(%s)(comment%s))" -> 20 + sizeof (). + + mpi: (X%m) -> 5. + + */ + sexp_template_n = 20 + (elems_n * 5); sexp_template = xtrymalloc (sexp_template_n); if (! sexp_template) { @@ -814,18 +823,25 @@ ssh_sexp_construct (gcry_sexp_t *sexp, goto out; } - arg_list = xtrymalloc (sizeof (*arg_list) * (elems_n + 1)); + /* Key identifier, algorithm identifier, mpis, comment. */ + arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1)); if (! arg_list) { err = gpg_error_from_errno (errno); goto out; } - sprintf (sexp_template, "(%s-key (%s ", - secret ? "private" : "public", key_spec.identifier); + i = 0; + arg_list[i++] = &key_identifier[secret]; + arg_list[i++] = &key_spec.identifier; + + *sexp_template = 0; + sexp_template_n = 0; + sexp_template_n = sprintf (sexp_template + sexp_template_n, "(%%s(%%s"); for (i = 0; i < elems_n; i++) { - sprintf (strchr (sexp_template, 0), "(%c %%m)", elems[i]); + sexp_template_n += sprintf (sexp_template + sexp_template_n, "(%c%%m)", + elems[i]); if (secret) { for (j = 0; j < elems_n; j++) @@ -834,10 +850,12 @@ ssh_sexp_construct (gcry_sexp_t *sexp, } else j = i; - arg_list[i] = &mpis[j]; + arg_list[i + 2] = &mpis[j]; } - arg_list[i] = &comment; - sprintf (strchr (sexp_template, 0), ") (comment %%s))"); + sexp_template_n += sprintf (sexp_template + sexp_template_n, + ")(comment%%s))"); + + arg_list[i + 2] = &comment; err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list); if (err) @@ -886,13 +904,14 @@ ssh_sexp_extract (gcry_sexp_t sexp, goto out; } - if (data_n == 10 && !strncmp (data, "public-key", 10)) + if ((data_n == 10 && !strncmp (data, "public-key", 10)) + || (data_n == 21 && !strncmp (data, "protected-private-key", 21)) + || (data_n == 20 && !strncmp (data, "shadowed-private-key", 20))) { is_secret = 0; elems = key_spec.elems_key_public; } - else if ((data_n == 11 && !strncmp (data, "private-key", 11)) - || (data_n == 21 && !strncmp (data, "protected-private-key", 21))) + else if (data_n == 11 && !strncmp (data, "private-key", 11)) { is_secret = 1; elems = key_spec.elems_key_secret; @@ -1276,115 +1295,24 @@ static gpg_error_t key_secret_to_public (gcry_sexp_t *key_public, ssh_key_type_spec_t spec, gcry_sexp_t key_secret) { - gpg_error_t err; - gcry_sexp_t value_pair; - unsigned int i; + const char *comment; gcry_mpi_t *mpis; - gcry_mpi_t mpi; - void **arglist; - size_t elems_n; - char *template; - size_t template_n; - const char *elems; - char *comment; - const char *data; - size_t data_n; + gpg_error_t err; + int is_secret; - err = 0; - mpis = NULL; - arglist = NULL; comment = NULL; - template = NULL; - value_pair = NULL; - - elems = spec.elems_key_public; - elems_n = strlen (elems); - - data = NULL; - value_pair = gcry_sexp_find_token (key_secret, "comment", 0); - if (value_pair) - data = gcry_sexp_nth_data (value_pair, 1, &data_n); - if (! data) - { - data = ""; - data_n = 0; - } - - comment = xtrymalloc (data_n + 1); - if (! comment) - { - err = gpg_error_from_errno (errno); - goto out; - } - strncpy (comment, data, data_n); - comment[data_n] = 0; - - gcry_sexp_release (value_pair); - value_pair = NULL; - - template_n = 29 + strlen (spec.identifier) + (elems_n * 7) + 1; - template = xtrymalloc (template_n); - if (! template) - { - err = gpg_error_from_errno (errno); - goto out; - } - - mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1)); - if (! mpis) - { - err = gpg_error_from_errno (errno); /* FIXME: errno. */ - goto out; - } - memset (mpis, 0, sizeof (*mpis) * (elems_n + 1)); - - arglist = xtrymalloc (sizeof (*arglist) * (elems_n + 1)); - if (! arglist) - { - err = gpg_error_from_errno (errno); - goto out; - } - - for (i = 0; i < elems_n; i++) - { - value_pair = gcry_sexp_find_token (key_secret, elems + i, 1); - if (! value_pair) - { - err = gpg_error (GPG_ERR_INV_SEXP); - break; - } - mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_USG); - if (! mpi) - { - err = gpg_error (GPG_ERR_INV_SEXP); - break; - } - gcry_sexp_release (value_pair); - value_pair = NULL; + mpis = NULL; - mpis[i] = mpi; - arglist[i] = &mpis[i]; - mpi = NULL; - } + err = ssh_sexp_extract (key_secret, spec, &is_secret, &mpis, &comment); if (err) goto out; - /* FIXME: write better. */ - sprintf (template, "(public-key (%s", spec.identifier); - for (i = 0; i < elems_n; i++) - sprintf (strchr (template, 0)," (%c %%m)", elems[i]); - sprintf (strchr (template, 0), ") (comment %%s))"); - arglist[i] = &comment; + err = ssh_sexp_construct (key_public, spec, 0, mpis, comment); - err = gcry_sexp_build_array (key_public, NULL, template, arglist); - out: - gcry_sexp_release (value_pair); - xfree (template); mpint_list_free (mpis); - xfree (arglist); - xfree (comment); + xfree ((char *) comment); return err; } -- cgit From 823eaefb0ba96f68e867745910116ddb15a8d03f Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Sat, 19 Feb 2005 17:17:30 +0000 Subject: 2005-02-19 Moritz Schulte * command-ssh.c (ssh_receive_mpint_list): Slightly rewritten, do not use elems_secret member of key_spec. (ssh_key_type_spec): Removed member: elems_secret. (ssh_key_types): Removed elems_secret data. (ssh_sexp_construct): Renamed to ... (sexp_key_construct): ... this; changed callers. (ssh_sexp_extract): Renamed to ... (sexp_key_extract): ... this; changed callers. (ssh_sexp_extract_key_type): Renamed to ... (sexp_extract_identifier): ... this; changed callers; use make_cstring(). Added more comments. --- agent/ChangeLog | 15 +++++++ agent/command-ssh.c | 115 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 92 insertions(+), 38 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 17641966a..f9064e46b 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,18 @@ +2005-02-19 Moritz Schulte + + * command-ssh.c (ssh_receive_mpint_list): Slightly rewritten, do + not use elems_secret member of key_spec. + (ssh_key_type_spec): Removed member: elems_secret. + (ssh_key_types): Removed elems_secret data. + (ssh_sexp_construct): Renamed to ... + (sexp_key_construct): ... this; changed callers. + (ssh_sexp_extract): Renamed to ... + (sexp_key_extract): ... this; changed callers. + (ssh_sexp_extract_key_type): Renamed to ... + (sexp_extract_identifier): ... this; changed callers; use + make_cstring(). + Added more comments. + 2005-02-18 Moritz Schulte * command-ssh.c (ssh_sexp_construct): Rewritten generation of sexp diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 2cb8ee8d7..fbd296ea6 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -75,12 +75,17 @@ -/* Basic types. */ +/* + * Basic types. + */ +/* Type for a request handler. */ typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl, estream_t request, estream_t response); +/* Type, which is used for associating request handlers with the + appropriate request IDs. */ typedef struct ssh_request_spec { unsigned char type; @@ -88,22 +93,51 @@ typedef struct ssh_request_spec const char *identifier; } ssh_request_spec_t; +/* Type for "key modifier functions", which are necessary since + OpenSSH and GnuPG treat key material slightly different. A key + modifier is called right after a new key identity has been received + in order to "sanitize" the material. */ typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems, gcry_mpi_t *mpis); + +/* The encoding of a generated signature is dependent on the + algorithm; therefore algorithm specific signature encoding + functions are necessary. */ typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob, gcry_mpi_t *mpis); +/* Type, which is used for boundling all the algorithm specific + information together in a single object. */ typedef struct ssh_key_type_spec { + /* Algorithm identifier as used by OpenSSH. */ const char *ssh_identifier; + + /* Algorithm identifier as used by GnuPG. */ const char *identifier; + + /* List of MPI names for secret keys; order matches the one of the + agent protocol. */ const char *elems_key_secret; + + /* List of MPI names for public keys; order matches the one of the + agent protocol. */ const char *elems_key_public; - const char *elems_secret; + + /* List of MPI names for signature data. */ const char *elems_signature; + + /* List of MPI names for secret keys; order matches the one, which + is required by gpg-agent's key access layer. */ const char *elems_sexp_order; + + /* Key modifier function. */ ssh_key_modifier_t key_modifier; + + /* Signature encoder function. */ ssh_signature_encoder_t signature_encoder; + + /* Misc flags. */ unsigned int flags; } ssh_key_type_spec_t; @@ -166,12 +200,12 @@ static ssh_request_spec_t request_specs[] = static ssh_key_type_spec_t ssh_key_types[] = { { - "ssh-rsa", "rsa", "nedupq", "en", "dupq", "s", "nedpqu", + "ssh-rsa", "rsa", "nedupq", "en", "s", "nedpqu", ssh_key_modifier_rsa, ssh_signature_encoder_rsa, SPEC_FLAG_USE_PKCS1V2 }, { - "ssh-dss", "dsa", "pqgyx", "pqgy", "x", "rs", "pqgyx", + "ssh-dss", "dsa", "pqgyx", "pqgy", "rs", "pqgyx", NULL, ssh_signature_encoder_dsa, 0 }, @@ -206,7 +240,8 @@ realloc_secure (void *a, size_t n) } - +/* Create and return a new C-string from DATA/DATA_N (i.e.: add + NUL-termination); return NULL on OOM. */ static char * make_cstring (const char *data, size_t data_n) { @@ -604,6 +639,7 @@ file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) */ +/* Free the list of MPIs MPI_LIST. */ static void mpint_list_free (gcry_mpi_t *mpi_list) { @@ -622,29 +658,27 @@ static gpg_error_t ssh_receive_mpint_list (estream_t stream, int secret, ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list) { - const char *elems_secret; - const char *elems; + unsigned int elems_public_n; + const char *elems_public; unsigned int elems_n; + const char *elems; + int elem_is_secret; gcry_mpi_t *mpis; - unsigned int i; gpg_error_t err; - int elem_is_secret; + unsigned int i; mpis = NULL; err = 0; if (secret) - { - elems = key_spec.elems_key_secret; - elems_secret = key_spec.elems_secret; - } + elems = key_spec.elems_key_secret; else - { - elems = key_spec.elems_key_public; - elems_secret = ""; - } + elems = key_spec.elems_key_public; elems_n = strlen (elems); + elems_public = key_spec.elems_key_public; + elems_public_n = strlen (elems_public); + mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1)); if (! mpis) { @@ -653,10 +687,12 @@ ssh_receive_mpint_list (estream_t stream, int secret, } memset (mpis, 0, sizeof (*mpis) * (elems_n + 1)); - + + elem_is_secret = 0; for (i = 0; i < elems_n; i++) { - elem_is_secret = strchr (elems_secret, elems[i]) ? 1 : 0; + if (secret) + elem_is_secret = ! strchr (elems_public, elems[i]); err = stream_read_mpi (stream, elem_is_secret, &mpis[i]); if (err) break; @@ -676,6 +712,7 @@ ssh_receive_mpint_list (estream_t stream, int secret, +/* Key modifier function for RSA. */ static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis) { @@ -709,6 +746,7 @@ ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis) return 0; } +/* Signature encoder function for RSA. */ static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis) { @@ -732,7 +770,7 @@ ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis) } - +/* Signature encoder function for DSA. */ static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) { @@ -781,9 +819,9 @@ ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) */ - +/* */ static gpg_error_t -ssh_sexp_construct (gcry_sexp_t *sexp, +sexp_key_construct (gcry_sexp_t *sexp, ssh_key_type_spec_t key_spec, int secret, gcry_mpi_t *mpis, const char *comment) { @@ -871,8 +909,9 @@ ssh_sexp_construct (gcry_sexp_t *sexp, return err; } + static gpg_error_t -ssh_sexp_extract (gcry_sexp_t sexp, +sexp_key_extract (gcry_sexp_t sexp, ssh_key_type_spec_t key_spec, int *secret, gcry_mpi_t **mpis, const char **comment) { @@ -1002,17 +1041,19 @@ ssh_sexp_extract (gcry_sexp_t sexp, return err; } +/* Extract the car from SEXP, and create a newly created C-string it, + which is to be stored in IDENTIFIER. */ static gpg_error_t -ssh_sexp_extract_key_type (gcry_sexp_t sexp, const char **key_type) +sexp_extract_identifier (gcry_sexp_t sexp, const char **identifier) { + char *identifier_new; gcry_sexp_t sublist; - char *key_type_new; const char *data; size_t data_n; gpg_error_t err; + identifier_new = NULL; err = 0; - key_type_new = NULL; sublist = gcry_sexp_nth (sexp, 1); if (! sublist) @@ -1028,16 +1069,14 @@ ssh_sexp_extract_key_type (gcry_sexp_t sexp, const char **key_type) goto out; } - key_type_new = xtrymalloc (data_n + 1); - if (! key_type_new) + identifier_new = make_cstring (data, data_n); + if (! identifier_new) { - err = gpg_error_from_errno (errno); + err = gpg_err_code_from_errno (errno); goto out; } - strncpy (key_type_new, data, data_n); - key_type_new[data_n] = 0; - *key_type = key_type_new; + *identifier = identifier_new; out: @@ -1121,7 +1160,7 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, goto out; } - err = ssh_sexp_construct (&key, spec, secret, mpi_list, comment); + err = sexp_key_construct (&key, spec, secret, mpi_list, comment); if (err) goto out; @@ -1221,7 +1260,7 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public) comment = NULL; blob = NULL; - err = ssh_sexp_extract_key_type (key_public, &key_type); + err = sexp_extract_identifier (key_public, &key_type); if (err) goto out; @@ -1229,7 +1268,7 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public) if (err) goto out; - err = ssh_sexp_extract (key_public, spec, NULL, &mpi_list, &comment); + err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &comment); if (err) goto out; @@ -1303,11 +1342,11 @@ key_secret_to_public (gcry_sexp_t *key_public, comment = NULL; mpis = NULL; - err = ssh_sexp_extract (key_secret, spec, &is_secret, &mpis, &comment); + err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, &comment); if (err) goto out; - err = ssh_sexp_construct (key_public, spec, 0, mpis, comment); + err = sexp_key_construct (key_public, spec, 0, mpis, comment); out: @@ -1415,7 +1454,7 @@ ssh_handler_request_identities (ctrl_t ctrl, xfree (buffer); buffer = NULL; - err = ssh_sexp_extract_key_type (key_secret, &key_type); + err = sexp_extract_identifier (key_secret, &key_type); if (err) break; -- cgit From cf8f6d3cefd3ed45bac7f944c03319746277c292 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 22 Feb 2005 18:08:28 +0000 Subject: (stream_read_string): Removed call to abort on memory error because the CVS version of libgcrypt makes sure that ERRNO gets always set on error even with a faulty user supplied function. --- TODO | 2 + agent/ChangeLog | 7 ++ agent/call-scd.c | 2 +- agent/command-ssh.c | 13 ++- agent/learncard.c | 28 +++++-- doc/ChangeLog | 4 + doc/README.W32 | 222 +++++++++------------------------------------------- doc/gpgsm.texi | 6 ++ jnlib/ChangeLog | 3 +- jnlib/argparse.c | 2 +- 10 files changed, 87 insertions(+), 202 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/TODO b/TODO index 7a2292bd6..2aace782f 100644 --- a/TODO +++ b/TODO @@ -54,6 +54,8 @@ might want to have an agent context for each service request ** A SIGHUP should also restart the scdaemon But do this only after all connections terminated. As of now we only send a RESET. +** Watch the child process if not invoked as a daemon + and terminate after the child has terminated * agent/command.c ** Make sure that secure memory is used where appropriate diff --git a/agent/ChangeLog b/agent/ChangeLog index f9064e46b..420dc6368 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,10 @@ +2005-02-22 Werner Koch + + * command-ssh.c (stream_read_string): Removed call to abort on + memory error because the CVS version of libgcrypt makes sure + that ERRNO gets always set on error even with a faulty user + supplied function. + 2005-02-19 Moritz Schulte * command-ssh.c (ssh_receive_mpint_list): Slightly rewritten, do diff --git a/agent/call-scd.c b/agent/call-scd.c index 619a549f9..bffdbcbad 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -296,7 +296,7 @@ learn_status_cb (void *opaque, const char *line) return 0; } -/* Perform the learn command and return a list of all private keys +/* Perform the LEARN command and return a list of all private keys stored on the card. */ int agent_card_learn (ctrl_t ctrl, diff --git a/agent/command-ssh.c b/agent/command-ssh.c index fbd296ea6..1719602f2 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -215,15 +215,12 @@ static ssh_key_type_spec_t ssh_key_types[] = - - - /* General utility functions. */ /* A secure realloc, i.e. it makes sure to allocate secure memory if A - is NULL. This is required becuase the standard gcry_realloc does + is NULL. This is required because the standard gcry_realloc does not know whether to allocate secure or normal if NULL is passed as existing buffer. */ static void * @@ -419,9 +416,7 @@ stream_read_string (estream_t stream, unsigned int secure, buffer = xtrymalloc (length + 1); if (! buffer) { - /* FIXME: xtrymalloc_secure does not set errno, does it? */ err = gpg_error_from_errno (errno); - abort (); goto out; } @@ -1530,6 +1525,8 @@ ssh_handler_request_identities (ctrl_t ctrl, free (key_directory); xfree (key_path); xfree (buffer); + /* FIXME: Ist is for sure is a Bad Thing to use the const qualifier + and later cast it away. You can't do that!!! */ xfree ((void *) key_type); /* FIXME? */ return ret_err; @@ -2159,7 +2156,7 @@ ssh_lock (void) gpg_error_t err; /* FIXME */ - log_error (_("lock command is not implemented\n")); + log_error ("ssh-agent's lock command is not implemented\n"); err = 0; return err; @@ -2170,7 +2167,7 @@ ssh_unlock (void) { gpg_error_t err; - log_error (_("unlock command is not implemented\n")); + log_error ("ssh-agent's unlock command is not implemented\n"); err = 0; return err; diff --git a/agent/learncard.c b/agent/learncard.c index 76e8986f8..7dcacee28 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -31,11 +31,16 @@ #include "agent.h" #include +/* Structures used by the callback mechanism to convey information + pertaining to key pairs. */ struct keypair_info_s { struct keypair_info_s *next; int no_cert; - char *id; /* points into grip */ - char hexgrip[1]; + char *id; /* points into grip */ + char hexgrip[1]; /* The keygrip (i.e. a hash over the public key + parameters) formatted as a hex string. + Allocated somewhat large to also act as + memeory for the above ID field. */ }; typedef struct keypair_info_s *KEYPAIR_INFO; @@ -45,6 +50,9 @@ struct kpinfo_cb_parm_s { }; + +/* Structures used by the callback mechanism to convey information + pertaining to certificates. */ struct certinfo_s { struct certinfo_s *next; int type; @@ -59,6 +67,8 @@ struct certinfo_cb_parm_s { }; +/* Structures used by the callback mechanism to convey assuan status + lines. */ struct sinfo_s { struct sinfo_s *next; char *data; /* Points into keyword. */ @@ -72,7 +82,7 @@ struct sinfo_cb_parm_s { }; - +/* Destructor for key information objects. */ static void release_keypair_info (KEYPAIR_INFO info) { @@ -84,6 +94,7 @@ release_keypair_info (KEYPAIR_INFO info) } } +/* Destructor for certificate information objects. */ static void release_certinfo (CERTINFO info) { @@ -95,6 +106,7 @@ release_certinfo (CERTINFO info) } } +/* Destructor for status information objects. */ static void release_sinfo (SINFO info) { @@ -285,7 +297,7 @@ send_cert_back (ctrl_t ctrl, const char *id, void *assuan_context) } /* Perform the learn operation. If ASSUAN_CONTEXT is not NULL all new - certificates are send via Assuan */ + certificates are send back via Assuan. */ int agent_handle_learn (ctrl_t ctrl, void *assuan_context) { @@ -317,7 +329,7 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context) if (rc) goto leave; - /* now gather all the available info */ + /* Now gather all the available info. */ rc = agent_card_learn (ctrl, kpinfo_cb, &parm, certinfo_cb, &cparm, sinfo_cb, &sparm); if (!rc && (parm.error || cparm.error || sparm.error)) @@ -371,15 +383,15 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context) log_info (" id: %s (grip=%s)\n", item->id, item->hexgrip); if (item->no_cert) - continue; /* no public key yet available */ + continue; /* No public key yet available. */ for (p=item->hexgrip, i=0; i < 20; p += 2, i++) grip[i] = xtoi_2 (p); if (!agent_key_available (grip)) - continue; + continue; /* The key is already available. */ - /* unknown - store it */ + /* Unknown key - store it. */ rc = agent_card_readkey (ctrl, item->id, &pubkey); if (rc) { diff --git a/doc/ChangeLog b/doc/ChangeLog index fa61b0466..49e8b026f 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2005-02-14 Werner Koch + + * gpgsm.texi (Certificate Management): Document --import. + 2005-01-27 Moritz Schulte * gpg-agent.texi: Document ssh-agent emulation layer. diff --git a/doc/README.W32 b/doc/README.W32 index 18f745d9c..6417e90cb 100644 --- a/doc/README.W32 +++ b/doc/README.W32 @@ -1,186 +1,42 @@ -README.W32 -*- text -*- + README.W32 + ============ + 2004-12-22 -This is a binary package with GnuPG for MS-Windows 95, 98, WNT, W2000 -and XP. See the file README for generic instructions and usage hints. + This is a precompiled version of gnupg 1.9.14 for MS Windows. + Please see the manual (gnupg.pdf) for the current limitations. Be + aware that this is the first released version and thus bugs are + pretty likely. -A FAQ comes with this package and a probably more recent one can be -found online at http://www.gnupg.org/faq.html. See -http://www.gnupg.org/docs-mls.html for a list of mailing lists. In -particular the list gnupg-users@gnupg.org might be useful to answer -questions - but please read the FAQ first. - - -Installation directory: -======================= - -The installation directory of GnuPG is stored in the Registry under -the key HKEY_LOCAL_MACHINE\Software\GNU\GnuPG with the name "Install -Directory". The installer does not change the PATH environment -variable to include this directory. You might want to do this -manually. - -Below the Installation directory, you will find directories named -"Doc", "gnupg.nls" and "Src". The latter will be used for distributed -patched, if any, and to store the source file if they have been -included in this package. The source files usually require further -unpacking using a the TAR utility. - - -Internationalization support: -============================= - -Store the locale id (like "de") into the Registry under the key -HKEY_CURRENT_USER\Software\GNU\GnuPG with the name "Lang". This must -match one of the installed languages files in the directory named -"gnupg.nls" below the installation directory. Note, that the ".mo" -extension is not part of the lcoale id. - - -Home directory: -=============== - -GnuPG makes use of a per user home directory to store its keys as well -as configuration files. The default home directory is a directory -named "gnupg" below the application data directory of the user. This -directory will be created if it does not exist. Being only a default, -it may be changed by setting the name of the home directory into the -Registry under the key HKEY_CURRENT_USER\Software\GNU\GnuPG using the -name "HomeDir". If an environment varaibale "GNUPGHOME" exists, this -even overrides the registry setting. The command line option -"--homedir" may be used to override all other settings of the home -directory. - - -Reporting bugs: -=============== - -Please check the documentation first before asking or reporting a -bugs. In particular check the archives of the mailing lists (see -www.gnupg.org) and the bug tracking system at http://bugs.gnupg.org -(login is "guest" password is "guest") whether the problem is already -known. Asking on the gnupg-users mailing list is also strongly -encouraged; if you are not subscribed it may some time until a posting -is approved (this is an anti-spam measure). Bug reporting addresses -are listed in the file AUTHORS. - -If you want to report a bug or have other problems, always give -detailed description of the problem, the version of GnuPG you used, -the version of the OS, whether it is the official version from -gnupg.org or how you built it. Don't edit error messages - replacing -sensitive information like user IDs, fingerprints and keyids is okay. -If possible, switch to English messages by changing the "Lang" entry -to empty (see under Internationalization support). - - -How to build GnuPG from the source: -=================================== - -Until recently all official GnuPG versions have been build using the -Mingw32/CPD kit as available at -ftp://ftp.gnupg.org/people/werner/cpd/mingw32-cqpd-0.3.2.tar.gz . -However, for maintenance reasons we switched to Debian's mingw32 cross -compiler package and that is now the recommended way of building GnuPG -for W32 platforms. It might be possible to build it nativly on a W32 -platform but this is not supported. Please don't file any bug reports -if it does not build with any other system than the recommended one. - -According to the conditions of the GNU General Public License you -either got the source files with this package, a written offer to send -you the source on demand or the source is available at the same site -you downloaded the binary package. If you downloaded the package from -the official GnuPG site or one of its mirrors, the corresponding -source tarball is available in the sibling directory named gnupg. The -source used to build all versions is always the same and the version -numbers should match. If the version number of the binary package has -a letter suffix, you will find a patch file installed in the "Src" -directory with the changes relative to the generic version. - -The source is distributed as a BZIP2 or GZIP compressed tar archive. -See the instructions in file README on how to check the integrity of -that file. Wir a properly setup build environment, you unpack the -tarball change to the created directory and run - - $ ./autogen.sh --build-w32 - $ make - $ cp g10/gpg*.exe /some_windows_drive/ - -Building a version with the installer is a bit more complex and -basically works by creating a top directory, unpacking in that top -directory, switching to the gnupg-1.x.y directory, running -"./autogen.sh --build-w32" and "make", switching back to the top -directory, running a "mkdir dist-w32; mkdir iconv", copying the -required iconv files (iconv.dll, README.iconv, COPYING.LIB) into the -iconv directory, running gnupg-1.x.y/scripts/mk-w32-dist and voila, -the installer package will be available in the dist-w32 directory. - - -Copying: -======== - -GnuPG is - - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005 Free Software Foundation, Inc. - - GnuPG is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GnuPG 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 General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA - -See the files AUTHORS and THANKS for credits, further legal -information and bug reporting addresses pertaining to GnuPG. - -For copying conditions of the GNU LIBICONV library see the file -README.iconv. + Please copy all files to the directory c:\gnupg and follow the + manual instructions. -The installer software used to create the official binary packages for -W32 is NSIS (http://nsis.sourceforge.net/): - - Copyright (C) 1999-2005 Nullsoft, Inc. - - This license applies to everything in the NSIS package, except where - otherwise noted. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any - damages arising from the use of this software. - - Permission is granted to anyone to use this software for any - purpose, including commercial applications, and to alter it and - redistribute it freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. - -The user interface used with the installer is - - Copyright (C) 2002-2005 Joost Verburg - - [It is distributed along with NSIS and the same conditions as stated - above apply] - - -The term "W32" is used to describe the API used by current Microsoft -Windows versions. We don't use the Microsft terminology here; in -hacker terminology, calling something a "win" is a form of praise. -Keep in mind that Windows ist just a temporary workaround until you -can switch to a complete Free Software system. Be the source always -with you. + This software has been build using Debian's mingw package, version + 3.3.1.20030804.1-1. Libraries are all compiled statically, versions + of the used libraries are: + + gpg-error-config: 1.1-cvs + libgcrypt-config: 1.2.1-cvs + ksba-config: 0.9.11-cvs + libassuan-config: 0.6.9-cvs + + as these are all CVS versions you need to get the from the CVS. See + www.gnupg.org for details. Use 2004-12-22 18:00 UTC as revision + date. The source code of GnuPG itsself is available at + ftp://ftp.gnupg.org/gcrypt/alpha/gnupg/gnupg-1.9.14.tar.bz2 + ftp://ftp.gnupg.org/gcrypt/alpha/gnupg/gnupg-1.9.14.tar.bz2.sig + + Building has been done by running the command + + ./autogen.sh --build-w32 + + for all these libraries and then for gnupg. The PDF file has been + produced by first converting the logo file to pdf and the running + "make gnupg.pdf" in the doc directory. All executables have been + stripped. + + In case of questions please contact us at info@g10code.com or better + write to the mailing list gnupg-devel@gnupg.org. + + Thanks, + + The g10 Code team diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 1e7368041..09fd7d660 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -190,6 +190,12 @@ a few informational lines are prepended to the output. Note, that the PKCS#12 format is higly insecure and this command is only provided if there is no other way to exchange the private key. +@item --import [@var{files}] +@opindex import +Import the certificates from the PEM or binary encoded files as well as +from signed-only messages. This command may also be used to import a +secret key from a PKCS#12 file. + @item --learn-card @opindex learn-card Read information about the private keys from the smartcard and import diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index 0c82c8724..f308a7ea3 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -316,7 +316,8 @@ Mon Jan 24 13:04:28 CET 2000 Werner Koch * You may find it source-copied in other packages. * *********************************************************** - Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002, 2003, 2004, + 2005 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/jnlib/argparse.c b/jnlib/argparse.c index de828e8ce..485c60786 100644 --- a/jnlib/argparse.c +++ b/jnlib/argparse.c @@ -904,7 +904,7 @@ strusage( int level ) switch( level ) { case 11: p = "foo"; break; case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2004 Free Software Foundation, Inc."; break; + case 14: p = "Copyright (C) 2005 Free Software Foundation, Inc."; break; case 15: p = "This program comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it\n" -- cgit From 4e5bf2fd93a175f64aa1ca2e4b35dcf853f7f828 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 23 Feb 2005 21:06:32 +0000 Subject: * command-ssh.c (get_passphrase): Removed. (ssh_identity_register): Partly rewritten. (open_control_file, search_control_file, add_control_entry): New. (ssh_handler_request_identities): Return only files listed in our control file. * findkey.c (unprotect): Check for allocation error. * agent.h (opt): Add fields to record the startup terminal settings. * gpg-agent.c (main): Record them and do not force keep display with --enable-ssh-support. * command-ssh.c (start_command_handler_ssh): Use them here. * gpg-agent.c: Renamed option --ssh-support to --enable-ssh-support. * command.c (cmd_readkey): New. (register_commands): Register new command "READKEY". * command-ssh.c (ssh_request_process): Improved logging. * findkey.c (agent_write_private_key): Always use plain open. Don't depend on an umask for permissions. (agent_key_from_file): Factored file reading code out to .. (read_key_file): .. new function. (agent_public_key_from_file): New. --- agent/ChangeLog | 40 +++++- agent/agent.h | 12 ++ agent/command-ssh.c | 363 +++++++++++++++++++++++++++++++++++++++++----------- agent/command.c | 54 +++++++- agent/findkey.c | 330 +++++++++++++++++++++++++++++++++++++++-------- agent/gpg-agent.c | 30 +++-- agent/keyformat.txt | 6 + agent/protect.c | 2 +- agent/query.c | 2 +- 9 files changed, 690 insertions(+), 149 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 420dc6368..47ca2debf 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,33 @@ +2005-02-23 Werner Koch + + * command-ssh.c (get_passphrase): Removed. + (ssh_identity_register): Partly rewritten. + (open_control_file, search_control_file, add_control_entry): New. + (ssh_handler_request_identities): Return only files listed in our + control file. + + * findkey.c (unprotect): Check for allocation error. + + * agent.h (opt): Add fields to record the startup terminal + settings. + * gpg-agent.c (main): Record them and do not force keep display + with --enable-ssh-support. + * command-ssh.c (start_command_handler_ssh): Use them here. + + * gpg-agent.c: Renamed option --ssh-support to + --enable-ssh-support. + + * command.c (cmd_readkey): New. + (register_commands): Register new command "READKEY". + + * command-ssh.c (ssh_request_process): Improved logging. + + * findkey.c (agent_write_private_key): Always use plain open. + Don't depend on an umask for permissions. + (agent_key_from_file): Factored file reading code out to .. + (read_key_file): .. new function. + (agent_public_key_from_file): New. + 2005-02-22 Werner Koch * command-ssh.c (stream_read_string): Removed call to abort on @@ -1092,21 +1122,21 @@ Mon Aug 21 17:59:17 CEST 2000 Werner Koch - * gpg-agent.c (passphrase_dialog): Cleanup the window and added the + * gpg-agent.c (passphrase_dialog): Cleanup the window and added the user supplied text to the window. (main): Fixed segv in gtk_init when used without a command to start. - * gpg-agent.c: --flush option. + * gpg-agent.c: --flush option. (req_flush): New. (req_clear_passphrase): Implemented. Fri Aug 18 14:27:14 CEST 2000 Werner Koch - * gpg-agent.c: New. - * Makefile.am: New. + * gpg-agent.c: New. + * Makefile.am: New. - Copyright 2001, 2002 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/agent/agent.h b/agent/agent.h index a1196bc0b..0661cc4ad 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -53,6 +53,15 @@ struct { int dry_run; /* Don't change any persistent data */ int batch; /* Batch mode */ const char *homedir; /* Configuration directory name */ + + /* Environment setting gathred at program start. */ + const char *startup_display; + const char *startup_ttyname; + const char *startup_ttytype; + const char *startup_lc_ctype; + const char *startup_lc_messages; + + const char *pinentry_program; /* Filename of the program to start as pinentry. */ const char *scdaemon_program; /* Filename of the program to handle @@ -150,6 +159,9 @@ gpg_error_t agent_key_from_file (ctrl_t ctrl, const unsigned char *grip, unsigned char **shadow_info, int ignore_cache, gcry_sexp_t *result); +gpg_error_t agent_public_key_from_file (ctrl_t ctrl, + const unsigned char *grip, + gcry_sexp_t *result); int agent_key_available (const unsigned char *grip); /*-- query.c --*/ diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 1719602f2..8ea042e19 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -23,13 +23,14 @@ #include +#include #include #include #include #include #include #include -#include +#include #include "agent.h" @@ -63,7 +64,22 @@ #define SSH_DSA_SIGNATURE_ELEMS 2 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0) - + +/* The blurb we put into the header of a newly created control file. */ +static const char sshcontrolblurb[] = +"# List of allowed ssh keys. Only keys present in this file are used\n" +"# in the SSH protocol. The ssh-add tool may add new entries to this\n" +"# file to enable them; you may also add them manually. Comment\n" +"# lines, like this one, as well as empty lines are ignored. Lines do\n" +"# have a certain length limit but this is not serious limitation as\n" +"# the format of the entries is fixed and checked by gpg-agent. A\n" +"# non-comment line starts with optional white spaces, followed by the\n" +"# keygrip of the key given as 40 hex digits, optionally followed by a\n" +"# the caching TTL in seconds and another optional field for arbitrary\n" +"# flags. Prepend the keygrip with an '!' mark to disable it.\n" +"\n"; + + /* Macros. */ @@ -626,6 +642,155 @@ file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) } + + +/* Open the ssh control file and create it if not available. With + APPEND passed as true the file will be opened in append mode, + otherwise in read only mode. On success a file pointer is stored + at the address of R_FP. */ +static gpg_error_t +open_control_file (FILE **r_fp, int append) +{ + gpg_error_t err; + char *fname; + FILE *fp; + + /* Note: As soon as we start to use non blocking functions here + (i.e. where Pth might switch threads) we need to employ a + mutex. */ + *r_fp = NULL; + fname = make_filename (opt.homedir, "sshcontrol.txt", NULL); + fp = fopen (fname, append? "a+":"r"); + if (!fp && errno == ENOENT) + { + /* Fixme: "x" is a GNU extension. We might want to use the es_ + functions here. */ + fp = fopen (fname, "wx"); + if (!fp) + { + err = gpg_error (gpg_err_code_from_errno (errno)); + log_error (_("can't create `%s': %s\n"), fname, gpg_strerror (err)); + xfree (fname); + return err; + } + fputs (sshcontrolblurb, fp); + fclose (fp); + fp = fopen (fname, append? "a+":"r"); + } + + if (!fp) + { + err = gpg_error (gpg_err_code_from_errno (errno)); + log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err)); + xfree (fname); + return err; + } + + *r_fp = fp; + + return 0; +} + + +/* Search the file at stream FP from the beginning until a matching + HEXGRIP is found; return success in this case and store true at + DISABLED if the found key has been disabled. */ +static gpg_error_t +search_control_file (FILE *fp, const char *hexgrip, int *disabled) +{ + int c, i; + char *p, line[256]; + + assert (strlen (hexgrip) == 40 ); + + rewind (fp); + *disabled = 0; + next_line: + do + { + if (!fgets (line, DIM(line)-1, fp) ) + { + if (feof (fp)) + return gpg_error (GPG_ERR_EOF); + return gpg_error (gpg_err_code_from_errno (errno)); + } + + if (!*line || line[strlen(line)-1] != '\n') + { + /* Eat until end of line */ + while ( (c=getc (fp)) != EOF && c != '\n') + ; + return gpg_error (*line? GPG_ERR_LINE_TOO_LONG + : GPG_ERR_INCOMPLETE_LINE); + } + + /* Allow for empty lines and spaces */ + for (p=line; spacep (p); p++) + ; + } + while (!*p || *p == '\n' || *p == '#'); + + *disabled = 0; + if (*p == '!') + { + *disabled = 1; + for (p++; spacep (p); p++) + ; + } + + for (i=0; hexdigitp (p) && i < 40; p++, i++) + if (hexgrip[i] != (*p >= 'a'? (*p & 0xdf): *p)) + goto next_line; + if (i != 40 || !(spacep (p) || *p == '\n')) + { + log_error ("invalid formatted line in ssh control file\n"); + return gpg_error (GPG_ERR_BAD_DATA); + } + + /* Fixme: Get TTL and flags. */ + + return 0; /* Okay: found it. */ +} + + + +/* Add an entry to the control file to mark the key with the keygrip + HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks + for it. This function is in general used to add a key received + through the ssh-add function. We can assume that the user wants to + allow ssh using this key. */ +static gpg_error_t +add_control_entry (ctrl_t ctrl, const char *hexgrip, int ttl) +{ + gpg_error_t err; + FILE *fp; + int disabled; + + err = open_control_file (&fp, 1); + if (err) + return err; + + err = search_control_file (fp, hexgrip, &disabled); + if (err && gpg_err_code(err) == GPG_ERR_EOF) + { + struct tm *tp; + time_t atime = time (NULL); + + /* Not yet in the file - add it. Becuase the file has been + opened in append mode, we simply need to write to it. */ + tp = localtime (&atime); + fprintf (fp, "# Key added on %04d-%02d-%02d %02d:%02d:%02d\n%s %d\n", + 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec, + hexgrip, ttl); + + } + fclose (fp); + return 0; +} + + + /* @@ -1377,6 +1542,7 @@ ssh_handler_request_identities (ctrl_t ctrl, gpg_error_t err; gpg_error_t ret_err; int ret; + FILE *ctrl_fp = NULL; /* Prepare buffer stream. */ @@ -1427,6 +1593,19 @@ ssh_handler_request_identities (ctrl_t ctrl, /* FIXME: make sure that buffer gets deallocated properly. */ + /* Fixme: We should better iterate over the control file and check + whether the key file is there. This is better in resepct to + performance if tehre are a lot of key sin our key storage. */ + + err = open_control_file (&ctrl_fp, 0); + if (err) + goto out; + +#warning Really need to fix this fixme. + /* + FIXME: First check whether a key is currently available in the card reader - this should be allowed even without being listed in sshcontrol.txt. + */ + while (1) { dir_entry = readdir (dir); @@ -1435,6 +1614,19 @@ ssh_handler_request_identities (ctrl_t ctrl, if ((strlen (dir_entry->d_name) == 44) && (! strncmp (dir_entry->d_name + 40, ".key", 4))) { + char hexgrip[41]; + int disabled; + + /* We do only want to return keys listed in our control + file. */ + strncpy (hexgrip, dir_entry->d_name, 40); + hexgrip[40] = 0; + if ( strlen (hexgrip) != 40 ) + continue; + if (search_control_file (ctrl_fp, hexgrip, &disabled) + || disabled) + continue; + strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40); /* Read file content. */ @@ -1522,6 +1714,9 @@ ssh_handler_request_identities (ctrl_t ctrl, if (dir) closedir (dir); + if (ctrl_fp) + fclose (ctrl_fp); + free (key_directory); xfree (key_path); xfree (buffer); @@ -1802,43 +1997,6 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) return ret_err; } -static gpg_error_t -get_passphrase (ctrl_t ctrl, - const char *description, size_t passphrase_n, char *passphrase) -{ - struct pin_entry_info_s *pi; - gpg_error_t err; - - err = 0; - pi = gcry_calloc_secure (1, sizeof (*pi) + passphrase_n + 1); - if (! pi) - { - err = gpg_error (GPG_ERR_ENOMEM); - goto out; - } - - pi->min_digits = 0; /* We want a real passphrase. */ - pi->max_digits = 8; - pi->max_tries = 1; - pi->failed_tries = 0; - pi->check_cb = NULL; - pi->check_cb_arg = NULL; - pi->cb_errtext = NULL; - pi->max_length = 100; - - err = agent_askpin (ctrl, description, NULL, pi); - if (err) - goto out; - - memcpy (passphrase, pi->pin, passphrase_n); - passphrase[passphrase_n] = 0; - - out: - - xfree (pi); - - return err; -} static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment) @@ -1929,76 +2087,100 @@ ssh_key_to_buffer (gcry_sexp_t key, const char *passphrase, return err; } + + +/* Store the ssh KEY into our local key storage and protect him after + asking for a passphrase. Cache that passphrase. TTL is the + maximum caching time for that key. If the key already exists in + our key storage, don't do anything. When entering a new key also + add an entry to the sshcontrol file. */ static gpg_error_t ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) { + gpg_error_t err; unsigned char key_grip_raw[21]; - unsigned char *buffer; - unsigned int buffer_n; - char passphrase[100]; - char *description; char key_grip[41]; - char *comment; - gpg_error_t err; + unsigned char *buffer = NULL; + unsigned int buffer_n; + char *description = NULL; + char *comment = NULL; unsigned int i; - int ret; - - description = NULL; - comment = NULL; - buffer = NULL; + struct pin_entry_info_s *pi = NULL; err = ssh_key_grip (key, key_grip_raw); if (err) goto out; - key_grip_raw[sizeof (key_grip_raw) - 1] = 0; - ret = agent_key_available (key_grip_raw); - if (! ret) - goto out; + key_grip_raw[sizeof (key_grip_raw) - 1] = 0; /* FIXME: Why?? */ + /* Check whether the key is alread in our key storage. Don't do + anything then. */ + if ( !agent_key_available (key_grip_raw) ) + goto out; /* Yes, key is available. */ + + err = ssh_key_extract_comment (key, &comment); if (err) goto out; - ret = asprintf (&description, - "Please provide the passphrase, which should be used " - "for protecting the received secret key `%s':", - comment ? comment : ""); - if (ret < 0) + if ( asprintf (&description, + _("Please enter a passphrase to protect%%0A" + "the received secret key%%0A" + " %s%%0A" + "within gpg-agent's key storage"), + comment ? comment : "?") < 0) { - err = gpg_err_code_from_errno (errno); + err = gpg_error_from_errno (errno); goto out; } - err = get_passphrase (ctrl, description, sizeof (passphrase), passphrase); + + pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1); + if (!pi) + { + err = gpg_error_from_errno (errno); + goto out; + } + pi->max_length = 100; + pi->max_tries = 1; + err = agent_askpin (ctrl, description, NULL, pi); if (err) goto out; - err = ssh_key_to_buffer (key, passphrase, &buffer, &buffer_n); + err = ssh_key_to_buffer (key, pi->pin, &buffer, &buffer_n); if (err) goto out; + /* Store this key to our key storage. */ err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0); if (err) goto out; + /* Cache this passphrase. */ for (i = 0; i < 20; i++) sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]); - err = agent_put_cache (key_grip, passphrase, ttl); + err = agent_put_cache (key_grip, pi->pin, ttl); if (err) goto out; - out: + /* And add an entry to the sshcontrol file. */ + err = add_control_entry (ctrl, key_grip, ttl); + + out: + if (pi && pi->max_length) + wipememory (pi->pin, pi->max_length); + xfree (pi); xfree (buffer); xfree (comment); - free (description); - /* FIXME: verify xfree vs free. */ + free (description); /* (asprintf allocated, thus regular free.) */ return err; } + + static gpg_error_t ssh_identity_drop (gcry_sexp_t key) { @@ -2234,12 +2416,9 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) if (err) goto out; - if (opt.verbose) /* FIXME: using log_debug is not good with - verbose. log_debug should only be used in - debugging mode or in sitattions which are - unexpected. */ - log_debug ("received request of length: %u\n", - request_data_size); + if (opt.verbose > 1) + log_info ("received ssh request of length %u\n", + (unsigned int)request_data_size); request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+"); if (! request) @@ -2277,17 +2456,28 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) break; if (i == DIM (request_specs)) { - log_debug ("request %u is not supported\n", - request_type); + log_info ("ssh request %u is not supported\n", request_type); send_err = 1; goto out; } if (opt.verbose) - log_debug ("executing request handler: %s (%u)\n", + log_info ("ssh request handler for %s (%u) started\n", request_specs[i].identifier, request_specs[i].type); err = (*request_specs[i].handler) (ctrl, request, response); + + if (opt.verbose) + { + if (err) + log_info ("ssh request handler for %s (%u) failed: %s\n", + request_specs[i].identifier, request_specs[i].type, + gpg_strerror (err)); + else + log_info ("ssh request handler for %s (%u) ready\n", + request_specs[i].identifier, request_specs[i].type); + } + if (err) { send_err = 1; @@ -2295,6 +2485,10 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) } response_size = es_ftell (response); + if (opt.verbose > 1) + log_info ("sending ssh response of length %u\n", + (unsigned int)response_size); + err = es_fseek (response, 0, SEEK_SET); if (err) { @@ -2325,6 +2519,8 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) if (send_err) { + if (opt.verbose > 1) + log_info ("sending ssh error response\n"); err = stream_write_uint32 (stream_sock, 1); if (err) goto leave; @@ -2341,7 +2537,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) es_fclose (response); xfree (request_data); /* FIXME? */ - return !! err; + return !!err; } void @@ -2359,6 +2555,21 @@ start_command_handler_ssh (int sock_client) agent_init_default_ctrl (&ctrl); ctrl.connection_fd = sock_client; + /* Because the ssh protocol does not send us information about the + the current TTY setting, we resort here to use those from startup + or those explictly set. */ + if (!ctrl.display && opt.startup_display) + ctrl.display = strdup (opt.startup_display); + if (!ctrl.ttyname && opt.startup_ttyname) + ctrl.ttyname = strdup (opt.startup_ttyname); + if (!ctrl.ttytype && opt.startup_ttytype) + ctrl.ttytype = strdup (opt.startup_ttytype); + if (!ctrl.lc_ctype && opt.startup_lc_ctype) + ctrl.lc_ctype = strdup (opt.startup_lc_ctype); + if (!ctrl.lc_messages && opt.startup_lc_messages) + ctrl.lc_messages = strdup (opt.startup_lc_messages); + + /* Create stream from socket. */ stream_sock = es_fdopen (sock_client, "r+"); if (!stream_sock) diff --git a/agent/command.c b/agent/command.c index dc8a4a158..997140207 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1,5 +1,5 @@ /* command.c - gpg-agent command handler - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -22,12 +22,14 @@ some buffering in secure mempory to protect session keys etc. */ #include + #include #include #include #include #include #include +#include #include @@ -504,6 +506,55 @@ cmd_genkey (ASSUAN_CONTEXT ctx, char *line) } + + +/* READKEY + + Return the public key for the given keygrip. */ +static int +cmd_readkey (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + unsigned char grip[20]; + gcry_sexp_t s_pkey = NULL; + + rc = parse_keygrip (ctx, line, grip); + if (rc) + return rc; /* Return immediately as this is already an Assuan error code.*/ + + rc = agent_public_key_from_file (ctrl, grip, &s_pkey); + if (!rc) + { + size_t len; + unsigned char *buf; + + len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); + assert (len); + buf = xtrymalloc (len); + if (!buf) + rc = gpg_error_from_errno (errno); + else + { + len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len); + assert (len); + rc = assuan_send_data (ctx, buf, len); + rc = map_assuan_err (rc); + xfree (buf); + } + gcry_sexp_release (s_pkey); + } + + if (rc) + log_error ("command readkey failed: %s\n", gpg_strerror (rc)); + return map_to_assuan_status (rc); +} + + + + + + /* GET_PASSPHRASE [ ] This function is usually used to ask for a passphrase to be used @@ -894,6 +945,7 @@ register_commands (ASSUAN_CONTEXT ctx) { "PKSIGN", cmd_pksign }, { "PKDECRYPT", cmd_pkdecrypt }, { "GENKEY", cmd_genkey }, + { "READKEY", cmd_readkey }, { "GET_PASSPHRASE", cmd_get_passphrase }, { "PRESET_PASSPHRASE", cmd_preset_passphrase }, { "CLEAR_PASSPHRASE", cmd_clear_passphrase }, diff --git a/agent/findkey.c b/agent/findkey.c index 1ac57ad07..86a28d511 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -39,7 +39,9 @@ struct try_unprotect_arg_s { }; - +/* Write an S-expression formatted key to our key storage. With FORCE + pased as true an existsing key with the given GRIP will get + overwritten. */ int agent_write_private_key (const unsigned char *grip, const void *buffer, size_t length, int force) @@ -48,51 +50,44 @@ agent_write_private_key (const unsigned char *grip, char *fname; FILE *fp; char hexgrip[40+4+1]; + int fd; for (i=0; i < 20; i++) sprintf (hexgrip+2*i, "%02X", grip[i]); strcpy (hexgrip+40, ".key"); fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); - if (force) - fp = fopen (fname, "wb"); - else - { - int fd; - - if (!access (fname, F_OK)) - { - log_error ("secret key file `%s' already exists\n", fname); - xfree (fname); - return gpg_error (GPG_ERR_GENERAL); - } - /* We would like to create FNAME but only if it does not already - exist. We cannot make this guarantee just using POSIX (GNU - provides the "x" opentype for fopen, however, this is not - portable). Thus, we use the more flexible open function and - then use fdopen to obtain a stream. + if (!force && !access (fname, F_OK)) + { + log_error ("secret key file `%s' already exists\n", fname); + xfree (fname); + return gpg_error (GPG_ERR_GENERAL); + } - The mode parameter to open is what fopen uses. It will be - combined with the process' umask automatically. */ - fd = open (fname, O_CREAT | O_EXCL | O_RDWR, - S_IRUSR | S_IWUSR + /* In FORCE mode we would like to create FNAME but only if it does + not already exist. We cannot make this guarantee just using + POSIX (GNU provides the "x" opentype for fopen, however, this is + not portable). Thus, we use the more flexible open function and + then use fdopen to obtain a stream. */ + fd = open (fname, force? (O_CREAT | O_TRUNC | O_WRONLY) + : (O_CREAT | O_EXCL | O_WRONLY), + S_IRUSR | S_IWUSR #ifndef HAVE_W32_SYSTEM - | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH + | S_IRGRP #endif ); - if (fd < 0) - fp = 0; - else - { - fp = fdopen (fd, "wb"); - if (!fp) - { - int save_e = errno; - close (fd); - errno = save_e; - } - } + if (fd < 0) + fp = NULL; + else + { + fp = fdopen (fd, "wb"); + if (!fp) + { + int save_e = errno; + close (fd); + errno = save_e; + } } if (!fp) @@ -263,6 +258,8 @@ unprotect (CTRL ctrl, const char *desc_text, } pi = gcry_calloc_secure (1, sizeof (*pi) + 100); + if (!pi) + return gpg_error_from_errno (errno); pi->max_length = 100; pi->min_digits = 0; /* we want a real passphrase */ pi->max_digits = 8; @@ -285,32 +282,22 @@ unprotect (CTRL ctrl, const char *desc_text, } - -/* Return the secret key as an S-Exp in RESULT after locating it using - the grip. Returns NULL in RESULT if the operation should be - diverted to a token; SHADOW_INFO will point then to an allocated - S-Expression with the shadow_info part from the file. With - IGNORE_CACHE passed as true the passphrase is not taken from the - cache. DESC_TEXT may be set to present a custom description for the - pinentry. */ -gpg_error_t -agent_key_from_file (CTRL ctrl, const char *desc_text, - const unsigned char *grip, unsigned char **shadow_info, - int ignore_cache, gcry_sexp_t *result) +/* Read the key identified by GRIP from the private key directory and + return it as an gcrypt S-expression object in RESULT. On failure + returns an error code and stores NULL at RESULT. */ +static gpg_error_t +read_key_file (const unsigned char *grip, gcry_sexp_t *result) { int i, rc; char *fname; FILE *fp; struct stat st; unsigned char *buf; - size_t len, buflen, erroff; + size_t buflen, erroff; gcry_sexp_t s_skey; char hexgrip[40+4+1]; - int got_shadow_info = 0; *result = NULL; - if (shadow_info) - *shadow_info = NULL; for (i=0; i < 20; i++) sprintf (hexgrip+2*i, "%02X", grip[i]); @@ -336,8 +323,8 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, } buflen = st.st_size; - buf = xmalloc (buflen+1); - if (fread (buf, buflen, 1, fp) != 1) + buf = xtrymalloc (buflen+1); + if (!buf || fread (buf, buflen, 1, fp) != 1) { rc = gpg_error_from_errno (errno); log_error ("error reading `%s': %s\n", fname, strerror (errno)); @@ -347,6 +334,7 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, return rc; } + /* Convert the file into a gcrypt S-expression object. */ rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen); xfree (fname); fclose (fp); @@ -357,18 +345,52 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, (unsigned int)erroff, gpg_strerror (rc)); return rc; } + *result = s_skey; + return 0; +} + + +/* Return the secret key as an S-Exp in RESULT after locating it using + the grip. Returns NULL in RESULT if the operation should be + diverted to a token; SHADOW_INFO will point then to an allocated + S-Expression with the shadow_info part from the file. With + IGNORE_CACHE passed as true the passphrase is not taken from the + cache. DESC_TEXT may be set to present a custom description for the + pinentry. */ +gpg_error_t +agent_key_from_file (ctrl_t ctrl, const char *desc_text, + const unsigned char *grip, unsigned char **shadow_info, + int ignore_cache, gcry_sexp_t *result) +{ + int rc; + unsigned char *buf; + size_t len, buflen, erroff; + gcry_sexp_t s_skey; + int got_shadow_info = 0; + + *result = NULL; + if (shadow_info) + *shadow_info = NULL; + + rc = read_key_file (grip, &s_skey); + if (rc) + return rc; + + /* For use with the protection functions we also need the key as an + canonical encoded S-expression in abuffer. Create this buffer + now. */ len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0); assert (len); buf = xtrymalloc (len); if (!buf) { - rc = out_of_core (); + rc = gpg_error_from_errno (errno); gcry_sexp_release (s_skey); return rc; } len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, buf, len); assert (len); - gcry_sexp_release (s_skey); + switch (agent_private_key_type (buf)) { @@ -381,7 +403,7 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, char *desc_text_final; const char *comment = NULL; - /* Note, that we will take the comment as a C styring for + /* Note, that we will take the comment as a C string for display purposes; i.e. all stuff beyond a Nul character is ignored. */ comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0); @@ -460,6 +482,8 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, rc = gpg_error (GPG_ERR_BAD_SECKEY); break; } + gcry_sexp_release (s_skey); + s_skey = NULL; if (rc || got_shadow_info) { xfree (buf); @@ -481,6 +505,200 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, return 0; } + + +/* Return the public key for the keygrip GRIP. The result is stored + at RESULT. This function extracts the public key from the private + key database. On failure an error code is returned and NULL stored + at RESULT. */ +gpg_error_t +agent_public_key_from_file (ctrl_t ctrl, + const unsigned char *grip, + gcry_sexp_t *result) +{ + int i, idx, rc; + gcry_sexp_t s_skey; + const char *algoname; + gcry_sexp_t uri_sexp, comment_sexp; + const char *uri, *comment; + size_t uri_length, comment_length; + char *format, *p; + void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2 + for comment + end-of-list. */ + int argidx; + gcry_sexp_t list, l2; + const char *name; + const char *s; + size_t n; + const char *elems; + gcry_mpi_t *array; + + *result = NULL; + + rc = read_key_file (grip, &s_skey); + if (rc) + return rc; + + list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 ); + if (!list) + list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 ); + if (!list) + list = gcry_sexp_find_token (s_skey, "private-key", 0 ); + if (!list) + { + log_error ("invalid private key format\n"); + gcry_sexp_release (s_skey); + return gpg_error (GPG_ERR_BAD_SECKEY); + } + + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + name = gcry_sexp_nth_data (list, 0, &n); + if (n==3 && !memcmp (name, "rsa", 3)) + { + algoname = "rsa"; + elems = "ne"; + } + else if (n==3 && !memcmp (name, "dsa", 3)) + { + algoname = "dsa"; + elems = "pqgy"; + } + else if (n==3 && !memcmp (name, "elg", 3)) + { + algoname = "elg"; + elems = "pgy"; + } + else + { + log_error ("unknown private key algorithm\n"); + gcry_sexp_release (list); + gcry_sexp_release (s_skey); + return gpg_error (GPG_ERR_BAD_SECKEY); + } + + /* Allocate an array for the parameters and copy them out of the + secret key. FIXME: We should have a generic copy function. */ + array = xtrycalloc (strlen(elems) + 1, sizeof *array); + if (!array) + { + rc = gpg_error_from_errno (errno); + gcry_sexp_release (list); + gcry_sexp_release (s_skey); + return rc; + } + + for (idx=0, s=elems; *s; s++, idx++ ) + { + l2 = gcry_sexp_find_token (list, s, 1); + if (!l2) + { + /* Required parameter not found. */ + for (i=0; i Date: Thu, 24 Feb 2005 21:40:48 +0000 Subject: * call-scd.c (unescape_status_string): New. Actual a copy of ../g10/call-agent.c (card_getattr_cb, agent_card_getattr): New. * command-ssh.c (card_key_available): New. (ssh_handler_request_identities): First see whether a card key is available. * app.c (app_getattr): Return APPTYPE or SERIALNO type even if the application does dot support the getattr call. * app.c (select_application): Return an error code and the application context in an new arg. * command.c (open_card): Adjusted for that. Don't use the fallback if no card is present. Return an error if the card has been removed without a reset. (do_reset, cmd_serialno): Clear that error flag. (TEST_CARD_REMOVAL): New. Use it with all command handlers. (scd_update_reader_status_file): Set the error flag on all changes. --- agent/ChangeLog | 8 ++ agent/agent.h | 1 + agent/call-scd.c | 133 ++++++++++++++++++++++++++++++--- agent/command-ssh.c | 208 +++++++++++++++++++++++++++++++++++----------------- scd/ChangeLog | 4 + scd/app.c | 29 ++++++++ scd/command.c | 24 ++++-- 7 files changed, 323 insertions(+), 84 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 775a44489..118559c64 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,5 +1,13 @@ 2005-02-24 Werner Koch + * call-scd.c (unescape_status_string): New. Actual a copy of + ../g10/call-agent.c + (card_getattr_cb, agent_card_getattr): New. + + * command-ssh.c (card_key_available): New. + (ssh_handler_request_identities): First see whether a card key is + available. + * gpg-agent.c (handle_connections): Need to check for events if select returns with -1. diff --git a/agent/agent.h b/agent/agent.h index 0661cc4ad..39e479e48 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -259,6 +259,7 @@ int agent_card_pkdecrypt (ctrl_t ctrl, int agent_card_readcert (ctrl_t ctrl, const char *id, char **r_buf, size_t *r_buflen); int agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf); +gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result); int agent_card_scd (ctrl_t ctrl, const char *cmdline, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, void *assuan_context); diff --git a/agent/call-scd.c b/agent/call-scd.c index bffdbcbad..f7d32f7cf 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -1,5 +1,5 @@ /* call-scd.c - fork of the scdaemon to do SC operations - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -66,7 +66,7 @@ static pth_mutex_t scd_lock; static int active_connection_fd = -1; static int active_connection = 0; -/* callback parameter for learn card */ +/* Callback parameter for learn card */ struct learn_parm_s { void (*kpinfo_cb)(void*, const char *); void *kpinfo_cb_arg; @@ -266,6 +266,41 @@ agent_reset_scd (ctrl_t ctrl) } + +/* Return a new malloced string by unescaping the string S. Escaping + is percent escaping and '+'/space mapping. A binary Nul will + silently be replaced by a 0xFF. Function returns NULL to indicate + an out of memory status. */ +static char * +unescape_status_string (const unsigned char *s) +{ + char *buffer, *d; + + buffer = d = xtrymalloc (strlen (s)+1); + if (!buffer) + return NULL; + while (*s) + { + if (*s == '%' && s[1] && s[2]) + { + s++; + *d = xtoi_2 (s); + if (!*d) + *d = '\xff'; + d++; + s += 2; + } + else if (*s == '+') + { + *d++ = ' '; + s++; + } + else + *d++ = *s++; + } + *d = 0; + return buffer; +} @@ -375,14 +410,6 @@ agent_card_serialno (ctrl_t ctrl, char **r_serialno) if (rc) return rc; - /* Hmm, do we really need this reset - scddaemon should do this or - we can do this if we for some reason figure out that the - operation might have failed due to a missing RESET. Hmmm, I feel - this is really SCdaemon's duty */ -/* rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); */ -/* if (rc) */ -/* return unlock_scd (map_assuan_err (rc)); */ - rc = assuan_transact (scd_ctx, "SERIALNO", NULL, NULL, NULL, NULL, get_serialno_cb, &serialno); @@ -395,6 +422,8 @@ agent_card_serialno (ctrl_t ctrl, char **r_serialno) return unlock_scd (0); } + + static AssuanError membuf_data_cb (void *opaque, const void *buffer, size_t length) @@ -644,6 +673,90 @@ agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf) } + +/* Type used with the card_getattr_cb. */ +struct card_getattr_parm_s { + const char *keyword; /* Keyword to look for. */ + size_t keywordlen; /* strlen of KEYWORD. */ + char *data; /* Malloced and unescaped data. */ + int error; /* ERRNO value or 0 on success. */ +}; + +/* Callback function for agent_card_getattr. */ +static assuan_error_t +card_getattr_cb (void *opaque, const char *line) +{ + struct card_getattr_parm_s *parm = opaque; + const char *keyword = line; + int keywordlen; + + if (parm->data) + return 0; /* We want only the first occurrence. */ + + for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) + ; + while (spacep (line)) + line++; + + if (keywordlen == parm->keywordlen + && !memcmp (keyword, parm->keyword, keywordlen)) + { + parm->data = unescape_status_string (line); + if (!parm->data) + parm->error = errno; + } + + return 0; +} + + +/* Call the agent to retrieve a single line data object. On success + the object is malloced and stored at RESULT; it is guaranteed that + NULL is never stored in this case. On error an error code is + returned and NULL stored at RESULT. */ +gpg_error_t +agent_card_getattr (ctrl_t ctrl, const char *name, char **result) +{ + int err; + struct card_getattr_parm_s parm; + char line[ASSUAN_LINELENGTH]; + + *result = NULL; + + if (!*name) + return gpg_error (GPG_ERR_INV_VALUE); + + memset (&parm, 0, sizeof parm); + parm.keyword = name; + parm.keywordlen = strlen (name); + + /* We assume that NAME does not need escaping. */ + if (8 + strlen (name) > DIM(line)-1) + return gpg_error (GPG_ERR_TOO_LARGE); + stpcpy (stpcpy (line, "GETATTR "), name); + + err = start_scd (ctrl); + if (err) + return err; + + err = map_assuan_err (assuan_transact (scd_ctx, line, + NULL, NULL, NULL, NULL, + card_getattr_cb, &parm)); + if (!err && parm.error) + err = gpg_error_from_errno (parm.error); + + if (!err && !parm.data) + err = gpg_error (GPG_ERR_NO_DATA); + + if (!err) + *result = parm.data; + else + xfree (parm.data); + + return unlock_scd (err); +} + + static AssuanError diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 8ea042e19..2c0d25ef6 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1201,7 +1201,7 @@ sexp_key_extract (gcry_sexp_t sexp, return err; } -/* Extract the car from SEXP, and create a newly created C-string it, +/* Extract the car from SEXP, and create a newly created C-string which is to be stored in IDENTIFIER. */ static gpg_error_t sexp_extract_identifier (gcry_sexp_t sexp, const char **identifier) @@ -1404,6 +1404,7 @@ ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, } +/* Write the public key KEY_PUBLIC to STREAM in SSH key format. */ static gpg_error_t ssh_send_key_public (estream_t stream, gcry_sexp_t key_public) { @@ -1516,7 +1517,78 @@ key_secret_to_public (gcry_sexp_t *key_public, return err; } - + +/* Chec whether a smartcard is available and whether it has a usable + key. Store a copy of that key at R_PK and return 0. If no key is + available store NULL at R_PK and return an error code. */ +static gpg_error_t +card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk) +{ + gpg_error_t err; + char *appname; + unsigned char *sbuf; + size_t sbuflen; + gcry_sexp_t pk; + + *r_pk = NULL; + + /* First see whether a card is available and whether the application + is supported. */ + err = agent_card_getattr (ctrl, "APPTYPE", &appname); + if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED ) + { + /* Ask for the serial number to reset the card. */ + err = agent_card_serialno (ctrl, &appname); + if (err) + { + if (opt.verbose) + log_info (_("can't get serial number of card: %s\n"), + gpg_strerror (err)); + return err; + } + log_info (_("detected card with S/N: %s\n"), appname); + xfree (appname); + err = agent_card_getattr (ctrl, "APPTYPE", &appname); + } + if (err) + { + log_error (_("error getting application type of card: %s\n"), + gpg_strerror (err)); + return err; + } + if (strcmp (appname, "OPENPGP")) + { + log_info (_("card application `%s' is not supported\n"), appname); + xfree (appname); + return gpg_error (GPG_ERR_NOT_SUPPORTED); + } + xfree (appname); + appname = NULL; + + /* Read the public key. */ + err = agent_card_readkey (ctrl, "OPENPGP.3", &sbuf); + if (err) + { + if (opt.verbose) + log_info (_("no suitable card key found: %s\n"), gpg_strerror (err)); + return err; + } + + sbuflen = gcry_sexp_canon_len (sbuf, 0, NULL, NULL); + err = gcry_sexp_sscan (&pk, NULL, sbuf, sbuflen); + xfree (sbuf); + if (err) + { + log_error ("failed to build S-Exp from received card key: %s\n", + gpg_strerror (err)); + return err; + } + + *r_pk = pk; + return 0; +} + + /* Request handler. @@ -1589,91 +1661,95 @@ ssh_handler_request_identities (ctrl_t ctrl, goto out; } - /* Iterate over key files. */ - /* FIXME: make sure that buffer gets deallocated properly. */ + + /* First check whether a key is currently available in the card + reader - this should be allowed even without being listed in + sshcontrol.txt. */ + + if (!card_key_available (ctrl, &key_public)) + { + err = ssh_send_key_public (key_blobs, key_public); + gcry_sexp_release (key_public); + key_public = NULL; + if (err) + goto out; + + key_counter++; + } + + + /* Then look at all the registered an allowed keys. */ + /* Fixme: We should better iterate over the control file and check whether the key file is there. This is better in resepct to performance if tehre are a lot of key sin our key storage. */ - + /* FIXME: make sure that buffer gets deallocated properly. */ err = open_control_file (&ctrl_fp, 0); if (err) goto out; -#warning Really need to fix this fixme. - /* - FIXME: First check whether a key is currently available in the card reader - this should be allowed even without being listed in sshcontrol.txt. - */ - - while (1) + while ( (dir_entry = readdir (dir)) ) { - dir_entry = readdir (dir); - if (dir_entry) - { - if ((strlen (dir_entry->d_name) == 44) - && (! strncmp (dir_entry->d_name + 40, ".key", 4))) - { - char hexgrip[41]; - int disabled; - - /* We do only want to return keys listed in our control - file. */ - strncpy (hexgrip, dir_entry->d_name, 40); - hexgrip[40] = 0; - if ( strlen (hexgrip) != 40 ) - continue; - if (search_control_file (ctrl_fp, hexgrip, &disabled) - || disabled) - continue; - - strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40); - - /* Read file content. */ - err = file_to_buffer (key_path, &buffer, &buffer_n); - if (err) - break; + if ((strlen (dir_entry->d_name) == 44) + && (! strncmp (dir_entry->d_name + 40, ".key", 4))) + { + char hexgrip[41]; + int disabled; + + /* We do only want to return keys listed in our control + file. */ + strncpy (hexgrip, dir_entry->d_name, 40); + hexgrip[40] = 0; + if ( strlen (hexgrip) != 40 ) + continue; + if (search_control_file (ctrl_fp, hexgrip, &disabled) + || disabled) + continue; + + strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40); + + /* Read file content. */ + err = file_to_buffer (key_path, &buffer, &buffer_n); + if (err) + goto out; - err = gcry_sexp_sscan (&key_secret, NULL, buffer, buffer_n); - if (err) - break; + err = gcry_sexp_sscan (&key_secret, NULL, buffer, buffer_n); + if (err) + goto out; - xfree (buffer); - buffer = NULL; + xfree (buffer); + buffer = NULL; - err = sexp_extract_identifier (key_secret, &key_type); - if (err) - break; + err = sexp_extract_identifier (key_secret, &key_type); + if (err) + goto out; - err = ssh_key_type_lookup (NULL, key_type, &spec); - if (err) - break; + err = ssh_key_type_lookup (NULL, key_type, &spec); + if (err) + goto out; - xfree ((void *) key_type); - key_type = NULL; + xfree ((void *) key_type); + key_type = NULL; - err = key_secret_to_public (&key_public, spec, key_secret); - if (err) - break; + err = key_secret_to_public (&key_public, spec, key_secret); + if (err) + goto out; - gcry_sexp_release (key_secret); - key_secret = NULL; + gcry_sexp_release (key_secret); + key_secret = NULL; - err = ssh_send_key_public (key_blobs, key_public); - if (err) - break; + err = ssh_send_key_public (key_blobs, key_public); + if (err) + goto out; - gcry_sexp_release (key_public); - key_public = NULL; + gcry_sexp_release (key_public); + key_public = NULL; - key_counter++; - } - } - else - break; + key_counter++; + } } - if (err) - goto out; ret = es_fseek (key_blobs, 0, SEEK_SET); if (ret) diff --git a/scd/ChangeLog b/scd/ChangeLog index c78bd011f..dc394b677 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,5 +1,8 @@ 2005-02-24 Werner Koch + * app.c (app_getattr): Return APPTYPE or SERIALNO type even if the + application does dot support the getattr call. + * app-openpgp.c (get_one_do): Never try to get a non cacheable object from the cache. (get_one_do): Add new arg to return an error code. Changed all @@ -13,6 +16,7 @@ been removed without a reset. (do_reset, cmd_serialno): Clear that error flag. (TEST_CARD_REMOVAL): New. Use it with all command handlers. + (scd_update_reader_status_file): Set the error flag on all changes. * scdaemon.c (ticker_thread): Termintate if a shutdown is pending. diff --git a/scd/app.c b/scd/app.c index 857f9e10b..384ee2143 100644 --- a/scd/app.c +++ b/scd/app.c @@ -305,6 +305,35 @@ app_getattr (APP app, CTRL ctrl, const char *name) return gpg_error (GPG_ERR_INV_VALUE); if (!app->initialized) return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); + + if (app->apptype && name && !strcmp (name, "APPTYPE")) + { + send_status_info (ctrl, "APPTYPE", + app->apptype, strlen (app->apptype), NULL, 0); + return 0; + } + if (name && !strcmp (name, "SERIALNO")) + { + char *serial_and_stamp; + char *serial; + time_t stamp; + int rc; + + rc = app_get_serial_and_stamp (app, &serial, &stamp); + if (rc) + return rc; + rc = asprintf (&serial_and_stamp, "%s %lu", + serial, (unsigned long)stamp); + rc = (rc < 0)? gpg_error_from_errno (errno) : 0; + xfree (serial); + if (rc) + return rc; + send_status_info (ctrl, "SERIALNO", + serial_and_stamp, strlen (serial_and_stamp), NULL, 0); + free (serial_and_stamp); + return 0; + } + if (!app->fnc.getattr) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return app->fnc.getattr (app, ctrl, name); diff --git a/scd/command.c b/scd/command.c index a4fb968cf..63e3e28e1 100644 --- a/scd/command.c +++ b/scd/command.c @@ -239,7 +239,7 @@ percent_plus_unescape (unsigned char *string) operations are done on the same card unless he calls this function. */ static int -cmd_serialno (ASSUAN_CONTEXT ctx, char *line) +cmd_serialno (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc = 0; @@ -248,7 +248,8 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line) time_t stamp; /* Clear the remove flag so that the open_card is able to reread it. */ - ctrl->server_local->card_removed = 0; + if (ctrl->server_local->card_removed) + do_reset (ctrl, 0); if ((rc = open_card (ctrl, *line? line:NULL))) return rc; @@ -1092,7 +1093,6 @@ cmd_checkpin (ASSUAN_CONTEXT ctx, char *line) - /* Tell the assuan library about our commands */ static int @@ -1299,10 +1299,6 @@ scd_update_reader_status_file (void) char templ[50]; FILE *fp; - last[slot].any = 1; - last[slot].status = status; - last[slot].changed = changed; - log_info ("updating status of slot %d to 0x%04X\n", slot, status); sprintf (templ, "reader_%d.status", slot); @@ -1318,7 +1314,19 @@ scd_update_reader_status_file (void) } xfree (fname); - /* Send a signal to the primary client, if any. */ + /* Set the card removed flag. We will set this on any + card change because a reset or SERIALNO request must be + done in any case. */ + if (primary_connection && primary_connection->server_local + && last[slot].any ) + primary_connection->server_local->card_removed = 1; + + last[slot].any = 1; + last[slot].status = status; + last[slot].changed = changed; + + + /* Send a signal to the primary client, if any. */ if (primary_connection && primary_connection->server_local && primary_connection->server_local->assuan_ctx) { -- cgit From faef9f929b845dc712c8d705620661b5bc6f6767 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 25 Feb 2005 16:14:55 +0000 Subject: * findkey.c (modify_description): Keep invalid % escapes, so that %0A may pass through. * agent.h (server_control_s): New field USE_AUTH_CALL. * call-scd.c (agent_card_pksign): Make use of it. * command-ssh.c (data_sign): Set the flag. (ssh_send_key_public): New arg OVERRIDE_COMMENT. (card_key_available): Add new arg CARDSN. (ssh_handler_request_identities): Use the card s/n as comment. (sexp_key_extract): Use GCRYMPI_FMT_STD. (data_sign): Ditto. * learncard.c (make_shadow_info): Moved to .. * protect.c (make_shadow_info): .. here. Return NULL on malloc failure. Made global. * agent.h: Add prototype. * xasprintf.c (xtryasprintf): New. * app-openpgp.c (get_public_key): Make sure not to return negative numbers. (do_sign): Allow passing of indata with algorithm prefix. (do_auth): Allow OPENPGP.3 as an alternative ID. * app.c (app_getattr): Return just the S/N but not the timestamp. * no-libgcrypt.c (gcry_strdup): New. --- agent/ChangeLog | 19 ++++++ agent/agent.h | 3 + agent/call-scd.c | 22 ++++--- agent/command-ssh.c | 156 +++++++++++++++++++++++++++++++++++++--------- agent/findkey.c | 15 +++-- agent/keyformat.txt | 4 +- agent/learncard.c | 28 +-------- agent/protect-tool.c | 2 +- agent/protect.c | 37 ++++++++++- common/ChangeLog | 4 ++ common/util.h | 4 ++ common/xasprintf.c | 20 +++++- scd/ChangeLog | 9 +++ scd/app-openpgp.c | 86 +++++++++++++++++++------ scd/app.c | 10 +-- tools/ChangeLog | 4 ++ tools/gpg-connect-agent.c | 47 ++++++++++++-- tools/no-libgcrypt.c | 6 ++ 18 files changed, 368 insertions(+), 108 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 118559c64..2138f6674 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,22 @@ +2005-02-25 Werner Koch + + * findkey.c (modify_description): Keep invalid % escapes, so that + %0A may pass through. + + * agent.h (server_control_s): New field USE_AUTH_CALL. + * call-scd.c (agent_card_pksign): Make use of it. + * command-ssh.c (data_sign): Set the flag. + (ssh_send_key_public): New arg OVERRIDE_COMMENT. + (card_key_available): Add new arg CARDSN. + (ssh_handler_request_identities): Use the card s/n as comment. + (sexp_key_extract): Use GCRYMPI_FMT_STD. + (data_sign): Ditto. + + * learncard.c (make_shadow_info): Moved to .. + * protect.c (make_shadow_info): .. here. Return NULL on malloc + failure. Made global. + * agent.h: Add prototype. + 2005-02-24 Werner Koch * call-scd.c (unescape_status_string): New. Actual a copy of diff --git a/agent/agent.h b/agent/agent.h index 39e479e48..e12a02b6e 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -116,6 +116,8 @@ struct server_control_s { char keygrip[20]; int have_keygrip; + int use_auth_call; /* Hack to send the PKAUTH command instead of the + PKSIGN command tro scdaemon. */ }; typedef struct server_control_s *CTRL; typedef struct server_control_s *ctrl_t; @@ -204,6 +206,7 @@ int agent_protect (const unsigned char *plainkey, const char *passphrase, int agent_unprotect (const unsigned char *protectedkey, const char *passphrase, unsigned char **result, size_t *resultlen); int agent_private_key_type (const unsigned char *privatekey); +unsigned char *make_shadow_info (const char *serialno, const char *idstring); int agent_shadow_key (const unsigned char *pubkey, const unsigned char *shadow_info, unsigned char **result); diff --git a/agent/call-scd.c b/agent/call-scd.c index f7d32f7cf..904059291 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -225,15 +225,16 @@ start_scd (ctrl_t ctrl) /* Tell the scdaemon that we want him to send us an event signal. But only do this if we are running as a regular sever and not simply as a pipe server. */ - if (ctrl->connection_fd != -1) - { -#ifndef HAVE_W32_SYSTEM - char buf[100]; + /* Fixme: gpg-agent does not use this signal yet. */ +/* if (ctrl->connection_fd != -1) */ +/* { */ +/* #ifndef HAVE_W32_SYSTEM */ +/* char buf[100]; */ - sprintf (buf, "OPTION event-signal=%d", SIGUSR2); - assuan_transact (scd_ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL); -#endif - } +/* sprintf (buf, "OPTION event-signal=%d", SIGUSR2); */ +/* assuan_transact (scd_ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL); */ +/* #endif */ +/* } */ return 0; } @@ -505,7 +506,8 @@ agent_card_pksign (ctrl_t ctrl, inqparm.ctx = scd_ctx; inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; - snprintf (line, DIM(line)-1, "PKSIGN %s", keyid); + snprintf (line, DIM(line)-1, + ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid); line[DIM(line)-1] = 0; rc = assuan_transact (scd_ctx, line, membuf_data_cb, &data, @@ -518,7 +520,7 @@ agent_card_pksign (ctrl_t ctrl, } sigbuf = get_membuf (&data, &sigbuflen); - /* create an S-expression from it which is formatted like this: + /* Create an S-expression from it which is formatted like this: "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */ *r_buflen = 21 + 11 + sigbuflen + 4; *r_buf = xtrymalloc (*r_buflen); diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 2c0d25ef6..ebb44fa74 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -659,7 +659,9 @@ open_control_file (FILE **r_fp, int append) (i.e. where Pth might switch threads) we need to employ a mutex. */ *r_fp = NULL; - fname = make_filename (opt.homedir, "sshcontrol.txt", NULL); + fname = make_filename (opt.homedir, "sshcontrol", NULL); + /* FIXME: With "a+" we are not able to check whether this will will + be created and thus the blurb needs to be written first. */ fp = fopen (fname, append? "a+":"r"); if (!fp && errno == ENOENT) { @@ -1146,7 +1148,9 @@ sexp_key_extract (gcry_sexp_t sexp, break; } - mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_USG); + /* Note that we need to use STD format; i.e. prepend a 0x00 to + indicate a positive number if the high bit is set. */ + mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD); if (! mpi) { err = gpg_error (GPG_ERR_INV_SEXP); @@ -1404,9 +1408,12 @@ ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, } -/* Write the public key KEY_PUBLIC to STREAM in SSH key format. */ +/* Write the public key KEY_PUBLIC to STREAM in SSH key format. If + OVERRIDE_COMMENT is not NULL, it will be used instead of the + comment stored in the key. */ static gpg_error_t -ssh_send_key_public (estream_t stream, gcry_sexp_t key_public) +ssh_send_key_public (estream_t stream, gcry_sexp_t key_public, + const char *override_comment) { ssh_key_type_spec_t spec; gcry_mpi_t *mpi_list; @@ -1442,7 +1449,8 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public) if (err) goto out; - err = stream_write_cstring (stream, comment); + err = stream_write_cstring (stream, + override_comment? override_comment : comment); out: @@ -1520,17 +1528,23 @@ key_secret_to_public (gcry_sexp_t *key_public, /* Chec whether a smartcard is available and whether it has a usable key. Store a copy of that key at R_PK and return 0. If no key is - available store NULL at R_PK and return an error code. */ + available store NULL at R_PK and return an error code. If CARDSN + is no NULL, a string with the serial number of the card will be + amalloced and stored there. */ static gpg_error_t -card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk) +card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) { gpg_error_t err; char *appname; - unsigned char *sbuf; - size_t sbuflen; - gcry_sexp_t pk; + char *serialno = NULL; + unsigned char *pkbuf; + size_t pkbuflen; + gcry_sexp_t s_pk; + unsigned char grip[20]; *r_pk = NULL; + if (cardsn) + *cardsn = NULL; /* First see whether a card is available and whether the application is supported. */ @@ -1538,53 +1552,135 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk) if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED ) { /* Ask for the serial number to reset the card. */ - err = agent_card_serialno (ctrl, &appname); + err = agent_card_serialno (ctrl, &serialno); if (err) { if (opt.verbose) - log_info (_("can't get serial number of card: %s\n"), + log_info (_("error getting serial number of card: %s\n"), gpg_strerror (err)); return err; } - log_info (_("detected card with S/N: %s\n"), appname); - xfree (appname); + log_info (_("detected card with S/N: %s\n"), serialno); err = agent_card_getattr (ctrl, "APPTYPE", &appname); } if (err) { log_error (_("error getting application type of card: %s\n"), gpg_strerror (err)); + xfree (serialno); return err; } if (strcmp (appname, "OPENPGP")) { log_info (_("card application `%s' is not supported\n"), appname); xfree (appname); + xfree (serialno); return gpg_error (GPG_ERR_NOT_SUPPORTED); } xfree (appname); appname = NULL; + /* Get the S/N if we don't have it yet. Use the fast getattr method. */ + if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) ) + { + log_error (_("error getting serial number of card: %s\n"), + gpg_strerror (err)); + return err; + } + /* Read the public key. */ - err = agent_card_readkey (ctrl, "OPENPGP.3", &sbuf); + err = agent_card_readkey (ctrl, "OPENPGP.3", &pkbuf); if (err) { if (opt.verbose) log_info (_("no suitable card key found: %s\n"), gpg_strerror (err)); + xfree (serialno); return err; } - sbuflen = gcry_sexp_canon_len (sbuf, 0, NULL, NULL); - err = gcry_sexp_sscan (&pk, NULL, sbuf, sbuflen); - xfree (sbuf); + pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL); + err = gcry_sexp_sscan (&s_pk, NULL, pkbuf, pkbuflen); if (err) { log_error ("failed to build S-Exp from received card key: %s\n", gpg_strerror (err)); + xfree (pkbuf); + xfree (serialno); return err; } - *r_pk = pk; + if ( !gcry_pk_get_keygrip (s_pk, grip) ) + { + log_debug ("error computing keygrip from received card key\n"); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + return gpg_error (GPG_ERR_INTERNAL); + } + + if ( agent_key_available (grip) ) + { + /* (Shadow)-key is not available in our key storage. */ + unsigned char *shadow_info; + unsigned char *tmp; + + shadow_info = make_shadow_info (serialno, "OPENPGP.3"); + if (!shadow_info) + { + err = gpg_error_from_errno (errno); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + return err; + } + err = agent_shadow_key (pkbuf, shadow_info, &tmp); + xfree (shadow_info); + if (err) + { + log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err)); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + return err; + } + xfree (pkbuf); + pkbuf = tmp; + pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL); + assert (pkbuflen); + + err = agent_write_private_key (grip, pkbuf, pkbuflen, 0); + if (err) + { + log_error (_("error writing key: %s\n"), gpg_strerror (err)); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + return err; + } + } + + if (cardsn) + { + size_t snlen = strlen (serialno); + + if (snlen == 32 + && !memcmp (serialno, "D27600012401", 12)) /* OpenPGP card. */ + *cardsn = xtryasprintf ("cardno:%.12s", serialno+16); + else /* Something is wrong: Print all. */ + *cardsn = xtryasprintf ("cardno:%s", serialno); + if (!*cardsn) + { + err = gpg_error_from_errno (errno); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + return err; + } + } + + xfree (pkbuf); + xfree (serialno); + *r_pk = s_pk; return 0; } @@ -1615,6 +1711,7 @@ ssh_handler_request_identities (ctrl_t ctrl, gpg_error_t ret_err; int ret; FILE *ctrl_fp = NULL; + char *cardsn; /* Prepare buffer stream. */ @@ -1665,13 +1762,14 @@ ssh_handler_request_identities (ctrl_t ctrl, /* First check whether a key is currently available in the card reader - this should be allowed even without being listed in - sshcontrol.txt. */ + sshcontrol. */ - if (!card_key_available (ctrl, &key_public)) + if (!card_key_available (ctrl, &key_public, &cardsn)) { - err = ssh_send_key_public (key_blobs, key_public); + err = ssh_send_key_public (key_blobs, key_public, cardsn); gcry_sexp_release (key_public); key_public = NULL; + xfree (cardsn); if (err) goto out; @@ -1740,7 +1838,7 @@ ssh_handler_request_identities (ctrl_t ctrl, gcry_sexp_release (key_secret); key_secret = NULL; - err = ssh_send_key_public (key_blobs, key_public); + err = ssh_send_key_public (key_blobs, key_public, NULL); if (err) goto out; @@ -1845,9 +1943,11 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, sig_value = NULL; mpis = NULL; + ctrl->use_auth_call = 1; err = agent_pksign_do (ctrl, - _("Please provide the passphrase " - "for the ssh key `%c':"), &signature_sexp, 0); + _("Please enter the passphrase " + "for the ssh key%0A %c"), &signature_sexp, 0); + ctrl->use_auth_call = 0; if (err) goto out; @@ -2189,7 +2289,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) key_grip_raw[sizeof (key_grip_raw) - 1] = 0; /* FIXME: Why?? */ - /* Check whether the key is alread in our key storage. Don't do + /* Check whether the key is already in our key storage. Don't do anything then. */ if ( !agent_key_available (key_grip_raw) ) goto out; /* Yes, key is available. */ @@ -2200,8 +2300,8 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) goto out; if ( asprintf (&description, - _("Please enter a passphrase to protect%%0A" - "the received secret key%%0A" + _("Please enter a passphrase to protect" + " the received secret key%%0A" " %s%%0A" "within gpg-agent's key storage"), comment ? comment : "?") < 0) diff --git a/agent/findkey.c b/agent/findkey.c index 86a28d511..0b5816bf5 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -166,9 +166,7 @@ modify_description (const char *in, const char *comment, char **result) special = 0; for (i = 0; i < in_len; i++) { - if (in[i] == '%') - special = 1; - else if (special) + if (special) { special = 0; switch (in[i]) @@ -190,10 +188,19 @@ modify_description (const char *in, const char *comment, char **result) out_len += comment_length; break; - default: /* Invalid special sequences are ignored. */ + default: /* Invalid special sequences are kept as they are. */ + if (out) + { + *out++ = '%'; + *out++ = in[i]; + } + else + out_len+=2; break; } } + else if (in[i] == '%') + special = 1; else { if (out) diff --git a/agent/keyformat.txt b/agent/keyformat.txt index 726990315..7bdb94c0e 100644 --- a/agent/keyformat.txt +++ b/agent/keyformat.txt @@ -161,9 +161,9 @@ term secret key because it can be visually be better distinguished from the term public key. [2] The keygrip is a unique identifier for a key pair, it is -independent of any protocol, so that the same key can be ised with +independent of any protocol, so that the same key can be used with different protocols. PKCS-15 calls this a subjectKeyHash; it can be -calculate using Libgcrypt's gcry_pk_get_keygrip(). +calculated using Libgcrypt's gcry_pk_get_keygrip (). [3] Even when canonical representation are required we will show the S-expression here in a more readable representation. diff --git a/agent/learncard.c b/agent/learncard.c index 7dcacee28..72238507f 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -1,5 +1,5 @@ /* learncard.c - Handle the LEARN command - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -239,32 +239,6 @@ sinfo_cb (void *opaque, const char *keyword, size_t keywordlen, } -/* Create an S-expression with the shadow info. */ -static unsigned char * -make_shadow_info (const char *serialno, const char *idstring) -{ - const char *s; - unsigned char *info, *p; - char numbuf[21]; - int n; - - for (s=serialno, n=0; *s && s[1]; s += 2) - n++; - - info = p = xtrymalloc (1 + 21 + n - + 21 + strlen (idstring) + 1 + 1); - *p++ = '('; - sprintf (numbuf, "%d:", n); - p = stpcpy (p, numbuf); - for (s=serialno; *s && s[1]; s += 2) - *p++ = xtoi_2 (s); - sprintf (numbuf, "%d:", strlen (idstring)); - p = stpcpy (p, numbuf); - p = stpcpy (p, idstring); - *p++ = ')'; - *p = 0; - return info; -} static int send_cert_back (ctrl_t ctrl, const char *id, void *assuan_context) diff --git a/agent/protect-tool.c b/agent/protect-tool.c index ee0276a43..c21aa0517 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -110,7 +110,7 @@ static ARGPARSE_OPTS opts[] = { { oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" }, { oProtect, "protect", 256, "protect a private key"}, { oUnprotect, "unprotect", 256, "unprotect a private key"}, - { oShadow, "shadow", 256, "create a shadow entry for a priblic key"}, + { oShadow, "shadow", 256, "create a shadow entry for a public key"}, { oShowShadowInfo, "show-shadow-info", 256, "return the shadow info"}, { oShowKeygrip, "show-keygrip", 256, "show the \"keygrip\""}, diff --git a/agent/protect.c b/agent/protect.c index cafeb4685..ae3061c77 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -831,10 +831,43 @@ hash_passphrase (const char *passphrase, int hashalgo, + +/* Create an canonical encoded S-expression with the shadow info from + a card's SERIALNO and the IDSTRING. */ +unsigned char * +make_shadow_info (const char *serialno, const char *idstring) +{ + const char *s; + unsigned char *info, *p; + char numbuf[21]; + int n; + + for (s=serialno, n=0; *s && s[1]; s += 2) + n++; + + info = p = xtrymalloc (1 + 21 + n + + 21 + strlen (idstring) + 1 + 1); + if (!info) + return NULL; + *p++ = '('; + sprintf (numbuf, "%d:", n); + p = stpcpy (p, numbuf); + for (s=serialno; *s && s[1]; s += 2) + *p++ = xtoi_2 (s); + sprintf (numbuf, "%d:", strlen (idstring)); + p = stpcpy (p, numbuf); + p = stpcpy (p, idstring); + *p++ = ')'; + *p = 0; + return info; +} + + + /* Create a shadow key from a public key. We use the shadow protocol "ti-v1" and insert the S-expressionn SHADOW_INFO. The resulting S-expression is returned in an allocated buffer RESULT will point - to. The input parameters are expected to be valid canonilized + to. The input parameters are expected to be valid canonicalized S-expressions */ int agent_shadow_key (const unsigned char *pubkey, @@ -894,7 +927,7 @@ agent_shadow_key (const unsigned char *pubkey, s++; assert (depth == 1); - /* calculate required length by taking in account: the "shadowed-" + /* Calculate required length by taking in account: the "shadowed-" prefix, the "shadowed", "t1-v1" as well as some parenthesis */ n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1; *result = p = xtrymalloc (n); diff --git a/common/ChangeLog b/common/ChangeLog index e323dc148..db0593176 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,7 @@ +2005-02-25 Werner Koch + + * xasprintf.c (xtryasprintf): New. + 2005-01-26 Moritz Schulte * Makefile.am (libcommon_a_SOURCES): New source files: estream.c, diff --git a/common/util.h b/common/util.h index 4ab55acb4..bbf7241a3 100644 --- a/common/util.h +++ b/common/util.h @@ -131,6 +131,10 @@ const char *default_homedir (void); freed using xfree. This function simply dies on memory failure, thus no extra check is required. */ char *xasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2); +/* Same as asprintf but return an allocated buffer suitable to be + freed using xfree. This function returns NULL on memory failure and + sets errno. */ +char *xtryasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2); const char *print_fname_stdout (const char *s); const char *print_fname_stdin (const char *s); diff --git a/common/xasprintf.c b/common/xasprintf.c index 2c8fafc06..a3b5e27ac 100644 --- a/common/xasprintf.c +++ b/common/xasprintf.c @@ -1,5 +1,5 @@ /* xasprintf.c - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -42,3 +42,21 @@ xasprintf (const char *fmt, ...) free (buf); return p; } + +/* Same as above bit return NULL on memory failure. */ +char * +xtryasprintf (const char *fmt, ...) +{ + int rc; + va_list ap; + char *buf, *p; + + va_start (ap, fmt); + rc = vasprintf (&buf, fmt, ap); + va_end (ap); + if (rc < 0) + return NULL; + p = xtrystrdup (buf); + free (buf); + return p; +} diff --git a/scd/ChangeLog b/scd/ChangeLog index dc394b677..e3b4ae64c 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,12 @@ +2005-02-25 Werner Koch + + * app-openpgp.c (get_public_key): Make sure not to return negative + numbers. + (do_sign): Allow passing of indata with algorithm prefix. + (do_auth): Allow OPENPGP.3 as an alternative ID. + + * app.c (app_getattr): Return just the S/N but not the timestamp. + 2005-02-24 Werner Koch * app.c (app_getattr): Return APPTYPE or SERIALNO type even if the diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 14c802d10..6ebc13704 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -794,6 +794,8 @@ get_public_key (app_t app, int keyno) const unsigned char *keydata, *m, *e; size_t buflen, keydatalen, mlen, elen; gcry_sexp_t sexp; + unsigned char *mbuf = NULL; + unsigned char *ebuf = NULL; if (keyno < 1 || keyno > 3) return gpg_error (GPG_ERR_INV_ID); @@ -835,6 +837,7 @@ get_public_key (app_t app, int keyno) log_error (_("response does not contain the RSA modulus\n")); goto leave; } + e = find_tlv (keydata, keydatalen, 0x0082, &elen); if (!e) @@ -844,10 +847,38 @@ get_public_key (app_t app, int keyno) goto leave; } + /* Prepend numbers with a 0 if needed. */ + if (mlen && (*m & 0x80)) + { + mbuf = xtrymalloc ( mlen + 1); + if (!mbuf) + { + err = gpg_error_from_errno (errno); + goto leave; + } + *mbuf = 0; + memcpy (mbuf+1, m, mlen); + mlen++; + m = mbuf; + } + if (elen && (*e & 0x80)) + { + ebuf = xtrymalloc ( elen + 1); + if (!ebuf) + { + err = gpg_error_from_errno (errno); + goto leave; + } + *ebuf = 0; + memcpy (ebuf+1, e, elen); + elen++; + e = ebuf; + } + + err = gcry_sexp_build (&sexp, NULL, "(public-key (rsa (n %b) (e %b)))", (int)mlen, m,(int)elen, e); - if (err) { log_error ("error formatting the key into an S-expression: %s\n", @@ -874,6 +905,8 @@ get_public_key (app_t app, int keyno) app->app_local->pk[keyno].read_done = 1; xfree (buffer); + xfree (mbuf); + xfree (ebuf); return 0; } #endif /* GNUPG_MAJOR_VERSION > 1 */ @@ -1557,7 +1590,15 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, if (!keyidstr || !*keyidstr) return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen != 20) + if (indatalen == 20) + ; + else if (indatalen == (15 + 20) && hashalgo == GCRY_MD_SHA1 + && !memcmp (indata, sha1_prefix, 15)) + ; + else if (indatalen == (15 + 20) && hashalgo == GCRY_MD_RMD160 + && !memcmp (indata, rmd160_prefix, 15)) + ; + else return gpg_error (GPG_ERR_INV_VALUE); /* Check whether an OpenPGP card of any version has been requested. */ @@ -1668,7 +1709,8 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, /* Compute a digital signature using the INTERNAL AUTHENTICATE command on INDATA which is expected to be the raw message digest. For this application the KEYIDSTR consists of the serialnumber and the - fingerprint delimited by a slash. + fingerprint delimited by a slash. Optionally the id OPENPGP.3 may + be given. Note that this fucntion may return the error code GPG_ERR_WRONG_CARD to indicate that the card currently present does @@ -1693,27 +1735,31 @@ do_auth (app_t app, const char *keyidstr, return gpg_error (GPG_ERR_INV_VALUE); /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) + if (!strcmp (keyidstr, "OPENPGP.3")) ; - if (n != 32) + else if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* no fingerprint given: we allow this for now. */ - else if (*s == '/') - fpr = s + 1; else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); + { + for (s=keyidstr, n=0; hexdigitp (s); s++, n++) + ; + if (n != 32) + return gpg_error (GPG_ERR_INV_ID); + else if (!*s) + ; /* no fingerprint given: we allow this for now. */ + else if (*s == '/') + fpr = s + 1; + else + return gpg_error (GPG_ERR_INV_ID); - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); + for (s=keyidstr, n=0; n < 16; s += 2, n++) + tmp_sn[n] = xtoi_2 (s); + + if (app->serialnolen != 16) + return gpg_error (GPG_ERR_INV_CARD); + if (memcmp (app->serialno, tmp_sn, 16)) + return gpg_error (GPG_ERR_WRONG_CARD); + } /* If a fingerprint has been specified check it against the one on the card. This is allows for a meaningful error message in case diff --git a/scd/app.c b/scd/app.c index 384ee2143..0625dc8ef 100644 --- a/scd/app.c +++ b/scd/app.c @@ -314,7 +314,6 @@ app_getattr (APP app, CTRL ctrl, const char *name) } if (name && !strcmp (name, "SERIALNO")) { - char *serial_and_stamp; char *serial; time_t stamp; int rc; @@ -322,15 +321,8 @@ app_getattr (APP app, CTRL ctrl, const char *name) rc = app_get_serial_and_stamp (app, &serial, &stamp); if (rc) return rc; - rc = asprintf (&serial_and_stamp, "%s %lu", - serial, (unsigned long)stamp); - rc = (rc < 0)? gpg_error_from_errno (errno) : 0; + send_status_info (ctrl, "SERIALNO", serial, strlen (serial), NULL, 0); xfree (serial); - if (rc) - return rc; - send_status_info (ctrl, "SERIALNO", - serial_and_stamp, strlen (serial_and_stamp), NULL, 0); - free (serial_and_stamp); return 0; } diff --git a/tools/ChangeLog b/tools/ChangeLog index 6895198c5..4d520cfca 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2005-02-25 Werner Koch + + * no-libgcrypt.c (gcry_strdup): New. + 2005-02-24 Werner Koch * gpg-connect-agent.c: New. diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index 399a5d369..19ff160f0 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "i18n.h" @@ -40,7 +41,8 @@ enum cmd_and_opt_values oVerbose = 'v', oNoVerbose = 500, - oHomedir + oHomedir, + oHex }; @@ -52,6 +54,7 @@ static ARGPARSE_OPTS opts[] = { oVerbose, "verbose", 0, N_("verbose") }, { oQuiet, "quiet", 0, N_("quiet") }, + { oHex, "hex", 0, N_("print data out hex encoded") }, /* hidden options */ { oNoVerbose, "no-verbose", 0, "@"}, @@ -66,7 +69,7 @@ struct int verbose; /* Verbosity level. */ int quiet; /* Be extra quiet. */ const char *homedir; /* Configuration directory name */ - + int hex; /* Print data lines in hex format. */ } opt; @@ -155,6 +158,7 @@ main (int argc, char **argv) case oVerbose: opt.verbose++; break; case oNoVerbose: opt.verbose = 0; break; case oHomedir: opt.homedir = pargs.r.ret_str; break; + case oHex: opt.hex = 1; break; default: pargs.err = 2; break; } @@ -220,6 +224,7 @@ read_and_print_response (assuan_context_t ctx) char *line; int linelen; assuan_error_t rc; + int i, j; for (;;) { @@ -234,8 +239,42 @@ read_and_print_response (assuan_context_t ctx) if (linelen >= 1 && line[0] == 'D' && line[1] == ' ') { - fwrite (line, linelen, 1, stdout); - putchar ('\n'); + if (opt.hex) + { + for (i=2; i < linelen; ) + { + int save_i = i; + + printf ("D[%04X] ", i-2); + for (j=0; j < 16 ; j++, i++) + { + if (j == 8) + putchar (' '); + if (i < linelen) + printf (" %02X", ((unsigned char*)line)[i]); + else + fputs (" ", stdout); + } + fputs (" ", stdout); + i= save_i; + for (j=0; j < 16; j++, i++) + { + unsigned int c = ((unsigned char*)line)[i]; + if ( i >= linelen ) + putchar (' '); + else if (isascii (c) && isprint (c) && !iscntrl (c)) + putchar (c); + else + putchar ('.'); + } + putchar ('\n'); + } + } + else + { + fwrite (line, linelen, 1, stdout); + putchar ('\n'); + } } else if (linelen >= 1 && line[0] == 'S' diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c index 0fabec90d..82f6a8bb5 100644 --- a/tools/no-libgcrypt.c +++ b/tools/no-libgcrypt.c @@ -53,6 +53,12 @@ gcry_xmalloc (size_t n) return p; } +char * +gcry_strdup (const char *string) +{ + return malloc (strlen (string)+1); +} + void * gcry_realloc (void *a, size_t n) -- cgit From 843e844d98499efa9b29416661ea74d64fe61177 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Wed, 2 Mar 2005 20:36:50 +0000 Subject: 2005-03-02 Moritz Schulte * command-ssh.c (sexp_key_extract): Removed FIXME, since xtrymallos does set errno correctly by now. (sexp_extract_identifier): Remove const attribute from identifier. (ssh_handler_request_identities): Remove const attribute from key_type; removes ugly casts and FIXME. (sexp_key_extract): Remove const attribute from comment. (ssh_send_key_public): Remove const attribute from key_type/comment; removes ugly cast. (data_sign): Remove const attribute from identifier; removes ugly cast. (key_secret_to_public): Remove const attribute from comment; removes ugly cast. (ssh_handler_sign_request): Remove const attribute from p. (sexp_key_extract): Use make_cstring(). (ssh_key_extract_comment): Likewise. (ssh_key_to_buffer): Use secure memory for memory area to hold the key S-Expression. Added more comments. --- agent/ChangeLog | 21 +++++++++++++++ agent/command-ssh.c | 77 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 70 insertions(+), 28 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 2138f6674..c16e0e37a 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,24 @@ +2005-03-02 Moritz Schulte + + * command-ssh.c (sexp_key_extract): Removed FIXME, since + xtrymallos does set errno correctly by now. + (sexp_extract_identifier): Remove const attribute from identifier. + (ssh_handler_request_identities): Remove const attribute from + key_type; removes ugly casts and FIXME. + (sexp_key_extract): Remove const attribute from comment. + (ssh_send_key_public): Remove const attribute from + key_type/comment; removes ugly cast. + (data_sign): Remove const attribute from identifier; removes ugly + cast. + (key_secret_to_public): Remove const attribute from comment; + removes ugly cast. + (ssh_handler_sign_request): Remove const attribute from p. + (sexp_key_extract): Use make_cstring(). + (ssh_key_extract_comment): Likewise. + (ssh_key_to_buffer): Use secure memory for memory area to hold the + key S-Expression. + Added more comments. + 2005-02-25 Werner Koch * findkey.c (modify_description): Keep invalid % escapes, so that diff --git a/agent/command-ssh.c b/agent/command-ssh.c index ebb44fa74..3b2dcd335 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1075,7 +1075,7 @@ sexp_key_construct (gcry_sexp_t *sexp, static gpg_error_t sexp_key_extract (gcry_sexp_t sexp, ssh_key_type_spec_t key_spec, int *secret, - gcry_mpi_t **mpis, const char **comment) + gcry_mpi_t **mpis, char **comment) { gpg_error_t err; gcry_sexp_t value_list; @@ -1127,7 +1127,7 @@ sexp_key_extract (gcry_sexp_t sexp, mpis_new = xtrymalloc (sizeof (*mpis_new) * (elems_n + 1)); if (! mpis_new) { - err = gpg_error_from_errno (errno); /* FIXME, xtrymalloc+errno. */ + err = gpg_error_from_errno (errno); goto out; } memset (mpis_new, 0, sizeof (*mpis_new) * (elems_n + 1)); @@ -1176,14 +1176,12 @@ sexp_key_extract (gcry_sexp_t sexp, data_n = 6; } - comment_new = xtrymalloc (data_n + 1); + comment_new = make_cstring (data, data_n); if (! comment_new) { err = gpg_error_from_errno (errno); goto out; } - strncpy (comment_new, data, data_n); - comment_new[data_n] = 0; if (secret) *secret = is_secret; @@ -1208,7 +1206,7 @@ sexp_key_extract (gcry_sexp_t sexp, /* Extract the car from SEXP, and create a newly created C-string which is to be stored in IDENTIFIER. */ static gpg_error_t -sexp_extract_identifier (gcry_sexp_t sexp, const char **identifier) +sexp_extract_identifier (gcry_sexp_t sexp, char **identifier) { char *identifier_new; gcry_sexp_t sublist; @@ -1251,8 +1249,16 @@ sexp_extract_identifier (gcry_sexp_t sexp, const char **identifier) -/* Key I/O. */ +/* + + Key I/O. +*/ + +/* Search for a key specification entry. If SSH_NAME is not NULL, + search for an entry whose "ssh_name" is equal to SSH_NAME; + otherwise, search for an entry whose "name" is equal to NAME. + Store found entry in SPEC on success, return error otherwise. */ static gpg_error_t ssh_key_type_lookup (const char *ssh_name, const char *name, ssh_key_type_spec_t *spec) @@ -1276,6 +1282,11 @@ ssh_key_type_lookup (const char *ssh_name, const char *name, return err; } +/* Receive a key from STREAM, according to the key specification given + as KEY_SPEC. Depending on SECRET, receive a secret or a public + key. If READ_COMMENT is true, receive a comment string as well. + Constructs a new S-Expression from received data and stores it in + KEY_NEW. Returns zero on success or an error code. */ static gpg_error_t ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, int read_comment, ssh_key_type_spec_t *key_spec) @@ -1342,6 +1353,9 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, return err; } +/* Converts a key of type TYPE, whose key material is given in MPIS, + into a newly created binary blob, which is to be stored in + BLOB/BLOB_SIZE. Returns zero on success or an error code. */ static gpg_error_t ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, const char *type, gcry_mpi_t *mpis) @@ -1417,8 +1431,8 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public, { ssh_key_type_spec_t spec; gcry_mpi_t *mpi_list; - const char *key_type; - const char *comment; + char *key_type; + char *comment; unsigned char *blob; size_t blob_n; gpg_error_t err; @@ -1455,13 +1469,16 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public, out: mpint_list_free (mpi_list); - xfree ((void *) key_type); - xfree ((void *) comment); + xfree (key_type); + xfree (comment); xfree (blob); return err; } +/* Read a public key out of BLOB/BLOB_SIZE according to the key + specification given as KEY_SPEC, storing the new key in KEY_PUBLIC. + Returns zero on success or an error code. */ static gpg_error_t ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size, gcry_sexp_t *key_public, @@ -1499,11 +1516,14 @@ ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size, +/* Converts the secret key KEY_SECRET into a public key, storing it in + KEY_PUBLIC. SPEC is the according key specification. Returns zero + on success or an error code. */ static gpg_error_t key_secret_to_public (gcry_sexp_t *key_public, ssh_key_type_spec_t spec, gcry_sexp_t key_secret) { - const char *comment; + char *comment; gcry_mpi_t *mpis; gpg_error_t err; int is_secret; @@ -1520,13 +1540,13 @@ key_secret_to_public (gcry_sexp_t *key_public, out: mpint_list_free (mpis); - xfree ((char *) comment); + xfree (comment); return err; } -/* Chec whether a smartcard is available and whether it has a usable +/* Check whether a smartcard is available and whether it has a usable key. Store a copy of that key at R_PK and return 0. If no key is available store NULL at R_PK and return an error code. If CARDSN is no NULL, a string with the serial number of the card will be @@ -1685,16 +1705,21 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) } + /* + Request handler. - */ +*/ + + +/* Handler for the "request_identities" command. */ static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t response) { - const char *key_type; + char *key_type; ssh_key_type_spec_t spec; struct dirent *dir_entry; char *key_directory; @@ -1828,7 +1853,7 @@ ssh_handler_request_identities (ctrl_t ctrl, if (err) goto out; - xfree ((void *) key_type); + xfree (key_type); key_type = NULL; err = key_secret_to_public (&key_public, spec, key_secret); @@ -1894,13 +1919,12 @@ ssh_handler_request_identities (ctrl_t ctrl, free (key_directory); xfree (key_path); xfree (buffer); - /* FIXME: Ist is for sure is a Bad Thing to use the const qualifier - and later cast it away. You can't do that!!! */ - xfree ((void *) key_type); /* FIXME? */ + xfree (key_type); return ret_err; } +/* */ static gpg_error_t data_hash (unsigned char *data, size_t data_n, int md_algorithm, unsigned char *hash) @@ -1923,7 +1947,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, gcry_mpi_t sig_value; unsigned char *sig_blob; size_t sig_blob_n; - const char *identifier; + char *identifier; const char *identifier_raw; size_t identifier_n; ssh_key_type_spec_t spec; @@ -2064,7 +2088,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, gcry_sexp_release (signature_sexp); gcry_sexp_release (sublist); mpint_list_free (mpis); - xfree ((void *) identifier); + xfree (identifier); return err; } @@ -2084,7 +2108,7 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) size_t sig_n; u32 data_size; u32 flags; - const void *p; + void *p; gpg_error_t err; gpg_error_t ret_err; @@ -2197,15 +2221,13 @@ ssh_key_extract_comment (gcry_sexp_t key, char **comment) goto out; } - comment_new = xtrymalloc (data_n + 1); + comment_new = make_cstring (data, data_n); if (! comment_new) { err = gpg_error_from_errno (errno); goto out; } - strncpy (comment_new, data, data_n); - comment_new[data_n] = 0; *comment = comment_new; err = 0; @@ -2243,8 +2265,7 @@ ssh_key_to_buffer (gcry_sexp_t key, const char *passphrase, err = 0; buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0); - buffer_new = xtrymalloc (buffer_new_n); - /* FIXME: secmem? */ + buffer_new = xtrymalloc_secure (buffer_new_n); if (! buffer_new) { err = gpg_error_from_errno (errno); -- cgit From df05dde9d59e4ed2a8eefd0a5e285f4930ac7e3a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 3 Mar 2005 10:15:07 +0000 Subject: * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Accidently used --ldflags instead of --cflags. Reported by Kazu Yamamoto. * Makefile.am (AM_CFLAGS): Added PTH_CFLAGS. Noted by Kazu Yamamoto. * Makefile.am (gpgsm_LDADD): Added PTH_LIBS. Noted by Kazu Yamamoto. --- ChangeLog | 5 +++++ THANKS | 3 ++- TODO | 2 ++ acinclude.m4 | 2 +- agent/command-ssh.c | 2 +- common/ChangeLog | 4 ++++ common/Makefile.am | 2 +- sm/ChangeLog | 4 ++++ sm/Makefile.am | 2 +- 9 files changed, 21 insertions(+), 5 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/ChangeLog b/ChangeLog index 2c86f42a8..c9f9fe3dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-03-03 Werner Koch + + * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Accidently used + --ldflags instead of --cflags. Reported by Kazu Yamamoto. + 2005-02-03 Werner Koch * AUTHORS: Copied from 1.4 and edited to refelct the changes in diff --git a/THANKS b/THANKS index d523474c7..e1424cab1 100644 --- a/THANKS +++ b/THANKS @@ -1,5 +1,6 @@ Alexander Belopolsky belopolsky at mac.com -Richard Lefebvre rick at cerca.umontreal.ca Andrew J. Schorr aschorr at telemetry-investments.com +Kazu Yamamoto kazu@iij.ad.jp Michael Nottebrock michaelnottebrock at gmx.net +Richard Lefebvre rick at cerca.umontreal.ca diff --git a/TODO b/TODO index 2aace782f..9efbe6a1c 100644 --- a/TODO +++ b/TODO @@ -104,3 +104,5 @@ might want to have an agent context for each service request ** No card status notifications. +* [scdaemon] release the card after use so that gpg 1.4 is abale to access it + diff --git a/acinclude.m4 b/acinclude.m4 index 31f540640..e933e6ee0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -246,7 +246,7 @@ AC_DEFUN([GNUPG_PTH_VERSION_CHECK], _gnupg_pth_save_cflags=$CFLAGS _gnupg_pth_save_ldflags=$LDFLAGS _gnupg_pth_save_libs=$LIBS - CFLAGS="$CFLAGS `$PTH_CONFIG --ldflags`" + CFLAGS="$CFLAGS `$PTH_CONFIG --cflags`" LDFLAGS="$LDFLAGS `$PTH_CONFIG --ldflags`" LIBS="$LIBS `$PTH_CONFIG --libs`" AC_LINK_IFELSE([AC_LANG_PROGRAM([#include diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 3b2dcd335..f48df69e4 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1550,7 +1550,7 @@ key_secret_to_public (gcry_sexp_t *key_public, key. Store a copy of that key at R_PK and return 0. If no key is available store NULL at R_PK and return an error code. If CARDSN is no NULL, a string with the serial number of the card will be - amalloced and stored there. */ + a malloced and stored there. */ static gpg_error_t card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) { diff --git a/common/ChangeLog b/common/ChangeLog index db0593176..e9bb42a57 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,7 @@ +2005-03-03 Werner Koch + + * Makefile.am (AM_CFLAGS): Added PTH_CFLAGS. Noted by Kazu Yamamoto. + 2005-02-25 Werner Koch * xasprintf.c (xtryasprintf): New. diff --git a/common/Makefile.am b/common/Makefile.am index 6cbbf9f3a..ed7659793 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -21,7 +21,7 @@ noinst_LIBRARIES = libcommon.a libsimple-pwquery.a -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) $(PTH_CFLAGS) libcommon_a_SOURCES = \ util.h i18n.h \ diff --git a/sm/ChangeLog b/sm/ChangeLog index a4f07b048..85af542d0 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,7 @@ +2005-03-03 Werner Koch + + * Makefile.am (gpgsm_LDADD): Added PTH_LIBS. Noted by Kazu Yamamoto. + 2005-01-13 Werner Koch * certreqgen.c (proc_parameters): Cast printf arg. diff --git a/sm/Makefile.am b/sm/Makefile.am index 9136eb920..d4f972527 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -54,6 +54,6 @@ gpgsm_SOURCES = \ gpgsm_LDADD = ../jnlib/libjnlib.a ../kbx/libkeybox.a \ ../common/libcommon.a \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) -lgpg-error \ - $(LIBINTL) + $(LIBINTL) $(PTH_LIBS) -- cgit From 6ece9a0de94511ce5765edd05f6b9671c0354897 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Sat, 9 Apr 2005 16:41:28 +0000 Subject: 2005-04-03 Moritz Schulte * command-ssh.c (ssh_request_spec): New member: secret_input. (REQUEST_SPEC_DEFINE): New argument: secret_input. (request_specs): Add secret_input flag. (request_spec_lookup): New function ... (ssh_request_process): ... use it here; depending on secret_input flag allocate secure or non-secure memory. --- agent/ChangeLog | 9 +++ agent/command-ssh.c | 157 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 106 insertions(+), 60 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index c16e0e37a..5a709a5db 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,12 @@ +2005-04-03 Moritz Schulte + + * command-ssh.c (ssh_request_spec): New member: secret_input. + (REQUEST_SPEC_DEFINE): New argument: secret_input. + (request_specs): Add secret_input flag. + (request_spec_lookup): New function ... + (ssh_request_process): ... use it here; depending on secret_input + flag allocate secure or non-secure memory. + 2005-03-02 Moritz Schulte * command-ssh.c (sexp_key_extract): Removed FIXME, since diff --git a/agent/command-ssh.c b/agent/command-ssh.c index f48df69e4..f9ad2a80e 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -107,6 +107,7 @@ typedef struct ssh_request_spec unsigned char type; ssh_request_handler_t handler; const char *identifier; + unsigned int secret_input; } ssh_request_spec_t; /* Type for "key modifier functions", which are necessary since @@ -160,26 +161,26 @@ typedef struct ssh_key_type_spec /* Prototypes. */ static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl, - estream_t request, - estream_t response); + estream_t request, + estream_t response); static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl, - estream_t request, - estream_t response); + estream_t request, + estream_t response); static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl, - estream_t request, - estream_t response); + estream_t request, + estream_t response); static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl, - estream_t request, - estream_t response); + estream_t request, + estream_t response); static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl, - estream_t request, - estream_t response); + estream_t request, + estream_t response); static gpg_error_t ssh_handler_lock (ctrl_t ctrl, - estream_t request, - estream_t response); + estream_t request, + estream_t response); static gpg_error_t ssh_handler_unlock (ctrl_t ctrl, - estream_t request, - estream_t response); + estream_t request, + estream_t response); static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis); static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob, @@ -195,19 +196,19 @@ static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob, /* Associating request types with the corresponding request handlers. */ -#define REQUEST_SPEC_DEFINE(id, name) \ - { SSH_REQUEST_##id, ssh_handler_##name, #name } +#define REQUEST_SPEC_DEFINE(id, name, secret_input) \ + { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input } static ssh_request_spec_t request_specs[] = { - REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities), - REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request), - REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity), - REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity), - REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity), - REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities), - REQUEST_SPEC_DEFINE (LOCK, lock), - REQUEST_SPEC_DEFINE (UNLOCK, unlock) + REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities, 1), + REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request, 0), + REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity, 1), + REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity, 1), + REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity, 0), + REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0), + REQUEST_SPEC_DEFINE (LOCK, lock, 0), + REQUEST_SPEC_DEFINE (UNLOCK, unlock, 0) }; #undef REQUEST_SPEC_DEFINE @@ -1733,13 +1734,15 @@ ssh_handler_request_identities (ctrl_t ctrl, gcry_sexp_t key_public; DIR *dir; gpg_error_t err; - gpg_error_t ret_err; int ret; FILE *ctrl_fp = NULL; char *cardsn; + gpg_error_t ret_err; /* Prepare buffer stream. */ + sleep (5); + key_directory = NULL; key_secret = NULL; key_public = NULL; @@ -2460,8 +2463,10 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) gcry_sexp_release (key); - ret_err = stream_write_byte (response, - err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); return ret_err; } @@ -2496,8 +2501,10 @@ ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, xfree (key_blob); gcry_sexp_release (key); - ret_err = stream_write_byte (response, - err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); return ret_err; } @@ -2523,8 +2530,11 @@ ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request, gpg_error_t err; err = ssh_identities_remove_all (); - ret_err = stream_write_byte (response, - err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); return ret_err; } @@ -2559,8 +2569,11 @@ ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response) gpg_error_t err; err = ssh_lock (); - ret_err = stream_write_byte (response, - err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); return ret_err; } @@ -2572,22 +2585,45 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) gpg_error_t err; err = ssh_unlock (); - ret_err = stream_write_byte (response, - err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS); + + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); return ret_err; } +static ssh_request_spec_t * +request_spec_lookup (int type) +{ + ssh_request_spec_t *spec; + unsigned int i; + + for (i = 0; i < DIM (request_specs); i++) + if (request_specs[i].type == type) + break; + if (i == DIM (request_specs)) + { + log_info ("ssh request %u is not supported\n", type); + spec = NULL; + } + else + spec = request_specs + i; + + return spec; +} + static int ssh_request_process (ctrl_t ctrl, estream_t stream_sock) { + ssh_request_spec_t *spec; estream_t response; estream_t request; unsigned char request_type; gpg_error_t err; - unsigned int i; int send_err; int ret; unsigned char *request_data; @@ -2617,7 +2653,26 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) log_info ("received ssh request of length %u\n", (unsigned int)request_data_size); - request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+"); + if (! request_data_size) + { + send_err = 1; + goto out; + /* Broken request; FIXME. */ + } + + request_type = request_data[0]; + spec = request_spec_lookup (request_type); + if (! spec) + { + send_err = 1; + goto out; + /* Unknown request; FIXME. */ + } + + if (spec->secret_input) + request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+"); + else + request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+"); if (! request) { err = gpg_error_from_errno (errno); @@ -2629,7 +2684,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) err = gpg_error_from_errno (errno); goto out; } - err = stream_write_data (request, request_data, request_data_size); + err = stream_write_data (request, request_data + 1, request_data_size - 1); if (err) goto out; es_rewind (request); @@ -2641,38 +2696,20 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) goto out; } - err = stream_read_byte (request, &request_type); - if (err) - { - send_err = 1; - goto out; - } - - for (i = 0; i < DIM (request_specs); i++) - if (request_specs[i].type == request_type) - break; - if (i == DIM (request_specs)) - { - log_info ("ssh request %u is not supported\n", request_type); - send_err = 1; - goto out; - } - if (opt.verbose) log_info ("ssh request handler for %s (%u) started\n", - request_specs[i].identifier, request_specs[i].type); + spec->identifier, spec->type); - err = (*request_specs[i].handler) (ctrl, request, response); + err = (*spec->handler) (ctrl, request, response); if (opt.verbose) { if (err) log_info ("ssh request handler for %s (%u) failed: %s\n", - request_specs[i].identifier, request_specs[i].type, - gpg_strerror (err)); + spec->identifier, spec->type, gpg_strerror (err)); else log_info ("ssh request handler for %s (%u) ready\n", - request_specs[i].identifier, request_specs[i].type); + spec->identifier, spec->type); } if (err) -- cgit From eff62d82bfcb9df1b85ce596f0f5b6ef00d3a0ca Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 18 Apr 2005 10:44:46 +0000 Subject: * configure.ac: Require libksba 0.9.11. sm/ * call-dirmngr.c (inq_certificate): Add new inquire SENDCERT_SKI. * certlist.c (gpgsm_find_cert): Add new arg KEYID and implement this filter. Changed all callers. * certchain.c (find_up_search_by_keyid): New helper. (find_up): Also try using the AKI.keyIdentifier. (find_up_external): Ditto. --- ChangeLog | 4 ++ NEWS | 9 ++++- README | 8 ++-- TODO | 4 ++ agent/command-ssh.c | 1 + common/ChangeLog | 5 +++ common/sexputil.c | 78 ++++++++++++++++++++++++++++++++++++ common/util.h | 3 ++ configure.ac | 2 +- sm/ChangeLog | 15 +++++++ sm/call-dirmngr.c | 21 ++++++++-- sm/certchain.c | 113 ++++++++++++++++++++++++++++++++++++++++++---------- sm/certdump.c | 1 + sm/certlist.c | 40 ++++++++++++++++--- sm/gpgsm.c | 2 +- sm/gpgsm.h | 2 +- sm/keylist.c | 35 +++++++++++++--- 17 files changed, 302 insertions(+), 41 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/ChangeLog b/ChangeLog index 3c3c700c5..013241648 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-04-15 Werner Koch + + * configure.ac: Require libksba 0.9.11. + 2005-04-15 Marcus Brinkmann * configure.ac: Check for /usr/bin/shred and define SHRED. diff --git a/NEWS b/NEWS index 101e04b98..d2334d9cd 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,13 @@ Noteworthy changes in version 1.9.16 ------------------------------------------------- + * gpg-agent does now support the ssh-agent protocol and thus allows + to use the pinentry as well as the OpenPGP smartcard with ssh. + + * New tool gpg-connect-agent as a genereal client for the gpg-agent. + + * New tool symcryptrun as a wrapper for certain encryption tools. + Noteworthy changes in version 1.9.15 (2005-01-13) ------------------------------------------------- @@ -226,7 +233,7 @@ Noteworthy changes in version 1.9.0 (2003-08-05) development branch. - Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/README b/README index c14534e93..7e44765a6 100644 --- a/README +++ b/README @@ -399,7 +399,7 @@ modes for gpgsm, here is the entire list of ways to specify a key: +Heinrich Heine duesseldorf - * [NEW] Exact match by subject's DN + * Exact match by subject's DN This is indicated by a leading slash, directly followed by the rfc2253 encoded DN of the subject. Note that you can't use the @@ -411,7 +411,7 @@ modes for gpgsm, here is the entire list of ways to specify a key: /CN=Heinrich Heine,O=Poets,L=Paris,C=FR - * [NEW] Excact match by issuer's DN + * Excact match by issuer's DN This is indicated by a leading hash mark, directly followed by a slash and then directly followed by the rfc2253 encoded DN of the @@ -422,10 +422,10 @@ modes for gpgsm, here is the entire list of ways to specify a key: #/CN=Root Cert,O=Poets,L=Paris,C=FR - * [NEW] Exact match by serial number and subject's DN + * Exact match by serial number and issuer's DN This is indicated by a hash mark, followed by the hexadecmal - representation of the serial number, the followed by a slahs and + representation of the serial number, the followed by a slash and the RFC2253 encoded DN of the issuer. See note above. Example: diff --git a/TODO b/TODO index 9efbe6a1c..26b2cee60 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,9 @@ -*- outline -*- +* IMPORTANT +Check that openpty and pty.h are available and build symcryptrun only +then. Run shred on the temporary files. + * src/base64 ** Make parsing more robust diff --git a/agent/command-ssh.c b/agent/command-ssh.c index f9ad2a80e..00c202078 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1741,6 +1741,7 @@ ssh_handler_request_identities (ctrl_t ctrl, /* Prepare buffer stream. */ +#warning Huh, sleep? why that? Anyway, this should be pth_sleep sleep (5); key_directory = NULL; diff --git a/common/ChangeLog b/common/ChangeLog index a42b07b4d..4688d2765 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,8 @@ +2005-04-17 Werner Koch + + * sexputil.c (cmp_simple_canon_sexp): New. + (make_simple_sexp_from_hexstr): New. + 2005-04-07 Werner Koch * sexputil.c: New. diff --git a/common/sexputil.c b/common/sexputil.c index 853d7e58a..802916b44 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -61,3 +61,81 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, return err; } + +/* Compare two simple S-expressions like "(3:foo)". Returns 0 if they + are identical or !0 if they are not. Not that this function can't + be used for sorting. */ +int +cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b) +{ + unsigned long n1, n2; + char *endp; + + if (!a && !b) + return 0; /* Both are NULL, they are identical. */ + if (!a || !b) + return 1; /* One is NULL, they are not identical. */ + if (*a != '(' || *b != '(') + log_bug ("invalid S-exp in cmp_simple_canon_sexp\n"); + + a++; + n1 = strtoul (a, &endp, 10); + a = endp; + b++; + n2 = strtoul (b, &endp, 10); + b = endp; + + if (*a != ':' || *b != ':' ) + log_bug ("invalid S-exp in cmp_simple_canon_sexp\n"); + if (n1 != n2) + return 1; /* Not the same. */ + + for (a++, b++; n1; n1--, a++, b++) + if (*a != *b) + return 1; /* Not the same. */ + return 0; +} + + +/* Create a simple S-expression from the hex string at LIBNE. Returns + a newly allocated buffer with that canonical encoded S-expression + or NULL in case of an error. On return the number of characters + scanned in LINE will be stored at NSCANNED. This fucntions stops + converting at the first character not representing a hexdigit. Odd + numbers of hex digits are allowed; a leading zero is then + assumed. If no characters have been found, NULL is returned.*/ +unsigned char * +make_simple_sexp_from_hexstr (const char *line, size_t *nscanned) +{ + size_t n, len; + const char *s; + unsigned char *buf; + unsigned char *p; + char numbuf[50]; + + for (n=0, s=line; hexdigitp (s); s++, n++) + ; + if (nscanned) + *nscanned = n; + if (!n) + return NULL; + len = ((n+1) & ~0x01)/2; + sprintf (numbuf, "(%u:", (unsigned int)len); + buf = xtrymalloc (strlen (numbuf) + len + 1 + 1); + if (!buf) + return NULL; + p = stpcpy (buf, numbuf); + s = line; + if ((n&1)) + { + *p++ = xtoi_1 (s); + s++; + n--; + } + for (; n > 1; n -=2, s += 2) + *p++ = xtoi_2 (s); + *p++ = ')'; + *p = 0; /* (Not really neaded.) */ + + return buf; +} diff --git a/common/util.h b/common/util.h index 14180bec4..6a9b54ef5 100644 --- a/common/util.h +++ b/common/util.h @@ -123,6 +123,9 @@ gpg_error_t b64enc_finish (struct b64state *state); /*-- sexputil.c */ gpg_error_t keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, unsigned char *grip); +int cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b); +unsigned char *make_simple_sexp_from_hexstr (const char *line, + size_t *nscanned); /*-- homedir. c --*/ const char *default_homedir (void); diff --git a/configure.ac b/configure.ac index d331566be..d0ffa8ca4 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ NEED_LIBGCRYPT_VERSION=1.1.94 NEED_LIBASSUAN_VERSION=0.6.9 -NEED_KSBA_VERSION=0.9.7 +NEED_KSBA_VERSION=0.9.11 NEED_OPENSC_VERSION=0.8.0 diff --git a/sm/ChangeLog b/sm/ChangeLog index e74381bd5..7b67407ad 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,18 @@ +2005-04-17 Werner Koch + + * call-dirmngr.c (inq_certificate): Add new inquire SENDCERT_SKI. + * certlist.c (gpgsm_find_cert): Add new arg KEYID and implement + this filter. Changed all callers. + + * certchain.c (find_up_search_by_keyid): New helper. + (find_up): Also try using the AKI.keyIdentifier. + (find_up_external): Ditto. + +2005-04-15 Werner Koch + + * keylist.c (list_cert_raw): Print the subjectKeyIdentifier as + well as the keyIdentifier part of the authorityKeyIdentifier. + 2005-03-31 Werner Koch * call-dirmngr.c (start_dirmngr): Use PATHSEP_C instead of ':'. diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 5988ea952..847e78490 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -1,5 +1,5 @@ /* call-dirmngr.c - communication with the dromngr - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -266,11 +266,25 @@ inq_certificate (void *opaque, const char *line) const unsigned char *der; size_t derlen; int issuer_mode = 0; + ksba_sexp_t ski = NULL; if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8])) { line += 8; } + else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12])) + { + size_t n; + + /* Send a certificate where a sourceKeyidentifier is included. */ + line += 12; + while (*line == ' ') + line++; + ski = make_simple_sexp_from_hexstr (line, &n); + line += n; + while (*line == ' ') + line++; + } else if (!strncmp (line, "SENDISSUERCERT", 14) && (line[14] == ' ' || !line[14])) { @@ -304,7 +318,7 @@ inq_certificate (void *opaque, const char *line) ksba_cert_t cert; - err = gpgsm_find_cert (line, &cert); + err = gpgsm_find_cert (line, ski, &cert); if (err) { log_error ("certificate not found: %s\n", gpg_strerror (err)); @@ -321,6 +335,7 @@ inq_certificate (void *opaque, const char *line) } } + xfree (ski); return rc; } @@ -717,7 +732,7 @@ run_command_inq_cb (void *opaque, const char *line) if (!*line) return ASSUAN_Inquire_Error; - err = gpgsm_find_cert (line, &cert); + err = gpgsm_find_cert (line, NULL, &cert); if (err) { log_error ("certificate not found: %s\n", gpg_strerror (err)); diff --git a/sm/certchain.c b/sm/certchain.c index 514ee23a5..a5fdbc622 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -266,6 +266,42 @@ check_cert_policy (ksba_cert_t cert, int listmode, FILE *fplist) } +/* Helper fucntion for find_up. This resets the key handle and search + for an issuer ISSUER with a subjectKeyIdentifier of KEYID. Returns + 0 obn success or -1 when not found. */ +static int +find_up_search_by_keyid (KEYDB_HANDLE kh, + const char *issuer, ksba_sexp_t keyid) +{ + int rc; + ksba_cert_t cert = NULL; + ksba_sexp_t subj = NULL; + + keydb_search_reset (kh); + while (!(rc = keydb_search_subject (kh, issuer))) + { + ksba_cert_release (cert); cert = NULL; + rc = keydb_get_cert (kh, &cert); + if (rc) + { + log_error ("keydb_get_cert() failed: rc=%d\n", rc); + rc = -1; + break; + } + xfree (subj); + if (!ksba_cert_get_subj_key_id (cert, NULL, &subj)) + { + if (!cmp_simple_canon_sexp (keyid, subj)) + break; /* Found matching cert. */ + } + } + + ksba_cert_release (cert); + xfree (subj); + return rc? -1:0; +} + + static void find_up_store_certs_cb (void *cb_value, ksba_cert_t cert) { @@ -275,13 +311,13 @@ find_up_store_certs_cb (void *cb_value, ksba_cert_t cert) } - /* Helper for find_up(). Locate the certificate for ISSUER using an external lookup. KH is the keydb context we are currently using. On success 0 is returned and the certificate may be retrieved from - the keydb using keydb_get_cert().*/ + the keydb using keydb_get_cert(). KEYID is the keyIdentifier from + the AKI or NULL. */ static int -find_up_external (KEYDB_HANDLE kh, const char *issuer) +find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) { int rc; strlist_t names = NULL; @@ -324,8 +360,13 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer) /* The issuers are currently stored in the ephemeral key DB, so we temporary switch to ephemeral mode. */ old = keydb_set_ephemeral (kh, 1); - keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); + if (keyid) + rc = find_up_search_by_keyid (kh, issuer, keyid); + else + { + keydb_search_reset (kh); + rc = keydb_search_subject (kh, issuer); + } keydb_set_ephemeral (kh, old); } return rc; @@ -343,9 +384,10 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) { ksba_name_t authid; ksba_sexp_t authidno; + ksba_sexp_t keyid; int rc = -1; - if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno)) + if (!ksba_cert_get_auth_key_id (cert, &keyid, &authid, &authidno)) { const char *s = ksba_name_enum (authid, 0); if (s && *authidno) @@ -369,28 +411,57 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) keydb_set_ephemeral (kh, old); } - /* If we didn't found it, try an external lookup. */ - if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) - rc = find_up_external (kh, issuer); } + if (rc == -1 && keyid && !find_next) + { + /* Not found by AIK.issuer_sn. Lets try the AIY.ki + instead. Loop over all certificates with that issuer as + subject and stop for the one with a matching + subjectKeyIdentifier. */ + rc = find_up_search_by_keyid (kh, issuer, keyid); + if (rc) + { + int old = keydb_set_ephemeral (kh, 1); + if (!old) + rc = find_up_search_by_keyid (kh, issuer, keyid); + keydb_set_ephemeral (kh, old); + } + if (rc) + rc = -1; /* Need to make sure to have this error code. */ + } + + /* If we still didn't found it, try an external lookup. */ + if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) + rc = find_up_external (kh, issuer, keyid); + /* Print a note so that the user does not feel too helpless when an issuer certificate was found and gpgsm prints BAD signature because it is not the correct one. */ if (rc == -1) { - log_info ("%sissuer certificate (#", find_next?"next ":""); - gpgsm_dump_serial (authidno); - log_printf ("/"); - gpgsm_dump_string (s); - log_printf (") not found using authorityKeyIdentifier\n"); + log_info ("%sissuer certificate ", find_next?"next ":""); + if (keyid) + { + log_printf ("{"); + gpgsm_dump_serial (keyid); + log_printf ("} "); + } + if (authidno) + { + log_printf ("(#"); + gpgsm_dump_serial (authidno); + log_printf ("/"); + gpgsm_dump_string (s); + log_printf (") "); + } + log_printf ("not found using authorityKeyIdentifier\n"); } else if (rc) log_error ("failed to find authorityKeyIdentifier: rc=%d\n", rc); + xfree (keyid); ksba_name_release (authid); xfree (authidno); - /* Fixme: There is no way to do an external lookup with - serial+issuer. */ } if (rc) /* Not found via authorithyKeyIdentifier, try regular issuer name. */ @@ -409,7 +480,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) /* Still not found. If enabled, try an external lookup. */ if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) - rc = find_up_external (kh, issuer); + rc = find_up_external (kh, issuer, NULL); return rc; } @@ -468,7 +539,7 @@ gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next) rc = keydb_get_cert (kh, r_next); if (rc) { - log_error ("failed to get cert: rc=%d\n", rc); + log_error ("keydb_get_cert() failed: rc=%d\n", rc); rc = gpg_error (GPG_ERR_GENERAL); } @@ -791,7 +862,7 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, rc = keydb_get_cert (kh, &issuer_cert); if (rc) { - log_error ("failed to get cert: rc=%d\n", rc); + log_error ("keydb_get_cert() failed: rc=%d\n", rc); rc = gpg_error (GPG_ERR_GENERAL); goto leave; } @@ -818,6 +889,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, might have been used. This is required because some CAs are reusing the issuer and subject DN for new root certificates. */ + /* FIXME: Do this only if we don't have an + AKI.keyIdentifier */ rc = find_up (kh, subject_cert, issuer, 1); if (!rc) { @@ -1008,7 +1081,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert) rc = keydb_get_cert (kh, &issuer_cert); if (rc) { - log_error ("failed to get cert: rc=%d\n", rc); + log_error ("keydb_get_cert() failed: rc=%d\n", rc); rc = gpg_error (GPG_ERR_GENERAL); goto leave; } diff --git a/sm/certdump.c b/sm/certdump.c index cdf4edcc1..26510c70d 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -75,6 +75,7 @@ gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) } +/* Dump the serial number or any other simple S-expression. */ void gpgsm_dump_serial (ksba_const_sexp_t p) { diff --git a/sm/certlist.c b/sm/certlist.c index 018ad47ff..b036a85d7 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -1,5 +1,5 @@ /* certlist.c - build list of certificates - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -412,9 +412,11 @@ gpgsm_release_certlist (CERTLIST list) /* Like gpgsm_add_to_certlist, but look only for one certificate. No - chain validation is done */ + chain validation is done. If KEYID is not NULL it is take as an + additional filter value which must match the + subjectKeyIdentifier. */ int -gpgsm_find_cert (const char *name, ksba_cert_t *r_cert) +gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert) { int rc; KEYDB_SEARCH_DESC desc; @@ -429,10 +431,38 @@ gpgsm_find_cert (const char *name, ksba_cert_t *r_cert) rc = gpg_error (GPG_ERR_ENOMEM); else { + nextone: rc = keydb_search (kh, &desc, 1); if (!rc) - rc = keydb_get_cert (kh, r_cert); - if (!rc) + { + rc = keydb_get_cert (kh, r_cert); + if (!rc && keyid) + { + ksba_sexp_t subj; + + rc = ksba_cert_get_subj_key_id (*r_cert, NULL, &subj); + if (!rc) + { + if (cmp_simple_canon_sexp (keyid, subj)) + { + xfree (subj); + goto nextone; + } + xfree (subj); + /* Okay: Here we know that the certificate's + subjectKeyIdentifier matches the requested + one. */ + } + else if (gpg_err_code (rc) == GPG_ERR_NO_DATA) + goto nextone; + } + } + + /* If we don't have the KEYID filter we need to check for + ambigious search results. Note, that it is somehwat + reasonable to assume that a specification of a KEYID + won't lead to ambiguous names. */ + if (!rc && !keyid) { rc = keydb_search (kh, &desc, 1); if (rc == -1) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ff404dc69..dae547702 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1566,7 +1566,7 @@ main ( int argc, char **argv) ksba_cert_t cert = NULL; char *grip = NULL; - rc = gpgsm_find_cert (*argv, &cert); + rc = gpgsm_find_cert (*argv, NULL, &cert); if (rc) ; else if (!(grip = gpgsm_get_keygrip_hexstring (cert))) diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 17ad21ed6..aafc4815d 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -252,7 +252,7 @@ int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert, int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, certlist_t *listaddr, int is_encrypt_to); void gpgsm_release_certlist (certlist_t list); -int gpgsm_find_cert (const char *name, ksba_cert_t *r_cert); +int gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert); /*-- keylist.c --*/ gpg_error_t gpgsm_list_keys (ctrl_t ctrl, STRLIST names, diff --git a/sm/keylist.c b/sm/keylist.c index aa6db46c3..8e1233341 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -1,6 +1,6 @@ -/* keylist.c +/* keylist.c - Print certificates in various formats. * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004 Free Software Foundation, Inc. + * 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -122,7 +122,7 @@ static struct { { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" }, /* X.509 id-ce */ - { "2.5.29.14", "subjectKeyIdentifier"}, + { "2.5.29.14", "subjectKeyIdentifier", 1}, { "2.5.29.15", "keyUsage", 1 }, { "2.5.29.16", "privateKeyUsagePeriod" }, { "2.5.29.17", "subjectAltName", 1 }, @@ -512,7 +512,7 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, { gpg_error_t err; size_t off, len; - ksba_sexp_t sexp; + ksba_sexp_t sexp, keyid; char *dn; ksba_isotime_t t; int idx, i; @@ -588,9 +588,27 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, fprintf (fp, " keyType: %u bit %s\n", nbits, algoname? algoname:"?"); } + /* subjectKeyIdentifier */ + fputs (" subjKeyId: ", fp); + err = ksba_cert_get_subj_key_id (cert, NULL, &keyid); + if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA) + { + if (gpg_err_code (err) == GPG_ERR_NO_DATA) + fputs ("[none]\n", fp); + else + { + gpgsm_print_serial (fp, keyid); + ksba_free (keyid); + putc ('\n', fp); + } + } + else + fputs ("[?]\n", fp); + + /* authorityKeyIdentifier */ fputs (" authKeyId: ", fp); - err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp); + err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp); if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA) { if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name) @@ -603,6 +621,13 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, print_names_raw (fp, -15, name); ksba_name_release (name); } + if (keyid) + { + fputs (" authKeyId.ki: ", fp); + gpgsm_print_serial (fp, keyid); + ksba_free (keyid); + putc ('\n', fp); + } } else fputs ("[?]\n", fp); -- cgit From a78c5e9673bbbee0ec277bbd39a5e38ebaf41052 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Wed, 20 Apr 2005 14:47:19 +0000 Subject: 2005-04-20 Moritz Schulte * command-ssh.c (ssh_handler_request_identities): Removed debugging code (sleep call), which was commited unintenionally. --- agent/ChangeLog | 5 +++++ agent/command-ssh.c | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 5a709a5db..e30b2cbc5 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,8 @@ +2005-04-20 Moritz Schulte + + * command-ssh.c (ssh_handler_request_identities): Removed + debugging code (sleep call), which was commited unintenionally. + 2005-04-03 Moritz Schulte * command-ssh.c (ssh_request_spec): New member: secret_input. diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 00c202078..133dd01dd 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1741,9 +1741,6 @@ ssh_handler_request_identities (ctrl_t ctrl, /* Prepare buffer stream. */ -#warning Huh, sleep? why that? Anyway, this should be pth_sleep - sleep (5); - key_directory = NULL; key_secret = NULL; key_public = NULL; -- cgit From e22f6db54430bcbc1db5ca1b06cf9777230ae8ea Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Thu, 5 May 2005 14:49:54 +0000 Subject: 2005-05-05 Moritz Schulte * command-ssh.c (ssh_key_to_buffer): Rename to ... (ssh_key_to_protected_buffer): ... this; change callers. Improved documentation. --- agent/ChangeLog | 6 +++ agent/command-ssh.c | 123 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 91 insertions(+), 38 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 5f26fc624..940294c52 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,9 @@ +2005-05-05 Moritz Schulte + + * command-ssh.c (ssh_key_to_buffer): Rename to ... + (ssh_key_to_protected_buffer): ... this; change callers. + Improved documentation. + 2005-04-20 Moritz Schulte * command-ssh.c (ssh_handler_request_identities): Removed diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 133dd01dd..0b6769209 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -148,10 +148,14 @@ typedef struct ssh_key_type_spec is required by gpg-agent's key access layer. */ const char *elems_sexp_order; - /* Key modifier function. */ + /* Key modifier function. Key modifier functions are necessary in + order to fix any inconsistencies between the representation of + keys on the SSH and on the GnuPG side. */ ssh_key_modifier_t key_modifier; - /* Signature encoder function. */ + /* Signature encoder function. Signature encoder functions are + necessary since the encoding of signatures depends on the used + algorithm. */ ssh_signature_encoder_t signature_encoder; /* Misc flags. */ @@ -196,11 +200,11 @@ static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob, /* Associating request types with the corresponding request handlers. */ +static ssh_request_spec_t request_specs[] = + { #define REQUEST_SPEC_DEFINE(id, name, secret_input) \ { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input } -static ssh_request_spec_t request_specs[] = - { REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities, 1), REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request, 0), REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity, 1), @@ -209,8 +213,8 @@ static ssh_request_spec_t request_specs[] = REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0), REQUEST_SPEC_DEFINE (LOCK, lock, 0), REQUEST_SPEC_DEFINE (UNLOCK, unlock, 0) - }; #undef REQUEST_SPEC_DEFINE + }; /* Table holding key type specifications. */ @@ -816,7 +820,10 @@ mpint_list_free (gcry_mpi_t *mpi_list) } } - +/* Receive key material MPIs from STREAM according to KEY_SPEC; + depending on SECRET expect a public key or secret key. The newly + allocated list of MPIs is stored in MPI_LIST. Returns usual error + code. */ static gpg_error_t ssh_receive_mpint_list (estream_t stream, int secret, ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list) @@ -982,7 +989,9 @@ ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) */ -/* */ +/* This function constructs a new S-Expression for the key identified + by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in + *SEXP. Returns usual error code. */ static gpg_error_t sexp_key_construct (gcry_sexp_t *sexp, ssh_key_type_spec_t key_spec, int secret, @@ -1072,7 +1081,12 @@ sexp_key_construct (gcry_sexp_t *sexp, return err; } - +/* This functions breaks up the key contained in the S-Expression SEXP + according to KEY_SPEC. The MPIs are bundled in a newly create + list, which is to be stored in MPIS; a newly allocated string + holding the comment will be stored in COMMENT; SECRET will be + filled with a boolean flag specifying what kind of key it is. + Returns usual error code. */ static gpg_error_t sexp_key_extract (gcry_sexp_t sexp, ssh_key_type_spec_t key_spec, int *secret, @@ -1710,7 +1724,9 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) /* - Request handler. + Request handler. Each handler is provided with a CTRL context, a + REQUEST object and a RESPONSE object. The actual request is to be + read from REQUEST, the response needs to be written to RESPONSE. */ @@ -1925,7 +1941,30 @@ ssh_handler_request_identities (ctrl_t ctrl, return ret_err; } -/* */ +/* This function calculates the key grip for the key contained in the + S-Expression KEY and writes it to BUFFER, which must be large + enough to hold it. Returns usual error code. */ +static gpg_error_t +ssh_key_grip (gcry_sexp_t key, char *buffer) +{ + gpg_error_t err; + char *p; + + /* FIXME: unsigned vs. signed. */ + + p = gcry_pk_get_keygrip (key, buffer); + if (! p) + err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ + else + err = 0; + + return err; +} + +/* This function hashes the data contained in DATA of size DATA_N + according to the message digest algorithm specified by MD_ALGORITHM + and writes the message digest to HASH, which needs to large enough + for the digest. */ static gpg_error_t data_hash (unsigned char *data, size_t data_n, int md_algorithm, unsigned char *hash) @@ -1935,7 +1974,9 @@ data_hash (unsigned char *data, size_t data_n, return 0; } - +/* This function signs the data contained in CTRL, stores the created + signature in newly allocated memory in SIG and it's size in SIG_N; + SIG_ENCODER is the signature encoder to use. */ static gpg_error_t data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, unsigned char **sig, size_t *sig_n) @@ -2094,6 +2135,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, return err; } +/* Handler for the "sign_request" command. */ static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) { @@ -2198,7 +2240,9 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) return ret_err; } - +/* This function extracts the comment contained in the key + S-Expression KEY and stores a copy in COMMENT. Returns usual error + code. */ static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment) { @@ -2239,26 +2283,12 @@ ssh_key_extract_comment (gcry_sexp_t key, char **comment) return err; } +/* This function converts the key contained in the S-Expression KEY + into a buffer, which is protected by the passphrase PASSPHRASE. + Returns usual error code. */ static gpg_error_t -ssh_key_grip (gcry_sexp_t key, char *buffer) -{ - gpg_error_t err; - char *p; - - /* FIXME: unsigned vs. signed. */ - - p = gcry_pk_get_keygrip (key, buffer); - if (! p) - err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ - else - err = 0; - - return err; -} - -static gpg_error_t -ssh_key_to_buffer (gcry_sexp_t key, const char *passphrase, - unsigned char **buffer, size_t *buffer_n) +ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase, + unsigned char **buffer, size_t *buffer_n) { unsigned char *buffer_new; unsigned int buffer_new_n; @@ -2287,7 +2317,7 @@ ssh_key_to_buffer (gcry_sexp_t key, const char *passphrase, -/* Store the ssh KEY into our local key storage and protect him after +/* Store the ssh KEY into our local key storage and protect it after asking for a passphrase. Cache that passphrase. TTL is the maximum caching time for that key. If the key already exists in our key storage, don't do anything. When entering a new key also @@ -2345,7 +2375,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) if (err) goto out; - err = ssh_key_to_buffer (key, pi->pin, &buffer, &buffer_n); + err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n); if (err) goto out; @@ -2378,7 +2408,9 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) } - +/* This function removes the key contained in the S-Expression KEY + from the local key storage, in case it exists there. Returns usual + error code. FIXME: this function is a stub. */ static gpg_error_t ssh_identity_drop (gcry_sexp_t key) { @@ -2399,6 +2431,7 @@ ssh_identity_drop (gcry_sexp_t key) return err; } +/* Handler for the "add_identity" command. */ static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) { @@ -2469,9 +2502,10 @@ ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) return ret_err; } +/* Handler for the "remove_identity" command. */ static gpg_error_t -ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, - estream_t response) +ssh_handler_remove_identity (ctrl_t ctrl, + estream_t request, estream_t response) { unsigned char *key_blob; u32 key_blob_size; @@ -2507,6 +2541,7 @@ ssh_handler_remove_identity (ctrl_t ctrl, estream_t request, return ret_err; } +/* FIXME: stub function. Actually useful? */ static gpg_error_t ssh_identities_remove_all (void) { @@ -2520,9 +2555,10 @@ ssh_identities_remove_all (void) return err; } +/* Handler for the "remove_all_identities" command. */ static gpg_error_t -ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request, - estream_t response) +ssh_handler_remove_all_identities (ctrl_t ctrl, + estream_t request, estream_t response) { gpg_error_t ret_err; gpg_error_t err; @@ -2537,6 +2573,7 @@ ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request, return ret_err; } +/* Lock agent? FIXME: stub function. */ static gpg_error_t ssh_lock (void) { @@ -2549,6 +2586,7 @@ ssh_lock (void) return err; } +/* Unock agent? FIXME: stub function. */ static gpg_error_t ssh_unlock (void) { @@ -2560,6 +2598,7 @@ ssh_unlock (void) return err; } +/* Handler for the "lock" command. */ static gpg_error_t ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response) { @@ -2576,6 +2615,7 @@ ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response) return ret_err; } +/* Handler for the "unlock" command. */ static gpg_error_t ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) { @@ -2594,6 +2634,9 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) +/* Return the request specification for the request identified by TYPE + or NULL in case the requested request specification could not be + found. */ static ssh_request_spec_t * request_spec_lookup (int type) { @@ -2614,6 +2657,9 @@ request_spec_lookup (int type) return spec; } +/* Process a single request. The request is read from and the + response is written to STREAM_SOCK. Uses CTRL as context. Returns + zero in case of success, non zero in case of failure. */ static int ssh_request_process (ctrl_t ctrl, estream_t stream_sock) { @@ -2772,6 +2818,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) return !!err; } +/* Start serving client on SOCK_CLIENT. */ void start_command_handler_ssh (int sock_client) { -- cgit From 2fb1abb84906d37eef459fd70d014c3c5e93294d Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Thu, 5 May 2005 14:57:59 +0000 Subject: 2005-05-05 Moritz Schulte * command-ssh.c: Use ssh_key_grip(), where gcry_pk_get_keygrip() has been used before. (ssh_handler_sign_request): Removed unusued variable P. --- agent/ChangeLog | 3 +++ agent/command-ssh.c | 60 ++++++++++++++++++++++++++--------------------------- 2 files changed, 32 insertions(+), 31 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 940294c52..f5dbeb9e3 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -3,6 +3,9 @@ * command-ssh.c (ssh_key_to_buffer): Rename to ... (ssh_key_to_protected_buffer): ... this; change callers. Improved documentation. + Use ssh_key_grip(), where gcry_pk_get_keygrip() has been used + before. + (ssh_handler_sign_request): Removed unusued variable P. 2005-04-20 Moritz Schulte diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 0b6769209..92a84c662 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1531,6 +1531,26 @@ ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size, +/* This function calculates the key grip for the key contained in the + S-Expression KEY and writes it to BUFFER, which must be large + enough to hold it. Returns usual error code. */ +static gpg_error_t +ssh_key_grip (gcry_sexp_t key, char *buffer) +{ + gpg_error_t err; + char *p; + + /* FIXME: unsigned vs. signed. */ + + p = gcry_pk_get_keygrip (key, buffer); + if (! p) + err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ + else + err = 0; + + return err; +} + /* Converts the secret key KEY_SECRET into a public key, storing it in KEY_PUBLIC. SPEC is the according key specification. Returns zero on success or an error code. */ @@ -1643,14 +1663,16 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) xfree (serialno); return err; } - - if ( !gcry_pk_get_keygrip (s_pk, grip) ) + + err = ssh_key_grip (s_pk, grip); + if (err) { - log_debug ("error computing keygrip from received card key\n"); + log_debug ("error computing keygrip from received card key: %s\n", + gcry_strerror (err)); xfree (pkbuf); gcry_sexp_release (s_pk); xfree (serialno); - return gpg_error (GPG_ERR_INTERNAL); + return err; } if ( agent_key_available (grip) ) @@ -1941,26 +1963,6 @@ ssh_handler_request_identities (ctrl_t ctrl, return ret_err; } -/* This function calculates the key grip for the key contained in the - S-Expression KEY and writes it to BUFFER, which must be large - enough to hold it. Returns usual error code. */ -static gpg_error_t -ssh_key_grip (gcry_sexp_t key, char *buffer) -{ - gpg_error_t err; - char *p; - - /* FIXME: unsigned vs. signed. */ - - p = gcry_pk_get_keygrip (key, buffer); - if (! p) - err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ - else - err = 0; - - return err; -} - /* This function hashes the data contained in DATA of size DATA_N according to the message digest algorithm specified by MD_ALGORITHM and writes the message digest to HASH, which needs to large enough @@ -2151,7 +2153,6 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) size_t sig_n; u32 data_size; u32 flags; - void *p; gpg_error_t err; gpg_error_t ret_err; @@ -2192,12 +2193,9 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) goto out; /* Calculate key grip. */ - p = gcry_pk_get_keygrip (key, key_grip); - if (! p) - { - err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ - goto out; - } + err = ssh_key_grip (key, key_grip); + if (err) + goto out; /* Sign data. */ -- cgit From e96af3715b9b126b435c7887e47a660a73bf237b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 24 May 2005 12:37:36 +0000 Subject: * call-scd.c (inq_needpin): Skip leading spaces in of PIN description. * divert-scd.c (getpin_cb): Enhanced to cope with description flags. * query.c (agent_askpin): Add arg PROMPT_TEXT. Changed all callers. --- TODO | 8 ----- agent/ChangeLog | 9 +++++ agent/agent.h | 3 +- agent/call-scd.c | 2 ++ agent/command-ssh.c | 2 +- agent/divert-scd.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++------ agent/findkey.c | 2 +- agent/genkey.c | 8 ++--- agent/query.c | 18 ++++++---- scd/app-openpgp.c | 4 +-- 10 files changed, 121 insertions(+), 35 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/TODO b/TODO index fe10e9f77..74763a71f 100644 --- a/TODO +++ b/TODO @@ -96,11 +96,3 @@ might want to have an agent context for each service request -* IMPORTANT: - Check that the PIN cache is cleared after failed card operations. - After receiving a HUP gpg-agent should set a flag to kill scdaemon - as soon as possible, w/o that scdaemon will continue running as a - zombie and gpg-agent won't be able to fire up a new one. - Implement an scd/agent option to wait for a card. - - diff --git a/agent/ChangeLog b/agent/ChangeLog index 6c271c8e2..dcf0cdfd3 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,12 @@ +2005-05-24 Werner Koch + + * call-scd.c (inq_needpin): Skip leading spaces in of PIN + description. + * divert-scd.c (getpin_cb): Enhanced to cope with description + flags. + * query.c (agent_askpin): Add arg PROMPT_TEXT. Changed all + callers. + 2005-05-21 Werner Koch * call-scd.c (start_scd): Don't test for an alive scdaemon here. diff --git a/agent/agent.h b/agent/agent.h index 7e4f555e8..e416914cf 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -179,7 +179,8 @@ int agent_key_available (const unsigned char *grip); /*-- query.c --*/ void initialize_module_query (void); int agent_askpin (ctrl_t ctrl, - const char *desc_text, const char *inital_errtext, + const char *desc_text, const char *prompt_text, + const char *inital_errtext, struct pin_entry_info_s *pininfo); int agent_get_passphrase (ctrl_t ctrl, char **retpass, const char *desc, const char *prompt, diff --git a/agent/call-scd.c b/agent/call-scd.c index 617ef0d48..78e28fe97 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -601,6 +601,8 @@ inq_needpin (void *opaque, const char *line) return ASSUAN_Inquire_Unknown; } line += 7; + while (*line == ' ') + line++; pinlen = 90; pin = gcry_malloc_secure (pinlen); diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 92a84c662..030cc70a0 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2369,7 +2369,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) } pi->max_length = 100; pi->max_tries = 1; - err = agent_askpin (ctrl, description, NULL, pi); + err = agent_askpin (ctrl, description, NULL, NULL, pi); if (err) goto out; diff --git a/agent/divert-scd.c b/agent/divert-scd.c index f460ffe0c..41a5dfcda 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -168,35 +168,113 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, buf has been allocated by the caller and is of size MAXBUF which includes the terminating null. The function should return an UTF-8 string with the passphrase, the buffer may optionally be padded - with arbitrary characters */ + with arbitrary characters. + + INFO gets displayed as part of a generic string. However if the + first character of INFO is a vertical bar all up to the next + verical bar are considered flags and only everything after the + second vertical bar gets displayed as the full prompt. + + Flags: + + 'N' = New PIN, this requests a second prompt to repeat the the + PIN. If the PIN is not correctly repeated it starts from + all over. + 'A' = The PIN is an Admin PIN, SO-PIN, PUK or alike. + + Example: + + "|AN|Please enter the new security officer's PIN" + + The text "Please ..." will get displayed and the flags 'A' and 'N' + are considered. + */ static int getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) { struct pin_entry_info_s *pi; int rc; - char *desc; - CTRL ctrl = opaque; + ctrl_t ctrl = opaque; + const char *ends, *s; + int any_flags = 0; + int newpin = 0; + const char *again_text = NULL; + const char *prompt = "PIN"; if (maxbuf < 2) return gpg_error (GPG_ERR_INV_VALUE); + /* Parse the flags. */ + if (info && *info =='|' && (ends=strchr (info+1, '|'))) + { + for (s=info+1; s < ends; s++) + { + if (*s == 'A') + prompt = _("Admin PIN"); + else if (*s == 'N') + newpin = 1; + } + info = ends+1; + any_flags = 1; + } + else if (info && *info == '|') + log_debug ("pin_cb called without proper PIN info hack\n"); + /* FIXME: keep PI and TRIES in OPAQUE. Frankly this is a whole mess because we should call the card's verify function from the pinentry check pin CB. */ - pi = gcry_calloc_secure (1, sizeof (*pi) + 100); + again: + pi = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10); + if (!pi) + return gpg_error_from_errno (errno); pi->max_length = maxbuf-1; pi->min_digits = 0; /* we want a real passphrase */ pi->max_digits = 8; pi->max_tries = 3; - if ( asprintf (&desc, _("Please enter the PIN%s%s%s to unlock the card"), - info? " (`":"", - info? info:"", - info? "')":"") < 0) - desc = NULL; - rc = agent_askpin (ctrl, desc?desc:info, NULL, pi); - free (desc); + if (any_flags) + { + rc = agent_askpin (ctrl, info, prompt, again_text, pi); + again_text = NULL; + if (!rc && newpin) + { + struct pin_entry_info_s *pi2; + pi2 = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10); + if (!pi2) + { + rc = gpg_error_from_errno (errno); + xfree (pi); + return rc; + } + pi2->max_length = maxbuf-1; + pi2->min_digits = 0; + pi2->max_digits = 8; + pi2->max_tries = 1; + rc = agent_askpin (ctrl, _("Repeat this PIN"), prompt, NULL, pi2); + if (!rc && strcmp (pi->pin, pi2->pin)) + { + again_text = N_("PIN not correctly repeated; try again"); + xfree (pi2); + xfree (pi); + goto again; + } + xfree (pi2); + } + } + else + { + char *desc; + if ( asprintf (&desc, + _("Please enter the PIN%s%s%s to unlock the card"), + info? " (`":"", + info? info:"", + info? "')":"") < 0) + desc = NULL; + rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi); + free (desc); + } + if (!rc) { strncpy (buf, pi->pin, maxbuf-1); diff --git a/agent/findkey.c b/agent/findkey.c index 0b5816bf5..999a5d620 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -276,7 +276,7 @@ unprotect (CTRL ctrl, const char *desc_text, arg.unprotected_key = NULL; pi->check_cb_arg = &arg; - rc = agent_askpin (ctrl, desc_text, NULL, pi); + rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi); if (!rc) { assert (arg.unprotected_key); diff --git a/agent/genkey.c b/agent/genkey.c index 17d85f77c..e07518d5a 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -120,11 +120,11 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen, pi2->check_cb_arg = pi->pin; next_try: - rc = agent_askpin (ctrl, text1, initial_errtext, pi); + rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi); initial_errtext = NULL; if (!rc) { - rc = agent_askpin (ctrl, text2, NULL, pi2); + rc = agent_askpin (ctrl, text2, NULL, NULL, pi2); if (rc == -1) { /* The re-entered one did not match and the user did not hit cancel. */ @@ -228,10 +228,10 @@ agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey) pi2->check_cb_arg = pi->pin; next_try: - rc = agent_askpin (ctrl, text1, initial_errtext, pi); + rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi); if (!rc) { - rc = agent_askpin (ctrl, text2, NULL, pi2); + rc = agent_askpin (ctrl, text2, NULL, NULL, pi2); if (rc == -1) { /* The re-entered one did not match and the user did not hit cancel. */ diff --git a/agent/query.c b/agent/query.c index 622a2662c..d3b42a416 100644 --- a/agent/query.c +++ b/agent/query.c @@ -288,8 +288,9 @@ all_digitsp( const char *s) number here and repeat it as long as we have invalid formed numbers. */ int -agent_askpin (CTRL ctrl, - const char *desc_text, const char *initial_errtext, +agent_askpin (ctrl_t ctrl, + const char *desc_text, const char *prompt_text, + const char *initial_errtext, struct pin_entry_info_s *pininfo) { int rc; @@ -310,7 +311,10 @@ agent_askpin (CTRL ctrl, desc_text = _("Please enter your passphrase, so that the secret key " "can be unlocked for this session"); - is_pin = desc_text && strstr (desc_text, "PIN"); + if (prompt_text) + is_pin = !!strstr (prompt_text, "PIN"); + else + is_pin = desc_text && strstr (desc_text, "PIN"); rc = start_pinentry (ctrl); if (rc) @@ -322,10 +326,10 @@ agent_askpin (CTRL ctrl, if (rc) return unlock_pinentry (map_assuan_err (rc)); - rc = assuan_transact (entry_ctx, - is_pin? "SETPROMPT PIN:" - : "SETPROMPT Passphrase:", - NULL, NULL, NULL, NULL, NULL, NULL); + snprintf (line, DIM(line)-1, "SETPROMPT %s", + prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:"); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); if (rc) return unlock_pinentry (map_assuan_err (rc)); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 91e208a0a..14483869b 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1528,7 +1528,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, /* Check whether a key already exists. KEYIDX is the index of the key - (0..2). If FORCE is TRUE a diagnositivc will be printed but no + (0..2). If FORCE is TRUE a diagnositic will be printed but no error returned if the key already exists. */ static gpg_error_t does_key_exist (app_t app, int keyidx, int force) @@ -2134,7 +2134,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, { char *prompt; -#define PROMPTSTRING _("PIN [sigs done: %lu]") +#define PROMPTSTRING _("||Please enter the PIN%%0A[sigs done: %lu]") prompt = malloc (strlen (PROMPTSTRING) + 50); if (!prompt) -- cgit From 33701641829798ddd7fced64cf9a504cc5f48cc1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 7 Jun 2005 19:09:18 +0000 Subject: New debugging optionhs, updates to the manual. --- NEWS | 5 +- agent/ChangeLog | 21 ++ agent/agent.h | 49 +++-- agent/cache.c | 36 +++- agent/call-scd.c | 30 +-- agent/command-ssh.c | 5 +- agent/command.c | 21 +- agent/findkey.c | 24 +-- agent/gpg-agent.c | 6 + agent/pkdecrypt.c | 3 +- agent/pksign.c | 18 +- agent/query.c | 30 ++- common/sysutils.c | 2 +- doc/ChangeLog | 4 + doc/Makefile.am | 24 ++- doc/debugging.texi | 44 +++++ doc/gnupg-card-architecture.fig | 419 ++++++++++++++++++++++++++++++++++++++++ doc/gnupg.texi | 19 +- doc/gpg-agent.texi | 47 ++++- doc/scdaemon.texi | 8 + scd/ChangeLog | 4 + scd/command.c | 3 +- scd/scdaemon.c | 18 ++ 23 files changed, 759 insertions(+), 81 deletions(-) create mode 100644 doc/gnupg-card-architecture.fig (limited to 'agent/command-ssh.c') diff --git a/NEWS b/NEWS index e28f1284a..daa18c4c0 100644 --- a/NEWS +++ b/NEWS @@ -13,9 +13,12 @@ Noteworthy changes in version 1.9.17 does allows only signing using TCOS cards but we are going to enhance it to match all the old capabilities. - * [gpg-agent] New option --rite-env-file and Assuan command + * [gpg-agent] New option --write-env-file and Assuan command UPDATESTARTUPTTY. + * [gpg-agent] New option --default-cache-ttl-ssh to set the TTL for + SSH passphrase caching independent from the other passphrases. + Noteworthy changes in version 1.9.16 (2005-04-21) ------------------------------------------------- diff --git a/agent/ChangeLog b/agent/ChangeLog index 9621e5de0..1a157fa52 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,24 @@ +2005-06-06 Werner Koch + + * gpg-agent.c: New option --default-cache-ttl-ssh. + * agent.h (cache_mode_t): New. + * pksign.c (agent_pksign_do): New arg CACHE_MODE to replace the + ARG IGNORE_CACHE. Changed all callers. + (agent_pksign): Ditto. + * findkey.c (agent_key_from_file): Ditto. Canged all callers. + (unprotect): Ditto. + * command-ssh.c (data_sign): Use CACHE_MODE_SSH. + * cache.c (agent_get_cache): New arg CACHE_MODE. + (agent_put_cache): Ditto. Store it in the cache. + + * query.c (agent_query_dump_state, dump_mutex_state): New. + (unlock_pinentry): Reset the global context before releasing the + mutex. + * gpg-agent.c (handle_signal): Dump query.c info on SIGUSR1. + + * call-scd.c (agent_scd_check_aliveness): Always do a waitpid and + add a timeout to the locking. + 2005-06-03 Werner Koch * command.c (cmd_updatestartuptty): New. diff --git a/agent/agent.h b/agent/agent.h index 51e66abee..350e5c0d2 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -69,9 +69,13 @@ struct { smartcard tasks. */ int disable_scdaemon; /* Never use the SCdaemon. */ int no_grab; /* Don't let the pinentry grab the keyboard */ - unsigned long def_cache_ttl; + + /* The default and maximum TTL of cache entries. */ + unsigned long def_cache_ttl; /* Normal. */ + unsigned long def_cache_ttl_ssh; /* SSH. */ unsigned long max_cache_ttl; + int running_detached; /* We are running detached from the tty. */ int ignore_cache_for_signing; @@ -147,12 +151,26 @@ struct pin_entry_info_s { }; -enum { - PRIVATE_KEY_UNKNOWN = 0, - PRIVATE_KEY_CLEAR = 1, - PRIVATE_KEY_PROTECTED = 2, - PRIVATE_KEY_SHADOWED = 3 -}; +enum + { + PRIVATE_KEY_UNKNOWN = 0, + PRIVATE_KEY_CLEAR = 1, + PRIVATE_KEY_PROTECTED = 2, + PRIVATE_KEY_SHADOWED = 3 + }; + + +/* Values for the cache_mode arguments. */ +typedef enum + { + CACHE_MODE_IGNORE = 0, /* Special mode to by pass the cache. */ + CACHE_MODE_ANY, /* Any mode except ignore matches. */ + CACHE_MODE_NORMAL, /* Normal cache (gpg-agent). */ + CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */ + CACHE_MODE_SSH /* SSH related cache. */ + } +cache_mode_t; + /*-- gpg-agent.c --*/ void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */ @@ -171,7 +189,8 @@ gpg_error_t agent_key_from_file (ctrl_t ctrl, const char *desc_text, const unsigned char *grip, unsigned char **shadow_info, - int ignore_cache, gcry_sexp_t *result); + cache_mode_t cache_mode, + gcry_sexp_t *result); gpg_error_t agent_public_key_from_file (ctrl_t ctrl, const unsigned char *grip, gcry_sexp_t *result); @@ -179,6 +198,7 @@ int agent_key_available (const unsigned char *grip); /*-- query.c --*/ void initialize_module_query (void); +void agent_query_dump_state (void); int agent_askpin (ctrl_t ctrl, const char *desc_text, const char *prompt_text, const char *inital_errtext, @@ -191,16 +211,19 @@ int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok, /*-- cache.c --*/ void agent_flush_cache (void); -int agent_put_cache (const char *key, const char *data, int ttl); -const char *agent_get_cache (const char *key, void **cache_id); +int agent_put_cache (const char *key, cache_mode_t cache_mode, + const char *data, int ttl); +const char *agent_get_cache (const char *key, cache_mode_t cache_mode, + void **cache_id); void agent_unlock_cache_entry (void **cache_id); /*-- pksign.c --*/ -int agent_pksign_do (CTRL ctrl, const char *desc_text, - gcry_sexp_t *signature_sexp, int ignore_cache); +int agent_pksign_do (ctrl_t ctrl, const char *desc_text, + gcry_sexp_t *signature_sexp, + cache_mode_t cache_mode); int agent_pksign (ctrl_t ctrl, const char *desc_text, - membuf_t *outbuf, int ignore_cache); + membuf_t *outbuf, cache_mode_t cache_mode); /*-- pkdecrypt.c --*/ int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, diff --git a/agent/cache.c b/agent/cache.c index 18aa7653b..a032b4fa7 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -42,6 +42,7 @@ struct cache_item_s { int ttl; /* max. lifetime given in seconds, -1 one means infinite */ int lockcount; struct secret_data_s *pw; + cache_mode_t cache_mode; char key[1]; }; @@ -78,6 +79,7 @@ new_data (const void *data, size_t length) } + /* check whether there are items to expire */ static void housekeeping (void) @@ -85,7 +87,7 @@ housekeeping (void) ITEM r, rprev; time_t current = gnupg_get_time (); - /* first expire the actual data */ + /* First expire the actual data */ for (r=thecache; r; r = r->next) { if (!r->lockcount && r->pw @@ -100,7 +102,7 @@ housekeeping (void) } } - /* second, make sure that we also remove them based on the created stamp so + /* Second, make sure that we also remove them based on the created stamp so that the user has to enter it from time to time. We do this every hour */ for (r=thecache; r; r = r->next) { @@ -115,7 +117,7 @@ housekeeping (void) } } - /* third, make sure that we don't have too many items in the list. + /* Third, make sure that we don't have too many items in the list. Expire old and unused entries after 30 minutes */ for (rprev=NULL, r=thecache; r; ) { @@ -186,19 +188,27 @@ agent_flush_cache (void) with a maximum lifetime of TTL seconds. If there is already data under this key, it will be replaced. Using a DATA of NULL deletes the entry. A TTL of 0 is replaced by the default TTL and a TTL of - -1 set infinite timeout. */ + -1 set infinite timeout. CACHE_MODE is stored with the cache entry + and used t select different timeouts. */ int -agent_put_cache (const char *key, const char *data, int ttl) +agent_put_cache (const char *key, cache_mode_t cache_mode, + const char *data, int ttl) { ITEM r; if (DBG_CACHE) - log_debug ("agent_put_cache `%s' requested ttl=%d\n", key, ttl); + log_debug ("agent_put_cache `%s' requested ttl=%d mode=%d\n", + key, ttl, cache_mode); housekeeping (); if (!ttl) - ttl = opt.def_cache_ttl; - if (!ttl) + { + if (cache_mode == CACHE_MODE_SSH) + ttl = opt.def_cache_ttl_ssh; + else + ttl = opt.def_cache_ttl; + } + if (!ttl || cache_mode == CACHE_MODE_IGNORE) return 0; for (r=thecache; r; r = r->next) @@ -217,6 +227,7 @@ agent_put_cache (const char *key, const char *data, int ttl) { r->created = r->accessed = gnupg_get_time (); r->ttl = ttl; + r->cache_mode = cache_mode; r->pw = new_data (data, strlen (data)+1); if (!r->pw) log_error ("out of core while allocating new cache item\n"); @@ -232,6 +243,7 @@ agent_put_cache (const char *key, const char *data, int ttl) strcpy (r->key, key); r->created = r->accessed = gnupg_get_time (); r->ttl = ttl; + r->cache_mode = cache_mode; r->pw = new_data (data, strlen (data)+1); if (!r->pw) { @@ -249,12 +261,16 @@ agent_put_cache (const char *key, const char *data, int ttl) } -/* Try to find an item in the cache */ +/* Try to find an item in the cache. Note that we currently don't + make use of CACHE_MODE. */ const char * -agent_get_cache (const char *key, void **cache_id) +agent_get_cache (const char *key, cache_mode_t cache_mode, void **cache_id) { ITEM r; + if (cache_mode == CACHE_MODE_IGNORE) + return NULL; + if (DBG_CACHE) log_debug ("agent_get_cache `%s'...\n", key); housekeeping (); diff --git a/agent/call-scd.c b/agent/call-scd.c index 00c9df2a7..4dff8e3c1 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -372,25 +372,33 @@ start_scd (ctrl_t ctrl) void agent_scd_check_aliveness (void) { + pth_event_t evt; pid_t pid; int rc; - /* We can do so only if there is no more active primary connection. - With an active primary connection, this is all no problem because - with the end of gpg-agent's session a disconnect is send and the - this function will be used at a later time. */ - if (!primary_scd_ctx || !primary_scd_ctx_reusable) - return; + if (!primary_scd_ctx) + return; /* No scdaemon running. */ - if (!pth_mutex_acquire (&start_scd_lock, 0, NULL)) + /* This is not a critical function so we use a short timeout while + acquiring the lock. */ + evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0)); + if (!pth_mutex_acquire (&start_scd_lock, 0, evt)) { - log_error ("failed to acquire the start_scd lock while" - " doing an aliveness check: %s\n", - strerror (errno)); + if (pth_event_occurred (evt)) + { + if (opt.verbose > 1) + log_info ("failed to acquire the start_scd lock while" + " doing an aliveness check: %s\n", "timeout"); + } + else + log_error ("failed to acquire the start_scd lock while" + " doing an aliveness check: %s\n", strerror (errno)); + pth_event_free (evt, PTH_FREE_THIS); return; } + pth_event_free (evt, PTH_FREE_THIS); - if (primary_scd_ctx && primary_scd_ctx_reusable) + if (primary_scd_ctx) { pid = assuan_get_pid (primary_scd_ctx); if (pid != (pid_t)(-1) && pid diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 030cc70a0..870afe059 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2014,7 +2014,8 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, ctrl->use_auth_call = 1; err = agent_pksign_do (ctrl, _("Please enter the passphrase " - "for the ssh key%0A %c"), &signature_sexp, 0); + "for the ssh key%0A %c"), &signature_sexp, + CACHE_MODE_SSH); ctrl->use_auth_call = 0; if (err) goto out; @@ -2386,7 +2387,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) for (i = 0; i < 20; i++) sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]); - err = agent_put_cache (key_grip, pi->pin, ttl); + err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl); if (err) goto out; diff --git a/agent/command.c b/agent/command.c index 56167118d..ebf3a8220 100644 --- a/agent/command.c +++ b/agent/command.c @@ -404,19 +404,19 @@ static int cmd_pksign (ASSUAN_CONTEXT ctx, char *line) { int rc; - int ignore_cache = 0; + cache_mode_t cache_mode = CACHE_MODE_NORMAL; ctrl_t ctrl = assuan_get_pointer (ctx); membuf_t outbuf; - + if (opt.ignore_cache_for_signing) - ignore_cache = 1; + cache_mode = CACHE_MODE_IGNORE; else if (!ctrl->server_local->use_cache_for_signing) - ignore_cache = 1; + cache_mode = CACHE_MODE_IGNORE; init_membuf (&outbuf, 512); rc = agent_pksign (ctrl, ctrl->server_local->keydesc, - &outbuf, ignore_cache); + &outbuf, cache_mode); if (rc) clear_outbuf (&outbuf); else @@ -623,7 +623,8 @@ cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line) desc = NULL; /* Note: we store the hexified versions in the cache. */ - pw = cacheid ? agent_get_cache (cacheid, &cache_marker) : NULL; + pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker) + : NULL; if (pw) { assuan_begin_confidential (ctx); @@ -647,7 +648,7 @@ cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line) if (!rc) { if (cacheid) - agent_put_cache (cacheid, response, 0); + agent_put_cache (cacheid, CACHE_MODE_USER, response, 0); assuan_begin_confidential (ctx); rc = assuan_set_okay_line (ctx, response); xfree (response); @@ -682,7 +683,7 @@ cmd_clear_passphrase (ASSUAN_CONTEXT ctx, char *line) if (!cacheid || !*cacheid || strlen (cacheid) > 50) return set_error (Parameter_Error, "invalid length of cacheID"); - agent_put_cache (cacheid, NULL, 0); + agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0); return 0; } @@ -772,7 +773,7 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line) Assuan error code. */ rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc, - grip, &shadow_info, 1, &s_skey); + grip, &shadow_info, CACHE_MODE_IGNORE, &s_skey); if (rc) ; else if (!s_skey) @@ -842,7 +843,7 @@ cmd_preset_passphrase (ASSUAN_CONTEXT ctx, char *line) else return map_to_assuan_status (gpg_error (GPG_ERR_NOT_IMPLEMENTED)); - rc = agent_put_cache (grip_clear, passphrase, ttl); + rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl); if (rc) log_error ("command preset_passwd failed: %s\n", gpg_strerror (rc)); diff --git a/agent/findkey.c b/agent/findkey.c index 999a5d620..56433c9c4 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -230,8 +230,9 @@ modify_description (const char *in, const char *comment, char **result) caching mechanism. DESC_TEXT may be set to override the default description used for the pinentry. */ static int -unprotect (CTRL ctrl, const char *desc_text, - unsigned char **keybuf, const unsigned char *grip, int ignore_cache) +unprotect (ctrl_t ctrl, const char *desc_text, + unsigned char **keybuf, const unsigned char *grip, + cache_mode_t cache_mode) { struct pin_entry_info_s *pi; struct try_unprotect_arg_s arg; @@ -246,10 +247,12 @@ unprotect (CTRL ctrl, const char *desc_text, /* First try to get it from the cache - if there is none or we can't unprotect it, we fall back to ask the user */ - if (!ignore_cache) + if (cache_mode != CACHE_MODE_IGNORE) { void *cache_marker; - const char *pw = agent_get_cache (hexgrip, &cache_marker); + const char *pw; + + pw = agent_get_cache (hexgrip, cache_mode, &cache_marker); if (pw) { rc = agent_unprotect (*keybuf, pw, &result, &resultlen); @@ -280,7 +283,7 @@ unprotect (CTRL ctrl, const char *desc_text, if (!rc) { assert (arg.unprotected_key); - agent_put_cache (hexgrip, pi->pin, 0); + agent_put_cache (hexgrip, cache_mode, pi->pin, 0); xfree (*keybuf); *keybuf = arg.unprotected_key; } @@ -360,14 +363,13 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result) /* Return the secret key as an S-Exp in RESULT after locating it using the grip. Returns NULL in RESULT if the operation should be diverted to a token; SHADOW_INFO will point then to an allocated - S-Expression with the shadow_info part from the file. With - IGNORE_CACHE passed as true the passphrase is not taken from the - cache. DESC_TEXT may be set to present a custom description for the - pinentry. */ + S-Expression with the shadow_info part from the file. CACHE_MODE + defines now the cache shall be used. DESC_TEXT may be set to + present a custom description for the pinentry. */ gpg_error_t agent_key_from_file (ctrl_t ctrl, const char *desc_text, const unsigned char *grip, unsigned char **shadow_info, - int ignore_cache, gcry_sexp_t *result) + cache_mode_t cache_mode, gcry_sexp_t *result) { int rc; unsigned char *buf; @@ -447,7 +449,7 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text, if (!rc) { - rc = unprotect (ctrl, desc_text_final, &buf, grip, ignore_cache); + rc = unprotect (ctrl, desc_text_final, &buf, grip, cache_mode); if (rc) log_error ("failed to unprotect the secret key: %s\n", gpg_strerror (rc)); diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 90b071d5e..6cc08f845 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -83,6 +83,7 @@ enum cmd_and_opt_values oLCmessages, oScdaemonProgram, oDefCacheTTL, + oDefCacheTTLSSH, oMaxCacheTTL, oUseStandardSocket, oNoUseStandardSocket, @@ -140,6 +141,7 @@ static ARGPARSE_OPTS opts[] = { { oDefCacheTTL, "default-cache-ttl", 4, N_("|N|expire cached PINs after N seconds")}, + { oDefCacheTTLSSH, "default-cache-ttl-ssh", 4, "@" }, { oMaxCacheTTL, "max-cache-ttl", 4, "@" }, { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0, N_("do not use the PIN cache when signing")}, @@ -367,6 +369,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) opt.pinentry_program = NULL; opt.scdaemon_program = NULL; opt.def_cache_ttl = DEFAULT_CACHE_TTL; + opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL; opt.max_cache_ttl = MAX_CACHE_TTL; opt.ignore_cache_for_signing = 0; opt.allow_mark_trusted = 0; @@ -402,6 +405,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) case oDisableScdaemon: opt.disable_scdaemon = 1; break; case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break; + case oDefCacheTTLSSH: opt.def_cache_ttl_ssh = pargs->r.ret_ulong; break; case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break; case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break; @@ -413,6 +417,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) default: return 0; /* not handled */ } + return 1; /* handled */ } @@ -1339,6 +1344,7 @@ handle_signal (int signo) case SIGUSR1: log_info ("SIGUSR1 received - printing internal information:\n"); pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); + agent_query_dump_state (); agent_scd_dump_state (); break; diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 7a93e58f8..42ce69697 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -66,7 +66,8 @@ agent_pkdecrypt (CTRL ctrl, const char *desc_text, log_printhex ("cipher: ", ciphertext, ciphertextlen); } rc = agent_key_from_file (ctrl, desc_text, - ctrl->keygrip, &shadow_info, 0, &s_skey); + ctrl->keygrip, &shadow_info, + CACHE_MODE_NORMAL, &s_skey); if (rc) { log_error ("failed to read the secret key\n"); diff --git a/agent/pksign.c b/agent/pksign.c index 3337e188c..2a355e43e 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -79,8 +79,8 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash, /* SIGN whatever information we have accumulated in CTRL and return the signature S-Expression. */ int -agent_pksign_do (CTRL ctrl, const char *desc_text, - gcry_sexp_t *signature_sexp, int ignore_cache) +agent_pksign_do (ctrl_t ctrl, const char *desc_text, + gcry_sexp_t *signature_sexp, cache_mode_t cache_mode) { gcry_sexp_t s_skey = NULL, s_sig = NULL; unsigned char *shadow_info = NULL; @@ -90,16 +90,16 @@ agent_pksign_do (CTRL ctrl, const char *desc_text, return gpg_error (GPG_ERR_NO_SECKEY); rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip, - &shadow_info, ignore_cache, &s_skey); + &shadow_info, cache_mode, &s_skey); if (rc) { log_error ("failed to read the secret key\n"); goto leave; } - if (! s_skey) + if (!s_skey) { - /* divert operation to the smartcard */ + /* Divert operation to the smartcard */ unsigned char *buf = NULL; size_t len = 0; @@ -128,7 +128,7 @@ agent_pksign_do (CTRL ctrl, const char *desc_text, } else { - /* no smartcard, but a private key */ + /* No smartcard, but a private key */ gcry_sexp_t s_hash = NULL; @@ -176,15 +176,15 @@ agent_pksign_do (CTRL ctrl, const char *desc_text, /* SIGN whatever information we have accumulated in CTRL and write it back to OUTFP. */ int -agent_pksign (CTRL ctrl, const char *desc_text, - membuf_t *outbuf, int ignore_cache) +agent_pksign (ctrl_t ctrl, const char *desc_text, + membuf_t *outbuf, cache_mode_t cache_mode) { gcry_sexp_t s_sig = NULL; char *buf = NULL; size_t len = 0; int rc = 0; - rc = agent_pksign_do (ctrl, desc_text, &s_sig, ignore_cache); + rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode); if (rc) goto leave; diff --git a/agent/query.c b/agent/query.c index d3b42a416..c1e4dbacc 100644 --- a/agent/query.c +++ b/agent/query.c @@ -49,7 +49,7 @@ #define LOCK_TIMEOUT (1*60) -static ASSUAN_CONTEXT entry_ctx = NULL; +static assuan_context_t entry_ctx = NULL; #ifdef USE_GNU_PTH static pth_mutex_t entry_lock; #endif @@ -82,6 +82,30 @@ initialize_module_query (void) +static void +dump_mutex_state (pth_mutex_t *m) +{ + if (!(m->mx_state & PTH_MUTEX_INITIALIZED)) + log_printf ("not_initialized"); + else if (!(m->mx_state & PTH_MUTEX_LOCKED)) + log_printf ("not_locked"); + else + log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count); +} + + +/* This function may be called to print infromation pertaining to the + current state of this module to the log. */ +void +agent_query_dump_state (void) +{ + log_info ("agent_query_dump_state: entry_lock="); + dump_mutex_state (&entry_lock); + log_printf ("\n"); + log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld\n", + entry_ctx, (long)assuan_get_pid (entry_ctx)); +} + /* Unlock the pinentry so that another thread can start one and disconnect that pinentry - we do this after the unlock so that a @@ -90,8 +114,9 @@ initialize_module_query (void) static int unlock_pinentry (int rc) { - ASSUAN_CONTEXT ctx = entry_ctx; + assuan_context_t ctx = entry_ctx; + entry_ctx = NULL; #ifdef USE_GNU_PTH if (!pth_mutex_release (&entry_lock)) { @@ -100,7 +125,6 @@ unlock_pinentry (int rc) rc = gpg_error (GPG_ERR_INTERNAL); } #endif - entry_ctx = NULL; assuan_disconnect (ctx); return rc; } diff --git a/common/sysutils.c b/common/sysutils.c index 97fa23d95..a8f6f6f5d 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -105,7 +105,7 @@ enable_core_dumps (void) setrlimit (RLIMIT_CORE, &limit); return 1; /* We always return true because trhis function is merely a debugging aid. */ -#endif +# endif return 1; #endif } diff --git a/doc/ChangeLog b/doc/ChangeLog index f353bdf03..c4d263513 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,9 @@ 2005-06-03 Werner Koch + * debugging.texi (Architecture Details): New section, mostly empty. + * gnupg-card-architecture.fig: New. + * Makefile.am: Rules to build png and eps versions. + * gpg-agent.texi (Agent UPDATESTARTUPTTY): New. 2005-05-17 Werner Koch diff --git a/doc/Makefile.am b/doc/Makefile.am index 988bbf849..fdcd62dc0 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -18,14 +18,34 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = gnupg-badge-openpgp.eps gnupg-badge-openpgp.jpg +EXTRA_DIST = gnupg-badge-openpgp.eps gnupg-badge-openpgp.jpg \ + gnupg-card-architecture.eps gnupg-card-architecture.png + +BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png info_TEXINFOS = gnupg.texi + + gnupg_TEXINFOS = \ gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi assuan.texi \ tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \ - sysnotes.texi + sysnotes.texi gnupg-card-architecture.fig DISTCLEANFILES = gnupg.tmp gnupg.ops + + +.fig.png: + fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.jpg: + fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.eps: + fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.pdf: + fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@ + + diff --git a/doc/debugging.texi b/doc/debugging.texi index 49ab70bde..429dbd407 100644 --- a/doc/debugging.texi +++ b/doc/debugging.texi @@ -18,6 +18,7 @@ solve the problem at hand. @menu * Debugging Tools:: Description of some useful tools * Common Problems:: Commonly seen problems. +* Architecture Details:: How the whole thing works internally. @end menu @@ -105,6 +106,49 @@ shell). Even for GUI based Pinentries; you should have set on how to do it. +@item SSH hangs while a popping up pinentry was expected + +SSH has no way to tell the gpg-agent what terminal or X display it is +running on. So when remotely logging into a box where a gpg-agent with +SSH support is running, the pinentry will get popped up on whatever +display t he gpg-agent has been started. To solve this problem you may +issue the command + +@smallexample +echo UPDATESTARTUPTTY | gpg-connect-agent +@end smallexample + +and the next pinentry will pop up on your display or screen. However, +you need to kill the running pinentry first because only one pinentry +may be running at once. If you plan to use ssh on a new display you +should issue the above command before invoking ssh or any other service +making use of ssh. + @end itemize + +@c ******************************************** +@c *** Architecture Details ***************** +@c ******************************************** +@node Architecture Details +@section How the whole thing works internally. + + +@menu +* gpg 1.4 vs. 1.9:: Relationship between the two branches. +@end menu + +@node gpg 1.4 vs. 1.9 +@subsection Relationship between the two branches. + +Here is a little picture showing how the components work together: + +@image{gnupg-card-architecture, 14cm} + +@noindent +Lets try to explain it: + +TO BE DONE. + + diff --git a/doc/gnupg-card-architecture.fig b/doc/gnupg-card-architecture.fig new file mode 100644 index 000000000..e5772cd0f --- /dev/null +++ b/doc/gnupg-card-architecture.fig @@ -0,0 +1,419 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +# Copyright 2005 Werner Koch +# +# This file is part of GnuPG. +# +# GnuPG is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GnuPG 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +0 32 #414541 +0 33 #808080 +0 34 #c0c0c0 +0 35 #c6b797 +0 36 #eff8ff +0 37 #dccba6 +0 38 #e0e0e0 +0 39 #8e8f8e +0 40 #aaaaaa +0 41 #555555 +0 42 #404040 +0 43 #868286 +0 44 #c7c3c7 +0 45 #e7e3e7 +0 46 #8e8e8e +0 47 #444444 +0 48 #868686 +0 49 #c7c7c7 +0 50 #666666 +0 51 #e2e2ee +0 52 #94949a +0 53 #dbdbdb +0 54 #a1a1b7 +0 55 #9c0000 +0 56 #ededed +0 57 #86acff +0 58 #7070ff +0 59 #bebebe +0 60 #515151 +0 61 #000049 +0 62 #797979 +0 63 #303430 +0 64 #c7b696 +0 65 #d7d7d7 +0 66 #aeaeae +0 67 #85807d +0 68 #d2d2d2 +0 69 #3a3a3a +0 70 #4573aa +0 71 #000000 +0 72 #e7e7e7 +0 73 #f7f7f7 +0 74 #d6d7d6 +0 75 #7b79a5 +0 76 #effbff +0 77 #9e9e9e +0 78 #717571 +0 79 #73758c +0 80 #414141 +0 81 #635dce +0 82 #565151 +0 83 #dd9d93 +0 84 #f1ece0 +0 85 #c3c3c3 +0 86 #e2c8a8 +0 87 #e1e1e1 +0 88 #da7a1a +0 89 #f1e41a +0 90 #887dc2 +0 91 #d6d6d6 +0 92 #8c8ca5 +0 93 #4a4a4a +0 94 #8c6b6b +0 95 #5a5a5a +0 96 #636363 +0 97 #b79b73 +0 98 #4193ff +0 99 #bf703b +0 100 #db7700 +0 101 #dab800 +0 102 #006400 +0 103 #5a6b3b +0 104 #d3d3d3 +0 105 #8e8ea4 +0 106 #f3b95d +0 107 #89996b +0 108 #646464 +0 109 #b7e6ff +0 110 #86c0ec +0 111 #bdbdbd +0 112 #d39552 +0 113 #98d2fe +0 114 #8c9c6b +0 115 #f76b00 +0 116 #5a6b39 +0 117 #8c9c6b +0 118 #8c9c7b +0 119 #184a18 +0 120 #adadad +0 121 #f7bd5a +0 122 #636b9c +0 123 #de0000 +0 124 #adadad +0 125 #f7bd5a +0 126 #adadad +0 127 #f7bd5a +0 128 #636b9c +0 129 #526b29 +0 130 #949494 +0 131 #006300 +0 132 #00634a +0 133 #7b844a +0 134 #e7bd7b +0 135 #a5b5c6 +0 136 #6b6b94 +0 137 #846b6b +0 138 #529c4a +0 139 #d6e7e7 +0 140 #526363 +0 141 #186b4a +0 142 #9ca5b5 +0 143 #ff9400 +0 144 #ff9400 +0 145 #00634a +0 146 #7b844a +0 147 #63737b +0 148 #e7bd7b +0 149 #184a18 +0 150 #f7bd5a +0 151 #dedede +0 152 #f3eed3 +0 153 #f5ae5d +0 154 #95ce99 +0 155 #b5157d +0 156 #eeeeee +0 157 #848484 +0 158 #7b7b7b +0 159 #005a00 +0 160 #e77373 +0 161 #ffcb31 +0 162 #29794a +0 163 #de2821 +0 164 #2159c6 +0 165 #f8f8f8 +0 166 #e6e6e6 +0 167 #21845a +0 168 #ff9408 +0 169 #007000 +0 170 #d00000 +0 171 #fed600 +0 172 #d82010 +0 173 #003484 +0 174 #d62010 +0 175 #389000 +0 176 #ba0000 +0 177 #003380 +0 178 #00a7bd +0 179 #ffc500 +0 180 #087bd0 +0 181 #fbc100 +0 182 #840029 +0 183 #07399c +0 184 #0063bd +0 185 #39acdf +0 186 #42c0e0 +0 187 #31ceff +0 188 #ffde00 +0 189 #085a00 +0 190 #ff2100 +0 191 #f75e08 +0 192 #ef7b08 +0 193 #ff8200 +0 194 #007d00 +0 195 #0000be +0 196 #757575 +0 197 #f3f3f3 +0 198 #d7d3d7 +0 199 #aeaaae +0 200 #c2c2c2 +0 201 #303030 +0 202 #515551 +0 203 #f7f3f7 +0 204 #717171 +6 9270 1980 13230 6570 +6 9471 3906 13014 5677 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 10540 4394 10540 3936 9471 3936 9471 4394 10540 4394 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 10387 5616 10387 5158 9471 5158 9471 5616 10387 5616 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 12984 5005 12984 4547 9471 4547 9471 5005 12984 5005 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 12984 5616 12984 5158 12067 5158 12067 5616 12984 5616 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 11701 5627 11701 5168 10784 5168 10784 5627 11701 5627 +4 0 0 50 -1 16 11 0.0000 4 173 835 9623 4242 OpenPGP\001 +4 0 0 50 -1 16 11 0.0000 4 132 2770 9776 4853 APDU and ISO-7816 access code\001 +4 0 0 50 -1 16 11 0.0000 4 132 448 9623 5464 CCID\001 +4 0 0 50 -1 16 11 0.0000 4 132 601 12220 5464 CT-API\001 +4 0 0 50 -1 16 11 0.0000 4 132 560 10957 5464 PC/SC\001 +-6 +6 10693 3906 13014 4394 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 11762 4394 11762 3936 10693 3936 10693 4394 11762 4394 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 12984 4394 12984 3936 11915 3936 11915 4394 12984 4394 +4 0 0 50 -1 16 11 0.0000 4 132 377 10998 4242 NKS\001 +4 0 0 50 -1 16 11 0.0000 4 132 804 12067 4242 PKCS#15\001 +-6 +2 4 0 2 0 6 60 -1 20 0.000 0 0 5 0 0 5 + 13137 2072 9318 2072 9318 5739 13137 5739 13137 2072 +2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 + 9318 3753 13137 3753 +2 4 0 2 0 6 60 -1 20 0.000 0 0 5 0 0 5 + 11691 6360 10774 6360 10774 5901 11691 5901 11691 6360 +2 1 2 2 0 7 50 -1 -1 4.500 0 0 -1 0 0 1 + 11762 5739 +2 1 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 4 + 10693 5739 10693 6502 11762 6502 11762 5739 +4 0 0 50 -1 18 15 0.0000 4 183 1293 10540 2989 SCDaemon\001 +4 0 0 50 -1 16 11 0.0000 4 133 662 10896 6176 wrapper\001 +-6 +6 90 1980 4050 5760 +6 306 3906 3849 5677 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 1375 4394 1375 3936 306 3936 306 4394 1375 4394 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 1222 5616 1222 5158 306 5158 306 5616 1222 5616 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 3819 5005 3819 4547 306 4547 306 5005 3819 5005 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 3819 5616 3819 5158 2902 5158 2902 5616 3819 5616 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 5 0 0 5 + 2536 5627 2536 5168 1619 5168 1619 5627 2536 5627 +4 0 0 50 -1 16 11 0.0000 4 173 835 458 4242 OpenPGP\001 +4 0 0 50 -1 16 11 0.0000 4 132 2770 611 4853 APDU and ISO-7816 access code\001 +4 0 0 50 -1 16 11 0.0000 4 132 448 458 5464 CCID\001 +4 0 0 50 -1 16 11 0.0000 4 132 601 3055 5464 CT-API\001 +4 0 0 50 -1 16 11 0.0000 4 132 560 1792 5464 PC/SC\001 +-6 +6 2139 3753 3208 4211 +2 4 0 1 0 7 50 -1 -1 4.000 0 0 5 0 0 5 + 3208 4211 3208 3753 2139 3753 2139 4211 3208 4211 +4 0 0 50 -1 16 11 0.0000 4 132 784 2291 4058 Gluecode\001 +-6 +2 1 2 2 0 7 50 -1 -1 4.500 0 0 -1 0 0 1 + 2597 5739 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 40.73 81.47 + 2139 4028 1405 4150 +2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 4 + 153 3753 1833 3753 1833 4364 3972 4364 +2 4 0 2 0 6 60 -1 20 0.000 0 0 5 0 0 5 + 3972 2072 153 2072 153 5739 3972 5739 3972 2072 +4 0 0 50 -1 18 15 0.0000 4 224 866 1375 2989 gpg 1.4\001 +-6 +6 4888 4058 5346 5433 +2 4 0 1 0 7 50 -1 -1 4.000 0 0 5 0 0 5 + 5346 5433 5346 4058 4888 4058 4888 5433 5346 5433 +4 0 0 50 -1 16 11 1.5708 4 132 611 5194 5128 Assuan\001 +-6 +6 4680 1980 8640 5760 +2 4 0 1 0 7 50 -1 -1 4.000 0 0 5 0 0 5 + 5346 3753 5346 2378 4888 2378 4888 3753 5346 3753 +2 4 0 2 0 6 60 -1 20 0.000 0 0 5 0 0 5 + 8554 5739 4735 5739 4735 2072 8554 2072 8554 5739 +4 0 0 50 -1 16 11 1.5708 4 173 804 5194 3447 ssh-agent\001 +-6 +6 5805 3447 7332 4975 +6 5957 3447 7179 4211 +2 4 0 1 0 7 50 -1 -1 4.000 0 0 5 0 0 5 + 7179 4211 7179 3447 5957 3447 5957 4211 7179 4211 +4 0 0 50 -1 16 11 0.0000 4 173 937 6110 3753 Private Key\001 +4 0 0 50 -1 16 11 0.0000 4 173 896 6110 4058 Operations\001 +-6 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 1 + 7195 4883 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 1 + 7195 4883 +2 4 0 1 0 7 50 -1 -1 4.000 0 0 5 0 0 5 + 7332 4975 7332 4517 6721 4517 6721 4975 7332 4975 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 1 1 1.00 40.73 81.47 + 1 1 1.00 40.73 81.47 + 6568 4211 7027 4517 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 1 1 1.00 40.73 81.47 + 1 1 1.00 40.73 81.47 + 6568 4211 6110 4517 +2 4 0 1 0 7 50 -1 -1 4.000 0 0 5 0 0 5 + 6416 4975 6416 4517 5805 4517 5805 4975 6416 4975 +4 0 0 50 -1 16 11 0.0000 4 132 397 6874 4822 Card\001 +4 0 0 50 -1 16 11 0.0000 4 132 356 5957 4822 Disk\001 +-6 +6 7638 3600 8401 4058 +2 4 0 1 0 7 50 -1 -1 4.000 0 0 5 0 0 5 + 8401 4058 8401 3600 7638 3600 7638 4058 8401 4058 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 1 + 7638 3814 +4 0 0 50 -1 16 11 0.0000 4 132 530 7790 3905 Cache\001 +-6 +6 9471 2225 9929 3600 +2 4 0 1 0 7 50 -1 -1 4.000 0 0 5 0 0 5 + 9929 3600 9929 2225 9471 2225 9471 3600 9929 3600 +4 0 0 50 -1 16 11 1.5708 4 132 611 9776 3294 Assuan\001 +-6 +6 6480 360 8640 1440 +2 4 0 2 0 6 60 -1 20 0.000 0 0 5 0 0 5 + 8554 1339 6568 1339 6568 423 8554 423 8554 1339 +4 0 0 50 -1 18 15 0.0000 4 234 967 7027 881 pinentry\001 +4 0 0 50 -1 16 10 0.0000 4 153 1375 6874 1187 (GTK+, Qt, Curses)\001 +-6 +6 10570 270 13137 1003 +2 1 1 1 1 2 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 40.73 81.47 + 10632 331 11181 331 +2 1 0 2 1 2 50 -1 -1 6.000 0 0 -1 1 0 2 + 1 1 2.00 81.47 162.94 + 10632 637 11181 637 +2 1 0 1 0 2 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 40.73 81.47 + 10632 942 11181 942 +4 0 0 50 -1 16 10 0.0000 4 163 1762 11365 392 Alternative access paths\001 +4 0 0 50 -1 16 10 0.0000 4 163 1426 11365 698 IPC (pipe or socket)\001 +4 0 0 50 -1 16 10 0.0000 4 122 1232 11365 1003 Internal data flow\001 +-6 +# Smartcard ID-1 +6 6840 6120 8550 7200 +6 7069 6526 7307 6746 +2 1 0 1 0 7 48 -1 -1 0.000 0 0 -1 0 0 2 + 7234 6691 7307 6691 +2 1 0 1 0 0 48 -1 20 0.000 0 0 -1 0 0 2 + 7069 6636 7143 6636 +2 1 0 1 0 7 48 -1 -1 0.000 0 0 -1 0 0 2 + 7069 6581 7143 6581 +2 1 0 1 0 7 48 -1 -1 0.000 0 0 -1 0 0 2 + 7069 6691 7143 6691 +2 1 0 1 0 7 48 -1 -1 0.000 0 0 -1 0 0 2 + 7143 6526 7143 6746 +2 1 0 1 0 7 48 -1 -1 0.000 0 0 -1 0 0 3 + 7307 6581 7234 6581 7234 6746 +2 1 0 1 0 7 48 -1 -1 0.000 0 0 -1 0 0 2 + 7234 6636 7307 6636 +2 4 0 1 0 31 49 -1 20 0.000 0 0 1 0 0 5 + 7069 6526 7307 6526 7307 6746 7069 6746 7069 6526 +-6 +2 4 0 1 -1 7 50 -1 20 0.000 0 0 1 0 0 5 + 8472 7185 6904 7185 6904 6197 8472 6197 8472 7185 +-6 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 40.73 81.47 + 5346 3142 5957 3753 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 40.73 81.47 + 5346 4669 5957 3905 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 1 1 1.00 40.73 81.47 + 1 1 1.00 40.73 81.47 + 7179 3814 7638 3814 +2 4 0 2 0 6 60 -1 20 0.000 0 0 5 0 0 5 + 11731 7480 10693 7480 10693 6991 11731 6991 11731 7480 +3 2 0 2 1 2 50 -1 -1 6.000 0 1 0 3 + 1 1 2.00 81.47 162.94 + 8022 3600 8096 2225 7513 1360 + 0.000 -1.000 0.000 +3 2 0 2 1 2 50 -1 -1 0.000 0 1 0 3 + 0 0 2.00 81.47 162.94 + 7332 4730 8737 4486 9471 2897 + 0.000 -1.000 0.000 +3 2 0 2 1 2 50 -1 -1 6.000 0 1 0 3 + 1 1 2.00 81.47 162.94 + 3238 3997 4216 4242 4888 4730 + 0.000 -1.000 0.000 +3 2 0 2 1 2 50 -1 -1 6.000 0 1 0 3 + 1 1 2.00 81.47 162.94 + 11243 6502 11304 6747 11181 6991 + 0.000 -1.000 0.000 +3 2 1 1 1 2 50 -1 -1 4.000 0 1 0 3 + 1 1 1.00 40.73 81.47 + 10693 7235 9471 7174 8493 6869 + 0.000 -1.000 0.000 +3 2 1 1 1 2 50 -1 -1 4.000 0 1 0 3 + 1 1 1.00 40.73 81.47 + 9898 5647 9532 6380 8493 6563 + 0.000 -1.000 0.000 +3 2 1 1 1 2 50 -1 -1 4.000 0 1 0 3 + 1 1 1.00 40.73 81.47 + 12465 5647 11731 6624 8493 6747 + 0.000 -1.000 0.000 +3 2 1 1 1 2 50 -1 -1 4.000 0 1 0 3 + 1 1 1.00 40.73 81.47 + 2077 5647 3177 6502 6843 6624 + 0.000 -1.000 0.000 +3 2 1 1 1 2 50 -1 -1 4.000 0 1 0 3 + 1 1 1.00 40.73 81.47 + 733 5647 2444 6808 6843 6747 + 0.000 -1.000 0.000 +3 2 1 1 1 2 50 -1 -1 4.000 0 1 0 3 + 1 1 1.00 40.73 81.47 + 3361 5647 4155 6319 6843 6502 + 0.000 -1.000 0.000 +4 0 0 50 -1 18 15 0.0000 4 214 1191 5957 2989 gpg-agent\001 +4 0 0 50 -1 16 11 0.0000 4 173 387 10998 7297 pcsd\001 diff --git a/doc/gnupg.texi b/doc/gnupg.texi index 4c30980b3..d92f01cd9 100644 --- a/doc/gnupg.texi +++ b/doc/gnupg.texi @@ -86,14 +86,15 @@ section entitled ``Copying''. @insertcopying @end titlepage - +@ifnothtml @summarycontents @contents @page +@end ifnothtml @ifnottex @node Top -@top The GNU Privacy Guard +@top @insertcopying This manual documents how to use the GNU Privacy Guard system as well as @@ -120,6 +121,20 @@ the administration and the architecture. * Index:: Index of concepts and symbol names. @end menu +@ifhtml + +@center @image{gnupg-badge-openpgp,6cm,,The GnuPG Logo} + +@end ifhtml + + +@ifhtml +@page +@summarycontents +@contents +@end ifhtml + + @include gpg.texi @include gpgsm.texi @include gpg-agent.texi diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 5e8c19468..bad6639e2 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -42,7 +42,8 @@ else fi @end smallexample -The new option @option{--write-env-file} may be used instead. +@noindent +Note that the new option @option{--write-env-file} may be used instead. @noindent @@ -289,6 +290,11 @@ control this behaviour but this command line option takes precedence. Set the time a cache entry is valid to @var{n} seconds. The default are 600 seconds. +@item --default-cache-ttl-ssh @var{n} +@opindex default-cache-ttl +Set the time a cache entry used for SSH keys is valid to @var{n} +seconds. The default are 600 seconds. + @item --max-cache-ttl @var{n} @opindex max-cache-ttl Set the maximum time a cache entry is valid to @var{n} seconds. After @@ -506,12 +512,13 @@ are still pending, a shutdown is forced. @cpindex SIGINT Shuts down the process immediately. - @item SIGUSR1 -@itemx SIGUSR2 @cpindex SIGUSR1 +Dump internal information to the log file. + +@item SIGUSR2 @cpindex SIGUSR2 -These signals are used for internal purposes. +This signal is used for internal purposes. @end table @@ -523,12 +530,44 @@ These signals are used for internal purposes. @c man begin EXAMPLES +The usual way to invoke @command{gpg-agent} is + @example $ eval `gpg-agent --daemon` @end example @c man end +An alternative way is by replacing @command{ssh-agent} with +@command{gpg-agent}. If for example @command{ssh-agent} is started as +part of the Xsession intialization you may simply replace +@command{ssh-agent} by a script like: + +@cartouche +@example +#!/bin/sh + +exec /usr/local/bin/gpg-agent --enable-ssh-support --daemon \ + --write-env-file $@{HOME@}/.gpg-agent-info "$@@" +@end example +@end cartouche + +@noindent +and add something like (for Bourne shells) + +@cartouche +@example + if [ -f "$@{HOME@}/.gpg-agent-info" ]; then + . "$@{HOME@}/.gpg-agent-info" + export GPG_AGENT_INFO + export SSH_AUTH_SOCK + export SSH_AGENT_PID + fi +@end example +@end cartouche + +@noindent +to your shell initialization file (e.g. @file{~/.bashrc}). @c @c Assuan Protocol diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 134ca40df..d4a21b5ce 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -181,6 +181,14 @@ protocol. Note that this option may reveal sensitive data. This option disables all ticker functions like checking for card insertions. +@item --debug-allow-core-dump +@opindex debug-allow-core-dump +For security reasons we won't create a core dump when the process +aborts. For debugging purposes it is sometimes better to allow core +dump. This options enables it and also changes the working directory to +@file{/tmp} when running in @option{--server} mode. + + @item --no-detach @opindex no-detach Don't detach the process from the console. This is manly usefule for diff --git a/scd/ChangeLog b/scd/ChangeLog index da433e2f8..0f7e4d2fa 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,7 @@ +2005-06-06 Werner Koch + + * scdaemon.c (main): New option --debug-allow-core-dump. + 2005-06-03 Werner Koch * scdaemon.c (handle_connections): Make sure that the signals we diff --git a/scd/command.c b/scd/command.c index 287f8c921..a308078d3 100644 --- a/scd/command.c +++ b/scd/command.c @@ -70,7 +70,7 @@ struct server_local_s { struct server_local_s *next_session; /* This object is usually assigned to a CTRL object (which is - globally visible). While enumeratin all sessions we sometimes + globally visible). While enumerating all sessions we sometimes need to access data of the CTRL object; thus we keep a backpointer here. */ ctrl_t ctrl_backlink; @@ -860,6 +860,7 @@ cmd_getattr (assuan_context_t ctx, char *line) /* FIXME: Applications should not return sensistive data if the card is locked. */ rc = app_getattr (ctrl->app_ctx, ctrl, keyword); + xfree (keyword); TEST_CARD_REMOVAL (ctrl, rc); return map_to_assuan_status (rc); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 5b5e09176..c75e87a62 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -67,6 +67,7 @@ enum cmd_and_opt_values oDebugAll, oDebugLevel, oDebugWait, + oDebugAllowCoreDump, oDebugCCIDDriver, oNoGreeting, oNoOptions, @@ -110,6 +111,7 @@ static ARGPARSE_OPTS opts[] = { { oDebugAll, "debug-all" ,0, "@"}, { oDebugLevel, "debug-level" ,2, "@"}, { oDebugWait,"debug-wait",1, "@"}, + { oDebugAllowCoreDump, "debug-allow-core-dump", 0, "@" }, { oDebugCCIDDriver, "debug-ccid-driver", 0, "@"}, { oDebugDisableTicker, "debug-disable-ticker", 0, "@"}, { oNoDetach, "no-detach" ,0, N_("do not detach from the console")}, @@ -318,6 +320,7 @@ main (int argc, char **argv ) int debug_wait = 0; int gpgconf_list = 0; const char *config_filename = NULL; + int allow_coredump = 0; set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); @@ -448,6 +451,10 @@ main (int argc, char **argv ) case oDebugAll: opt.debug = ~0; break; case oDebugLevel: debug_level = pargs.r.ret_str; break; case oDebugWait: debug_wait = pargs.r.ret_int; break; + case oDebugAllowCoreDump: + enable_core_dumps (); + allow_coredump = 1; + break; case oDebugCCIDDriver: ccid_set_debug_level (ccid_set_debug_level (-1)+1); break; @@ -604,6 +611,17 @@ main (int argc, char **argv ) sigaction (SIGPIPE, &sa, NULL); } + /* If --debug-allow-core-dump has been given we also need to + switch the working directory to a place where we can actually + write. */ + if (allow_coredump) + { + if (chdir("/tmp")) + log_debug ("chdir to `/tmp' failed: %s\n", strerror (errno)); + else + log_debug ("changed working directory to `/tmp'\n"); + } + /* In multi server mode we need to listen on an additional socket. Create that socket now before starting the handler for the pipe connection. This allows that handler to send -- cgit From deeba405a9a5868ea478db5003be6335ab9aac6f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 Jun 2005 08:12:03 +0000 Subject: gcc-4 defaults forced me to edit many many files to get rid of the char * vs. unsigned char * warnings. The GNU coding standards used to say that these mismatches are okay and better than a bunch of casts. Obviously this has changed now. --- agent/ChangeLog | 46 ++++++++++++++++++++++ agent/agent.h | 15 ++++---- agent/cache.c | 20 +++++++--- agent/call-scd.c | 19 ++++------ agent/command-ssh.c | 75 ++++++++++++++++-------------------- agent/command.c | 4 +- agent/divert-scd.c | 9 +++-- agent/findkey.c | 4 +- agent/genkey.c | 2 +- agent/gpg-agent.c | 11 ++++-- agent/minip12.c | 2 + agent/pkdecrypt.c | 2 +- agent/pksign.c | 2 +- agent/protect-tool.c | 21 +++++----- agent/protect.c | 29 ++++++++------ agent/query.c | 9 +++-- common/ChangeLog | 26 ++++++++++++- common/estream.c | 21 +++++----- common/estream.h | 8 ++-- common/iobuf.c | 19 ++++++---- common/iobuf.h | 4 +- common/miscellaneous.c | 2 +- common/sexputil.c | 9 +++-- common/simple-pwquery.c | 2 +- common/ttyio.c | 2 +- common/util.h | 2 +- doc/gpg-agent.texi | 8 +++- g10/ChangeLog | 5 +++ g10/g10.c | 4 +- g10/misc.c | 5 ++- jnlib/ChangeLog | 13 +++++++ jnlib/argparse.c | 2 +- jnlib/logging.c | 5 ++- jnlib/stringhelp.c | 97 ++++++++++++++++++++++++++++------------------- jnlib/stringhelp.h | 9 ++--- jnlib/utf8conv.c | 21 +++++----- kbx/ChangeLog | 11 ++++++ kbx/kbxutil.c | 2 +- kbx/keybox-blob.c | 45 ++++++++++++---------- kbx/keybox-defs.h | 5 ++- kbx/keybox-file.c | 4 +- scd/apdu.c | 2 +- scd/app-help.c | 2 +- scd/app-openpgp.c | 27 ++++++------- scd/app-p15.c | 28 +++++++------- scd/app.c | 2 +- scd/ccid-driver.c | 14 +++---- scd/command.c | 10 ++--- scd/iso7816.c | 18 +++++---- scd/pcsc-wrapper.c | 4 +- sm/ChangeLog | 32 ++++++++++++++++ sm/base64.c | 14 ++++--- sm/call-agent.c | 25 ++++++------ sm/certcheck.c | 14 ++++--- sm/certdump.c | 28 +++++++------- sm/certreqgen.c | 9 +++-- sm/delete.c | 4 +- sm/encrypt.c | 12 +++--- sm/fingerprint.c | 17 +++++---- sm/gpgsm.h | 10 ++--- sm/keydb.c | 9 +++-- sm/keylist.c | 4 +- sm/server.c | 4 +- sm/sign.c | 2 +- tools/ChangeLog | 5 +++ tools/gpg-connect-agent.c | 2 +- tools/gpgconf-comp.c | 2 +- tools/gpgkey2ssh.c | 3 ++ tools/watchgnupg.c | 2 +- 69 files changed, 558 insertions(+), 348 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 1a157fa52..055dbe53e 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,49 @@ +2005-06-16 Werner Koch + + * protect-tool.c (make_advanced): Makde RESULT a plain char. + * call-scd.c (unescape_status_string): Need to cast unsigned char* + for strcpy. + (agent_card_pksign): Made arg R_BUF an unsigned char**. + * divert-scd.c (divert_pksign): Made SIGVAL unsigned char*. + (encode_md_for_card): Initialize R_VAL and R_LEN. + * genkey.c (store_key): Made BUF unsigned. + * protect.c (do_encryption): Ditto. + (do_encryption): Made arg PROTBEGIN unsigned. Initialize RESULT + and RESULTLEN even on error. + (merge_lists): Need to cast unsigned char * for strcpy. Initialize + RESULTand RESULTLEN even on error. + (agent_unprotect): Likewise for strtoul. + (make_shadow_info): Made P and INFO plain char. + (agent_shadow_key): Made P plain char. + +2005-06-15 Werner Koch + + * query.c (agent_get_passphrase): Made HEXSTRING a char*. + * command-ssh.c (ssh_key_grip): Made arg BUFFER unsigned. + (ssh_key_grip): Simplified. + (data_sign): Initialize variables with the definition. + (ssh_convert_key_to_blob): Make sure that BLOB and BLOB_SIZE + are set to NULL on error. Cool, gcc-4 detects uninitialized stuff + beyond function boundaries; well it can't know that we do error + proper error handling so that this was not a real error. + (file_to_buffer): Likewise for BUFFER and BUFFER_N. + (data_sign): Likewise for SIG and SIG_N. + (stream_read_byte): Set B to a value even on error. + * command.c (cmd_genkey): Changed VALUE to char. + (cmd_readkey): Cast arg for gcry_sexp_sprint. + * agent.h (struct server_control_s): Made KEYGRIP unsigned. + +2005-06-13 Werner Koch + + * command-ssh.c (start_command_handler_ssh): Reset the SCD. + +2005-06-09 Werner Koch + + * gpg-agent.c (create_socket_name): New option --max-cache-ttl-ssh. + * cache.c (housekeeping): Use it. + (agent_put_cache): Use a switch to get the default ttl so that it + is easier to add more cases. + 2005-06-06 Werner Koch * gpg-agent.c: New option --default-cache-ttl-ssh. diff --git a/agent/agent.h b/agent/agent.h index 350e5c0d2..7a646a85f 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -71,9 +71,10 @@ struct { int no_grab; /* Don't let the pinentry grab the keyboard */ /* The default and maximum TTL of cache entries. */ - unsigned long def_cache_ttl; /* Normal. */ - unsigned long def_cache_ttl_ssh; /* SSH. */ - unsigned long max_cache_ttl; + unsigned long def_cache_ttl; /* Default. */ + unsigned long def_cache_ttl_ssh; /* for SSH. */ + unsigned long max_cache_ttl; /* Default. */ + unsigned long max_cache_ttl_ssh; /* for SSH. */ int running_detached; /* We are running detached from the tty. */ @@ -107,8 +108,8 @@ struct server_local_s; struct scd_local_s; /* Collection of data per session (aka connection). */ -struct server_control_s { - +struct server_control_s +{ /* Private data of the server (command.c). */ struct server_local_s *server_local; @@ -128,7 +129,7 @@ struct server_control_s { int valuelen; int raw_value: 1; } digest; - char keygrip[20]; + unsigned char keygrip[20]; int have_keygrip; int use_auth_call; /* Hack to send the PKAUTH command instead of the @@ -289,7 +290,7 @@ int agent_card_pksign (ctrl_t ctrl, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen); + unsigned char **r_buf, size_t *r_buflen); int agent_card_pkdecrypt (ctrl_t ctrl, const char *keyid, int (*getpin_cb)(void *, const char *, char*,size_t), diff --git a/agent/cache.c b/agent/cache.c index a032b4fa7..32b6ac0c7 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -103,10 +103,17 @@ housekeeping (void) } /* Second, make sure that we also remove them based on the created stamp so - that the user has to enter it from time to time. We do this every hour */ + that the user has to enter it from time to time. */ for (r=thecache; r; r = r->next) { - if (!r->lockcount && r->pw && r->created + opt.max_cache_ttl < current) + unsigned long maxttl; + + switch (r->cache_mode) + { + case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break; + default: maxttl = opt.max_cache_ttl; break; + } + if (!r->lockcount && r->pw && r->created + maxttl < current) { if (DBG_CACHE) log_debug (" expired `%s' (%lus after creation)\n", @@ -203,10 +210,11 @@ agent_put_cache (const char *key, cache_mode_t cache_mode, if (!ttl) { - if (cache_mode == CACHE_MODE_SSH) - ttl = opt.def_cache_ttl_ssh; - else - ttl = opt.def_cache_ttl; + switch(cache_mode) + { + case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break; + default: ttl = opt.def_cache_ttl; break; + } } if (!ttl || cache_mode == CACHE_MODE_IGNORE) return 0; diff --git a/agent/call-scd.c b/agent/call-scd.c index 4dff8e3c1..7a623fda4 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -465,7 +465,7 @@ unescape_status_string (const unsigned char *s) { char *buffer, *d; - buffer = d = xtrymalloc (strlen (s)+1); + buffer = d = xtrymalloc (strlen ((const char*)s)+1); if (!buffer) return NULL; while (*s) @@ -666,7 +666,7 @@ agent_card_pksign (ctrl_t ctrl, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen) + unsigned char **r_buf, size_t *r_buflen) { int rc, i; char *p, line[ASSUAN_LINELENGTH]; @@ -714,14 +714,11 @@ agent_card_pksign (ctrl_t ctrl, /* Create an S-expression from it which is formatted like this: "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */ *r_buflen = 21 + 11 + sigbuflen + 4; - *r_buf = xtrymalloc (*r_buflen); - if (!*r_buf) - { - gpg_error_t tmperr = out_of_core (); - xfree (*r_buf); - return unlock_scd (ctrl, tmperr); - } - p = stpcpy (*r_buf, "(7:sig-val(3:rsa(1:s" ); + p = xtrymalloc (*r_buflen); + *r_buf = (unsigned char*)p; + if (!p) + return unlock_scd (ctrl, out_of_core ()); + p = stpcpy (p, "(7:sig-val(3:rsa(1:s" ); sprintf (p, "%u:", (unsigned int)sigbuflen); p += strlen (p); memcpy (p, sigbuf, sigbuflen); @@ -895,7 +892,7 @@ card_getattr_cb (void *opaque, const char *line) if (keywordlen == parm->keywordlen && !memcmp (keyword, parm->keyword, keywordlen)) { - parm->data = unescape_status_string (line); + parm->data = unescape_status_string ((const unsigned char*)line); if (!parm->data) parm->error = errno; } diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 870afe059..a43fee24f 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -297,6 +297,7 @@ stream_read_byte (estream_t stream, unsigned char *b) err = gpg_error_from_errno (errno); else err = gpg_error (GPG_ERR_EOF); + *b = 0; } else { @@ -604,6 +605,9 @@ file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) gpg_error_t err; int ret; + *buffer = NULL; + *buffer_n = 0; + buffer_new = NULL; err = 0; @@ -1381,6 +1385,9 @@ ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, gpg_error_t err; unsigned int i; + *blob = NULL; + *blob_size = 0; + blob_new = NULL; stream = NULL; err = 0; @@ -1535,20 +1542,12 @@ ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size, S-Expression KEY and writes it to BUFFER, which must be large enough to hold it. Returns usual error code. */ static gpg_error_t -ssh_key_grip (gcry_sexp_t key, char *buffer) +ssh_key_grip (gcry_sexp_t key, unsigned char *buffer) { - gpg_error_t err; - char *p; + if (!gcry_pk_get_keygrip (key, buffer)) + return gpg_error (GPG_ERR_INTERNAL); - /* FIXME: unsigned vs. signed. */ - - p = gcry_pk_get_keygrip (key, buffer); - if (! p) - err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ - else - err = 0; - - return err; + return 0; } /* Converts the secret key KEY_SECRET into a public key, storing it in @@ -1654,7 +1653,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) } pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL); - err = gcry_sexp_sscan (&s_pk, NULL, pkbuf, pkbuflen); + err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen); if (err) { log_error ("failed to build S-Exp from received card key: %s\n", @@ -1877,7 +1876,7 @@ ssh_handler_request_identities (ctrl_t ctrl, if (err) goto out; - err = gcry_sexp_sscan (&key_secret, NULL, buffer, buffer_n); + err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n); if (err) goto out; @@ -1984,14 +1983,14 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, unsigned char **sig, size_t *sig_n) { gpg_error_t err; - gcry_sexp_t signature_sexp; - estream_t stream; - gcry_sexp_t valuelist; - gcry_sexp_t sublist; - gcry_mpi_t sig_value; - unsigned char *sig_blob; - size_t sig_blob_n; - char *identifier; + gcry_sexp_t signature_sexp = NULL; + estream_t stream = NULL; + gcry_sexp_t valuelist = NULL; + gcry_sexp_t sublist = NULL; + gcry_mpi_t sig_value = NULL; + unsigned char *sig_blob = NULL;; + size_t sig_blob_n = 0; + char *identifier = NULL; const char *identifier_raw; size_t identifier_n; ssh_key_type_spec_t spec; @@ -1999,17 +1998,10 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, unsigned int i; const char *elems; size_t elems_n; - gcry_mpi_t *mpis; + gcry_mpi_t *mpis = NULL; - signature_sexp = NULL; - identifier = NULL; - valuelist = NULL; - sublist = NULL; - sig_blob = NULL; - sig_blob_n = 0; - stream = NULL; - sig_value = NULL; - mpis = NULL; + *sig = NULL; + *sig_n = 0; ctrl->use_auth_call = 1; err = agent_pksign_do (ctrl, @@ -2119,7 +2111,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, if (err) goto out; - *sig = (char *) sig_blob; + *sig = sig_blob; *sig_n = sig_blob_n; out: @@ -2684,7 +2676,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) secure memory, since we never give out secret keys. FIXME: This is a pretty good DoS. We only have a limited amount - of secure memory, we can't trhow hin everything we get from a + of secure memory, we can't throw in everything we get from a client -wk */ /* Retrieve request. */ @@ -2824,7 +2816,6 @@ start_command_handler_ssh (int sock_client) struct server_control_s ctrl; estream_t stream_sock; gpg_error_t err; - int bad; int ret; /* Setup control structure. */ @@ -2868,15 +2859,15 @@ start_command_handler_ssh (int sock_client) goto out; } - while (1) - { - bad = ssh_request_process (&ctrl, stream_sock); - if (bad) - break; - }; + /* Main processing loop. */ + while ( !ssh_request_process (&ctrl, stream_sock) ) + ; - out: + /* Reset the SCD in case it has been used. */ + agent_reset_scd (&ctrl); + + out: if (stream_sock) es_fclose (stream_sock); diff --git a/agent/command.c b/agent/command.c index ebf3a8220..c39bcc6ab 100644 --- a/agent/command.c +++ b/agent/command.c @@ -168,7 +168,7 @@ parse_keygrip (ASSUAN_CONTEXT ctx, const char *string, unsigned char *buf) if (n != 20) return set_error (Parameter_Error, "invalid length of keygrip"); - for (p=string, n=0; n < 20; p += 2, n++) + for (p=(const unsigned char*)string, n=0; n < 20; p += 2, n++) buf[n] = xtoi_2 (p); return 0; @@ -494,7 +494,7 @@ cmd_genkey (ASSUAN_CONTEXT ctx, char *line) init_membuf (&outbuf, 512); - rc = agent_genkey (ctrl, value, valuelen, &outbuf); + rc = agent_genkey (ctrl, (char*)value, valuelen, &outbuf); xfree (value); if (rc) clear_outbuf (&outbuf); diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 41a5dfcda..9d2fa446c 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -139,10 +139,13 @@ static int encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, unsigned char **r_val, size_t *r_len) { - byte *frame; - byte asn[100]; + unsigned char *frame; + unsigned char asn[100]; size_t asnlen; + *r_val = NULL; + *r_len = 0; + asnlen = DIM(asn); if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) { @@ -295,7 +298,7 @@ divert_pksign (CTRL ctrl, int rc; char *kid; size_t siglen; - char *sigval; + unsigned char *sigval; unsigned char *data; size_t ndata; diff --git a/agent/findkey.c b/agent/findkey.c index 56433c9c4..1cb7efaf3 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -345,7 +345,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result) } /* Convert the file into a gcrypt S-expression object. */ - rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen); + rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); xfree (fname); fclose (fp); xfree (buf); @@ -500,7 +500,7 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text, } buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL); - rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen); + rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); wipememory (buf, buflen); xfree (buf); if (rc) diff --git a/agent/genkey.c b/agent/genkey.c index e07518d5a..d0319f7b4 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -33,7 +33,7 @@ static int store_key (gcry_sexp_t private, const char *passphrase, int force) { int rc; - char *buf; + unsigned char *buf; size_t len; unsigned char grip[20]; diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 6cc08f845..8732c98d7 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -85,6 +85,7 @@ enum cmd_and_opt_values oDefCacheTTL, oDefCacheTTLSSH, oMaxCacheTTL, + oMaxCacheTTLSSH, oUseStandardSocket, oNoUseStandardSocket, @@ -143,6 +144,7 @@ static ARGPARSE_OPTS opts[] = { N_("|N|expire cached PINs after N seconds")}, { oDefCacheTTLSSH, "default-cache-ttl-ssh", 4, "@" }, { oMaxCacheTTL, "max-cache-ttl", 4, "@" }, + { oMaxCacheTTLSSH, "max-cache-ttl-ssh", 4, "@" }, { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0, N_("do not use the PIN cache when signing")}, { oAllowMarkTrusted, "allow-mark-trusted", 0, @@ -156,8 +158,9 @@ static ARGPARSE_OPTS opts[] = { }; -#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */ -#define MAX_CACHE_TTL (120*60) /* 2 hours */ +#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */ +#define DEFAULT_CACHE_TTL_SSH (30*60) /* 30 minutes */ +#define MAX_CACHE_TTL (120*60) /* 2 hours */ /* flag to indicate that a shutdown was requested */ @@ -369,8 +372,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) opt.pinentry_program = NULL; opt.scdaemon_program = NULL; opt.def_cache_ttl = DEFAULT_CACHE_TTL; - opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL; + opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL_SSH; opt.max_cache_ttl = MAX_CACHE_TTL; + opt.max_cache_ttl_ssh = MAX_CACHE_TTL; opt.ignore_cache_for_signing = 0; opt.allow_mark_trusted = 0; opt.disable_scdaemon = 0; @@ -407,6 +411,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break; case oDefCacheTTLSSH: opt.def_cache_ttl_ssh = pargs->r.ret_ulong; break; case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break; + case oMaxCacheTTLSSH: opt.max_cache_ttl_ssh = pargs->r.ret_ulong; break; case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break; diff --git a/agent/minip12.c b/agent/minip12.c index 5ca85033d..31be15373 100644 --- a/agent/minip12.c +++ b/agent/minip12.c @@ -1552,6 +1552,8 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen, struct buffer_s seqlist[2]; int seqlistidx = 0; + n = buflen = 0; /* (avoid compiler warning). */ + if (cert && certlen) { /* Encode the certificate. */ diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 42ce69697..1d64c1b15 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -52,7 +52,7 @@ agent_pkdecrypt (CTRL ctrl, const char *desc_text, goto leave; } - rc = gcry_sexp_sscan (&s_cipher, NULL, ciphertext, ciphertextlen); + rc = gcry_sexp_sscan (&s_cipher, NULL, (char*)ciphertext, ciphertextlen); if (rc) { log_error ("failed to convert ciphertext: %s\n", gpg_strerror (rc)); diff --git a/agent/pksign.c b/agent/pksign.c index 2a355e43e..e9df19351 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -117,7 +117,7 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text, len = gcry_sexp_canon_len (buf, 0, NULL, NULL); assert (len); - rc = gcry_sexp_sscan (&s_sig, NULL, buf, len); + rc = gcry_sexp_sscan (&s_sig, NULL, (char*)buf, len); xfree (buf); if (rc) { diff --git a/agent/protect-tool.c b/agent/protect-tool.c index e8f1d2c10..5f59d5e06 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -239,9 +239,9 @@ make_advanced (const unsigned char *buf, size_t buflen) int rc; size_t erroff, len; gcry_sexp_t sexp; - unsigned char *result; + char *result; - rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen); + rc = gcry_sexp_sscan (&sexp, &erroff, (const char*)buf, buflen); if (rc) { log_error ("invalid canonical S-Expression (off=%u): %s\n", @@ -378,7 +378,7 @@ read_and_protect (const char *fname) xfree (result); if (!p) return; - result = p; + result = (unsigned char*)p; resultlen = strlen (p); } @@ -417,7 +417,7 @@ read_and_unprotect (const char *fname) xfree (result); if (!p) return; - result = p; + result = (unsigned char*)p; resultlen = strlen (p); } @@ -434,12 +434,13 @@ read_and_shadow (const char *fname) unsigned char *key; unsigned char *result; size_t resultlen; + unsigned char dummy_info[] = "(8:313233342:43)"; key = read_key (fname); if (!key) return; - rc = agent_shadow_key (key, "(8:313233342:43)", &result); + rc = agent_shadow_key (key, dummy_info, &result); xfree (key); if (rc) { @@ -455,7 +456,7 @@ read_and_shadow (const char *fname) xfree (result); if (!p) return; - result = p; + result = (unsigned char*)p; resultlen = strlen (p); } @@ -682,7 +683,7 @@ import_p12_file (const char *fname) if (!buf) return; - kparms = p12_parse (buf, buflen, (pw=get_passphrase (2)), + kparms = p12_parse ((unsigned char*)buf, buflen, (pw=get_passphrase (2)), import_p12_cert_cb, NULL); release_passphrase (pw); xfree (buf); @@ -773,7 +774,7 @@ import_p12_file (const char *fname) xfree (result); if (!p) return; - result = p; + result = (unsigned char*)p; resultlen = strlen (p); } @@ -932,7 +933,7 @@ export_p12_file (const char *fname) if (opt_have_cert) { - cert = read_file ("-", &certlen); + cert = (unsigned char*)read_file ("-", &certlen); if (!cert) { wipememory (key, keylen_for_wipe); @@ -1040,7 +1041,7 @@ percent_plus_unescape (unsigned char *string) static char * percent_plus_unescape_string (char *string) { - unsigned char *p = string; + unsigned char *p = (unsigned char*)string; size_t n; n = percent_plus_unescape (p); diff --git a/agent/protect.c b/agent/protect.c index 658c8c529..45bdae496 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -134,19 +134,22 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) */ static int -do_encryption (const char *protbegin, size_t protlen, +do_encryption (const unsigned char *protbegin, size_t protlen, const char *passphrase, const unsigned char *sha1hash, unsigned char **result, size_t *resultlen) { gcry_cipher_hd_t hd; const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"; int blklen, enclen, outlen; - char *iv = NULL; + unsigned char *iv = NULL; int rc; char *outbuf = NULL; char *p; int saltpos, ivpos, encpos; + *resultlen = 0; + *result = NULL; + rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_SECURE); if (rc) @@ -250,7 +253,7 @@ do_encryption (const char *protbegin, size_t protlen, return tmperr; } *resultlen = strlen (p); - *result = p; + *result = (unsigned char*)p; memcpy (p+saltpos, iv+2*blklen, 8); memcpy (p+ivpos, iv, blklen); memcpy (p+encpos, outbuf, enclen); @@ -261,7 +264,7 @@ do_encryption (const char *protbegin, size_t protlen, -/* Protect the key encoded in canonical format in plainkey. We assume +/* Protect the key encoded in canonical format in PLAINKEY. We assume a valid S-Exp here. */ int agent_protect (const unsigned char *plainkey, const char *passphrase, @@ -469,6 +472,9 @@ merge_lists (const unsigned char *protectedkey, const unsigned char *startpos, *endpos; int i, rc; + *result = NULL; + *resultlen = 0; + if (replacepos < 26) return gpg_error (GPG_ERR_BUG); @@ -487,7 +493,7 @@ merge_lists (const unsigned char *protectedkey, return out_of_core (); /* Copy the initial segment */ - strcpy (newlist, "(11:private-key"); + strcpy ((char*)newlist, "(11:private-key"); p = newlist + 15; memcpy (p, protectedkey+15+10, replacepos-15-10); p += replacepos-15-10; @@ -669,7 +675,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, is nothing we should worry about */ if (s[n] != ')' ) return gpg_error (GPG_ERR_INV_SEXP); - s2kcount = strtoul (s, NULL, 10); + s2kcount = strtoul ((const char*)s, NULL, 10); if (!s2kcount) return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); s += n; @@ -838,7 +844,7 @@ unsigned char * make_shadow_info (const char *serialno, const char *idstring) { const char *s; - unsigned char *info, *p; + char *info, *p; char numbuf[21]; int n; @@ -853,13 +859,13 @@ make_shadow_info (const char *serialno, const char *idstring) sprintf (numbuf, "%d:", n); p = stpcpy (p, numbuf); for (s=serialno; *s && s[1]; s += 2) - *p++ = xtoi_2 (s); + *(unsigned char *)p++ = xtoi_2 (s); sprintf (numbuf, "%d:", strlen (idstring)); p = stpcpy (p, numbuf); p = stpcpy (p, idstring); *p++ = ')'; *p = 0; - return info; + return (unsigned char *)info; } @@ -878,7 +884,7 @@ agent_shadow_key (const unsigned char *pubkey, const unsigned char *point; size_t n; int depth = 0; - unsigned char *p; + char *p; size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL); size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL); @@ -930,7 +936,8 @@ agent_shadow_key (const unsigned char *pubkey, /* Calculate required length by taking in account: the "shadowed-" prefix, the "shadowed", "t1-v1" as well as some parenthesis */ n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1; - *result = p = xtrymalloc (n); + *result = xtrymalloc (n); + p = (char*)*result; if (!p) return out_of_core (); p = stpcpy (p, "(20:shadowed-private-key"); diff --git a/agent/query.c b/agent/query.c index c1e4dbacc..b231f6fc3 100644 --- a/agent/query.c +++ b/agent/query.c @@ -58,7 +58,7 @@ static pth_mutex_t entry_lock; struct entry_parm_s { int lines; size_t size; - char *buffer; + unsigned char *buffer; }; @@ -372,7 +372,7 @@ agent_askpin (ctrl_t ctrl, { memset (&parm, 0, sizeof parm); parm.size = pininfo->max_length; - parm.buffer = pininfo->pin; + parm.buffer = (unsigned char*)pininfo->pin; if (errtext) { @@ -444,7 +444,8 @@ agent_get_passphrase (CTRL ctrl, int rc; char line[ASSUAN_LINELENGTH]; struct entry_parm_s parm; - unsigned char *p, *hexstring; + unsigned char *p; + char *hexstring; int i; *retpass = NULL; @@ -497,7 +498,7 @@ agent_get_passphrase (CTRL ctrl, return unlock_pinentry (map_assuan_err (rc)); } - hexstring = gcry_malloc_secure (strlen (parm.buffer)*2+1); + hexstring = gcry_malloc_secure (strlen ((char*)parm.buffer)*2+1); if (!hexstring) { gpg_error_t tmperr = out_of_core (); diff --git a/common/ChangeLog b/common/ChangeLog index 08fb06775..e7905ea58 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,9 +1,33 @@ +2005-06-15 Werner Koch + + * miscellaneous.c (make_printable_string): Made P a void*. + + * sexputil.c (keygrip_from_canon_sexp, cmp_simple_canon_sexp): + Fixed signed/unsigned pointer mismatch. + (make_simple_sexp_from_hexstr): Ditto. This is all too ugly; I + wonder why gcc-4's default is to warn about them and forcing us to + use cast the warning away. + * iobuf.c (block_filter): Ditto. + (iobuf_flush): Ditto. + (iobuf_read_line): Ditto. + (iobuf_read): Make BUFFER a void *. + (iobuf_write): Make BUFFER a const void *. + * ttyio.c (tty_print_utf8_string2): Ditto. + * estream.c (estream_cookie_mem): Make MEMORY unsigned char*. + (es_write): Make BUFFER a void *. + (es_writen): Ditto. + (es_func_fd_read, es_func_fd_write, es_func_mem_read) + (es_func_mem_write): Ditto. + (es_read, es_readn): Ditto. + (es_func_mem_write): Made MEMORY_NEW an unsigned char *. + * estream.h (es_cookie_read_function_t) + (es_cookie_write_function_t): Changed buffer arg to void*. + 2005-06-03 Werner Koch * estream.c: Use HAVE_CONFIG_H and not USE_CONFIG_H! (es_func_fd_read, es_func_fd_write): Protect against EINTR. - 2005-06-01 Werner Koch * Makefile.am (AM_CPPFLAGS): Added. diff --git a/common/estream.c b/common/estream.c index bf5b02001..70b3d9c6e 100644 --- a/common/estream.c +++ b/common/estream.c @@ -294,7 +294,7 @@ es_init_do (void) typedef struct estream_cookie_mem { unsigned int flags; /* Open flags. */ - char *memory; /* Data. */ + unsigned char *memory; /* Data. */ size_t memory_size; /* Size of MEMORY. */ size_t offset; /* Current offset in MEMORY. */ size_t data_len; /* Length of data in MEMORY. */ @@ -350,7 +350,7 @@ es_func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie, /* Read function for memory objects. */ static ssize_t -es_func_mem_read (void *cookie, char *buffer, size_t size) +es_func_mem_read (void *cookie, void *buffer, size_t size) { estream_cookie_mem_t mem_cookie = cookie; ssize_t ret; @@ -371,11 +371,11 @@ es_func_mem_read (void *cookie, char *buffer, size_t size) /* Write function for memory objects. */ static ssize_t -es_func_mem_write (void *cookie, const char *buffer, size_t size) +es_func_mem_write (void *cookie, const void *buffer, size_t size) { estream_cookie_mem_t mem_cookie = cookie; func_realloc_t func_realloc = mem_cookie->func_realloc; - char *memory_new; + unsigned char *memory_new; size_t newsize; ssize_t ret; int err; @@ -591,7 +591,7 @@ es_func_fd_create (void **cookie, int fd, unsigned int flags) /* Read function for fd objects. */ static ssize_t -es_func_fd_read (void *cookie, char *buffer, size_t size) +es_func_fd_read (void *cookie, void *buffer, size_t size) { estream_cookie_fd_t file_cookie = cookie; @@ -606,7 +606,7 @@ es_func_fd_read (void *cookie, char *buffer, size_t size) /* Write function for fd objects. */ static ssize_t -es_func_fd_write (void *cookie, const char *buffer, size_t size) +es_func_fd_write (void *cookie, const void *buffer, size_t size) { estream_cookie_fd_t file_cookie = cookie; @@ -1122,9 +1122,10 @@ es_read_lbf (estream_t ES__RESTRICT stream, *the amount of bytes read in BYTES_READ. */ static int es_readn (estream_t ES__RESTRICT stream, - unsigned char *ES__RESTRICT buffer, + void *ES__RESTRICT buffer_arg, size_t bytes_to_read, size_t *ES__RESTRICT bytes_read) { + unsigned char *buffer = (unsigned char *)buffer_arg; size_t data_read_unread, data_read; int err; @@ -1388,7 +1389,7 @@ es_write_lbf (estream_t ES__RESTRICT stream, amount of bytes written in BYTES_WRITTEN. */ static int es_writen (estream_t ES__RESTRICT stream, - const unsigned char *ES__RESTRICT buffer, + const void *ES__RESTRICT buffer, size_t bytes_to_write, size_t *ES__RESTRICT bytes_written) { size_t data_written; @@ -2289,7 +2290,7 @@ es_ungetc (int c, estream_t stream) int es_read (estream_t ES__RESTRICT stream, - char *ES__RESTRICT buffer, size_t bytes_to_read, + void *ES__RESTRICT buffer, size_t bytes_to_read, size_t *ES__RESTRICT bytes_read) { int err; @@ -2309,7 +2310,7 @@ es_read (estream_t ES__RESTRICT stream, int es_write (estream_t ES__RESTRICT stream, - const char *ES__RESTRICT buffer, size_t bytes_to_write, + const void *ES__RESTRICT buffer, size_t bytes_to_write, size_t *ES__RESTRICT bytes_written) { int err; diff --git a/common/estream.h b/common/estream.h index c201b666a..ebe575926 100644 --- a/common/estream.h +++ b/common/estream.h @@ -72,9 +72,9 @@ typedef struct es__stream *estream_t; typedef ssize_t (*es_cookie_read_function_t) (void *cookie, - char *buffer, size_t size); + void *buffer, size_t size); typedef ssize_t (*es_cookie_write_function_t) (void *cookie, - const char *buffer, + const void *buffer, size_t size); typedef int (*es_cookie_seek_function_t) (void *cookie, off_t *pos, int whence); @@ -166,10 +166,10 @@ int _es_putc_overflow (int c, estream_t stream); int es_ungetc (int c, estream_t stream); int es_read (estream_t ES__RESTRICT stream, - char *ES__RESTRICT buffer, size_t bytes_to_read, + void *ES__RESTRICT buffer, size_t bytes_to_read, size_t *ES__RESTRICT bytes_read); int es_write (estream_t ES__RESTRICT stream, - const char *ES__RESTRICT buffer, size_t bytes_to_write, + const void *ES__RESTRICT buffer, size_t bytes_to_write, size_t *ES__RESTRICT bytes_written); size_t es_fread (void *ES__RESTRICT ptr, size_t size, size_t nitems, diff --git a/common/iobuf.c b/common/iobuf.c index 52a388514..32b9e18c6 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -675,10 +675,11 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, * without a filter */ static int -block_filter (void *opaque, int control, iobuf_t chain, byte * buf, +block_filter (void *opaque, int control, iobuf_t chain, byte * buffer, size_t * ret_len) { block_filter_ctx_t *a = opaque; + char *buf = (char *)buffer; size_t size = *ret_len; int c, needed, rc = 0; char *p; @@ -1762,7 +1763,7 @@ iobuf_flush (iobuf_t a) if (a->use == 3) { /* increase the temp buffer */ - char *newbuf; + unsigned char *newbuf; size_t newsize = a->d.size + 8192; if (DBG_IOBUF) @@ -1829,8 +1830,9 @@ iobuf_readbyte (iobuf_t a) int -iobuf_read (iobuf_t a, byte * buf, unsigned buflen) +iobuf_read (iobuf_t a, void *buffer, unsigned int buflen) { + unsigned char *buf = (unsigned char *)buffer; int c, n; if (a->unget.buf || a->nlimit) @@ -1915,7 +1917,7 @@ iobuf_peek (iobuf_t a, byte * buf, unsigned buflen) int -iobuf_writebyte (iobuf_t a, unsigned c) +iobuf_writebyte (iobuf_t a, unsigned int c) { int rc; @@ -1933,8 +1935,9 @@ iobuf_writebyte (iobuf_t a, unsigned c) int -iobuf_write (iobuf_t a, byte * buf, unsigned buflen) +iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen) { + const unsigned char *buf = (const unsigned char *)buffer; int rc; if (a->directfp) @@ -2311,7 +2314,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, unsigned *length_of_buffer, unsigned *max_length) { int c; - char *buffer = *addr_of_buffer; + char *buffer = (char *)*addr_of_buffer; unsigned length = *length_of_buffer; unsigned nbytes = 0; unsigned maxlen = *max_length; @@ -2321,7 +2324,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, { /* must allocate a new buffer */ length = 256; buffer = xmalloc (length); - *addr_of_buffer = buffer; + *addr_of_buffer = (unsigned char *)buffer; *length_of_buffer = length; } @@ -2344,7 +2347,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, length += 3; /* correct for the reserved byte */ length += length < 1024 ? 256 : 1024; buffer = xrealloc (buffer, length); - *addr_of_buffer = buffer; + *addr_of_buffer = (unsigned char *)buffer; *length_of_buffer = length; length -= 3; /* and reserve again */ p = buffer + nbytes; diff --git a/common/iobuf.h b/common/iobuf.h index 0af94e22d..b991717c2 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -120,12 +120,12 @@ off_t iobuf_tell (iobuf_t a); int iobuf_seek (iobuf_t a, off_t newpos); int iobuf_readbyte (iobuf_t a); -int iobuf_read (iobuf_t a, byte * buf, unsigned buflen); +int iobuf_read (iobuf_t a, void *buf, unsigned buflen); unsigned iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, unsigned *length_of_buffer, unsigned *max_length); int iobuf_peek (iobuf_t a, byte * buf, unsigned buflen); int iobuf_writebyte (iobuf_t a, unsigned c); -int iobuf_write (iobuf_t a, byte * buf, unsigned buflen); +int iobuf_write (iobuf_t a, const void *buf, unsigned buflen); int iobuf_writestr (iobuf_t a, const char *buf); void iobuf_flush_temp (iobuf_t temp); diff --git a/common/miscellaneous.c b/common/miscellaneous.c index 86b0fcb3a..d81213ef9 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -66,7 +66,7 @@ print_utf8_string( FILE *fp, const byte *p, size_t n ) } char * -make_printable_string( const byte *p, size_t n, int delim ) +make_printable_string (const void *p, size_t n, int delim ) { return sanitize_buffer (p, n, delim); } diff --git a/common/sexputil.c b/common/sexputil.c index 802916b44..8a27ad978 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -52,7 +52,7 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, if (!grip) return gpg_error (GPG_ERR_INV_VALUE); - err = gcry_sexp_sscan (&sexp, NULL, key, keylen); + err = gcry_sexp_sscan (&sexp, NULL, (const char *)key, keylen); if (err) return err; if (!gcry_pk_get_keygrip (sexp, grip)) @@ -66,8 +66,11 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, are identical or !0 if they are not. Not that this function can't be used for sorting. */ int -cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b) +cmp_simple_canon_sexp (const unsigned char *a_orig, + const unsigned char *b_orig) { + const char *a = (const char *)a_orig; + const char *b = (const char *)b_orig; unsigned long n1, n2; char *endp; @@ -124,7 +127,7 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned) buf = xtrymalloc (strlen (numbuf) + len + 1 + 1); if (!buf) return NULL; - p = stpcpy (buf, numbuf); + p = (unsigned char *)stpcpy ((char *)buf, numbuf); s = line; if ((n&1)) { diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index 8a027e799..de3689810 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -404,7 +404,7 @@ static char * copy_and_escape (char *buffer, const char *text) { int i; - const unsigned char *s = text; + const unsigned char *s = (unsigned char *)text; char *p = buffer; diff --git a/common/ttyio.c b/common/ttyio.c index eab805e20..5749c59fe 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -322,7 +322,7 @@ tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) break; } if( i < n ) { - buf = utf8_to_native( p, n, 0 ); + buf = utf8_to_native( (const char *)p, n, 0 ); if( max_n && (strlen( buf ) > max_n )) { buf[max_n] = 0; } diff --git a/common/util.h b/common/util.h index d233dbf5e..1ced59b67 100644 --- a/common/util.h +++ b/common/util.h @@ -153,7 +153,7 @@ const char *print_fname_stdin (const char *s); void print_string (FILE *fp, const byte *p, size_t n, int delim); void print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim); void print_utf8_string (FILE *fp, const byte *p, size_t n); -char *make_printable_string (const byte *p, size_t n, int delim); +char *make_printable_string (const void *p, size_t n, int delim); int is_file_compressed (const char *s, int *ret_rc); diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index bad6639e2..144745b4c 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -293,7 +293,7 @@ Set the time a cache entry is valid to @var{n} seconds. The default are @item --default-cache-ttl-ssh @var{n} @opindex default-cache-ttl Set the time a cache entry used for SSH keys is valid to @var{n} -seconds. The default are 600 seconds. +seconds. The default are 1800 seconds. @item --max-cache-ttl @var{n} @opindex max-cache-ttl @@ -301,6 +301,12 @@ Set the maximum time a cache entry is valid to @var{n} seconds. After this time a cache entry will get expired even if it has been accessed recently. The default are 2 hours (7200 seconds). +@item --max-cache-ttl-ssh @var{n} +@opindex max-cache-ttl-ssh +Set the maximum time a cache entry used for SSH keys is valid to @var{n} +seconds. After this time a cache entry will get expired even if it has +been accessed recently. The default are 2 hours (7200 seconds). + @item --pinentry-program @var{filename} @opindex pinentry-program Use program @var{filename} as the PIN entry. The default is installation diff --git a/g10/ChangeLog b/g10/ChangeLog index b33735e1f..0ae73b535 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2005-06-15 Werner Koch + + * g10.c (print_hashline, add_group): Fixes for signed/unsigned + pointer mismatch warnings. + 2005-06-01 Werner Koch * mkdtemp.c: Removed. diff --git a/g10/g10.c b/g10/g10.c index 0be5636a2..234d13f41 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -933,7 +933,7 @@ static void add_group(char *string) return; } - trim_trailing_ws(name,strlen(name)); + trim_trailing_ws((unsigned char *)name,strlen(name)); /* Break apart the values */ while ((value= strsep(&string," \t"))) @@ -3124,7 +3124,7 @@ print_hashline( MD_HANDLE md, int algo, const char *fname ) const byte *p; if ( fname ) { - for (p = fname; *p; p++ ) { + for (p = (const unsigned char *)fname; *p; p++ ) { if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' ) printf("%%%02X", *p ); else diff --git a/g10/misc.c b/g10/misc.c index 7012a8a25..516e80bcc 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -986,9 +986,10 @@ mpi_print( FILE *fp, gcry_mpi_t a, int mode ) } else { int rc; - unsigned char *buffer; + char *buffer; - rc = gcry_mpi_aprint( GCRYMPI_FMT_HEX, &buffer, NULL, a ); + rc = gcry_mpi_aprint( GCRYMPI_FMT_HEX, + &(unsigned char*)buffer, NULL, a ); assert( !rc ); fputs( buffer, fp ); n += strlen(buffer); diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index f308a7ea3..f0463c5b3 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,16 @@ +2005-06-15 Werner Koch + + * stringhelp.c (sanitize_buffer): Make P a void*. + (ascii_memistr, memistr): Ditto. + (ascii_memcasecmp): Ditto. + * logging.c (writen): Use void * for arg BUFFER. + * stringhelp.c (memistr): Fixed unsigned/signed pointer conflict. + (ascii_memistr): Ditto. + (ascii_memcasemem): Ditto. + * utf8conv.c (utf8_to_native): Ditto. + (utf8_to_native): Ditto. + * argparse.c (show_version): Removed non-required cast. + 2005-01-19 Werner Koch * logging.c (fun_writer): Don't fallback to stderr. Print to diff --git a/jnlib/argparse.c b/jnlib/argparse.c index 485c60786..980d1186c 100644 --- a/jnlib/argparse.c +++ b/jnlib/argparse.c @@ -852,7 +852,7 @@ show_version() /* additional program info */ for(i=30; i < 40; i++ ) if( (s=strusage(i)) ) - fputs( (const byte*)s, stdout); + fputs (s, stdout); fflush(stdout); } diff --git a/jnlib/logging.c b/jnlib/logging.c index 97a2b9c9e..c944006a5 100644 --- a/jnlib/logging.c +++ b/jnlib/logging.c @@ -87,10 +87,11 @@ struct fun_cookie_s { char name[1]; }; -/* Write NBYTES of BUF to file descriptor FD. */ +/* Write NBYTES of BUFFER to file descriptor FD. */ static int -writen (int fd, const unsigned char *buf, size_t nbytes) +writen (int fd, const void *buffer, size_t nbytes) { + const char *buf = buffer; size_t nleft = nbytes; int nwritten; diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c index 5a3b41528..760398b0c 100644 --- a/jnlib/stringhelp.c +++ b/jnlib/stringhelp.c @@ -1,6 +1,6 @@ /* stringhelp.c - standard string helper functions * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004 Free Software Foundation, Inc. + * 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -35,45 +35,57 @@ /* * Look for the substring SUB in buffer and return a pointer to that - * substring in BUF or NULL if not found. + * substring in BUFFER or NULL if not found. * Comparison is case-insensitive. */ const char * -memistr( const char *buf, size_t buflen, const char *sub ) +memistr (const void *buffer, size_t buflen, const char *sub) { - const byte *t, *s ; - size_t n; + const unsigned char *buf = buffer; + const unsigned char *t = (const unsigned char *)buffer; + const unsigned char *s = (const unsigned char *)sub; + size_t n = buflen; - for( t=buf, n=buflen, s=sub ; n ; t++, n-- ) - if( toupper(*t) == toupper(*s) ) { - for( buf=t++, buflen = n--, s++; - n && toupper(*t) == toupper(*s); t++, s++, n-- ) - ; - if( !*s ) - return buf; - t = buf; n = buflen; s = sub ; + for ( ; n ; t++, n-- ) + { + if ( toupper (*t) == toupper (*s) ) + { + for ( buf=t++, buflen = n--, s++; + n && toupper (*t) == toupper (*s); t++, s++, n-- ) + ; + if (!*s) + return (const char*)buf; + t = buf; + s = (const unsigned char *)sub ; + n = buflen; } - - return NULL ; + } + return NULL; } const char * -ascii_memistr( const char *buf, size_t buflen, const char *sub ) +ascii_memistr ( const void *buffer, size_t buflen, const char *sub ) { - const byte *t, *s ; - size_t n; + const unsigned char *buf = buffer; + const unsigned char *t = (const unsigned char *)buf; + const unsigned char *s = (const unsigned char *)sub; + size_t n = buflen; - for( t=buf, n=buflen, s=sub ; n ; t++, n-- ) - if( ascii_toupper(*t) == ascii_toupper(*s) ) { - for( buf=t++, buflen = n--, s++; - n && ascii_toupper(*t) == ascii_toupper(*s); t++, s++, n-- ) - ; - if( !*s ) - return buf; - t = buf; n = buflen; s = sub ; + for ( ; n ; t++, n-- ) + { + if (ascii_toupper (*t) == ascii_toupper (*s) ) + { + for ( buf=t++, buflen = n--, s++; + n && ascii_toupper (*t) == ascii_toupper (*s); t++, s++, n-- ) + ; + if (!*s) + return (const char*)buf; + t = (const unsigned char *)buf; + s = (const unsigned char *)sub ; + n = buflen; } - - return NULL ; + } + return NULL; } /* This function is similar to strncpy(). However it won't copy more @@ -402,13 +414,14 @@ print_sanitized_utf8_string (FILE *fp, const char *string, int delim) delim) : 0; } -/* Create a string from the buffer P of length N which is suitable for +/* Create a string from the buffer P_ARG of length N which is suitable for printing. Caller must release the created string using xfree. */ char * -sanitize_buffer (const unsigned char *p, size_t n, int delim) +sanitize_buffer (const void *p_arg, size_t n, int delim) { + const unsigned char *p = p_arg; size_t save_n, buflen; - const byte *save_p; + const unsigned char *save_p; char *buffer, *d; /* first count length */ @@ -552,15 +565,19 @@ ascii_strncasecmp (const char *a, const char *b, size_t n) int -ascii_memcasecmp( const char *a, const char *b, size_t n ) +ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n ) { - if (a == b) - return 0; - for ( ; n; n--, a++, b++ ) { - if( *a != *b && ascii_toupper (*a) != ascii_toupper (*b) ) - return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); - } + const char *a = a_arg; + const char *b = b_arg; + + if (a == b) return 0; + for ( ; n; n--, a++, b++ ) + { + if( *a != *b && ascii_toupper (*a) != ascii_toupper (*b) ) + return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); + } + return 0; } int @@ -586,8 +603,8 @@ ascii_memcasemem (const void *haystack, size_t nhaystack, return (void*)haystack; /* finding an empty needle is really easy */ if (nneedle <= nhaystack) { - const unsigned char *a = haystack; - const unsigned char *b = a + nhaystack - nneedle; + const char *a = haystack; + const char *b = a + nhaystack - nneedle; for (; a <= b; a++) { diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h index 412da3a0e..bdd7d561c 100644 --- a/jnlib/stringhelp.h +++ b/jnlib/stringhelp.h @@ -23,7 +23,7 @@ #include "types.h" -const char *memistr( const char *buf, size_t buflen, const char *sub ); +const char *memistr (const void *buf, size_t buflen, const char *sub); char *mem2str( char *, const void *, size_t); char *trim_spaces( char *string ); char *trim_trailing_spaces( char *string ); @@ -46,7 +46,7 @@ size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer, size_t length, int delim); size_t print_sanitized_string (FILE *fp, const char *string, int delim); size_t print_sanitized_utf8_string (FILE *fp, const char *string, int delim); -char *sanitize_buffer (const unsigned char *p, size_t n, int delim); +char *sanitize_buffer (const void *p, size_t n, int delim); #ifdef HAVE_W32_SYSTEM @@ -54,15 +54,14 @@ const char *w32_strerror (int ec); #endif -const char *ascii_memistr( const char *buf, size_t buflen, const char *sub ); int ascii_isupper (int c); int ascii_islower (int c); int ascii_toupper (int c); int ascii_tolower (int c); int ascii_strcasecmp( const char *a, const char *b ); int ascii_strncasecmp (const char *a, const char *b, size_t n); -int ascii_memcasecmp( const char *a, const char *b, size_t n ); -const char *ascii_memistr ( const char *buf, size_t buflen, const char *sub); +int ascii_memcasecmp( const void *a, const void *b, size_t n ); +const char *ascii_memistr ( const void *buf, size_t buflen, const char *sub); void *ascii_memcasemem (const void *haystack, size_t nhaystack, const void *needle, size_t nneedle); diff --git a/jnlib/utf8conv.c b/jnlib/utf8conv.c index 691176766..4df8b7b32 100644 --- a/jnlib/utf8conv.c +++ b/jnlib/utf8conv.c @@ -136,16 +136,17 @@ get_native_charset () * new allocated UTF8 string. */ char * -native_to_utf8 (const char *string) +native_to_utf8 (const char *orig_string) { - const byte *s; + const unsigned char *string = (const unsigned char *)orig_string; + const unsigned char *s; char *buffer; - byte *p; + unsigned char *p; size_t length = 0; if (no_translation) { - buffer = jnlib_xstrdup (string); + buffer = jnlib_xstrdup (orig_string); } else if (active_charset) { @@ -156,7 +157,7 @@ native_to_utf8 (const char *string) length += 2; /* we may need 3 bytes */ } buffer = jnlib_xmalloc (length + 1); - for (p = buffer, s = string; *s; s++) + for (p = (unsigned char *)buffer, s = string; *s; s++) { if ((*s & 0x80)) { @@ -187,7 +188,7 @@ native_to_utf8 (const char *string) length++; } buffer = jnlib_xmalloc (length + 1); - for (p = buffer, s = string; *s; s++) + for (p = (unsigned char *)buffer, s = string; *s; s++) { if (*s & 0x80) { @@ -212,11 +213,12 @@ utf8_to_native (const char *string, size_t length, int delim) { int nleft; int i; - byte encbuf[8]; + unsigned char encbuf[8]; int encidx; const byte *s; size_t n; - byte *buffer = NULL, *p = NULL; + char *buffer = NULL; + char *p = NULL; unsigned long val = 0; size_t slen; int resync = 0; @@ -225,7 +227,8 @@ utf8_to_native (const char *string, size_t length, int delim) /* 2. pass (p!=NULL): create string */ for (;;) { - for (slen = length, nleft = encidx = 0, n = 0, s = string; slen; + for (slen = length, nleft = encidx = 0, n = 0, + s = (const unsigned char *)string; slen; s++, slen--) { if (resync) diff --git a/kbx/ChangeLog b/kbx/ChangeLog index 7c112085c..4fd06d5ca 100644 --- a/kbx/ChangeLog +++ b/kbx/ChangeLog @@ -1,3 +1,14 @@ +2005-06-15 Werner Koch + + * keybox-file.c (_keybox_read_blob2): Make IMAGE unsigned. + (_keybox_write_blob): + + * keybox-blob.c (create_blob_finish, _keybox_create_x509_blob): + Fixed warnings about signed/unsigned pointer mismatches. + (x509_email_kludge): Ditto. + (_keybox_new_blob): Changed arg IMAGE to unsigned char *. + (_keybox_get_blob_image): Changed return type to unsigned char*. + 2005-06-01 Werner Koch * keybox-file.c (ftello) [!HAVE_FSEEKO]: New replacement diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 7fe6178d6..0569b5a67 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -386,7 +386,7 @@ import_openpgp (const char *filename) buffer = read_file (filename, &buflen); if (!buffer) return; - p = buffer; + p = (unsigned char *)buffer; for (;;) { err = _keybox_parse_openpgp (p, buflen, &nparsed, &info); diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 48bce28e2..67c74b777 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -646,8 +646,8 @@ static int create_blob_finish (KEYBOXBLOB blob) { struct membuf *a = blob->buf; - byte *p; - char *pp; + unsigned char *p; + unsigned char *pp; int i; size_t n; @@ -656,6 +656,7 @@ create_blob_finish (KEYBOXBLOB blob) put32 (a, 0); /* Hmmm: why put32() ?? */ /* get the memory area */ + n = 0; /* (Just to avoid compiler warning.) */ p = get_membuf (a, &n); if (!p) return gpg_error (GPG_ERR_ENOMEM); @@ -783,7 +784,7 @@ _keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral) static char * x509_email_kludge (const char *name) { - const unsigned char *p; + const char *p; unsigned char *buf; int n; @@ -805,7 +806,7 @@ x509_email_kludge (const char *name) buf[n] = xtoi_2 (p); buf[n++] = '>'; buf[n] = 0; - return buf; + return (char *)buf; } @@ -818,8 +819,9 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, { int i, rc = 0; KEYBOXBLOB blob; - unsigned char *p; - unsigned char **names = NULL; + unsigned char *sn; + char *p; + char **names = NULL; size_t max_names; *r_blob = NULL; @@ -827,28 +829,28 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, if( !blob ) return gpg_error (gpg_err_code_from_errno (errno)); - p = ksba_cert_get_serial (cert); - if (p) + sn = ksba_cert_get_serial (cert); + if (sn) { size_t n, len; - n = gcry_sexp_canon_len (p, 0, NULL, NULL); + n = gcry_sexp_canon_len (sn, 0, NULL, NULL); if (n < 2) { - xfree (p); + xfree (sn); return gpg_error (GPG_ERR_GENERAL); } - blob->serialbuf = p; - p++; n--; /* skip '(' */ - for (len=0; n && *p && *p != ':' && digitp (p); n--, p++) - len = len*10 + atoi_1 (p); - if (*p != ':') + blob->serialbuf = sn; + sn++; n--; /* skip '(' */ + for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++) + len = len*10 + atoi_1 (sn); + if (*sn != ':') { xfree (blob->serialbuf); blob->serialbuf = NULL; return gpg_error (GPG_ERR_GENERAL); } - p++; - blob->serial = p; + sn++; + blob->serial = sn; blob->seriallen = len; } @@ -863,6 +865,7 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, rc = gpg_error (gpg_err_code_from_errno (errno)); goto leave; } + p = ksba_cert_get_issuer (cert, 0); if (!p) { @@ -872,10 +875,9 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, names[blob->nuids++] = p; for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) { - if (blob->nuids >= max_names) { - unsigned char **tmp; + char **tmp; max_names += 100; tmp = xtryrealloc (names, max_names * sizeof *names); @@ -964,7 +966,8 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, int -_keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, off_t off) +_keybox_new_blob (KEYBOXBLOB *r_blob, + unsigned char *image, size_t imagelen, off_t off) { KEYBOXBLOB blob; @@ -1000,7 +1003,7 @@ _keybox_release_blob (KEYBOXBLOB blob) -const char * +const unsigned char * _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n ) { *n = blob->bloblen; diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index b58294459..7bbed8519 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -140,10 +140,11 @@ int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, unsigned char *sha1_digest, int as_ephemeral); #endif /*KEYBOX_WITH_X509*/ -int _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, +int _keybox_new_blob (KEYBOXBLOB *r_blob, + unsigned char *image, size_t imagelen, off_t off); void _keybox_release_blob (KEYBOXBLOB blob); -const char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n); +const unsigned char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n); off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob); void _keybox_update_header_blob (KEYBOXBLOB blob); diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c index fe02c1f9f..3883ce607 100644 --- a/kbx/keybox-file.c +++ b/kbx/keybox-file.c @@ -48,7 +48,7 @@ ftello (FILE *stream) int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted) { - char *image; + unsigned char *image; size_t imagelen = 0; int c1, c2, c3, c4, type; int rc; @@ -118,7 +118,7 @@ _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp) int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp) { - const char *image; + const unsigned char *image; size_t length; image = _keybox_get_blob_image (blob, &length); diff --git a/scd/apdu.c b/scd/apdu.c index 212b9df24..975fffa24 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2393,7 +2393,7 @@ apdu_activate (int slot) unsigned char * apdu_get_atr (int slot, size_t *atrlen) { - char *buf; + unsigned char *buf; if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return NULL; diff --git a/scd/app-help.c b/scd/app-help.c index 1c3c52b15..27cbea5c7 100644 --- a/scd/app-help.c +++ b/scd/app-help.c @@ -48,7 +48,7 @@ app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip) n = gcry_sexp_canon_len (p, 0, NULL, NULL); if (!n) return gpg_error (GPG_ERR_INV_SEXP); - err = gcry_sexp_sscan (&s_pkey, NULL, p, n); + err = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n); xfree (p); if (err) return err; /* Can't parse that S-expression. */ diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 1ff096138..11e6eebaf 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -948,8 +948,8 @@ get_public_key (app_t app, int keyno) size_t buflen, keydatalen, mlen, elen; unsigned char *mbuf = NULL; unsigned char *ebuf = NULL; - unsigned char *keybuf = NULL; - unsigned char *keybuf_p; + char *keybuf = NULL; + char *keybuf_p; if (keyno < 1 || keyno > 3) return gpg_error (GPG_ERR_INV_ID); @@ -963,14 +963,16 @@ get_public_key (app_t app, int keyno) app->app_local->pk[keyno].key = NULL; app->app_local->pk[keyno].keylen = 0; + m = e = NULL; /* (avoid cc warning) */ + if (app->card_version > 0x0100) { /* We may simply read the public key out of these cards. */ - err = iso7816_read_public_key (app->slot, - keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4", - 2, - &buffer, &buflen); + err = iso7816_read_public_key + (app->slot, (const unsigned char*)(keyno == 0? "\xB6" : + keyno == 1? "\xB8" : "\xA4"), + 2, + &buffer, &buflen); if (err) { log_error (_("reading public key failed: %s\n"), gpg_strerror (err)); @@ -1107,7 +1109,7 @@ get_public_key (app_t app, int keyno) strcpy (keybuf_p, ")))"); keybuf_p += strlen (keybuf_p); - app->app_local->pk[keyno].key = keybuf; + app->app_local->pk[keyno].key = (unsigned char*)keybuf; app->app_local->pk[keyno].keylen = (keybuf_p - keybuf); leave: @@ -1889,11 +1891,10 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, #warning key generation temporary replaced by reading an existing key. rc = iso7816_read_public_key #endif - (app->slot, - keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4", - 2, - &buffer, &buflen); + (app->slot, (const unsigned char*)(keyno == 0? "\xB6" : + keyno == 1? "\xB8" : "\xA4"), + 2, + &buffer, &buflen); if (rc) { rc = gpg_error (GPG_ERR_CARD); diff --git a/scd/app-p15.c b/scd/app-p15.c index 831f0d1f4..f03e5d5f0 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -43,33 +43,35 @@ typedef enum } card_type_t; /* A list card types with ATRs noticed with these cards. */ +#define X(a) ((unsigned char const *)(a)) static struct { size_t atrlen; - unsigned char *atr; + unsigned char const *atr; card_type_t type; } card_atr_list[] = { - { 19, "\x3B\xBA\x13\x00\x81\x31\x86\x5D\x00\x64\x05\x0A\x02\x01\x31\x80" - "\x90\x00\x8B", + { 19, X("\x3B\xBA\x13\x00\x81\x31\x86\x5D\x00\x64\x05\x0A\x02\x01\x31\x80" + "\x90\x00\x8B"), CARD_TYPE_TCOS }, /* SLE44 */ - { 19, "\x3B\xBA\x14\x00\x81\x31\x86\x5D\x00\x64\x05\x14\x02\x02\x31\x80" - "\x90\x00\x91", + { 19, X("\x3B\xBA\x14\x00\x81\x31\x86\x5D\x00\x64\x05\x14\x02\x02\x31\x80" + "\x90\x00\x91"), CARD_TYPE_TCOS }, /* SLE66S */ - { 19, "\x3B\xBA\x96\x00\x81\x31\x86\x5D\x00\x64\x05\x60\x02\x03\x31\x80" - "\x90\x00\x66", + { 19, X("\x3B\xBA\x96\x00\x81\x31\x86\x5D\x00\x64\x05\x60\x02\x03\x31\x80" + "\x90\x00\x66"), CARD_TYPE_TCOS }, /* SLE66P */ - { 27, "\x3B\xFF\x94\x00\xFF\x80\xB1\xFE\x45\x1F\x03\x00\x68\xD2\x76\x00" - "\x00\x28\xFF\x05\x1E\x31\x80\x00\x90\x00\x23", + { 27, X("\x3B\xFF\x94\x00\xFF\x80\xB1\xFE\x45\x1F\x03\x00\x68\xD2\x76\x00" + "\x00\x28\xFF\x05\x1E\x31\x80\x00\x90\x00\x23"), CARD_TYPE_MICARDO }, /* German BMI card */ - { 19, "\x3B\x6F\x00\xFF\x00\x68\xD2\x76\x00\x00\x28\xFF\x05\x1E\x31\x80" - "\x00\x90\x00", + { 19, X("\x3B\x6F\x00\xFF\x00\x68\xD2\x76\x00\x00\x28\xFF\x05\x1E\x31\x80" + "\x00\x90\x00"), CARD_TYPE_MICARDO }, /* German BMI card (ATR due to reader problem) */ - { 26, "\x3B\xFE\x94\x00\xFF\x80\xB1\xFA\x45\x1F\x03\x45\x73\x74\x45\x49" - "\x44\x20\x76\x65\x72\x20\x31\x2E\x30\x43", + { 26, X("\x3B\xFE\x94\x00\xFF\x80\xB1\xFA\x45\x1F\x03\x45\x73\x74\x45\x49" + "\x44\x20\x76\x65\x72\x20\x31\x2E\x30\x43"), CARD_TYPE_MICARDO }, /* EstEID (Estonian Big Brother card) */ { 0 } }; +#undef X /* The Pin Types as defined in pkcs#15 v1.1 */ diff --git a/scd/app.c b/scd/app.c index 2c8c915d7..f27b400b1 100644 --- a/scd/app.c +++ b/scd/app.c @@ -357,7 +357,7 @@ app_munge_serialno (app_t app) gpg_error_t app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp) { - unsigned char *buf, *p; + char *buf, *p; int i; if (!app || !serial) diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 9ac655e63..096a6811b 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -555,7 +555,7 @@ get_escaped_usb_string (usb_dev_handle *idev, int idx, all in a 2 bute Unicode encoding using little endian. */ rc = usb_control_msg (idev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8), 0, - buf, sizeof buf, 1000 /* ms timeout */); + (char*)buf, sizeof buf, 1000 /* ms timeout */); if (rc < 4) langid = 0x0409; /* English. */ else @@ -563,7 +563,7 @@ get_escaped_usb_string (usb_dev_handle *idev, int idx, rc = usb_control_msg (idev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + idx, langid, - buf, sizeof buf, 1000 /* ms timeout */); + (char*)buf, sizeof buf, 1000 /* ms timeout */); if (rc < 2 || buf[1] != USB_DT_STRING) return NULL; /* Error or not a string. */ len = buf[0]; @@ -1155,7 +1155,7 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen) rc = usb_bulk_write (handle->idev, handle->ep_bulk_out, - msg, msglen, + (char*)msg, msglen, 1000 /* ms timeout */); if (rc == msglen) return 0; @@ -1188,7 +1188,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, retry: rc = usb_bulk_read (handle->idev, handle->ep_bulk_in, - buffer, length, + (char*)buffer, length, timeout); if (rc < 0) { @@ -1300,7 +1300,7 @@ ccid_poll (ccid_driver_t handle) rc = usb_bulk_read (handle->idev, handle->ep_intr, - msg, sizeof msg, + (char*)msg, sizeof msg, 0 /* ms timeout */ ); if (rc < 0 && errno == ETIMEDOUT) return 0; @@ -1444,7 +1444,7 @@ ccid_get_atr (ccid_driver_t handle, { tried_iso = 1; /* Try switching to ISO mode. */ - if (!send_escape_cmd (handle, "\xF1\x01", 2)) + if (!send_escape_cmd (handle, (const unsigned char*)"\xF1\x01", 2)) goto again; } else if (CCID_COMMAND_FAILED (msg)) @@ -2026,7 +2026,7 @@ ccid_transceive_secure (ccid_driver_t handle, if (handle->id_vendor == VENDOR_SCM) { DEBUGOUT ("sending escape sequence to switch to a case 1 APDU\n"); - rc = send_escape_cmd (handle, "\x80\x02\x00", 3); + rc = send_escape_cmd (handle, (const unsigned char*)"\x80\x02\x00", 3); if (rc) return rc; } diff --git a/scd/command.c b/scd/command.c index a308078d3..52a86871e 100644 --- a/scd/command.c +++ b/scd/command.c @@ -679,7 +679,7 @@ pin_cb (void *opaque, const char *info, char **retstr) xfree (value); return gpg_error (GPG_ERR_INV_RESPONSE); } - *retstr = value; + *retstr = (char*)value; return 0; } @@ -844,7 +844,7 @@ cmd_getattr (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc; - char *keyword; + const char *keyword; if ((rc = open_card (ctrl, NULL))) return rc; @@ -860,7 +860,6 @@ cmd_getattr (assuan_context_t ctx, char *line) /* FIXME: Applications should not return sensistive data if the card is locked. */ rc = app_getattr (ctrl->app_ctx, ctrl, keyword); - xfree (keyword); TEST_CARD_REMOVAL (ctrl, rc); return map_to_assuan_status (rc); @@ -908,9 +907,10 @@ cmd_setattr (assuan_context_t ctx, char *orig_line) *line++ = 0; while (spacep (line)) line++; - nbytes = percent_plus_unescape (line); + nbytes = percent_plus_unescape ((unsigned char*)line); - rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes); + rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, + (const unsigned char*)line, nbytes); xfree (linebuf); TEST_CARD_REMOVAL (ctrl, rc); diff --git a/scd/iso7816.c b/scd/iso7816.c index e9dc6541c..742ed9433 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -153,7 +153,7 @@ iso7816_select_file (int slot, int tag, int is_dir, p0 = (tag == 0x3F00)? 0: is_dir? 1:2; p1 = 0x0c; /* No FC return. */ sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, - p0, p1, 2, tagbuf ); + p0, p1, 2, (char*)tagbuf ); return map_sw (sw); } @@ -285,7 +285,7 @@ iso7816_put_data (int slot, int tag, sw = apdu_send_simple (slot, 0x00, CMD_PUT_DATA, ((tag >> 8) & 0xff), (tag & 0xff), - datalen, data); + datalen, (const char*)data); return map_sw (sw); } @@ -303,7 +303,7 @@ iso7816_manage_security_env (int slot, int p1, int p2, return gpg_error (GPG_ERR_INV_VALUE); sw = apdu_send_simple (slot, 0x00, CMD_MSE, p1, p2, - data? datalen : -1, data); + data? datalen : -1, (const char*)data); return map_sw (sw); } @@ -323,7 +323,7 @@ iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen, *result = NULL; *resultlen = 0; - sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, data, + sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, (const char*)data, result, resultlen); if (sw != SW_SUCCESS) { @@ -364,13 +364,15 @@ iso7816_decipher (int slot, const unsigned char *data, size_t datalen, *buf = padind; /* Padding indicator. */ memcpy (buf+1, data, datalen); - sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen+1, buf, + sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, + datalen+1, (char*)buf, result, resultlen); xfree (buf); } else { - sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen, data, + sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, + datalen, (const char *)data, result, resultlen); } if (sw != SW_SUCCESS) @@ -399,7 +401,7 @@ iso7816_internal_authenticate (int slot, *resultlen = 0; sw = apdu_send (slot, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0, - datalen, data, result, resultlen); + datalen, (const char*)data, result, resultlen); if (sw != SW_SUCCESS) { /* Make sure that pending buffers are released. */ @@ -426,7 +428,7 @@ do_generate_keypair (int slot, int readonly, *resultlen = 0; sw = apdu_send (slot, 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0, - datalen, data, result, resultlen); + datalen, (const char*)data, result, resultlen); if (sw != SW_SUCCESS) { /* Make sure that pending buffers are released. */ diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c index 93e78fdfe..21af16fba 100644 --- a/scd/pcsc-wrapper.c +++ b/scd/pcsc-wrapper.c @@ -390,9 +390,9 @@ handle_open (unsigned char *argbuf, size_t arglen) unsigned char atr[33]; /* Make sure there is only the port string */ - if (arglen != strlen (argbuf)) + if (arglen != strlen ((char*)argbuf)) bad_request ("OPEN"); - portstr = argbuf; + portstr = (char*)argbuf; if (driver_is_open) { diff --git a/sm/ChangeLog b/sm/ChangeLog index ffb61a294..d9f295e1d 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,35 @@ +2005-06-15 Werner Koch + + * delete.c (delete_one): Changed FPR to unsigned. + * encrypt.c (encrypt_dek): Made ENCVAL unsigned. + (gpgsm_encrypt): Ditto. + * sign.c (gpgsm_sign): Made SIGVAL unsigned. + * base64.c (base64_reader_cb): Need to use some casting to get + around signed/unsigned char* warnings. + * certcheck.c (gpgsm_check_cms_signature): Ditto. + (gpgsm_create_cms_signature): Changed arg R_SIGVAL to unsigned char*. + (do_encode_md): Made NFRAME a size_t. + * certdump.c (gpgsm_print_serial): Fixed signed/unsigned warning. + (gpgsm_dump_serial): Ditto. + (gpgsm_format_serial): Ditto. + (gpgsm_dump_string): Ditto. + (gpgsm_dump_cert): Ditto. + (parse_dn_part): Ditto. + (gpgsm_print_name2): Ditto. + * keylist.c (email_kludge): Ditto. + * certreqgen.c (proc_parameters, create_request): Ditto. + (create_request): Ditto. + * call-agent.c (gpgsm_agent_pksign): Made arg R_BUF unsigned. + (struct cipher_parm_s): Made CIPHERTEXT unsigned. + (struct genkey_parm_s): Ditto. + * server.c (strcpy_escaped_plus): Made arg S signed char*. + * fingerprint.c (gpgsm_get_fingerprint): Made ARRAY unsigned. + (gpgsm_get_keygrip): Ditto. + * keydb.c (keydb_insert_cert): Made DIGEST unsigned. + (keydb_update_cert): Ditto. + (classify_user_id): Apply cast to signed/unsigned assignment. + (hextobyte): Ditto. + 2005-06-01 Werner Koch * misc.c: Include setenv.h. diff --git a/sm/base64.c b/sm/base64.c index 4cc6ffa27..62c2c9ad9 100644 --- a/sm/base64.c +++ b/sm/base64.c @@ -95,7 +95,7 @@ struct base64_context_s { /* The base-64 character list */ -static unsigned char bintoasc[64] = +static char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; @@ -202,8 +202,9 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) { /* wait for the header line */ parm->linelen = parm->readpos = 0; - if (!parm->have_lf || strncmp (parm->line, "-----BEGIN ", 11) - || !strncmp (parm->line+11, "PGP ", 4)) + if (!parm->have_lf + || strncmp ((char*)parm->line, "-----BEGIN ", 11) + || !strncmp ((char*)parm->line+11, "PGP ", 4)) goto next; parm->is_pem = 1; } @@ -220,8 +221,9 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) /* the very first byte does pretty much look like a SEQUENCE tag*/ parm->is_pem = 0; } - else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11) - && strncmp (parm->line+11, "PGP ", 4) ) + else if ( parm->have_lf + && !strncmp ((char*)parm->line, "-----BEGIN ", 11) + && strncmp ((char *)parm->line+11, "PGP ", 4) ) { /* Fixme: we must only compare if the line really starts at the beginning */ @@ -268,7 +270,7 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) if (parm->is_pem || parm->is_base64) { if (parm->is_pem && parm->have_lf - && !strncmp (parm->line, "-----END ", 9)) + && !strncmp ((char*)parm->line, "-----END ", 9)) { parm->identified = 0; parm->linelen = parm->readpos = 0; diff --git a/sm/call-agent.c b/sm/call-agent.c index 885abf421..92a29928c 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -39,24 +39,27 @@ #include "../common/membuf.h" -static ASSUAN_CONTEXT agent_ctx = NULL; +static assuan_context_t agent_ctx = NULL; static int force_pipe_server = 0; -struct cipher_parm_s { - ASSUAN_CONTEXT ctx; - const char *ciphertext; +struct cipher_parm_s +{ + assuan_context_t ctx; + const unsigned char *ciphertext; size_t ciphertextlen; }; -struct genkey_parm_s { - ASSUAN_CONTEXT ctx; - const char *sexp; +struct genkey_parm_s +{ + assuan_context_t ctx; + const unsigned char *sexp; size_t sexplen; }; -struct learn_parm_s { +struct learn_parm_s +{ int error; - ASSUAN_CONTEXT ctx; + assuan_context_t ctx; membuf_t *data; }; @@ -204,7 +207,7 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length) int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, unsigned char *digest, size_t digestlen, int digestalgo, - char **r_buf, size_t *r_buflen ) + unsigned char **r_buf, size_t *r_buflen ) { int rc, i; char *p, line[ASSUAN_LINELENGTH]; @@ -392,7 +395,7 @@ gpgsm_agent_genkey (ctrl_t ctrl, struct genkey_parm_s gk_parm; membuf_t data; size_t len; - char *buf; + unsigned char *buf; *r_pubkey = NULL; rc = start_agent (ctrl); diff --git a/sm/certcheck.c b/sm/certcheck.c index 611d3219c..84dfdb9ab 100644 --- a/sm/certcheck.c +++ b/sm/certcheck.c @@ -39,7 +39,8 @@ static int do_encode_md (gcry_md_hd_t md, int algo, int pkalgo, unsigned int nbits, gcry_mpi_t *r_val) { - int n, nframe; + int n; + size_t nframe; unsigned char *frame; if (pkalgo == GCRY_PK_DSA) @@ -205,7 +206,7 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) log_printf ("\n"); } - rc = gcry_sexp_sscan ( &s_sig, NULL, p, n); + rc = gcry_sexp_sscan ( &s_sig, NULL, (char*)p, n); ksba_free (p); if (rc) { @@ -224,7 +225,7 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) gcry_sexp_release (s_sig); return gpg_error (GPG_ERR_BUG); } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); + rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n); ksba_free (p); if (rc) { @@ -278,7 +279,7 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, log_error ("libksba did not return a proper S-Exp\n"); return gpg_error (GPG_ERR_BUG); } - rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n); + rc = gcry_sexp_sscan (&s_sig, NULL, (char*)sigval, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); @@ -297,7 +298,7 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, if (DBG_CRYPTO) log_printhex ("public key: ", p, n); - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); + rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n); ksba_free (p); if (rc) { @@ -333,7 +334,8 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, int gpgsm_create_cms_signature (ctrl_t ctrl, ksba_cert_t cert, - gcry_md_hd_t md, int mdalgo, char **r_sigval) + gcry_md_hd_t md, int mdalgo, + unsigned char **r_sigval) { int rc; char *grip, *desc; diff --git a/sm/certdump.c b/sm/certdump.c index 26510c70d..98f019c4a 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -50,8 +50,9 @@ struct dn_array_s { /* print the first element of an S-Expression */ void -gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) +gpgsm_print_serial (FILE *fp, ksba_const_sexp_t sn) { + const char *p = (const char *)sn; unsigned long n; char *endp; @@ -77,8 +78,9 @@ gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) /* Dump the serial number or any other simple S-expression. */ void -gpgsm_dump_serial (ksba_const_sexp_t p) +gpgsm_dump_serial (ksba_const_sexp_t sn) { + const char *p = (const char *)sn; unsigned long n; char *endp; @@ -103,8 +105,9 @@ gpgsm_dump_serial (ksba_const_sexp_t p) char * -gpgsm_format_serial (ksba_const_sexp_t p) +gpgsm_format_serial (ksba_const_sexp_t sn) { + const char *p = (const char *)sn; unsigned long n; char *endp; char *buffer; @@ -168,7 +171,7 @@ gpgsm_dump_string (const char *string) { const unsigned char *s; - for (s=string; *s; s++) + for (s=(const unsigned char*)string; *s; s++) { if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) break; @@ -190,7 +193,7 @@ void gpgsm_dump_cert (const char *text, ksba_cert_t cert) { ksba_sexp_t sexp; - unsigned char *p; + char *p; char *dn; ksba_isotime_t t; @@ -260,7 +263,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string) }; const unsigned char *s, *s1; size_t n; - unsigned char *p; + char *p; int i; /* Parse attributeType */ @@ -306,7 +309,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string) return NULL; for (s1=string; n; s1 += 2, n--, p++) { - *p = xtoi_2 (s1); + *(unsigned char *)p = xtoi_2 (s1); if (!*p) *p = 0x01; /* Better print a wrong value than truncating the string. */ @@ -351,7 +354,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string) s++; if (hexdigitp (s)) { - *p++ = xtoi_2 (s); + *(unsigned char *)p++ = xtoi_2 (s); s++; } else @@ -485,23 +488,22 @@ print_dn_parts (FILE *fp, struct dn_array_s *dn, int translate) void gpgsm_print_name2 (FILE *fp, const char *name, int translate) { - const unsigned char *s; + const unsigned char *s = (const unsigned char *)name; int i; - s = name; if (!s) { fputs (_("[Error - No name]"), fp); } else if (*s == '<') { - const unsigned char *s2 = strchr (s+1, '>'); + const char *s2 = strchr ( (char*)s+1, '>'); if (s2) { if (translate) - print_sanitized_utf8_buffer (fp, s + 1, s2 - s - 1, 0); + print_sanitized_utf8_buffer (fp, s + 1, s2 - (char*)s - 1, 0); else - print_sanitized_buffer (fp, s + 1, s2 - s - 1, 0); + print_sanitized_buffer (fp, s + 1, s2 - (char*)s - 1, 0); } } else if (*s == '(') diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 7b29a5b8d..2b920da7e 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -492,7 +492,7 @@ proc_parameters (ctrl_t ctrl, } sprintf (numbuf, "%u", nbits); - snprintf (keyparms, DIM (keyparms)-1, + snprintf ((char*)keyparms, DIM (keyparms)-1, "(6:genkey(3:rsa(5:nbits%d:%s)))", (int)strlen (numbuf), numbuf); rc = gpgsm_agent_genkey (ctrl, keyparms, &public); if (rc) @@ -627,8 +627,9 @@ create_request (ctrl_t ctrl, { gcry_sexp_t s_pkey; size_t n; - unsigned char grip[20], hexgrip[41]; - char *sigval; + unsigned char grip[20]; + char hexgrip[41]; + unsigned char *sigval; size_t siglen; n = gcry_sexp_canon_len (public, 0, NULL, NULL); @@ -638,7 +639,7 @@ create_request (ctrl_t ctrl, err = gpg_error (GPG_ERR_BUG); goto leave; } - rc = gcry_sexp_sscan (&s_pkey, NULL, public, n); + rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)public, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); diff --git a/sm/delete.c b/sm/delete.c index 11a0a5476..8e06b9489 100644 --- a/sm/delete.c +++ b/sm/delete.c @@ -67,7 +67,7 @@ delete_one (CTRL ctrl, const char *username) rc = keydb_get_cert (kh, &cert); if (!rc) { - char fpr[20]; + unsigned char fpr[20]; gpgsm_get_fingerprint (cert, 0, fpr, NULL); @@ -78,7 +78,7 @@ delete_one (CTRL ctrl, const char *username) else if (!rc) { ksba_cert_t cert2 = NULL; - char fpr2[20]; + unsigned char fpr2[20]; /* We ignore all duplicated certificates which might have been inserted due to program bugs. */ diff --git a/sm/encrypt.c b/sm/encrypt.c index 50da92c32..e4c0d5437 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -164,10 +164,10 @@ encode_session_key (DEK dek, gcry_sexp_t * r_data) } -/* encrypt the DEK under the key contained in CERT and return it as a - canonical S-Exp in encval */ +/* Encrypt the DEK under the key contained in CERT and return it as a + canonical S-Exp in encval. */ static int -encrypt_dek (const DEK dek, ksba_cert_t cert, char **encval) +encrypt_dek (const DEK dek, ksba_cert_t cert, unsigned char **encval) { gcry_sexp_t s_ciph, s_data, s_pkey; int rc; @@ -189,7 +189,7 @@ encrypt_dek (const DEK dek, ksba_cert_t cert, char **encval) log_error ("libksba did not return a proper S-Exp\n"); return gpg_error (GPG_ERR_BUG); } - rc = gcry_sexp_sscan (&s_pkey, NULL, buf, len); + rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)buf, len); xfree (buf); buf = NULL; if (rc) { @@ -220,7 +220,7 @@ encrypt_dek (const DEK dek, ksba_cert_t cert, char **encval) gcry_sexp_release (s_ciph); return tmperr; } - len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, buf, len); + len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, (char*)buf, len); assert (len); *encval = buf; @@ -437,7 +437,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp) each and store them in the CMS object */ for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next) { - char *encval; + unsigned char *encval; rc = encrypt_dek (dek, cl->cert, &encval); if (rc) diff --git a/sm/fingerprint.c b/sm/fingerprint.c index 7fe619c18..9c3ab85db 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -42,8 +42,9 @@ If there is a problem , the function does never return NULL but a digest of all 0xff. */ -char * -gpgsm_get_fingerprint (ksba_cert_t cert, int algo, char *array, int *r_len) +unsigned char * +gpgsm_get_fingerprint (ksba_cert_t cert, int algo, + unsigned char *array, int *r_len) { gcry_md_hd_t md; int rc, len; @@ -140,8 +141,8 @@ gpgsm_get_short_fingerprint (ksba_cert_t cert) key parameters expressed as an canoncial encoded S-Exp. array must be 20 bytes long. returns the array or a newly allocated one if the passed one was NULL */ -char * -gpgsm_get_keygrip (ksba_cert_t cert, char *array) +unsigned char * +gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array) { gcry_sexp_t s_pkey; int rc; @@ -160,7 +161,7 @@ gpgsm_get_keygrip (ksba_cert_t cert, char *array) log_error ("libksba did not return a proper S-Exp\n"); return NULL; } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); + rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n); xfree (p); if (rc) { @@ -223,7 +224,7 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits) xfree (p); return 0; } - rc = gcry_sexp_sscan (&s_pkey, NULL, p, n); + rc = gcry_sexp_sscan (&s_pkey, NULL, (char *)p, n); xfree (p); if (rc) return 0; @@ -272,7 +273,7 @@ char * gpgsm_get_certid (ksba_cert_t cert) { ksba_sexp_t serial; - unsigned char *p; + char *p; char *endp; unsigned char hash[20]; unsigned long n; @@ -288,7 +289,7 @@ gpgsm_get_certid (ksba_cert_t cert) serial = ksba_cert_get_serial (cert); if (!serial) return NULL; /* oops: no serial number */ - p = serial; + p = (char *)serial; if (*p != '(') { log_error ("Ooops: invalid serial number\n"); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 1068e9d5e..2f3e83485 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -181,12 +181,12 @@ gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, gpg_err_code_t ec); /*-- fingerprint --*/ -char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo, - char *array, int *r_len); +unsigned char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo, + unsigned char *array, int *r_len); char *gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo); char *gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo); unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert); -char *gpgsm_get_keygrip (ksba_cert_t cert, char *array); +unsigned char *gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array); char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert); int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits); char *gpgsm_get_certid (ksba_cert_t cert); @@ -229,7 +229,7 @@ int gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, /* fixme: move create functions to another file */ int gpgsm_create_cms_signature (ctrl_t ctrl, ksba_cert_t cert, gcry_md_hd_t md, int mdalgo, - char **r_sigval); + unsigned char **r_sigval); /*-- certchain.c --*/ @@ -293,7 +293,7 @@ int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, unsigned char *digest, size_t digestlen, int digestalgo, - char **r_buf, size_t *r_buflen); + unsigned char **r_buf, size_t *r_buflen); int gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, ksba_const_sexp_t ciphertext, char **r_buf, size_t *r_buflen); diff --git a/sm/keydb.c b/sm/keydb.c index 293e5233d..17f04fe4b 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -681,7 +681,7 @@ keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert) { int rc = -1; int idx; - char digest[20]; + unsigned char digest[20]; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -723,7 +723,7 @@ int keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert) { int rc = 0; - char digest[20]; + unsigned char digest[20]; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -1010,8 +1010,9 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name) static int -hextobyte (const unsigned char *s) +hextobyte (const char *string) { + const unsigned char *s = (const unsigned char *)string; int c; if( *s >= '0' && *s <= '9' ) @@ -1122,7 +1123,7 @@ classify_user_id (const char *name, if (!strchr("01234567890abcdefABCDEF", *si)) return 0; /* invalid digit in serial number*/ } - desc->sn = s; + desc->sn = (const unsigned char*)s; desc->snlen = -1; if (!*si) mode = KEYDB_SEARCH_MODE_SN; diff --git a/sm/keylist.c b/sm/keylist.c index 8e1233341..a0ac73fb3 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -256,7 +256,7 @@ print_time (gnupg_isotime_t t, FILE *fp) static char * email_kludge (const char *name) { - const unsigned char *p; + const char *p; unsigned char *buf; int n; @@ -278,7 +278,7 @@ email_kludge (const char *name) buf[n] = xtoi_2 (p); buf[n++] = '>'; buf[n] = 0; - return buf; + return (char*)buf; } diff --git a/sm/server.c b/sm/server.c index 7bfd3fc20..b3816d3d9 100644 --- a/sm/server.c +++ b/sm/server.c @@ -53,14 +53,14 @@ struct server_local_s { /* Note that it is sufficient to allocate the target string D as long as the source string S, i.e.: strlen(s)+1; */ static void -strcpy_escaped_plus (char *d, const unsigned char *s) +strcpy_escaped_plus (char *d, const char *s) { while (*s) { if (*s == '%' && s[1] && s[2]) { s++; - *d++ = xtoi_2 ( s); + *d++ = xtoi_2 (s); s += 2; } else if (*s == '+') diff --git a/sm/sign.c b/sm/sign.c index 5deef6088..3230a0e98 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -575,7 +575,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist, ksba_cms_set_hash_function (cms, HASH_FNC, md); for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) { - char *sigval = NULL; + unsigned char *sigval = NULL; char *buf, *fpr; if (signer) diff --git a/tools/ChangeLog b/tools/ChangeLog index 39f17e2ce..5965b2871 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2005-06-16 Werner Koch + + * gpg-connect-agent.c (read_and_print_response): Made LINELEN a + size_t. + 2005-06-04 Marcus Brinkmann * symcryptrun.c (main): Allow any number of arguments, don't use diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index bb05030ee..c9a324fa8 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -458,7 +458,7 @@ static int read_and_print_response (assuan_context_t ctx) { char *line; - int linelen; + size_t linelen; assuan_error_t rc; int i, j; diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index c49d1dcbb..e8d9ca27e 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2316,7 +2316,7 @@ gc_component_change_options (int component, FILE *in) char *linep; unsigned long flags = 0; char *new_value = ""; - unsigned long new_value_nr; + unsigned long new_value_nr = 0; /* Strip newline and carriage return, if present. */ while (length > 0 diff --git a/tools/gpgkey2ssh.c b/tools/gpgkey2ssh.c index 75b18b29b..e874ab22e 100644 --- a/tools/gpgkey2ssh.c +++ b/tools/gpgkey2ssh.c @@ -249,6 +249,9 @@ main (int argc, char **argv) pkdbuf = NULL; pkdbuf_n = 0; + algorithm_id = 0; /* (avoid cc warning) */ + identifier = NULL; /* (avoid cc warning) */ + assert (argc == 2); keyid = argv[1]; diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index 25ca8c413..6cb570fbc 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -223,7 +223,7 @@ main (int argc, char **argv) int force = 0; struct sockaddr_un srvr_addr; - int addrlen; + socklen_t addrlen; int server; int flags; client_t client_list = NULL; -- cgit From f1ce96e40435b7d7d12855de76d8956b807ccb3d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 29 Jun 2005 14:12:18 +0000 Subject: (data_sign): Removed empty statement. --- agent/ChangeLog | 9 ++++ agent/Makefile.am | 15 ++++++ agent/command-ssh.c | 2 +- agent/minip12.c | 12 +++-- agent/t-protect.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 agent/t-protect.c (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 055dbe53e..4d539d485 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,12 @@ +2005-06-29 Werner Koch + + * command-ssh.c (data_sign): Removed empty statement. + +2005-06-21 Werner Koch + + * minip12.c (create_final): Cast size_t to ulong for printf. + (build_key_bag, build_cert_bag, build_cert_sequence): Ditto. + 2005-06-16 Werner Koch * protect-tool.c (make_advanced): Makde RESULT a plain char. diff --git a/agent/Makefile.am b/agent/Makefile.am index 017b84795..c1a7c820e 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -20,6 +20,7 @@ bin_PROGRAMS = gpg-agent libexec_PROGRAMS = gpg-protect-tool gpg-preset-passphrase +noinst_PROGRAMS = $(TESTS) AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl @@ -70,3 +71,17 @@ if HAVE_W32_SYSTEM gpg_preset_passphrase_LDADD += -lwsock32 endif +# +# Module tests +# +TESTS = t-protect + +t_common_ldadd = ../jnlib/libjnlib.a ../common/libcommon.a \ + $(LIBGCRYPT_LIBS) -lgpg-error @LIBINTL@ + +t_protect_SOURCES = t-protect.c protect.c +t_protect_LDADD = $(t_common_ldadd) + + + + diff --git a/agent/command-ssh.c b/agent/command-ssh.c index a43fee24f..642bcbbba 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1988,7 +1988,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, gcry_sexp_t valuelist = NULL; gcry_sexp_t sublist = NULL; gcry_mpi_t sig_value = NULL; - unsigned char *sig_blob = NULL;; + unsigned char *sig_blob = NULL; size_t sig_blob_n = 0; char *identifier = NULL; const char *identifier_raw; diff --git a/agent/minip12.c b/agent/minip12.c index 31be15373..030043962 100644 --- a/agent/minip12.c +++ b/agent/minip12.c @@ -1085,7 +1085,8 @@ create_final (struct buffer_s *sequences, size_t *r_length) /* Ready. */ resultlen = p - result; if (needed != resultlen) - log_debug ("length mismatch: %u, %u\n", needed, resultlen); + log_debug ("length mismatch: %lu, %lu\n", + (unsigned long)needed, (unsigned long)resultlen); *r_length = resultlen; return result; @@ -1339,7 +1340,8 @@ build_key_bag (unsigned char *buffer, size_t buflen, char *salt, keybaglen = p - keybag; if (needed != keybaglen) - log_debug ("length mismatch: %u, %u\n", needed, keybaglen); + log_debug ("length mismatch: %lu, %lu\n", + (unsigned long)needed, (unsigned long)keybaglen); *r_length = keybaglen; return keybag; @@ -1437,7 +1439,8 @@ build_cert_bag (unsigned char *buffer, size_t buflen, char *salt, certbaglen = p - certbag; if (needed != certbaglen) - log_debug ("length mismatch: %u, %u\n", needed, certbaglen); + log_debug ("length mismatch: %lu, %lu\n", + (unsigned long)needed, (unsigned long)certbaglen); *r_length = certbaglen; return certbag; @@ -1527,7 +1530,8 @@ build_cert_sequence (unsigned char *buffer, size_t buflen, size_t *r_length) certseqlen = p - certseq; if (needed != certseqlen) - log_debug ("length mismatch: %u, %u\n", needed, certseqlen); + log_debug ("length mismatch: %lu, %lu\n", + (unsigned long)needed, (unsigned long)certseqlen); /* Append some pad characters; we already allocated extra space. */ n = 8 - certseqlen % 8; diff --git a/agent/t-protect.c b/agent/t-protect.c new file mode 100644 index 000000000..0cb8265ba --- /dev/null +++ b/agent/t-protect.c @@ -0,0 +1,142 @@ +/* t-protect.c - Module tests for protect.c + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include + +#include "agent.h" + + +#define pass() do { ; } while(0) +#define fail() do { fprintf (stderr, "%s:%d: test failed\n",\ + __FILE__,__LINE__); \ + exit (1); \ + } while(0) + + +static void +test_agent_protect (void) +{ + /* Protect the key encoded in canonical format in PLAINKEY. We assume + a valid S-Exp here. */ +/* int agent_protect (const unsigned char *plainkey, const char *passphrase, */ +/* unsigned char **result, size_t *resultlen); */ +} + + +static void +test_agent_unprotect (void) +{ + /* Unprotect the key encoded in canonical format. We assume a valid + S-Exp here. */ +/* int */ +/* agent_unprotect (const unsigned char *protectedkey, const char *passphrase, */ +/* unsigned char **result, size_t *resultlen) */ +} + + +static void +test_agent_private_key_type (void) +{ +/* Check the type of the private key, this is one of the constants: + PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the + value 0), PRIVATE_KEY_CLEAR for an unprotected private key. + PRIVATE_KEY_PROTECTED for an protected private key or + PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored + elsewhere. */ +/* int */ +/* agent_private_key_type (const unsigned char *privatekey) */ +} + + +static void +test_make_shadow_info (void) +{ + static struct + { + const char *snstr; + const char *idstr; + const char *expected; + } data[] = { + { "", "", NULL }, + + }; + int i; + unsigned char *result; + + for (i=0; i < DIM(data); i++) + { + result = make_shadow_info (data[i].snstr, data[i].idstr); + if (!result && !data[i].expected) + pass (); + else if (!result && data[i].expected) + fail (); + else if (!data[i].expected) + fail (); + /* fixme: Need to compare the result but also need to check + proper S-expression syntax. */ + } +} + + + +static void +test_agent_shadow_key (void) +{ +/* Create a shadow key from a public key. We use the shadow protocol + "ti-v1" and insert the S-expressionn SHADOW_INFO. The resulting + S-expression is returned in an allocated buffer RESULT will point + to. The input parameters are expected to be valid canonicalized + S-expressions */ +/* int */ +/* agent_shadow_key (const unsigned char *pubkey, */ +/* const unsigned char *shadow_info, */ +/* unsigned char **result) */ +} + + +static void +test_agent_get_shadow_info (void) +{ +/* Parse a canonical encoded shadowed key and return a pointer to the + inner list with the shadow_info */ +/* int */ +/* agent_get_shadow_info (const unsigned char *shadowkey, */ +/* unsigned char const **shadow_info) */ +} + + + + +int +main (int argc, char **argv) +{ + test_agent_protect (); + test_agent_unprotect (); + test_agent_private_key_type (); + test_make_shadow_info (); + test_agent_shadow_key (); + test_agent_get_shadow_info (); + + return 0; +} -- cgit From 6f90f05cb2181bc4ab64959c0f3590f48c9c39c6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 9 Sep 2005 11:18:08 +0000 Subject: Bug fixes and ssh support for the BELPIC. --- NEWS | 4 +- agent/ChangeLog | 14 ++++++ agent/command-ssh.c | 46 ++++++++++--------- agent/minip12.c | 4 +- po/de.po | 70 ++++++++++++++-------------- scd/ChangeLog | 14 +++++- scd/app-openpgp.c | 27 ++++++++++- scd/app-p15.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++-- scd/ccid-driver.c | 3 +- scd/ccid-driver.h | 3 +- scd/iso7816.c | 3 +- scd/iso7816.h | 3 +- scd/pcsc-wrapper.c | 1 - sm/ChangeLog | 6 +++ sm/export.c | 1 + 15 files changed, 256 insertions(+), 71 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/NEWS b/NEWS index 75410e8d5..acc7c25f3 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,10 @@ Noteworthy changes in version 1.9.19 ------------------------------------------------- - * The Belgian eID card is now supported. + * The Belgian eID card is now supported for signatures and ssh. + * Fixed bug in --export-secret-key-p12 so that certificates are again + included. Noteworthy changes in version 1.9.18 (2005-08-01) ------------------------------------------------- diff --git a/agent/ChangeLog b/agent/ChangeLog index adb7b1bb6..83e1fe867 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,17 @@ +2005-09-09 Werner Koch + + * minip12.c (p12_build): Oops, array needs to be larger for the + certificate. + + * command-ssh.c (card_key_available): Let the card handler decide + whether the card is supported here. Also get a short serial + number to return from the card handler. + +2005-09-08 Werner Koch + + * minip12.c (build_cert_bag): Use a non constructed object. + i.e. 0x80 and not 0xa0. + 2005-08-16 Werner Koch * gpg-agent.c (main): Use a default file name for --write-env-file. diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 642bcbbba..b8f0d20b0 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1583,13 +1583,13 @@ key_secret_to_public (gcry_sexp_t *key_public, /* Check whether a smartcard is available and whether it has a usable key. Store a copy of that key at R_PK and return 0. If no key is available store NULL at R_PK and return an error code. If CARDSN - is no NULL, a string with the serial number of the card will be + is not NULL, a string with the serial number of the card will be a malloced and stored there. */ static gpg_error_t card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) { gpg_error_t err; - char *appname; + char *authkeyid; char *serialno = NULL; unsigned char *pkbuf; size_t pkbuflen; @@ -1602,7 +1602,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) /* First see whether a card is available and whether the application is supported. */ - err = agent_card_getattr (ctrl, "APPTYPE", &appname); + err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid); if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED ) { /* Ask for the serial number to reset the card. */ @@ -1615,40 +1615,33 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) return err; } log_info (_("detected card with S/N: %s\n"), serialno); - err = agent_card_getattr (ctrl, "APPTYPE", &appname); + err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid); } if (err) { - log_error (_("error getting application type of card: %s\n"), + log_error (_("error getting default authentication keyID of card: %s\n"), gpg_strerror (err)); xfree (serialno); return err; } - if (strcmp (appname, "OPENPGP")) - { - log_info (_("card application `%s' is not supported\n"), appname); - xfree (appname); - xfree (serialno); - return gpg_error (GPG_ERR_NOT_SUPPORTED); - } - xfree (appname); - appname = NULL; /* Get the S/N if we don't have it yet. Use the fast getattr method. */ if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) ) { log_error (_("error getting serial number of card: %s\n"), gpg_strerror (err)); + xfree (authkeyid); return err; } /* Read the public key. */ - err = agent_card_readkey (ctrl, "OPENPGP.3", &pkbuf); + err = agent_card_readkey (ctrl, authkeyid, &pkbuf); if (err) { if (opt.verbose) log_info (_("no suitable card key found: %s\n"), gpg_strerror (err)); xfree (serialno); + xfree (authkeyid); return err; } @@ -1660,6 +1653,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) gpg_strerror (err)); xfree (pkbuf); xfree (serialno); + xfree (authkeyid); return err; } @@ -1671,6 +1665,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) xfree (pkbuf); gcry_sexp_release (s_pk); xfree (serialno); + xfree (authkeyid); return err; } @@ -1680,13 +1675,14 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) unsigned char *shadow_info; unsigned char *tmp; - shadow_info = make_shadow_info (serialno, "OPENPGP.3"); + shadow_info = make_shadow_info (serialno, authkeyid); if (!shadow_info) { err = gpg_error_from_errno (errno); xfree (pkbuf); gcry_sexp_release (s_pk); xfree (serialno); + xfree (authkeyid); return err; } err = agent_shadow_key (pkbuf, shadow_info, &tmp); @@ -1697,6 +1693,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) xfree (pkbuf); gcry_sexp_release (s_pk); xfree (serialno); + xfree (authkeyid); return err; } xfree (pkbuf); @@ -1711,18 +1708,23 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) xfree (pkbuf); gcry_sexp_release (s_pk); xfree (serialno); + xfree (authkeyid); return err; } } if (cardsn) { - size_t snlen = strlen (serialno); + char *dispsn; - if (snlen == 32 - && !memcmp (serialno, "D27600012401", 12)) /* OpenPGP card. */ - *cardsn = xtryasprintf ("cardno:%.12s", serialno+16); - else /* Something is wrong: Print all. */ + /* If the card handler is able to return a short serialnumber, + use that one, else use the complete serialno. */ + if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn)) + { + *cardsn = xtryasprintf ("cardno:%s", dispsn); + xfree (dispsn); + } + else *cardsn = xtryasprintf ("cardno:%s", serialno); if (!*cardsn) { @@ -1730,12 +1732,14 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) xfree (pkbuf); gcry_sexp_release (s_pk); xfree (serialno); + xfree (authkeyid); return err; } } xfree (pkbuf); xfree (serialno); + xfree (authkeyid); *r_pk = s_pk; return 0; } diff --git a/agent/minip12.c b/agent/minip12.c index 030043962..ea9f9b1b8 100644 --- a/agent/minip12.c +++ b/agent/minip12.c @@ -1409,7 +1409,7 @@ build_cert_bag (unsigned char *buffer, size_t buflen, char *salt, p += DIM (oid_encryptedData); /* 2. Store a [0] tag. */ - p = store_tag_length (p, 0xa0, len[2]); + p = store_tag_length (p, 0x80, len[2]); /* 3. Store a sequence. */ p = store_tag_length (p, TAG_SEQUENCE, len[3]); @@ -1553,7 +1553,7 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen, unsigned char *buffer; size_t n, buflen; char salt[8]; - struct buffer_s seqlist[2]; + struct buffer_s seqlist[3]; int seqlistidx = 0; n = buflen = 0; /* (avoid compiler warning). */ diff --git a/po/de.po b/po/de.po index 69606fa8b..11f2c8a36 100644 --- a/po/de.po +++ b/po/de.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg2 1.9.18\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2005-09-06 20:01+0200\n" +"POT-Creation-Date: 2005-09-09 12:47+0200\n" "PO-Revision-Date: 2005-08-02 17:02+0200\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" @@ -605,52 +605,52 @@ msgstr "Der Fingerprint kann nicht gespeichert werden: %s\n" msgid "failed to store the creation date: %s\n" msgstr "Das Erzeugungsdatum kann nicht gespeichert werden: %s\n" -#: scd/app-openpgp.c:978 +#: scd/app-openpgp.c:1003 #, c-format msgid "reading public key failed: %s\n" msgstr "Fehler beim Lesen des öffentlichen Schlüssels: %s\n" -#: scd/app-openpgp.c:986 scd/app-openpgp.c:1917 +#: scd/app-openpgp.c:1011 scd/app-openpgp.c:1942 msgid "response does not contain the public key data\n" msgstr "Die Antwort enthält keine Public Key Daten\n" -#: scd/app-openpgp.c:994 scd/app-openpgp.c:1925 +#: scd/app-openpgp.c:1019 scd/app-openpgp.c:1950 msgid "response does not contain the RSA modulus\n" msgstr "Die Antwort enthält keinen RSA Modulus\n" -#: scd/app-openpgp.c:1003 scd/app-openpgp.c:1935 +#: scd/app-openpgp.c:1028 scd/app-openpgp.c:1960 msgid "response does not contain the RSA public exponent\n" msgstr "Die Antwort enthält keinen öffenlichen RSA Exponent\n" -#: scd/app-openpgp.c:1266 scd/app-openpgp.c:1354 scd/app-openpgp.c:2157 +#: scd/app-openpgp.c:1291 scd/app-openpgp.c:1379 scd/app-openpgp.c:2182 #, c-format msgid "PIN callback returned error: %s\n" msgstr "Fehler vom PIN \"callback\": %s\n" -#: scd/app-openpgp.c:1272 scd/app-openpgp.c:1360 scd/app-openpgp.c:2163 +#: scd/app-openpgp.c:1297 scd/app-openpgp.c:1385 scd/app-openpgp.c:2188 #, c-format msgid "PIN for CHV%d is too short; minimum length is %d\n" msgstr "Die PIN für den CHV%d ist zu kurz; Mindestlänge ist %d\n" -#: scd/app-openpgp.c:1281 scd/app-openpgp.c:1295 scd/app-openpgp.c:1370 -#: scd/app-openpgp.c:2172 scd/app-openpgp.c:2186 +#: scd/app-openpgp.c:1306 scd/app-openpgp.c:1320 scd/app-openpgp.c:1395 +#: scd/app-openpgp.c:2197 scd/app-openpgp.c:2211 #, c-format msgid "verify CHV%d failed: %s\n" msgstr "Prüfen von CHV%d fehlgeschlagen: %s\n" -#: scd/app-openpgp.c:1318 +#: scd/app-openpgp.c:1343 msgid "access to admin commands is not configured\n" msgstr "Zugriff auf Admin Kommandos ist nicht konfiguriert\n" -#: scd/app-openpgp.c:1333 scd/app-openpgp.c:2392 +#: scd/app-openpgp.c:1358 scd/app-openpgp.c:2417 msgid "error retrieving CHV status from card\n" msgstr "Fehler beim Holen des CHV Status von der Karte\n" -#: scd/app-openpgp.c:1339 scd/app-openpgp.c:2401 +#: scd/app-openpgp.c:1364 scd/app-openpgp.c:2426 msgid "card is permanently locked!\n" msgstr "Die Karte ist dauerhaft gesperrt!\n" -#: scd/app-openpgp.c:1344 +#: scd/app-openpgp.c:1369 #, c-format msgid "%d Admin PIN attempts remaining before card is permanently locked\n" msgstr "" @@ -659,105 +659,105 @@ msgstr "" #. TRANSLATORS: Do not translate the "|A|" prefix but #. keep it at the start of the string. We need this elsewhere #. to get some infos on the string. -#: scd/app-openpgp.c:1351 +#: scd/app-openpgp.c:1376 msgid "|A|Admin PIN" msgstr "|A|Admin PIN" #. TRANSLATORS: Do not translate the "|*|" prefixes but #. keep it at the start of the string. We need this elsewhere #. to get some infos on the string. -#: scd/app-openpgp.c:1500 +#: scd/app-openpgp.c:1525 msgid "|AN|New Admin PIN" msgstr "|AN|Neue Admin PIN" -#: scd/app-openpgp.c:1500 +#: scd/app-openpgp.c:1525 msgid "|N|New PIN" msgstr "|N|Neue PIN" -#: scd/app-openpgp.c:1504 +#: scd/app-openpgp.c:1529 #, c-format msgid "error getting new PIN: %s\n" msgstr "Fehler beim Holen der neuen PIN: %s\n" -#: scd/app-openpgp.c:1554 scd/app-openpgp.c:2003 +#: scd/app-openpgp.c:1579 scd/app-openpgp.c:2028 msgid "error reading application data\n" msgstr "Fehler beim Lesen der Anwendungsdaten\n" -#: scd/app-openpgp.c:1560 scd/app-openpgp.c:2010 +#: scd/app-openpgp.c:1585 scd/app-openpgp.c:2035 msgid "error reading fingerprint DO\n" msgstr "Fehler beim Lesen des Fingerabdruck Datenobjekts\n" -#: scd/app-openpgp.c:1570 +#: scd/app-openpgp.c:1595 msgid "key already exists\n" msgstr "Schlüssel existiert bereits\n" -#: scd/app-openpgp.c:1574 +#: scd/app-openpgp.c:1599 msgid "existing key will be replaced\n" msgstr "Existierender Schlüssel wird ersetzt\n" -#: scd/app-openpgp.c:1576 +#: scd/app-openpgp.c:1601 msgid "generating new key\n" msgstr "Neuer Schlüssel wird erzeugt\n" -#: scd/app-openpgp.c:1743 +#: scd/app-openpgp.c:1768 msgid "creation timestamp missing\n" msgstr "Erzeugungsdatum fehlt\n" -#: scd/app-openpgp.c:1750 +#: scd/app-openpgp.c:1775 #, c-format msgid "RSA modulus missing or not of size %d bits\n" msgstr "Der RSA Modulus fehlt oder ist nicht %d Bits lang\n" -#: scd/app-openpgp.c:1757 +#: scd/app-openpgp.c:1782 #, c-format msgid "RSA public exponent missing or larger than %d bits\n" msgstr "Der öffentliche RSA Exponent fehlt oder ist länger als %d Bits\n" -#: scd/app-openpgp.c:1765 scd/app-openpgp.c:1772 +#: scd/app-openpgp.c:1790 scd/app-openpgp.c:1797 #, c-format msgid "RSA prime %s missing or not of size %d bits\n" msgstr "Die RSA Primzahl %s fehlt oder ist nicht %d Bits lang\n" -#: scd/app-openpgp.c:1835 +#: scd/app-openpgp.c:1860 #, c-format msgid "failed to store the key: %s\n" msgstr "Fehler beim Speichern des Schlüssels: %s\n" -#: scd/app-openpgp.c:1894 +#: scd/app-openpgp.c:1919 msgid "please wait while key is being generated ...\n" msgstr "Bitte warten bis der Schlüssel erzeugt wurde ...\n" -#: scd/app-openpgp.c:1908 +#: scd/app-openpgp.c:1933 msgid "generating key failed\n" msgstr "Fehler beim Erzeugen des Schlüssels\n" -#: scd/app-openpgp.c:1911 +#: scd/app-openpgp.c:1936 #, c-format msgid "key generation completed (%d seconds)\n" msgstr "Schlüsselerzeugung vollendet (%d Sekunden)\n" -#: scd/app-openpgp.c:1968 +#: scd/app-openpgp.c:1993 msgid "invalid structure of OpenPGP card (DO 0x93)\n" msgstr "Ungültige Struktur der OpenPGP Karte (DO 0x93)\n" -#: scd/app-openpgp.c:2137 +#: scd/app-openpgp.c:2162 #, c-format msgid "signatures created so far: %lu\n" msgstr "Anzahl bereits erzeugter Signaturen: %lu\n" -#: scd/app-openpgp.c:2145 +#: scd/app-openpgp.c:2170 #, c-format msgid "||Please enter the PIN%%0A[sigs done: %lu]" msgstr "||Bitte geben Sie die PIN ein%%0A[Sigs bisher: %lu]" -#: scd/app-openpgp.c:2406 +#: scd/app-openpgp.c:2431 msgid "" "verification of Admin PIN is currently prohibited through this command\n" msgstr "" "Die Überprüfung der Admin PIN is momentan durch ein Kommando verboten " "worden\n" -#: scd/app-openpgp.c:2477 scd/app-openpgp.c:2487 +#: scd/app-openpgp.c:2502 scd/app-openpgp.c:2512 #, c-format msgid "can't access %s - invalid OpenPGP card?\n" msgstr "Zugriff auf %s nicht möglich - ungültige OpenPGP Karte?\n" diff --git a/scd/ChangeLog b/scd/ChangeLog index df22c6bfd..207670072 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,15 @@ +2005-09-09 Werner Koch + + * pcsc-wrapper.c (main): Removed bogus free. + + * app-p15.c (do_auth): New. + (do_getattr): New attribs $AUTHKEYID and $DISPSERIALNO. + * app-openpgp.c (do_getattr): Ditto. + +2005-09-08 Werner Koch + + * app-openpgp.c (do_getattr): New key $AUTHKEYID. + 2005-09-06 Werner Koch * app-p15.c (do_sign): Tweaked for BELPIC cards. @@ -8,7 +20,7 @@ * iso7816.c (iso7816_select_path): New. * app-p15.c (select_ef_by_path): Allow for direct path selection. - (app_select_p15): Try using the beigian variant of pkcs#15. + (app_select_p15): Try using the Belgian variant of pkcs#15. (read_home_df): New. (read_ef_odf): Generalized. (read_ef_tokeninfo): New. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index bd56fb99d..5625c729b 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -696,6 +696,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) { "PRIVATE-DO-2", 0x0102 }, { "PRIVATE-DO-3", 0x0103 }, { "PRIVATE-DO-4", 0x0104 }, + { "$AUTHKEYID", 0x0000, -3 }, + { "$DISPSERIALNO",0x0000, -4 }, { NULL, 0 } }; int idx, i, rc; @@ -742,6 +744,29 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0); return 0; } + if (table[idx].special == -3) + { + char const tmp[] = "OPENPGP.3"; + send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0); + return 0; + } + if (table[idx].special == -4) + { + char *serial; + time_t stamp; + + if (!app_get_serial_and_stamp (app, &serial, &stamp)) + { + if (strlen (serial) > 16+12) + { + send_status_info (ctrl, table[idx].name, serial+16, 12, NULL, 0); + xfree (serial); + return 0; + } + xfree (serial); + } + return gpg_error (GPG_ERR_INV_NAME); + } relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &rc); if (relptr) @@ -2203,7 +2228,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, fingerprint delimited by a slash. Optionally the id OPENPGP.3 may be given. - Note that this fucntion may return the error code + Note that this function may return the error code GPG_ERR_WRONG_CARD to indicate that the card currently present does not match the one required for the requested action (e.g. the serial number does not match). */ diff --git a/scd/app-p15.c b/scd/app-p15.c index bf3c4dc1e..739a9ef95 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -2629,7 +2629,6 @@ readcert_by_cdf (app_t app, cdf_object_t cdf, } - /* Handler for the READCERT command. Read the certificate with id CERTID (as returned by learn_status in @@ -2653,6 +2652,95 @@ do_readcert (app_t app, const char *certid, } + +/* Implement the GETATTR command. This is similar to the LEARN + command but returns just one value via the status interface. */ +static gpg_error_t +do_getattr (app_t app, ctrl_t ctrl, const char *name) +{ + gpg_error_t err; + int i; + + if (!strcmp (name, "$AUTHKEYID")) + { + char *buf, *p; + prkdf_object_t prkdf; + + /* We return the ID of the first private keycapable of + signing. */ + for (prkdf = app->app_local->private_key_info; prkdf; + prkdf = prkdf->next) + if (prkdf->usageflags.sign) + break; + if (prkdf) + { + buf = xtrymalloc (9 + prkdf->objidlen*2 + 1); + if (!buf) + return gpg_error_from_errno (errno); + p = stpcpy (buf, "P15"); + if (app->app_local->home_df) + { + sprintf (p, "-%04hX", (app->app_local->home_df & 0xffff)); + p += 5; + } + p = stpcpy (p, "."); + for (i=0; i < prkdf->objidlen; i++) + { + sprintf (p, "%02X", prkdf->objid[i]); + p += 2; + } + + send_status_info (ctrl, name, buf, strlen (buf), NULL, 0); + xfree (buf); + return 0; + } + } + else if (!strcmp (name, "$DISPSERIALNO")) + { + /* For certain cards we return special IDs. There is no + general rule for it so we need to decide case by case. */ + if (app->app_local->card_type == CARD_TYPE_BELPIC) + { + /* The eID card has a card number printed on the fron matter + which seems to be a good indication. */ + unsigned char *buffer; + const unsigned char *p; + size_t buflen, n; + unsigned short path[] = { 0x3F00, 0xDF01, 0x4031 }; + + err = select_ef_by_path (app, path, DIM(path) ); + if (!err) + err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); + if (err) + { + log_error ("error accessing EF(ID): %s\n", gpg_strerror (err)); + return err; + } + + p = find_tlv (buffer, buflen, 1, &n); + if (p && n == 12) + { + char tmp[12+2+1]; + memcpy (tmp, p, 3); + tmp[3] = '-'; + memcpy (tmp+4, p+3, 7); + tmp[11] = '-'; + memcpy (tmp+12, p+10, 2); + tmp[14] = 0; + send_status_info (ctrl, name, tmp, strlen (tmp), NULL, 0); + xfree (buffer); + return 0; + } + xfree (buffer); + } + + } + return gpg_error (GPG_ERR_INV_NAME); +} + + + + /* Micardo cards require special treatment. This is a helper for the crypto functions to manage the security environment. We expect that the key file has already been selected. FID is the one of the @@ -3086,6 +3174,38 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, } +/* Handler for the PKAUTH command. + + This is basically the same as the PKSIGN command but we firstcheck + that the requested key is suitable for authentication; that is, it + must match the criteria used for the attribute $AUTHKEYID. See + do_sign for calling conventions; there is no HASHALGO, though. */ +static gpg_error_t +do_auth (app_t app, const char *keyidstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const void *indata, size_t indatalen, + unsigned char **outdata, size_t *outdatalen ) +{ + gpg_error_t err; + prkdf_object_t prkdf; + + if (!keyidstr || !*keyidstr) + return gpg_error (GPG_ERR_INV_VALUE); + + err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf); + if (err) + return err; + if (!prkdf->usageflags.sign) + { + log_error ("key %s may not be used for authentication\n", keyidstr); + return gpg_error (GPG_ERR_WRONG_KEY_USAGE); + } + return do_sign (app, keyidstr, GCRY_MD_SHA1, pincb, pincb_arg, + indata, indatalen, outdata, outdatalen); +} + + /* Assume that EF(DIR) has been selected. Read its content and figure out the home EF of pkcs#15. Return that home DF or 0 if not found @@ -3270,11 +3390,11 @@ app_select_p15 (app_t app) app->fnc.deinit = do_deinit; app->fnc.learn_status = do_learn_status; app->fnc.readcert = do_readcert; - app->fnc.getattr = NULL; + app->fnc.getattr = do_getattr; app->fnc.setattr = NULL; app->fnc.genkey = NULL; app->fnc.sign = do_sign; - app->fnc.auth = NULL; + app->fnc.auth = do_auth; app->fnc.decipher = NULL; app->fnc.change_pin = NULL; app->fnc.check_pin = NULL; @@ -3286,5 +3406,3 @@ app_select_p15 (app_t app) return rc; } - - diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 096a6811b..f82d93b00 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * ALTERNATIVELY, this file may be distributed under the terms of the * following license, in which case the provisions of this license are diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h index 82feed5c9..1b9ac2f85 100644 --- a/scd/ccid-driver.h +++ b/scd/ccid-driver.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * ALTERNATIVELY, this file may be distributed under the terms of the * following license, in which case the provisions of this license are diff --git a/scd/iso7816.c b/scd/iso7816.c index 484906251..5b985324f 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * $Id$ */ diff --git a/scd/iso7816.h b/scd/iso7816.h index 828fabb01..04c7ae63e 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * $Id$ */ diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c index f149e785a..23e8442f7 100644 --- a/scd/pcsc-wrapper.c +++ b/scd/pcsc-wrapper.c @@ -819,7 +819,6 @@ main (int argc, char **argv) fprintf (stderr, PGM ": invalid request 0x%02X\n", c); exit (1); } - free (argbuffer); } return 0; } diff --git a/sm/ChangeLog b/sm/ChangeLog index a76f586eb..41cf7bd35 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,9 @@ +2005-09-08 Werner Koch + + * export.c (popen_protect_tool): Add option --have-cert. We + probably lost this option with 1.9.14 due to restructuring of + export.c. + 2005-07-21 Werner Koch * gpgsm.c (main): New options --no-log-file and --debug-none. diff --git a/sm/export.c b/sm/export.c index b4450b2c2..f9d6dac62 100644 --- a/sm/export.c +++ b/sm/export.c @@ -520,6 +520,7 @@ popen_protect_tool (const char *pgmname, argv[i++] = "--homedir"; argv[i++] = opt.homedir; argv[i++] = "--p12-export"; + argv[i++] = "--have-cert"; argv[i++] = "--prompt"; argv[i++] = prompt?prompt:""; argv[i++] = "--enable-status-msg"; -- cgit From 4a31738bd1a302c76333a32b72ffc5ab78c71103 Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Sat, 1 Apr 2006 11:04:14 +0000 Subject: 2006-04-01 Moritz Schulte * command-ssh.c (ssh_identity_register): Make KEY_GRIP_RAW be 20 instead of 21 bytes long; do not fill KEY_GRIP_RAW[20] with NUL byte - KEY_GRIP_RAW is a raw binary string anyway. --- agent/ChangeLog | 6 ++++++ agent/command-ssh.c | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index fbb1a37e0..ed4c8a4cb 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,9 @@ +2006-04-01 Moritz Schulte + + * command-ssh.c (ssh_identity_register): Make KEY_GRIP_RAW be 20 + instead of 21 bytes long; do not fill KEY_GRIP_RAW[20] with NUL + byte - KEY_GRIP_RAW is a raw binary string anyway. + 2006-02-09 Werner Koch * call-scd.c (struct scd_local_s): New field next_local. diff --git a/agent/command-ssh.c b/agent/command-ssh.c index b8f0d20b0..be2a8385d 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2321,7 +2321,7 @@ static gpg_error_t ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) { gpg_error_t err; - unsigned char key_grip_raw[21]; + unsigned char key_grip_raw[20]; char key_grip[41]; unsigned char *buffer = NULL; unsigned int buffer_n; @@ -2334,8 +2334,6 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl) if (err) goto out; - key_grip_raw[sizeof (key_grip_raw) - 1] = 0; /* FIXME: Why?? */ - /* Check whether the key is already in our key storage. Don't do anything then. */ if ( !agent_key_available (key_grip_raw) ) -- cgit From 76cb368202383d28308b6a688348e11d4f5b507b Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Sun, 9 Apr 2006 11:31:37 +0000 Subject: 2006-04-09 Moritz Schulte * command-ssh.c (ssh_request_process): Removed FIXME mentioning a possible DoS attack. --- agent/ChangeLog | 5 +++++ agent/command-ssh.c | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index ed4c8a4cb..a2c240e2e 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,8 @@ +2006-04-09 Moritz Schulte + + * command-ssh.c (ssh_request_process): Removed FIXME mentioning a + possible DoS attack. + 2006-04-01 Moritz Schulte * command-ssh.c (ssh_identity_register): Make KEY_GRIP_RAW be 20 diff --git a/agent/command-ssh.c b/agent/command-ssh.c index be2a8385d..23f083c2f 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1,5 +1,5 @@ /* command-ssh.c - gpg-agent's ssh-agent emulation layer - * Copyright (C) 2004, 2005 Free Software Foundation, Inc. + * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -2677,10 +2677,13 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) secret key material. The response does not have to be stored in secure memory, since we never give out secret keys. - FIXME: This is a pretty good DoS. We only have a limited amount - of secure memory, we can't throw in everything we get from a - client -wk */ - + Note: we only have little secure memory, but there is NO + possibility of DoS here; only trusted clients are allowed to + connect to the agent. What could happen is that the agent + returns out-of-secure-memory errors on requests in case the + agent's owner floods his own agent with many large messages. + -moritz */ + /* Retrieve request. */ err = stream_read_string (stream_sock, 1, &request_data, &request_data_size); if (err) -- cgit From f98537733ac96fd7e786286944fd3c2696229c4f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Jun 2006 17:21:37 +0000 Subject: Updated FSF's address. --- Makefile.am | 3 ++- NEWS | 3 +++ TODO | 5 ++--- agent/Makefile.am | 3 ++- agent/agent.h | 3 ++- agent/cache.c | 3 ++- agent/call-scd.c | 3 ++- agent/command-ssh.c | 4 ++-- agent/command.c | 3 ++- agent/divert-scd.c | 3 ++- agent/findkey.c | 3 ++- agent/genkey.c | 3 ++- agent/gpg-agent.c | 3 ++- agent/learncard.c | 3 ++- agent/minip12.c | 3 ++- agent/minip12.h | 3 ++- agent/pkdecrypt.c | 3 ++- agent/pksign.c | 3 ++- agent/preset-passphrase.c | 3 ++- agent/protect-tool.c | 3 ++- agent/protect.c | 3 ++- agent/query.c | 3 ++- agent/t-protect.c | 3 ++- agent/trans.c | 3 ++- agent/trustlist.c | 3 ++- am/cmacros.am | 3 ++- common/Makefile.am | 3 ++- common/asshelp.c | 3 ++- common/asshelp.h | 3 ++- common/b64enc.c | 3 ++- common/dynload.h | 3 ++- common/errors.h | 3 ++- common/estream.c | 37 +++++++++++++++++++------------------ common/estream.h | 37 +++++++++++++++++++------------------ common/exechelp.c | 3 ++- common/exechelp.h | 3 ++- common/gettime.c | 3 ++- common/homedir.c | 3 ++- common/i18n.h | 3 ++- common/iobuf.c | 3 ++- common/iobuf.h | 3 ++- common/isascii.c | 3 ++- common/maperror.c | 3 ++- common/membuf.c | 3 ++- common/membuf.h | 3 ++- common/miscellaneous.c | 3 ++- common/mkerrors | 3 ++- common/mkerrtok | 3 ++- common/sexp-parse.h | 3 ++- common/sexputil.c | 3 ++- common/signal.c | 3 ++- common/simple-gettext.c | 3 ++- common/simple-pwquery.c | 3 ++- common/simple-pwquery.h | 3 ++- common/sysutils.c | 3 ++- common/sysutils.h | 3 ++- common/ttyio.c | 3 ++- common/ttyio.h | 3 ++- common/util.h | 3 ++- common/vasprintf.c | 4 ++-- common/w32reg.c | 3 ++- common/xasprintf.c | 3 ++- common/xreadline.c | 3 ++- common/yesno.c | 3 ++- configure.ac | 3 ++- doc/Makefile.am | 3 ++- doc/gnupg-card-architecture.fig | 3 ++- g10/Makefile.am | 3 ++- g10/call-agent.c | 3 ++- g10/call-agent.h | 3 ++- g10/comment.c | 3 ++- g10/gpg.c | 9 +++++++++ g10/gpg.h | 3 ++- g10/pkglue.c | 3 ++- g10/pkglue.h | 3 ++- include/_regex.h | 4 ++-- include/errors.h | 3 ++- include/memory.h | 3 ++- include/mpi.h | 3 ++- include/util.h | 3 ++- jnlib/Makefile.am | 3 ++- jnlib/argparse.c | 30 ++++++++++++++++-------------- jnlib/argparse.h | 3 ++- jnlib/dotlock.c | 3 ++- jnlib/dotlock.h | 3 ++- jnlib/libjnlib-config.h | 3 ++- jnlib/logging.c | 3 ++- jnlib/logging.h | 3 ++- jnlib/mischelp.h | 3 ++- jnlib/stringhelp.c | 3 ++- jnlib/stringhelp.h | 3 ++- jnlib/strlist.c | 3 ++- jnlib/strlist.h | 3 ++- jnlib/types.h | 3 ++- jnlib/utf8conv.c | 3 ++- jnlib/utf8conv.h | 3 ++- jnlib/w32-afunix.c | 3 ++- jnlib/w32-afunix.h | 3 ++- jnlib/w32-pth.c | 3 ++- jnlib/w32-pth.h | 3 ++- jnlib/xmalloc.c | 3 ++- jnlib/xmalloc.h | 3 ++- kbx/Makefile.am | 3 ++- kbx/kbxutil.c | 3 ++- kbx/keybox-blob.c | 3 ++- kbx/keybox-defs.h | 3 ++- kbx/keybox-dump.c | 3 ++- kbx/keybox-file.c | 3 ++- kbx/keybox-init.c | 3 ++- kbx/keybox-openpgp.c | 3 ++- kbx/keybox-search-desc.h | 3 ++- kbx/keybox-search.c | 3 ++- kbx/keybox-update.c | 3 ++- kbx/keybox-util.c | 3 ++- kbx/keybox.h | 3 ++- kbx/mkerrors | 3 ++- scd/Makefile.am | 3 ++- scd/app-common.h | 3 ++- scd/app-dinsig.c | 3 ++- scd/app-help.c | 3 ++- scd/app-nks.c | 3 ++- scd/app-openpgp.c | 3 ++- scd/app-p15.c | 3 ++- scd/app.c | 3 ++- scd/atr.c | 3 ++- scd/atr.h | 3 ++- scd/card-common.h | 3 ++- scd/card-dinsig.c | 3 ++- scd/card-p15.c | 3 ++- scd/card.c | 3 ++- scd/command.c | 3 ++- scd/sc-copykeys.c | 3 ++- scd/scdaemon.c | 3 ++- scd/scdaemon.h | 3 ++- scd/tlv.c | 3 ++- scd/tlv.h | 3 ++- scripts/compile | 3 ++- scripts/config.guess | 3 ++- sm/ChangeLog | 7 +++++++ sm/Makefile.am | 3 ++- sm/base64.c | 3 ++- sm/call-agent.c | 3 ++- sm/call-dirmngr.c | 3 ++- sm/certchain.c | 3 ++- sm/certcheck.c | 3 ++- sm/certdump.c | 3 ++- sm/certlist.c | 3 ++- sm/certreqgen.c | 3 ++- sm/decrypt.c | 3 ++- sm/delete.c | 3 ++- sm/encrypt.c | 3 ++- sm/export.c | 3 ++- sm/fingerprint.c | 3 ++- sm/gpgsm.c | 16 ++++++++++++---- sm/gpgsm.h | 3 ++- sm/import.c | 3 ++- sm/keydb.c | 3 ++- sm/keydb.h | 3 ++- sm/keylist.c | 7 ++++++- sm/misc.c | 3 ++- sm/qualified.c | 3 ++- sm/server.c | 3 ++- sm/sign.c | 3 ++- sm/verify.c | 3 ++- tests/Makefile.am | 3 ++- tests/asschk.c | 3 ++- tests/pkits/Makefile.am | 3 ++- tests/pkits/common.sh | 3 ++- tests/pkits/import-all-certs | 3 ++- tests/pkits/validate-all-certs | 3 ++- tools/Makefile.am | 3 ++- tools/gpg-connect-agent.c | 3 ++- tools/gpgconf-comp.c | 36 +++++++++++++++++++----------------- tools/gpgconf.c | 3 ++- tools/gpgconf.h | 3 ++- tools/gpgkey2ssh.c | 37 +++++++++++++++++++------------------ tools/gpgparsemail.c | 3 ++- tools/no-libgcrypt.c | 3 ++- tools/symcryptrun.c | 3 ++- tools/watchgnupg.c | 3 ++- 180 files changed, 469 insertions(+), 265 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/Makefile.am b/Makefile.am index 9fafb1102..0c5fbe4c3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/NEWS b/NEWS index 6413242c6..679bf7d5b 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,9 @@ Noteworthy changes in version 1.9.21 * [scdaemon] Added --hash=xxx option to the PKSIGN command. + * [gpg-protect-tool] Does now create a MAC for P12 files. This is for + better interoperability. + Noteworthy changes in version 1.9.20 (2005-12-20) ------------------------------------------------- diff --git a/TODO b/TODO index 7958ed18e..da3a76e06 100644 --- a/TODO +++ b/TODO @@ -21,7 +21,7 @@ might want to have an agent context for each service request ** When a certificate chain was sucessfully verified, make ephemeral certs used in this chain permanent. ** Try to keep certificate references somewhere This will help with some of our caching code. We also need to test - that cachining; in particular "regtp_ca_chainlen". + that caching; in particular "regtp_ca_chainlen". * sm/decrypt.c ** replace leading zero in integer hack by a cleaner solution @@ -101,7 +101,6 @@ might want to have an agent context for each service request * sm/ -** --include-certs is as of now still a dummy command line option ** check that we issue NO_SECKEY xxx if a -u key was not found * gpg/ @@ -117,4 +116,4 @@ might want to have an agent context for each service request ** ttyio Add completion support. ** yesno - Update to gpg 1.4.3 version \ No newline at end of file + Update to gpg 1.4.3 version diff --git a/agent/Makefile.am b/agent/Makefile.am index bc96531e0..961f0bb97 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/agent/agent.h b/agent/agent.h index 1542d6b9f..fdfe510fb 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef AGENT_H diff --git a/agent/cache.c b/agent/cache.c index 32b6ac0c7..2f468396d 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/call-scd.c b/agent/call-scd.c index ff241ce41..d0d24f9d5 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 23f083c2f..18375a9ae 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -15,8 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* Only v2 of the ssh-agent protocol is implemented. */ diff --git a/agent/command.c b/agent/command.c index daf9b8698..12770dac8 100644 --- a/agent/command.c +++ b/agent/command.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* FIXME: we should not use the default assuan buffering but setup diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 926df2622..3dc7984e6 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/findkey.c b/agent/findkey.c index 73ffb530d..3f793e5dd 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/genkey.c b/agent/genkey.c index d0319f7b4..04ee865f4 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 22bd5589d..fc2a2001a 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/learncard.c b/agent/learncard.c index 72238507f..8ddf4ee54 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/minip12.c b/agent/minip12.c index 6f99bf24d..912d387d8 100644 --- a/agent/minip12.c +++ b/agent/minip12.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef HAVE_CONFIG_H diff --git a/agent/minip12.h b/agent/minip12.h index 2fbb490d7..6275f9ccb 100644 --- a/agent/minip12.h +++ b/agent/minip12.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef MINIP12_H diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 1d64c1b15..f61f0f844 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/pksign.c b/agent/pksign.c index e9df19351..9863f9de0 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c index 6a9f07a3e..013c9411d 100644 --- a/agent/preset-passphrase.c +++ b/agent/preset-passphrase.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 5f59d5e06..bb14ca1e1 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/protect.c b/agent/protect.c index 45bdae496..19f6ccbc6 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/query.c b/agent/query.c index a5a3d0153..0516bec03 100644 --- a/agent/query.c +++ b/agent/query.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/t-protect.c b/agent/t-protect.c index fee3c561d..9ddd49414 100644 --- a/agent/t-protect.c +++ b/agent/t-protect.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/trans.c b/agent/trans.c index 7fa5e3d6b..5eb7d25c0 100644 --- a/agent/trans.c +++ b/agent/trans.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* To avoid any problems with the gettext implementation (there used diff --git a/agent/trustlist.c b/agent/trustlist.c index edb00650d..d234af692 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/am/cmacros.am b/am/cmacros.am index de68b6f31..7b449e2c0 100644 --- a/am/cmacros.am +++ b/am/cmacros.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. localedir = $(datadir)/locale diff --git a/common/Makefile.am b/common/Makefile.am index 34819e93f..085440bb3 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/common/asshelp.c b/common/asshelp.c index 0edaeae0e..1da899522 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/asshelp.h b/common/asshelp.h index 2d6dc79e6..9f4b5806b 100644 --- a/common/asshelp.h +++ b/common/asshelp.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_ASSHELP_H diff --git a/common/b64enc.c b/common/b64enc.c index 5b7a42ab3..bfc49deb6 100644 --- a/common/b64enc.c +++ b/common/b64enc.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/dynload.h b/common/dynload.h index 2c074141f..9b67fa9ed 100644 --- a/common/dynload.h +++ b/common/dynload.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_DYNLOAD_H diff --git a/common/errors.h b/common/errors.h index f34f3ba79..131891f65 100644 --- a/common/errors.h +++ b/common/errors.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_ERRORS_H diff --git a/common/estream.c b/common/estream.c index 70b3d9c6e..c2030371b 100644 --- a/common/estream.c +++ b/common/estream.c @@ -1,22 +1,23 @@ /* estream.c - Extended stream I/O/ Library - Copyright (C) 2004 g10 Code GmbH - - This file is part of Libestream. - - Libestream is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - Libestream 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 General Public License - along with Libestream; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of Libestream. + * + * Libestream is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * Libestream 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 General Public License + * along with Libestream; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ #ifdef USE_ESTREAM_SUPPORT_H # include diff --git a/common/estream.h b/common/estream.h index ebe575926..a9b4847c8 100644 --- a/common/estream.h +++ b/common/estream.h @@ -1,22 +1,23 @@ /* estream.h - Extended stream I/O/ Library - Copyright (C) 2004 g10 Code GmbH - - This file is part of Libestream. - - Libestream is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - Libestream 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 General Public License - along with Libestream; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of Libestream. + * + * Libestream is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * Libestream 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 General Public License + * along with Libestream; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ #ifndef ESTREAM_H #define ESTREAM_H diff --git a/common/exechelp.c b/common/exechelp.c index dc0a6b0e1..e64b69022 100644 --- a/common/exechelp.c +++ b/common/exechelp.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/exechelp.h b/common/exechelp.h index f00d18dd8..1df029b7e 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_EXECHELP_H diff --git a/common/gettime.c b/common/gettime.c index ecdc7df95..c4ea3283a 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/homedir.c b/common/homedir.c index a118cbac1..39d6dce20 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/i18n.h b/common/i18n.h index 0e13dca4d..0187ba265 100644 --- a/common/i18n.h +++ b/common/i18n.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_I18N_H diff --git a/common/iobuf.c b/common/iobuf.c index bbb666f67..8f7374f8c 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/iobuf.h b/common/iobuf.h index 3b8f4b572..a3dd7f1c5 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_IOBUF_H diff --git a/common/isascii.c b/common/isascii.c index 565c71664..b71febe99 100644 --- a/common/isascii.c +++ b/common/isascii.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef HAVE_CONFIG_H diff --git a/common/maperror.c b/common/maperror.c index 9efd64338..06546b501 100644 --- a/common/maperror.c +++ b/common/maperror.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/membuf.c b/common/membuf.c index 75f6bdb2a..2d35fefab 100644 --- a/common/membuf.c +++ b/common/membuf.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/membuf.h b/common/membuf.h index c199363cc..9033be61e 100644 --- a/common/membuf.h +++ b/common/membuf.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_MEMBUF_H diff --git a/common/miscellaneous.c b/common/miscellaneous.c index e9f8ed27f..da74f65bc 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/mkerrors b/common/mkerrors index 5a1ef33da..994c61352 100755 --- a/common/mkerrors +++ b/common/mkerrors @@ -17,7 +17,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. cat < diff --git a/common/simple-gettext.c b/common/simple-gettext.c index b6b851c77..56a305fd8 100644 --- a/common/simple-gettext.c +++ b/common/simple-gettext.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* This is a simplified version of gettext written by Ulrich Drepper. diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index f156ca3f1..e405c1ec0 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* This module is intended as a standalone client implementation to diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h index e3270d6c5..5b941d06f 100644 --- a/common/simple-pwquery.h +++ b/common/simple-pwquery.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef SIMPLE_PWQUERY_H diff --git a/common/sysutils.c b/common/sysutils.c index a8f6f6f5d..3e52cdaa3 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/sysutils.h b/common/sysutils.h index 08198f685..c40dbfaa9 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_SYSUTILS_H diff --git a/common/ttyio.c b/common/ttyio.c index c9f41c626..38883afa5 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/ttyio.h b/common/ttyio.h index 6148d644a..32d159863 100644 --- a/common/ttyio.h +++ b/common/ttyio.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_TTYIO_H #define GNUPG_COMMON_TTYIO_H diff --git a/common/util.h b/common/util.h index 295d785c5..29106bf9c 100644 --- a/common/util.h +++ b/common/util.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_UTIL_H diff --git a/common/vasprintf.c b/common/vasprintf.c index 9efea33f2..4bed8de66 100644 --- a/common/vasprintf.c +++ b/common/vasprintf.c @@ -15,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street, +Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include diff --git a/common/w32reg.c b/common/w32reg.c index a85ac7348..84308e916 100644 --- a/common/w32reg.c +++ b/common/w32reg.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/xasprintf.c b/common/xasprintf.c index 46740a2e6..75ae18072 100644 --- a/common/xasprintf.c +++ b/common/xasprintf.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/xreadline.c b/common/xreadline.c index 23aa35269..8400df330 100644 --- a/common/xreadline.c +++ b/common/xreadline.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/yesno.c b/common/yesno.c index 737071691..9ca513740 100644 --- a/common/yesno.c +++ b/common/yesno.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/configure.ac b/configure.ac index f3066a0a9..d77093a63 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. # Process this file with autoconf to produce a configure script. AC_PREREQ(2.52) diff --git a/doc/Makefile.am b/doc/Makefile.am index 47dd36208..dae053ec2 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/doc/gnupg-card-architecture.fig b/doc/gnupg-card-architecture.fig index e5772cd0f..49351c720 100644 --- a/doc/gnupg-card-architecture.fig +++ b/doc/gnupg-card-architecture.fig @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. Landscape Center Metric diff --git a/g10/Makefile.am b/g10/Makefile.am index aeb24d7b3..fb54dd9f0 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/g10/call-agent.c b/g10/call-agent.c index 55fc62569..e3bd7ed57 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #if 0 /* let Emacs display a red warning */ diff --git a/g10/call-agent.h b/g10/call-agent.h index 71044e38b..d09b87e3a 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_G10_CALL_AGENT_H #define GNUPG_G10_CALL_AGENT_H diff --git a/g10/comment.c b/g10/comment.c index b52104cd7..193087107 100644 --- a/g10/comment.c +++ b/g10/comment.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/g10/gpg.c b/g10/gpg.c index 52ae553c1..4235f3f7a 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -356,6 +356,7 @@ enum cmd_and_opt_values oAllowMultisigVerification, oEnableDSA2, oDisableDSA2, + oDebugAllowRun, oNoop }; @@ -701,6 +702,8 @@ static ARGPARSE_OPTS opts[] = { { oNoRequireCrossCert, "no-require-cross-certification", 0, "@"}, { oAutoKeyLocate, "auto-key-locate", 2, "@"}, { oNoAutoKeyLocate, "no-auto-key-locate", 0, "@"}, + + { oDebugAllowRun, "debug_allow_run", 0, "@"}, {0,NULL,0,NULL} }; @@ -1684,6 +1687,7 @@ main (int argc, char **argv ) int with_fpr = 0; /* make an option out of --fingerprint */ int any_explicit_recipient = 0; int require_secmem=0,got_secmem=0; + int allow_run = 0; #ifdef __riscos__ opt.lock_once = 1; @@ -2663,6 +2667,8 @@ main (int argc, char **argv ) case oEnableDSA2: opt.flags.dsa2=1; break; case oDisableDSA2: opt.flags.dsa2=0; break; + case oDebugAllowRun: allow_run = 1; break; + case oNoop: break; default : pargs.err = configfp? 1:2; break; @@ -2716,6 +2722,9 @@ main (int argc, char **argv ) } #endif + if (!allow_run) + log_fatal ("This version of gpg is not ready for use, use gpg 1.4.x\n"); + /* FIXME: We should use logging to a file only in server mode; however we have not yet implemetyed that. Thus we try to get away with --batch as indication for logging to file diff --git a/g10/gpg.h b/g10/gpg.h index 8ef46fdca..100a8e349 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_G10_GPG_H #define GNUPG_G10_GPG_H diff --git a/g10/pkglue.c b/g10/pkglue.c index f062d8366..3f9669d27 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/g10/pkglue.h b/g10/pkglue.h index 43b82785b..866960bfd 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_G10_PKGLUE_H diff --git a/include/_regex.h b/include/_regex.h index fac441dc6..ddd002484 100644 --- a/include/_regex.h +++ b/include/_regex.h @@ -16,8 +16,8 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ #ifndef _REGEX_H #define _REGEX_H 1 diff --git a/include/errors.h b/include/errors.h index ed437fa99..f3269ce5b 100644 --- a/include/errors.h +++ b/include/errors.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_INCLUDE_ERRORS_H #define GNUPG_INCLUDE_ERRORS_H diff --git a/include/memory.h b/include/memory.h index 35719da62..2e2f8fdce 100644 --- a/include/memory.h +++ b/include/memory.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef G10_MEMORY_H diff --git a/include/mpi.h b/include/mpi.h index b732923a2..7402ef6d3 100644 --- a/include/mpi.h +++ b/include/mpi.h @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * Note: This code is heavily based on the GNU MP Library. * Actually it's the same code with only minor changes in the diff --git a/include/util.h b/include/util.h index c579c152e..1d6d01366 100644 --- a/include/util.h +++ b/include/util.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef G10_UTIL_H #define G10_UTIL_H diff --git a/jnlib/Makefile.am b/jnlib/Makefile.am index 69eac4bf7..5fd48495c 100644 --- a/jnlib/Makefile.am +++ b/jnlib/Makefile.am @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/jnlib/argparse.c b/jnlib/argparse.c index 980d1186c..15a7c546e 100644 --- a/jnlib/argparse.c +++ b/jnlib/argparse.c @@ -1,21 +1,22 @@ /* [argparse.c wk 17.06.97] Argument Parser for option handling * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. * - * This file is part of GnuPG. + * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * GnuPG 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 General Public License for more details. + * GnuPG 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * You should have received a copy of the GNU 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. */ #include @@ -904,7 +905,7 @@ strusage( int level ) switch( level ) { case 11: p = "foo"; break; case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2005 Free Software Foundation, Inc."; break; + case 14: p = "Copyright (C) 2006 Free Software Foundation, Inc."; break; case 15: p = "This program comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it\n" @@ -920,7 +921,8 @@ strusage( int level ) "GNU General Public License for more details.\n\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" -"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"; +"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n" +"USA.\n"; break; case 40: /* short and long usage */ case 41: p = ""; break; diff --git a/jnlib/argparse.h b/jnlib/argparse.h index e8922faa4..531622ea5 100644 --- a/jnlib/argparse.h +++ b/jnlib/argparse.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_ARGPARSE_H diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c index b7f892717..89edb7b91 100644 --- a/jnlib/dotlock.c +++ b/jnlib/dotlock.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/dotlock.h b/jnlib/dotlock.h index 2cb39008a..1c0f05cb2 100644 --- a/jnlib/dotlock.h +++ b/jnlib/dotlock.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_DOTLOCK_H diff --git a/jnlib/libjnlib-config.h b/jnlib/libjnlib-config.h index da3991432..ded6e057b 100644 --- a/jnlib/libjnlib-config.h +++ b/jnlib/libjnlib-config.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /**************** diff --git a/jnlib/logging.c b/jnlib/logging.c index c944006a5..20ba02ccd 100644 --- a/jnlib/logging.c +++ b/jnlib/logging.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ diff --git a/jnlib/logging.h b/jnlib/logging.h index b5c0bd741..3ad43b4ec 100644 --- a/jnlib/logging.h +++ b/jnlib/logging.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_LOGGING_H diff --git a/jnlib/mischelp.h b/jnlib/mischelp.h index 54da4cc1f..8e7f9c346 100644 --- a/jnlib/mischelp.h +++ b/jnlib/mischelp.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_MISCHELP_H diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c index 27b8a25e8..9df852754 100644 --- a/jnlib/stringhelp.c +++ b/jnlib/stringhelp.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h index 405d6dbc4..b8f4dbec0 100644 --- a/jnlib/stringhelp.h +++ b/jnlib/stringhelp.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_STRINGHELP_H diff --git a/jnlib/strlist.c b/jnlib/strlist.c index 52b4d5869..87e121705 100644 --- a/jnlib/strlist.c +++ b/jnlib/strlist.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/strlist.h b/jnlib/strlist.h index 3c1252a44..ee9f1fa60 100644 --- a/jnlib/strlist.h +++ b/jnlib/strlist.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_STRLIST_H diff --git a/jnlib/types.h b/jnlib/types.h index 934b7a6ee..89d245943 100644 --- a/jnlib/types.h +++ b/jnlib/types.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_TYPES_H diff --git a/jnlib/utf8conv.c b/jnlib/utf8conv.c index 4df8b7b32..9fba1ed4f 100644 --- a/jnlib/utf8conv.c +++ b/jnlib/utf8conv.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/utf8conv.h b/jnlib/utf8conv.h index 6e2ce9944..344c47f92 100644 --- a/jnlib/utf8conv.h +++ b/jnlib/utf8conv.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_UTF8CONF_H diff --git a/jnlib/w32-afunix.c b/jnlib/w32-afunix.c index c93d389da..84d799f1f 100644 --- a/jnlib/w32-afunix.c +++ b/jnlib/w32-afunix.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef _WIN32 #include diff --git a/jnlib/w32-afunix.h b/jnlib/w32-afunix.h index 367832299..d0eb8cf7e 100644 --- a/jnlib/w32-afunix.h +++ b/jnlib/w32-afunix.h @@ -15,7 +15,8 @@ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef _WIN32 #ifndef W32AFUNIX_DEFS_H diff --git a/jnlib/w32-pth.c b/jnlib/w32-pth.c index 2f041c490..4107c7cb3 100644 --- a/jnlib/w32-pth.c +++ b/jnlib/w32-pth.c @@ -16,7 +16,8 @@ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * ------------------------------------------------------------------ * This code is based on Ralf Engelschall's GNU Pth, a non-preemptive diff --git a/jnlib/w32-pth.h b/jnlib/w32-pth.h index 5ef0ab240..524010d92 100644 --- a/jnlib/w32-pth.h +++ b/jnlib/w32-pth.h @@ -16,7 +16,8 @@ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * ------------------------------------------------------------------ * This code is based on Ralf Engelschall's GNU Pth, a non-preemptive diff --git a/jnlib/xmalloc.c b/jnlib/xmalloc.c index 1cfaab9f7..f5b92ba41 100644 --- a/jnlib/xmalloc.c +++ b/jnlib/xmalloc.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/xmalloc.h b/jnlib/xmalloc.h index 150ef3664..8bfa7df79 100644 --- a/jnlib/xmalloc.h +++ b/jnlib/xmalloc.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_XMALLOC_H diff --git a/kbx/Makefile.am b/kbx/Makefile.am index f42e517bf..063dbb4c0 100644 --- a/kbx/Makefile.am +++ b/kbx/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 0569b5a67..19d356007 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index eacc0014a..f3fe31617 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index 7bbed8519..ad53c71a7 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef KEYBOX_DEFS_H diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index 495fb249e..d28611377 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c index 3883ce607..e68e96cf9 100644 --- a/kbx/keybox-file.c +++ b/kbx/keybox-file.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index 46a29978a..6c01b4f3a 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index 7401949c9..8ac713979 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* This is a simple OpenPGP parser suitable for all OpenPGP key diff --git a/kbx/keybox-search-desc.h b/kbx/keybox-search-desc.h index 4be59c27d..f3a69d0f1 100644 --- a/kbx/keybox-search-desc.h +++ b/kbx/keybox-search-desc.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index 2ce3c1923..f95e6eb06 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index a16c18e23..bb43d287b 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c index ed5d93de0..6eb85ba3f 100644 --- a/kbx/keybox-util.c +++ b/kbx/keybox-util.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox.h b/kbx/keybox.h index af1fc4516..0f97fb7fc 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef KEYBOX_H diff --git a/kbx/mkerrors b/kbx/mkerrors index 5adb7bfdf..d3d096c5d 100755 --- a/kbx/mkerrors +++ b/kbx/mkerrors @@ -17,7 +17,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. cat < diff --git a/scd/app-nks.c b/scd/app-nks.c index 73ec8ea01..1ca8d4187 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 5e9281a38..842881f3a 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * $Id$ */ diff --git a/scd/app-p15.c b/scd/app-p15.c index 4203a6840..8a7732c85 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* Information pertaining to the BELPIC developer card samples: diff --git a/scd/app.c b/scd/app.c index 363e386ce..e3d42054b 100644 --- a/scd/app.c +++ b/scd/app.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/atr.c b/scd/atr.c index 6475e83f8..bd5a22621 100644 --- a/scd/atr.c +++ b/scd/atr.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/atr.h b/scd/atr.h index 5fdd57457..c70089ca5 100644 --- a/scd/atr.h +++ b/scd/atr.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef ATR_H diff --git a/scd/card-common.h b/scd/card-common.h index cefaf120f..dd7529d5b 100644 --- a/scd/card-common.h +++ b/scd/card-common.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef CARD_COMMON_H diff --git a/scd/card-dinsig.c b/scd/card-dinsig.c index df09bfb57..d50d758f2 100644 --- a/scd/card-dinsig.c +++ b/scd/card-dinsig.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* The German signature law and its bylaw (SigG and SigV) is currently diff --git a/scd/card-p15.c b/scd/card-p15.c index ae3ef148f..63d537d5a 100644 --- a/scd/card-p15.c +++ b/scd/card-p15.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/card.c b/scd/card.c index 9ec2a52c5..7a41ab7bb 100644 --- a/scd/card.c +++ b/scd/card.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/command.c b/scd/command.c index 2ed685587..4629d9edf 100644 --- a/scd/command.c +++ b/scd/command.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c index 66b6894e0..395b4625a 100644 --- a/scd/sc-copykeys.c +++ b/scd/sc-copykeys.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/scdaemon.c b/scd/scdaemon.c index e24b42132..b11cc7a91 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/scdaemon.h b/scd/scdaemon.h index abe9730a7..f9689ee09 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef SCDAEMON_H diff --git a/scd/tlv.c b/scd/tlv.c index b436d956a..6ddbeaf1f 100644 --- a/scd/tlv.c +++ b/scd/tlv.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/tlv.h b/scd/tlv.h index f587dd9df..877573d25 100644 --- a/scd/tlv.h +++ b/scd/tlv.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef SCD_TLV_H diff --git a/scripts/compile b/scripts/compile index ac07cc541..b6e6dcb0f 100755 --- a/scripts/compile +++ b/scripts/compile @@ -17,7 +17,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA.. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/scripts/config.guess b/scripts/config.guess index 77c7cbab0..a4929a979 100755 --- a/scripts/config.guess +++ b/scripts/config.guess @@ -17,7 +17,8 @@ timestamp='2004-08-13' # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA.. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/sm/ChangeLog b/sm/ChangeLog index 48e8473fa..f191e7512 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,10 @@ +2006-06-20 Werner Koch + + * gpgsm.c (gpgsm_init_default_ctrl): Take care of the command line + option --include-certs. + + * keylist.c (list_cert_raw): Print the certid. + 2006-05-23 Werner Koch * keydb.c (hextobyte): Deleted as it is now defined in jnlib. diff --git a/sm/Makefile.am b/sm/Makefile.am index b5882ae1d..be53e8d25 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/sm/base64.c b/sm/base64.c index 62c2c9ad9..59ab6f24b 100644 --- a/sm/base64.c +++ b/sm/base64.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/call-agent.c b/sm/call-agent.c index 9942672ae..85ec78c63 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 85467d4a2..0de09a9ba 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certchain.c b/sm/certchain.c index 44d72efd3..4a4ac49f6 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certcheck.c b/sm/certcheck.c index 5fb376712..732356149 100644 --- a/sm/certcheck.c +++ b/sm/certcheck.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certdump.c b/sm/certdump.c index 1f2ea7b18..0d5146abc 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certlist.c b/sm/certlist.c index b036a85d7..cde2930ec 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certreqgen.c b/sm/certreqgen.c index c523c992a..744969719 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* diff --git a/sm/decrypt.c b/sm/decrypt.c index 9e5518b0f..70d48c983 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/delete.c b/sm/delete.c index 7533f7291..0d2f1fd9d 100644 --- a/sm/delete.c +++ b/sm/delete.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/encrypt.c b/sm/encrypt.c index e4c0d5437..07c2ba8ce 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/export.c b/sm/export.c index f9d6dac62..b08a017d2 100644 --- a/sm/export.c +++ b/sm/export.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/fingerprint.c b/sm/fingerprint.c index 9441483bf..d6a3900f0 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 7347bf575..5363b8ad6 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1,5 +1,6 @@ /* gpgsm.c - GnuPG for S/MIME - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005, + * 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -15,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include @@ -461,6 +463,10 @@ static unsigned int debug_value; /* Option --enable-special-filenames */ static int allow_special_filenames; +/* Default value for include-certs. */ +static int default_include_certs = 1; /* Only include the signer's cert. */ + + static char *build_list (const char *text, const char *(*mapf)(int), int (*chkf)(int)); @@ -998,7 +1004,9 @@ main ( int argc, char **argv) ctrl.use_ocsp = opt.enable_ocsp = 1; break; - case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break; + case oIncludeCerts: + ctrl.include_certs = default_include_certs = pargs.r.ret_int; + break; case oPolicyFile: xfree (opt.policy_file); @@ -1657,7 +1665,7 @@ gpgsm_exit (int rc) void gpgsm_init_default_ctrl (struct server_control_s *ctrl) { - ctrl->include_certs = 1; /* only include the signer's cert */ + ctrl->include_certs = default_include_certs; ctrl->use_ocsp = opt.enable_ocsp; } diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 438252050..b49f34640 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GPGSM_H diff --git a/sm/import.c b/sm/import.c index 6d00e91ea..b56014a1a 100644 --- a/sm/import.c +++ b/sm/import.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/keydb.c b/sm/keydb.c index d5932135d..81936cf6a 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/keydb.h b/sm/keydb.h index fb4001b64..814ae9f1e 100644 --- a/sm/keydb.h +++ b/sm/keydb.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_KEYDB_H diff --git a/sm/keylist.c b/sm/keylist.c index b744a157f..9baf065d0 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include @@ -598,6 +599,10 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, fprintf (fp, " md5_fpr: %s\n", dn?dn:"error"); xfree (dn); + dn = gpgsm_get_certid (cert); + fprintf (fp, " certid: %s\n", dn?dn:"error"); + xfree (dn); + dn = gpgsm_get_keygrip_hexstring (cert); fprintf (fp, " keygrip: %s\n", dn?dn:"error"); xfree (dn); diff --git a/sm/misc.c b/sm/misc.c index cd072ce6b..86cb506d6 100644 --- a/sm/misc.c +++ b/sm/misc.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/qualified.c b/sm/qualified.c index 07abaadc4..474e1488d 100644 --- a/sm/qualified.c +++ b/sm/qualified.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/server.c b/sm/server.c index 87a06ee4e..57e5d8f38 100644 --- a/sm/server.c +++ b/sm/server.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/sign.c b/sm/sign.c index 74bfe41aa..d656825e8 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/verify.c b/sm/verify.c index f37cf4a75..4e6574078 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/tests/Makefile.am b/tests/Makefile.am index 5264b8859..38b64c6ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/tests/asschk.c b/tests/asschk.c index 6a05fe1a8..40b95ba7d 100644 --- a/tests/asschk.c +++ b/tests/asschk.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* This is a simple stand-alone Assuan server test program. We don't diff --git a/tests/pkits/Makefile.am b/tests/pkits/Makefile.am index 41fdec497..d53d35a25 100644 --- a/tests/pkits/Makefile.am +++ b/tests/pkits/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/tests/pkits/common.sh b/tests/pkits/common.sh index 5e773ea5d..09fb62bc8 100644 --- a/tests/pkits/common.sh +++ b/tests/pkits/common.sh @@ -16,7 +16,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. # reset some environment variables because we do not want to test locals export LANG=C diff --git a/tests/pkits/import-all-certs b/tests/pkits/import-all-certs index d1af5fb03..2d70d06df 100755 --- a/tests/pkits/import-all-certs +++ b/tests/pkits/import-all-certs @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. . ${srcdir:-.}/common.sh || exit 2 diff --git a/tests/pkits/validate-all-certs b/tests/pkits/validate-all-certs index f482fdb51..08f72af71 100755 --- a/tests/pkits/validate-all-certs +++ b/tests/pkits/validate-all-certs @@ -16,7 +16,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. . ${srcdir:-.}/common.sh || exit 2 diff --git a/tools/Makefile.am b/tools/Makefile.am index d9ef8812a..6b4767a79 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. EXTRA_DIST = Manifest watchgnupg.c \ addgnupghome gpgsm-gencert.sh diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index c9a324fa8..90e321000 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 2da88bc49..04a61a193 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1,21 +1,23 @@ /* gpgconf-comp.c - Configuration utility for GnuPG. - Copyright (C) 2004 Free Software Foundation, Inc. - - This file is part of GnuPG. - - GnuPG is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GnuPG 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 - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GnuPG; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + * Copyright (C) 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GnuPG; if not, write to the Free Software Foundation, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ #if HAVE_CONFIG_H #include diff --git a/tools/gpgconf.c b/tools/gpgconf.c index dd505e99d..87ba45ae1 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/tools/gpgconf.h b/tools/gpgconf.h index 138380b6d..c083c26aa 100644 --- a/tools/gpgconf.h +++ b/tools/gpgconf.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GPGCONF_H diff --git a/tools/gpgkey2ssh.c b/tools/gpgkey2ssh.c index e874ab22e..3dcb6516e 100644 --- a/tools/gpgkey2ssh.c +++ b/tools/gpgkey2ssh.c @@ -1,22 +1,23 @@ /* gpgkey2ssh.c - Converter ... - Copyright (C) 2005 Free Software Foundation, Inc. - - This file is part of GnuPG. - - GnuPG is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GnuPG 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 General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG 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 General Public + * License for more details. + * + * You should have received a copy of the GNU 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. + */ #include diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c index 566f5747f..30759f9a4 100644 --- a/tools/gpgparsemail.c +++ b/tools/gpgparsemail.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c index 82f6a8bb5..636df10c6 100644 --- a/tools/no-libgcrypt.c +++ b/tools/no-libgcrypt.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index 075e0b444..406cbb2a2 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index 6cb570fbc..051ca50fe 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef HAVE_CONFIG_H -- cgit From 98c6970ad1c55d38d7e3d1ba4c97d01dacec281f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 27 Jun 2006 14:32:34 +0000 Subject: Various smaller changes --- NEWS | 5 +++++ TODO | 4 ++++ agent/ChangeLog | 11 +++++++++++ agent/command-ssh.c | 18 +++++++----------- agent/gpg-agent.c | 3 ++- configure.ac | 4 ++-- sm/ChangeLog | 5 +++++ sm/certchain.c | 2 ++ sm/certdump.c | 30 ++++++++++++++++++++++++++++++ sm/gpgsm.h | 2 ++ sm/keylist.c | 2 +- 11 files changed, 71 insertions(+), 15 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/NEWS b/NEWS index b85f1aef6..7fafd44d3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Noteworthy changes in version 1.9.22 +------------------------------------------------- + + + Noteworthy changes in version 1.9.21 (2006-06-20) ------------------------------------------------- diff --git a/TODO b/TODO index da3a76e06..0650361c6 100644 --- a/TODO +++ b/TODO @@ -111,6 +111,10 @@ might want to have an agent context for each service request anyway. ** skclist.c:random_is_faked Remove the whole stuff? +** qbits + We pass a new qbit parameter to genkey - implement this in libgcrypt. +** Makefile.am + Remove the no-pointer-sign kludge. * common/ ** ttyio diff --git a/agent/ChangeLog b/agent/ChangeLog index 7c4799d1c..a194e0d2e 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,14 @@ +2006-06-26 Werner Koch + + * gpg-agent.c (handle_signal): Print infor for SIGUSR2 only in + verbose mode. + +2006-06-22 Werner Koch + + * command-ssh.c (make_cstring): Use memcpy instead of strncpy. + (ssh_receive_mpint_list, sexp_key_extract, data_sign): Use + xtrycalloc instead of xtrymalloc followed by memset. + 2006-06-20 Werner Koch * minip12.c (create_final): New arg PW. Add code to calculate the diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 18375a9ae..4e81aa2f2 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -268,7 +268,7 @@ make_cstring (const char *data, size_t data_n) s = xtrymalloc (data_n + 1); if (s) { - strncpy (s, data, data_n); + memcpy (s, data, data_n); s[data_n] = 0; } @@ -853,14 +853,12 @@ ssh_receive_mpint_list (estream_t stream, int secret, elems_public = key_spec.elems_key_public; elems_public_n = strlen (elems_public); - mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1)); - if (! mpis) + mpis = xtrycalloc (elems_n + 1, sizeof *mpis ); + if (!mpis) { err = gpg_error_from_errno (errno); goto out; } - - memset (mpis, 0, sizeof (*mpis) * (elems_n + 1)); elem_is_secret = 0; for (i = 0; i < elems_n; i++) @@ -1143,13 +1141,12 @@ sexp_key_extract (gcry_sexp_t sexp, } elems_n = strlen (elems); - mpis_new = xtrymalloc (sizeof (*mpis_new) * (elems_n + 1)); - if (! mpis_new) + mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new ); + if (!mpis_new) { err = gpg_error_from_errno (errno); goto out; } - memset (mpis_new, 0, sizeof (*mpis_new) * (elems_n + 1)); value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0); if (! value_list) @@ -2055,13 +2052,12 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, elems = spec.elems_signature; elems_n = strlen (elems); - mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1)); - if (! mpis) + mpis = xtrycalloc (elems_n + 1, sizeof *mpis); + if (!mpis) { err = gpg_error_from_errno (errno); goto out; } - memset (mpis, 0, sizeof (*mpis) * (elems_n + 1)); for (i = 0; i < elems_n; i++) { diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index fc2a2001a..24e0b588b 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1360,7 +1360,8 @@ handle_signal (int signo) break; case SIGUSR2: - log_info ("SIGUSR2 received - checking smartcard status\n"); + if (opt.verbose) + log_info ("SIGUSR2 received - checking smartcard status\n"); break; case SIGTERM: diff --git a/configure.ac b/configure.ac index eb29111a7..3f536e472 100644 --- a/configure.ac +++ b/configure.ac @@ -26,8 +26,8 @@ min_automake_version="1.9.3" # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.9.21]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.9.22]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([echo -n $((svn info 2>/dev/null \ diff --git a/sm/ChangeLog b/sm/ChangeLog index f191e7512..97fa8cd89 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,8 @@ +2006-06-26 Werner Koch + + * certdump.c (gpgsm_cert_log_name): New. + * certchain.c (is_cert_still_valid): Log the name of the certificate. + 2006-06-20 Werner Koch * gpgsm.c (gpgsm_init_default_ctrl): Take care of the command line diff --git a/sm/certchain.c b/sm/certchain.c index 4a4ac49f6..647adc030 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -597,6 +597,8 @@ is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp, { /* Fixme: We should change the wording because we may have used OCSP. */ + if (!lm) + gpgsm_cert_log_name (NULL, subject_cert); switch (gpg_err_code (err)) { case GPG_ERR_CERT_REVOKED: diff --git a/sm/certdump.c b/sm/certdump.c index 0d5146abc..2f7c1fd54 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -238,6 +238,36 @@ gpgsm_dump_cert (const char *text, ksba_cert_t cert) } +/* Log the certificate's name in "#SN/ISSUERDN" format along with + TEXT. */ +void +gpgsm_cert_log_name (const char *text, ksba_cert_t cert) +{ + log_info ("%s", text? text:"certificate" ); + if (cert) + { + ksba_sexp_t sn; + char *p; + + p = ksba_cert_get_issuer (cert, 0); + sn = ksba_cert_get_serial (cert); + if (p && sn) + { + log_printf (" #"); + gpgsm_dump_serial (sn); + log_printf ("/"); + gpgsm_dump_string (p); + } + else + log_printf (" [invalid]"); + ksba_free (sn); + xfree (p); + } + log_printf ("\n"); +} + + + /* helper for the rfc2253 string parser */ static const unsigned char * diff --git a/sm/gpgsm.h b/sm/gpgsm.h index b49f34640..0d9bac560 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -218,6 +218,8 @@ void gpgsm_print_time (FILE *fp, ksba_isotime_t t); void gpgsm_print_name2 (FILE *fp, const char *string, int translate); void gpgsm_print_name (FILE *fp, const char *string); +void gpgsm_cert_log_name (const char *text, ksba_cert_t cert); + void gpgsm_dump_cert (const char *text, ksba_cert_t cert); void gpgsm_dump_serial (ksba_const_sexp_t p); void gpgsm_dump_time (ksba_isotime_t t); diff --git a/sm/keylist.c b/sm/keylist.c index 9baf065d0..c44d62102 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -672,7 +672,7 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, else fputs ("[?]\n", fp); - fputs (" keyUsage:", fp); + fputs (" keyUsage: ", fp); err = ksba_cert_get_key_usage (cert, &kusage); if (gpg_err_code (err) != GPG_ERR_NO_DATA) { -- cgit