]> andersk Git - gssapi-openssh.git/blobdiff - openssh/sshd.c
merged OPENSSH_3_8P1_GSSAPI_20040304 to gpt-branch
[gssapi-openssh.git] / openssh / sshd.c
index 59eacafb33e0e80d984e815c498a6e88b9ef3d60..474f77792982860611a68847062620e0959d239a 100644 (file)
@@ -42,7 +42,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.276 2003/08/28 12:54:34 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.286 2004/02/23 12:02:33 markus Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -110,6 +110,7 @@ extern char *__progname;
 #else
 char *__progname;
 #endif
+extern char **environ;
 
 /* Server configuration options. */
 ServerOptions options;
@@ -208,11 +209,14 @@ int startup_pipe;         /* in child */
 
 /* variables used for privilege separation */
 int use_privsep;
-struct monitor *pmonitor;
+struct monitor *pmonitor = NULL;
 
 /* message to be displayed after login */
 Buffer loginmsg;
 
+/* global authentication context */
+Authctxt *the_authctxt = NULL;
+
 /* Prototypes for various functions defined later in this file. */
 void destroy_sensitive_data(void);
 void demote_sensitive_data(void);
@@ -311,6 +315,9 @@ grace_alarm_handler(int sig)
 {
        /* XXX no idea how fix this signal handler */
 
+       if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
+               kill(pmonitor->m_pid, SIGALRM);
+
        /* Log error and exit. */
        fatal("Timeout before authentication for %s", get_remote_ipaddr());
 }
@@ -384,7 +391,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
            strlen(server_version_string))
            != strlen(server_version_string)) {
                logit("Could not write ident string to %s", get_remote_ipaddr());
-               fatal_cleanup();
+               cleanup_exit(255);
        }
 
        /* Read other sides version identification. */
@@ -393,7 +400,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
                if (atomicio(read, sock_in, &buf[i], 1) != 1) {
                        logit("Did not receive identification string from %s",
                            get_remote_ipaddr());
-                       fatal_cleanup();
+                       cleanup_exit(255);
                }
                if (buf[i] == '\r') {
                        buf[i] = 0;
@@ -423,7 +430,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
                close(sock_out);
                logit("Bad protocol version identification '%.100s' from %s",
                    client_version_string, get_remote_ipaddr());
-               fatal_cleanup();
+               cleanup_exit(255);
        }
        debug("Client protocol version %d.%d; client software version %.100s",
            remote_major, remote_minor, remote_version);
@@ -433,13 +440,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
        if (datafellows & SSH_BUG_PROBE) {
                logit("probed from %s with %s.  Don't panic.",
                    get_remote_ipaddr(), client_version_string);
-               fatal_cleanup();
+               cleanup_exit(255);
        }
 
        if (datafellows & SSH_BUG_SCANNER) {
                logit("scanned from %s with %s.  Don't panic.",
                    get_remote_ipaddr(), client_version_string);
-               fatal_cleanup();
+               cleanup_exit(255);
        }
 
        mismatch = 0;
@@ -485,7 +492,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
                logit("Protocol major versions differ for %s: %.200s vs. %.200s",
                    get_remote_ipaddr(),
                    server_version_string, client_version_string);
-               fatal_cleanup();
+               cleanup_exit(255);
        }
 }
 
@@ -580,10 +587,9 @@ privsep_preauth_child(void)
 #endif
 }
 
