]> andersk Git - openssh.git/blobdiff - sshd.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / sshd.c
diff --git a/sshd.c b/sshd.c
index f9b87ea1ce50a77327a8ccfc356160b31be5be1c..bf2e76cc8ef45a368a5ede22c9d1ddde8e5562f5 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.360 2008/06/12 20:38:28 dtucker Exp $ */
+/* $OpenBSD: sshd.c,v 1.372 2010/01/29 00:20:41 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 #include "ssh-gss.h"
 #endif
 #include "monitor_wrap.h"
-#include "monitor_fdpass.h"
+#include "roaming.h"
 #include "version.h"
 
 #ifdef LIBWRAP
@@ -309,6 +309,7 @@ sighup_restart(void)
        close_listen_socks();
        close_startup_pipes();
        alarm(0);  /* alarm timer persists across exec */
+       signal(SIGHUP, SIG_IGN); /* will be restored after exec */
        execv(saved_argv[0], saved_argv);
        logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
            strerror(errno));
@@ -399,7 +400,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
        int mismatch;
        int remote_major, remote_minor;
        int major, minor;
-       char *s;
+       char *s, *newline = "\n";
        char buf[256];                  /* Must not be larger than remote_version. */
        char remote_version[256];       /* Must be at least as big as buf. */
 
@@ -410,15 +411,17 @@ sshd_exchange_identification(int sock_in, int sock_out)
        } else if (options.protocol & SSH_PROTO_2) {
                major = PROTOCOL_MAJOR_2;
                minor = PROTOCOL_MINOR_2;
+               newline = "\r\n";
        } else {
                major = PROTOCOL_MAJOR_1;
                minor = PROTOCOL_MINOR_1;
        }
-       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
+       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
+           SSH_VERSION, newline);
        server_version_string = xstrdup(buf);
 
        /* Send our protocol version identification. */
