]> andersk Git - gssapi-openssh.git/blobdiff - openssh/ssh.c
merged OpenSSH 5.3p1 to trunk
[gssapi-openssh.git] / openssh / ssh.c
index 9d43bb74fc3295d4988cdbb6924b172a69cd34ab..21f4c84e9bfb0a4cbd4267a3aacfdd4d489765fa 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.324 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.326 2009/07/02 02:11:47 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -48,6 +48,7 @@
 #endif
 #include <sys/resource.h>
 #include <sys/ioctl.h>
+#include <sys/param.h>
 #include <sys/socket.h>
 
 #include <ctype.h>
@@ -203,8 +204,8 @@ void muxserver_listen(void);
 int
 main(int ac, char **av)
 {
-       int i, opt, exit_status, use_syslog;
-       char *p, *cp, *line, buf[256];
+       int i, r, opt, exit_status, use_syslog;
+       char *p, *cp, *line, *argv0, buf[MAXPATHLEN];
        struct stat st;
        struct passwd *pw;
        int dummy, timeout_ms;
@@ -270,6 +271,7 @@ main(int ac, char **av)
        /* Parse command-line arguments. */
        host = NULL;
        use_syslog = 0;
+       argv0 = av[0];
 
  again:
        while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
@@ -492,9 +494,6 @@ main(int ac, char **av)
                        no_shell_flag = 1;
                        no_tty_flag = 1;
                        break;
-               case 'T':
-                       no_tty_flag = 1;
-                       break;
                case 'o':
                        dummy = 1;
                        line = xstrdup(optarg);
@@ -503,6 +502,13 @@ main(int ac, char **av)
                                exit(255);
                        xfree(line);
                        break;
+               case 'T':
+                       no_tty_flag = 1;
+                       /* ensure that the user doesn't try to backdoor a */
+                       /* null cipher switch on an interactive session */
+                       /* so explicitly disable it no matter what */
+                       options.none_switch=0;
+                       break;
                case 's':
                        subsystem_flag = 1;
                        break;
@@ -600,7 +606,7 @@ main(int ac, char **av)
         * Initialize "log" output.  Since we are the client all output
         * actually goes to stderr.
         */
-       log_init(av[0],
+       log_init(argv0,
            options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
            SYSLOG_FACILITY_USER, !use_syslog);
 
@@ -613,9 +619,36 @@ main(int ac, char **av)
                        fatal("Can't open user config file %.100s: "
                            "%.100s", config, strerror(errno));
        } else {
-               snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir,
+           /*
+            * Since the config file parsing code aborts if it sees
+            * options it doesn't recognize, allow users to put
+            * options specific to compile-time add-ons in alternate
+            * config files so their primary config file will
+            * interoperate SSH versions that don't support those
+            * options.
+            */
+#ifdef GSSAPI
+               r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir,
+                   _PATH_SSH_USER_CONFFILE);
+               if (r > 0 && (size_t)r < sizeof(buf))
+                       (void)read_config_file(buf, host, &options, 1);
+#ifdef GSI
+               r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir,
+                   _PATH_SSH_USER_CONFFILE);
+               if (r > 0 && (size_t)r < sizeof(buf))
+                       (void)read_config_file(buf, host, &options, 1);
+#endif
+#if defined(KRB5)
+               r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir,
+                   _PATH_SSH_USER_CONFFILE);
+               if (r > 0 && (size_t)r < sizeof(buf))
+                       (void)read_config_file(buf, host, &options, 1);
+#endif
+#endif
+               r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
                    _PATH_SSH_USER_CONFFILE);
