diff options
-rw-r--r-- | agent/agent.h | 1 | ||||
-rw-r--r-- | agent/call-pinentry.c | 5 | ||||
-rw-r--r-- | agent/command-ssh.c | 27 | ||||
-rw-r--r-- | agent/command.c | 18 |
4 files changed, 38 insertions, 13 deletions
diff --git a/agent/agent.h b/agent/agent.h index f5df75e6e..af64f335e 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -226,6 +226,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 6a5c1fe1e..98af95a92 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -593,8 +593,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/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 fd39c680f..4016cc20b 100644 --- a/agent/command.c +++ b/agent/command.c @@ -3328,7 +3328,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) @@ -3341,12 +3341,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) |