]> andersk Git - openssh.git/blobdiff - sshd.c
20010115
[openssh.git] / sshd.c
diff --git a/sshd.c b/sshd.c
index 56a39bd01b4b62f5c996c6a54e0d21c4679859bb..298a1b6bdd58955415451935bfed80da954941a9 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.134 2000/11/12 19:50:38 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.147 2001/01/10 19:43:20 deraadt Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -78,6 +78,12 @@ int deny_severity = LOG_WARNING;
 #define O_NOCTTY       0
 #endif
 
+#ifdef HAVE___PROGNAME
+extern char *__progname;
+#else
+char *__progname;
+#endif
+
 /* Server configuration options. */
 ServerOptions options;
 
@@ -105,12 +111,12 @@ int debug_flag = 0;
 /* Flag indicating that the daemon is being started from inetd. */
 int inetd_flag = 0;
 
+/* Flag indicating that sshd should not detach and become a daemon. */
+int no_daemon_flag = 0;
+
 /* debug goes to stderr unless inetd_flag is set */
 int log_stderr = 0;
 
-/* argv[0] without path. */
-char *av0;
-
 /* Saved arguments to main(). */
 char **saved_argv;
 int saved_argc;
@@ -156,18 +162,18 @@ int key_used = 0;
 int received_sighup = 0;
 
 /* session identifier, used by RSA-auth */
-unsigned char session_id[16];
+u_char session_id[16];
 
 /* same for ssh2 */
-unsigned char *session_id2 = NULL;
+u_char *session_id2 = NULL;
 int session_id2_len = 0;
 
 /* record remote hostname or ip */
-unsigned int utmp_len = MAXHOSTNAMELEN;
+u_int utmp_len = MAXHOSTNAMELEN;
 
 /* Prototypes for various functions defined later in this file. */
-void do_ssh1_kex();
-void do_ssh2_kex();
+void do_ssh1_kex(void);
+void do_ssh2_kex(void);
 
 void ssh_dh1_server(Kex *, Buffer *_kexinit, Buffer *);
 void ssh_dhgex_server(Kex *, Buffer *_kexinit, Buffer *);
@@ -206,7 +212,7 @@ sighup_restart()
        log("Received SIGHUP; restarting.");
        close_listen_socks();
        execv(saved_argv[0], saved_argv);
-       log("RESTART FAILED: av0='%s', error: %s.", av0, strerror(errno));
+       log("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], strerror(errno));
        exit(1);
 }
 
@@ -260,8 +266,8 @@ grace_alarm_handler(int sig)
  * do anything with the private key or random state before forking.
  * Thus there should be no concurrency control/asynchronous execution
  * problems.
+ * XXX calling log() is not safe from races.
  */
-/* XXX do we really want this work to be done in a signal handler ? -m */
 void
 generate_empheral_server_key(void)
 {
@@ -273,6 +279,7 @@ generate_empheral_server_key(void)
        arc4random_stir();
        log("RSA key generation complete.");
 }
+
 void
 key_regeneration_alarm(int sig)
 {
@@ -562,21 +569,18 @@ main(int ac, char **av)
        int startup_p[2];
        int startups = 0;
 
+       __progname = get_progname(av[0]);
        init_rng();
 
-       /* Save argv[0]. */
+       /* Save argv. */
        saved_argc = ac;
        saved_argv = av;
-       if (strchr(av[0], '/'))
-               av0 = strrchr(av[0], '/') + 1;
-       else
-               av0 = av[0];
 
        /* Initialize configuration options to their default values. */
        initialize_server_options(&options);
 
        /* Parse command-line arguments. */
-       while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:diqQ46")) != EOF) {
+       while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDiqQ46")) != EOF) {
                switch (opt) {
                case '4':
                        IPv4or6 = AF_INET;
@@ -598,6 +602,9 @@ main(int ac, char **av)
                                exit(1);
                        }
                        break;
+               case 'D':
+                       no_daemon_flag = 1;
+                       break;
                case 'i':
                        inetd_flag = 1;
                        break;
@@ -642,15 +649,16 @@ main(int ac, char **av)
                case '?':
                default:
                        fprintf(stderr, "sshd version %s\n", SSH_VERSION);
-                       fprintf(stderr, "Usage: %s [options]\n", av0);
+                       fprintf(stderr, "Usage: %s [options]\n", __progname);
                        fprintf(stderr, "Options:\n");
                        fprintf(stderr, "  -f file    Configuration file (default %s)\n", SERVER_CONFIG_FILE);
                        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, "  -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");
