]> andersk Git - openssh.git/blobdiff - sshd.c
- markus@cvs.openbsd.org 2001/08/30 22:22:32
[openssh.git] / sshd.c
diff --git a/sshd.c b/sshd.c
index 0bb4269d5a8a0cfacf2791109836ee3f762a727d..aa822df1786315a841e48a8a0f40d26cebbfe21c 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.188 2001/04/04 09:48:35 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.204 2001/08/23 17:59:31 camield Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -113,6 +113,9 @@ int IPv4or6 = AF_UNSPEC;
  */
 int debug_flag = 0;
 
+/* Flag indicating that the daemon should only test the configuration and keys. */
+int test_flag = 0;
+
 /* Flag indicating that the daemon is being started from inetd. */
 int inetd_flag = 0;
 
@@ -141,6 +144,9 @@ int num_listen_socks = 0;
 char *client_version_string = NULL;
 char *server_version_string = NULL;
 
+/* for rekeying XXX fixme */
+Kex *xxx_kex;
+
 /*
  * Any really sensitive data in the application is contained in this
  * structure. The idea is that this structure could be locked into memory so
@@ -164,8 +170,9 @@ struct {
  */
 int key_do_regen = 0;
 
-/* This is set to true when SIGHUP is received. */
+/* This is set to true when a signal is received. */
 int received_sighup = 0;
+int received_sigterm = 0;
 
 /* session identifier, used by RSA-auth */
 u_char session_id[16];
@@ -178,16 +185,15 @@ int session_id2_len = 0;
 u_int utmp_len = MAXHOSTNAMELEN;
 
 /* Prototypes for various functions defined later in this file. */
-void do_ssh1_kex(void);
-void do_ssh2_kex(void);
+void destroy_sensitive_data(void);
 
-void ssh_dh1_server(Kex *, Buffer *_kexinit, Buffer *);
-void ssh_dhgex_server(Kex *, Buffer *_kexinit, Buffer *);
+static void do_ssh1_kex(void);
+static void do_ssh2_kex(void);
 
 /*
  * Close all listening sockets
  */
