*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.181 2004/12/23 17:35:48 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
#include "serverloop.h"
#include "canohost.h"
#include "session.h"
+#include "kex.h"
#include "monitor_wrap.h"
#if defined(KRB5) && defined(USE_AFS)
packet_disconnect("listen: %.100s", strerror(errno));
/* Allocate a channel for the authentication agent socket. */
+ /* this shouldn't matter if its hpn or not - cjr */
nc = channel_new("auth socket",
SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
static void
display_loginmsg(void)
{
- if (buffer_len(&loginmsg) > 0) {
- buffer_append(&loginmsg, "\0", 1);
- printf("%s", (char *)buffer_ptr(&loginmsg));
- buffer_clear(&loginmsg);
- }
+ if (buffer_len(&loginmsg) > 0) {
+ buffer_append(&loginmsg, "\0", 1);
+ printf("%s", (char *)buffer_ptr(&loginmsg));
+ buffer_clear(&loginmsg);
+ }
}
void
{
setproctitle("%s", authctxt->pw->pw_name);
- /*
- * Cancel the alarm we set to limit the time taken for
- * authentication.
- */
- alarm(0);
- if (startup_pipe != -1) {
- close(startup_pipe);
- startup_pipe = -1;
- }
/* setup the channel layer */
if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
channel_permit_all_opens();
compression_level);
break;
}
- if (!options.compression) {
+ if (options.compression == COMP_NONE) {
debug2("compression disabled");
break;
}
break;
}
debug("Received TCP/IP port forwarding request.");
- channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
+ channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports,
+ options.hpn_disabled,
+ options.hpn_buffer_size);
success = 1;
break;
}
#endif
-#ifdef GSSAPI
- if (options.gss_authentication) {
- temporarily_use_uid(s->pw);
- ssh_gssapi_storecreds();
- restore_uid();
- }
-#endif
-
#ifdef SSH_AUDIT_EVENTS
if (command != NULL)
PRIVSEP(audit_run_command(command));
}
#endif /* HAVE_ETC_DEFAULT_LOGIN */
-void copy_environment(char **source, char ***env, u_int *envsize)
+void
+copy_environment(char **source, char ***env, u_int *envsize)
{
char *var_name, *var_val;
int i;
# ifdef _AIX
aix_usrinfo(pw);
# endif /* _AIX */
+#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF)
+ if (set_id(pw->pw_name) != 0) {
+ exit(1);
+ }
+#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */
/* Permanently switch to the desired uid. */
permanently_set_uid(pw);
#endif
endpwent();
/*
- * Close any extra open file descriptors so that we don\'t have them
+ * Close any extra open file descriptors so that we don't have them
* hanging around in clients. Note that we want to do this after
* initgroups, because at least on Solaris 2.3 it leaves file
* descriptors open.
if (!check_quietlogin(s, command))
do_motd();
#else /* HAVE_OSF_SIA */
- do_nologin(pw);
+ /* When PAM is enabled we rely on it to do the nologin check */
+ if (!options.use_pam)
+ do_nologin(pw);
do_setusercontext(pw);
/*
* PAM session modules in do_setusercontext may have
*/
if (options.kerberos_get_afs_token && k_hasafs() &&
- (s->authctxt->krb5_ctx != NULL)) {
+ (s->authctxt->krb5_ctx != NULL)) {
char cell[64];
debug("Getting AFS token");
}
#endif
- /* Change current directory to the user\'s home directory. */
+ /* Change current directory to the user's home directory. */
if (chdir(pw->pw_dir) < 0) {
fprintf(stderr, "Could not chdir to home directory %s: %s\n",
pw->pw_dir, strerror(errno));
s->ttyfd = -1;
s->used = 1;
s->self = i;
+ s->x11_chanids = NULL;
debug("session_new: session %d", i);
return s;
}
return NULL;
}
+static Session *
+session_by_x11_channel(int id)
+{
+ int i, j;
+
+ for (i = 0; i < MAX_SESSIONS; i++) {
+ Session *s = &sessions[i];
+
+ if (s->x11_chanids == NULL || !s->used)
+ continue;
+ for (j = 0; s->x11_chanids[j] != -1; j++) {
+ if (s->x11_chanids[j] == id) {
+ debug("session_by_x11_channel: session %d "
+ "channel %d", s->self, id);
+ return s;
+ }
+ }
+ }
+ debug("session_by_x11_channel: unknown channel %d", id);
+ session_dump();
+ return NULL;
+}
+
static Session *
session_by_pid(pid_t pid)
{
u_int len;
int success = 0;
char *cmd, *subsys = packet_get_string(&len);
- int i;
+ u_int i;
packet_check_eom();
logit("subsystem request for %.100s", subsys);
{
int success;
+ if (s->auth_proto != NULL || s->auth_data != NULL) {
+ error("session_x11_req: session %d: "
+ "x11 forwarding already active", s->self);
+ return 0;
+ }
s->single_connection = packet_get_char();
s->auth_proto = packet_get_string(NULL);
s->auth_data = packet_get_string(NULL);
*/
if (s->chanid == -1)
fatal("no channel for session %d", s->self);
- channel_set_fds(s->chanid,
- fdout, fdin, fderr,
- fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
- 1,
- CHAN_SES_WINDOW_DEFAULT);
+ if(options.hpn_disabled)
+ channel_set_fds(s->chanid,
+ fdout, fdin, fderr,
+ fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
+ 1,
+ CHAN_SES_WINDOW_DEFAULT);
+ else
+ channel_set_fds(s->chanid,
+ fdout, fdin, fderr,
+ fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
+ 1,
+ options.hpn_buffer_size);
}
/*
return "SIG@openssh.com";
}
+static void
+session_close_x11(int id)
+{
+ Channel *c;
+
+ if ((c = channel_by_id(id)) == NULL) {
+ debug("session_close_x11: x11 channel %d missing", id);
+ } else {
+ /* Detach X11 listener */
+ debug("session_close_x11: detach x11 channel %d", id);
+ channel_cancel_cleanup(id);
+ if (c->ostate != CHAN_OUTPUT_CLOSED)
+ chan_mark_dead(c);
+ }
+}
+
+static void
+session_close_single_x11(int id, void *arg)
+{
+ Session *s;
+ u_int i;
+
+ debug3("session_close_single_x11: channel %d", id);
+ channel_cancel_cleanup(id);
+ if ((s = session_by_x11_channel(id)) == NULL)
+ fatal("session_close_single_x11: no x11 channel %d", 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]);
+ /*
+ * 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]);
+ }
+ xfree(s->x11_chanids);
+ s->x11_chanids = NULL;
+ if (s->display) {
+ xfree(s->display);
+ s->display = NULL;
+ }
+ if (s->auth_proto) {
+ xfree(s->auth_proto);
+ s->auth_proto = NULL;
+ }
+ if (s->auth_data) {
+ xfree(s->auth_data);
+ s->auth_data = NULL;
+ }
+ if (s->auth_display) {
+ xfree(s->auth_display);
+ s->auth_display = NULL;
+ }
+}
+
static void
session_exit_message(Session *s, int status)
{
/* disconnect channel */
debug("session_exit_message: release channel %d", s->chanid);
- channel_cancel_cleanup(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);
+
/*
* emulate a write failure with 'chan_write_failed', nobody will be
* interested in data we write.
*/
if (c->ostate != CHAN_OUTPUT_CLOSED)
chan_write_failed(c);
- s->chanid = -1;
}
void
session_close(Session *s)
{
- int i;
+ u_int i;
debug("session_close: session %d pid %ld", s->self, (long)s->pid);
if (s->ttyfd != -1)
xfree(s->term);
if (s->display)
xfree(s->display);
+ if (s->x11_chanids)
+ xfree(s->x11_chanids);
if (s->auth_display)
xfree(s->auth_display);
if (s->auth_data)
}
if (s->chanid != -1)
session_exit_message(s, status);
- session_close(s);
+ if (s->ttyfd != -1)
+ session_pty_cleanup(s);
+ s->pid = 0;
}
/*
session_close_by_channel(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);
return;
}
/* detach by removing callback */
channel_cancel_cleanup(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]);
+ s->x11_chanids[i] = -1;
+ }
+ }
+
s->chanid = -1;
session_close(s);
}
struct stat st;
char display[512], auth_display[512];
char hostname[MAXHOSTNAMELEN];
+ u_int i;
if (no_x11_forwarding_flag) {
packet_send_debug("X11 forwarding disabled in user configuration file.");
}
if (x11_create_display_inet(options.x11_display_offset,
options.x11_use_localhost, s->single_connection,
- &s->display_number) == -1) {
+ &s->display_number, &s->x11_chanids,
+ options.hpn_disabled, options.hpn_buffer_size) == -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],
+ session_close_single_x11, 0);
+ }
/* Set up a suitable value for the DISPLAY variable. */
if (gethostname(hostname, sizeof(hostname)) < 0)