Don't set SSH_AGENTPID_INFO.

Doc fixes.
Allow TCP and local sockets in watchgnupg.
This commit is contained in:
Werner Koch 2010-10-05 19:05:43 +00:00
parent 93fa99c07a
commit cc71376bce
6 changed files with 189 additions and 116 deletions

View File

@ -1,3 +1,8 @@
2010-10-05 Werner Koch <wk@g10code.com>
* gpg-agent.c (main): Don't set SSH_AGENT_PID so that ssh-agent -k
won't kill out gpg-agent.
2010-09-30 Werner Koch <wk@g10code.com> 2010-09-30 Werner Koch <wk@g10code.com>
* gpg-agent.c (agent_exit): Run cleanup. * gpg-agent.c (agent_exit): Run cleanup.

View File

@ -1054,7 +1054,7 @@ main (int argc, char **argv )
} }
else if (pid) else if (pid)
{ /* We are the parent */ { /* We are the parent */
char *infostr, *infostr_ssh_sock, *infostr_ssh_pid; char *infostr, *infostr_ssh_sock;
/* Close the socket FD. */ /* Close the socket FD. */
close (fd); close (fd);
@ -1100,13 +1100,6 @@ main (int argc, char **argv )
kill (pid, SIGTERM); kill (pid, SIGTERM);
exit (1); exit (1);
} }
if (asprintf (&infostr_ssh_pid, "SSH_AGENT_PID=%u",
pid) < 0)
{
log_error ("out of core\n");
kill (pid, SIGTERM);
exit (1);
}
} }
*socket_name = 0; /* Don't let cleanup() remove the socket - *socket_name = 0; /* Don't let cleanup() remove the socket -
@ -1130,8 +1123,6 @@ main (int argc, char **argv )
{ {
es_fputs (infostr_ssh_sock, fp); es_fputs (infostr_ssh_sock, fp);
es_putc ('\n', fp); es_putc ('\n', fp);
es_fputs (infostr_ssh_pid, fp);
es_putc ('\n', fp);
} }
es_fclose (fp); es_fclose (fp);
} }
@ -1154,13 +1145,6 @@ main (int argc, char **argv )
kill (pid, SIGTERM ); kill (pid, SIGTERM );
exit (1); exit (1);
} }
if (opt.ssh_support && putenv (infostr_ssh_pid))
{
log_error ("failed to set environment: %s\n",
strerror (errno) );
kill (pid, SIGTERM );
exit (1);
}
/* Close all the file descriptors except the standard /* Close all the file descriptors except the standard
ones and those open at startup. We explicitly don't ones and those open at startup. We explicitly don't
@ -1186,8 +1170,6 @@ main (int argc, char **argv )
{ {
*strchr (infostr_ssh_sock, '=') = ' '; *strchr (infostr_ssh_sock, '=') = ' ';
es_printf ("setenv %s\n", infostr_ssh_sock); es_printf ("setenv %s\n", infostr_ssh_sock);
*strchr (infostr_ssh_pid, '=') = ' ';
es_printf ("setenv %s\n", infostr_ssh_pid);
} }
} }
else else
@ -1197,15 +1179,12 @@ main (int argc, char **argv )
{ {
es_printf ("%s; export SSH_AUTH_SOCK;\n", es_printf ("%s; export SSH_AUTH_SOCK;\n",
infostr_ssh_sock); infostr_ssh_sock);
es_printf ("%s; export SSH_AGENT_PID;\n",
infostr_ssh_pid);
} }
} }
xfree (infostr); xfree (infostr);
if (opt.ssh_support) if (opt.ssh_support)
{ {
xfree (infostr_ssh_sock); xfree (infostr_ssh_sock);
xfree (infostr_ssh_pid);
} }
exit (0); exit (0);
} }

View File

@ -83,7 +83,6 @@ if [ -f "$@{HOME@}/.gpg-agent-info" ]; then
. "$@{HOME@}/.gpg-agent-info" . "$@{HOME@}/.gpg-agent-info"
export GPG_AGENT_INFO export GPG_AGENT_INFO
export SSH_AUTH_SOCK export SSH_AUTH_SOCK
export SSH_AGENT_PID
fi fi
@end smallexample @end smallexample
@ -576,10 +575,13 @@ It is possible to add further flags after the @code{S} for use by the
caller: caller:
@table @code @table @code
@item relax @item relax
Relax checking of some root certificate requirements. This is for @cindex relax
example required if the certificate is missing the basicConstraints Relax checking of some root certificate requirements. As of now this
attribute (despite that it is a MUST for CA certificates). flag allows the use of root certificates with a missing basicConstraints
attribute (despite that it is a MUST for CA certificates) and disables
CRL checking for the root certificate.
@item cm @item cm
If validation of a certificate finally issued by a CA with this flag set If validation of a certificate finally issued by a CA with this flag set
@ -589,7 +591,7 @@ fails, try again using the chain validation model.
@item sshcontrol @item sshcontrol
@cindex sshcontrol
This file is used when support for the secure shell agent protocol has This file is used when support for the secure shell agent protocol has
been enabled (@pxref{option --enable-ssh-support}). Only keys present in been enabled (@pxref{option --enable-ssh-support}). Only keys present in
this file are used in the SSH protocol. You should backup this file. this file are used in the SSH protocol. You should backup this file.
@ -712,7 +714,6 @@ and add something like (for Bourne shells)
. "$@{HOME@}/.gpg-agent-info" . "$@{HOME@}/.gpg-agent-info"
export GPG_AGENT_INFO export GPG_AGENT_INFO
export SSH_AUTH_SOCK export SSH_AUTH_SOCK
export SSH_AGENT_PID
fi fi
@end example @end example
@end cartouche @end cartouche

View File

@ -274,7 +274,7 @@ unknown_criticals (ksba_cert_t cert, int listmode, estream_t fp)
/* Check whether CERT is an allowed certificate. This requires that /* Check whether CERT is an allowed certificate. This requires that
CERT matches all requirements for such a CA, i.e. the CERT matches all requirements for such a CA, i.e. the
BasicConstraints extension. The function returns 0 on success and BasicConstraints extension. The function returns 0 on success and
the awlloed length of the chain at CHAINLEN. */ the allowed length of the chain at CHAINLEN. */
static int static int
allowed_ca (ctrl_t ctrl, allowed_ca (ctrl_t ctrl,
ksba_cert_t cert, int *chainlen, int listmode, estream_t fp) ksba_cert_t cert, int *chainlen, int listmode, estream_t fp)

