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. --- agent/findkey.c | 200 +++++++++++++++++++++++++++----------------------------- 1 file changed, 97 insertions(+), 103 deletions(-) (limited to 'agent/findkey.c') 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); } -- cgit v1.2.3