*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.61 2001/03/16 19:06:30 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.67 2001/03/23 14:28:32 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
struct Session {
int used;
int self;
- int extended;
struct passwd *pw;
pid_t pid;
/* tty */
int single_connection;
/* proto 2 */
int chanid;
+ int is_subsystem;
};
/* func */
void session_set_fds(Session *s, int fdin, int fdout, int fderr);
void session_pty_cleanup(Session *s);
void session_proctitle(Session *s);
-void do_exec_pty(Session *s, const char *command, struct passwd * pw);
-void do_exec_no_pty(Session *s, const char *command, struct passwd * pw);
+void do_exec_pty(Session *s, const char *command);
+void do_exec_no_pty(Session *s, const char *command);
void do_login(Session *s, const char *command);
void do_child(Session *s, const char *command);
+void do_authenticated1(Authctxt *authctxt);
+void do_authenticated2(Authctxt *authctxt);
+
/* import */
extern ServerOptions options;
extern char *__progname;
static login_cap_t *lc;
#endif
+void
+do_authenticated(Authctxt *authctxt)
+{
+ /*
+ * Cancel the alarm we set to limit the time taken for
+ * authentication.
+ */
+ alarm(0);
+ if (startup_pipe != -1) {
+ close(startup_pipe);
+ startup_pipe = -1;
+ }
+#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD)
+ if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
+ error("unable to get login class");
+ return;
+ }
+#endif
+ /* setup the channel layer */
+ if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
+ channel_permit_all_opens();
+
+ if (compat20)
+ do_authenticated2(authctxt);
+ else
+ do_authenticated1(authctxt);
+}
+
/*
* Remove local Xauthority file.
*/
* are requested, etc.
*/
void
-do_authenticated(struct passwd * pw)
+do_authenticated1(Authctxt *authctxt)
{
Session *s;
- int type, fd;
- int compression_level = 0, enable_compression_after_reply = 0;
- int have_pty = 0;
char *command;
- int n_bytes;
- int plen;
+ int success, type, fd, n_bytes, plen, screen_flag, have_pty = 0;
+ int compression_level = 0, enable_compression_after_reply = 0;
u_int proto_len, data_len, dlen;
- int screen_flag;
-
- /*
- * Cancel the alarm we set to limit the time taken for
- * authentication.
- */
- alarm(0);
- if (startup_pipe != -1) {
- close(startup_pipe);
- startup_pipe = -1;
- }
-
- if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
- channel_permit_all_opens();
s = session_new();
- s->pw = pw;
-
-#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD)
- if ((lc = login_getclass(pw->pw_class)) == NULL) {
- error("unable to get login class");
- return;
- }
-#endif
+ s->pw = authctxt->pw;
/*
* We stay in this loop until the client requests to execute a shell
* or a command.
*/
for (;;) {
- int success = 0;
+ success = 0;
/* Get a packet from the client. */
type = packet_read(&plen);
break;
}
fatal_add_cleanup(pty_cleanup_proc, (void *)s);
- pty_setowner(pw, s->tty);
+ pty_setowner(s->pw, s->tty);
/* Get TERM from the packet. Note that the value may be of arbitrary length. */
s->term = packet_get_string(&dlen);
/* Setup to always have a local .Xauthority. */
xauthfile = xmalloc(MAXPATHLEN);
strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
- temporarily_use_uid(pw->pw_uid);
+ temporarily_use_uid(s->pw->pw_uid);
if (mkdtemp(xauthfile) == NULL) {
restore_uid();
error("private X11 dir: mkdtemp %s failed: %s",
break;
}
debug("Received authentication agent forwarding request.");
- success = auth_input_request_forwarding(pw);
+ success = auth_input_request_forwarding(s->pw);
break;
case SSH_CMSG_PORT_FORWARD_REQUEST:
break;
}
debug("Received TCP/IP port forwarding request.");
- channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports);
+ channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
success = 1;
break;
debug("Forced command '%.500s'", forced_command);
}
if (have_pty)
- do_exec_pty(s, command, pw);
+ do_exec_pty(s, command);
else
- do_exec_no_pty(s, command, pw);
+ do_exec_no_pty(s, command);
if (command != NULL)
xfree(command);
* setting up file descriptors and such.
*/
void
-do_exec_no_pty(Session *s, const char *command, struct passwd * pw)
+do_exec_no_pty(Session *s, const char *command)
{
int pid;
close(perr[1]);
if (compat20) {
- session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1);
+ session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]);
} else {
/* Enter the interactive session. */
server_loop(pid, pin[1], pout[0], perr[0]);
- /* server_loop has closed pin[1], pout[1], and perr[1]. */
+ /* server_loop has closed pin[1], pout[0], and perr[0]. */
}
#else /* USE_PIPES */
/* We are the parent. Close the child sides of the socket pairs. */
* handle the case that fdin and fdout are the same.
*/
if (compat20) {
- session_set_fds(s, inout[1], inout[1], s->extended ? err[1] : -1);
+ session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]);
} else {
server_loop(pid, inout[1], inout[1], err[1]);
/* server_loop has closed inout[1] and err[1]. */
* lastlog, and other such operations.
*/
void
-do_exec_pty(Session *s, const char *command, struct passwd * pw)
+do_exec_pty(Session *s, const char *command)
{
int fdout, ptyfd, ttyfd, ptymaster;
pid_t pid;
ttyfd = s->ttyfd;
#if defined(USE_PAM)
- do_pam_session(pw->pw_name, s->tty);
+ do_pam_session(s->pw->pw_name, s->tty);
do_pam_setcred();
#endif
switch, so we let login(1) to this for us. */
if (!options.use_login) {
#ifdef HAVE_OSF_SIA
- session_setup_sia(pw->pw_name, ttyname);
+ session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty);
#else /* HAVE_OSF_SIA */
#ifdef HAVE_CYGWIN
if (is_winnt) {
* other stuff is stored - a few applications
* actually use this and die if it's not set
*/
- cp = xmalloc(22 + strlen(ttyname) +
+ if (s->ttyfd == -1)
+ s->tty[0] = '\0';
+ cp = xmalloc(22 + strlen(s->tty) +
2 * strlen(pw->pw_name));
i = sprintf(cp, "LOGNAME=%s%cNAME=%s%cTTY=%s%c%c",
- pw->pw_name, 0, pw->pw_name, 0, ttyname, 0,0);
+ pw->pw_name, 0, pw->pw_name, 0, s->tty, 0, 0);
if (usrinfo(SETUINFO, cp, i) == -1)
fatal("Couldn't set usrinfo: %s",
strerror(errno));
else
cp = shell;
}
+
+ /* restore SIGPIPE for child */
+ signal(SIGPIPE, SIG_DFL);
+
/*
* If we have no command, execute the shell. In this case, the shell
* name to be passed in argv[0] is preceded by '-' to indicate that
Session *s = &sessions[i];
if (! s->used) {
s->pid = 0;
- s->extended = 0;
+ s->is_subsystem = 0;
s->chanid = -1;
s->ptyfd = -1;
s->ttyfd = -1;
+ s->tty[0] = '\0';
s->term = NULL;
s->pw = NULL;
s->display = NULL;
for (i = 0; i < options.num_subsystems; i++) {
if(strcmp(subsys, options.subsystem_name[i]) == 0) {
debug("subsystem: exec() %s", options.subsystem_command[i]);
- do_exec_no_pty(s, options.subsystem_command[i], s->pw);
+ s->is_subsystem = 1;
+ do_exec_no_pty(s, options.subsystem_command[i]);
success = 1;
}
}
/* if forced_command == NULL, the shell is execed */
char *shell = forced_command;
packet_done();
- s->extended = 1;
if (s->ttyfd == -1)
- do_exec_no_pty(s, shell, s->pw);
+ do_exec_no_pty(s, shell);
else
- do_exec_pty(s, shell, s->pw);
+ do_exec_pty(s, shell);
return 1;
}
command = forced_command;
debug("Forced command '%.500s'", forced_command);
}
- s->extended = 1;
if (s->ttyfd == -1)
- do_exec_no_pty(s, command, s->pw);
+ do_exec_no_pty(s, command);
else
- do_exec_pty(s, command, s->pw);
+ do_exec_pty(s, command);
if (forced_command == NULL)
xfree(command);
return 1;
s->self, id, rtype, reply);
/*
- * a session is in LARVAL state until a shell
- * or programm is executed
+ * a session is in LARVAL state until a shell, a command
+ * or a subsystem is executed
*/
if (c->type == SSH_CHANNEL_LARVAL) {
if (strcmp(rtype, "shell") == 0) {
void
do_authenticated2(Authctxt *authctxt)
{
- /*
- * Cancel the alarm we set to limit the time taken for
- * authentication.
- */
- alarm(0);
- if (startup_pipe != -1) {
- close(startup_pipe);
- startup_pipe = -1;
- }
- if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
- channel_permit_all_opens();
-#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD)
- if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
- error("unable to get login class");
- return;
- }
-#endif
+
server_loop2();
if (xauthfile)
xauthfile_cleanup_proc(NULL);