1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-08 23:37:47 +02:00

agent: Let gpg-protect-tool pass envvars to pinentry.

* agent/protect-tool.c (opt_session_env): New.
(main): Pass session environment object to
gnupg_prepare_get_passphrase.
--
GnuPG-bug-id: 1402

The full story can be found at
https://bugzilla.redhat.com/show_bug.cgi?id=548528

Sorry for the delay.
This commit is contained in:
Werner Koch 2014-06-25 17:16:40 +02:00
parent 044847a0e2
commit 045c979a76

View File

@ -47,8 +47,8 @@
#include "estream.h" #include "estream.h"
enum cmd_and_opt_values enum cmd_and_opt_values
{ {
aNull = 0, aNull = 0,
oVerbose = 'v', oVerbose = 'v',
oArmor = 'a', oArmor = 'a',
@ -56,7 +56,7 @@ enum cmd_and_opt_values
oProtect = 'p', oProtect = 'p',
oUnprotect = 'u', oUnprotect = 'u',
oNoVerbose = 500, oNoVerbose = 500,
oShadow, oShadow,
oShowShadowInfo, oShowShadowInfo,
@ -73,13 +73,13 @@ enum cmd_and_opt_values
oNoFailOnExist, oNoFailOnExist,
oHomedir, oHomedir,
oPrompt, oPrompt,
oStatusMsg, oStatusMsg,
oAgentProgram oAgentProgram
}; };
struct rsa_secret_key_s struct rsa_secret_key_s
{ {
gcry_mpi_t n; /* public modulus */ gcry_mpi_t n; /* public modulus */
gcry_mpi_t e; /* public exponent */ gcry_mpi_t e; /* public exponent */
@ -101,7 +101,8 @@ static const char *opt_passphrase;
static char *opt_prompt; static char *opt_prompt;
static int opt_status_msg; static int opt_status_msg;
static const char *opt_p12_charset; static const char *opt_p12_charset;
static const char *opt_agent_program; static const char *opt_agent_program;
static session_env_t opt_session_env;
static char *get_passphrase (int promptno); static char *get_passphrase (int promptno);
static void release_passphrase (char *pw); static void release_passphrase (char *pw);
@ -117,13 +118,13 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (oShadow, "shadow", "create a shadow entry for a public 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 (oShowShadowInfo, "show-shadow-info", "return the shadow info"),
ARGPARSE_c (oShowKeygrip, "show-keygrip", "show the \"keygrip\""), ARGPARSE_c (oShowKeygrip, "show-keygrip", "show the \"keygrip\""),
ARGPARSE_c (oP12Import, "p12-import", ARGPARSE_c (oP12Import, "p12-import",
"import a pkcs#12 encoded private key"), "import a pkcs#12 encoded private key"),
ARGPARSE_c (oP12Export, "p12-export", ARGPARSE_c (oP12Export, "p12-export",
"export a private key pkcs#12 encoded"), "export a private key pkcs#12 encoded"),
ARGPARSE_c (oS2Kcalibration, "s2k-calibration", "@"), ARGPARSE_c (oS2Kcalibration, "s2k-calibration", "@"),
ARGPARSE_group (301, N_("@\nOptions:\n ")), ARGPARSE_group (301, N_("@\nOptions:\n ")),
ARGPARSE_s_n (oVerbose, "verbose", "verbose"), ARGPARSE_s_n (oVerbose, "verbose", "verbose"),
@ -135,14 +136,14 @@ static ARGPARSE_OPTS opts[] = {
"|NAME|set charset for a new PKCS#12 passphrase to NAME"), "|NAME|set charset for a new PKCS#12 passphrase to NAME"),
ARGPARSE_s_n (oHaveCert, "have-cert", ARGPARSE_s_n (oHaveCert, "have-cert",
"certificate to export provided on STDIN"), "certificate to export provided on STDIN"),
ARGPARSE_s_n (oStore, "store", ARGPARSE_s_n (oStore, "store",
"store the created key in the appropriate place"), "store the created key in the appropriate place"),
ARGPARSE_s_n (oForce, "force", ARGPARSE_s_n (oForce, "force",
"force overwriting"), "force overwriting"),
ARGPARSE_s_n (oNoFailOnExist, "no-fail-on-exist", "@"), ARGPARSE_s_n (oNoFailOnExist, "no-fail-on-exist", "@"),
ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_s (oPrompt, "prompt", ARGPARSE_s_s (oPrompt, "prompt",
"|ESCSTRING|use ESCSTRING as prompt in pinentry"), "|ESCSTRING|use ESCSTRING as prompt in pinentry"),
ARGPARSE_s_n (oStatusMsg, "enable-status-msg", "@"), ARGPARSE_s_n (oStatusMsg, "enable-status-msg", "@"),
ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
@ -168,7 +169,7 @@ my_strusage (int level)
case 41: p = _("Syntax: gpg-protect-tool [options] [args]\n" case 41: p = _("Syntax: gpg-protect-tool [options] [args]\n"
"Secret key maintenance tool\n"); "Secret key maintenance tool\n");
break; break;
default: p = NULL; default: p = NULL;
} }
return p; return p;
@ -249,7 +250,7 @@ read_file (const char *fname, size_t *r_length)
FILE *fp; FILE *fp;
char *buf; char *buf;
size_t buflen; size_t buflen;
if (!strcmp (fname, "-")) if (!strcmp (fname, "-"))
{ {
size_t nread, bufsize = 0; size_t nread, bufsize = 0;
@ -261,7 +262,7 @@ read_file (const char *fname, size_t *r_length)
buf = NULL; buf = NULL;
buflen = 0; buflen = 0;
#define NCHUNK 8192 #define NCHUNK 8192
do do
{ {
bufsize += NCHUNK; bufsize += NCHUNK;
if (!buf) if (!buf)
@ -292,14 +293,14 @@ read_file (const char *fname, size_t *r_length)
log_error ("can't open `%s': %s\n", fname, strerror (errno)); log_error ("can't open `%s': %s\n", fname, strerror (errno));
return NULL; return NULL;
} }
if (fstat (fileno(fp), &st)) if (fstat (fileno(fp), &st))
{ {
log_error ("can't stat `%s': %s\n", fname, strerror (errno)); log_error ("can't stat `%s': %s\n", fname, strerror (errno));
fclose (fp); fclose (fp);
return NULL; return NULL;
} }
buflen = st.st_size; buflen = st.st_size;
buf = xmalloc (buflen+1); buf = xmalloc (buflen+1);
if (fread (buf, buflen, 1, fp) != 1) if (fread (buf, buflen, 1, fp) != 1)
@ -323,7 +324,7 @@ read_key (const char *fname)
char *buf; char *buf;
size_t buflen; size_t buflen;
unsigned char *key; unsigned char *key;
buf = read_file (fname, &buflen); buf = read_file (fname, &buflen);
if (!buf) if (!buf)
return NULL; return NULL;
@ -342,7 +343,7 @@ read_and_protect (const char *fname)
unsigned char *result; unsigned char *result;
size_t resultlen; size_t resultlen;
char *pw; char *pw;
key = read_key (fname); key = read_key (fname);
if (!key) if (!key)
return; return;
@ -356,7 +357,7 @@ read_and_protect (const char *fname)
log_error ("protecting the key failed: %s\n", gpg_strerror (rc)); log_error ("protecting the key failed: %s\n", gpg_strerror (rc));
return; return;
} }
if (opt_armor) if (opt_armor)
{ {
char *p = make_advanced (result, resultlen); char *p = make_advanced (result, resultlen);
@ -386,7 +387,7 @@ read_and_unprotect (const char *fname)
if (!key) if (!key)
return; return;
rc = agent_unprotect (key, (pw=get_passphrase (1)), rc = agent_unprotect (key, (pw=get_passphrase (1)),
protected_at, &result, &resultlen); protected_at, &result, &resultlen);
release_passphrase (pw); release_passphrase (pw);
xfree (key); xfree (key);
@ -427,7 +428,7 @@ read_and_shadow (const char *fname)
unsigned char *result; unsigned char *result;
size_t resultlen; size_t resultlen;
unsigned char dummy_info[] = "(8:313233342:43)"; unsigned char dummy_info[] = "(8:313233342:43)";
key = read_key (fname); key = read_key (fname);
if (!key) if (!key)
return; return;
@ -441,7 +442,7 @@ read_and_shadow (const char *fname)
} }
resultlen = gcry_sexp_canon_len (result, 0, NULL,NULL); resultlen = gcry_sexp_canon_len (result, 0, NULL,NULL);
assert (resultlen); assert (resultlen);
if (opt_armor) if (opt_armor)
{ {
char *p = make_advanced (result, resultlen); char *p = make_advanced (result, resultlen);
@ -463,7 +464,7 @@ show_shadow_info (const char *fname)
unsigned char *key; unsigned char *key;
const unsigned char *info; const unsigned char *info;
size_t infolen; size_t infolen;
key = read_key (fname); key = read_key (fname);
if (!key) if (!key)
return; return;
@ -477,7 +478,7 @@ show_shadow_info (const char *fname)
} }
infolen = gcry_sexp_canon_len (info, 0, NULL,NULL); infolen = gcry_sexp_canon_len (info, 0, NULL,NULL);
assert (infolen); assert (infolen);
if (opt_armor) if (opt_armor)
{ {
char *p = make_advanced (info, infolen); char *p = make_advanced (info, infolen);
@ -497,14 +498,14 @@ show_file (const char *fname)
unsigned char *key; unsigned char *key;
size_t keylen; size_t keylen;
char *p; char *p;
key = read_key (fname); key = read_key (fname);
if (!key) if (!key)
return; return;
keylen = gcry_sexp_canon_len (key, 0, NULL,NULL); keylen = gcry_sexp_canon_len (key, 0, NULL,NULL);
assert (keylen); assert (keylen);
if (opt_canonical) if (opt_canonical)
{ {
fwrite (key, keylen, 1, stdout); fwrite (key, keylen, 1, stdout);
@ -528,7 +529,7 @@ show_keygrip (const char *fname)
gcry_sexp_t private; gcry_sexp_t private;
unsigned char grip[20]; unsigned char grip[20];
int i; int i;
key = read_key (fname); key = read_key (fname);
if (!key) if (!key)
return; return;
@ -537,7 +538,7 @@ show_keygrip (const char *fname)
{ {
log_error ("gcry_sexp_new failed\n"); log_error ("gcry_sexp_new failed\n");
return; return;
} }
xfree (key); xfree (key);
if (!gcry_pk_get_keygrip (private, grip)) if (!gcry_pk_get_keygrip (private, grip))
@ -672,7 +673,7 @@ import_p12_file (const char *fname)
char *pw; char *pw;
/* fixme: we should release some stuff on error */ /* fixme: we should release some stuff on error */
buf = read_file (fname, &buflen); buf = read_file (fname, &buflen);
if (!buf) if (!buf)
return; return;
@ -776,7 +777,7 @@ import_p12_file (const char *fname)
log_error ("protecting the key failed: %s\n", gpg_strerror (rc)); log_error ("protecting the key failed: %s\n", gpg_strerror (rc));
return; return;
} }
if (opt_armor) if (opt_armor)
{ {
char *p = make_advanced (result, resultlen); char *p = make_advanced (result, resultlen);
@ -810,7 +811,7 @@ sexp_to_kparms (gcry_sexp_t sexp)
list = gcry_sexp_find_token (sexp, "private-key", 0 ); list = gcry_sexp_find_token (sexp, "private-key", 0 );
if(!list) if(!list)
return NULL; return NULL;
l2 = gcry_sexp_cadr (list); l2 = gcry_sexp_cadr (list);
gcry_sexp_release (list); gcry_sexp_release (list);
list = l2; list = l2;
@ -824,7 +825,7 @@ sexp_to_kparms (gcry_sexp_t sexp)
/* Parameter names used with RSA. */ /* Parameter names used with RSA. */
elems = "nedpqu"; elems = "nedpqu";
array = xcalloc (strlen(elems) + 1, sizeof *array); array = xcalloc (strlen(elems) + 1, sizeof *array);
for (idx=0, s=elems; *s; s++, idx++ ) for (idx=0, s=elems; *s; s++, idx++ )
{ {
l2 = gcry_sexp_find_token (list, s, 1); l2 = gcry_sexp_find_token (list, s, 1);
if (!l2) if (!l2)
@ -846,7 +847,7 @@ sexp_to_kparms (gcry_sexp_t sexp)
return NULL; /* required parameter is invalid */ return NULL; /* required parameter is invalid */
} }
} }
gcry_sexp_release (list); gcry_sexp_release (list);
return array; return array;
} }
@ -859,9 +860,9 @@ is_keygrip (const char *string)
{ {
int i; int i;
for(i=0; string[i] && i < 41; i++) for(i=0; string[i] && i < 41; i++)
if (!strchr("01234567890ABCDEF", string[i])) if (!strchr("01234567890ABCDEF", string[i]))
return 0; return 0;
return i == 40; return i == 40;
} }
@ -886,7 +887,7 @@ export_p12_file (const char *fname)
{ {
char hexgrip[40+4+1]; char hexgrip[40+4+1];
char *p; char *p;
assert (strlen(fname) == 40); assert (strlen(fname) == 40);
strcpy (stpcpy (hexgrip, fname), ".key"); strcpy (stpcpy (hexgrip, fname), ".key");
@ -960,7 +961,7 @@ export_p12_file (const char *fname)
xfree (key); xfree (key);
xfree (cert); xfree (cert);
return; return;
} }
wipememory (key, keylen_for_wipe); wipememory (key, keylen_for_wipe);
xfree (key); xfree (key);
@ -971,7 +972,7 @@ export_p12_file (const char *fname)
log_error ("error converting key parameters\n"); log_error ("error converting key parameters\n");
xfree (cert); xfree (cert);
return; return;
} }
sk.n = kp[0]; sk.n = kp[0];
sk.e = kp[1]; sk.e = kp[1];
sk.d = kp[2]; sk.d = kp[2];
@ -980,7 +981,7 @@ export_p12_file (const char *fname)
sk.u = kp[5]; sk.u = kp[5];
xfree (kp); xfree (kp);
kparms[0] = sk.n; kparms[0] = sk.n;
kparms[1] = sk.e; kparms[1] = sk.e;
kparms[2] = sk.d; kparms[2] = sk.d;
@ -988,10 +989,10 @@ export_p12_file (const char *fname)
kparms[4] = sk.p; kparms[4] = sk.p;
kparms[5] = gcry_mpi_snew (0); /* compute d mod (p-1) */ kparms[5] = gcry_mpi_snew (0); /* compute d mod (p-1) */
gcry_mpi_sub_ui (kparms[5], kparms[3], 1); gcry_mpi_sub_ui (kparms[5], kparms[3], 1);
gcry_mpi_mod (kparms[5], sk.d, kparms[5]); gcry_mpi_mod (kparms[5], sk.d, kparms[5]);
kparms[6] = gcry_mpi_snew (0); /* compute d mod (q-1) */ kparms[6] = gcry_mpi_snew (0); /* compute d mod (q-1) */
gcry_mpi_sub_ui (kparms[6], kparms[4], 1); gcry_mpi_sub_ui (kparms[6], kparms[4], 1);
gcry_mpi_mod (kparms[6], sk.d, kparms[6]); gcry_mpi_mod (kparms[6], sk.d, kparms[6]);
kparms[7] = sk.u; kparms[7] = sk.u;
kparms[8] = NULL; kparms[8] = NULL;
@ -1003,7 +1004,7 @@ export_p12_file (const char *fname)
gcry_mpi_release (kparms[i]); gcry_mpi_release (kparms[i]);
if (!key) if (!key)
return; return;
#ifdef HAVE_DOSISH_SYSTEM #ifdef HAVE_DOSISH_SYSTEM
setmode ( fileno (stdout) , O_BINARY ); setmode ( fileno (stdout) , O_BINARY );
#endif #endif
@ -1022,7 +1023,7 @@ main (int argc, char **argv )
set_strusage (my_strusage); set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
log_set_prefix ("gpg-protect-tool", 1); log_set_prefix ("gpg-protect-tool", 1);
/* Make sure that our subsystems are ready. */ /* Make sure that our subsystems are ready. */
i18n_init (); i18n_init ();
@ -1040,6 +1041,7 @@ main (int argc, char **argv )
opt_homedir = default_homedir (); opt_homedir = default_homedir ();
opt_session_env = session_env_new ();
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
@ -1073,7 +1075,7 @@ main (int argc, char **argv )
case oHaveCert: opt_have_cert = 1; break; case oHaveCert: opt_have_cert = 1; break;
case oPrompt: opt_prompt = pargs.r.ret_str; break; case oPrompt: opt_prompt = pargs.r.ret_str; break;
case oStatusMsg: opt_status_msg = 1; break; case oStatusMsg: opt_status_msg = 1; break;
default: pargs.err = ARGPARSE_PRINT_ERROR; break; default: pargs.err = ARGPARSE_PRINT_ERROR; break;
} }
} }
@ -1091,7 +1093,7 @@ main (int argc, char **argv )
opt.verbose, opt.verbose,
opt_homedir, opt_homedir,
opt_agent_program, opt_agent_program,
NULL, NULL, NULL); NULL, NULL, opt_session_env);
if (opt_prompt) if (opt_prompt)
opt_prompt = percent_plus_unescape (opt_prompt, 0); opt_prompt = percent_plus_unescape (opt_prompt, 0);
@ -1127,6 +1129,8 @@ void
agent_exit (int rc) agent_exit (int rc)
{ {
rc = rc? rc : log_get_errorcount(0)? 2 : 0; rc = rc? rc : log_get_errorcount(0)? 2 : 0;
session_env_release (opt_session_env);
opt_session_env = NULL;
exit (rc); exit (rc);
} }
@ -1147,7 +1151,7 @@ get_passphrase (int promptno)
const char *desc; const char *desc;
char *orig_codeset; char *orig_codeset;
int repeat = 0; int repeat = 0;
if (opt_passphrase) if (opt_passphrase)
return xstrdup (opt_passphrase); return xstrdup (opt_passphrase);
@ -1214,7 +1218,7 @@ store_private_key (const unsigned char *grip,
char *fname; char *fname;
estream_t fp; estream_t fp;
char hexgrip[40+4+1]; char hexgrip[40+4+1];
bin2hex (grip, 20, hexgrip); bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key"); strcpy (hexgrip+40, ".key");
@ -1236,11 +1240,11 @@ store_private_key (const unsigned char *grip,
} }
/* FWIW: Under Windows Vista the standard fopen in the msvcrt /* FWIW: Under Windows Vista the standard fopen in the msvcrt
fails if the "x" GNU extension is used. */ fails if the "x" GNU extension is used. */
fp = es_fopen (fname, "wbx"); fp = es_fopen (fname, "wbx");
} }
if (!fp) if (!fp)
{ {
log_error ("can't create `%s': %s\n", fname, strerror (errno)); log_error ("can't create `%s': %s\n", fname, strerror (errno));
xfree (fname); xfree (fname);
return -1; return -1;