]> andersk Git - openssh.git/commitdiff
- OpenBSD CVS updates:
authordamien <damien>
Tue, 30 May 2000 03:44:51 +0000 (03:44 +0000)
committerdamien <damien>
Tue, 30 May 2000 03:44:51 +0000 (03:44 +0000)
  - markus@cvs.openbsd.org
    [session.c]
    make x11-fwd work w/ localhost (xauth add host/unix:11)
    [cipher.c compat.c readconf.c servconf.c]
    check strtok() != NULL; ok niels@
    [key.c]
    fix key_read() for uuencoded keys w/o '='
    [serverloop.c]
    group ssh1 vs. ssh2 in serverloop
    [kex.c kex.h myproposal.h sshconnect2.c sshd.c]
    split kexinit/kexdh, factor out common code
    [readconf.c ssh.1 ssh.c]
    forwardagent defaults to no, add ssh -A
  - theo@cvs.openbsd.org
    [session.c]
    just some line shortening

15 files changed:
ChangeLog
cipher.c
compat.c
kex.c
kex.h
key.c
myproposal.h
readconf.c
servconf.c
serverloop.c
session.c
ssh.1
ssh.c
sshconnect2.c
sshd.c

index 3037eac38a7eb869caf78bcf6b65a51b96951a01..f8dcd9ce9e7e6c393d28db49bff0b8c80ac824c5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,23 @@
  - Define atexit for old Solaris
  - Fix buffer overrun in login.c for systems which use syslen in utmpx.
    patch from YOSHIFUJI Hideaki <yoshfuji@cerberus.nemoto.ecei.tohoku.ac.jp>
+ - OpenBSD CVS updates:
+  - markus@cvs.openbsd.org
+    [session.c]
+    make x11-fwd work w/ localhost (xauth add host/unix:11)
+    [cipher.c compat.c readconf.c servconf.c]
+    check strtok() != NULL; ok niels@
+    [key.c]
+    fix key_read() for uuencoded keys w/o '='
+    [serverloop.c]
+    group ssh1 vs. ssh2 in serverloop
+    [kex.c kex.h myproposal.h sshconnect2.c sshd.c]
+    split kexinit/kexdh, factor out common code
+    [readconf.c ssh.1 ssh.c]
+    forwardagent defaults to no, add ssh -A
+  - theo@cvs.openbsd.org
+    [session.c]
+    just some line shortening
 
 20000520
  - Xauth fix from Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
index 361da070a693a5536715af954884ce497d7fe4ba..aeabbc352d32d0721711f63fb6fef73a9e3e75d5 100644 (file)
--- a/cipher.c
+++ b/cipher.c
@@ -178,7 +178,7 @@ ciphers_valid(const char *names)
        char *p;
        int i;
 
