]> andersk Git - openssh.git/blobdiff - sshd.c
[configure.ac] Make sure -lcrypto is before -lsocket for sco3. ok mouring@
[openssh.git] / sshd.c
diff --git a/sshd.c b/sshd.c
index 896e56c76a9132d37d8c408f2b2a29d423bf600c..42484c0648645d60577fb54d50871708c93b244f 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -42,7 +42,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.274 2003/07/22 13:35:22 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.285 2004/02/05 05:37:17 dtucker Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -101,6 +101,7 @@ extern char *__progname;
 #else
 char *__progname;
 #endif
+extern char **environ;
 
 /* Server configuration options. */
 ServerOptions options;
@@ -199,11 +200,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);
@@ -302,6 +306,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());
 }
@@ -375,7 +382,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. */
@@ -384,7 +391,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;
@@ -414,7 +421,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);
@@ -424,13 +431,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;
@@ -476,7 +483,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);
        }
 }
 
@@ -571,10 +578,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;
 
@@ -587,12 +593,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 */
@@ -602,11 +607,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 */
 
@@ -617,17 +618,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
@@ -653,8 +649,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);
@@ -679,7 +673,8 @@ static char *
 list_hostkey_types(void)
 {
        Buffer b;
-       char *p;
+       const char *p;
+       char *ret;
        int i;
 
        buffer_init(&b);
@@ -698,10 +693,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 *
@@ -769,7 +764,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);
@@ -809,17 +805,18 @@ 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
        (void)set_auth_parameters(ac, av);
 #endif
-       __progname = get_progname(av[0]);
+       __progname = ssh_get_progname(av[0]);
        init_rng();
 
        /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
@@ -917,9 +914,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:
@@ -1064,8 +1063,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)
@@ -1107,6 +1106,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);
 
@@ -1147,11 +1151,6 @@ main(int ac, char **av)
                                verbose("socket: %.100s", strerror(errno));
                                continue;
                        }
-                       if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) {
-                               error("listen_sock O_NONBLOCK: %s", strerror(errno));
-                               close(listen_sock);
-                               continue;
-                       }
                        /*
                         * Set socket options.
                         * Allow local port reuse in TIME_WAIT.
@@ -1175,7 +1174,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));
 
                }
@@ -1291,11 +1290,6 @@ main(int ac, char **av)
                                                error("accept: %.100s", strerror(errno));
                                        continue;
                                }
-                               if (fcntl(newsock, F_SETFL, 0) < 0) {
-                                       error("newsock del O_NONBLOCK: %s", strerror(errno));
-                                       close(newsock);
-                                       continue;
-                               }
                                if (drop_connection(startups) == 1) {
                                        debug("drop connection #%d", startups);
                                        close(newsock);
@@ -1368,7 +1362,7 @@ main(int ac, char **av)
                                if ((options.protocol & SSH_PROTO_1) &&
                                    key_used == 0) {
                                        /* Schedule server key regeneration alarm. */
-                                       mysignal(SIGALRM, key_regeneration_alarm);
+                                       signal(SIGALRM, key_regeneration_alarm);
                                        alarm(options.key_regeneration_time);
                                        key_used = 1;
                                }
@@ -1414,8 +1408,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));
@@ -1457,50 +1451,36 @@ main(int ac, char **av)
         * mode; it is just annoying to have the server exit just when you
         * are about to discover the bug.
         */
-       mysignal(SIGALRM, grace_alarm_handler);
+       signal(SIGALRM, grace_alarm_handler);
        if (!debug_flag)
                alarm(options.login_grace_time);
 
        sshd_exchange_identification(sock_in, sock_out);
-       /*
-        * Check that the connection comes from a privileged port.
-        * Rhosts-Authentication only makes sense from privileged
-        * programs.  Of course, if the intruder has root access on his local
-        * machine, he can connect from any port.  So do not use these
-        * authentication methods from machines that you do not trust.
-        */
-       if (options.rhosts_authentication &&
-           (remote_port >= IPPORT_RESERVED ||
-           remote_port < IPPORT_RESERVED / 2)) {
-               debug("Rhosts Authentication disabled, "
-                   "originating port %d not trusted.", remote_port);
-               options.rhosts_authentication = 0;
-       }
-#ifdef KRB5
-       if (!packet_connection_is_ipv4() &&
-           options.kerberos_authentication) {
-               debug("Kerberos Authentication disabled, only available for IPv4.");
-               options.kerberos_authentication = 0;
-       }
-#endif
 
        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 +1503,7 @@ main(int ac, char **av)
                        destroy_sensitive_data();
        }
 
-       /* Perform session preparation. */
+       /* Start session. */
        do_authenticated(authctxt);
 
        /* The connection has been terminated. */
@@ -1643,18 +1623,10 @@ do_ssh1_kex(void)
 
        /* Declare supported authentication types. */
        auth_mask = 0;
-       if (options.rhosts_authentication)
-               auth_mask |= 1 << SSH_AUTH_RHOSTS;
        if (options.rhosts_rsa_authentication)
                auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
        if (options.rsa_authentication)
                auth_mask |= 1 << SSH_AUTH_RSA;
-#ifdef KRB5
-       if (options.kerberos_authentication)
-               auth_mask |= 1 << SSH_AUTH_KERBEROS;
-       if (options.kerberos_tgt_passing)
-               auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
-#endif
        if (options.challenge_response_authentication == 1)
                auth_mask |= 1 << SSH_AUTH_TIS;
        if (options.password_authentication)
@@ -1824,3 +1796,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.053122 seconds and 4 git commands to generate.