aboutsummaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
Diffstat (limited to 'agent')
-rw-r--r--agent/ChangeLog18
-rw-r--r--agent/Makefile.am6
-rw-r--r--agent/call-pinentry.c1
-rw-r--r--agent/call-scd.c40
-rw-r--r--agent/command.c38
-rw-r--r--agent/protect-tool.c274
6 files changed, 122 insertions, 255 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 10390da3f..e691ad7e6 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,21 @@
+2009-04-01 Werner Koch <[email protected]>
+
+ * protect-tool.c (pe_opt): New.
+ (opts): Add option --agent-program. Use ARGPARSE macros.
+ (get_new_passphrase): Remove.
+ (get_passphrase): Use gpg-agent directly. Remove arg OPT_CHECK and
+ change all callers.
+ * Makefile.am (gpg_protect_tool_LDADD): Replace pwquery_libs by
+ LIBASSUAN_LIBS.
+ (gpg_protect_tool_CFLAGS): New.
+
+ * command.c (percent_plus_unescape): Remove.
+ (cmd_putval): Use percent_plus_unescape_inplace.
+ * call-scd.c (unescape_status_string): Remove.
+ (card_getattr_cb): Use percent_plus_unescape.
+ * protect-tool.c (main): Use percent_plus_unescape from common/.
+ (percent_plus_unescape, percent_plus_unescape_string): Remove.
+
2009-03-27 Werner Koch <[email protected]>
* learncard.c (agent_handle_learn): Add new certtype 111.
diff --git a/agent/Makefile.am b/agent/Makefile.am
index 95ffafeec..c2830a94b 100644
--- a/agent/Makefile.am
+++ b/agent/Makefile.am
@@ -74,9 +74,9 @@ gpg_protect_tool_SOURCES = \
protect.c \
minip12.c minip12.h
-# Needs $(NETLIBS) for libsimple-pwquery.la.
-gpg_protect_tool_LDADD = $(pwquery_libs) $(common_libs) \
- $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV)
+gpg_protect_tool_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS)
+gpg_protect_tool_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \
+ $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV)
gpg_preset_passphrase_SOURCES = \
preset-passphrase.c
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 86792d8d7..c840bb68d 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -105,6 +105,7 @@ static void
dump_mutex_state (pth_mutex_t *m)
{
#ifdef _W32_PTH_H
+ (void)m;
log_printf ("unknown under W32");
#else
if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
diff --git a/agent/call-scd.c b/agent/call-scd.c
index f45e94097..d09812e57 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -136,6 +136,7 @@ static void
dump_mutex_state (pth_mutex_t *m)
{
#ifdef _W32_PTH_H
+ (void)m;
log_printf ("unknown under W32");
#else
if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
@@ -562,43 +563,6 @@ 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 ((const char*)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;
-}
-
-
-
static int
learn_status_cb (void *opaque, const char *line)
{
@@ -1045,7 +1009,7 @@ card_getattr_cb (void *opaque, const char *line)
if (keywordlen == parm->keywordlen
&& !memcmp (keyword, parm->keyword, keywordlen))
{
- parm->data = unescape_status_string ((const unsigned char*)line);
+ parm->data = percent_plus_unescape ((const unsigned char*)line, 0xff);
if (!parm->data)
parm->error = errno;
}
diff --git a/agent/command.c b/agent/command.c
index 56d390bd8..728b160a8 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -236,42 +236,6 @@ plus_to_blank (char *s)
}
-/* Do the percent and plus/space unescaping in place and return the
- length of the valid buffer. */
-static size_t
-percent_plus_unescape (char *string)
-{
- unsigned char *p = (unsigned char *)string;
- size_t n = 0;
-
- while (*string)
- {
- if (*string == '%' && string[1] && string[2])
- {
- string++;
- *p++ = xtoi_2 (string);
- n++;
- string+= 2;
- }
- else if (*string == '+')
- {
- *p++ = ' ';
- n++;
- string++;
- }
- else
- {
- *p++ = *string++;
- n++;
- }
- }
-
- return n;
-}
-
-
-
-
/* Parse a hex string. Return an Assuan error code or 0 on success and the
length of the parsed string in LEN. */
static int
@@ -1494,7 +1458,7 @@ cmd_putval (assuan_context_t ctx, char *line)
p = strchr (value, ' ');
if (p)
*p = 0;
- valuelen = percent_plus_unescape (value);
+ valuelen = percent_plus_unescape_inplace (value, 0);
}
}
if (!key || !*key)
diff --git a/agent/protect-tool.c b/agent/protect-tool.c
index 848ad9f4b..d0b68a1fa 100644
--- a/agent/protect-tool.c
+++ b/agent/protect-tool.c
@@ -41,13 +41,14 @@
#define JNLIB_NEED_LOG_LOGV
#include "agent.h"
#include "minip12.h"
-#include "simple-pwquery.h"
#include "i18n.h"
+#include "get-passphrase.h"
#include "sysutils.h"
enum cmd_and_opt_values
-{ aNull = 0,
+{
+ aNull = 0,
oVerbose = 'v',
oArmor = 'a',
oPassphrase = 'P',
@@ -72,17 +73,19 @@ enum cmd_and_opt_values
oPrompt,
oStatusMsg,
-aTest };
+ oAgentProgram
+};
+
struct rsa_secret_key_s
- {
- gcry_mpi_t n; /* public modulus */
- gcry_mpi_t e; /* public exponent */
- gcry_mpi_t d; /* exponent */
- gcry_mpi_t p; /* prime p. */
- gcry_mpi_t q; /* prime q. */
- gcry_mpi_t u; /* inverse of p mod q. */
- };
+{
+ gcry_mpi_t n; /* public modulus */
+ gcry_mpi_t e; /* public exponent */
+ gcry_mpi_t d; /* exponent */
+ gcry_mpi_t p; /* prime p. */
+ gcry_mpi_t q; /* prime q. */
+ gcry_mpi_t u; /* inverse of p mod q. */
+};
static const char *opt_homedir;
@@ -96,41 +99,51 @@ static const char *opt_passphrase;
static char *opt_prompt;
static int opt_status_msg;
static const char *opt_p12_charset;
+static const char *opt_agent_program;
-static char *get_passphrase (int promptno, int opt_check);
-static char *get_new_passphrase (int promptno);
+static char *get_passphrase (int promptno);
static void release_passphrase (char *pw);
static int store_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force);
static ARGPARSE_OPTS opts[] = {
+ ARGPARSE_group (300, N_("@Commands:\n ")),
+
+ ARGPARSE_c (oProtect, "protect", "protect a private key"),
+ ARGPARSE_c (oUnprotect, "unprotect", "unprotect a private key"),
+ ARGPARSE_c (oShadow, "shadow", "create a shadow entry for a public key"),
+ ARGPARSE_c (oShowShadowInfo, "show-shadow-info", "return the shadow info"),
+ ARGPARSE_c (oShowKeygrip, "show-keygrip", "show the \"keygrip\""),
+ ARGPARSE_c (oP12Import, "p12-import",
+ "import a pkcs#12 encoded private key"),
+ ARGPARSE_c (oP12Export, "p12-export",
+ "export a private key pkcs#12 encoded"),
- { 301, NULL, 0, N_("@Options:\n ") },
-
- { oVerbose, "verbose", 0, "verbose" },
- { oArmor, "armor", 0, "write output in advanced format" },
- { oCanonical, "canonical", 0, "write output in canonical format" },
- { 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 public key"},
- { oShowShadowInfo, "show-shadow-info", 256, "return the shadow info"},
- { oShowKeygrip, "show-keygrip", 256, "show the \"keygrip\""},
-
- { oP12Import, "p12-import", 256, "import a pkcs#12 encoded private key"},
- { oP12Export, "p12-export", 256, "export a private key pkcs#12 encoded"},
- { oP12Charset,"p12-charset", 2,
- "|NAME|set charset for a new PKCS#12 passphrase to NAME" },
- { oHaveCert, "have-cert", 0, "certificate to export provided on STDIN"},
- { oStore, "store", 0, "store the created key in the appropriate place"},
- { oForce, "force", 0, "force overwriting"},
- { oNoFailOnExist, "no-fail-on-exist", 0, "@" },
- { oHomedir, "homedir", 2, "@" },
- { oPrompt, "prompt", 2, "|ESCSTRING|use ESCSTRING as prompt in pinentry"},
- { oStatusMsg, "enable-status-msg", 0, "@"},
-
- {0}
+ ARGPARSE_group (301, N_("@\nOptions:\n ")),
+
+ ARGPARSE_s_n (oVerbose, "verbose", "verbose"),
+ ARGPARSE_s_n (oArmor, "armor", "write output in advanced format"),
+ ARGPARSE_s_n (oCanonical, "canonical", "write output in canonical format"),
+
+ ARGPARSE_s_s (oPassphrase, "passphrase", "|STRING|use passphrase STRING"),
+ ARGPARSE_s_s (oP12Charset,"p12-charset",
+ "|NAME|set charset for a new PKCS#12 passphrase to NAME"),
+ ARGPARSE_s_n (oHaveCert, "have-cert",
+ "certificate to export provided on STDIN"),
+ ARGPARSE_s_n (oStore, "store",
+ "store the created key in the appropriate place"),
+ ARGPARSE_s_n (oForce, "force",
+ "force overwriting"),
+ ARGPARSE_s_n (oNoFailOnExist, "no-fail-on-exist", "@"),
+ ARGPARSE_s_s (oHomedir, "homedir", "@"),
+ ARGPARSE_s_s (oPrompt, "prompt",
+ "|ESCSTRING|use ESCSTRING as prompt in pinentry"),
+ ARGPARSE_s_n (oStatusMsg, "enable-status-msg", "@"),
+
+ ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
+
+ ARGPARSE_end ()
};
static const char *
@@ -158,9 +171,6 @@ my_strusage (int level)
}
-/* Include the implementation of map_spwq_error. */
-MAP_SPWQ_ERROR_IMPL
-
/* static void */
/* print_mpi (const char *text, gcry_mpi_t a) */
/* { */
@@ -333,7 +343,7 @@ read_and_protect (const char *fname)
if (!key)
return;
- pw = get_passphrase (1, 0);
+ pw = get_passphrase (1);
rc = agent_protect (key, pw, &result, &resultlen);
release_passphrase (pw);
xfree (key);
@@ -372,7 +382,7 @@ read_and_unprotect (const char *fname)
if (!key)
return;
- rc = agent_unprotect (key, (pw=get_passphrase (1, 0)),
+ rc = agent_unprotect (key, (pw=get_passphrase (1)),
protected_at, &result, &resultlen);
release_passphrase (pw);
xfree (key);
@@ -678,7 +688,7 @@ import_p12_file (const char *fname)
buf_off = 0;
kparms = p12_parse ((unsigned char*)buf+buf_off, buflen-buf_off,
- (pw=get_passphrase (2, 0)),
+ (pw=get_passphrase (2)),
import_p12_cert_cb, NULL);
release_passphrase (pw);
xfree (buf);
@@ -753,12 +763,8 @@ import_p12_file (const char *fname)
assert (buflen);
gcry_sexp_release (s_key);
-
- pw = get_new_passphrase (4);
- if (!pw)
- rc = gpg_error (GPG_ERR_CANCELED);
- else
- rc = agent_protect (key, pw, &result, &resultlen);
+ pw = get_passphrase (4);
+ rc = agent_protect (key, pw, &result, &resultlen);
release_passphrase (pw);
xfree (key);
if (rc)
@@ -896,7 +902,7 @@ export_p12_file (const char *fname)
unsigned char *tmpkey;
size_t tmplen;
- rc = agent_unprotect (key, (pw=get_passphrase (1, 0)),
+ rc = agent_unprotect (key, (pw=get_passphrase (1)),
NULL, &tmpkey, &tmplen);
release_passphrase (pw);
if (rc)
@@ -985,11 +991,8 @@ export_p12_file (const char *fname)
kparms[7] = sk.u;
kparms[8] = NULL;
- pw = get_new_passphrase (3);
- if (!pw)
- key = NULL;
- else
- key = p12_build (kparms, cert, certlen, pw, opt_p12_charset, &keylen);
+ pw = get_passphrase (3);
+ key = p12_build (kparms, cert, certlen, pw, opt_p12_charset, &keylen);
release_passphrase (pw);
xfree (cert);
for (i=0; i < 8; i++)
@@ -1005,54 +1008,6 @@ export_p12_file (const char *fname)
}
-
-/* Do the percent and plus/space unescaping in place and return the
- length of the valid buffer. */
-static size_t
-percent_plus_unescape (unsigned char *string)
-{
- unsigned char *p = string;
- size_t n = 0;
-
- while (*string)
- {
- if (*string == '%' && string[1] && string[2])
- {
- string++;
- *p++ = xtoi_2 (string);
- n++;
- string+= 2;
- }
- else if (*string == '+')
- {
- *p++ = ' ';
- n++;
- string++;
- }
- else
- {
- *p++ = *string++;
- n++;
- }
- }
-
- return n;
-}
-
-/* Remove percent and plus escaping and make sure that the reuslt is a
- string. This is done in place. Returns STRING. */
-static char *
-percent_plus_unescape_string (char *string)
-{
- unsigned char *p = (unsigned char*)string;
- size_t n;
-
- n = percent_plus_unescape (p);
- p[n] = 0;
-
- return string;
-}
-
int
main (int argc, char **argv )
@@ -1094,6 +1049,8 @@ main (int argc, char **argv )
case oCanonical: opt_canonical=1; break;
case oHomedir: opt_homedir = pargs.r.ret_str; break;
+ case oAgentProgram: opt_agent_program = pargs.r.ret_str; break;
+
case oProtect: cmd = oProtect; break;
case oUnprotect: cmd = oUnprotect; break;
case oShadow: cmd = oShadow; break;
@@ -1111,11 +1068,11 @@ main (int argc, char **argv )
case oPrompt: opt_prompt = pargs.r.ret_str; break;
case oStatusMsg: opt_status_msg = 1; break;
- default : pargs.err = 2; break;
+ default: pargs.err = ARGPARSE_PRINT_ERROR; break;
}
}
- if (log_get_errorcount(0))
- exit(2);
+ if (log_get_errorcount (0))
+ exit (2);
fname = "-";
if (argc == 1)
@@ -1123,15 +1080,15 @@ main (int argc, char **argv )
else if (argc > 1)
usage (1);
- /* Tell simple-pwquery about the the standard socket name. */
- {
- char *tmp = make_filename (opt_homedir, "S.gpg-agent", NULL);
- simple_pw_set_socket (tmp);
- xfree (tmp);
- }
+ /* Set the information which can't be taken from envvars. */
+ gnupg_prepare_get_passphrase (GPG_ERR_SOURCE_DEFAULT,
+ opt.verbose,
+ opt_homedir,
+ opt_agent_program,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (opt_prompt)
- opt_prompt = percent_plus_unescape_string (xstrdup (opt_prompt));
+ opt_prompt = percent_plus_unescape (opt_prompt, 0);
if (cmd == oProtect)
read_and_protect (fname);
@@ -1169,102 +1126,65 @@ agent_exit (int rc)
2 = for unprotecting a pkcs#12 object
3 = for protecting a new pkcs#12 object
4 = for protecting an imported pkcs#12 in our system
- 5 = reenter the passphrase
- When adding 100 to the values, a "does not match - try again" error
- message is shown.
*/
static char *
-get_passphrase (int promptno, int opt_check)
+get_passphrase (int promptno)
{
char *pw;
int err;
const char *desc;
char *orig_codeset;
- int error_msgno;
+ int repeat = 0;
if (opt_passphrase)
return xstrdup (opt_passphrase);
- error_msgno = promptno / 100;
- promptno %= 100;
-
orig_codeset = i18n_switchto_utf8 ();
if (promptno == 1 && opt_prompt)
- desc = opt_prompt;
+ {
+ desc = opt_prompt;
+ }
else if (promptno == 2)
- desc = _("Please enter the passphrase to unprotect the "
- "PKCS#12 object.");
+ {
+ desc = _("Please enter the passphrase to unprotect the "
+ "PKCS#12 object.");
+ }
else if (promptno == 3)
- desc = _("Please enter the passphrase to protect the "
- "new PKCS#12 object.");
+ {
+ desc = _("Please enter the passphrase to protect the "
+ "new PKCS#12 object.");
+ repeat = 1;
+ }
else if (promptno == 4)
- desc = _("Please enter the passphrase to protect the "
- "imported object within the GnuPG system.");
- else if (promptno == 5)
- desc = _("Please re-enter this passphrase");
+ {
+ desc = _("Please enter the passphrase to protect the "
+ "imported object within the GnuPG system.");
+ repeat = 1;
+ }
else
desc = _("Please enter the passphrase or the PIN\n"
"needed to complete this operation.");
- pw = simple_pwquery (NULL,
- error_msgno == 1? _("does not match - try again"):NULL,
- _("Passphrase:"), desc, opt_check, &err);
- err = map_spwq_error (err);
-
i18n_switchback (orig_codeset);
- if (!pw)
+ err = gnupg_get_passphrase (NULL, NULL, _("Passphrase:"), desc,
+ repeat, repeat, 1, &pw);
+ if (err)
{
- if (err)
+ if (gpg_err_code (err) == GPG_ERR_CANCELED)
+ log_info (_("cancelled\n"));
+ else
log_error (_("error while asking for the passphrase: %s\n"),
gpg_strerror (err));
- else
- log_info (_("cancelled\n"));
agent_exit (0);
}
+ assert (pw);
return pw;
}
-/* Same as get_passphrase but requests it a second time and compares
- it to the one entered the first time. */
-static char *
-get_new_passphrase (int promptno)
-{
- char *pw;
- int i, secondpromptno;
-
- pw = get_passphrase (promptno, 1);
- if (!pw)
- return NULL; /* Canceled. */
- if (!*pw)
- return pw; /* Empty passphrase - no need to ask for repeating it. */
-
- secondpromptno = 5;
- for (i=0; i < 3; i++)
- {
- char *pw2 = get_passphrase (secondpromptno, 0);
- if (!pw2)
- {
- xfree (pw);
- return NULL; /* Canceled. */
- }
- if (!strcmp (pw, pw2))
- {
- xfree (pw2);
- return pw; /* Okay. */
- }
- secondpromptno = 105;
- xfree (pw2);
- }
- xfree (pw);
- return NULL; /* 3 times repeated wrong - cancel. */
-}
-
-
-
static void
release_passphrase (char *pw)
{