mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
2004-09-27 Moritz Schulte <moritz@g10code.com>
**MERGED FROM MAIN BRANCH, RE-PATCHED** * command-ssh.c: New file. * findkey.c (modify_description): New function. (agent_key_from_file): New variables: comment, comment_sexp, comment_length, desc_text_modified; extract comment from S-Exp, pass modified version to unprotect(). * agent.h: Declare: start_command_handler_ssh. (struct opt): New member: ssh_support. * gpg-agent.c: Include <sys/select.h>. New configuration option: ssh-support. (socket_name_ssh): New variabel. (handle_connections): Additional argument: listen_fd_ssh. Accept connections on both sockets, call start_connection_thread_ssh for connections on listen_fd_ssh. (start_connection_thread_ssh): New function. (cleanup_do): New functions, basically old cleanup function. (cleanup): Call cleanup_do for socket_name and socket_name_ssh. (server_socket_create): New function ... (main): ... use it. (main): Generate environment entries for ssh. * query.c (start_pinentry): Accept CTRL being NULL.
This commit is contained in:
parent
a8dfea6457
commit
3504abfa29
7 changed files with 1799 additions and 1135 deletions
|
@ -78,15 +78,17 @@ enum cmd_and_opt_values
|
|||
oLCctype,
|
||||
oLCmessages,
|
||||
oScdaemonProgram,
|
||||
oDefCacheTTL,
|
||||
oDisablePth,
|
||||
oDefCacheTTL,
|
||||
oMaxCacheTTL,
|
||||
|
||||
oIgnoreCacheForSigning,
|
||||
oAllowMarkTrusted,
|
||||
oKeepTTY,
|
||||
oKeepDISPLAY,
|
||||
aTest,
|
||||
oSSHSupport };
|
||||
oSSHSupport,
|
||||
|
||||
aTest };
|
||||
|
||||
|
||||
|
||||
|
@ -128,17 +130,18 @@ static ARGPARSE_OPTS opts[] = {
|
|||
|
||||
{ oDefCacheTTL, "default-cache-ttl", 4,
|
||||
N_("|N|expire cached PINs after N seconds")},
|
||||
{ oMaxCacheTTL, "max-cache-ttl", 4, "@" },
|
||||
{ oIgnoreCacheForSigning, "ignore-cache-for-signing", 0,
|
||||
N_("do not use the PIN cache when signing")},
|
||||
{ oAllowMarkTrusted, "allow-mark-trusted", 0,
|
||||
N_("allow clients to mark keys as \"trusted\"")},
|
||||
{ oSSHSupport, "ssh-support", 0, "Enable SSH-Agent emulation" },
|
||||
|
||||
{0}
|
||||
};
|
||||
|
||||
|
||||
#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */
|
||||
#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */
|
||||
#define MAX_CACHE_TTL (120*60) /* 2 hours */
|
||||
|
||||
static volatile int caught_fatal_sig = 0;
|
||||
|
||||
|
@ -181,6 +184,7 @@ static void handle_connections (int listen_fd, int listen_fd_ssh);
|
|||
GCRY_THREAD_OPTION_PTH_IMPL;
|
||||
|
||||
#endif /*USE_GNU_PTH*/
|
||||
static void check_for_running_agent (void);
|
||||
|
||||
|
||||
|
||||
|
@ -286,6 +290,7 @@ set_debug (void)
|
|||
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
|
||||
gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cleanup_do (char *name)
|
||||
|
@ -353,6 +358,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
|
|||
opt.pinentry_program = NULL;
|
||||
opt.scdaemon_program = NULL;
|
||||
opt.def_cache_ttl = DEFAULT_CACHE_TTL;
|
||||
opt.max_cache_ttl = MAX_CACHE_TTL;
|
||||
opt.ignore_cache_for_signing = 0;
|
||||
opt.allow_mark_trusted = 0;
|
||||
return 1;
|
||||
|
@ -368,8 +374,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
|
|||
case oDebugLevel: debug_level = pargs->r.ret_str; break;
|
||||
|
||||
case oLogFile:
|
||||
if (!current_logfile || !pargs->r.ret_str
|
||||
|| strcmp (current_logfile, pargs->r.ret_str))
|
||||
if (reread
|
||||
&& (!current_logfile || !pargs->r.ret_str
|
||||
|| strcmp (current_logfile, pargs->r.ret_str)))
|
||||
{
|
||||
log_set_file (pargs->r.ret_str);
|
||||
xfree (current_logfile);
|
||||
|
@ -383,6 +390,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
|
|||
case oScdaemonProgram: opt.scdaemon_program = pargs->r.ret_str; break;
|
||||
|
||||
case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break;
|
||||
case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break;
|
||||
|
||||
case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break;
|
||||
|
||||
|
@ -394,6 +402,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
|
|||
return 1; /* handled */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
server_socket_create (int *sock,
|
||||
const char *identifier, char *name, int name_size)
|
||||
|
@ -681,7 +690,9 @@ main (int argc, char **argv )
|
|||
fprintf (stderr, "%s\n", strusage(15) );
|
||||
}
|
||||
#ifdef IS_DEVELOPMENT_VERSION
|
||||
log_info ("NOTE: this is a development version!\n");
|
||||
/* We don't want to print it here because gpg-agent is useful of its
|
||||
own and quite matured. */
|
||||
/*log_info ("NOTE: this is a development version!\n");*/
|
||||
#endif
|
||||
|
||||
set_debug ();
|
||||
|
@ -751,9 +762,15 @@ main (int argc, char **argv )
|
|||
agent_exit (0);
|
||||
}
|
||||
|
||||
/* If this has been called without any options, we merely check
|
||||
whether an agent is already running. We do this here so that we
|
||||
don't clobber a logfile but print it directly to stderr. */
|
||||
if (!pipe_server && !is_daemon)
|
||||
log_info (_("please use the option `--daemon'"
|
||||
" to run the program in the background\n"));
|
||||
{
|
||||
log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
|
||||
check_for_running_agent ();
|
||||
agent_exit (0);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
/* gpg-agent usually does not output any messages because it runs in
|
||||
|
@ -787,12 +804,11 @@ main (int argc, char **argv )
|
|||
start_command_handler (-1, -1);
|
||||
}
|
||||
else if (!is_daemon)
|
||||
;
|
||||
; /* NOTREACHED */
|
||||
else
|
||||
{ /* regular server mode */
|
||||
{ /* Regular server mode */
|
||||
int fd = -1, fd_ssh = -1;
|
||||
pid_t pid;
|
||||
//char *p;
|
||||
|
||||
/* Remove the DISPLAY variable so that a pinentry does not
|
||||
default to a specific display. There is still a default
|
||||
|
@ -806,7 +822,6 @@ main (int argc, char **argv )
|
|||
server_socket_create (&fd_ssh, "-ssh",
|
||||
socket_name_ssh, sizeof (socket_name_ssh));
|
||||
|
||||
|
||||
if (opt.verbose)
|
||||
{
|
||||
log_info ("listening on socket `%s'\n", socket_name);
|
||||
|
@ -814,6 +829,7 @@ main (int argc, char **argv )
|
|||
log_info ("listening on socket `%s'\n", socket_name_ssh);
|
||||
}
|
||||
|
||||
|
||||
fflush (NULL);
|
||||
pid = fork ();
|
||||
if (pid == (pid_t)-1)
|
||||
|
@ -826,8 +842,6 @@ main (int argc, char **argv )
|
|||
char *infostr, *infostr_ssh_sock, *infostr_ssh_pid;
|
||||
|
||||
close (fd);
|
||||
if (opt.ssh_support)
|
||||
close (fd_ssh);
|
||||
|
||||
/* create the info string: <name>:<pid>:<protocol_version> */
|
||||
if (asprintf (&infostr, "GPG_AGENT_INFO=%s:%lu:1",
|
||||
|
@ -858,7 +872,7 @@ main (int argc, char **argv )
|
|||
*socket_name = 0; /* don't let cleanup() remove the socket -
|
||||
the child should do this from now on */
|
||||
*socket_name_ssh = 0;
|
||||
|
||||
|
||||
if (argc)
|
||||
{ /* run the program given on the commandline */
|
||||
if (putenv (infostr))
|
||||
|
@ -994,7 +1008,7 @@ main (int argc, char **argv )
|
|||
}
|
||||
close (fd);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1235,6 +1249,7 @@ start_connection_thread (void *arg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
start_connection_thread_ssh (void *arg)
|
||||
{
|
||||
|
@ -1268,7 +1283,12 @@ handle_connections (int listen_fd, int listen_fd_ssh)
|
|||
int ret = -1;
|
||||
int fd;
|
||||
|
||||
sigemptyset (&sigs);
|
||||
tattr = pth_attr_new();
|
||||
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
|
||||
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64);
|
||||
pth_attr_set (tattr, PTH_ATTR_NAME, "gpg-agent");
|
||||
|
||||
sigemptyset (&sigs );
|
||||
sigaddset (&sigs, SIGHUP);
|
||||
sigaddset (&sigs, SIGUSR1);
|
||||
sigaddset (&sigs, SIGUSR2);
|
||||
|
@ -1276,11 +1296,6 @@ handle_connections (int listen_fd, int listen_fd_ssh)
|
|||
sigaddset (&sigs, SIGTERM);
|
||||
ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
|
||||
|
||||
tattr = pth_attr_new();
|
||||
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
|
||||
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 32*1024);
|
||||
pth_attr_set (tattr, PTH_ATTR_NAME, "gpg-agent");
|
||||
|
||||
FD_ZERO (&fdset);
|
||||
FD_SET (listen_fd, &fdset);
|
||||
if (listen_fd_ssh != -1)
|
||||
|
@ -1370,4 +1385,58 @@ handle_connections (int listen_fd, int listen_fd_ssh)
|
|||
cleanup ();
|
||||
log_info ("%s %s stopped\n", strusage(11), strusage(13));
|
||||
}
|
||||
|
||||
#endif /*USE_GNU_PTH*/
|
||||
|
||||
|
||||
/* Figure out whether an agent is available and running. Prints an
|
||||
error if not. */
|
||||
static void
|
||||
check_for_running_agent ()
|
||||
{
|
||||
int rc;
|
||||
char *infostr, *p;
|
||||
assuan_context_t ctx;
|
||||
int prot, pid;
|
||||
|
||||
infostr = getenv ("GPG_AGENT_INFO");
|
||||
if (!infostr || !*infostr)
|
||||
{
|
||||
log_error (_("no gpg-agent running in this session\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
infostr = xstrdup (infostr);
|
||||
if ( !(p = strchr (infostr, ':')) || p == infostr)
|
||||
{
|
||||
log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
|
||||
xfree (infostr);
|
||||
return;
|
||||
}
|
||||
|
||||
*p++ = 0;
|
||||
pid = atoi (p);
|
||||
while (*p && *p != ':')
|
||||
p++;
|
||||
prot = *p? atoi (p+1) : 0;
|
||||
if (prot != 1)
|
||||
{
|
||||
log_error (_("gpg-agent protocol version %d is not supported\n"),
|
||||
prot);
|
||||
xfree (infostr);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = assuan_socket_connect (&ctx, infostr, pid);
|
||||
xfree (infostr);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("can't connect to the agent: %s\n", assuan_strerror (rc));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!opt.quiet)
|
||||
log_info ("gpg-agent running and available\n");
|
||||
|
||||
assuan_disconnect (ctx);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue