diff --git a/agent/ChangeLog b/agent/ChangeLog index 84ee66462..96817c3f3 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,15 @@ +2002-04-24 Marcus Brinkmann + + * agent.h (struct opt): Add members display, ttyname, ttytype, + lc_ctype, and lc_messages. + * gpg-agent.c (enum cmd_and_opt_values): Add oDisplay, oTTYname, + oTTYtype, oLCctype, and LCmessages. + (main): Handle these options. + * command.c (option_handler): New function. + (register_commands): Register option handler. + * query.c (start_pinentry): Pass the various display and tty + options to the pinentry. + 2002-04-05 Werner Koch * protect-tool.c (show_file): New. Used as default action. diff --git a/agent/agent.h b/agent/agent.h index 2b5a2fa31..b6bdb0caa 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -36,6 +36,11 @@ struct { int batch; /* batch mode */ const char *homedir; /* configuration directory name */ const char *pinentry_program; + char *display; + char *ttyname; + char *ttytype; + char *lc_ctype; + char *lc_messages; const char *scdaemon_program; int no_grab; /* don't let the pinentry grab the keyboard */ unsigned long def_cache_ttl; diff --git a/agent/command.c b/agent/command.c index e617d684f..b405ec61c 100644 --- a/agent/command.c +++ b/agent/command.c @@ -494,6 +494,58 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line) } + +static int +option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) +{ + CTRL ctrl = assuan_get_pointer (ctx); + + if (!strcmp (key, "display")) + { + if (opt.display) + free (opt.display); + opt.display = strdup (value); + if (!opt.display) + return ASSUAN_Out_Of_Core; + } + else if (!strcmp (key, "ttyname")) + { + if (opt.ttyname) + free (opt.ttyname); + opt.ttyname = strdup (value); + if (!opt.ttyname) + return ASSUAN_Out_Of_Core; + } + else if (!strcmp (key, "ttytype")) + { + if (opt.ttytype) + free (opt.ttytype); + opt.ttytype = strdup (value); + if (!opt.ttytype) + return ASSUAN_Out_Of_Core; + } + else if (!strcmp (key, "lc-ctype")) + { + if (opt.lc_ctype) + free (opt.lc_ctype); + opt.lc_ctype = strdup (value); + if (!opt.lc_ctype) + return ASSUAN_Out_Of_Core; + } + else if (!strcmp (key, "lc-messages")) + { + if (opt.lc_messages) + free (opt.lc_messages); + opt.lc_messages = strdup (value); + if (!opt.lc_messages) + return ASSUAN_Out_Of_Core; + } + else + return ASSUAN_Invalid_Option; + + return 0; +} + /* Tell the assuan library about our commands */ static int @@ -533,6 +585,7 @@ register_commands (ASSUAN_CONTEXT ctx) return rc; } assuan_register_reset_notify (ctx, reset_notify); + assuan_register_option_handler (ctx, option_handler); return 0; } diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index ca49a8463..3741fa005 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -67,8 +67,13 @@ enum cmd_and_opt_values oLogFile, oServer, oBatch, - + oPinentryProgram, + oDisplay, + oTTYname, + oTTYtype, + oLCctype, + oLCmessages, oScdaemonProgram, oDefCacheTTL, @@ -94,6 +99,12 @@ static ARGPARSE_OPTS opts[] = { { oLogFile, "log-file" ,2, N_("use a log file for the server")}, { oPinentryProgram, "pinentry-program", 2 , "path to PIN Entry program" }, + { oDisplay, "display", 2, "set the display" }, + { oTTYname, "ttyname", 2, "set the tty terminal node name" }, + { oTTYtype, "ttytype", 2, "set the tty terminal type" }, + { oLCctype, "lc-ctype", 2, "set the tty LC_CTYPE value" }, + { oLCmessages, "lc-messages", 2, "set the tty LC_MESSAGES value" }, + { oScdaemonProgram, "scdaemon-program", 2 , "path to SCdaemon program" }, { oDefCacheTTL, "default-cache-ttl", 4, "|N|expire cached PINs after N seconds"}, @@ -374,6 +385,11 @@ main (int argc, char **argv ) case oServer: pipe_server = 1; break; case oPinentryProgram: opt.pinentry_program = pargs.r.ret_str; break; + case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break; + case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break; + case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break; + case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break; + case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break; case oScdaemonProgram: opt.scdaemon_program = pargs.r.ret_str; break; case oDefCacheTTL: opt.def_cache_ttl = pargs.r.ret_ulong; break; diff --git a/agent/query.c b/agent/query.c index 09aada0fd..4243f0026 100644 --- a/agent/query.c +++ b/agent/query.c @@ -56,7 +56,7 @@ start_pinentry (void) int rc; const char *pgmname; ASSUAN_CONTEXT ctx; - const char *argv[3]; + const char *argv[5]; if (entry_ctx) return 0; /* No need to serialize things becuase the agent is @@ -81,7 +81,14 @@ start_pinentry (void) pgmname++; argv[0] = pgmname; - argv[1] = NULL; + if (opt.display) + { + argv[1] = "--display"; + argv[2] = opt.display; + argv[3] = NULL; + } + else + argv[1] = NULL; /* connect to the pinentry and perform initial handshaking */ rc = assuan_pipe_connect (&ctx, opt.pinentry_program, (char**)argv, 0); @@ -100,7 +107,47 @@ start_pinentry (void) NULL, NULL, NULL, NULL, NULL, NULL); if (rc) return map_assuan_err (rc); - + if (opt.ttyname) + { + char *optstr; + if (asprintf (&optstr, "OPTION ttyname=%s", opt.ttyname) < 0 ) + return GNUPG_Out_Of_Core; + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } + if (opt.ttytype) + { + char *optstr; + if (asprintf (&optstr, "OPTION ttytype=%s", opt.ttytype) < 0 ) + return GNUPG_Out_Of_Core; + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + if (rc) + return map_assuan_err (rc); + } + if (opt.lc_ctype) + { + char *optstr; + if (asprintf (&optstr, "OPTION lc-ctype=%s", opt.lc_ctype) < 0 ) + return GNUPG_Out_Of_Core; + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + if (rc) + return map_assuan_err (rc); + } + if (opt.lc_messages) + { + char *optstr; + if (asprintf (&optstr, "OPTION lc-messages=%s", opt.lc_messages) < 0 ) + return GNUPG_Out_Of_Core; + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + if (rc) + return map_assuan_err (rc); + } return 0; } diff --git a/sm/ChangeLog b/sm/ChangeLog index 240f18a16..69deb671f 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,14 @@ +2002-04-24 Marcus Brinkmann + + * gpgsm.h (struct opt): New members display, ttyname, ttytype, + lc_ctype, lc_messages. + * gpgsm.c (enum cmd_and_opt_values): New members oDisplay, + oTTYname, oTTYtype, oLCctype, oLCmessages. + (opts): New entries for these options. + (main): Handle these new options. + * call-agent.c (start_agent): Set the various display and tty + parameter after resetting. + 2002-04-18 Werner Koch * certreqgen.c (gpgsm_genkey): Write status output on success. diff --git a/sm/call-agent.c b/sm/call-agent.c index a7e7a315b..0e0c60923 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -26,8 +26,10 @@ #include #include #include - #include +#ifdef HAVE_LOCALE_H +#include +#endif #include "gpgsm.h" #include "../assuan/assuan.h" @@ -133,6 +135,11 @@ start_agent (void) int rc; char *infostr, *p; ASSUAN_CONTEXT ctx; + char *dft_display = NULL; + char *dft_ttyname = NULL; + char *dft_ttytype = NULL; + char *old_lc = NULL; + char *dft_lc = NULL; if (agent_ctx) return 0; /* fixme: We need a context for each thread or serialize @@ -144,9 +151,8 @@ start_agent (void) { const char *pgmname; const char *argv[3]; - log_info (_("no running gpg-agent - starting one\n")); - + if (fflush (NULL)) { log_error ("error flushing pending output: %s\n", strerror (errno)); @@ -204,7 +210,6 @@ start_agent (void) } } - if (rc) { log_error ("can't connect to the agent: %s\n", assuan_strerror (rc)); @@ -214,6 +219,92 @@ start_agent (void) if (DBG_AGENT) log_debug ("connection to agent established\n"); + + rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return map_assuan_err (rc); + + dft_display = getenv ("DISPLAY"); + if (opt.display || dft_display) + { + char *optstr; + if (asprintf (&optstr, "OPTION display=%s", + opt.display ? opt.display : dft_display) < 0) + return GNUPG_Out_Of_Core; + rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } + if (!opt.ttyname && ttyname (1)) + dft_ttyname = ttyname (1); + if (opt.ttyname || dft_ttyname) + { + char *optstr; + if (asprintf (&optstr, "OPTION ttyname=%s", + opt.ttyname ? opt.ttyname : dft_ttyname) < 0) + return GNUPG_Out_Of_Core; + rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } + dft_ttytype = getenv ("TERM"); + if (!rc && (opt.ttytype || (dft_ttyname && dft_ttytype))) + { + char *optstr; + if (asprintf (&optstr, "OPTION ttytype=%s", + opt.ttyname ? opt.ttytype : dft_ttytype) < 0) + return GNUPG_Out_Of_Core; + rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } +#ifdef LC_CTYPE + old_lc = setlocale (LC_CTYPE, NULL); + dft_lc = setlocale (LC_CTYPE, ""); +#endif + if (!rc && (opt.lc_ctype || (dft_ttyname && dft_lc))) + { + char *optstr; + if (asprintf (&optstr, "OPTION lc-ctype=%s", + opt.lc_ctype ? opt.lc_ctype : dft_lc) < 0) + return GNUPG_Out_Of_Core; + rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } +#ifdef LC_CTYPE + if (old_lc) + setlocale (LC_CTYPE, old_lc); +#endif +#ifdef LC_MESSAGES + old_lc = setlocale (LC_MESSAGES, NULL); + dft_lc = setlocale (LC_MESSAGES, ""); +#endif + if (!rc && (opt.lc_messages || (dft_ttyname && dft_lc))) + { + char *optstr; + if (asprintf (&optstr, "OPTION lc-messages=%s", + opt.lc_messages ? opt.lc_messages : dft_lc) < 0) + return GNUPG_Out_Of_Core; + rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } +#ifdef LC_MESSAGES + if (old_lc) + setlocale (LC_MESSAGES, old_lc); +#endif + return 0; } diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 7d21f1c09..f755c02c7 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -83,7 +83,14 @@ enum cmd_and_opt_values { oDebugWait, oEnableSpecialFilenames, + oAgentProgram, + oDisplay, + oTTYname, + oTTYtype, + oLCctype, + oLCmessages, + oDirmngrProgram, @@ -340,6 +347,11 @@ static ARGPARSE_OPTS opts[] = { { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */ { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ { oAgentProgram, "agent-program", 2 , "@" }, + { oDisplay, "display", 2, "@" }, + { oTTYname, "ttyname", 2, "@" }, + { oTTYtype, "ttytype", 2, "@" }, + { oLCctype, "lc-ctype", 2, "@" }, + { oLCmessages, "lc-messages", 2, "@" }, { oDirmngrProgram, "dirmngr-program", 2 , "@" }, { oNoBatch, "no-batch", 0, "@" }, @@ -842,6 +854,11 @@ main ( int argc, char **argv) case oNoOptions: break; /* no-options */ case oHomedir: opt.homedir = pargs.r.ret_str; break; case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; + case oDisplay: opt.display = pargs.r.ret_str; break; + case oTTYname: opt.ttyname = pargs.r.ret_str; break; + case oTTYtype: opt.ttytype = pargs.r.ret_str; break; + case oLCctype: opt.lc_ctype = pargs.r.ret_str; break; + case oLCmessages: opt.lc_messages = pargs.r.ret_str; break; case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; case oNoDefKeyring: default_keyring = 0; break; diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 9cba457dd..09a633d4c 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -39,6 +39,12 @@ struct { const char *homedir; /* configuration directory name */ const char *agent_program; + const char *display; + const char *ttyname; + const char *ttytype; + const char *lc_ctype; + const char *lc_messages; + const char *dirmngr_program; char *outfile; /* name of output file */