summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2018-05-06 12:24:45 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2018-05-06 12:24:45 +0000
commit20adc8f2a99cd37b64a80ef63dfc5ba6627d4dfb (patch)
treead57ce9ac9538c780c802adbdfc4c581f9100310 /session.c
parent343d57711556d429eda777ab259ff924acbd6b34 (diff)
Notes
Diffstat (limited to 'session.c')
-rw-r--r--session.c377
1 files changed, 185 insertions, 192 deletions
diff --git a/session.c b/session.c
index a08aa69d1679..4bccb62d1e4d 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.286 2016/11/30 03:00:05 djm Exp $ */
+/* $OpenBSD: session.c,v 1.292 2017/09/12 06:32:07 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -94,6 +94,7 @@
#include "kex.h"
#include "monitor_wrap.h"
#include "sftp.h"
+#include "atomicio.h"
#if defined(KRB5) && defined(USE_AFS)
#include <kafs.h>
@@ -112,29 +113,28 @@
/* func */
Session *session_new(void);
-void session_set_fds(Session *, int, int, int, int, int);
+void session_set_fds(struct ssh *, Session *, int, int, int, int, int);
void session_pty_cleanup(Session *);
void session_proctitle(Session *);
-int session_setup_x11fwd(Session *);
-int do_exec_pty(Session *, const char *);
-int do_exec_no_pty(Session *, const char *);
-int do_exec(Session *, const char *);
-void do_login(Session *, const char *);
+int session_setup_x11fwd(struct ssh *, Session *);
+int do_exec_pty(struct ssh *, Session *, const char *);
+int do_exec_no_pty(struct ssh *, Session *, const char *);
+int do_exec(struct ssh *, Session *, const char *);
+void do_login(struct ssh *, Session *, const char *);
+void do_child(struct ssh *, Session *, const char *);
#ifdef LOGIN_NEEDS_UTMPX
static void do_pre_login(Session *s);
#endif
-void do_child(Session *, const char *);
void do_motd(void);
int check_quietlogin(Session *, const char *);
-static void do_authenticated2(Authctxt *);
+static void do_authenticated2(struct ssh *, Authctxt *);
-static int session_pty_req(Session *);
+static int session_pty_req(struct ssh *, Session *);
/* import */
extern ServerOptions options;
extern char *__progname;
-extern int log_stderr;
extern int debug_flag;
extern u_int utmp_len;
extern int startup_pipe;
@@ -161,6 +161,9 @@ login_cap_t *lc;
static int is_child = 0;
static int in_chroot = 0;
+/* File containing userauth info, if ExposeAuthInfo set */
+static char *auth_info_file = NULL;
+
/* Name and directory of socket for authentication agent forwarding. */
static char *auth_sock_name = NULL;
static char *auth_sock_dir = NULL;
@@ -180,7 +183,7 @@ auth_sock_cleanup_proc(struct passwd *pw)
}
static int
-auth_input_request_forwarding(struct passwd * pw)
+auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
{
Channel *nc;
int sock = -1;
@@ -220,7 +223,7 @@ auth_input_request_forwarding(struct passwd * pw)
goto authsock_err;
/* Allocate a channel for the authentication agent socket. */
- nc = channel_new("auth socket",
+ nc = channel_new(ssh, "auth socket",
SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
0, "auth socket", 1);
@@ -250,8 +253,42 @@ display_loginmsg(void)
}
}
+static void
+prepare_auth_info_file(struct passwd *pw, struct sshbuf *info)
+{
+ int fd = -1, success = 0;
+
+ if (!options.expose_userauth_info || info == NULL)
+ return;
+
+ temporarily_use_uid(pw);
+ auth_info_file = xstrdup("/tmp/sshauth.XXXXXXXXXXXXXXX");
+ if ((fd = mkstemp(auth_info_file)) == -1) {
+ error("%s: mkstemp: %s", __func__, strerror(errno));
+ goto out;
+ }
+ if (atomicio(vwrite, fd, sshbuf_mutable_ptr(info),
+ sshbuf_len(info)) != sshbuf_len(info)) {
+ error("%s: write: %s", __func__, strerror(errno));
+ goto out;
+ }
+ if (close(fd) != 0) {
+ error("%s: close: %s", __func__, strerror(errno));
+ goto out;
+ }
+ success = 1;
+ out:
+ if (!success) {
+ if (fd != -1)
+ close(fd);
+ free(auth_info_file);
+ auth_info_file = NULL;
+ }
+ restore_uid();
+}
+
void
-do_authenticated(Authctxt *authctxt)
+do_authenticated(struct ssh *ssh, Authctxt *authctxt)
{
setproctitle("%s", authctxt->pw->pw_name);
@@ -259,14 +296,17 @@ do_authenticated(Authctxt *authctxt)
/* XXX - streamlocal? */
if (no_port_forwarding_flag || options.disable_forwarding ||
(options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
- channel_disable_adm_local_opens();
+ channel_disable_adm_local_opens(ssh);
else
- channel_permit_all_opens();
+ channel_permit_all_opens(ssh);
auth_debug_send();
- do_authenticated2(authctxt);
- do_cleanup(authctxt);
+ prepare_auth_info_file(authctxt->pw, authctxt->session_info);
+
+ do_authenticated2(ssh, authctxt);
+
+ do_cleanup(ssh, authctxt);
}
/* Check untrusted xauth strings for metacharacters */
@@ -291,7 +331,7 @@ xauth_valid_string(const char *s)
* setting up file descriptors and such.
*/
int
-do_exec_no_pty(Session *s, const char *command)
+do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
{
pid_t pid;
@@ -364,10 +404,6 @@ do_exec_no_pty(Session *s, const char *command)
case 0:
is_child = 1;
- /* Child. Reinitialize the log since the pid has changed. */
- log_init(__progname, options.log_level,
- options.log_facility, log_stderr);
-
/*
* Create a new session and process group since the 4.4BSD
* setlogin() affects the entire process group.
@@ -420,7 +456,7 @@ do_exec_no_pty(Session *s, const char *command)
#endif
/* Do processing for the child (exec command etc). */
- do_child(s, command);
+ do_child(ssh, s, command);
/* NOTREACHED */
default:
break;
@@ -451,7 +487,7 @@ do_exec_no_pty(Session *s, const char *command)
close(pout[1]);
close(perr[1]);
- session_set_fds(s, pin[1], pout[0], perr[0],
+ session_set_fds(ssh, s, pin[1], pout[0], perr[0],
s->is_subsystem, 0);
#else
/* We are the parent. Close the child sides of the socket pairs. */
@@ -475,7 +511,7 @@ do_exec_no_pty(Session *s, const char *command)
* lastlog, and other such operations.
*/
int
-do_exec_pty(Session *s, const char *command)
+do_exec_pty(struct ssh *ssh, Session *s, const char *command)
{
int fdout, ptyfd, ttyfd, ptymaster;
pid_t pid;
@@ -522,9 +558,6 @@ do_exec_pty(Session *s, const char *command)
close(fdout);
close(ptymaster);
- /* Child. Reinitialize the log because the pid has changed. */
- log_init(__progname, options.log_level,
- options.log_facility, log_stderr);
/* Close the master side of the pseudo tty. */
close(ptyfd);
@@ -547,13 +580,13 @@ do_exec_pty(Session *s, const char *command)
cray_init_job(s->pw); /* set up cray jid and tmpdir */
#endif /* _UNICOS */
#ifndef HAVE_OSF_SIA
- do_login(s, command);
+ do_login(ssh, s, command);
#endif
/*
* Do common processing for the child, such as execing
* the command.
*/
- do_child(s, command);
+ do_child(ssh, s, command);
/* NOTREACHED */
default:
break;
@@ -575,7 +608,7 @@ do_exec_pty(Session *s, const char *command)
s->ptymaster = ptymaster;
packet_set_interactive(1,
options.ip_qos_interactive, options.ip_qos_bulk);
- session_set_fds(s, ptyfd, fdout, -1, 1, 1);
+ session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1);
return 0;
}
@@ -613,9 +646,8 @@ do_pre_login(Session *s)
* to be forced, execute that instead.
*/
int
-do_exec(Session *s, const char *command)
+do_exec(struct ssh *ssh, Session *s, const char *command)
{
- struct ssh *ssh = active_state; /* XXX */
int ret;
const char *forced = NULL, *tty = NULL;
char session_type[1024];
@@ -674,9 +706,9 @@ do_exec(Session *s, const char *command)
}
#endif
if (s->ttyfd != -1)
- ret = do_exec_pty(s, command);
+ ret = do_exec_pty(ssh, s, command);
else
- ret = do_exec_no_pty(s, command);
+ ret = do_exec_no_pty(ssh, s, command);
original_command = NULL;
@@ -692,9 +724,8 @@ do_exec(Session *s, const char *command)
/* administrative, login(1)-like work */
void
-do_login(Session *s, const char *command)
+do_login(struct ssh *ssh, Session *s, const char *command)
{
- struct ssh *ssh = active_state; /* XXX */
socklen_t fromlen;
struct sockaddr_storage from;
struct passwd * pw = s->pw;
@@ -792,65 +823,6 @@ check_quietlogin(Session *s, const char *command)
}
/*
- * Sets the value of the given variable in the environment. If the variable
- * already exists, its value is overridden.
- */
-void
-child_set_env(char ***envp, u_int *envsizep, const char *name,
- const char *value)
-{
- char **env;
- u_int envsize;
- u_int i, namelen;
-
- if (strchr(name, '=') != NULL) {
- error("Invalid environment variable \"%.100s\"", name);
- return;
- }
-
- /*
- * If we're passed an uninitialized list, allocate a single null
- * entry before continuing.
- */
- if (*envp == NULL && *envsizep == 0) {
- *envp = xmalloc(sizeof(char *));
- *envp[0] = NULL;
- *envsizep = 1;
- }
-
- /*
- * Find the slot where the value should be stored. If the variable
- * already exists, we reuse the slot; otherwise we append a new slot
- * at the end of the array, expanding if necessary.
- */
- env = *envp;
- namelen = strlen(name);
- for (i = 0; env[i]; i++)
- if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
- break;
- if (env[i]) {
- /* Reuse the slot. */
- free(env[i]);
- } else {
- /* New variable. Expand if necessary. */
- envsize = *envsizep;
- if (i >= envsize - 1) {
- if (envsize >= 1000)
- fatal("child_set_env: too many env vars");
- envsize += 50;
- env = (*envp) = xreallocarray(env, envsize, sizeof(char *));
- *envsizep = envsize;
- }
- /* Need to set the NULL pointer at end of array beyond the new slot. */
- env[i + 1] = NULL;
- }
-
- /* Allocate space and format the variable in the appropriate slot. */
- env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
- snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
-}
-
-/*
* Reads environment variables from the given file and adds/overrides them
* into the environment. If the file does not exist, this does nothing.
* Otherwise, it must consist of empty lines, comments (line starts with '#')
@@ -951,8 +923,9 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
}
#endif /* HAVE_ETC_DEFAULT_LOGIN */
-void
-copy_environment(char **source, char ***env, u_int *envsize)
+static void
+copy_environment_blacklist(char **source, char ***env, u_int *envsize,
+ const char *blacklist)
{
char *var_name, *var_val;
int i;
@@ -968,17 +941,25 @@ copy_environment(char **source, char ***env, u_int *envsize)
}
*var_val++ = '\0';
- debug3("Copy environment: %s=%s", var_name, var_val);
- child_set_env(env, envsize, var_name, var_val);
+ if (blacklist == NULL ||
+ match_pattern_list(var_name, blacklist, 0) != 1) {
+ debug3("Copy environment: %s=%s", var_name, var_val);
+ child_set_env(env, envsize, var_name, var_val);
+ }
free(var_name);
}
}
+void
+copy_environment(char **source, char ***env, u_int *envsize)
+{
+ copy_environment_blacklist(source, env, envsize, NULL);
+}
+
static char **
-do_setup_env(Session *s, const char *shell)
+do_setup_env(struct ssh *ssh, Session *s, const char *shell)
{
- struct ssh *ssh = active_state; /* XXX */
char buf[256];
u_int i, envsize;
char **env, *laddr;
@@ -1085,6 +1066,8 @@ do_setup_env(Session *s, const char *shell)
free(laddr);
child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
+ if (auth_info_file != NULL)
+ child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
if (s->ttyfd != -1)
child_set_env(&env, &envsize, "SSH_TTY", s->tty);
if (s->term)
@@ -1134,12 +1117,16 @@ do_setup_env(Session *s, const char *shell)
if (options.use_pam) {
char **p;
+ /*
+ * Don't allow SSH_AUTH_INFO variables posted to PAM to leak
+ * back into the environment.
+ */
p = fetch_pam_child_environment();
- copy_environment(p, &env, &envsize);
+ copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*");
free_pam_environment(p);
p = fetch_pam_environment();
- copy_environment(p, &env, &envsize);
+ copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*");
free_pam_environment(p);
}
#endif /* USE_PAM */
@@ -1431,7 +1418,7 @@ do_pwchange(Session *s)
}
static void
-child_close_fds(void)
+child_close_fds(struct ssh *ssh)
{
extern int auth_sock;
@@ -1451,7 +1438,7 @@ child_close_fds(void)
* open in the parent.
*/
/* XXX better use close-on-exec? -markus */
- channel_close_all();
+ channel_close_all(ssh);
/*
* Close any extra file descriptors. Note that there may still be
@@ -1475,7 +1462,7 @@ child_close_fds(void)
*/
#define ARGV_MAX 10
void
-do_child(Session *s, const char *command)
+do_child(struct ssh *ssh, Session *s, const char *command)
{
extern char **environ;
char **env;
@@ -1486,11 +1473,12 @@ do_child(Session *s, const char *command)
/* remove hostkey from the child's memory */
destroy_sensitive_data();
+ packet_clear_keys();
/* Force a password change */
if (s->authctxt->force_pwchange) {
do_setusercontext(pw);
- child_close_fds();
+ child_close_fds(ssh);
do_pwchange(s);
exit(1);
}
@@ -1539,7 +1527,7 @@ do_child(Session *s, const char *command)
* Make sure $SHELL points to the shell from the password file,
* even if shell is overridden from login.conf
*/
- env = do_setup_env(s, shell);
+ env = do_setup_env(ssh, s, shell);
#ifdef HAVE_LOGIN_CAP
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
@@ -1552,7 +1540,7 @@ do_child(Session *s, const char *command)
* closed before building the environment, as we call
* ssh_remote_ipaddr there.
*/
- child_close_fds();
+ child_close_fds(ssh);
/*
* Must take new environment into use so that .ssh/rc,
@@ -1710,8 +1698,8 @@ session_new(void)
return NULL;
debug2("%s: allocate (allocated %d max %d)",
__func__, sessions_nalloc, options.max_sessions);
- tmp = xreallocarray(sessions, sessions_nalloc + 1,
- sizeof(*sessions));
+ tmp = xrecallocarray(sessions, sessions_nalloc,
+ sessions_nalloc + 1, sizeof(*sessions));
if (tmp == NULL) {
error("%s: cannot allocate %d sessions",
__func__, sessions_nalloc + 1);
@@ -1849,7 +1837,7 @@ session_by_pid(pid_t pid)
}
static int
-session_window_change_req(Session *s)
+session_window_change_req(struct ssh *ssh, Session *s)
{
s->col = packet_get_int();
s->row = packet_get_int();
@@ -1861,7 +1849,7 @@ session_window_change_req(Session *s)
}
static int
-session_pty_req(Session *s)
+session_pty_req(struct ssh *ssh, Session *s)
{
u_int len;
int n_bytes;
@@ -1914,7 +1902,7 @@ session_pty_req(Session *s)
}
static int
-session_subsystem_req(Session *s)
+session_subsystem_req(struct ssh *ssh, Session *s)
{
struct stat st;
u_int len;
@@ -1941,7 +1929,7 @@ session_subsystem_req(Session *s)
s->is_subsystem = SUBSYSTEM_EXT;
debug("subsystem: exec() %s", cmd);
}
- success = do_exec(s, cmd) == 0;
+ success = do_exec(ssh, s, cmd) == 0;
break;
}
}
@@ -1954,7 +1942,7 @@ session_subsystem_req(Session *s)
}
static int
-session_x11_req(Session *s)
+session_x11_req(struct ssh *ssh, Session *s)
{
int success;
@@ -1971,7 +1959,7 @@ session_x11_req(Session *s)
if (xauth_valid_string(s->auth_proto) &&
xauth_valid_string(s->auth_data))
- success = session_setup_x11fwd(s);
+ success = session_setup_x11fwd(ssh, s);
else {
success = 0;
error("Invalid X11 forwarding data");
@@ -1986,26 +1974,26 @@ session_x11_req(Session *s)
}
static int
-session_shell_req(Session *s)
+session_shell_req(struct ssh *ssh, Session *s)
{
packet_check_eom();
- return do_exec(s, NULL) == 0;
+ return do_exec(ssh, s, NULL) == 0;
}
static int
-session_exec_req(Session *s)
+session_exec_req(struct ssh *ssh, Session *s)
{
u_int len, success;
char *command = packet_get_string(&len);
packet_check_eom();
- success = do_exec(s, command) == 0;
+ success = do_exec(ssh, s, command) == 0;
free(command);
return success;
}
static int
-session_break_req(Session *s)
+session_break_req(struct ssh *ssh, Session *s)
{
packet_get_int(); /* ignored */
@@ -2017,7 +2005,7 @@ session_break_req(Session *s)
}
static int
-session_env_req(Session *s)
+session_env_req(struct ssh *ssh, Session *s)
{
char *name, *val;
u_int name_len, val_len, i;
@@ -2035,8 +2023,8 @@ session_env_req(Session *s)
for (i = 0; i < options.num_accept_env; i++) {
if (match_pattern(name, options.accept_env[i])) {
debug2("Setting env %d: %s=%s", s->num_env, name, val);
- s->env = xreallocarray(s->env, s->num_env + 1,
- sizeof(*s->env));
+ s->env = xrecallocarray(s->env, s->num_env,
+ s->num_env + 1, sizeof(*s->env));
s->env[s->num_env].name = name;
s->env[s->num_env].val = val;
s->num_env++;
@@ -2052,7 +2040,7 @@ session_env_req(Session *s)
}
static int
-session_auth_agent_req(Session *s)
+session_auth_agent_req(struct ssh *ssh, Session *s)
{
static int called = 0;
packet_check_eom();
@@ -2064,22 +2052,21 @@ session_auth_agent_req(Session *s)
return 0;
} else {
called = 1;
- return auth_input_request_forwarding(s->pw);
+ return auth_input_request_forwarding(ssh, s->pw);
}
}
int
-session_input_channel_req(Channel *c, const char *rtype)
+session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype)
{
int success = 0;
Session *s;
if ((s = session_by_channel(c->self)) == NULL) {
- logit("session_input_channel_req: no session %d req %.100s",
- c->self, rtype);
+ logit("%s: no session %d req %.100s", __func__, c->self, rtype);
return 0;
}
- debug("session_input_channel_req: session %d req %s", s->self, rtype);
+ debug("%s: session %d req %s", __func__, s->self, rtype);
/*
* a session is in LARVAL state until a shell, a command
@@ -2087,33 +2074,33 @@ session_input_channel_req(Channel *c, const char *rtype)
*/
if (c->type == SSH_CHANNEL_LARVAL) {
if (strcmp(rtype, "shell") == 0) {
- success = session_shell_req(s);
+ success = session_shell_req(ssh, s);
} else if (strcmp(rtype, "exec") == 0) {
- success = session_exec_req(s);
+ success = session_exec_req(ssh, s);
} else if (strcmp(rtype, "pty-req") == 0) {
- success = session_pty_req(s);
+ success = session_pty_req(ssh, s);
} else if (strcmp(rtype, "x11-req") == 0) {
- success = session_x11_req(s);
+ success = session_x11_req(ssh, s);
} else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
- success = session_auth_agent_req(s);
+ success = session_auth_agent_req(ssh, s);
} else if (strcmp(rtype, "subsystem") == 0) {
- success = session_subsystem_req(s);
+ success = session_subsystem_req(ssh, s);
} else if (strcmp(rtype, "env") == 0) {
- success = session_env_req(s);
+ success = session_env_req(ssh, s);
}
}
if (strcmp(rtype, "window-change") == 0) {
- success = session_window_change_req(s);
+ success = session_window_change_req(ssh, s);
} else if (strcmp(rtype, "break") == 0) {
- success = session_break_req(s);
+ success = session_break_req(ssh, s);
}
return success;
}
void
-session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
- int is_tty)
+session_set_fds(struct ssh *ssh, Session *s,
+ int fdin, int fdout, int fderr, int ignore_fderr, int is_tty)
{
/*
* now that have a child and a pipe to the child,
@@ -2121,7 +2108,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
*/
if (s->chanid == -1)
fatal("no channel for session %d", s->self);
- channel_set_fds(s->chanid,
+ channel_set_fds(ssh, s->chanid,
fdout, fdin, fderr,
ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1, is_tty, CHAN_SES_WINDOW_DEFAULT);
@@ -2192,40 +2179,40 @@ sig2name(int sig)
}
static void
-session_close_x11(int id)
+session_close_x11(struct ssh *ssh, int id)
{
Channel *c;
- if ((c = channel_by_id(id)) == NULL) {
- debug("session_close_x11: x11 channel %d missing", id);
+ if ((c = channel_by_id(ssh, id)) == NULL) {
+ debug("%s: x11 channel %d missing", __func__, id);
} else {
/* Detach X11 listener */
- debug("session_close_x11: detach x11 channel %d", id);
- channel_cancel_cleanup(id);
+ debug("%s: detach x11 channel %d", __func__, id);
+ channel_cancel_cleanup(ssh, id);
if (c->ostate != CHAN_OUTPUT_CLOSED)
- chan_mark_dead(c);
+ chan_mark_dead(ssh, c);
}
}
static void
-session_close_single_x11(int id, void *arg)
+session_close_single_x11(struct ssh *ssh, int id, void *arg)
{
Session *s;
u_int i;
- debug3("session_close_single_x11: channel %d", id);
- channel_cancel_cleanup(id);
+ debug3("%s: channel %d", __func__, id);
+ channel_cancel_cleanup(ssh, id);
if ((s = session_by_x11_channel(id)) == NULL)
- fatal("session_close_single_x11: no x11 channel %d", id);
+ fatal("%s: no x11 channel %d", __func__, id);
for (i = 0; s->x11_chanids[i] != -1; i++) {
- debug("session_close_single_x11: session %d: "
- "closing channel %d", s->self, s->x11_chanids[i]);
+ debug("%s: session %d: closing channel %d",
+ __func__, s->self, s->x11_chanids[i]);
/*
* The channel "id" is already closing, but make sure we
* close all of its siblings.
*/
if (s->x11_chanids[i] != id)
- session_close_x11(s->x11_chanids[i]);
+ session_close_x11(ssh, s->x11_chanids[i]);
}
free(s->x11_chanids);
s->x11_chanids = NULL;
@@ -2240,22 +2227,22 @@ session_close_single_x11(int id, void *arg)
}
static void
-session_exit_message(Session *s, int status)
+session_exit_message(struct ssh *ssh, Session *s, int status)
{
Channel *c;
- if ((c = channel_lookup(s->chanid)) == NULL)
- fatal("session_exit_message: session %d: no channel %d",
- s->self, s->chanid);
- debug("session_exit_message: session %d channel %d pid %ld",
- s->self, s->chanid, (long)s->pid);
+ if ((c = channel_lookup(ssh, s->chanid)) == NULL)
+ fatal("%s: session %d: no channel %d",
+ __func__, s->self, s->chanid);
+ debug("%s: session %d channel %d pid %ld",
+ __func__, s->self, s->chanid, (long)s->pid);
if (WIFEXITED(status)) {
- channel_request_start(s->chanid, "exit-status", 0);
+ channel_request_start(ssh, s->chanid, "exit-status", 0);
packet_put_int(WEXITSTATUS(status));
packet_send();
} else if (WIFSIGNALED(status)) {
- channel_request_start(s->chanid, "exit-signal", 0);
+ channel_request_start(ssh, s->chanid, "exit-signal", 0);
packet_put_cstring(sig2name(WTERMSIG(status)));
#ifdef WCOREDUMP
packet_put_char(WCOREDUMP(status)? 1 : 0);
@@ -2271,14 +2258,14 @@ session_exit_message(Session *s, int status)
}
/* disconnect channel */
- debug("session_exit_message: release channel %d", s->chanid);
+ debug("%s: release channel %d", __func__, s->chanid);
/*
* Adjust cleanup callback attachment to send close messages when
* the channel gets EOF. The session will be then be closed
* by session_close_by_channel when the childs close their fds.
*/
- channel_register_cleanup(c->self, session_close_by_channel, 1);
+ channel_register_cleanup(ssh, c->self, session_close_by_channel, 1);
/*
* emulate a write failure with 'chan_write_failed', nobody will be
@@ -2287,13 +2274,12 @@ session_exit_message(Session *s, int status)
* be some more data waiting in the pipe.
*/
if (c->ostate != CHAN_OUTPUT_CLOSED)
- chan_write_failed(c);
+ chan_write_failed(ssh, c);
}
void
-session_close(Session *s)
+session_close(struct ssh *ssh, Session *s)
{
- struct ssh *ssh = active_state; /* XXX */
u_int i;
verbose("Close session: user %s from %.200s port %d id %d",
@@ -2323,16 +2309,15 @@ session_close(Session *s)
}
void
-session_close_by_pid(pid_t pid, int status)
+session_close_by_pid(struct ssh *ssh, pid_t pid, int status)
{
Session *s = session_by_pid(pid);
if (s == NULL) {
- debug("session_close_by_pid: no session for pid %ld",
- (long)pid);
+ debug("%s: no session for pid %ld", __func__, (long)pid);
return;
}
if (s->chanid != -1)
- session_exit_message(s, status);
+ session_exit_message(ssh, s, status);
if (s->ttyfd != -1)
session_pty_cleanup(s);
s->pid = 0;
@@ -2343,19 +2328,18 @@ session_close_by_pid(pid_t pid, int status)
* the session 'child' itself dies
*/
void
-session_close_by_channel(int id, void *arg)
+session_close_by_channel(struct ssh *ssh, int id, void *arg)
{
Session *s = session_by_channel(id);
u_int i;
if (s == NULL) {
- debug("session_close_by_channel: no session for id %d", id);
+ debug("%s: no session for id %d", __func__, id);
return;
}
- debug("session_close_by_channel: channel %d child %ld",
- id, (long)s->pid);
+ debug("%s: channel %d child %ld", __func__, id, (long)s->pid);
if (s->pid != 0) {
- debug("session_close_by_channel: channel %d: has child", id);
+ debug("%s: channel %d: has child", __func__, id);
/*
* delay detach of session, but release pty, since
* the fd's to the child are already closed
@@ -2365,22 +2349,22 @@ session_close_by_channel(int id, void *arg)
return;
}
/* detach by removing callback */
- channel_cancel_cleanup(s->chanid);
+ channel_cancel_cleanup(ssh, s->chanid);
/* Close any X11 listeners associated with this session */
if (s->x11_chanids != NULL) {
for (i = 0; s->x11_chanids[i] != -1; i++) {
- session_close_x11(s->x11_chanids[i]);
+ session_close_x11(ssh, s->x11_chanids[i]);
s->x11_chanids[i] = -1;
}
}
s->chanid = -1;
- session_close(s);
+ session_close(ssh, s);
}
void
-session_destroy_all(void (*closefunc)(Session *))
+session_destroy_all(struct ssh *ssh, void (*closefunc)(Session *))
{
int i;
for (i = 0; i < sessions_nalloc; i++) {
@@ -2389,7 +2373,7 @@ session_destroy_all(void (*closefunc)(Session *))
if (closefunc != NULL)
closefunc(s);
else
- session_close(s);
+ session_close(ssh, s);
}
}
}
@@ -2432,7 +2416,7 @@ session_proctitle(Session *s)
}
int
-session_setup_x11fwd(Session *s)
+session_setup_x11fwd(struct ssh *ssh, Session *s)
{
struct stat st;
char display[512], auth_display[512];
@@ -2456,14 +2440,14 @@ session_setup_x11fwd(Session *s)
debug("X11 display already set.");
return 0;
}
- if (x11_create_display_inet(options.x11_display_offset,
+ if (x11_create_display_inet(ssh, options.x11_display_offset,
options.x11_use_localhost, s->single_connection,
&s->display_number, &s->x11_chanids) == -1) {
debug("x11_create_display_inet failed.");
return 0;
}
for (i = 0; s->x11_chanids[i] != -1; i++) {
- channel_register_cleanup(s->x11_chanids[i],
+ channel_register_cleanup(ssh, s->x11_chanids[i],
session_close_single_x11, 0);
}
@@ -2508,13 +2492,13 @@ session_setup_x11fwd(Session *s)
}
static void
-do_authenticated2(Authctxt *authctxt)
+do_authenticated2(struct ssh *ssh, Authctxt *authctxt)
{
- server_loop2(authctxt);
+ server_loop2(ssh, authctxt);
}
void
-do_cleanup(Authctxt *authctxt)
+do_cleanup(struct ssh *ssh, Authctxt *authctxt)
{
static int called = 0;
@@ -2556,12 +2540,21 @@ do_cleanup(Authctxt *authctxt)
/* remove agent socket */
auth_sock_cleanup_proc(authctxt->pw);
+ /* remove userauth info */
+ if (auth_info_file != NULL) {
+ temporarily_use_uid(authctxt->pw);
+ unlink(auth_info_file);
+ restore_uid();
+ free(auth_info_file);
+ auth_info_file = NULL;
+ }
+
/*
* Cleanup ptys/utmp only if privsep is disabled,
* or if running in monitor.
*/
if (!use_privsep || mm_is_monitor())
- session_destroy_all(session_pty_cleanup2);
+ session_destroy_all(ssh, session_pty_cleanup2);
}
/* Return a name for the remote host that fits inside utmp_size */