-       if (atomicio(vwrite, sock_out, server_version_string,
+       if (roaming_atomicio(vwrite, sock_out, server_version_string,
            strlen(server_version_string))
            != strlen(server_version_string)) {
                logit("Could not write ident string to %s", get_remote_ipaddr());
@@ -428,7 +431,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
        /* Read other sides version identification. */
        memset(buf, 0, sizeof(buf));
        for (i = 0; i < sizeof(buf) - 1; i++) {
-               if (atomicio(read, sock_in, &buf[i], 1) != 1) {
+               if (roaming_atomicio(read, sock_in, &buf[i], 1) != 1) {
                        logit("Did not receive identification string from %s",
                            get_remote_ipaddr());
                        cleanup_exit(255);
@@ -576,7 +579,7 @@ demote_sensitive_data(void)
 static void
 privsep_preauth_child(void)
 {
-       u_int32_t rnd[256];
+       u_int32_t rnd[256];
        gid_t gidset[1];
 
        /* Enable challenge-response authentication for privilege separation */
@@ -675,7 +678,7 @@ privsep_postauth(Authctxt *authctxt)
        if (pmonitor->m_pid == -1)
                fatal("fork of unprivileged child failed");
        else if (pmonitor->m_pid != 0) {
-               debug2("User child is on pid %ld", (long)pmonitor->m_pid);
+               verbose("User child is on pid %ld", (long)pmonitor->m_pid);
                close(pmonitor->m_recvfd);
                buffer_clear(&loginmsg);
                monitor_child_postauth(pmonitor);
@@ -977,15 +980,9 @@ server_listen(void)
                    &on, sizeof(on)) == -1)
                        error("setsockopt SO_REUSEADDR: %s", strerror(errno));
 
-#ifdef IPV6_V6ONLY
                /* Only communicate in IPv6 over AF_INET6 sockets. */
-               if (ai->ai_family == AF_INET6) {
-                       if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
-                           &on, sizeof(on)) == -1)
-                               error("setsockopt IPV6_V6ONLY: %s",
-                                   strerror(errno));
-               }
-#endif
+               if (ai->ai_family == AF_INET6)
+                       sock_set_v6only(listen_sock);
 
                debug("Bind to port %s on %s.", strport, ntop);
 
@@ -1094,7 +1091,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
                        *newsock = accept(listen_socks[i],
                            (struct sockaddr *)&from, &fromlen);
                        if (*newsock < 0) {
-                               if (errno != EINTR && errno != EWOULDBLOCK)
+                               if (errno != EINTR && errno != EAGAIN &&
+                                   errno != EWOULDBLOCK)
                                        error("accept: %.100s", strerror(errno));
                                continue;
                        }
@@ -1245,6 +1243,8 @@ main(int ac, char **av)
        int remote_port;
        char *line, *p, *cp;
        int config_s[2] = { -1 , -1 };
+       u_int64_t ibytes, obytes;
+       mode_t new_umask;
        Key *key;
        Authctxt *authctxt;
 
@@ -1329,7 +1329,7 @@ main(int ac, char **av)
                                exit(1);
                        }
                        options.ports[options.num_ports++] = a2port(optarg);
-                       if (options.ports[options.num_ports-1] == 0) {
+                       if (options.ports[options.num_ports-1] <= 0) {
                                fprintf(stderr, "Bad port number.\n");
                                exit(1);
                        }
@@ -1351,7 +1351,8 @@ main(int ac, char **av)
                                fprintf(stderr, "too many host keys.\n");
                                exit(1);
                        }
-                       options.host_key_files[options.num_host_key_files++] = optarg;
+                       options.host_key_files[options.num_host_key_files++] = 
+                          derelativise_path(optarg);
                        break;
                case 't':
                        test_flag = 1;
@@ -1441,7 +1442,8 @@ main(int ac, char **av)
         * the parameters we need.  If we're not doing an extended test,
         * do not silently ignore connection test params.
         */
-       if (test_flag >= 2 && (test_user != NULL || test_host != NULL || test_addr != NULL)
+       if (test_flag >= 2 &&
+          (test_user != NULL || test_host != NULL || test_addr != NULL)
            && (test_user == NULL || test_host == NULL || test_addr == NULL))
                fatal("user, host and addr are all required when testing "
                   "Match configs");
@@ -1609,6 +1611,10 @@ main(int ac, char **av)
                rexec_argv[rexec_argc + 1] = NULL;
        }
 
+       /* Ensure that umask disallows at least group and world write */
+       new_umask = umask(0077) | 0022;
+       (void) umask(new_umask);
+
        /* Initialize the log (it is reinitialized below in case we forked). */
        if (debug_flag && (!inetd_flag || rexeced_flag))
                log_stderr = 1;
@@ -1652,6 +1658,7 @@ main(int ac, char **av)
        if (inetd_flag) {
                server_accept_inetd(&sock_in, &sock_out);
        } else {
+               platform_pre_listen();
                server_listen();
 
                if (options.protocol & SSH_PROTO_1)
@@ -1741,6 +1748,10 @@ main(int ac, char **av)
                    sock_in, sock_out, newsock, startup_pipe, config_s[0]);
        }
 
+       /* Executed child processes don't need these. */
+       fcntl(sock_out, F_SETFD, FD_CLOEXEC);
+       fcntl(sock_in, F_SETFD, FD_CLOEXEC);
+
        /*
         * Disable the key regeneration alarm.  We will not regenerate the
         * key since we are no longer in a position to give it to anyone. We
@@ -1910,7 +1921,11 @@ main(int ac, char **av)
        do_authenticated(authctxt);
 
        /* The connection has been terminated. */
-       verbose("Closing connection to %.100s", remote_ip);
+       packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
+       packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
+       verbose("Transferred: sent %llu, received %llu bytes", obytes, ibytes);
+
+       verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
 
 #ifdef USE_PAM
        if (options.use_pam)
This page took 0.292455 seconds and 4 git commands to generate.