diff options
author | des <des@FreeBSD.org> | 2006-03-22 19:46:12 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2006-03-22 19:46:12 +0000 |
commit | 448503722a8c8934d8520302b7551e95de730b06 (patch) | |
tree | 42b3633dec62ddc0b702c6e83df5d64683b1c6c3 /crypto/openssh/serverloop.c | |
parent | 755a16fa864cacbbd9fbefc822011b6741351d8d (diff) | |
download | FreeBSD-src-448503722a8c8934d8520302b7551e95de730b06.zip FreeBSD-src-448503722a8c8934d8520302b7551e95de730b06.tar.gz |
Vendor import of OpenSSH 4.3p1.
Diffstat (limited to 'crypto/openssh/serverloop.c')
-rw-r--r-- | crypto/openssh/serverloop.c | 88 |
1 files changed, 85 insertions, 3 deletions
diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c index d2eff17..3d8e7cf 100644 --- a/crypto/openssh/serverloop.c +++ b/crypto/openssh/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.118 2005/07/17 07:17:55 djm Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.124 2005/12/13 15:03:02 reyk Exp $"); #include "xmalloc.h" #include "packet.h" @@ -61,6 +61,7 @@ extern ServerOptions options; /* XXX */ extern Kex *xxx_kex; extern Authctxt *the_authctxt; +extern int use_privsep; static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */ @@ -90,6 +91,9 @@ static int client_alive_timeouts = 0; static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */ +/* Cleanup on signals (!use_privsep case only) */ +static volatile sig_atomic_t received_sigterm = 0; + /* prototypes */ static void server_init_dispatch(void); @@ -151,6 +155,12 @@ sigchld_handler(int sig) errno = save_errno; } +static void +sigterm_handler(int sig) +{ + received_sigterm = sig; +} + /* * Make packets from buffered stderr data, and buffer it for sending * to the client. @@ -502,6 +512,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) child_terminated = 0; mysignal(SIGCHLD, sigchld_handler); + if (!use_privsep) { + signal(SIGTERM, sigterm_handler); + signal(SIGINT, sigterm_handler); + signal(SIGQUIT, sigterm_handler); + } + /* Initialize our global variables. */ fdin = fdin_arg; fdout = fdout_arg; @@ -548,7 +564,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) * If we have no separate fderr (which is the case when we have a pty * - there we cannot make difference between data sent to stdout and * stderr), indicate that we have seen an EOF from stderr. This way - * we don\'t need to check the descriptor everywhere. + * we don't need to check the descriptor everywhere. */ if (fderr == -1) fderr_eof = 1; @@ -629,6 +645,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, max_time_milliseconds); + if (received_sigterm) { + logit("Exiting on signal %d", received_sigterm); + /* Clean up sessions, utmp, etc. */ + cleanup_exit(255); + } + /* Process any channel events. */ channel_after_select(readset, writeset); @@ -749,6 +771,12 @@ server_loop2(Authctxt *authctxt) connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); + if (!use_privsep) { + signal(SIGTERM, sigterm_handler); + signal(SIGINT, sigterm_handler); + signal(SIGQUIT, sigterm_handler); + } + notify_setup(); max_fd = MAX(connection_in, connection_out); @@ -766,6 +794,12 @@ server_loop2(Authctxt *authctxt) wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, 0); + if (received_sigterm) { + logit("Exiting on signal %d", received_sigterm); + /* Clean up sessions, utmp, etc. */ + cleanup_exit(255); + } + collect_children(); if (!rekeying) { channel_after_select(readset, writeset); @@ -880,6 +914,52 @@ server_request_direct_tcpip(void) } static Channel * +server_request_tun(void) +{ + Channel *c = NULL; + int mode, tun; + int sock; + + mode = packet_get_int(); + switch (mode) { + case SSH_TUNMODE_POINTOPOINT: + case SSH_TUNMODE_ETHERNET: + break; + default: + packet_send_debug("Unsupported tunnel device mode."); + return NULL; + } + if ((options.permit_tun & mode) == 0) { + packet_send_debug("Server has rejected tunnel device " + "forwarding"); + return NULL; + } + + tun = packet_get_int(); + if (forced_tun_device != -1) { + if (tun != SSH_TUNID_ANY && forced_tun_device != tun) + goto done; + tun = forced_tun_device; + } + sock = tun_open(tun, mode); + if (sock < 0) + goto done; + c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + c->datagram = 1; +#if defined(SSH_TUN_FILTER) + if (mode == SSH_TUNMODE_POINTOPOINT) + channel_register_filter(c->self, sys_tun_infilter, + sys_tun_outfilter); +#endif + + done: + if (c == NULL) + packet_send_debug("Failed to open the tunnel device."); + return c; +} + +static Channel * server_request_session(void) { Channel *c; @@ -900,7 +980,7 @@ server_request_session(void) channel_free(c); return NULL; } - channel_register_cleanup(c->self, session_close_by_channel); + channel_register_cleanup(c->self, session_close_by_channel, 0); return c; } @@ -924,6 +1004,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt) c = server_request_session(); } else if (strcmp(ctype, "direct-tcpip") == 0) { c = server_request_direct_tcpip(); + } else if (strcmp(ctype, "tun@openssh.com") == 0) { + c = server_request_tun(); } if (c != NULL) { debug("server_input_channel_open: confirm %s", ctype); |