-               (void)read_config_file(buf, host, &options, 1);
+               if (r > 0 && (size_t)r < sizeof(buf))
+                       (void)read_config_file(buf, host, &options, 1);
 
                /* Read systemwide configuration file after use config. */
                (void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
@@ -628,12 +661,15 @@ main(int ac, char **av)
        channel_set_af(options.address_family);
 
        /* reinit */
-       log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
+       log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
 
        seed_rng();
 
-       if (options.user == NULL)
+       if (options.user == NULL) {
                options.user = xstrdup(pw->pw_name);
+               options.implicit = 1;
+       }
+        else options.implicit = 0;
 
        /* Get default port if port has not been set. */
        if (options.port == 0) {
@@ -766,9 +802,9 @@ main(int ac, char **av)
         * Now that we are back to our own permissions, create ~/.ssh
         * directory if it doesn't already exist.
         */
-       snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir,
+       r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
            strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
-       if (stat(buf, &st) < 0)
+       if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0)
                if (mkdir(buf, 0700) < 0)
                        error("Could not create directory '%.200s'.", buf);
 
@@ -1142,6 +1178,9 @@ ssh_session2_open(void)
 {
        Channel *c;
        int window, packetmax, in, out, err;
+       int sock;
+       int socksize;
+       int socksizelen = sizeof(int);
 
        if (stdin_null_flag) {
                in = open(_PATH_DEVNULL, O_RDONLY);
@@ -1162,9 +1201,75 @@ ssh_session2_open(void)
        if (!isatty(err))
                set_nonblock(err);
 
-       window = CHAN_SES_WINDOW_DEFAULT;
+       /* we need to check to see if what they want to do about buffer */
+       /* sizes here. In a hpn to nonhpn connection we want to limit */
+       /* the window size to something reasonable in case the far side */
+       /* has the large window bug. In hpn to hpn connection we want to */
+       /* use the max window size but allow the user to override it */
+       /* lastly if they disabled hpn then use the ssh std window size */
+
+       /* so why don't we just do a getsockopt() here and set the */
+       /* ssh window to that? In the case of a autotuning receive */
+       /* window the window would get stuck at the initial buffer */
+       /* size generally less than 96k. Therefore we need to set the */
+       /* maximum ssh window size to the maximum hpn buffer size */
+       /* unless the user has specifically set the tcprcvbufpoll */
+       /* to no. In which case we *can* just set the window to the */
+       /* minimum of the hpn buffer size and tcp receive buffer size */
+       
+       if (tty_flag)
+               options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
+       else
+               options.hpn_buffer_size = 2*1024*1024;
+
+       if (datafellows & SSH_BUG_LARGEWINDOW) 
+       {
+               debug("HPN to Non-HPN Connection");
+       } 
+       else 
+       {
+               if (options.tcp_rcv_buf_poll <= 0) 
+               {
+                       sock = socket(AF_INET, SOCK_STREAM, 0);
+                       getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
+                                  &socksize, &socksizelen);
+                       close(sock);
+                       debug("socksize %d", socksize);
+                       options.hpn_buffer_size = socksize;
+                       debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
+               } 
+               else
+               {
+                       if (options.tcp_rcv_buf > 0) 
+                       {
+                               /*create a socket but don't connect it */
+                               /* we use that the get the rcv socket size */
+                               sock = socket(AF_INET, SOCK_STREAM, 0);
+                               /* if they are using the tcp_rcv_buf option */
+                               /* attempt to set the buffer size to that */
+                               if (options.tcp_rcv_buf) 
+                                       setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, 
+                                                  sizeof(options.tcp_rcv_buf));
+                               getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
+                                          &socksize, &socksizelen);
+                               close(sock);
+                               debug("socksize %d", socksize);
+                               options.hpn_buffer_size = socksize;
+                               debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
+                       }
+               }
+               
+       }
+
+       debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
+
+       window = options.hpn_buffer_size;
+
+       channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
+
        packetmax = CHAN_SES_PACKET_DEFAULT;
        if (tty_flag) {
+               window = 4*CHAN_SES_PACKET_DEFAULT;
                window >>= 1;
                packetmax >>= 1;
        }
@@ -1172,7 +1277,10 @@ ssh_session2_open(void)
            "session", SSH_CHANNEL_OPENING, in, out, err,
            window, packetmax, CHAN_EXTENDED_WRITE,
            "client-session", /*nonblock*/0);
-
+       if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
+               c->dynamic_window = 1;
+               debug ("Enabled Dynamic Window Scaling\n");
+       }
        debug3("ssh_session2_open: channel_new: %d", c->self);
 
        channel_send_open(c->self);
This page took 0.141237 seconds and 4 git commands to generate.