aboutsummaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
Diffstat (limited to 'agent')
-rw-r--r--agent/agent.h1
-rw-r--r--agent/call-pinentry.c5
-rw-r--r--agent/call-scd.c41
-rw-r--r--agent/command-ssh.c27
-rw-r--r--agent/command.c20
-rw-r--r--agent/gpg-agent.c37
-rw-r--r--agent/protect.c20
-rw-r--r--agent/t-protect.c2
8 files changed, 74 insertions, 79 deletions
diff --git a/agent/agent.h b/agent/agent.h
index c2d857959..687635dc7 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -230,6 +230,7 @@ struct server_control_s
char *lc_ctype;
char *lc_messages;
unsigned long client_pid;
+ int client_uid;
/* The current pinentry mode. */
pinentry_mode_t pinentry_mode;
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index a0886814f..af4eb06f2 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -598,8 +598,9 @@ start_pinentry (ctrl_t ctrl)
nodename = utsbuf.nodename;
#endif /*!HAVE_W32_SYSTEM*/
- if ((optstr = xtryasprintf ("OPTION owner=%lu %s",
- ctrl->client_pid, nodename)))
+ if ((optstr = xtryasprintf ("OPTION owner=%lu/%d %s",
+ ctrl->client_pid, ctrl->client_uid,
+ nodename)))
{
assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
NULL);
diff --git a/agent/call-scd.c b/agent/call-scd.c
index cf61a3546..6ce0cddfb 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -89,7 +89,6 @@ struct inq_needpin_parm_s
const char *getpin_cb_desc;
assuan_context_t passthru; /* If not NULL, pass unknown inquiries
up to the caller. */
- int any_inq_seen;
/* The next fields are used by inq_writekey_parm. */
const unsigned char *keydata;
@@ -727,7 +726,6 @@ inq_needpin (void *opaque, const char *line)
size_t pinlen;
int rc;
- parm->any_inq_seen = 1;
if ((s = has_leading_keyword (line, "NEEDPIN")))
{
line = s;
@@ -811,30 +809,6 @@ hash_algo_option (int algo)
}
-static gpg_error_t
-cancel_inquire (ctrl_t ctrl, gpg_error_t rc)
-{
- gpg_error_t oldrc = rc;
-
- /* The inquire callback was called and transact returned a
- cancel error. We assume that the inquired process sent a
- CANCEL. The passthrough code is not able to pass on the
- CANCEL and thus scdaemon would stuck on this. As a
- workaround we send a CANCEL now. */
- rc = assuan_write_line (ctrl->scd_local->ctx, "CAN");
- if (!rc) {
- char *line;
- size_t len;
-
- rc = assuan_read_line (ctrl->scd_local->ctx, &line, &len);
- if (!rc)
- rc = oldrc;
- }
-
- return rc;
-}
-
-
/* Create a signature using the current card. MDALGO is either 0 or
* gives the digest algorithm. DESC_TEXT is an additional parameter
* passed to GETPIN_CB. */
@@ -875,7 +849,6 @@ agent_card_pksign (ctrl_t ctrl,
inqparm.getpin_cb_arg = getpin_cb_arg;
inqparm.getpin_cb_desc = desc_text;
inqparm.passthru = 0;
- inqparm.any_inq_seen = 0;
inqparm.keydata = NULL;
inqparm.keydatalen = 0;
@@ -888,9 +861,6 @@ agent_card_pksign (ctrl_t ctrl,
put_membuf_cb, &data,
inq_needpin, &inqparm,
NULL, NULL);
- if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED ||
- gpg_err_code(rc) == GPG_ERR_ASS_CANCELED))
- rc = cancel_inquire (ctrl, rc);
if (rc)
{
@@ -974,7 +944,6 @@ agent_card_pkdecrypt (ctrl_t ctrl,
inqparm.getpin_cb_arg = getpin_cb_arg;
inqparm.getpin_cb_desc = desc_text;
inqparm.passthru = 0;
- inqparm.any_inq_seen = 0;
inqparm.keydata = NULL;
inqparm.keydatalen = 0;
snprintf (line, DIM(line), "PKDECRYPT %s", keyid);
@@ -982,9 +951,6 @@ agent_card_pkdecrypt (ctrl_t ctrl,
put_membuf_cb, &data,
inq_needpin, &inqparm,
padding_info_cb, r_padding);
- if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED ||
- gpg_err_code(rc) == GPG_ERR_ASS_CANCELED))
- rc = cancel_inquire (ctrl, rc);
if (rc)
{
@@ -1111,15 +1077,11 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno,
parms.getpin_cb_arg = getpin_cb_arg;
parms.getpin_cb_desc= NULL;
parms.passthru = 0;
- parms.any_inq_seen = 0;
parms.keydata = keydata;
parms.keydatalen = keydatalen;
rc = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL,
inq_writekey_parms, &parms, NULL, NULL);
- if (parms.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED ||
- gpg_err_code(rc) == GPG_ERR_ASS_CANCELED))
- rc = cancel_inquire (ctrl, rc);
return unlock_scd (ctrl, rc);
}
@@ -1344,7 +1306,6 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
inqparm.getpin_cb_arg = getpin_cb_arg;
inqparm.getpin_cb_desc = NULL;
inqparm.passthru = assuan_context;
- inqparm.any_inq_seen = 0;
inqparm.keydata = NULL;
inqparm.keydatalen = 0;
@@ -1354,8 +1315,6 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
pass_data_thru, assuan_context,
inq_needpin, &inqparm,
pass_status_thru, assuan_context);
- if (inqparm.any_inq_seen && gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)
- rc = cancel_inquire (ctrl, rc);
assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, saveflag);
if (rc)
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 9d45a1864..866f43959 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -255,6 +255,11 @@ static gpg_error_t ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
+struct peer_info_s
+{
+ unsigned long pid;
+ int uid;
+};
/* Global variables. */
@@ -3581,10 +3586,11 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
/* Return the peer's pid. */
-static unsigned long
-get_client_pid (int fd)
+static void
+get_client_info (int fd, struct peer_info_s *out)
{
- pid_t client_pid = (pid_t)0;
+ pid_t client_pid = (pid_t)(-1);
+ uid_t client_uid = (uid_t)-1;
#ifdef SO_PEERCRED
{
@@ -3599,8 +3605,10 @@ get_client_pid (int fd)
{
#if defined (HAVE_STRUCT_SOCKPEERCRED_PID) || defined (HAVE_STRUCT_UCRED_PID)
client_pid = cr.pid;
+ client_uid = cr.uid;
#elif defined (HAVE_STRUCT_UCRED_CR_PID)
client_pid = cr.cr_pid;
+ client_pid = cr.cr_uid;
#else
#error "Unknown SO_PEERCRED struct"
#endif
@@ -3611,6 +3619,7 @@ get_client_pid (int fd)
socklen_t len = sizeof (pid_t);
getsockopt (fd, SOL_LOCAL, LOCAL_PEERPID, &client_pid, &len);
+ getsockopt (fd, SOL_LOCAL, LOCAL_PEERUID, &client_uid, &len);
}
#elif defined (LOCAL_PEEREID)
{
@@ -3619,6 +3628,7 @@ get_client_pid (int fd)
if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1)
client_pid = unp.unp_pid;
+ client_uid = unp.unp_euid;
}
#elif defined (HAVE_GETPEERUCRED)
{
@@ -3626,7 +3636,8 @@ get_client_pid (int fd)
if (getpeerucred (fd, &ucred) != -1)
{
- client_pid= ucred_getpid (ucred);
+ client_pid = ucred_getpid (ucred);
+ client_uid = ucred_geteuid (ucred);
ucred_free (ucred);
}
}
@@ -3634,7 +3645,8 @@ get_client_pid (int fd)
(void)fd;
#endif
- return (unsigned long)client_pid;
+ out->pid = (client_pid == (pid_t)(-1)? 0 : (unsigned long)client_pid);
+ out->uid = (int)client_uid;
}
@@ -3645,12 +3657,15 @@ start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
estream_t stream_sock = NULL;
gpg_error_t err;
int ret;
+ struct peer_info_s peer_info;
err = agent_copy_startup_env (ctrl);
if (err)
goto out;
- ctrl->client_pid = get_client_pid (FD2INT(sock_client));
+ get_client_info (FD2INT(sock_client), &peer_info);
+ ctrl->client_pid = peer_info.pid;
+ ctrl->client_uid = peer_info.uid;
/* Create stream from socket. */
stream_sock = es_fdopen (FD2INT(sock_client), "r+");
diff --git a/agent/command.c b/agent/command.c
index 0916f886a..7c7e8a4bc 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -874,7 +874,7 @@ static const char hlp_genkey[] =
"\n"
" C: GENKEY\n"
" S: INQUIRE KEYPARAM\n"
- " C: D (genkey (rsa (nbits 2048)))\n"
+ " C: D (genkey (rsa (nbits 3072)))\n"
" C: END\n"
" S: D (public-key\n"
" S: D (rsa (n 326487324683264) (e 10001)))\n"
@@ -3347,7 +3347,7 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
for (;;)
{
- pid_t client_pid;
+ assuan_peercred_t client_creds;
rc = assuan_accept (ctx);
if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
@@ -3360,12 +3360,20 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
break;
}
- client_pid = assuan_get_pid (ctx);
- ctrl->server_local->connect_from_self = (client_pid == getpid ());
- if (client_pid != ASSUAN_INVALID_PID)
- ctrl->client_pid = (unsigned long)client_pid;
+ rc = assuan_get_peercred (ctx, &client_creds);
+ if (rc)
+ {
+ log_info ("Assuan get_peercred failed: %s\n", gpg_strerror (rc));
+ client_creds->pid = assuan_get_pid (ctx);
+ ctrl->client_uid = -1;
+ }
+ ctrl->server_local->connect_from_self =
+ (client_creds->pid == getpid ());
+ if (client_creds->pid != ASSUAN_INVALID_PID)
+ ctrl->client_pid = (unsigned long)client_creds->pid;
else
ctrl->client_pid = 0;
+ ctrl->client_uid = client_creds->uid;
rc = assuan_process (ctx);
if (rc)
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 2e19d19c1..0b2b98212 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -3000,27 +3000,34 @@ handle_connections (gnupg_fd_t listen_fd,
next timeout. */
continue;
+ /* The inotify fds are set even when a shutdown is pending (see
+ * above). So we must handle them in any case. To avoid that
+ * they trigger a second time we close them immediately. */
+ if (sock_inotify_fd != -1
+ && FD_ISSET (sock_inotify_fd, &read_fdset)
+ && gnupg_inotify_has_name (sock_inotify_fd, GPG_AGENT_SOCK_NAME))
+ {
+ shutdown_pending = 1;
+ close (sock_inotify_fd);
+ sock_inotify_fd = -1;
+ log_info ("socket file has been removed - shutting down\n");
+ }
+
+ if (home_inotify_fd != -1
+ && FD_ISSET (home_inotify_fd, &read_fdset))
+ {
+ shutdown_pending = 1;
+ close (home_inotify_fd);
+ home_inotify_fd = -1;
+ log_info ("homedir has been removed - shutting down\n");
+ }
+
if (!shutdown_pending)
{
int idx;
ctrl_t ctrl;
npth_t thread;
- if (sock_inotify_fd != -1
- && FD_ISSET (sock_inotify_fd, &read_fdset)
- && gnupg_inotify_has_name (sock_inotify_fd, GPG_AGENT_SOCK_NAME))
- {
- shutdown_pending = 1;
- log_info ("socket file has been removed - shutting down\n");
- }
-
- if (home_inotify_fd != -1
- && FD_ISSET (home_inotify_fd, &read_fdset))
- {
- shutdown_pending = 1;
- log_info ("homedir has been removed - shutting down\n");
- }
-
for (idx=0; idx < DIM(listentbl); idx++)
{
if (listentbl[idx].l_fd == GNUPG_INVALID_FD)
diff --git a/agent/protect.c b/agent/protect.c
index 3073fc4de..90690d950 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
@@ -104,11 +105,14 @@ calibrate_get_time (struct calibrate_time_s *data)
&data->creation_time, &data->exit_time,
&data->kernel_time, &data->user_time);
# endif
-#else
- struct tms tmp;
+#elif defined (CLOCK_THREAD_CPUTIME_ID)
+ struct timespec tmp;
- times (&tmp);
- data->ticks = tmp.tms_utime;
+ clock_gettime (CLOCK_THREAD_CPUTIME_ID, &tmp);
+ data->ticks = (clock_t)(((unsigned long long)tmp.tv_sec * 1000000000 +
+ tmp.tv_nsec) * CLOCKS_PER_SEC / 1000000000);
+#else
+ data->ticks = clock ();
#endif
}
@@ -135,7 +139,7 @@ calibrate_elapsed_time (struct calibrate_time_s *starttime)
}
#else
return (unsigned long)((((double) (stoptime.ticks - starttime->ticks))
- /CLOCKS_PER_SEC)*10000000);
+ /CLOCKS_PER_SEC)*1000);
#endif
}
@@ -159,7 +163,7 @@ calibrate_s2k_count_one (unsigned long count)
/* Measure the time we need to do the hash operations and deduce an
- S2K count which requires about 100ms of time. */
+ S2K count which requires roughly some targeted amount of time. */
static unsigned long
calibrate_s2k_count (void)
{
@@ -171,11 +175,11 @@ calibrate_s2k_count (void)
ms = calibrate_s2k_count_one (count);
if (opt.verbose > 1)
log_info ("S2K calibration: %lu -> %lums\n", count, ms);
- if (ms > 100)
+ if (ms > AGENT_S2K_CALIBRATION)
break;
}
- count = (unsigned long)(((double)count / ms) * 100);
+ count = (unsigned long)(((double)count / ms) * AGENT_S2K_CALIBRATION);
count /= 1024;
count *= 1024;
if (count < 65536)
diff --git a/agent/t-protect.c b/agent/t-protect.c
index 1d3c8ec17..92d312c9b 100644
--- a/agent/t-protect.c
+++ b/agent/t-protect.c
@@ -322,9 +322,9 @@ test_agent_protect_shared_secret (void)
int
main (int argc, char **argv)
{
- (void)argc;
(void)argv;
+ opt.verbose = argc - 1; /* We can do "./t-protect -v -v" */
gcry_control (GCRYCTL_DISABLE_SECMEM);
test_agent_protect ();