View File

@ -1,3 +1,11 @@
2010-10-05 Werner Koch <wk@g10code.com>
* watchgnupg.c (main): Support TCP and local socket listening.
(main): Factor some code out to ..
(setup_client): this.
(err): New.
(client_list): New.
2010-08-25 Werner Koch <wk@g10code.com> 2010-08-25 Werner Koch <wk@g10code.com>
* gpgtar-extract.c (create_directory): Add .p7m as known * gpgtar-extract.c (create_directory): Add .p7m as known

View File

@ -71,19 +71,19 @@ die (const char *format, ...)
} }
/* static void */ static void
/* err (const char *format, ...) */ err (const char *format, ...)
/* { */ {
/* va_list arg_ptr; */ va_list arg_ptr;
/* fflush (stdout); */ fflush (stdout);
/* fprintf (stderr, "%s: ", PGM); */ fprintf (stderr, "%s: ", PGM);
/* va_start (arg_ptr, format); */ va_start (arg_ptr, format);
/* vfprintf (stderr, format, arg_ptr); */ vfprintf (stderr, format, arg_ptr);
/* va_end (arg_ptr); */ va_end (arg_ptr);
/* putc ('\n', stderr); */ putc ('\n', stderr);
/* } */ }
static void * static void *
xmalloc (size_t n) xmalloc (size_t n)
@ -123,6 +123,10 @@ struct client_s {
}; };
typedef struct client_s *client_t; typedef struct client_s *client_t;
/* The list of all connected peers. */
static client_t client_list;
static void static void
@ -186,6 +190,57 @@ print_line (client_t c, const char *line)
} }
static void
setup_client (int server_fd, int is_un)
{
struct sockaddr_un addr_un;
struct sockaddr_in addr_in;
struct sockaddr *addr;
socklen_t addrlen;
int fd;
client_t client;
if (is_un)
{
addr = (struct sockaddr *)&addr_un;
addrlen = sizeof addr_un;
}
else
{
addr = (struct sockaddr *)&addr_in;
addrlen = sizeof addr_in;
}
fd = accept (server_fd, addr, &addrlen);
if (fd == -1)
{
printf ("[accepting %s connection failed: %s]\n",
is_un? "local":"tcp", strerror (errno));
}
else if (fd >= FD_SETSIZE)
{
close (fd);
printf ("[connection request denied: too many connections]\n");
}
else
{
for (client = client_list; client && client->fd != -1;
client = client->next)
;
if (!client)
{
client = xcalloc (1, sizeof *client);
client->next = client_list;
client_list = client;
}
client->fd = fd;
printf ("[client at fd %d connected (%s)]\n",
client->fd, is_un? "local":"tcp");
}
}
static void static void
print_version (int with_help) print_version (int with_help)
{ {
@ -197,17 +252,19 @@ print_version (int with_help)
"There is NO WARRANTY, to the extent permitted by law.\n", "There is NO WARRANTY, to the extent permitted by law.\n",
stdout); stdout);
if (with_help) if (with_help)
fputs ("\n" fputs
"Usage: " PGM " [OPTIONS] SOCKETNAME|PORT\n" ("\n"
"Open the local socket SOCKETNAME (or the TCP port PORT)\n" "Usage: " PGM " [OPTIONS] SOCKETNAME\n"
"and display log messages\n" " " PGM " [OPTIONS] PORT [SOCKETNAME]\n"
"\n" "Open the local socket SOCKETNAME (or the TCP port PORT)\n"
" --force delete an already existing socket file\n" "and display log messages\n"
" --tcp listen on a TCP port instead of a local socket\n" "\n"
" --verbose enable extra informational output\n" " --tcp listen on a TCP port and optionally on a local socket\n"
" --version print version of the program and exit\n" " --force delete an already existing socket file\n"
" --help display this help and exit\n" " --verbose enable extra informational output\n"
BUGREPORT_LINE, stdout ); " --version print version of the program and exit\n"
" --help display this help and exit\n"
BUGREPORT_LINE, stdout );
exit (0); exit (0);
} }
@ -221,12 +278,12 @@ main (int argc, char **argv)
struct sockaddr_un srvr_addr_un; struct sockaddr_un srvr_addr_un;
struct sockaddr_in srvr_addr_in; struct sockaddr_in srvr_addr_in;
struct sockaddr *srvr_addr = NULL; struct sockaddr *addr_in = NULL;
socklen_t addrlen; struct sockaddr *addr_un = NULL;
socklen_t addrlen_in, addrlen_un;
unsigned short port; unsigned short port;
int server; int server_un, server_in;
int flags; int flags;
client_t client_list = NULL;
if (argc) if (argc)
{ {
@ -261,36 +318,70 @@ main (int argc, char **argv)
} }
} }
if (argc != 1) if (!((!tcp && argc == 1) || (tcp && (argc == 1 || argc == 2))))
{ {
fprintf (stderr, "usage: " PGM " socketname\n"); fprintf (stderr, "usage: " PGM " socketname\n"
" " PGM " --tcp port [socketname]\n");
exit (1); exit (1);
} }
port = tcp? atoi (*argv) : 0; if (tcp)
if (verbose)
{ {
if (tcp) port = atoi (*argv);
fprintf (stderr, "listening on port %hu\n", port); argc--; argv++;
else }
fprintf (stderr, "opening socket `%s'\n", *argv); else
{
port = 0;
} }
setvbuf (stdout, NULL, _IOLBF, 0); setvbuf (stdout, NULL, _IOLBF, 0);
server = socket (tcp? PF_INET : PF_LOCAL, SOCK_STREAM, 0); if (tcp)
if (server == -1) {
die ("socket() failed: %s\n", strerror (errno)); int i = 1;
server_in = socket (PF_INET, SOCK_STREAM, 0);
if (server_in == -1)
die ("socket(PF_INET) failed: %s\n", strerror (errno));
if (setsockopt (server_in, SOL_SOCKET, SO_REUSEADDR,
(unsigned char *)&i, sizeof (i)))
err ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
if (verbose)
fprintf (stderr, "listening on port %hu\n", port);
}
else
server_in = -1;
if (argc)
{
server_un = socket (PF_LOCAL, SOCK_STREAM, 0);
if (server_un == -1)
die ("socket(PF_LOCAL) failed: %s\n", strerror (errno));
if (verbose)
fprintf (stderr, "listening on socket `%s'\n", *argv);
}
else
server_un = -1;
/* We better set the listening socket to non-blocking so that we /* We better set the listening socket to non-blocking so that we
don't get bitten by race conditions in accept. The should not don't get bitten by race conditions in accept. The should not
happen for Unix Domain sockets but well, shit happens. */ happen for Unix Domain sockets but well, shit happens. */
flags = fcntl (server, F_GETFL, 0); if (server_in != -1)
if (flags == -1) {
die ("fcntl (F_GETFL) failed: %s\n", strerror (errno)); flags = fcntl (server_in, F_GETFL, 0);
if ( fcntl (server, F_SETFL, (flags | O_NONBLOCK)) == -1) if (flags == -1)
die ("fcntl (F_SETFL) failed: %s\n", strerror (errno)); die ("fcntl (F_GETFL) failed: %s\n", strerror (errno));
if ( fcntl (server_in, F_SETFL, (flags | O_NONBLOCK)) == -1)
die ("fcntl (F_SETFL) failed: %s\n", strerror (errno));
}
if (server_un != -1)
{
flags = fcntl (server_un, F_GETFL, 0);
if (flags == -1)
die ("fcntl (F_GETFL) failed: %s\n", strerror (errno));
if ( fcntl (server_un, F_SETFL, (flags | O_NONBLOCK)) == -1)
die ("fcntl (F_SETFL) failed: %s\n", strerror (errno));
}
if (tcp) if (tcp)
{ {
@ -298,36 +389,41 @@ main (int argc, char **argv)
srvr_addr_in.sin_family = AF_INET; srvr_addr_in.sin_family = AF_INET;
srvr_addr_in.sin_port = htons (port); srvr_addr_in.sin_port = htons (port);
srvr_addr_in.sin_addr.s_addr = htonl (INADDR_ANY); srvr_addr_in.sin_addr.s_addr = htonl (INADDR_ANY);
srvr_addr = (struct sockaddr *)&srvr_addr_in; addr_in = (struct sockaddr *)&srvr_addr_in;
addrlen = sizeof srvr_addr_in; addrlen_in = sizeof srvr_addr_in;
} }
else if (argc)
{ {
memset (&srvr_addr_un, 0, sizeof srvr_addr_un); memset (&srvr_addr_un, 0, sizeof srvr_addr_un);
srvr_addr_un.sun_family = AF_LOCAL; srvr_addr_un.sun_family = AF_LOCAL;
strncpy (srvr_addr_un.sun_path, *argv, sizeof (srvr_addr_un.sun_path)-1); strncpy (srvr_addr_un.sun_path, *argv, sizeof (srvr_addr_un.sun_path)-1);
srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path) - 1] = 0; srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path) - 1] = 0;
srvr_addr = (struct sockaddr *)&srvr_addr_un; addr_un = (struct sockaddr *)&srvr_addr_un;
addrlen = SUN_LEN (&srvr_addr_un); addrlen_un = SUN_LEN (&srvr_addr_un);
} }
else
addrlen_un = 0; /* Silent gcc. */
if (server_in != -1 && bind (server_in, addr_in, addrlen_in))
die ("bind to port %hu failed: %s\n", port, strerror (errno));
again: again:
if (bind (server, srvr_addr, addrlen)) if (server_un != -1 && bind (server_un, addr_un, addrlen_un))
{ {
if (!tcp && errno == EADDRINUSE && force) if (errno == EADDRINUSE && force)
{ {
force = 0; force = 0;
remove (srvr_addr_un.sun_path); remove (srvr_addr_un.sun_path);
goto again; goto again;
} }
if (tcp)
die ("bind to port %hu failed: %s\n", port, strerror (errno));
else else
die ("bind to `%s' failed: %s\n", *argv, strerror (errno)); die ("bind to `%s' failed: %s\n", *argv, strerror (errno));
} }
if (listen (server, 5)) if (server_in != -1 && listen (server_in, 5))
die ("listen failed: %s\n", strerror (errno)); die ("listen on inet failed: %s\n", strerror (errno));
if (server_un != -1 && listen (server_un, 5))
die ("listen on local failed: %s\n", strerror (errno));
for (;;) for (;;)
{ {
@ -339,8 +435,18 @@ main (int argc, char **argv)
to set them allways from scratch and don't maintain an active to set them allways from scratch and don't maintain an active
fd_set. */ fd_set. */
FD_ZERO (&rfds); FD_ZERO (&rfds);
FD_SET (server, &rfds); max_fd = -1;
max_fd = server; if (server_in != -1)
{
FD_SET (server_in, &rfds);
max_fd = server_in;
}
if (server_un != -1)
{
FD_SET (server_un, &rfds);
if (server_un > max_fd)
max_fd = server_un;
}
for (client = client_list; client; client = client->next) for (client = client_list; client; client = client->next)
if (client->fd != -1) if (client->fd != -1)
{ {
@ -352,37 +458,11 @@ main (int argc, char **argv)
if (select (max_fd + 1, &rfds, NULL, NULL, NULL) <= 0) if (select (max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
continue; /* Ignore any errors. */ continue; /* Ignore any errors. */
if (FD_ISSET (server, &rfds)) /* New connection. */ if (server_in != -1 && FD_ISSET (server_in, &rfds))
{ setup_client (server_in, 0);
struct sockaddr_un clnt_addr; if (server_un != -1 && FD_ISSET (server_un, &rfds))
int fd; setup_client (server_un, 1);
addrlen = sizeof clnt_addr;
fd = accept (server, (struct sockaddr *) &clnt_addr, &addrlen);
if (fd == -1)
{
printf ("[accepting connection failed: %s]\n", strerror (errno));
}
else if (fd >= FD_SETSIZE)
{
close (fd);
printf ("[connection request denied: too many connections]\n");
}
else
{
for (client = client_list; client && client->fd != -1;
client = client->next)
;
if (!client)
{
client = xcalloc (1, sizeof *client);
client->next = client_list;
client_list = client;
}
client->fd = fd;
printf ("[client at fd %d connected]\n", client->fd);
}
}
for (client = client_list; client; client = client->next) for (client = client_list; client; client = client->next)
if (client->fd != -1 && FD_ISSET (client->fd, &rfds)) if (client->fd != -1 && FD_ISSET (client->fd, &rfds))
{ {