aboutsummaryrefslogtreecommitdiffstats
path: root/agent/findkey.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2005-02-03 17:40:02 +0000
committerWerner Koch <[email protected]>2005-02-03 17:40:02 +0000
commitb326996b784b561ab56af5b41037f60ae8a79849 (patch)
tree01ced87c39b865a5cb754985217c6692f5fa3097 /agent/findkey.c
parentForgot to commit the recent fixed to scd and logging - doing it now (diff)
downloadgnupg-b326996b784b561ab56af5b41037f60ae8a79849.tar.gz
gnupg-b326996b784b561ab56af5b41037f60ae8a79849.zip
* 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.
Diffstat (limited to 'agent/findkey.c')
-rw-r--r--agent/findkey.c200
1 files changed, 97 insertions, 103 deletions
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 -> <COMMENT>. */
-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);
}