-static Authctxt *
-privsep_preauth(void)
+static int
+privsep_preauth(Authctxt *authctxt)
 {
-       Authctxt *authctxt = NULL;
        int status;
        pid_t pid;
 
@@ -596,12 +602,11 @@ privsep_preauth(void)
        if (pid == -1) {
                fatal("fork of unprivileged child failed");
        } else if (pid != 0) {
-               fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
-
                debug2("Network child is on pid %ld", (long)pid);
 
                close(pmonitor->m_recvfd);
-               authctxt = monitor_child_preauth(pmonitor);
+               pmonitor->m_pid = pid;
+               monitor_child_preauth(authctxt, pmonitor);
                close(pmonitor->m_sendfd);
 
                /* Sync memory */
@@ -611,11 +616,7 @@ privsep_preauth(void)
                while (waitpid(pid, &status, 0) < 0)
                        if (errno != EINTR)
                                break;
-
-               /* Reinstall, since the child has finished */
-               fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
-
-               return (authctxt);
+               return (1);
        } else {
                /* child */
 
@@ -626,17 +627,12 @@ privsep_preauth(void)
                        privsep_preauth_child();
                setproctitle("%s", "[net]");
        }
-       return (NULL);
+       return (0);
 }
 
 static void
 privsep_postauth(Authctxt *authctxt)
 {
-       extern Authctxt *x_authctxt;
-
-       /* XXX - Remote port forwarding */
-       x_authctxt = authctxt;
-
 #ifdef DISABLE_FD_PASSING
        if (1) {
 #else
@@ -662,8 +658,6 @@ privsep_postauth(Authctxt *authctxt)
        if (pmonitor->m_pid == -1)
                fatal("fork of unprivileged child failed");
        else if (pmonitor->m_pid != 0) {
-               fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
-
                debug2("User child is on pid %ld", (long)pmonitor->m_pid);
                close(pmonitor->m_recvfd);
                monitor_child_postauth(pmonitor);
@@ -688,7 +682,8 @@ static char *
 list_hostkey_types(void)
 {
        Buffer b;
-       char *p;
+       const char *p;
+       char *ret;
        int i;
 
        buffer_init(&b);
@@ -707,10 +702,10 @@ list_hostkey_types(void)
                }
        }
        buffer_append(&b, "\0", 1);
-       p = xstrdup(buffer_ptr(&b));
+       ret = xstrdup(buffer_ptr(&b));
        buffer_free(&b);
-       debug("list_hostkey_types: %s", p);
-       return p;
+       debug("list_hostkey_types: %s", ret);
+       return ret;
 }
 
 Key *
@@ -778,7 +773,8 @@ drop_connection(int startups)
 static void
 usage(void)
 {
-       fprintf(stderr, "sshd version %s\n", SSH_VERSION);
+       fprintf(stderr, "sshd version %s, %s\n",
+           SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
        fprintf(stderr, "Usage: %s [options]\n", __progname);
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "  -f file    Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE);
@@ -818,11 +814,12 @@ main(int ac, char **av)
        FILE *f;
        struct addrinfo *ai;
        char ntop[NI_MAXHOST], strport[NI_MAXSERV];
+       char *line;
        int listen_sock, maxfd;
        int startup_p[2];
        int startups = 0;
-       Authctxt *authctxt;
        Key *key;
+       Authctxt *authctxt;
        int ret, key_used = 0;
 
 #ifdef HAVE_SECUREWARE
@@ -928,9 +925,11 @@ main(int ac, char **av)
                        }
                        break;
                case 'o':
-                       if (process_server_config_line(&options, optarg,
+                       line = xstrdup(optarg);
+                       if (process_server_config_line(&options, line,
                            "command-line", 0) != 0)
                                exit(1);
+                       xfree(line);
                        break;
                case '?':
                default:
@@ -1078,8 +1077,8 @@ main(int ac, char **av)
        /*
         * Clear out any supplemental groups we may have inherited.  This
         * prevents inadvertent creation of files with bad modes (in the
-        * portable version at least, it's certainly possible for PAM 
-        * to create a file, and we can't control the code in every 
+        * portable version at least, it's certainly possible for PAM
+        * to create a file, and we can't control the code in every
         * module which might be used).
         */
        if (setgroups(0, NULL) < 0)
@@ -1121,6 +1120,11 @@ main(int ac, char **av)
           unmounted if desired. */
        chdir("/");
 
+#ifndef HAVE_CYGWIN
+       /* Clear environment */
+       environ[0] = NULL;
+#endif
+
        /* ignore SIGPIPE */
        signal(SIGPIPE, SIG_IGN);
 
@@ -1189,7 +1193,7 @@ main(int ac, char **av)
 
                        /* Start listening on the port. */
                        logit("Server listening on %s port %s.", ntop, strport);
-                       if (listen(listen_sock, 5) < 0)
+                       if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
                                fatal("listen: %.100s", strerror(errno));
 
                }
@@ -1428,8 +1432,8 @@ main(int ac, char **av)
        signal(SIGCHLD, SIG_DFL);
        signal(SIGINT, SIG_DFL);
 
-       /* Set keepalives if requested. */
-       if (options.keepalives &&
+       /* Set SO_KEEPALIVE if requested. */
+       if (options.tcp_keep_alive &&
            setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on,
            sizeof(on)) < 0)
                error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
@@ -1486,21 +1490,28 @@ main(int ac, char **av)
 
        packet_set_nonblocking();
 
-        /* prepare buffers to collect authentication messages */
+       /* prepare buffers to collect authentication messages */
        buffer_init(&loginmsg);
 
+       /* allocate authentication context */
+       authctxt = xmalloc(sizeof(*authctxt));
+       memset(authctxt, 0, sizeof(*authctxt));
+
+       /* XXX global for cleanup, access from other modules */
+       the_authctxt = authctxt;
+
        if (use_privsep)
-               if ((authctxt = privsep_preauth()) != NULL)
+               if (privsep_preauth(authctxt) == 1)
                        goto authenticated;
 
        /* perform the key exchange */
        /* authenticate user and start session */
        if (compat20) {
                do_ssh2_kex();
-               authctxt = do_authentication2();
+               do_authentication2(authctxt);
        } else {
                do_ssh1_kex();
-               authctxt = do_authentication();
+               do_authentication(authctxt);
        }
        /*
         * If we use privilege separation, the unprivileged child transfers
@@ -1523,7 +1534,7 @@ main(int ac, char **av)
                        destroy_sensitive_data();
        }
 
-       /* Perform session preparation. */
+       /* Start session. */
        do_authenticated(authctxt);
 
        /* The connection has been terminated. */
@@ -1858,3 +1869,12 @@ do_ssh2_kex(void)
 #endif
        debug("KEX done");
 }
+
+/* server specific fatal cleanup */
+void
+cleanup_exit(int i)
+{
+       if (the_authctxt)
+               do_cleanup(the_authctxt);
+       _exit(i);
+}
This page took 0.196146 seconds and 4 git commands to generate.