-       if (strcmp(names, "") == 0)
+       if (names == NULL || strcmp(names, "") == 0)
                return 0;
        ciphers = xstrdup(names);
        for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) {
@@ -201,6 +201,8 @@ int
 cipher_number(const char *name)
 {
        int i;
+       if (name == NULL)
+               return -1;
        for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++)
                if (strcmp(cipher_names[i], name) == 0 &&
                    (cipher_mask() & (1 << i)))
index 0862de2072be24eadf0cc8b72655524e7631630f..17cdf8d322d560f466c6f3551e3d4a1da7b84404 100644 (file)
--- a/compat.c
+++ b/compat.c
@@ -80,10 +80,12 @@ compat_datafellows(const char *version)
 int
 proto_spec(const char *spec)
 {
-       char *s = xstrdup(spec);
-       char *p;
+       char *s, *p;
        int ret = SSH_PROTO_UNKNOWN;
 
+       if (spec == NULL)
+               return ret;
+       s = xstrdup(spec);
        for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) {
                switch(atoi(p)) {
                case 1:
diff --git a/kex.c b/kex.c
index 9c41b5123e1d2c8b1e7e71a5a3ff5525d59caabd..3a925f94e64826641f7715784155db376036a8ec 100644 (file)
--- a/kex.c
+++ b/kex.c
@@ -35,6 +35,7 @@ RCSID("$Id$");
 #include "xmalloc.h"
 #include "buffer.h"
 #include "bufaux.h"
+#include "packet.h"
 #include "cipher.h"
 #include "compat.h"
 
@@ -49,15 +50,17 @@ RCSID("$Id$");
 
 #include "kex.h"
 
+#define KEX_COOKIE_LEN 16
+
 Buffer *
 kex_init(char *myproposal[PROPOSAL_MAX])
 {
-       char c = 0;
-       unsigned char cookie[16];
+       int first_kex_packet_follows = 0;
+       unsigned char cookie[KEX_COOKIE_LEN];
        u_int32_t rand = 0;
        int i;
        Buffer *ki = xmalloc(sizeof(*ki));
-       for (i = 0; i < 16; i++) {
+       for (i = 0; i < KEX_COOKIE_LEN; i++) {
                if (i % 4 == 0)
                        rand = arc4random();
                cookie[i] = rand & 0xff;
@@ -67,11 +70,55 @@ kex_init(char *myproposal[PROPOSAL_MAX])
        buffer_append(ki, (char *)cookie, sizeof cookie);
        for (i = 0; i < PROPOSAL_MAX; i++)
                buffer_put_cstring(ki, myproposal[i]);
-       buffer_append(ki, &c, 1); /* boolean   first_kex_packet_follows */
-       buffer_put_int(ki, 0);    /* uint32    0 (reserved for future extension) */
+       buffer_put_char(ki, first_kex_packet_follows);
+       buffer_put_int(ki, 0);                          /* uint32 reserved */
        return ki;
 }
 
+/* send kexinit, parse and save reply */
+void
+kex_exchange_kexinit(
+    Buffer *my_kexinit, Buffer *peer_kexint,
+    char *peer_proposal[PROPOSAL_MAX])
+{
+       int i;
+       char *ptr;
+       int plen;
+
+       debug("send KEXINIT");
+       packet_start(SSH2_MSG_KEXINIT);
+       packet_put_raw(buffer_ptr(my_kexinit), buffer_len(my_kexinit)); 
+       packet_send();
+       packet_write_wait();
+       debug("done");
+
+       /*
+        * read and save raw KEXINIT payload in buffer. this is used during
+        * computation of the session_id and the session keys.
+        */
+       debug("wait KEXINIT");
+       packet_read_expect(&plen, SSH2_MSG_KEXINIT);
+       ptr = packet_get_raw(&plen);
+       buffer_append(peer_kexint, ptr, plen);
+
+       /* parse packet and save algorithm proposal */
+       /* skip cookie */
+       for (i = 0; i < KEX_COOKIE_LEN; i++)
+               packet_get_char();
+       /* extract kex init proposal strings */
+       for (i = 0; i < PROPOSAL_MAX; i++) {
+               peer_proposal[i] = packet_get_string(NULL);
+               debug("got kexinit: %s", peer_proposal[i]);
+       }
+       /* first kex follow / reserved */
+       i = packet_get_char();
+       debug("first kex follow: %d ", i);
+       i = packet_get_int();
+       debug("reserved: %d ", i);
+       packet_done();
+       debug("done");
+}
+
 /* diffie-hellman-group1-sha1 */
 
 int
@@ -133,12 +180,6 @@ dh_new_group1()
        return dh;
 }
 
-void
-bignum_print(BIGNUM *b)
-{
-       BN_print_fp(stderr,b);
-}
-
 void
 dump_digest(unsigned char *digest, int len)
 {
@@ -246,10 +287,13 @@ char *
 get_match(char *client, char *server)
 {
        char *sproposals[MAX_PROP];
-       char *p;
+       char *c, *s, *p, *ret;
        int i, j, nproposals;
 
-       for ((p = strtok(server, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) {
+       c = xstrdup(client);
+       s = xstrdup(server);
+
+       for ((p = strtok(s, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) {
                if (i < MAX_PROP)
                        sproposals[i] = p;
                else
@@ -257,11 +301,18 @@ get_match(char *client, char *server)
        }
        nproposals = i;
 
-       for ((p = strtok(client, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) {
-               for (j = 0; j < nproposals; j++)
-                       if (strcmp(p, sproposals[j]) == 0)
-                               return xstrdup(p);
+       for ((p = strtok(c, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) {
+               for (j = 0; j < nproposals; j++) {
+                       if (strcmp(p, sproposals[j]) == 0) {
+                               ret = xstrdup(p);
+                               xfree(c);
+                               xfree(s);
+                               return ret;
+                       }
+               }
        }
+       xfree(c);
+       xfree(s);
        return NULL;
 }
 void
@@ -355,7 +406,6 @@ choose_hostkeyalg(Kex *k, char *client, char *server)
 Kex *
 kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server)
 {
-       int i;
        int mode;
        int ctos;                               /* direction: if true client-to-server */
        int need;
@@ -383,10 +433,6 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server
        choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
        choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
            sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
-       for (i = 0; i < PROPOSAL_MAX; i++) {
-               xfree(cprop[i]);
-               xfree(sprop[i]);
-       }
        need = 0;
        for (mode = 0; mode < MODE_MAX; mode++) {
            if (need < k->enc[mode].key_len)
@@ -396,9 +442,7 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server
            if (need < k->mac[mode].key_len)
                    need = k->mac[mode].key_len;
        }
-       /* need runden? */
-#define WE_NEED 32
-       k->we_need = WE_NEED;
+       /* XXX need runden? */
        k->we_need = need;
        return k;
 }
diff --git a/kex.h b/kex.h
index 5395ebc3f085c218b673e7ce0c76c4cc1e00e69f..7e5c67024bff2f2676cd3ab403d369199c883feb 100644 (file)
--- a/kex.h
+++ b/kex.h
@@ -91,12 +91,17 @@ struct Kex {
 };
 
 Buffer *kex_init(char *myproposal[PROPOSAL_MAX]);
-int    dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
-DH     *dh_new_group1();
-Kex    *kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server);
+void
+kex_exchange_kexinit(
+    Buffer *my_kexinit, Buffer *peer_kexint,
+    char *peer_proposal[PROPOSAL_MAX]);
+Kex *
+kex_choose_conf(char *cprop[PROPOSAL_MAX],
+    char *sprop[PROPOSAL_MAX], int server);
 int    kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret);
-void   bignum_print(BIGNUM *b);
 void   packet_set_kex(Kex *k);
+int    dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
+DH     *dh_new_group1();
 
 unsigned char *
 kex_hash(
diff --git a/key.c b/key.c
index ae355a3fcdc6532019f24f6a21a671d657537f82..d474f85c666a749e275010d1d9852780dd51a381 100644 (file)
--- a/key.c
+++ b/key.c
@@ -256,12 +256,14 @@ key_read(Key *ret, char **cpp)
                blob = xmalloc(len);
                n = uudecode(cp, blob, len);
                if (n < 0) {
-                       error("uudecode %s failed", cp);
+                       error("key_read: uudecode %s failed", cp);
                        return 0;
                }
                k = dsa_key_from_blob(blob, n);
-               if (k == NULL)
-                        return 0;
+               if (k == NULL) {
+                       error("key_read: dsa_key_from_blob %s failed", cp);
+                       return 0;
+               }
                xfree(blob);
                if (ret->dsa != NULL)
                        DSA_free(ret->dsa);
@@ -269,10 +271,12 @@ key_read(Key *ret, char **cpp)
                k->dsa = NULL;
                key_free(k);
                bits = BN_num_bits(ret->dsa->p);
-               cp = strchr(cp, '=');
-               if (cp == NULL)
-                       return 0;
-               *cpp = cp + 1;
+               /* advance cp: skip whitespace and data */
+               while (*cp == ' ' || *cp == '\t')
+                       cp++;
+               while (*cp != '\0' && *cp != ' ' && *cp != '\t')
+                       cp++;
+               *cpp = cp;
                break;
        default:
                fatal("key_read: bad key type: %d", ret->type);
index 8b24179724f3fd38f514c413b9afdc32f3b31736..9611d89517d80eb19891d718321366be6ce85571 100644 (file)
@@ -6,7 +6,7 @@
 #define        KEX_DEFAULT_LANG        ""
 
 
-static const char *myproposal[PROPOSAL_MAX] = {
+static char *myproposal[PROPOSAL_MAX] = {
        KEX_DEFAULT_KEX,
        KEX_DEFAULT_PK_ALG,
        KEX_DEFAULT_ENCRYPT,
index d30641ed17d0ab70541adb2724f36b9daeb05221..3b4e048bcdfefca5eaa22483844ba1126462c487 100644 (file)
@@ -464,6 +464,8 @@ parse_int:
        case oCipher:
                intptr = &options->cipher;
                cp = strtok(NULL, WHITESPACE);
+               if (!cp)
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
                value = cipher_number(cp);
                if (value == -1)
                        fatal("%.200s line %d: Bad cipher '%s'.",
@@ -474,6 +476,8 @@ parse_int:
 
        case oCiphers:
                cp = strtok(NULL, WHITESPACE);
+               if (!cp)
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!ciphers_valid(cp))
                        fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
                              filename, linenum, cp ? cp : "<NONE>");
@@ -484,6 +488,8 @@ parse_int:
        case oProtocol:
                intptr = &options->protocol;
                cp = strtok(NULL, WHITESPACE);
+               if (!cp)
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
                value = proto_spec(cp);
                if (value == SSH_PROTO_UNKNOWN)
                        fatal("%.200s line %d: Bad protocol spec '%s'.",
@@ -691,7 +697,7 @@ void
 fill_default_options(Options * options)
 {
        if (options->forward_agent == -1)
-               options->forward_agent = 1;
+               options->forward_agent = 0;
        if (options->forward_x11 == -1)
                options->forward_x11 = 0;
        if (options->gateway_ports == -1)
index a4a0197786d9cacdef7daab3266b486b06dd1e38..6f4f8218ff622465f0095c286f479e6199d6b0a0 100644 (file)
@@ -588,6 +588,8 @@ parse_flag:
 
                case sCiphers:
                        cp = strtok(NULL, WHITESPACE);
+                       if (!cp)
+                               fatal("%s line %d: Missing argument.", filename, linenum);
                        if (!ciphers_valid(cp))
                                fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
                                    filename, linenum, cp ? cp : "<NONE>");
@@ -598,6 +600,8 @@ parse_flag:
                case sProtocol:
                        intptr = &options->protocol;
                        cp = strtok(NULL, WHITESPACE);
+                       if (!cp)
+                               fatal("%s line %d: Missing argument.", filename, linenum);
                        value = proto_spec(cp);
                        if (value == SSH_PROTO_UNKNOWN)
                                fatal("%s line %d: Bad protocol spec '%s'.",
index 977ed41f6c56758d2a88c83ad0beb445b097fb7f..b08fcfd92d853a3cf1e3507882878feaea73277e 100644 (file)
@@ -164,33 +164,37 @@ retry_select:
 
        /* Initialize select() masks. */
        FD_ZERO(readset);
+       FD_ZERO(writeset);
 
-       /*
-        * Read packets from the client unless we have too much buffered
-        * stdin or channel data.
-        */
        if (compat20) {
                /* wrong: bad condition XXX */
                if (channel_not_very_much_buffered_data())
                        FD_SET(connection_in, readset);
        } else {
-               if (buffer_len(&stdin_buffer) < 4096 &&
+               /*
+                * Read packets from the client unless we have too much
+                * buffered stdin or channel data.
+                */
+               if (buffer_len(&stdin_buffer) < buffer_high &&
                    channel_not_very_much_buffered_data())
                        FD_SET(connection_in, readset);
+               /*
+                * If there is not too much data already buffered going to
+                * the client, try to get some more data from the program.
+                */
+               if (packet_not_very_much_data_to_write()) {
+                       if (!fdout_eof)
+                               FD_SET(fdout, readset);
+                       if (!fderr_eof)
+                               FD_SET(fderr, readset);
+               }
+               /*
+                * If we have buffered data, try to write some of that data
+                * to the program.
+                */
+               if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
+                       FD_SET(fdin, writeset);
        }
-
-       /*
-        * If there is not too much data already buffered going to the
-        * client, try to get some more data from the program.
-        */
-       if (!compat20 && packet_not_very_much_data_to_write()) {
-               if (!fdout_eof)
-                       FD_SET(fdout, readset);
-               if (!fderr_eof)
-                       FD_SET(fderr, readset);
-       }
-       FD_ZERO(writeset);
-
        /* Set masks for channel descriptors. */
        channel_prepare_select(readset, writeset);
 
@@ -201,11 +205,6 @@ retry_select:
        if (packet_have_data_to_write())
                FD_SET(connection_out, writeset);
 
-       /* If we have buffered data, try to write some of that data to the
-          program. */
-       if (!compat20 && fdin != -1 && buffer_len(&stdin_buffer) > 0)
-               FD_SET(fdin, writeset);
-
        /* Update the maximum descriptor number if appropriate. */
        if (channel_max_fd() > max_fd)
                max_fd = channel_max_fd();
@@ -377,6 +376,7 @@ process_buffered_input_packets()
 void
 server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
 {
+       fd_set readset, writeset;
        int wait_status;        /* Status returned by wait(). */
        pid_t wait_pid;         /* pid returned by wait(). */
        int waiting_termination = 0;    /* Have displayed waiting close message. */
@@ -445,7 +445,6 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
 
        /* Main loop of the server for the interactive session mode. */
        for (;;) {
-               fd_set readset, writeset;
 
                /* Process buffered packets from the client. */
                process_buffered_input_packets();
@@ -717,6 +716,9 @@ input_direct_tcpip(void)
        originator = packet_get_string(NULL);
        originator_port = packet_get_int();
        packet_done();
+
+       debug("open direct-tcpip: from %s port %d to %s port %d",
+          originator, originator_port, target, target_port);
        /* XXX check permission */
        sock = channel_connect_to(target, target_port);
        xfree(target);
@@ -768,7 +770,6 @@ server_input_channel_open(int type, int plen)
                        channel_free(id);
                }
        } else if (strcmp(ctype, "direct-tcpip") == 0) {
-               debug("open direct-tcpip");
                id = input_direct_tcpip();
                if (id >= 0)
                        c = channel_lookup(id);
index 4b7404f7380c6d62c4d4c5eb74b590e106e4a282..4791857c0d3561d5782d20e4213ee1e3f7a26a74 100644 (file)
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.14 2000/05/25 03:10:18 deraadt Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -645,7 +645,8 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
                }
 #endif
                /* Do common processing for the child, such as execing the command. */
-               do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty);
+               do_child(command, pw, s->term, s->display, s->auth_proto,
+                   s->auth_data, s->tty);
                /* NOTREACHED */
        }
        if (pid < 0)
@@ -749,7 +750,10 @@ read_environment_file(char ***env, unsigned int *envsize,
                        fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
                        continue;
                }
-               /* Replace the equals sign by nul, and advance value to the value string. */
+               /*
+                * Replace the equals sign by nul, and advance value to
+                * the value string.
+                */
                *value = '\0';
                value++;
                child_set_env(env, envsize, cp, value);
@@ -948,7 +952,8 @@ do_child(const char *command, struct passwd * pw, const char *term,
 
        /* read $HOME/.ssh/environment. */
        if (!options.use_login) {
-               snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir);
+               snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
+                   pw->pw_dir);
                read_environment_file(&env, &envsize, buf);
        }
        if (debug_flag) {
@@ -1037,21 +1042,27 @@ do_child(const char *command, struct passwd * pw, const char *term,
                        if (auth_proto != NULL && auth_data != NULL) {
                                char *screen = strchr(display, ':');
                                if (debug_flag) {
-                                       fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n",
+                                       fprintf(stderr,
+                                           "Running %.100s add %.100s %.100s %.100s\n",
                                            XAUTH_PATH, display, auth_proto, auth_data);
                                        if (screen != NULL)
-                                               fprintf(stderr, "Adding %.*s/unix%s %s %s\n",
-                                                   screen-display, display, screen, auth_proto, auth_data);
+                                               fprintf(stderr,
+                                                   "Adding %.*s/unix%s %s %s\n",
+                                                   screen-display, display,
+                                                   screen, auth_proto, auth_data);
                                }
                                f = popen(XAUTH_PATH " -q -", "w");
                                if (f) {
-                                       fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data);
+                                       fprintf(f, "add %s %s %s\n", display,
+                                           auth_proto, auth_data);
                                        if (screen != NULL) 
                                                fprintf(f, "add %.*s/unix%s %s %s\n",
-                                                    screen-display, display, screen, auth_proto, auth_data);
+                                                   screen-display, display,
+                                                   screen, auth_proto, auth_data);
                                        pclose(f);
                                } else
-                                       fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH);
+                                       fprintf(stderr, "Could not run %s -q -\n",
+                                           XAUTH_PATH);
                        }
                }
 #endif /* XAUTH_PATH */
@@ -1081,7 +1092,8 @@ do_child(const char *command, struct passwd * pw, const char *term,
                                struct stat mailstat;
                                mailbox = getenv("MAIL");
                                if (mailbox != NULL) {
-                                       if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0)
+                                       if (stat(mailbox, &mailstat) != 0 ||
+                                           mailstat.st_size == 0)
                                                printf("No mail.\n");
                                        else if (mailstat.st_mtime < mailstat.st_atime)
                                                printf("You have mail.\n");
diff --git a/ssh.1 b/ssh.1
index 90fec68d9dace4cb9208ff859a5bb0fdbddbe6f1..c8405d7ca57a4649968d877912e456f6c0ae0e7d 100644 (file)
--- a/ssh.1
+++ b/ssh.1
@@ -24,7 +24,7 @@
 .Op Ar command
 .Pp
 .Nm ssh
-.Op Fl afgknqtvxCNPTX246
+.Op Fl afgknqtvxACNPTX246
 .Op Fl c Ar cipher_spec
 .Op Fl e Ar escape_char
 .Op Fl i Ar identity_file
@@ -332,7 +332,9 @@ host key is not known or has changed.
 .Bl -tag -width Ds
 .It Fl a
 Disables forwarding of the authentication agent connection.
-This may also be specified on a per-host basis in the configuration file.
+.It Fl A
+Enables forwarding of the authentication agent connection.
+This can also be specified on a per-host basis in a configuration file.
 .It Fl c Ar blowfish|3des
 Selects the cipher to use for encrypting the session.
 .Ar 3des
@@ -460,9 +462,9 @@ The verbose mode is also used to display
 challenges, if the user entered "s/key" as password.
 .It Fl x
 Disables X11 forwarding.
-This can also be specified on a per-host basis in a configuration file.
 .It Fl X
 Enables X11 forwarding.
+This can also be specified on a per-host basis in a configuration file.
 .It Fl C
 Requests compression of all data (including stdin, stdout, stderr, and
 data for forwarded X11 and TCP/IP connections).
@@ -671,6 +673,8 @@ The argument must be
 .Dq yes
 or
 .Dq no .
+The default is
+.Dq no .
 .It Cm ForwardX11
 Specifies whether X11 connections will be automatically redirected
 over the secure channel and
diff --git a/ssh.c b/ssh.c
index 28d4e82dd9b1698b7e642579033fc4f4fae77c09..7b9ed7a239db61b03c00152db516b5bee62a3c49 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -116,6 +116,7 @@ usage()
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "  -l user     Log in using this user name.\n");
        fprintf(stderr, "  -n          Redirect input from /dev/null.\n");
+       fprintf(stderr, "  -A          Enable authentication agent forwarding.\n");
        fprintf(stderr, "  -a          Disable authentication agent forwarding.\n");
 #ifdef AFS
        fprintf(stderr, "  -k          Disable Kerberos ticket and AFS token forwarding.\n");
@@ -315,6 +316,9 @@ main(int ac, char **av)
                case 'a':
                        options.forward_agent = 0;
                        break;
+               case 'A':
+                       options.forward_agent = 1;
+                       break;
 #ifdef AFS
                case 'k':
                        options.kerberos_tgt_passing = 0;
index 99ffb2c478d4ec7d0aeb68f5a2218d26e4ec0409..0abcf89a0a0732bf7b49d9018d389749453c186c 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.10 2000/05/08 17:42:25 markus Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
@@ -68,16 +68,12 @@ unsigned char *session_id2 = NULL;
 int session_id2_len = 0;
 
 void
-ssh_kex2(char *host, struct sockaddr *hostaddr)
+ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
+    Buffer *client_kexinit, Buffer *server_kexinit)
 {
-       Kex *kex;
-       char *cprop[PROPOSAL_MAX];
-       char *sprop[PROPOSAL_MAX];
-       Buffer *client_kexinit;
-       Buffer *server_kexinit;
-       int payload_len, dlen;
+       int i;
+       int plen, dlen;
        unsigned int klen, kout;
-       char *ptr;
        char *signature = NULL;
        unsigned int slen;
        char *server_host_key_blob = NULL;
@@ -86,72 +82,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        DH *dh;
        BIGNUM *dh_server_pub = 0;
        BIGNUM *shared_secret = 0;
-       int i;
        unsigned char *kbuf;
        unsigned char *hash;
 
-/* KEXINIT */
-
-       debug("Sending KEX init.");
-       if (options.ciphers != NULL) {
-               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-               myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
-       } else if (options.cipher == SSH_CIPHER_3DES) {
-               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-               myproposal[PROPOSAL_ENC_ALGS_STOC] =
-                   cipher_name(SSH_CIPHER_3DES_CBC);
-       } else if (options.cipher == SSH_CIPHER_BLOWFISH) {
-               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-               myproposal[PROPOSAL_ENC_ALGS_STOC] =
-                   cipher_name(SSH_CIPHER_BLOWFISH_CBC);
-       }
-       if (options.compression) {
-               myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
-               myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
-       } else {
-               myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
-               myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
-       }
-       for (i = 0; i < PROPOSAL_MAX; i++)
-               cprop[i] = xstrdup(myproposal[i]);
-
-       client_kexinit = kex_init(cprop);
-       packet_start(SSH2_MSG_KEXINIT);
-       packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit)); 
-       packet_send();
-       packet_write_wait();
-
-       debug("done");
-
-       packet_read_expect(&payload_len, SSH2_MSG_KEXINIT);
-
-       /* save payload for session_id */
-       server_kexinit = xmalloc(sizeof(*server_kexinit));
-       buffer_init(server_kexinit);
-       ptr = packet_get_raw(&payload_len);
-       buffer_append(server_kexinit, ptr, payload_len);
-
-       /* skip cookie */
-       for (i = 0; i < 16; i++)
-               (void) packet_get_char();
-       /* kex init proposal strings */
-       for (i = 0; i < PROPOSAL_MAX; i++) {
-               sprop[i] = packet_get_string(NULL);
-               debug("got kexinit string: %s", sprop[i]);
-       }
-       i = (int) packet_get_char();
-       debug("first kex follow == %d", i);
-       i = packet_get_int();
-       debug("reserved == %d", i);
-       packet_done();
-
-       debug("done read kexinit");
-       kex = kex_choose_conf(cprop, sprop, 0);
-
-/* KEXDH */
-
        debug("Sending SSH2_MSG_KEXDH_INIT.");
-
        /* generate and send 'e', client DH public key */
        dh = dh_new_group1();
        packet_start(SSH2_MSG_KEXDH_INIT);
@@ -172,7 +106,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 
        debug("Wait SSH2_MSG_KEXDH_REPLY.");
 
-       packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY);
+       packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
 
        debug("Got SSH2_MSG_KEXDH_REPLY.");
 
@@ -233,10 +167,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
            shared_secret
        );
        xfree(server_host_key_blob);
-       buffer_free(client_kexinit);
-       buffer_free(server_kexinit);
-       xfree(client_kexinit);
-       xfree(server_kexinit);
+       DH_free(dh);
 #ifdef DEBUG_KEXDH
        fprintf(stderr, "hash == ");
        for (i = 0; i< 20; i++)
@@ -250,16 +181,61 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        kex_derive_keys(kex, hash, shared_secret);
        packet_set_kex(kex);
 
-       /* have keys, free DH */
-       DH_free(dh);
-
        /* save session id */
        session_id2_len = 20;
        session_id2 = xmalloc(session_id2_len);
        memcpy(session_id2, hash, session_id2_len);
+}
+
+void
+ssh_kex2(char *host, struct sockaddr *hostaddr)
+{
+       int i, plen;
+       Kex *kex;
+       Buffer *client_kexinit, *server_kexinit;
+       char *sprop[PROPOSAL_MAX];
+
+       if (options.ciphers != NULL) {
+               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+               myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
+       } else if (options.cipher == SSH_CIPHER_3DES) {
+               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+               myproposal[PROPOSAL_ENC_ALGS_STOC] =
+                   (char *) cipher_name(SSH_CIPHER_3DES_CBC);
+       } else if (options.cipher == SSH_CIPHER_BLOWFISH) {
+               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+               myproposal[PROPOSAL_ENC_ALGS_STOC] =
+                   (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC);
+       }
+       if (options.compression) {
+               myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
+               myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
+       } else {
+               myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
+               myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
+       }
+
+       /* buffers with raw kexinit messages */
+       server_kexinit = xmalloc(sizeof(*server_kexinit));
+       buffer_init(server_kexinit);
+       client_kexinit = kex_init(myproposal);
+
+       /* algorithm negotiation */
+       kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
+       kex = kex_choose_conf(myproposal, sprop, 0);
+       for (i = 0; i < PROPOSAL_MAX; i++)
+               xfree(sprop[i]);
+
+       /* server authentication and session key agreement */
+       ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit);
+
+       buffer_free(client_kexinit);
+       buffer_free(server_kexinit);
+       xfree(client_kexinit);
+       xfree(server_kexinit);
 
        debug("Wait SSH2_MSG_NEWKEYS.");
-       packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
+       packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
        packet_done();
        debug("GOT SSH2_MSG_NEWKEYS.");
 
@@ -278,6 +254,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 #endif
        debug("done: KEX2.");
 }
+
 /*
  * Authenticate user
  */
diff --git a/sshd.c b/sshd.c
index 39fbcba4042c3abfb0cb2b0c14212bc599640c58..ec860024b3d7e6a367eb7d08e2d36b18de0d1dc6 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -14,7 +14,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.117 2000/05/18 13:27:36 djm Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.118 2000/05/25 20:45:20 markus Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -1159,7 +1159,6 @@ do_ssh2_kex()
        int payload_len, dlen;
        int slen;
        unsigned int klen, kout;
-       char *ptr;
        unsigned char *signature = NULL;
        unsigned char *server_host_key_blob = NULL;
        unsigned int sbloblen;
@@ -1171,7 +1170,6 @@ do_ssh2_kex()
        unsigned char *hash;
        Kex *kex;
        char *cprop[PROPOSAL_MAX];
-       char *sprop[PROPOSAL_MAX];
 
 /* KEXINIT */
 
@@ -1179,46 +1177,15 @@ do_ssh2_kex()
                myproposal[PROPOSAL_ENC_ALGS_CTOS] =
                myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
        }
-
-       debug("Sending KEX init.");
-
-       for (i = 0; i < PROPOSAL_MAX; i++)
-               sprop[i] = xstrdup(myproposal[i]);
-       server_kexinit = kex_init(sprop);
-       packet_start(SSH2_MSG_KEXINIT);
-       packet_put_raw(buffer_ptr(server_kexinit), buffer_len(server_kexinit)); 
-       packet_send();
-       packet_write_wait();
-
-       debug("done");
-
-       packet_read_expect(&payload_len, SSH2_MSG_KEXINIT);
-
-       /*
-        * save raw KEXINIT payload in buffer. this is used during
-        * computation of the session_id and the session keys.
-        */
+       server_kexinit = kex_init(myproposal);
        client_kexinit = xmalloc(sizeof(*client_kexinit));
        buffer_init(client_kexinit);
-       ptr = packet_get_raw(&payload_len);
-       buffer_append(client_kexinit, ptr, payload_len);
 
-       /* skip cookie */
-       for (i = 0; i < 16; i++)
-               (void) packet_get_char();
-       /* save kex init proposal strings */
-       for (i = 0; i < PROPOSAL_MAX; i++) {
-               cprop[i] = packet_get_string(NULL);
-               debug("got kexinit string: %s", cprop[i]);
-       }
-
-       i = (int) packet_get_char();
-       debug("first kex follow == %d", i);
-       i = packet_get_int();
-       debug("reserved == %d", i);
-
-       debug("done read kexinit");
-       kex = kex_choose_conf(cprop, sprop, 1);
+       /* algorithm negotiation */
+       kex_exchange_kexinit(server_kexinit, client_kexinit, cprop);
+       kex = kex_choose_conf(cprop, myproposal, 1);
+       for (i = 0; i < PROPOSAL_MAX; i++)
+               xfree(cprop[i]);
 
 /* KEXDH */
 
This page took 0.090749 seconds and 5 git commands to generate.