-                       fprintf(stderr, "  -g seconds Grace period for authentication (default: 300)\n");
+                       fprintf(stderr, "  -g seconds Grace period for authentication (default: 600)\n");
                        fprintf(stderr, "  -b bits    Size of server RSA key (default: 768 bits)\n");
                        fprintf(stderr, "  -h file    File from which to read host key (default: %s)\n",
                            HOST_KEY_FILE);
@@ -665,8 +673,8 @@ main(int ac, char **av)
         * Force logging to stderr until we have loaded the private host
         * key (unless started from inetd)
         */
-       log_init(av0,
-           options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
+       log_init(__progname,
+           options.log_level == -1 ? SYSLOG_LEVEL_NOTICE : options.log_level,
            options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility,
            !silent && !inetd_flag);
 
@@ -686,6 +694,8 @@ main(int ac, char **av)
 
        /* load private host keys */
        sensitive_data.host_keys = xmalloc(options.num_host_key_files*sizeof(Key*));
+       for(i = 0; i < options.num_host_key_files; i++)
+               sensitive_data.host_keys[i] = NULL;
        sensitive_data.server_key = NULL;
        sensitive_data.ssh1_host_key = NULL;
        sensitive_data.have_ssh1_key = 0;
@@ -755,14 +765,14 @@ main(int ac, char **av)
        /* Initialize the log (it is reinitialized below in case we forked). */
        if (debug_flag && !inetd_flag)
                log_stderr = 1;
-       log_init(av0, options.log_level, options.log_facility, log_stderr);
+       log_init(__progname, options.log_level, options.log_facility, log_stderr);
 
        /*
         * If not in debugging mode, and not started from inetd, disconnect
         * from the controlling terminal, and fork.  The original process
         * exits.
         */
-       if (!debug_flag && !inetd_flag) {
+       if (!(debug_flag || inetd_flag || no_daemon_flag)) {
 #ifdef TIOCNOTTY
                int fd;
 #endif /* TIOCNOTTY */
@@ -779,7 +789,7 @@ main(int ac, char **av)
 #endif /* TIOCNOTTY */
        }
        /* Reinitialize the log (because of the fork above). */
-       log_init(av0, options.log_level, options.log_facility, log_stderr);
+       log_init(__progname, options.log_level, options.log_facility, log_stderr);
 
        /* Initialize the random number generator. */
        arc4random_stir();
@@ -868,15 +878,15 @@ main(int ac, char **av)
 
                if (!debug_flag) {
                        /*
-                        * Record our pid in /etc/sshd_pid to make it easier
-                        * to kill the correct sshd.  We don\'t want to do
-                        * this before the bind above because the bind will
+                        * Record our pid in /var/run/sshd.pid to make it
+                        * easier to kill the correct sshd.  We don't want to
+                        * do this before the bind above because the bind will
                         * fail if there already is a daemon, and this will
                         * overwrite any old pid in the file.
                         */
                        f = fopen(options.pid_file, "wb");
                        if (f) {
-                               fprintf(f, "%u\n", (unsigned int) getpid());
+                               fprintf(f, "%u\n", (u_int) getpid());
                                fclose(f);
                        }
                }
@@ -939,7 +949,7 @@ main(int ac, char **av)
                                        /*
                                         * the read end of the pipe is ready
                                         * if the child has closed the pipe
-                                        * after successfull authentication
+                                        * after successful authentication
                                         * or if the child has died
                                         */
                                        close(startup_pipes[i]);
@@ -1018,7 +1028,7 @@ main(int ac, char **av)
                                                close_listen_socks();
                                                sock_in = newsock;
                                                sock_out = newsock;
-                                               log_init(av0, options.log_level, options.log_facility, log_stderr);
+                                               log_init(__progname, options.log_level, options.log_facility, log_stderr);
                                                break;
                                        }
                                }