-void
+static void
 close_listen_socks(void)
 {
        int i;
@@ -201,7 +207,7 @@ close_listen_socks(void)
  * the effect is to reread the configuration file (and to regenerate
  * the server key).
  */
-void
+static void
 sighup_handler(int sig)
 {
        received_sighup = 1;
@@ -212,7 +218,7 @@ sighup_handler(int sig)
  * Called from the main program after receiving SIGHUP.
  * Restarts the server.
  */
-void
+static void
 sighup_restart(void)
 {
        log("Received SIGHUP; restarting.");
@@ -224,23 +230,18 @@ sighup_restart(void)
 
 /*
  * Generic signal handler for terminating signals in the master daemon.
- * These close the listen socket; not closing it seems to cause "Address
- * already in use" problems on some machines, which is inconvenient.
  */
-void
+static void
 sigterm_handler(int sig)
 {
-       log("Received signal %d; terminating.", sig);
-       close_listen_socks();
-       unlink(options.pid_file);
-       exit(255);
+       received_sigterm = sig;
 }
 
 /*
  * SIGCHLD handler.  This is called whenever a child dies.  This will then
- * reap any zombies left by exited c.
+ * reap any zombies left by exited children.
  */
-void
+static void
 main_sigchld_handler(int sig)
 {
        int save_errno = errno;
@@ -256,9 +257,11 @@ main_sigchld_handler(int sig)
 /*
  * Signal handler for the alarm after the login grace period has expired.
  */
-void
+static void
 grace_alarm_handler(int sig)
 {
+       /* XXX no idea how fix this signal handler */
+
        /* Close the connection. */
        packet_close();
 
@@ -273,17 +276,17 @@ grace_alarm_handler(int sig)
  * Thus there should be no concurrency control/asynchronous execution
  * problems.
  */
-void
+static void
 generate_ephemeral_server_key(void)
 {
        u_int32_t rand = 0;
        int i;
 
-       verbose("Generating %s%d bit RSA key.", 
+       verbose("Generating %s%d bit RSA key.",
            sensitive_data.server_key ? "new " : "", options.server_key_bits);
        if (sensitive_data.server_key != NULL)
                key_free(sensitive_data.server_key);
-       sensitive_data.server_key = key_generate(KEY_RSA1, 
+       sensitive_data.server_key = key_generate(KEY_RSA1,
            options.server_key_bits);
        verbose("RSA key generation complete.");
 
@@ -296,7 +299,7 @@ generate_ephemeral_server_key(void)
        arc4random_stir();
 }
 
-void
+static void
 key_regeneration_alarm(int sig)
 {
        int save_errno = errno;
@@ -305,7 +308,7 @@ key_regeneration_alarm(int sig)
        key_do_regen = 1;
 }
 
-void
+static void
 sshd_exchange_identification(int sock_in, int sock_out)
 {
        int i, mismatch;
@@ -338,7 +341,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
                }
 
                /* Read other side's version identification. */
-               memset(buf, 0, sizeof(buf)); 
+               memset(buf, 0, sizeof(buf));
                for (i = 0; i < sizeof(buf) - 1; i++) {
                        if (atomicio(read, sock_in, &buf[i], 1) != 1) {
                                log("Did not receive identification string from %s.",
@@ -432,8 +435,6 @@ sshd_exchange_identification(int sock_in, int sock_out)
                    server_version_string, client_version_string);
                fatal_cleanup();
        }
-       if (compat20)
-               packet_set_ssh2_format();
 }
 
 
@@ -457,7 +458,7 @@ destroy_sensitive_data(void)
        memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH);
 }
 
-char *
+static char *
 list_hostkey_types(void)
 {
        static char buf[1024];
@@ -482,7 +483,7 @@ list_hostkey_types(void)
        return buf;
 }
 
-Key *
+static Key *
 get_hostkey_by_type(int type)
 {
        int i;
@@ -500,7 +501,7 @@ get_hostkey_by_type(int type)
  * of (max_startups_rate/100). the probability increases linearly until
  * all connections are dropped for startups > max_startups
  */
-int
+static int
 drop_connection(int startups)
 {
        double p, r;
@@ -562,7 +563,7 @@ main(int ac, char **av)
        initialize_server_options(&options);
 
        /* Parse command-line arguments. */
-       while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDiqQ46")) != -1) {
+       while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDeiqtQ46")) != -1) {
                switch (opt) {
                case '4':
                        IPv4or6 = AF_INET;
@@ -587,6 +588,9 @@ main(int ac, char **av)
                case 'D':
                        no_daemon_flag = 1;
                        break;
+               case 'e':
+                       log_stderr = 1;
+                       break;
                case 'i':
                        inetd_flag = 1;
                        break;
@@ -605,13 +609,23 @@ main(int ac, char **av)
                                fprintf(stderr, "too many ports.\n");
                                exit(1);
                        }
-                       options.ports[options.num_ports++] = atoi(optarg);
+                       options.ports[options.num_ports++] = a2port(optarg);
+                       if (options.ports[options.num_ports-1] == 0) {
+                               fprintf(stderr, "Bad port number.\n");
+                               exit(1);
+                       }
                        break;
                case 'g':
-                       options.login_grace_time = atoi(optarg);
+                       if ((options.login_grace_time = convtime(optarg)) == -1) {
+                               fprintf(stderr, "Invalid login grace time.\n");
+                               exit(1);
+                       }
                        break;
                case 'k':
-                       options.key_regeneration_time = atoi(optarg);
+                       if ((options.key_regeneration_time = convtime(optarg)) == -1) {
+                               fprintf(stderr, "Invalid key regeneration interval.\n");
+                               exit(1);
+                       }
                        break;
                case 'h':
                        if (options.num_host_key_files >= MAX_HOSTKEYS) {
@@ -625,6 +639,9 @@ main(int ac, char **av)
                        /* only makes sense with inetd_flag, i.e. no listen() */
                        inetd_flag = 1;
                        break;
+               case 't':
+                       test_flag = 1;
+                       break;
                case 'u':
                        utmp_len = atoi(optarg);
                        break;
@@ -637,6 +654,7 @@ main(int ac, char **av)
                        fprintf(stderr, "  -d         Debugging mode (multiple -d means more debugging)\n");
                        fprintf(stderr, "  -i         Started from inetd\n");
                        fprintf(stderr, "  -D         Do not fork into daemon mode\n");
+                       fprintf(stderr, "  -t         Only test configuration file and keys\n");
                        fprintf(stderr, "  -q         Quiet (no logging)\n");
                        fprintf(stderr, "  -p port    Listen on the specified port (default: 22)\n");
                        fprintf(stderr, "  -k seconds Regenerate server key every this many seconds (default: 3600)\n");
@@ -661,6 +679,13 @@ main(int ac, char **av)
            options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility,
            !inetd_flag);
 
+#ifdef _CRAY
+       /* Cray can define user privs drop all prives now!
+        * Not needed on PRIV_SU systems!
+        */
+       drop_cray_privs();
+#endif
+
        seed_rng();
 
        /* Read server configuration options from the configuration file. */
@@ -690,8 +715,8 @@ main(int ac, char **av)
                key = key_load_private(options.host_key_files[i], "", NULL);
                sensitive_data.host_keys[i] = key;
                if (key == NULL) {
-                       error("Could not load host key: %.200s: %.100s",
-                           options.host_key_files[i], strerror(errno));
+                       error("Could not load host key: %s",
+                           options.host_key_files[i]);
                        sensitive_data.host_keys[i] = NULL;
                        continue;
                }
@@ -744,6 +769,10 @@ main(int ac, char **av)
                }
        }
 
+       /* Configuration looks good, so exit if in test mode. */
+       if (test_flag)
+               exit(0);
+
 #ifdef HAVE_SCO_PROTECTED_PW
        (void) set_auth_parameters(ac, av);
 #endif
@@ -789,9 +818,9 @@ main(int ac, char **av)
 
        /* Start listening for a socket, unless started from inetd. */
        if (inetd_flag) {
-               int s1, s2;
+               int s1;
                s1 = dup(0);    /* Make sure descriptors 0, 1, and 2 are in use. */
-               s2 = dup(s1);
+               dup(s1);
                sock_in = dup(0);
                sock_out = dup(1);
                startup_pipe = -1;
@@ -865,6 +894,22 @@ main(int ac, char **av)
                if (!num_listen_socks)
                        fatal("Cannot bind any address.");
 
+               if (options.protocol & SSH_PROTO_1)
+                       generate_ephemeral_server_key();
+
+               /*
+                * Arrange to restart on SIGHUP.  The handler needs
+                * listen_sock.
+                */
+               signal(SIGHUP, sighup_handler);
+
+               signal(SIGTERM, sigterm_handler);
+               signal(SIGQUIT, sigterm_handler);
+
+               /* Arrange SIGCHLD to be caught. */
+               signal(SIGCHLD, main_sigchld_handler);
+
+               /* Write out the pid file after the sigterm handler is setup */
                if (!debug_flag) {
                        /*
                         * Record our pid in /var/run/sshd.pid to make it
@@ -879,17 +924,6 @@ main(int ac, char **av)
                                fclose(f);
                        }
                }
-               if (options.protocol & SSH_PROTO_1)
-                       generate_ephemeral_server_key();
-
-               /* Arrange to restart on SIGHUP.  The handler needs listen_sock. */
-               signal(SIGHUP, sighup_handler);
-
-               signal(SIGTERM, sigterm_handler);
-               signal(SIGQUIT, sigterm_handler);
-
-               /* Arrange SIGCHLD to be caught. */
-               signal(SIGCHLD, main_sigchld_handler);
 
                /* setup fd set for listen */
                fdset = NULL;
@@ -925,6 +959,13 @@ main(int ac, char **av)
                        ret = select(maxfd+1, fdset, NULL, NULL, NULL);
                        if (ret < 0 && errno != EINTR)
                                error("select: %.100s", strerror(errno));
+                       if (received_sigterm) {
+                               log("Received signal %d; terminating.",
+                                   received_sigterm);
+                               close_listen_socks();
+                               unlink(options.pid_file);
+                               exit(255);
+                       }
                        if (key_used && key_do_regen) {
                                generate_ephemeral_server_key();
                                key_used = 0;
@@ -1097,7 +1138,7 @@ main(int ac, char **av)
        {
                struct request_info req;
 
-               request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, NULL);
+               request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0);
                fromhost(&req);
 
                if (!hosts_access(&req)) {
@@ -1137,13 +1178,13 @@ main(int ac, char **av)
                    "originating port not trusted.");
                options.rhosts_authentication = 0;
        }
-#ifdef KRB4
+#if defined(KRB4) && !defined(KRB5)
        if (!packet_connection_is_ipv4() &&
            options.kerberos_authentication) {
                debug("Kerberos Authentication disabled, only available for IPv4.");
                options.kerberos_authentication = 0;
        }
-#endif /* KRB4 */
+#endif /* KRB4 && !KRB5 */
 #ifdef AFS
        /* If machine has AFS, set process authentication group. */
        if (k_hasafs()) {
@@ -1163,13 +1204,6 @@ main(int ac, char **av)
                do_ssh1_kex();
                do_authentication();
        }
-
-#ifdef KRB4
-       /* Cleanup user's ticket cache file. */
-       if (options.kerberos_ticket_cleanup)
-               (void) dest_tkt();
-#endif /* KRB4 */
-
        /* The connection has been terminated. */
        verbose("Closing connection to %.100s", remote_ip);
 
@@ -1184,7 +1218,7 @@ main(int ac, char **av)
 /*
  * SSH1 key exchange
  */
-void
+static void
 do_ssh1_kex(void)
 {
        int i, len;
@@ -1245,17 +1279,19 @@ do_ssh1_kex(void)
                auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
        if (options.rsa_authentication)
                auth_mask |= 1 << SSH_AUTH_RSA;
-#ifdef KRB4
+#if defined(KRB4) || defined(KRB5)
        if (options.kerberos_authentication)
                auth_mask |= 1 << SSH_AUTH_KERBEROS;
 #endif
-#ifdef AFS
+#if defined(AFS) || defined(KRB5)
        if (options.kerberos_tgt_passing)
                auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
+#endif
+#ifdef AFS
        if (options.afs_token_passing)
                auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
 #endif
-       if (options.challenge_reponse_authentication == 1)
+       if (options.challenge_response_authentication == 1)
                auth_mask |= 1 << SSH_AUTH_TIS;
        if (options.password_authentication)
                auth_mask |= 1 << SSH_AUTH_PASSWORD;
@@ -1405,7 +1441,7 @@ do_ssh1_kex(void)
 /*
  * SSH2 key exchange: diffie-hellman-group1-sha1
  */
-void
+static void
 do_ssh2_kex(void)
 {
        Kex *kex;
@@ -1425,14 +1461,16 @@ do_ssh2_kex(void)
        }
        myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
 
+       /* start key exchange */
        kex = kex_setup(myproposal);
        kex->server = 1;
        kex->client_version_string=client_version_string;
        kex->server_version_string=server_version_string;
        kex->load_host_key=&get_hostkey_by_type;
 
-       /* start key exchange */
-       dispatch_run(DISPATCH_BLOCK, &kex->newkeys, kex);
+       xxx_kex = kex;
+
+       dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
 
        session_id2 = kex->session_id;
        session_id2_len = kex->session_id_len;
This page took 0.05514 seconds and 4 git commands to generate.