]> andersk Git - openssh.git/blobdiff - serverloop.c
- reyk@cvs.openbsd.org 2005/12/06 22:38:28
[openssh.git] / serverloop.c
index 208f7e1e9a48f42a6acef94a20d78d49c58ab4b1..199f7696d05be9a55dde2cfa41df95c6862836c6 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.120 2005/10/30 08:52:17 djm Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.122 2005/12/06 22:38:27 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;
@@ -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);
@@ -879,6 +913,36 @@ server_request_direct_tcpip(void)
        return c;
 }
 
+static Channel *
+server_request_tun(void)
+{
+       Channel *c = NULL;
+       int sock, tun;
+
+       if (!options.permit_tun) {
+               packet_send_debug("Server has disabled tunnel device forwarding.");
+               return NULL;
+       }
+
+       tun = packet_get_int();
+       if (forced_tun_device != -1) {
+               if (tun != -1 && forced_tun_device != tun)
+                       goto done;
+               tun = forced_tun_device;
+       }
+       sock = tun_open(tun);
+       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;
+
+ done:
+       if (c == NULL)
+               packet_send_debug("Failed to open the tunnel device.");
+       return c;
+}
+
 static Channel *
 server_request_session(void)
 {
@@ -924,6 +988,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);
This page took 0.039727 seconds and 4 git commands to generate.