@@ -1085,7 +1095,7 @@ main(int ac, char **av)
        {
                struct request_info req;
 
-               request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL);
+               request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, NULL);
                fromhost(&req);
 
                if (!hosts_access(&req)) {
@@ -1113,18 +1123,17 @@ main(int ac, char **av)
 
        sshd_exchange_identification(sock_in, sock_out);
        /*
-        * Check that the connection comes from a privileged port.  Rhosts-
-        * and Rhosts-RSA-Authentication only make sense from priviledged
+        * Check that the connection comes from a privileged port.
+        * Rhosts-Authentication only makes sense from priviledged
         * 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 (remote_port >= IPPORT_RESERVED ||
            remote_port < IPPORT_RESERVED / 2) {
-               debug("Rhosts Authentication methods disabled, "
+               debug("Rhosts Authentication disabled, "
                    "originating port not trusted.");
                options.rhosts_authentication = 0;
-               options.rhosts_rsa_authentication = 0;
        }
 #ifdef KRB4
        if (!packet_connection_is_ipv4() &&
@@ -1167,14 +1176,14 @@ main(int ac, char **av)
  * SSH1 key exchange
  */
 void
-do_ssh1_kex()
+do_ssh1_kex(void)
 {
        int i, len;
        int plen, slen;
        BIGNUM *session_key_int;
-       unsigned char session_key[SSH_SESSION_KEY_LENGTH];
-       unsigned char cookie[8];
-       unsigned int cipher_type, auth_mask, protocol_flags;
+       u_char session_key[SSH_SESSION_KEY_LENGTH];
+       u_char cookie[8];
+       u_int cipher_type, auth_mask, protocol_flags;
        u_int32_t rand = 0;
 
        /*
@@ -1358,7 +1367,7 @@ do_ssh1_kex()
  * SSH2 key exchange: diffie-hellman-group1-sha1
  */
 void
-do_ssh2_kex()
+do_ssh2_kex(void)
 {
        Buffer *server_kexinit;
        Buffer *client_kexinit;
@@ -1431,12 +1440,12 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
 #endif
        int payload_len, dlen;
        int slen;
-       unsigned char *signature = NULL;
-       unsigned char *server_host_key_blob = NULL;
-       unsigned int sbloblen;
-       unsigned int klen, kout;
-       unsigned char *kbuf;
-       unsigned char *hash;
+       u_char *signature = NULL;
+       u_char *server_host_key_blob = NULL;
+       u_int sbloblen;
+       u_int klen, kout;
+       u_char *kbuf;
+       u_char *hash;
        BIGNUM *shared_secret = 0;
        DH *dh;
        BIGNUM *dh_client_pub = 0;
@@ -1447,6 +1456,10 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
                fatal("Unsupported hostkey type %d", kex->hostkey_type);
 
 /* KEXDH */
+       /* generate DH key */
+       dh = dh_new_group1();                   /* XXX depends on 'kex' */
+       dh_gen_key(dh);
+
        debug("Wait SSH2_MSG_KEXDH_INIT.");
        packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT);
 
@@ -1463,9 +1476,6 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
        debug("bits %d", BN_num_bits(dh_client_pub));
 #endif
 
-       /* generate DH key */
-       dh = dh_new_group1();                   /* XXX depends on 'kex' */
-
 #ifdef DEBUG_KEXDH
        fprintf(stderr, "\np= ");
        BN_print_fp(stderr, dh->p);
@@ -1559,12 +1569,12 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
 #endif
        int payload_len, dlen;
        int slen, nbits;
-       unsigned char *signature = NULL;
-       unsigned char *server_host_key_blob = NULL;
-       unsigned int sbloblen;
-       unsigned int klen, kout;
-       unsigned char *kbuf;
-       unsigned char *hash;
+       u_char *signature = NULL;
+       u_char *server_host_key_blob = NULL;
+       u_int sbloblen;
+       u_int klen, kout;
+       u_char *kbuf;
+       u_char *hash;
        BIGNUM *shared_secret = 0;
        DH *dh;
        BIGNUM *dh_client_pub = 0;
@@ -1587,6 +1597,10 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
        packet_send();
        packet_write_wait();
 
+       /* Compute our exchange value in parallel with the client */
+
+       dh_gen_key(dh);
+
        debug("Wait SSH2_MSG_KEX_DH_GEX_INIT.");
        packet_read_expect(&payload_len, SSH2_MSG_KEX_DH_GEX_INIT);
 
This page took 0.138443 seconds and 4 git commands to generate.