Upgrade to OpenSSH-5.2p1.
authorPeter Avalos <pavalos@theshell.com>
Sat, 20 Jun 2009 18:55:46 +0000 (08:55 -1000)
committerPeter Avalos <pavalos@theshell.com>
Sat, 20 Jun 2009 18:55:46 +0000 (08:55 -1000)
Security:

 * This release changes the default cipher order to prefer the AES CTR
   modes and the revised "arcfour256" mode to CBC mode ciphers that are
   susceptible to CPNI-957037 "Plaintext Recovery Attack Against SSH".

 * This release also adds countermeasures to mitigate CPNI-957037-style
   attacks against the SSH protocol's use of CBC-mode ciphers. Upon
   detection of an invalid packet length or Message Authentication
   Code, ssh/sshd will continue reading up to the maximum supported
   packet length rather than immediately terminating the connection.
   This eliminates most of the known differences in behaviour that
   leaked information about the plaintext of injected data which formed
   the basis of this attack. We believe that these attacks are rendered
   infeasible by these changes.

New features:

 * Added a -y option to ssh(1) to force logging to syslog rather than
   stderr, which is useful when running daemonised (ssh -f)

 * The sshd_config(5) ForceCommand directive now accepts commandline
   arguments for the internal-sftp server.

 * The ssh(1) ~C escape commandline now support runtime creation of
   dynamic (-D) port forwards.

 * Support the SOCKS4A protocol in ssh(1) dynamic (-D) forwards.
   (bz#1482)

 * Support remote port forwarding with a listen port of '0'. This
   informs the server that it should dynamically allocate a listen
   port and report it back to the client. (bz#1003)

 * sshd(8) now supports setting PermitEmptyPasswords and
   AllowAgentForwarding in Match blocks

Bug and documentation fixes

 * Repair a ssh(1) crash introduced in openssh-5.1 when the client is
   sent a zero-length banner (bz#1496)

 * Due to interoperability problems with certain
   broken SSH implementations, the eow@openssh.com and
   no-more-sessions@openssh.com protocol extensions are now only sent
   to peers that identify themselves as OpenSSH.

 * Make ssh(1) send the correct channel number for
   SSH2_MSG_CHANNEL_SUCCESS and SSH2_MSG_CHANNEL_FAILURE messages to
   avoid triggering 'Non-public channel' error messages on sshd(8) in
   openssh-5.1.

 * Avoid printing 'Non-public channel' warnings in sshd(8), since the
   ssh(1) has sent incorrect channel numbers since ~2004 (this reverts
   a behaviour introduced in openssh-5.1).

 * Avoid double-free in ssh(1) ~C escape -L handler (bz#1539)

 * Correct fail-on-error behaviour in sftp(1) batchmode for remote
   stat operations. (bz#1541)

 * Disable nonfunctional ssh(1) ~C escape handler in multiplex slave
   connections. (bz#1543)

 * Avoid hang in ssh(1) when attempting to connect to a server that
   has MaxSessions=0 set.

 * Multiple fixes to sshd(8) configuration test (-T) mode

 * Several core and portable OpenSSH bugs fixed: 1380, 1412, 1418,
   1419, 1421, 1490, 1491, 1492, 1514, 1515, 1518, 1520, 1538, 1540

 * Many manual page improvements.

63 files changed:
crypto/openssh/PROTOCOL
crypto/openssh/README
crypto/openssh/README.DELETED
crypto/openssh/addrmatch.c
crypto/openssh/auth-options.c
crypto/openssh/auth.c
crypto/openssh/auth.h
crypto/openssh/auth2-chall.c
crypto/openssh/auth2.c
crypto/openssh/canohost.c
crypto/openssh/canohost.h
crypto/openssh/channels.c
crypto/openssh/channels.h
crypto/openssh/cipher.c
crypto/openssh/cipher.h
crypto/openssh/clientloop.c
crypto/openssh/compat.c
crypto/openssh/compat.h
crypto/openssh/defines.h
crypto/openssh/dispatch.c
crypto/openssh/jpake.h [new file with mode: 0644]
crypto/openssh/kex.c
crypto/openssh/kexgexs.c
crypto/openssh/key.c
crypto/openssh/loginrec.c
crypto/openssh/misc.c
crypto/openssh/monitor.c
crypto/openssh/monitor.h
crypto/openssh/monitor_fdpass.c
crypto/openssh/monitor_wrap.c
crypto/openssh/monitor_wrap.h
crypto/openssh/myproposal.h
crypto/openssh/nchan.c
crypto/openssh/openbsd-compat/xmmap.c
crypto/openssh/packet.c
crypto/openssh/pathnames.h
crypto/openssh/readconf.c
crypto/openssh/readconf.h
crypto/openssh/scp.c
crypto/openssh/servconf.c
crypto/openssh/servconf.h
crypto/openssh/serverloop.c
crypto/openssh/session.c
crypto/openssh/sftp-server-main.c
crypto/openssh/sftp.1
crypto/openssh/sftp.c
crypto/openssh/ssh-keygen.1
crypto/openssh/ssh-keygen.c
crypto/openssh/ssh-keyscan.1
crypto/openssh/ssh-keyscan.c
crypto/openssh/ssh.1
crypto/openssh/ssh.c
crypto/openssh/ssh2.h
crypto/openssh/ssh_config
crypto/openssh/ssh_config.5
crypto/openssh/sshconnect.c
crypto/openssh/sshconnect2.c
crypto/openssh/sshd.8
crypto/openssh/sshd.c
crypto/openssh/sshd_config.5
crypto/openssh/sshpty.c
crypto/openssh/ttymodes.c
crypto/openssh/uidswap.c

index 37fd536..5aada63 100644 (file)
@@ -64,6 +64,12 @@ remain open after a "eow@openssh.com" has been sent and more data may
 still be sent in the other direction. This message does not consume
 window space and may be sent even if no window space is available.
 
+NB. due to certain broken SSH implementations aborting upon receipt
+of this message (in contravention of RFC4254 section 5.4), this
+message is only sent to OpenSSH peers (identified by banner).
+Other SSH implementations may be whitelisted to receive this message
+upon request.
+
 4. connection: disallow additional sessions extension
    "no-more-sessions@openssh.com"
 
@@ -87,6 +93,11 @@ connection.
 Note that this is not a general defence against compromised clients
 (that is impossible), but it thwarts a simple attack.
 
+NB. due to certain broken SSH implementations aborting upon receipt
+of this message, the no-more-sessions request is only sent to OpenSSH
+servers (identified by banner). Other SSH implementations may be
+whitelisted to receive this message upon request.
+
 5. connection: Tunnel forward extension "tun@openssh.com"
 
 OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
@@ -240,4 +251,4 @@ The values of the f_flag bitmask are as follows:
 Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
 advertised in the SSH_FXP_VERSION hello with version "2".
 
-$OpenBSD: PROTOCOL,v 1.11 2008/07/05 05:16:01 djm Exp $
+$OpenBSD: PROTOCOL,v 1.12 2009/02/14 06:35:49 djm Exp $
index 183d92f..9de00c0 100644 (file)
@@ -1,4 +1,4 @@
-See http://www.openssh.com/txt/release-5.1 for the release notes.
+See http://www.openssh.com/txt/release-5.2 for the release notes.
 
 - A Japanese translation of this document and of the OpenSSH FAQ is
 - available at http://www.unixuser.org/~haruyama/security/openssh/index.html
@@ -62,4 +62,4 @@ References -
 [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
 [7] http://www.openssh.com/faq.html
 
-$Id: README,v 1.69 2008/07/21 08:21:52 djm Exp $
+$Id: README,v 1.70 2009/02/23 00:11:57 djm Exp $
index dcf4cae..202f8b4 100644 (file)
@@ -11,6 +11,7 @@ aclocal.m4
 auth-shadow.c
 auth-sia.c
 auth-sia.h
+auth2-jpake.c
 buildpkg.sh.in
 config.guess
 config.h.in
@@ -21,6 +22,7 @@ contrib/
 fixpaths
 fixprogs
 install-sh
+jpake.c
 logintest.c
 md-sha256.c
 mdoc2man.awk
@@ -32,6 +34,7 @@ openbsd-compat/Makefile.in
 openbsd-compat/base64.c
 openbsd-compat/basename.c
 openbsd-compat/bindresvport.c
+openbsd-compat/bsd-arc4random.c
 openbsd-compat/bsd-asprintf.c
 openbsd-compat/bsd-closefrom.c
 openbsd-compat/bsd-cray.c
@@ -83,6 +86,7 @@ opensshd.init.in
 regress/
 scard/
 scard.h
+schnorr.c
 scp.0
 sftp-server.0
 sftp.0
index 2086afe..d39885b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: addrmatch.c,v 1.3 2008/06/10 23:06:19 djm Exp $ */
+/*     $OpenBSD: addrmatch.c,v 1.4 2008/12/10 03:55:20 stevesk Exp $ */
 
 /*
  * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
@@ -31,6 +31,7 @@
 
 #include "match.h"
 #include "log.h"
+#include "xmalloc.h"
 
 struct xaddr {
        sa_family_t     af;
@@ -97,7 +98,9 @@ addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa)
                        return -1;
                xa->af = AF_INET6;
                memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6));
+#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
                xa->scope_id = in6->sin6_scope_id;
+#endif
                break;
        default:
                return -1;
@@ -415,7 +418,7 @@ addr_match_list(const char *addr, const char *_list)
                                goto foundit;
                }
        }
-       free(o);
+       xfree(o);
 
        return ret;
 }
index 2536145..ab085c2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.43 2008/06/10 23:06:19 djm Exp $ */
+/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -255,7 +255,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
                cp = "permitopen=\"";
                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        char *host, *p;
-                       u_short port;
+                       int port;
                        char *patterns = xmalloc(strlen(opts) + 1);
 
                        opts += strlen(cp);
@@ -293,7 +293,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
                                goto bad_option;
                        }
                        host = cleanhostname(host);
-                       if (p == NULL || (port = a2port(p)) == 0) {
+                       if (p == NULL || (port = a2port(p)) <= 0) {
                                debug("%.100s, line %lu: Bad permitopen port "
                                    "<%.100s>", file, linenum, p ? p : "");
                                auth_debug_add("%.100s, line %lu: "
index 2370e5c..3585daa 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.79 2008/07/02 12:03:51 dtucker Exp $ */
+/* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
index 6a70f0e..3a70f44 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.61 2008/07/02 12:03:51 dtucker Exp $ */
+/* $OpenBSD: auth.h,v 1.62 2008/11/04 08:22:12 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -59,6 +59,7 @@ struct Authctxt {
        struct passwd   *pw;            /* set if 'valid' */
        char            *style;
        void            *kbdintctxt;
+       void            *jpake_ctx;
 #ifdef BSD_AUTH
        auth_session_t  *as;
 #endif
@@ -156,6 +157,9 @@ int bsdauth_respond(void *, u_int, char **);
 int    skey_query(void *, char **, char **, u_int *, char ***, u_int **);
 int    skey_respond(void *, u_int, char **);
 
+void   auth2_jpake_get_pwdata(Authctxt *, BIGNUM **, char **, char **);
+void   auth2_jpake_stop(Authctxt *);
+
 int    allowed_user(struct passwd *);
 struct passwd * getpwnamallow(const char *user);
 
index d816578..e6dbffe 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-chall.c,v 1.33 2007/09/21 08:15:29 djm Exp $ */
+/* $OpenBSD: auth2-chall.c,v 1.34 2008/12/09 04:32:22 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2001 Per Allansson.  All rights reserved.
@@ -281,7 +281,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        KbdintAuthctxt *kbdintctxt;
-       int authenticated = 0, res, len;
+       int authenticated = 0, res;
        u_int i, nresp;
        char **response = NULL, *method;
 
@@ -330,11 +330,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
                break;
        }
 
-       len = strlen("keyboard-interactive") + 2 +
-               strlen(kbdintctxt->device->name);
-       method = xmalloc(len);
-       snprintf(method, len, "keyboard-interactive/%s",
-           kbdintctxt->device->name);
+       xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name);
 
        if (!authctxt->postponed) {
                if (authenticated) {
index a835abf..ecf8570 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2.c,v 1.119 2008/07/04 23:30:16 djm Exp $ */
+/* $OpenBSD: auth2.c,v 1.120 2008/11/04 08:22:12 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -71,12 +71,18 @@ extern Authmethod method_hostbased;
 #ifdef GSSAPI
 extern Authmethod method_gssapi;
 #endif
+#ifdef JPAKE
+extern Authmethod method_jpake;
+#endif
 
 Authmethod *authmethods[] = {
        &method_none,
        &method_pubkey,
 #ifdef GSSAPI
        &method_gssapi,
+#endif
+#ifdef JPAKE
+       &method_jpake,
 #endif
        &method_passwd,
        &method_kbdint,
@@ -257,8 +263,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
        }
        /* reset state */
        auth2_challenge_stop(authctxt);
+#ifdef JPAKE
+       auth2_jpake_stop(authctxt);
+#endif
 
 #ifdef GSSAPI
+       /* XXX move to auth2_gssapi_stop() */
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
 #endif
index 42011fd..7138f48 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.c,v 1.63 2008/06/12 00:03:49 dtucker Exp $ */
+/* $OpenBSD: canohost.c,v 1.64 2009/02/12 03:00:56 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -342,7 +342,7 @@ get_remote_name_or_ip(u_int utmp_len, int use_dns)
 
 /* Returns the local/remote port for the socket. */
 
-static int
+int
 get_sock_port(int sock, int local)
 {
        struct sockaddr_storage from;
index e33e894..d9b41ff 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.h,v 1.9 2006/03/25 22:22:42 djm Exp $ */
+/* $OpenBSD: canohost.h,v 1.10 2009/02/12 03:00:56 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -23,5 +23,7 @@ char          *get_local_name(int);
 
 int             get_remote_port(void);
 int             get_local_port(void);
+int             get_sock_port(int, int);
+
 
 void            ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
index 69c99c9..dea60ba 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.286 2008/07/16 11:52:19 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.295 2009/02/12 03:00:56 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -296,6 +296,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
        buffer_init(&c->input);
        buffer_init(&c->output);
        buffer_init(&c->extended);
+       c->path = NULL;
        c->ostate = CHAN_OUTPUT_OPEN;
        c->istate = CHAN_INPUT_OPEN;
        c->flags = 0;
@@ -402,6 +403,10 @@ channel_free(Channel *c)
                xfree(c->remote_name);
                c->remote_name = NULL;
        }
+       if (c->path) {
+               xfree(c->path);
+               c->path = NULL;
+       }
        while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
                if (cc->abandon_cb != NULL)
                        cc->abandon_cb(c, cc->ctx);
@@ -691,7 +696,7 @@ channel_register_open_confirm(int id, channel_callback_fn *fn, void *ctx)
        Channel *c = channel_lookup(id);
 
        if (c == NULL) {
-               logit("channel_register_open_comfirm: %d: bad id", id);
+               logit("channel_register_open_confirm: %d: bad id", id);
                return;
        }
        c->open_confirm = fn;
@@ -980,7 +985,7 @@ static int
 channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
 {
        char *p, *host;
-       u_int len, have, i, found;
+       u_int len, have, i, found, need;
        char username[256];
        struct {
                u_int8_t version;
@@ -996,10 +1001,20 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
        if (have < len)
                return 0;
        p = buffer_ptr(&c->input);
+
+       need = 1;
+       /* SOCKS4A uses an invalid IP address 0.0.0.x */
+       if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) {
+               debug2("channel %d: socks4a request", c->self);
+               /* ... and needs an extra string (the hostname) */
+               need = 2;
+       }
+       /* Check for terminating NUL on the string(s) */
        for (found = 0, i = len; i < have; i++) {
                if (p[i] == '\0') {
-                       found = 1;
-                       break;
+                       found++;
+                       if (found == need)
+                               break;
                }
                if (i > 1024) {
                        /* the peer is probably sending garbage */
@@ -1008,7 +1023,7 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
                        return -1;
                }
        }
-       if (!found)
+       if (found < need)
                return 0;
        buffer_get(&c->input, (char *)&s4_req.version, 1);
        buffer_get(&c->input, (char *)&s4_req.command, 1);
@@ -1018,23 +1033,46 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
        p = buffer_ptr(&c->input);
        len = strlen(p);
        debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
+       len++;                                  /* trailing '\0' */
        if (len > have)
                fatal("channel %d: decode socks4: len %d > have %d",
                    c->self, len, have);
        strlcpy(username, p, sizeof(username));
        buffer_consume(&c->input, len);
-       buffer_consume(&c->input, 1);           /* trailing '\0' */
 
-       host = inet_ntoa(s4_req.dest_addr);
-       strlcpy(c->path, host, sizeof(c->path));
+       if (c->path != NULL) {
+               xfree(c->path);
+               c->path = NULL;
+       }
+       if (need == 1) {                        /* SOCKS4: one string */
+               host = inet_ntoa(s4_req.dest_addr);
+               c->path = xstrdup(host);
+       } else {                                /* SOCKS4A: two strings */
+               have = buffer_len(&c->input);
+               p = buffer_ptr(&c->input);
+               len = strlen(p);
+               debug2("channel %d: decode socks4a: host %s/%d",
+                   c->self, p, len);
+               len++;                          /* trailing '\0' */
+               if (len > have)
+                       fatal("channel %d: decode socks4a: len %d > have %d",
+                           c->self, len, have);
+               if (len > NI_MAXHOST) {
+                       error("channel %d: hostname \"%.100s\" too long",
+                           c->self, p);
+                       return -1;
+               }
+               c->path = xstrdup(p);
+               buffer_consume(&c->input, len);
+       }
        c->host_port = ntohs(s4_req.dest_port);
 
        debug2("channel %d: dynamic request: socks4 host %s port %u command %u",
-           c->self, host, c->host_port, s4_req.command);
+           c->self, c->path, c->host_port, s4_req.command);
 
        if (s4_req.command != 1) {
-               debug("channel %d: cannot handle: socks4 cn %d",
-                   c->self, s4_req.command);
+               debug("channel %d: cannot handle: %s cn %d",
+                   c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command);
                return -1;
        }
        s4_rsp.version = 0;                     /* vn: 0 for reply */
@@ -1065,7 +1103,7 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
                u_int8_t atyp;
        } s5_req, s5_rsp;
        u_int16_t dest_port;
-       u_char *p, dest_addr[255+1];
+       u_char *p, dest_addr[255+1], ntop[INET6_ADDRSTRLEN];
        u_int have, need, i, found, nmethods, addrlen, af;
 
        debug2("channel %d: decode socks5", c->self);
@@ -1138,10 +1176,22 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
        buffer_get(&c->input, (char *)&dest_addr, addrlen);
        buffer_get(&c->input, (char *)&dest_port, 2);
        dest_addr[addrlen] = '\0';
-       if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
-               strlcpy(c->path, (char *)dest_addr, sizeof(c->path));
-       else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
-               return -1;
+       if (c->path != NULL) {
+               xfree(c->path);
+               c->path = NULL;
+       }
+       if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
+               if (addrlen >= NI_MAXHOST) {
+                       error("channel %d: dynamic request: socks5 hostname "
+                           "\"%.100s\" too long", c->self, dest_addr);
+                       return -1;
+               }
+               c->path = xstrdup(dest_addr);
+       } else {
+               if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL)
+                       return -1;
+               c->path = xstrdup(ntop);
+       }
        c->host_port = ntohs(dest_port);
 
        debug2("channel %d: dynamic request: socks5 host %s port %u command %u",
@@ -1370,7 +1420,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
                    c->local_window_max, c->local_maxpacket, 0, rtype, 1);
                nc->listening_port = c->listening_port;
                nc->host_port = c->host_port;
-               strlcpy(nc->path, c->path, sizeof(nc->path));
+               if (c->path != NULL)
+                       nc->path = xstrdup(c->path);
 
                if (nextstate == SSH_CHANNEL_DYNAMIC) {
                        /*
@@ -2311,8 +2362,8 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
                        xfree(lang);
        }
        packet_check_eom();
-       /* Free the channel.  This will also close the socket. */
-       channel_free(c);
+       /* Schedule the channel for cleanup/deletion. */
+       chan_mark_dead(c);
 }
 
 /* ARGSUSED */
@@ -2377,18 +2428,18 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c;
        struct channel_confirm *cc;
-       int remote_id;
+       int id;
 
        /* Reset keepalive timeout */
        keep_alive_timeouts = 0;
 
-       remote_id = packet_get_int();
+       id = packet_get_int();
        packet_check_eom();
 
-       debug2("channel_input_confirm: type %d id %d", type, remote_id);
+       debug2("channel_input_status_confirm: type %d id %d", type, id);
 
-       if ((c = channel_lookup(remote_id)) == NULL) {
-               logit("channel_input_success_failure: %d: unknown", remote_id);
+       if ((c = channel_lookup(id)) == NULL) {
+               logit("channel_input_status_confirm: %d: unknown", id);
                return;
        }       
        ;
@@ -2409,7 +2460,8 @@ channel_set_af(int af)
 }
 
 static int
-channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
+channel_setup_fwd_listener(int type, const char *listen_addr,
+    u_short listen_port, int *allocated_listen_port,
     const char *host_to_connect, u_short port_to_connect, int gateway_ports)
 {
        Channel *c;
@@ -2417,6 +2469,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
        struct addrinfo hints, *ai, *aitop;
        const char *host, *addr;
        char ntop[NI_MAXHOST], strport[NI_MAXSERV];
+       in_port_t *lport_p;
 
        host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
            listen_addr : host_to_connect;
@@ -2426,7 +2479,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                error("No forward host name.");
                return 0;
        }
-       if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
+       if (strlen(host) >= NI_MAXHOST) {
                error("Forward host name too long.");
                return 0;
        }
@@ -2485,10 +2538,29 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                }
                return 0;
        }
-
+       if (allocated_listen_port != NULL)
+               *allocated_listen_port = 0;
        for (ai = aitop; ai; ai = ai->ai_next) {
-               if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
+               switch (ai->ai_family) {
+               case AF_INET:
+                       lport_p = &((struct sockaddr_in *)ai->ai_addr)->
+                           sin_port;
+                       break;
+               case AF_INET6:
+                       lport_p = &((struct sockaddr_in6 *)ai->ai_addr)->
+                           sin6_port;
+                       break;
+               default:
                        continue;
+               }
+               /*
+                * If allocating a port for -R forwards, then use the
+                * same port for all address families.
+                */
+               if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
+                   allocated_listen_port != NULL && *allocated_listen_port > 0)
+                       *lport_p = htons(*allocated_listen_port);
+
                if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
                    strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
                        error("channel_setup_fwd_listener: getnameinfo failed");
@@ -2504,7 +2576,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
 
                channel_set_reuseaddr(sock);
 
-               debug("Local forwarding listening on %s port %s.", ntop, strport);
+               debug("Local forwarding listening on %s port %s.",
+                   ntop, strport);
 
                /* Bind the socket to the address. */
                if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
@@ -2523,11 +2596,24 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                        close(sock);
                        continue;
                }
+
+               /*
+                * listen_port == 0 requests a dynamically allocated port -
+                * record what we got.
+                */
+               if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
+                   allocated_listen_port != NULL &&
+                   *allocated_listen_port == 0) {
+                       *allocated_listen_port = get_sock_port(sock, 1);
+                       debug("Allocated listen port %d",
+                           *allocated_listen_port);
+               }
+
                /* Allocate a channel number for the socket. */
                c = channel_new("port listener", type, sock, sock, -1,
                    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
                    0, "port listener", 1);
-               strlcpy(c->path, host, sizeof(c->path));
+               c->path = xstrdup(host);
                c->host_port = port_to_connect;
                c->listening_port = listen_port;
                success = 1;
@@ -2549,8 +2635,7 @@ channel_cancel_rport_listener(const char *host, u_short port)
                Channel *c = channels[i];
 
                if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
-                   strncmp(c->path, host, sizeof(c->path)) == 0 &&
-                   c->listening_port == port) {
+                   strcmp(c->path, host) == 0 && c->listening_port == port) {
                        debug2("%s: close channel %d", __func__, i);
                        channel_free(c);
                        found = 1;
@@ -2566,17 +2651,18 @@ channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
     const char *host_to_connect, u_short port_to_connect, int gateway_ports)
 {
        return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
-           listen_host, listen_port, host_to_connect, port_to_connect,
+           listen_host, listen_port, NULL, host_to_connect, port_to_connect,
            gateway_ports);
 }
 
 /* protocol v2 remote port fwd, used by sshd */
 int
 channel_setup_remote_fwd_listener(const char *listen_address,
-    u_short listen_port, int gateway_ports)
+    u_short listen_port, int *allocated_listen_port, int gateway_ports)
 {
        return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
-           listen_address, listen_port, NULL, 0, gateway_ports);
+           listen_address, listen_port, allocated_listen_port,
+           NULL, 0, gateway_ports);
 }
 
 /*
@@ -2791,10 +2877,16 @@ channel_print_adm_permitted_opens(void)
 {
        int i;
 
+       printf("permitopen");
+       if (num_adm_permitted_opens == 0) {
+               printf(" any\n");
+               return;
+       }
        for (i = 0; i < num_adm_permitted_opens; i++)
                if (permitted_adm_opens[i].host_to_connect != NULL)
                        printf(" %s:%d", permitted_adm_opens[i].host_to_connect,
                            permitted_adm_opens[i].port_to_connect);
+       printf("\n");
 }
 
 /* Try to start non-blocking connect to next host in cctx list */
@@ -3074,7 +3166,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
 }
 
 static int
-connect_local_xsocket(u_int dnr)
+connect_local_xsocket_path(const char *pathname)
 {
        int sock;
        struct sockaddr_un addr;
@@ -3084,7 +3176,7 @@ connect_local_xsocket(u_int dnr)
                error("socket: %.100s", strerror(errno));
        memset(&addr, 0, sizeof(addr));
        addr.sun_family = AF_UNIX;
-       snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
+       strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
        if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
                return sock;
        close(sock);
@@ -3092,6 +3184,14 @@ connect_local_xsocket(u_int dnr)
        return -1;
 }
 
+static int
+connect_local_xsocket(u_int dnr)
+{
+       char buf[1024];
+       snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);
+       return connect_local_xsocket_path(buf);
+}
+
 int
 x11_connect_display(void)
 {
@@ -3113,6 +3213,17 @@ x11_connect_display(void)
         * connection to the real X server.
         */
 
+       /* Check if the display is from launchd. */
+#ifdef __APPLE__
+       if (strncmp(display, "/tmp/launch", 11) == 0) {
+               sock = connect_local_xsocket_path(display);
+               if (sock < 0)
+                       return -1;
+
+               /* OK, we now have a connection to the display. */
+               return sock;
+       }
+#endif
        /*
         * Check if it is a unix domain socket.  Unix domain displays are in
         * one of the following formats: unix:d[.s], :d[.s], ::d[.s]
index 108b360..1488ed7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.96 2008/06/15 20:06:26 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.98 2009/02/12 03:00:56 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -55,8 +55,6 @@
 #define SSH_CHANNEL_ZOMBIE             14      /* Almost dead. */
 #define SSH_CHANNEL_MAX_TYPE           15
 
-#define SSH_CHANNEL_PATH_LEN           256
-
 struct Channel;
 typedef struct Channel Channel;
 
@@ -105,7 +103,7 @@ struct Channel {
        Buffer  output;         /* data received over encrypted connection for
                                 * send on socket */
        Buffer  extended;
-       char    path[SSH_CHANNEL_PATH_LEN];
+       char    *path;
                /* path for unix domain sockets, or host name for forwards */
        int     listening_port; /* port being listened for forwards */
        int     host_port;      /* remote port to connect for forwards */
@@ -247,7 +245,7 @@ int  channel_request_remote_forwarding(const char *, u_short,
 int     channel_setup_local_fwd_listener(const char *, u_short,
             const char *, u_short, int);
 void    channel_request_rforward_cancel(const char *host, u_short port);
-int     channel_setup_remote_fwd_listener(const char *, u_short, int);
+int     channel_setup_remote_fwd_listener(const char *, u_short, int *, int);
 int     channel_cancel_rport_listener(const char *, u_short);
 
 /* x11 forwarding */
index b264063..bb5c0ac 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.c,v 1.81 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -63,31 +63,32 @@ struct Cipher {
        u_int   block_size;
        u_int   key_len;
        u_int   discard_len;
+       u_int   cbc_mode;
        const EVP_CIPHER        *(*evptype)(void);
 } ciphers[] = {
-       { "none",               SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null },
-       { "des",                SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc },
-       { "3des",               SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des },
-       { "blowfish",           SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf },
-
-       { "3des-cbc",           SSH_CIPHER_SSH2, 8, 24, 0, EVP_des_ede3_cbc },
-       { "blowfish-cbc",       SSH_CIPHER_SSH2, 8, 16, 0, EVP_bf_cbc },
-       { "cast128-cbc",        SSH_CIPHER_SSH2, 8, 16, 0, EVP_cast5_cbc },
-       { "arcfour",            SSH_CIPHER_SSH2, 8, 16, 0, EVP_rc4 },
-       { "arcfour128",         SSH_CIPHER_SSH2, 8, 16, 1536, EVP_rc4 },
-       { "arcfour256",         SSH_CIPHER_SSH2, 8, 32, 1536, EVP_rc4 },
-       { "aes128-cbc",         SSH_CIPHER_SSH2, 16, 16, 0, EVP_aes_128_cbc },
-       { "aes192-cbc",         SSH_CIPHER_SSH2, 16, 24, 0, EVP_aes_192_cbc },
-       { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
+       { "none",               SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null },
+       { "des",                SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc },
+       { "3des",               SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des },
+       { "blowfish",           SSH_CIPHER_BLOWFISH, 8, 32, 0, 1, evp_ssh1_bf },
+
+       { "3des-cbc",           SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc },
+       { "blowfish-cbc",       SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc },
+       { "cast128-cbc",        SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc },
+       { "arcfour",            SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 },
+       { "arcfour128",         SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 },
+       { "arcfour256",         SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 },
+       { "aes128-cbc",         SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc },
+       { "aes192-cbc",         SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc },
+       { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
        { "rijndael-cbc@lysator.liu.se",
-                               SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
-       { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
-       { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
-       { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
+                               SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
+       { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr },
+       { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr },
+       { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr },
 #ifdef USE_CIPHER_ACSS
-       { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
+       { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss },
 #endif
-       { NULL,                 SSH_CIPHER_INVALID, 0, 0, 0, NULL }
+       { NULL,                 SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL }
 };
 
 /*--*/
@@ -110,6 +111,12 @@ cipher_get_number(const Cipher *c)
        return (c->number);
 }
 
+u_int
+cipher_is_cbc(const Cipher *c)
+{
+       return (c->cbc_mode);
+}
+
 u_int
 cipher_mask_ssh1(int client)
 {
index 49bbc16..3dd2270 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.h,v 1.36 2006/03/25 22:22:42 djm Exp $ */
+/* $OpenBSD: cipher.h,v 1.37 2009/01/26 09:58:15 markus Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -81,6 +81,7 @@ void   cipher_cleanup(CipherContext *);
 void    cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
 u_int   cipher_blocksize(const Cipher *);
 u_int   cipher_keylen(const Cipher *);
+u_int   cipher_is_cbc(const Cipher *);
 
 u_int   cipher_get_number(const Cipher *);
 void    cipher_get_keyiv(CipherContext *, u_char *, u_int);
index f10fab7..a2d2d1d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.201 2008/07/16 11:51:14 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.209 2009/02/12 03:00:56 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 #include "atomicio.h"
 #include "sshpty.h"
 #include "misc.h"
-#include "monitor_fdpass.h"
 #include "match.h"
 #include "msg.h"
 
@@ -765,8 +764,8 @@ process_cmdline(void)
        void (*handler)(int);
        char *s, *cmd, *cancel_host;
        int delete = 0;
-       int local = 0;
-       u_short cancel_port;
+       int local = 0, remote = 0, dynamic = 0;
+       int cancel_port;
        Forward fwd;
 
        bzero(&fwd, sizeof(fwd));
@@ -790,6 +789,8 @@ process_cmdline(void)
                    "Request local forward");
                logit("      -R[bind_address:]port:host:hostport    "
                    "Request remote forward");
+               logit("      -D[bind_address:]port                  "
+                   "Request dynamic forward");
                logit("      -KR[bind_address:]port                 "
                    "Cancel remote forward");
                if (!options.permit_local_command)
@@ -809,17 +810,22 @@ process_cmdline(void)
                delete = 1;
                s++;
        }
-       if (*s != 'L' && *s != 'R') {
+       if (*s == 'L')
+               local = 1;
+       else if (*s == 'R')
+               remote = 1;
+       else if (*s == 'D')
+               dynamic = 1;
+       else {
                logit("Invalid command.");
                goto out;
        }
-       if (*s == 'L')
-               local = 1;
-       if (local && delete) {
+
+       if ((local || dynamic) && delete) {
                logit("Not supported.");
                goto out;
        }
-       if ((!local || delete) && !compat20) {
+       if (remote && delete && !compat20) {
                logit("Not supported for SSH protocol version 1.");
                goto out;
        }
@@ -837,17 +843,17 @@ process_cmdline(void)
                        cancel_port = a2port(cancel_host);
                        cancel_host = NULL;
                }
-               if (cancel_port == 0) {
+               if (cancel_port <= 0) {
                        logit("Bad forwarding close port");
                        goto out;
                }
                channel_request_rforward_cancel(cancel_host, cancel_port);
        } else {
-               if (!parse_forward(&fwd, s)) {
+               if (!parse_forward(&fwd, s, dynamic, remote)) {
                        logit("Bad forwarding specification.");
                        goto out;
                }
-               if (local) {
+               if (local || dynamic) {
                        if (channel_setup_local_fwd_listener(fwd.listen_host,
                            fwd.listen_port, fwd.connect_host,
                            fwd.connect_port, options.gateway_ports) < 0) {
@@ -1036,7 +1042,6 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
 Supported escape sequences:\r\n\
   %c.  - terminate session\r\n\
   %cB  - send a BREAK to the remote system\r\n\
-  %cC  - open a command line\r\n\
   %cR  - Request rekey (SSH protocol 2 only)\r\n\
   %c#  - list forwarded connections\r\n\
   %c?  - this message\r\n\
@@ -1045,8 +1050,7 @@ Supported escape sequences:\r\n\
                                            escape_char, escape_char,
                                            escape_char, escape_char,
                                            escape_char, escape_char,
-                                           escape_char, escape_char,
-                                           escape_char);
+                                           escape_char, escape_char);
                                } else {
                                        snprintf(string, sizeof string,
 "%c?\r\n\
@@ -1081,6 +1085,8 @@ Supported escape sequences:\r\n\
                                continue;
 
                        case 'C':
+                               if (c && c->ctl_fd != -1)
+                                       goto noescape;
                                process_cmdline();
                                continue;
 
@@ -1632,7 +1638,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan)
 {
        Channel *c = NULL;
        char *listen_address, *originator_address;
-       int listen_port, originator_port;
+       u_short listen_port, originator_port;
 
        /* Get rest of the packet */
        listen_address = packet_get_string(NULL);
@@ -1658,7 +1664,7 @@ client_request_x11(const char *request_type, int rchan)
 {
        Channel *c = NULL;
        char *originator;
-       int originator_port;
+       u_short originator_port;
        int sock;
 
        if (!options.forward_x11) {
@@ -1722,7 +1728,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
                return 0;
 
        if (!compat20) {
-               error("Tunnel forwarding is not support for protocol 1");
+               error("Tunnel forwarding is not supported for protocol 1");
                return -1;
        }
 
@@ -1846,7 +1852,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
        if (reply) {
                packet_start(success ?
                    SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
-               packet_put_int(id);
+               packet_put_int(c->remote_id);
                packet_send();
        }
        xfree(rtype);
index bc11315..df3541d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.c,v 1.77 2006/12/12 03:58:42 djm Exp $ */
+/* $OpenBSD: compat.c,v 1.78 2008/09/11 14:22:37 markus Exp $ */
 /*
  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
@@ -91,7 +91,8 @@ compat_datafellows(const char *version)
                  "OpenSSH_3.1*",       SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
                { "OpenSSH_3.*",        SSH_OLD_FORWARD_ADDR },
                { "Sun_SSH_1.0*",       SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
-               { "OpenSSH*",           0 },
+               { "OpenSSH_4*",         0 },
+               { "OpenSSH*",           SSH_NEW_OPENSSH },
                { "*MindTerm*",         0 },
                { "2.1.0*",             SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
                                        SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
index 4d8ebc9..16cf282 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.h,v 1.41 2006/12/12 03:58:42 djm Exp $ */
+/* $OpenBSD: compat.h,v 1.42 2008/09/11 14:22:37 markus Exp $ */
 
 /*
  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
@@ -57,6 +57,7 @@
 #define SSH_BUG_FIRSTKEX       0x00800000
 #define SSH_OLD_FORWARD_ADDR   0x01000000
 #define SSH_BUG_RFWD_ADDR      0x02000000
+#define SSH_NEW_OPENSSH                0x04000000
 
 void     enable_compat13(void);
 void     enable_compat20(void);
index a8203eb..536ec49 100644 (file)
@@ -25,7 +25,7 @@
 #ifndef _DEFINES_H
 #define _DEFINES_H
 
-/* $Id: defines.h,v 1.151 2008/07/04 13:10:49 djm Exp $ */
+/* $Id: defines.h,v 1.153 2009/02/01 11:19:54 dtucker Exp $ */
 
 
 /* Constants */
@@ -698,7 +698,7 @@ struct winsize {
 # define CUSTOM_SYS_AUTH_PASSWD 1
 #endif
 
-#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID)
+#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(HAVE_SECUREWARE)
 # define CUSTOM_SYS_AUTH_PASSWD 1
 #endif
 #if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF)
@@ -738,4 +738,8 @@ struct winsize {
 # define EWOULDBLOCK EAGAIN
 #endif
 
+#ifndef INET6_ADDRSTRLEN       /* for non IPv6 machines */
+#define INET6_ADDRSTRLEN 46
+#endif
+
 #endif /* _DEFINES_H */
index d6b63be..64bb809 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatch.c,v 1.21 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: dispatch.c,v 1.22 2008/10/31 15:05:34 stevesk Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -37,7 +37,6 @@
 #include "packet.h"
 #include "compat.h"
 
-#define DISPATCH_MIN   0
 #define DISPATCH_MAX   255
 
 dispatch_fn *dispatch[DISPATCH_MAX];
diff --git a/crypto/openssh/jpake.h b/crypto/openssh/jpake.h
new file mode 100644 (file)
index 0000000..a3d800c
--- /dev/null
@@ -0,0 +1,134 @@
+/* $OpenBSD: jpake.h,v 1.1 2008/11/04 08:22:13 djm Exp $ */
+/*
+ * Copyright (c) 2008 Damien Miller.  All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef JPAKE_H
+#define JPAKE_H
+
+#include <sys/types.h>
+
+#include <openssl/bn.h>
+
+/* Set JPAKE_DEBUG in CFLAGS for privacy-violating debugging */
+#ifndef JPAKE_DEBUG
+# define JPAKE_DEBUG_BN(a)
+# define JPAKE_DEBUG_BUF(a)
+# define JPAKE_DEBUG_CTX(a)
+#else
+# define JPAKE_DEBUG_BN(a)     jpake_debug3_bn a
+# define JPAKE_DEBUG_BUF(a)    jpake_debug3_buf a
+# define JPAKE_DEBUG_CTX(a)    jpake_dump a
+#endif /* SCHNORR_DEBUG */
+
+struct jpake_group {
+       BIGNUM *p, *q, *g;
+};
+
+#define KZP_ID_LEN     16      /* Length of client and server IDs */
+
+struct jpake_ctx {
+       /* Parameters */
+       struct jpake_group *grp;
+
+       /* Private values shared by client and server */
+       BIGNUM *s;                      /* Secret (salted, crypted password) */
+       BIGNUM *k;                      /* Derived key */
+
+       /* Client private values (NULL for server) */
+       BIGNUM *x1;                     /* random in Zq */
+       BIGNUM *x2;                     /* random in Z*q */
+
+       /* Server private values (NULL for server) */
+       BIGNUM *x3;                     /* random in Zq */
+       BIGNUM *x4;                     /* random in Z*q */
+
+       /* Step 1: C->S */
+       u_char *client_id;              /* Anti-replay nonce */
+       u_int client_id_len;
+       BIGNUM *g_x1;                   /* g^x1 */
+       BIGNUM *g_x2;                   /* g^x2 */
+
+       /* Step 1: S->C */
+       u_char *server_id;              /* Anti-replay nonce */
+       u_int server_id_len;
+       BIGNUM *g_x3;                   /* g^x3 */
+       BIGNUM *g_x4;                   /* g^x4 */
+
+       /* Step 2: C->S */
+       BIGNUM *a;                      /* g^((x1+x3+x4)*x2*s) */
+
+       /* Step 2: S->C */
+       BIGNUM *b;                      /* g^((x1+x2+x3)*x4*s) */
+
+       /* Confirmation: C->S */
+       u_char *h_k_cid_sessid;         /* H(k || client_id || session_id) */
+       u_int h_k_cid_sessid_len;
+
+       /* Confirmation: S->C */
+       u_char *h_k_sid_sessid;         /* H(k || server_id || session_id) */
+       u_int h_k_sid_sessid_len;
+};
+
+/* jpake.c */
+struct jpake_group *jpake_default_group(void);
+BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
+int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *);
+void jpake_debug3_bn(const BIGNUM *, const char *, ...)
+    __attribute__((__nonnull__ (2)))
+    __attribute__((format(printf, 2, 3)));
+void jpake_debug3_buf(const u_char *, u_int, const char *, ...)
+    __attribute__((__nonnull__ (3)))
+    __attribute__((format(printf, 3, 4)));
+void jpake_dump(struct jpake_ctx *, const char *, ...)
+    __attribute__((__nonnull__ (2)))
+    __attribute__((format(printf, 2, 3)));
+struct jpake_ctx *jpake_new(void);
+void jpake_free(struct jpake_ctx *);
+
+void jpake_step1(struct jpake_group *, u_char **, u_int *,
+    BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
+    u_char **, u_int *, u_char **, u_int *);
+
+void jpake_step2(struct jpake_group *, BIGNUM *,
+    BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
+    const u_char *, u_int, const u_char *, u_int,
+    const u_char *, u_int, const u_char *, u_int,
+    BIGNUM **, u_char **, u_int *);
+
+void jpake_confirm_hash(const BIGNUM *,
+    const u_char *, u_int,
+    const u_char *, u_int,
+    u_char **, u_int *);
+
+void jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
+    BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
+    const u_char *, u_int, const u_char *, u_int,
+    const u_char *, u_int, const u_char *, u_int,
+    BIGNUM **, u_char **, u_int *);
+
+int jpake_check_confirm(const BIGNUM *, const u_char *, u_int,
+    const u_char *, u_int, const u_char *, u_int);
+
+/* schnorr.c */
+int schnorr_sign(const BIGNUM *, const BIGNUM *, const BIGNUM *,
+    const BIGNUM *, const BIGNUM *, const u_char *, u_int ,
+    u_char **, u_int *);
+int schnorr_verify(const BIGNUM *, const BIGNUM *, const BIGNUM *, 
+    const BIGNUM *, const u_char *, u_int,
+    const u_char *, u_int);
+
+#endif /* JPAKE_H */
+
index 332fadf..48b54f5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.79 2007/06/05 06:52:37 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.80 2008/09/06 12:24:13 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
index a037f57..76a0f8c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexs.c,v 1.10 2006/11/06 21:25:28 markus Exp $ */
+/* $OpenBSD: kexgexs.c,v 1.11 2009/01/01 21:17:36 djm Exp $ */
 /*
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
@@ -56,7 +56,8 @@ kexgex_server(Kex *kex)
        DH *dh;
        u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
        u_int sbloblen, klen, slen, hashlen;
-       int min = -1, max = -1, nbits = -1, type, kout;
+       int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1;
+       int type, kout;
 
        if (kex->load_host_key == NULL)
                fatal("Cannot load hostkey");
@@ -68,27 +69,29 @@ kexgex_server(Kex *kex)
        switch (type) {
        case SSH2_MSG_KEX_DH_GEX_REQUEST:
                debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
-               min = packet_get_int();
-               nbits = packet_get_int();
-               max = packet_get_int();
+               omin = min = packet_get_int();
+               onbits = nbits = packet_get_int();
+               omax = max = packet_get_int();
                min = MAX(DH_GRP_MIN, min);
                max = MIN(DH_GRP_MAX, max);
+               nbits = MAX(DH_GRP_MIN, nbits);
+               nbits = MIN(DH_GRP_MAX, nbits);
                break;
        case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD:
                debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received");
-               nbits = packet_get_int();
-               min = DH_GRP_MIN;
-               max = DH_GRP_MAX;
+               onbits = nbits = packet_get_int();
                /* unused for old GEX */
+               omin = min = DH_GRP_MIN;
+               omax = max = DH_GRP_MAX;
                break;
        default:
                fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type);
        }
        packet_check_eom();
 
-       if (max < min || nbits < min || max < nbits)
+       if (omax < omin || onbits < omin || omax < onbits)
                fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
-                   min, nbits, max);
+                   omin, onbits, omax);
 
        /* Contact privileged parent */
        dh = PRIVSEP(choose_dh(min, nbits, max));
@@ -149,7 +152,7 @@ kexgex_server(Kex *kex)
        key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
 
        if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
-               min = max = -1;
+               omin = min = omax = max = -1;
 
        /* calc H */
        kexgex_hash(
@@ -159,7 +162,7 @@ kexgex_server(Kex *kex)
            buffer_ptr(&kex->peer), buffer_len(&kex->peer),
            buffer_ptr(&kex->my), buffer_len(&kex->my),
            server_host_key_blob, sbloblen,
-           min, nbits, max,
+           omin, onbits, omax,
            dh->p, dh->g,
            dh_client_pub,
            dh->pub_key,
index 2ea13d2..3e17da6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.c,v 1.78 2008/07/07 23:32:51 stevesk Exp $ */
+/* $OpenBSD: key.c,v 1.80 2008/10/10 05:00:12 stevesk Exp $ */
 /*
  * read_bignum():
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -369,7 +369,8 @@ key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
                        y = MIN(y, FLDSIZE_Y - 1);
 
                        /* augment the field */
-                       field[x][y]++;
+                       if (field[x][y] < len - 2)
+                               field[x][y]++;
                        input = input >> 2;
                }
        }
@@ -427,7 +428,7 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
                retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k);
                break;
        default:
-               fatal("key_fingerprint_ex: bad digest representation %d",
+               fatal("key_fingerprint: bad digest representation %d",
                    dgst_rep);
                break;
        }
index b411141..f4af067 100644 (file)
@@ -1456,25 +1456,14 @@ syslogin_write_entry(struct logininfo *li)
  **/
 
 #ifdef USE_LASTLOG
-#define LL_FILE 1
-#define LL_DIR 2
-#define LL_OTHER 3
-
-static void
-lastlog_construct(struct logininfo *li, struct lastlog *last)
-{
-       /* clear the structure */
-       memset(last, '\0', sizeof(*last));
-
-       line_stripname(last->ll_line, li->line, sizeof(last->ll_line));
-       strlcpy(last->ll_host, li->hostname,
-               MIN_SIZEOF(last->ll_host, li->hostname));
-       last->ll_time = li->tv_sec;
-}
 
+#if !defined(LASTLOG_WRITE_PUTUTXLINE) || !defined(HAVE_GETLASTLOGXBYNAME)
+/* open the file (using filemode) and seek to the login entry */
 static int
-lastlog_filetype(char *filename)
+lastlog_openseek(struct logininfo *li, int *fd, int filemode)
 {
+       off_t offset;
+       char lastlog_file[1024];
        struct stat st;
 
        if (stat(LASTLOG_FILE, &st) != 0) {
@@ -1482,34 +1471,12 @@ lastlog_filetype(char *filename)
                    LASTLOG_FILE, strerror(errno));
                return (0);
        }
-       if (S_ISDIR(st.st_mode))
-               return (LL_DIR);
-       else if (S_ISREG(st.st_mode))
-               return (LL_FILE);
-       else
-               return (LL_OTHER);
-}
-
-
-/* open the file (using filemode) and seek to the login entry */
-static int
-lastlog_openseek(struct logininfo *li, int *fd, int filemode)
-{
-       off_t offset;
-       int type;
-       char lastlog_file[1024];
-
-       type = lastlog_filetype(LASTLOG_FILE);
-       switch (type) {
-       case LL_FILE:
-               strlcpy(lastlog_file, LASTLOG_FILE,
-                   sizeof(lastlog_file));
-               break;
-       case LL_DIR:
+       if (S_ISDIR(st.st_mode)) {
                snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s",
                    LASTLOG_FILE, li->username);
-               break;
-       default:
+       } else if (S_ISREG(st.st_mode)) {
+               strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file));
+       } else {
                logit("%s: %.100s is not a file or directory!", __func__,
                    LASTLOG_FILE);
                return (0);
@@ -1522,7 +1489,7 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
                return (0);
        }
 
-       if (type == LL_FILE) {
+       if (S_ISREG(st.st_mode)) {
                /* find this uid's offset in the lastlog file */
                offset = (off_t) ((long)li->uid * sizeof(struct lastlog));
 
@@ -1535,52 +1502,74 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
 
        return (1);
 }
+#endif /* !LASTLOG_WRITE_PUTUTXLINE || !HAVE_GETLASTLOGXBYNAME */
 
-static int
-lastlog_perform_login(struct logininfo *li)
+#ifdef LASTLOG_WRITE_PUTUTXLINE
+int
+lastlog_write_entry(struct logininfo *li)
 {
-       struct lastlog last;
-       int fd;
-
-       /* create our struct lastlog */
-       lastlog_construct(li, &last);
-
-       if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT))
-               return (0);
-
-       /* write the entry */
-       if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) {
-               close(fd);
-               logit("%s: Error writing to %s: %s", __func__,
-                   LASTLOG_FILE, strerror(errno));
-               return (0);
+       switch(li->type) {
+       case LTYPE_LOGIN:
+               return 1; /* lastlog written by pututxline */
+       default:
+               logit("lastlog_write_entry: Invalid type field");
+               return 0;
        }
-
-       close(fd);
-       return (1);
 }
-
+#else /* LASTLOG_WRITE_PUTUTXLINE */
 int
 lastlog_write_entry(struct logininfo *li)
 {
+       struct lastlog last;
+       int fd;
+
        switch(li->type) {
        case LTYPE_LOGIN:
-               return (lastlog_perform_login(li));
+               /* create our struct lastlog */
+               memset(&last, '\0', sizeof(last));
+               line_stripname(last.ll_line, li->line, sizeof(last.ll_line));
+               strlcpy(last.ll_host, li->hostname,
+                   MIN_SIZEOF(last.ll_host, li->hostname));
+               last.ll_time = li->tv_sec;
+       
+               if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT))
+                       return (0);
+       
+               /* write the entry */
+               if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) {
+                       close(fd);
+                       logit("%s: Error writing to %s: %s", __func__,
+                           LASTLOG_FILE, strerror(errno));
+                       return (0);
+               }
+       
+               close(fd);
+               return (1);
        default:
                logit("%s: Invalid type field", __func__);
                return (0);
        }
 }
+#endif /* LASTLOG_WRITE_PUTUTXLINE */
 
-static void
-lastlog_populate_entry(struct logininfo *li, struct lastlog *last)
+#ifdef HAVE_GETLASTLOGXBYNAME
+int
+lastlog_get_entry(struct logininfo *li)
 {
-       line_fullname(li->line, last->ll_line, sizeof(li->line));
-       strlcpy(li->hostname, last->ll_host,
-           MIN_SIZEOF(li->hostname, last->ll_host));
-       li->tv_sec = last->ll_time;
-}
+       struct lastlogx l, *ll;
 
+       if ((ll = getlastlogxbyname(li->username, &l)) == NULL) {
+               memset(&l, '\0', sizeof(l));
+               ll = &l;
+       }
+       line_fullname(li->line, ll->ll_line, sizeof(li->line));
+       strlcpy(li->hostname, ll->ll_host,
+               MIN_SIZEOF(li->hostname, ll->ll_host));
+       li->tv_sec = ll->ll_tv.tv_sec;
+       li->tv_usec = ll->ll_tv.tv_usec;
+       return (1);
+}
+#else /* HAVE_GETLASTLOGXBYNAME */
 int
 lastlog_get_entry(struct logininfo *li)
 {
@@ -1598,7 +1587,10 @@ lastlog_get_entry(struct logininfo *li)
                memset(&last, '\0', sizeof(last));
                /* FALLTHRU */
        case sizeof(last):
-               lastlog_populate_entry(li, &last);
+               line_fullname(li->line, last.ll_line, sizeof(li->line));
+               strlcpy(li->hostname, last.ll_host,
+                   MIN_SIZEOF(li->hostname, last.ll_host));
+               li->tv_sec = last.ll_time;
                return (1);
        case -1:
                error("%s: Error reading from %s: %s", __func__,
@@ -1613,6 +1605,7 @@ lastlog_get_entry(struct logininfo *li)
        /* NOTREACHED */
        return (0);
 }
+#endif /* HAVE_GETLASTLOGXBYNAME */
 #endif /* USE_LASTLOG */
 
 #ifdef USE_BTMP
index 8b303f1..143dbf0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.69 2008/06/13 01:38:23 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.71 2009/02/21 19:32:04 tobias Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005,2006 Damien Miller.  All rights reserved.
@@ -221,23 +221,19 @@ pwcopy(struct passwd *pw)
 
 /*
  * Convert ASCII string to TCP/IP port number.
- * Port must be >0 and <=65535.
- * Return 0 if invalid.
+ * Port must be >=0 and <=65535.
+ * Return -1 if invalid.
  */
 int
 a2port(const char *s)
 {
-       long port;
-       char *endp;
-
-       errno = 0;
-       port = strtol(s, &endp, 0);
-       if (s == endp || *endp != '\0' ||
-           (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) ||
-           port <= 0 || port > 65535)
-               return 0;
+       long long port;
+       const char *errstr;
 
-       return port;
+       port = strtonum(s, 0, 65535, &errstr);
+       if (errstr != NULL)
+               return -1;
+       return (int)port;
 }
 
 int
@@ -718,7 +714,8 @@ sanitise_stdfd(void)
        int nullfd, dupfd;
 
        if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
-               fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
+               fprintf(stderr, "Couldn't open /dev/null: %s\n",
+                   strerror(errno));
                exit(1);
        }
        while (++dupfd <= 2) {
@@ -726,7 +723,7 @@ sanitise_stdfd(void)
                if (fcntl(dupfd, F_GETFL, 0) >= 0)
                        continue;
                if (dup2(nullfd, dupfd) == -1) {
-                       fprintf(stderr, "dup2: %s", strerror(errno));
+                       fprintf(stderr, "dup2: %s\n", strerror(errno));
                        exit(1);
                }
        }
index 73cf6bc..f57e74b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.99 2008/07/10 18:08:11 markus Exp $ */
+/* $OpenBSD: monitor.c,v 1.101 2009/02/12 03:26:22 djm Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -87,6 +87,7 @@
 #include "misc.h"
 #include "compat.h"
 #include "ssh2.h"
+#include "jpake.h"
 
 #ifdef GSSAPI
 static Gssctxt *gsscontext = NULL;
@@ -149,6 +150,11 @@ int mm_answer_rsa_challenge(int, Buffer *);
 int mm_answer_rsa_response(int, Buffer *);
 int mm_answer_sesskey(int, Buffer *);
 int mm_answer_sessid(int, Buffer *);
+int mm_answer_jpake_get_pwdata(int, Buffer *);
+int mm_answer_jpake_step1(int, Buffer *);
+int mm_answer_jpake_step2(int, Buffer *);
+int mm_answer_jpake_key_confirm(int, Buffer *);
+int mm_answer_jpake_check_confirm(int, Buffer *);
 
 #ifdef USE_PAM
 int mm_answer_pam_start(int, Buffer *);
@@ -233,6 +239,13 @@ struct mon_table mon_dispatch_proto20[] = {
     {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
     {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
     {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
+#endif
+#ifdef JPAKE
+    {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
+    {MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1},
+    {MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2},
+    {MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm},
+    {MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm},
 #endif
     {0, 0, NULL}
 };
@@ -379,6 +392,15 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
                        if (!authenticated)
                                authctxt->failures++;
                }
+#ifdef JPAKE
+               /* Cleanup JPAKE context after authentication */
+               if (ent->flags & MON_AUTHDECIDE) {
+                       if (authctxt->jpake_ctx != NULL) {
+                               jpake_free(authctxt->jpake_ctx);
+                               authctxt->jpake_ctx = NULL;
+                       }
+               }
+#endif
        }
 
        if (!authctxt->valid)
@@ -1478,7 +1500,9 @@ mm_answer_rsa_challenge(int sock, Buffer *m)
                fatal("%s: key type mismatch", __func__);
        if ((key = key_from_blob(blob, blen)) == NULL)
                fatal("%s: received bad key", __func__);
-
+       if (key->type != KEY_RSA)
+               fatal("%s: received bad key type %d", __func__, key->type);
+       key->type = KEY_RSA1;
        if (ssh1_challenge)
                BN_clear_free(ssh1_challenge);
        ssh1_challenge = auth_rsa_generate_challenge(key);
@@ -1969,3 +1993,206 @@ mm_answer_gss_userok(int sock, Buffer *m)
        return (authenticated);
 }
 #endif /* GSSAPI */
+
+#ifdef JPAKE
+int
+mm_answer_jpake_step1(int sock, Buffer *m)
+{
+       struct jpake_ctx *pctx;
+       u_char *x3_proof, *x4_proof;
+       u_int x3_proof_len, x4_proof_len;
+
+       if (!options.zero_knowledge_password_authentication)
+               fatal("zero_knowledge_password_authentication disabled");
+
+       if (authctxt->jpake_ctx != NULL)
+               fatal("%s: authctxt->jpake_ctx already set (%p)",
+                   __func__, authctxt->jpake_ctx);
+       authctxt->jpake_ctx = pctx = jpake_new();
+
+       jpake_step1(pctx->grp,
+           &pctx->server_id, &pctx->server_id_len,
+           &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4,
+           &x3_proof, &x3_proof_len,
+           &x4_proof, &x4_proof_len);
+
+       JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__));
+
+       buffer_clear(m);
+
+       buffer_put_string(m, pctx->server_id, pctx->server_id_len);
+       buffer_put_bignum2(m, pctx->g_x3);
+       buffer_put_bignum2(m, pctx->g_x4);
+       buffer_put_string(m, x3_proof, x3_proof_len);
+       buffer_put_string(m, x4_proof, x4_proof_len);
+
+       debug3("%s: sending step1", __func__);
+       mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m);
+
+       bzero(x3_proof, x3_proof_len);
+       bzero(x4_proof, x4_proof_len);
+       xfree(x3_proof);
+       xfree(x4_proof);
+
+       monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1);
+       monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0);
+
+       return 0;
+}
+
+int
+mm_answer_jpake_get_pwdata(int sock, Buffer *m)
+{
+       struct jpake_ctx *pctx = authctxt->jpake_ctx;
+       char *hash_scheme, *salt;
+
+       if (pctx == NULL)
+               fatal("%s: pctx == NULL", __func__);
+
+       auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt);
+
+       buffer_clear(m);
+       /* pctx->s is sensitive, not returned to slave */
+       buffer_put_cstring(m, hash_scheme);
+       buffer_put_cstring(m, salt);
+
+       debug3("%s: sending pwdata", __func__);
+       mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m);
+
+       bzero(hash_scheme, strlen(hash_scheme));
+       bzero(salt, strlen(salt));
+       xfree(hash_scheme);
+       xfree(salt);
+
+       monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1);
+
+       return 0;
+}
+
+int
+mm_answer_jpake_step2(int sock, Buffer *m)
+{
+       struct jpake_ctx *pctx = authctxt->jpake_ctx;
+       u_char *x1_proof, *x2_proof, *x4_s_proof;
+       u_int x1_proof_len, x2_proof_len, x4_s_proof_len;
+
+       if (pctx == NULL)
+               fatal("%s: pctx == NULL", __func__);
+
+       if ((pctx->g_x1 = BN_new()) == NULL ||
+           (pctx->g_x2 = BN_new()) == NULL)
+               fatal("%s: BN_new", __func__);
+       buffer_get_bignum2(m, pctx->g_x1);
+       buffer_get_bignum2(m, pctx->g_x2);
+       pctx->client_id = buffer_get_string(m, &pctx->client_id_len);
+       x1_proof = buffer_get_string(m, &x1_proof_len);
+       x2_proof = buffer_get_string(m, &x2_proof_len);
+
+       jpake_step2(pctx->grp, pctx->s, pctx->g_x3,
+           pctx->g_x1, pctx->g_x2, pctx->x4,
+           pctx->client_id, pctx->client_id_len,
+           pctx->server_id, pctx->server_id_len,
+           x1_proof, x1_proof_len,
+           x2_proof, x2_proof_len,
+           &pctx->b,
+           &x4_s_proof, &x4_s_proof_len);
+
+       JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__));
+
+       bzero(x1_proof, x1_proof_len);
+       bzero(x2_proof, x2_proof_len);
+       xfree(x1_proof);
+       xfree(x2_proof);
+
+       buffer_clear(m);
+
+       buffer_put_bignum2(m, pctx->b);
+       buffer_put_string(m, x4_s_proof, x4_s_proof_len);
+
+       debug3("%s: sending step2", __func__);
+       mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m);
+
+       bzero(x4_s_proof, x4_s_proof_len);
+       xfree(x4_s_proof);
+
+       monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1);
+
+       return 0;
+}
+
+int
+mm_answer_jpake_key_confirm(int sock, Buffer *m)
+{
+       struct jpake_ctx *pctx = authctxt->jpake_ctx;
+       u_char *x2_s_proof;
+       u_int x2_s_proof_len;
+
+       if (pctx == NULL)
+               fatal("%s: pctx == NULL", __func__);
+
+       if ((pctx->a = BN_new()) == NULL)
+               fatal("%s: BN_new", __func__);
+       buffer_get_bignum2(m, pctx->a);
+       x2_s_proof = buffer_get_string(m, &x2_s_proof_len);
+
+       jpake_key_confirm(pctx->grp, pctx->s, pctx->a,
+           pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2,
+           pctx->server_id, pctx->server_id_len,
+           pctx->client_id, pctx->client_id_len,
+           session_id2, session_id2_len,
+           x2_s_proof, x2_s_proof_len,
+           &pctx->k,
+           &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len);
+
+       JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__));
+
+       bzero(x2_s_proof, x2_s_proof_len);
+       buffer_clear(m);
+
+       /* pctx->k is sensitive, not sent */
+       buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
+
+       debug3("%s: sending confirmation hash", __func__);
+       mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m);
+
+       monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1);
+
+       return 0;
+}
+
+int
+mm_answer_jpake_check_confirm(int sock, Buffer *m)
+{
+       int authenticated = 0;
+       u_char *peer_confirm_hash;
+       u_int peer_confirm_hash_len;
+       struct jpake_ctx *pctx = authctxt->jpake_ctx;
+
+       if (pctx == NULL)
+               fatal("%s: pctx == NULL", __func__);
+
+       peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len);
+
+       authenticated = jpake_check_confirm(pctx->k,
+           pctx->client_id, pctx->client_id_len,
+           session_id2, session_id2_len,
+           peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid;
+
+       JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__));
+
+       bzero(peer_confirm_hash, peer_confirm_hash_len);
+       xfree(peer_confirm_hash);
+
+       buffer_clear(m);
+       buffer_put_int(m, authenticated);
+
+       debug3("%s: sending result %d", __func__, authenticated);
+       mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m);
+
+       monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1);
+
+       auth_method = "jpake-01@openssh.com";
+       return authenticated;
+}
+
+#endif /* JPAKE */
index 464009a..a8a2c0c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.h,v 1.14 2006/03/25 22:22:43 djm Exp $ */
+/* $OpenBSD: monitor.h,v 1.15 2008/11/04 08:22:13 djm Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -60,7 +60,12 @@ enum monitor_reqtype {
        MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
        MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
        MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND,
-       MONITOR_REQ_TERM
+       MONITOR_REQ_TERM,
+       MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
+       MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
+       MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2,
+       MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM,
+       MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM,
 };
 
 struct mm_master;
index cab538b..4b9a066 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_fdpass.c,v 1.17 2008/03/24 16:11:07 deraadt Exp $ */
+/* $OpenBSD: monitor_fdpass.c,v 1.18 2008/11/30 11:59:26 dtucker Exp $ */
 /*
  * Copyright 2001 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
@@ -45,17 +45,16 @@ mm_send_fd(int sock, int fd)
 {
 #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
        struct msghdr msg;
-       struct iovec vec;
-       char ch = '\0';
-       ssize_t n;
 #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
        union {
                struct cmsghdr hdr;
-               char tmp[CMSG_SPACE(sizeof(int))];
                char buf[CMSG_SPACE(sizeof(int))];
        } cmsgbuf;
        struct cmsghdr *cmsg;
 #endif
+       struct iovec vec;
+       char ch = '\0';
+       ssize_t n;
 
        memset(&msg, 0, sizeof(msg));
 #ifdef HAVE_ACCRIGHTS_IN_MSGHDR
@@ -76,7 +75,10 @@ mm_send_fd(int sock, int fd)
        msg.msg_iov = &vec;
        msg.msg_iovlen = 1;
 
-       if ((n = sendmsg(sock, &msg, 0)) == -1) {
+       while ((n = sendmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN ||
+           errno == EINTR))
+               debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno));
+       if (n == -1) {
                error("%s: sendmsg(%d): %s", __func__, fd,
                    strerror(errno));
                return -1;
@@ -99,10 +101,6 @@ mm_receive_fd(int sock)
 {
 #if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
        struct msghdr msg;
-       struct iovec vec;
-       ssize_t n;
-       char ch;
-       int fd;
 #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
        union {
                struct cmsghdr hdr;
@@ -110,6 +108,10 @@ mm_receive_fd(int sock)
        } cmsgbuf;
        struct cmsghdr *cmsg;
 #endif
+       struct iovec vec;
+       ssize_t n;
+       char ch;
+       int fd;
 
        memset(&msg, 0, sizeof(msg));
        vec.iov_base = &ch;
@@ -124,10 +126,14 @@ mm_receive_fd(int sock)
        msg.msg_controllen = sizeof(cmsgbuf.buf);
 #endif
 
-       if ((n = recvmsg(sock, &msg, 0)) == -1) {
+       while ((n = recvmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN ||
+           errno == EINTR))
+               debug3("%s: recvmsg: %s", __func__, strerror(errno));
+       if (n == -1) {
                error("%s: recvmsg: %s", __func__, strerror(errno));
                return -1;
        }
+
        if (n != 1) {
                error("%s: recvmsg: expected received 1 got %ld",
                    __func__, (long)n);
@@ -145,6 +151,7 @@ mm_receive_fd(int sock)
                error("%s: no message header", __func__);
                return -1;
        }
+
 #ifndef BROKEN_CMSG_TYPE
        if (cmsg->cmsg_type != SCM_RIGHTS) {
                error("%s: expected type %d got %d", __func__,
index 40463d0..0986fc5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.63 2008/07/10 18:08:11 markus Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.64 2008/11/04 08:22:13 djm Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -40,6 +40,7 @@
 
 #include <openssl/bn.h>
 #include <openssl/dh.h>
+#include <openssl/evp.h>
 
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
@@ -70,7 +71,7 @@
 #include "atomicio.h"
 #include "monitor_fdpass.h"
 #include "misc.h"
-#include "servconf.h"
+#include "jpake.h"
 
 #include "channels.h"
 #include "session.h"
@@ -1256,3 +1257,165 @@ mm_ssh_gssapi_userok(char *user)
        return (authenticated);
 }
 #endif /* GSSAPI */
+
+#ifdef JPAKE
+void
+mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
+    char **hash_scheme, char **salt)
+{
+       Buffer m;
+
+       debug3("%s entering", __func__);
+
+       buffer_init(&m);
+       mm_request_send(pmonitor->m_recvfd,
+           MONITOR_REQ_JPAKE_GET_PWDATA, &m);
+
+       debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd,
+           MONITOR_ANS_JPAKE_GET_PWDATA, &m);
+
+       *hash_scheme = buffer_get_string(&m, NULL);
+       *salt = buffer_get_string(&m, NULL);
+
+       buffer_free(&m);
+}
+
+void
+mm_jpake_step1(struct jpake_group *grp,
+    u_char **id, u_int *id_len,
+    BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
+    u_char **priv1_proof, u_int *priv1_proof_len,
+    u_char **priv2_proof, u_int *priv2_proof_len)
+{
+       Buffer m;
+
+       debug3("%s entering", __func__);
+
+       buffer_init(&m);
+       mm_request_send(pmonitor->m_recvfd,
+           MONITOR_REQ_JPAKE_STEP1, &m);
+
+       debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP1", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd,
+           MONITOR_ANS_JPAKE_STEP1, &m);
+
+       if ((*priv1 = BN_new()) == NULL ||
+           (*priv2 = BN_new()) == NULL ||
+           (*g_priv1 = BN_new()) == NULL ||
+           (*g_priv2 = BN_new()) == NULL)
+               fatal("%s: BN_new", __func__);
+
+       *id = buffer_get_string(&m, id_len);
+       /* priv1 and priv2 are, well, private */
+       buffer_get_bignum2(&m, *g_priv1);
+       buffer_get_bignum2(&m, *g_priv2);
+       *priv1_proof = buffer_get_string(&m, priv1_proof_len);
+       *priv2_proof = buffer_get_string(&m, priv2_proof_len);
+
+       buffer_free(&m);
+}
+
+void
+mm_jpake_step2(struct jpake_group *grp, BIGNUM *s,
+    BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
+    const u_char *theirid, u_int theirid_len,
+    const u_char *myid, u_int myid_len,
+    const u_char *theirpub1_proof, u_int theirpub1_proof_len,
+    const u_char *theirpub2_proof, u_int theirpub2_proof_len,
+    BIGNUM **newpub,
+    u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len)
+{
+       Buffer m;
+
+       debug3("%s entering", __func__);
+
+       buffer_init(&m);
+       /* monitor already has all bignums except theirpub1, theirpub2 */
+       buffer_put_bignum2(&m, theirpub1);
+       buffer_put_bignum2(&m, theirpub2);
+       /* monitor already knows our id */
+       buffer_put_string(&m, theirid, theirid_len);
+       buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len);
+       buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len);
+
+       mm_request_send(pmonitor->m_recvfd,
+           MONITOR_REQ_JPAKE_STEP2, &m);
+
+       debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd,
+           MONITOR_ANS_JPAKE_STEP2, &m);
+
+       if ((*newpub = BN_new()) == NULL)
+               fatal("%s: BN_new", __func__);
+
+       buffer_get_bignum2(&m, *newpub);
+       *newpub_exponent_proof = buffer_get_string(&m,
+           newpub_exponent_proof_len);
+
+       buffer_free(&m);
+}
+
+void
+mm_jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
+    BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
+    BIGNUM *theirpub1, BIGNUM *theirpub2,
+    const u_char *my_id, u_int my_id_len,
+    const u_char *their_id, u_int their_id_len,
+    const u_char *sess_id, u_int sess_id_len,
+    const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len,
+    BIGNUM **k,
+    u_char **confirm_hash, u_int *confirm_hash_len)
+{
+       Buffer m;
+
+       debug3("%s entering", __func__);
+
+       buffer_init(&m);
+       /* monitor already has all bignums except step2_val */
+       buffer_put_bignum2(&m, step2_val);
+       /* monitor already knows all the ids */
+       buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len);
+
+       mm_request_send(pmonitor->m_recvfd,
+           MONITOR_REQ_JPAKE_KEY_CONFIRM, &m);
+
+       debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd,
+           MONITOR_ANS_JPAKE_KEY_CONFIRM, &m);
+
+       /* 'k' is sensitive and stays in the monitor */
+       *confirm_hash = buffer_get_string(&m, confirm_hash_len);
+
+       buffer_free(&m);
+}
+
+int
+mm_jpake_check_confirm(const BIGNUM *k,
+    const u_char *peer_id, u_int peer_id_len,
+    const u_char *sess_id, u_int sess_id_len,
+    const u_char *peer_confirm_hash, u_int peer_confirm_hash_len)
+{
+       Buffer m;
+       int success = 0;
+
+       debug3("%s entering", __func__);
+
+       buffer_init(&m);
+       /* k is dummy in slave, ignored */
+       /* monitor knows all the ids */
+       buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len);
+       mm_request_send(pmonitor->m_recvfd,
+           MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m);
+
+       debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd,
+           MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m);
+
+       success = buffer_get_int(&m);
+       buffer_free(&m);
+
+       debug3("%s: success = %d", __func__, success);
+       return success;
+}
+#endif /* JPAKE */
index 329189c..55c4b99 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.h,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: monitor_wrap.h,v 1.21 2008/11/04 08:22:13 djm Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -101,6 +101,26 @@ int mm_bsdauth_respond(void *, u_int, char **);
 int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
 int mm_skey_respond(void *, u_int, char **);
 
+/* jpake */
+struct jpake_group;
+void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **);
+void mm_jpake_step1(struct jpake_group *, u_char **, u_int *,
+    BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
+    u_char **, u_int *, u_char **, u_int *);
+void mm_jpake_step2(struct jpake_group *, BIGNUM *,
+    BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
+    const u_char *, u_int, const u_char *, u_int,
+    const u_char *, u_int, const u_char *, u_int,
+    BIGNUM **, u_char **, u_int *);
+void mm_jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
+    BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
+    const u_char *, u_int, const u_char *, u_int,
+    const u_char *, u_int, const u_char *, u_int,
+    BIGNUM **, u_char **, u_int *);
+int mm_jpake_check_confirm(const BIGNUM *,
+    const u_char *, u_int, const u_char *, u_int, const u_char *, u_int);
+
+
 /* zlib allocation hooks */
 
 void *mm_zalloc(struct mm_master *, u_int, u_int);
index 87a9e58..7bca3bc 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.22 2007/06/07 19:37:34 pvalchev Exp $ */
+/* $OpenBSD: myproposal.h,v 1.23 2009/01/23 07:58:11 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
 #endif
 
 #define        KEX_DEFAULT_PK_ALG      "ssh-rsa,ssh-dss"
+
 #define        KEX_DEFAULT_ENCRYPT \
+       "aes128-ctr,aes192-ctr,aes256-ctr," \
+       "arcfour256,arcfour128," \
        "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
-       "arcfour128,arcfour256,arcfour," \
-       "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
-       "aes128-ctr,aes192-ctr,aes256-ctr"
+       "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se"
 #define        KEX_DEFAULT_MAC \
        "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
        "hmac-ripemd160@openssh.com," \
index e0ebf43..160445e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: nchan.c,v 1.60 2008/06/30 12:16:02 djm Exp $ */
+/* $OpenBSD: nchan.c,v 1.62 2008/11/07 18:50:18 stevesk Exp $ */
 /*
  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
@@ -387,6 +387,8 @@ chan_send_eow2(Channel *c)
                    c->self);
                return;
        }
+       if (!(datafellows & SSH_NEW_OPENSSH))
+               return;
        packet_start(SSH2_MSG_CHANNEL_REQUEST);
        packet_put_int(c->remote_id);
        packet_put_cstring("eow@openssh.com");
@@ -484,12 +486,12 @@ chan_shutdown_write(Channel *c)
        if (c->sock != -1) {
                if (shutdown(c->sock, SHUT_WR) < 0)
                        debug2("channel %d: chan_shutdown_write: "
-                           "shutdown() failed for fd%d: %.100s",
+                           "shutdown() failed for fd %d: %.100s",
                            c->self, c->sock, strerror(errno));
        } else {
                if (channel_close_fd(&c->wfd) < 0)
                        logit("channel %d: chan_shutdown_write: "
-                           "close() failed for fd%d: %.100s",
+                           "close() failed for fd %d: %.100s",
                            c->self, c->wfd, strerror(errno));
        }
 }
@@ -508,13 +510,13 @@ chan_shutdown_read(Channel *c)
                if (shutdown(c->sock, SHUT_RD) < 0
                    && errno != ENOTCONN)
                        error("channel %d: chan_shutdown_read: "
-                           "shutdown() failed for fd%d [i%d o%d]: %.100s",
+                           "shutdown() failed for fd %d [i%d o%d]: %.100s",
                            c->self, c->sock, c->istate, c->ostate,
                            strerror(errno));
        } else {
                if (channel_close_fd(&c->rfd) < 0)
                        logit("channel %d: chan_shutdown_read: "
-                           "close() failed for fd%d: %.100s",
+                           "close() failed for fd %d: %.100s",
                            c->self, c->rfd, strerror(errno));
        }
 }
index 23efe38..04c6bab 100644 (file)
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* $Id: xmmap.c,v 1.14 2007/06/11 02:52:24 djm Exp $ */
+/* $Id: xmmap.c,v 1.15 2009/02/16 04:21:40 djm Exp $ */
 
 #include "includes.h"
 
@@ -71,7 +71,8 @@ xmmap(size_t size)
                        fatal("mkstemp(\"%s\"): %s",
                            MM_SWAP_TEMPLATE, strerror(errno));
                unlink(tmpname);
-               ftruncate(tmpfd, size);
+               if (ftruncate(tmpfd, size) != 0)
+                       fatal("%s: ftruncate: %s", __func__, strerror(errno));
                address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
                    tmpfd, (off_t)0);
                close(tmpfd);
index 8abd43e..5afc84c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.157 2008/07/10 18:08:11 markus Exp $ */
+/* $OpenBSD: packet.c,v 1.160 2009/02/13 11:50:21 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -84,6 +84,8 @@
 #define DBG(x)
 #endif
 
+#define PACKET_MAX_SIZE (256 * 1024)
+
 /*
  * This variable contains the file descriptors used for communicating with
  * the other side.  connection_in is used for reading; connection_out for
@@ -160,6 +162,10 @@ static u_int ssh1_keylen;
 /* roundup current message to extra_pad bytes */
 static u_char extra_pad = 0;
 
+/* XXX discard incoming data after MAC error */
+static u_int packet_discard = 0;
+static Mac *packet_discard_mac = NULL;
+
 struct packet {
        TAILQ_ENTRY(packet) next;
        u_char type;
@@ -209,6 +215,36 @@ packet_set_timeout(int timeout, int count)
                packet_timeout_ms = timeout * count * 1000;
 }
 
+static void
+packet_stop_discard(void)
+{
+       if (packet_discard_mac) {
+               char buf[1024];
+               
+               memset(buf, 'a', sizeof(buf));
+               while (buffer_len(&incoming_packet) < PACKET_MAX_SIZE)
+                       buffer_append(&incoming_packet, buf, sizeof(buf));
+               (void) mac_compute(packet_discard_mac,
+                   p_read.seqnr,
+                   buffer_ptr(&incoming_packet),
+                   PACKET_MAX_SIZE);
+       }
+       logit("Finished discarding for %.200s", get_remote_ipaddr());
+       cleanup_exit(255);
+}
+
+static void
+packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
+{
+       if (enc == NULL || !cipher_is_cbc(enc->cipher))
+               packet_disconnect("Packet corrupt");
+       if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
+               packet_discard_mac = mac;
+       if (buffer_len(&input) >= discard)
+               packet_stop_discard();
+       packet_discard = discard - buffer_len(&input);
+}
+
 /* Returns 1 if remote host is connected via socket, 0 if not. */
 
 int
@@ -1127,6 +1163,9 @@ packet_read_poll2(u_int32_t *seqnr_p)
        Mac *mac   = NULL;
        Comp *comp = NULL;
 
+       if (packet_discard)
+               return SSH_MSG_NONE;
+
        if (newkeys[MODE_IN] != NULL) {
                enc  = &newkeys[MODE_IN]->enc;
                mac  = &newkeys[MODE_IN]->mac;
@@ -1148,11 +1187,14 @@ packet_read_poll2(u_int32_t *seqnr_p)
                    block_size);
                cp = buffer_ptr(&incoming_packet);
                packet_length = get_u32(cp);
-               if (packet_length < 1 + 4 || packet_length > 256 * 1024) {
+               if (packet_length < 1 + 4 || packet_length > PACKET_MAX_SIZE) {
 #ifdef PACKET_DEBUG
                        buffer_dump(&incoming_packet);
 #endif
-                       packet_disconnect("Bad packet length %u.", packet_length);
+                       logit("Bad packet length %u.", packet_length);
+                       packet_start_discard(enc, mac, packet_length,
+                           PACKET_MAX_SIZE);
+                       return SSH_MSG_NONE;
                }
                DBG(debug("input: packet len %u", packet_length+4));
                buffer_consume(&input, block_size);
@@ -1161,9 +1203,13 @@ packet_read_poll2(u_int32_t *seqnr_p)
        need = 4 + packet_length - block_size;
        DBG(debug("partial packet %d, need %d, maclen %d", block_size,
            need, maclen));
-       if (need % block_size != 0)
-               fatal("padding error: need %d block %d mod %d",
+       if (need % block_size != 0) {
+               logit("padding error: need %d block %d mod %d",
                    need, block_size, need % block_size);
+               packet_start_discard(enc, mac, packet_length,
+                   PACKET_MAX_SIZE - block_size);
+               return SSH_MSG_NONE;
+       }
        /*
         * check if the entire packet has been received and
         * decrypt into incoming_packet
@@ -1185,11 +1231,19 @@ packet_read_poll2(u_int32_t *seqnr_p)
                macbuf = mac_compute(mac, p_read.seqnr,
                    buffer_ptr(&incoming_packet),
                    buffer_len(&incoming_packet));
-               if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
-                       packet_disconnect("Corrupted MAC on input.");
+               if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) {
+                       logit("Corrupted MAC on input.");
+                       if (need > PACKET_MAX_SIZE)
+                               fatal("internal error need %d", need);
+                       packet_start_discard(enc, mac, packet_length,
+                           PACKET_MAX_SIZE - need);
+                       return SSH_MSG_NONE;
+               }
+                               
                DBG(debug("MAC #%d ok", p_read.seqnr));
                buffer_consume(&input, mac->mac_len);
        }
+       /* XXX now it's safe to use fatal/packet_disconnect */
        if (seqnr_p != NULL)
                *seqnr_p = p_read.seqnr;
        if (++p_read.seqnr == 0)
@@ -1322,6 +1376,13 @@ packet_read_poll(void)
 void
 packet_process_incoming(const char *buf, u_int len)
 {
+       if (packet_discard) {
+               keep_alive_timeouts = 0; /* ?? */
+               if (len >= packet_discard)
+                       packet_stop_discard();
+               packet_discard -= len;
+               return;
+       }
        buffer_append(&input, buf, len);
 }
 
index f2571e2..80c5d9c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pathnames.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */
+/* $OpenBSD: pathnames.h,v 1.17 2008/12/29 02:23:26 stevesk Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -54,7 +54,7 @@
 #define _PATH_SSH_DAEMON_PID_FILE      _PATH_SSH_PIDDIR "/sshd.pid"
 
 /*
- * The directory in user\'s home directory in which the files reside. The
+ * The directory in user's home directory in which the files reside. The
  * directory should be world-readable (though not all files are).
  */
 #define _PATH_SSH_USER_DIR             ".ssh"
@@ -77,9 +77,9 @@
 #define _PATH_SSH_CLIENT_ID_RSA                ".ssh/id_rsa"
 
 /*
- * Configuration file in user\'s home directory.  This file need not be
+ * Configuration file in user's home directory.  This file need not be
  * readable by anyone but the user him/herself, but does not contain anything
- * particularly secret.  If the user\'s home directory resides on an NFS
+ * particularly secret.  If the user's home directory resides on an NFS
  * volume where root is mapped to nobody, this may need to be world-readable.
  */
 #define _PATH_SSH_USER_CONFFILE                ".ssh/config"
@@ -87,7 +87,7 @@
 /*
  * File containing a list of those rsa keys that permit logging in as this
  * user.  This file need not be readable by anyone but the user him/herself,
- * but does not contain anything particularly secret.  If the user\'s home
+ * but does not contain anything particularly secret.  If the user's home
  * directory resides on an NFS volume where root is mapped to nobody, this
  * may need to be world-readable.  (This file is read by the daemon which is
  * running as root.)
index 73f6eb3..53fc6c7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.167 2008/06/26 11:46:31 grunk Exp $ */
+/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -130,7 +130,7 @@ typedef enum {
        oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
        oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
        oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
-       oVisualHostKey,
+       oVisualHostKey, oZeroKnowledgePasswordAuthentication,
        oDeprecated, oUnsupported
 } OpCodes;
 
@@ -172,7 +172,7 @@ static struct {
        { "fallbacktorsh", oDeprecated },
        { "usersh", oDeprecated },
        { "identityfile", oIdentityFile },
-       { "identityfile2", oIdentityFile },                     /* alias */
+       { "identityfile2", oIdentityFile },                     /* obsolete */
        { "identitiesonly", oIdentitiesOnly },
        { "hostname", oHostName },
        { "hostkeyalias", oHostKeyAlias },
@@ -188,8 +188,8 @@ static struct {
        { "host", oHost },
        { "escapechar", oEscapeChar },
        { "globalknownhostsfile", oGlobalKnownHostsFile },
-       { "userknownhostsfile", oUserKnownHostsFile },          /* obsolete */
-       { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
+       { "globalknownhostsfile2", oGlobalKnownHostsFile2 },    /* obsolete */
+       { "userknownhostsfile", oUserKnownHostsFile },
        { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
        { "connectionattempts", oConnectionAttempts },
        { "batchmode", oBatchMode },
@@ -228,6 +228,13 @@ static struct {
        { "localcommand", oLocalCommand },
        { "permitlocalcommand", oPermitLocalCommand },
        { "visualhostkey", oVisualHostKey },
+#ifdef JPAKE
+       { "zeroknowledgepasswordauthentication",
+           oZeroKnowledgePasswordAuthentication },
+#else
+       { "zeroknowledgepasswordauthentication", oUnsupported },
+#endif
+
        { NULL, oBadOption }
 };
 
@@ -249,10 +256,9 @@ add_local_forward(Options *options, const Forward *newfwd)
                fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->local_forwards[options->num_local_forwards++];
 
-       fwd->listen_host = (newfwd->listen_host == NULL) ?
-           NULL : xstrdup(newfwd->listen_host);
+       fwd->listen_host = newfwd->listen_host;
        fwd->listen_port = newfwd->listen_port;
-       fwd->connect_host = xstrdup(newfwd->connect_host);
+       fwd->connect_host = newfwd->connect_host;
        fwd->connect_port = newfwd->connect_port;
 }
 
@@ -270,10 +276,9 @@ add_remote_forward(Options *options, const Forward *newfwd)
                    SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->remote_forwards[options->num_remote_forwards++];
 
-       fwd->listen_host = (newfwd->listen_host == NULL) ?
-           NULL : xstrdup(newfwd->listen_host);
+       fwd->listen_host = newfwd->listen_host;
        fwd->listen_port = newfwd->listen_port;
-       fwd->connect_host = xstrdup(newfwd->connect_host);
+       fwd->connect_host = newfwd->connect_host;
        fwd->connect_port = newfwd->connect_port;
 }
 
@@ -412,6 +417,10 @@ parse_flag:
                intptr = &options->password_authentication;
                goto parse_flag;
 
+       case oZeroKnowledgePasswordAuthentication:
+               intptr = &options->zero_knowledge_password_authentication;
+               goto parse_flag;
+
        case oKbdInteractiveAuthentication:
                intptr = &options->kbd_interactive_authentication;
                goto parse_flag;
@@ -706,56 +715,40 @@ parse_int:
 
        case oLocalForward:
        case oRemoteForward:
+       case oDynamicForward:
                arg = strdelim(&s);
                if (arg == NULL || *arg == '\0')
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
-               arg2 = strdelim(&s);
-               if (arg2 == NULL || *arg2 == '\0')
-                       fatal("%.200s line %d: Missing target argument.",
-                           filename, linenum);
 
-               /* construct a string for parse_forward */
-               snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
+               if (opcode == oLocalForward ||
+                   opcode == oRemoteForward) {
+                       arg2 = strdelim(&s);
+                       if (arg2 == NULL || *arg2 == '\0')
+                               fatal("%.200s line %d: Missing target argument.",
+                                   filename, linenum);
+
+                       /* construct a string for parse_forward */
+                       snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
+               } else if (opcode == oDynamicForward) {
+                       strlcpy(fwdarg, arg, sizeof(fwdarg));
+               }
 
-               if (parse_forward(&fwd, fwdarg) == 0)
+               if (parse_forward(&fwd, fwdarg,
+                   opcode == oDynamicForward ? 1 : 0,
+                   opcode == oRemoteForward ? 1 : 0) == 0)
                        fatal("%.200s line %d: Bad forwarding specification.",
                            filename, linenum);
 
                if (*activep) {
-                       if (opcode == oLocalForward)
+                       if (opcode == oLocalForward ||
+                           opcode == oDynamicForward)
                                add_local_forward(options, &fwd);
                        else if (opcode == oRemoteForward)
                                add_remote_forward(options, &fwd);
                }
                break;
 
-       case oDynamicForward:
-               arg = strdelim(&s);
-               if (!arg || *arg == '\0')
-                       fatal("%.200s line %d: Missing port argument.",
-                           filename, linenum);
-               memset(&fwd, '\0', sizeof(fwd));
-               fwd.connect_host = "socks";
-               fwd.listen_host = hpdelim(&arg);
-               if (fwd.listen_host == NULL ||
-                   strlen(fwd.listen_host) >= NI_MAXHOST)
-                       fatal("%.200s line %d: Bad forwarding specification.",
-                           filename, linenum);
-               if (arg) {
-                       fwd.listen_port = a2port(arg);
-                       fwd.listen_host = cleanhostname(fwd.listen_host);
-               } else {
-                       fwd.listen_port = a2port(fwd.listen_host);
-                       fwd.listen_host = NULL;
-               }
-               if (fwd.listen_port == 0)
-                       fatal("%.200s line %d: Badly formatted port number.",
-                           filename, linenum);
-               if (*activep)
-                       add_local_forward(options, &fwd);
-               break;
-
        case oClearAllForwardings:
                intptr = &options->clear_forwardings;
                goto parse_flag;
@@ -959,7 +952,6 @@ read_config_file(const char *filename, const char *host, Options *options,
        int active, linenum;
        int bad_options = 0;
 
-       /* Open the file. */
        if ((f = fopen(filename, "r")) == NULL)
                return 0;
 
@@ -1072,6 +1064,7 @@ initialize_options(Options * options)
        options->local_command = NULL;
        options->permit_local_command = -1;
        options->visual_host_key = -1;
+       options->zero_knowledge_password_authentication = -1;
 }
 
 /*
@@ -1208,6 +1201,8 @@ fill_default_options(Options * options)
                options->permit_local_command = 0;
        if (options->visual_host_key == -1)
                options->visual_host_key = 0;
+       if (options->zero_knowledge_password_authentication == -1)
+               options->zero_knowledge_password_authentication = 0;
        /* options->local_command should not be set by default */
        /* options->proxy_command should not be set by default */
        /* options->user will be set in the main program if appropriate */
@@ -1219,11 +1214,14 @@ fill_default_options(Options * options)
 /*
  * parse_forward
  * parses a string containing a port forwarding specification of the form:
+ *   dynamicfwd == 0
  *     [listenhost:]listenport:connecthost:connectport
+ *   dynamicfwd == 1
+ *     [listenhost:]listenport
  * returns number of arguments parsed or zero on error
  */
 int
-parse_forward(Forward *fwd, const char *fwdspec)
+parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
 {
        int i;
        char *p, *cp, *fwdarg[4];
@@ -1240,11 +1238,23 @@ parse_forward(Forward *fwd, const char *fwdspec)
                if ((fwdarg[i] = hpdelim(&cp)) == NULL)
                        break;
 
-       /* Check for trailing garbage in 4-arg case*/
+       /* Check for trailing garbage */
        if (cp != NULL)
                i = 0;  /* failure */
 
        switch (i) {
+       case 1:
+               fwd->listen_host = NULL;
+               fwd->listen_port = a2port(fwdarg[0]);
+               fwd->connect_host = xstrdup("socks");
+               break;
+
+       case 2:
+               fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
+               fwd->listen_port = a2port(fwdarg[1]);
+               fwd->connect_host = xstrdup("socks");
+               break;
+
        case 3:
                fwd->listen_host = NULL;
                fwd->listen_port = a2port(fwdarg[0]);
@@ -1264,19 +1274,37 @@ parse_forward(Forward *fwd, const char *fwdspec)
 
        xfree(p);
 
-       if (fwd->listen_port == 0 || fwd->connect_port == 0)
+       if (dynamicfwd) {
+               if (!(i == 1 || i == 2))
+                       goto fail_free;
+       } else {
+               if (!(i == 3 || i == 4))
+                       goto fail_free;
+               if (fwd->connect_port <= 0)
+                       goto fail_free;
+       }
+
+       if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
                goto fail_free;
 
        if (fwd->connect_host != NULL &&
            strlen(fwd->connect_host) >= NI_MAXHOST)
                goto fail_free;
+       if (fwd->listen_host != NULL &&
+           strlen(fwd->listen_host) >= NI_MAXHOST)
+               goto fail_free;
+
 
        return (i);
 
  fail_free:
-       if (fwd->connect_host != NULL)
+       if (fwd->connect_host != NULL) {
                xfree(fwd->connect_host);
-       if (fwd->listen_host != NULL)
+               fwd->connect_host = NULL;
+       }
+       if (fwd->listen_host != NULL) {
                xfree(fwd->listen_host);
+               fwd->listen_host = NULL;
+       }
        return (0);
 }
index 47c7aef..8fb3a85 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.74 2008/06/26 11:46:31 grunk Exp $ */
+/* $OpenBSD: readconf.h,v 1.78 2009/02/12 03:00:56 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -20,9 +20,9 @@
 
 typedef struct {
        char     *listen_host;          /* Host (address) to listen on. */
-       u_short   listen_port;          /* Port to forward. */
+       int       listen_port;          /* Port to forward. */
        char     *connect_host;         /* Host to connect. */
-       u_short   connect_port;         /* Port to connect on connect_host. */
+       int       connect_port;         /* Port to connect on connect_host. */
 }       Forward;
 /* Data structure for representing option data. */
 
@@ -49,6 +49,7 @@ typedef struct {
                                                 * authentication. */
        int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
        char    *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
+       int     zero_knowledge_password_authentication; /* Try jpake */
        int     batch_mode;     /* Batch mode: do not ask for passwords. */
        int     check_host_ip;  /* Also keep track of keys for IP address */
        int     strict_host_key_checking;       /* Strict host key checking. */
@@ -133,7 +134,7 @@ typedef struct {
 void     initialize_options(Options *);
 void     fill_default_options(Options *);
 int     read_config_file(const char *, const char *, Options *, int);
-int     parse_forward(Forward *, const char *);
+int     parse_forward(Forward *, const char *, int, int);
 
 int
 process_config_line(Options *, const char *, char *, const char *, int, int *);
index 9f8b7a1..3237478 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.163 2008/06/13 18:55:22 dtucker Exp $ */
+/* $OpenBSD: scp.c,v 1.164 2008/10/10 04:55:16 stevesk Exp $ */
 /*
  * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).
@@ -434,7 +434,7 @@ main(int argc, char **argv)
        }
        /*
         * Finally check the exit status of the ssh process, if one was forked
-        * and no error has occured yet
+        * and no error has occurred yet
         */
        if (do_cmd_pid != -1 && errs == 0) {
                if (remin != -1)
index 66e2297..e7fc2a7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.194 2009/01/22 10:02:34 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -42,8 +42,8 @@
 #include "channels.h"
 #include "groupaccess.h"
 
-static void add_listen_addr(ServerOptions *, char *, u_short);
-static void add_one_listen_addr(ServerOptions *, char *, u_short);
+static void add_listen_addr(ServerOptions *, char *, int);
+static void add_one_listen_addr(ServerOptions *, char *, int);
 
 /* Use of privilege separation or not */
 extern int use_privsep;
@@ -127,6 +127,7 @@ initialize_server_options(ServerOptions *options)
        options->num_permitted_opens = -1;
        options->adm_forced_command = NULL;
        options->chroot_directory = NULL;
+       options->zero_knowledge_password_authentication = -1;
 }
 
 void
@@ -258,6 +259,8 @@ fill_default_server_options(ServerOptions *options)
                options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
        if (options->permit_tun == -1)
                options->permit_tun = SSH_TUNMODE_NO;
+       if (options->zero_knowledge_password_authentication == -1)
+               options->zero_knowledge_password_authentication = 0;
 
        /* Turn privilege separation on by default */
        if (use_privsep == -1)
@@ -302,6 +305,7 @@ typedef enum {
        sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
        sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
        sUsePrivilegeSeparation, sAllowAgentForwarding,
+       sZeroKnowledgePasswordAuthentication,
        sDeprecated, sUnsupported
 } ServerOpCodes;
 
@@ -368,6 +372,11 @@ static struct {
        { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
        { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
        { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
+#ifdef JPAKE
+       { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
+#else
+       { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
+#endif
        { "checkmail", sDeprecated, SSHCFG_GLOBAL },
        { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
        { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
@@ -380,7 +389,7 @@ static struct {
        { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
        { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
        { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
-       { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
+       { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
        { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
        { "uselogin", sUseLogin, SSHCFG_GLOBAL },
        { "compression", sCompression, SSHCFG_GLOBAL },
@@ -451,7 +460,7 @@ parse_token(const char *cp, const char *filename,
 }
 
 static void
-add_listen_addr(ServerOptions *options, char *addr, u_short port)
+add_listen_addr(ServerOptions *options, char *addr, int port)
 {
        u_int i;
 
@@ -467,7 +476,7 @@ add_listen_addr(ServerOptions *options, char *addr, u_short port)
 }
 
 static void
-add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
+add_one_listen_addr(ServerOptions *options, char *addr, int port)
 {
        struct addrinfo hints, *ai, *aitop;
        char strport[NI_MAXSERV];
@@ -477,7 +486,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
        hints.ai_family = options->address_family;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
-       snprintf(strport, sizeof strport, "%u", port);
+       snprintf(strport, sizeof strport, "%d", port);
        if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
                fatal("bad addr or host: %s (%s)",
                    addr ? addr : "<NULL>",
@@ -633,7 +642,7 @@ process_server_config_line(ServerOptions *options, char *line,
        SyslogFacility *log_facility_ptr;
        LogLevel *log_level_ptr;
        ServerOpCodes opcode;
-       u_short port;
+       int port;
        u_int i, flags = 0;
        size_t len;
 
@@ -690,7 +699,7 @@ process_server_config_line(ServerOptions *options, char *line,
                        fatal("%s line %d: missing port number.",
                            filename, linenum);
                options->ports[options->num_ports++] = a2port(arg);
-               if (options->ports[options->num_ports-1] == 0)
+               if (options->ports[options->num_ports-1] <= 0)
                        fatal("%s line %d: Badly formatted port number.",
                            filename, linenum);
                break;
@@ -743,7 +752,7 @@ process_server_config_line(ServerOptions *options, char *line,
                p = cleanhostname(p);
                if (arg == NULL)
                        port = 0;
-               else if ((port = a2port(arg)) == 0)
+               else if ((port = a2port(arg)) <= 0)
                        fatal("%s line %d: bad port number", filename, linenum);
 
                add_listen_addr(options, p, port);
@@ -890,6 +899,10 @@ process_server_config_line(ServerOptions *options, char *line,
                intptr = &options->password_authentication;
                goto parse_flag;
 
+       case sZeroKnowledgePasswordAuthentication:
+               intptr = &options->zero_knowledge_password_authentication;
+               goto parse_flag;
+
        case sKbdInteractiveAuthentication:
                intptr = &options->kbd_interactive_authentication;
                goto parse_flag;
@@ -1252,7 +1265,7 @@ process_server_config_line(ServerOptions *options, char *line,
                                fatal("%s line %d: missing host in PermitOpen",
                                    filename, linenum);
                        p = cleanhostname(p);
-                       if (arg == NULL || (port = a2port(arg)) == 0)
+                       if (arg == NULL || (port = a2port(arg)) <= 0)
                                fatal("%s line %d: bad port number in "
                                    "PermitOpen", filename, linenum);
                        if (*activep && n == -1)
@@ -1377,7 +1390,9 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
        M_CP_INTOPT(kerberos_authentication);
        M_CP_INTOPT(hostbased_authentication);
        M_CP_INTOPT(kbd_interactive_authentication);
+       M_CP_INTOPT(zero_knowledge_password_authentication);
        M_CP_INTOPT(permit_root_login);
+       M_CP_INTOPT(permit_empty_passwd);
 
        M_CP_INTOPT(allow_tcp_forwarding);
        M_CP_INTOPT(allow_agent_forwarding);
@@ -1439,7 +1454,7 @@ fmt_intarg(ServerOpCodes code, int val)
        if (code == sPermitRootLogin) {
                switch (val) {
                case PERMIT_NO_PASSWD:
-                       return "without-passord";
+                       return "without-password";
                case PERMIT_FORCED_ONLY:
                        return "forced-commands-only";
                case PERMIT_YES:
@@ -1544,11 +1559,15 @@ dump_config(ServerOptions *o)
        }
 
        /* integer arguments */
+#ifdef USE_PAM
+       dump_cfg_int(sUsePAM, o->use_pam);
+#endif
        dump_cfg_int(sServerKeyBits, o->server_key_bits);
        dump_cfg_int(sLoginGraceTime, o->login_grace_time);
        dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
        dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
        dump_cfg_int(sMaxAuthTries, o->max_authtries);
+       dump_cfg_int(sMaxSessions, o->max_sessions);
        dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
        dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
 
@@ -1562,12 +1581,22 @@ dump_config(ServerOptions *o)
            o->hostbased_uses_name_from_packet_only);
        dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
        dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
+#ifdef KRB5
        dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
        dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
        dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
+# ifdef USE_AFS
        dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
+# endif
+#endif
+#ifdef GSSAPI
        dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
        dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
+#endif
+#ifdef JPAKE
+       dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
+           o->zero_knowledge_password_authentication);
+#endif
        dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
        dump_cfg_fmtint(sKbdInteractiveAuthentication,
            o->kbd_interactive_authentication);
@@ -1626,7 +1655,5 @@ dump_config(ServerOptions *o)
                }
        dump_cfg_string(sPermitTunnel, s);
 
-       printf("permitopen");
        channel_print_adm_permitted_opens();
-       printf("\n");
 }
index 40ac64f..b3ac7da 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.85 2008/06/10 04:50:25 dtucker Exp $ */
+/* $OpenBSD: servconf.h,v 1.87 2009/01/22 10:02:34 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -41,9 +41,9 @@
 #define INTERNAL_SFTP_NAME     "internal-sftp"
 
 typedef struct {
-       u_int num_ports;
-       u_int ports_from_cmdline;
-       u_short ports[MAX_PORTS];       /* Port number to listen on. */
+       u_int   num_ports;
+       u_int   ports_from_cmdline;
+       int     ports[MAX_PORTS];       /* Port number to listen on. */
        char   *listen_addr;            /* Address on which the server listens. */
        struct addrinfo *listen_addrs;  /* Addresses on which the server listens. */
        int     address_family;         /* Address family used by the server. */
@@ -96,6 +96,8 @@ typedef struct {
                                                 * authentication. */
        int     kbd_interactive_authentication; /* If true, permit */
        int     challenge_response_authentication;
+       int     zero_knowledge_password_authentication;
+                                       /* If true, permit jpake auth */
        int     permit_empty_passwd;    /* If false, do not permit empty
                                         * passwords. */
        int     permit_user_env;        /* If true, read ~/.ssh/environment */
index 77d9dee..81cafe6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.153 2008/06/30 12:15:39 djm Exp $ */
+/* $OpenBSD: serverloop.c,v 1.157 2009/02/12 03:16:01 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -942,7 +942,7 @@ server_request_direct_tcpip(void)
 {
        Channel *c;
        char *target, *originator;
-       int target_port, originator_port;
+       u_short target_port, originator_port;
 
        target = packet_get_string(NULL);
        target_port = packet_get_int();
@@ -1095,7 +1095,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
 {
        char *rtype;
        int want_reply;
-       int success = 0;
+       int success = 0, allocated_listen_port = 0;
 
        rtype = packet_get_string(NULL);
        want_reply = packet_get_char();
@@ -1117,7 +1117,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
 
                /* check permissions */
                if (!options.allow_tcp_forwarding ||
-                   no_port_forwarding_flag
+                   no_port_forwarding_flag ||
+                   (!want_reply && listen_port == 0)
 #ifndef NO_IPPORT_RESERVED_CONCEPT
                    || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)
 #endif
@@ -1127,7 +1128,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
                } else {
                        /* Start listening on the port */
                        success = channel_setup_remote_fwd_listener(
-                           listen_address, listen_port, options.gateway_ports);
+                           listen_address, listen_port,
+                           &allocated_listen_port, options.gateway_ports);
                }
                xfree(listen_address);
        } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
@@ -1149,6 +1151,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
        if (want_reply) {
                packet_start(success ?
                    SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
+               if (success && allocated_listen_port > 0)
+                       packet_put_int(allocated_listen_port);
                packet_send();
                packet_write_wait();
        }
@@ -1202,9 +1206,9 @@ server_init_dispatch_20(void)
        dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
        dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
        dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
-       dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
-       dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
        /* client_alive */
+       dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive);
+       dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
        dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
        dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
        /* rekeying */
index 93babf9..f2549e0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.241 2008/06/16 13:22:53 dtucker Exp $ */
+/* $OpenBSD: session.c,v 1.245 2009/01/22 09:46:01 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
 #include <kafs.h>
 #endif
 
+#define IS_INTERNAL_SFTP(c) \
+       (!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
+        (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
+         c[sizeof(INTERNAL_SFTP_NAME) - 1] == ' ' || \
+         c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\t'))
+
 /* func */
 
 Session *session_new(void);
@@ -228,7 +234,7 @@ auth_input_request_forwarding(struct passwd * pw)
            SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
            CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
            0, "auth socket", 1);
-       strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
+       nc->path = xstrdup(auth_sock_name);
        return 1;
 
  authsock_err:
@@ -781,7 +787,7 @@ do_exec(Session *s, const char *command)
        if (options.adm_forced_command) {
                original_command = command;
                command = options.adm_forced_command;
-               if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
+               if (IS_INTERNAL_SFTP(command))
                        s->is_subsystem = SUBSYSTEM_INT_SFTP;
                else if (s->is_subsystem)
                        s->is_subsystem = SUBSYSTEM_EXT;
@@ -789,7 +795,7 @@ do_exec(Session *s, const char *command)
        } else if (forced_command) {
                original_command = command;
                command = forced_command;
-               if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
+               if (IS_INTERNAL_SFTP(command))
                        s->is_subsystem = SUBSYSTEM_INT_SFTP;
                else if (s->is_subsystem)
                        s->is_subsystem = SUBSYSTEM_EXT;
@@ -926,7 +932,7 @@ check_quietlogin(Session *s, const char *command)
 
 /*
  * Sets the value of the given variable in the environment.  If the variable
- * already exists, its value is overriden.
+ * already exists, its value is overridden.
  */
 void
 child_set_env(char ***envp, u_int *envsizep, const char *name,
@@ -1789,7 +1795,7 @@ do_child(Session *s, const char *command)
                char *p, *args;
 
                setproctitle("%s@internal-sftp-server", s->pw->pw_name);
-               args = strdup(command ? command : "sftp-server");
+               args = xstrdup(command ? command : "sftp-server");
                for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
                        if (i < ARGV_MAX - 1)
                                argv[i++] = p;
index 2b14569..7e644ab 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-server-main.c,v 1.3 2008/03/26 23:44:41 djm Exp $ */
+/* $OpenBSD: sftp-server-main.c,v 1.4 2009/02/21 19:32:04 tobias Exp $ */
 /*
  * Copyright (c) 2008 Markus Friedl.  All rights reserved.
  *
@@ -42,7 +42,8 @@ main(int argc, char **argv)
        sanitise_stdfd();
 
        if ((user_pw = getpwuid(getuid())) == NULL) {
-               fprintf(stderr, "No user found for uid %lu", (u_long)getuid());
+               fprintf(stderr, "No user found for uid %lu\n",
+                   (u_long)getuid());
                return 1;
        }
 
index b4f9a68..37ccb3a 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.67 2008/07/15 02:23:14 djm Exp $
+.\" $OpenBSD: sftp.1,v 1.69 2008/12/09 15:35:00 sobrado Exp $
 .\"
 .\" Copyright (c) 2001 Damien Miller.  All rights reserved.
 .\"
@@ -22,7 +22,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: July 15 2008 $
+.Dd $Mdocdate: December 9 2008 $
 .Dt SFTP 1
 .Os
 .Sh NAME
 .Ar host
 .Ek
 .Nm sftp
-.Oo Oo Ar user Ns @ Oc Ns
-.Ar host Ns Oo : Ns Ar file Oo
-.Ar file Oc Oc Oc
+.Oo Ar user Ns @ Oc Ns
+.Ar host Ns Op : Ns Ar
 .Nm sftp
-.Oo Oo Ar user Ns @ Oc Ns
+.Oo Ar user Ns @ Oc Ns
 .Ar host Ns Oo : Ns Ar dir Ns
-.Oo Ar / Oc Oc Oc
+.Op Ar / Oc
 .Nm sftp
 .Fl b Ar batchfile
 .Oo Ar user Ns @ Oc Ns Ar host
@@ -442,7 +441,7 @@ to
 Display the
 .Nm
 protocol version.
-.It Ic \&! Ar command
+.It Ic \&! Ns Ar command
 Execute
 .Ar command
 in local shell.
index e1aa49d..66bd111 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.103 2008/07/13 22:16:03 djm Exp $ */
+/* $OpenBSD: sftp.c,v 1.107 2009/02/02 11:15:14 dtucker Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
  *
@@ -207,36 +207,37 @@ cmd_interrupt(int signo)
 static void
 help(void)
 {
-       printf("Available commands:\n");
-       printf("cd path                       Change remote directory to 'path'\n");
-       printf("lcd path                      Change local directory to 'path'\n");
-       printf("chgrp grp path                Change group of file 'path' to 'grp'\n");
-       printf("chmod mode path               Change permissions of file 'path' to 'mode'\n");
-       printf("chown own path                Change owner of file 'path' to 'own'\n");
-       printf("df [path]                     Display statistics for current directory or\n");
-       printf("                              filesystem containing 'path'\n");
-       printf("help                          Display this help text\n");
-       printf("get remote-path [local-path]  Download file\n");
-       printf("lls [ls-options [path]]       Display local directory listing\n");
-       printf("ln oldpath newpath            Symlink remote file\n");
-       printf("lmkdir path                   Create local directory\n");
-       printf("lpwd                          Print local working directory\n");
-       printf("ls [path]                     Display remote directory listing\n");
-       printf("lumask umask                  Set local umask to 'umask'\n");
-       printf("mkdir path                    Create remote directory\n");
-       printf("progress                      Toggle display of progress meter\n");
-       printf("put local-path [remote-path]  Upload file\n");
-       printf("pwd                           Display remote working directory\n");
-       printf("exit                          Quit sftp\n");
-       printf("quit                          Quit sftp\n");
-       printf("rename oldpath newpath        Rename remote file\n");
-       printf("rmdir path                    Remove remote directory\n");
-       printf("rm path                       Delete remote file\n");
-       printf("symlink oldpath newpath       Symlink remote file\n");
-       printf("version                       Show SFTP version\n");
-       printf("!command                      Execute 'command' in local shell\n");
-       printf("!                             Escape to local shell\n");
-       printf("?                             Synonym for help\n");
+       printf("Available commands:\n"
+           "bye                                Quit sftp\n"
+           "cd path                            Change remote directory to 'path'\n"
+           "chgrp grp path                     Change group of file 'path' to 'grp'\n"
+           "chmod mode path                    Change permissions of file 'path' to 'mode'\n"
+           "chown own path                     Change owner of file 'path' to 'own'\n"
+           "df [-hi] [path]                    Display statistics for current directory or\n"
+           "                                   filesystem containing 'path'\n"
+           "exit                               Quit sftp\n"
+           "get [-P] remote-path [local-path]  Download file\n"
+           "help                               Display this help text\n"
+           "lcd path                           Change local directory to 'path'\n"
+           "lls [ls-options [path]]            Display local directory listing\n"
+           "lmkdir path                        Create local directory\n"
+           "ln oldpath newpath                 Symlink remote file\n"
+           "lpwd                               Print local working directory\n"
+           "ls [-1aflnrSt] [path]              Display remote directory listing\n"
+           "lumask umask                       Set local umask to 'umask'\n"
+           "mkdir path                         Create remote directory\n"
+           "progress                           Toggle display of progress meter\n"
+           "put [-P] local-path [remote-path]  Upload file\n"
+           "pwd                                Display remote working directory\n"
+           "quit                               Quit sftp\n"
+           "rename oldpath newpath             Rename remote file\n"
+           "rm path                            Delete remote file\n"
+           "rmdir path                         Remove remote directory\n"
+           "symlink oldpath newpath            Symlink remote file\n"
+           "version                            Show SFTP version\n"
+           "!command                           Execute 'command' in local shell\n"
+           "!                                  Escape to local shell\n"
+           "?                                  Synonym for help\n");
 }
 
 static void
@@ -1234,8 +1235,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
     int err_abort)
 {
        char *path1, *path2, *tmp;
-       int pflag, lflag, iflag, hflag, cmdnum, i;
-       unsigned long n_arg;
+       int pflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i;
+       unsigned long n_arg = 0;
        Attrib a, *aa;
        char path_buf[MAXPATHLEN];
        int err = 0;
@@ -1386,17 +1387,19 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
                remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
                for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
                        if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
-                               if (err != 0 && err_abort)
+                               if (err_abort) {
+                                       err = -1;
                                        break;
-                               else
+                               else
                                        continue;
                        }
                        if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
                                error("Can't get current ownership of "
                                    "remote file \"%s\"", g.gl_pathv[i]);
-                               if (err != 0 && err_abort)
+                               if (err_abort) {
+                                       err = -1;
                                        break;
-                               else
+                               else
                                        continue;
                        }
                        aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
@@ -1668,8 +1671,8 @@ usage(void)
            "usage: %s [-1Cv] [-B buffer_size] [-b batchfile] [-F ssh_config]\n"
            "            [-o ssh_option] [-P sftp_server_path] [-R num_requests]\n"
            "            [-S program] [-s subsystem | sftp_server] host\n"
-           "       %s [[user@]host[:file [file]]]\n"
-           "       %s [[user@]host[:dir[/]]]\n"
+           "       %s [user@]host[:file ...]\n"
+           "       %s [user@]host[:dir[/]]\n"
            "       %s -b batchfile [user@]host\n", __progname, __progname, __progname, __progname);
        exit(1);
 }
index 3fff59e..3596cc1 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ssh-keygen.1,v 1.78 2008/06/12 19:10:09 jmc Exp $
+.\"    $OpenBSD: ssh-keygen.1,v 1.79 2008/07/24 23:55:30 sthen Exp $
 .\"
 .\"  -*- nroff -*-
 .\"
@@ -37,7 +37,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: June 12 2008 $
+.Dd $Mdocdate: July 24 2008 $
 .Dt SSH-KEYGEN 1
 .Os
 .Sh NAME
@@ -83,6 +83,7 @@
 .Nm ssh-keygen
 .Fl F Ar hostname
 .Op Fl f Ar known_hosts_file
+.Op Fl l
 .Nm ssh-keygen
 .Fl H
 .Op Fl f Ar known_hosts_file
index f7e2840..5765cff 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.171 2008/07/13 21:22:52 sthen Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.173 2009/02/21 19:32:04 tobias Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -135,7 +135,7 @@ ask_filename(struct passwd *pw, const char *prompt)
                        name = _PATH_SSH_CLIENT_ID_RSA;
                        break;
                default:
-                       fprintf(stderr, "bad key type");
+                       fprintf(stderr, "bad key type\n");
                        exit(1);
                        break;
                }
@@ -421,7 +421,7 @@ do_convert_from_ssh2(struct passwd *pw)
                 PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) :
            key_write(k, stdout);
        if (!ok) {
-               fprintf(stderr, "key write failed");
+               fprintf(stderr, "key write failed\n");
                exit(1);
        }
        key_free(k);
@@ -1015,11 +1015,11 @@ do_change_comment(struct passwd *pw)
        }
        f = fdopen(fd, "w");
        if (f == NULL) {
-               printf("fdopen %s failed", identity_file);
+               printf("fdopen %s failed\n", identity_file);
                exit(1);
        }
        if (!key_write(public, f))
-               fprintf(stderr, "write key failed");
+               fprintf(stderr, "write key failed\n");
        key_free(public);
        fprintf(f, " %s\n", new_comment);
        fclose(f);
@@ -1366,7 +1366,7 @@ main(int argc, char **argv)
                printf("Generating public/private %s key pair.\n", key_type_name);
        private = key_generate(type, bits);
        if (private == NULL) {
-               fprintf(stderr, "key_generate failed");
+               fprintf(stderr, "key_generate failed\n");
                exit(1);
        }
        public  = key_from_private(private);
@@ -1426,7 +1426,7 @@ passphrase_again:
        if (identity_comment) {
                strlcpy(comment, identity_comment, sizeof(comment));
        } else {
-               /* Create default commend field for the passphrase. */
+               /* Create default comment field for the passphrase. */
                snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
        }
 
@@ -1456,11 +1456,11 @@ passphrase_again:
        }
        f = fdopen(fd, "w");
        if (f == NULL) {
-               printf("fdopen %s failed", identity_file);
+               printf("fdopen %s failed\n", identity_file);
                exit(1);
        }
        if (!key_write(public, f))
-               fprintf(stderr, "write key failed");
+               fprintf(stderr, "write key failed\n");
        fprintf(f, " %s\n", comment);
        fclose(f);
 
index 8a4f3bc..4a58645 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ssh-keyscan.1,v 1.24 2008/04/30 10:14:03 djm Exp $
+.\"    $OpenBSD: ssh-keyscan.1,v 1.26 2008/12/29 01:12:36 stevesk Exp $
 .\"
 .\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
 .\"
@@ -6,7 +6,7 @@
 .\" permitted provided that due credit is given to the author and the
 .\" OpenBSD project by leaving this copyright notice intact.
 .\"
-.Dd $Mdocdate: April 30 2008 $
+.Dd $Mdocdate: December 29 2008 $
 .Dt SSH-KEYSCAN 1
 .Os
 .Sh NAME
@@ -21,7 +21,7 @@
 .Op Fl T Ar timeout
 .Op Fl t Ar type
 .Op Ar host | addrlist namelist
-.Op Ar ...
+.Ar ...
 .Ek
 .Sh DESCRIPTION
 .Nm
@@ -137,7 +137,7 @@ or
 .Pa /etc/ssh/ssh_known_hosts
 .Sh EXAMPLES
 Print the
-.Pa rsa1
+.Pa rsa
 host key for machine
 .Pa hostname :
 .Bd -literal
index d810777..9a91be4 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.76 2008/04/30 10:14:03 djm Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.78 2009/01/22 10:02:34 djm Exp $ */
 /*
  * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
  *
@@ -713,8 +713,9 @@ fatal(const char *fmt,...)
 static void
 usage(void)
 {
-       fprintf(stderr, "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n"
-           "\t\t   [host | addrlist namelist] [...]\n",
+       fprintf(stderr,
+           "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n"
+           "\t\t   [host | addrlist namelist] ...\n",
            __progname);
        exit(1);
 }
@@ -747,7 +748,7 @@ main(int argc, char **argv)
                        break;
                case 'p':
                        ssh_port = a2port(optarg);
-                       if (ssh_port == 0) {
+                       if (ssh_port <= 0) {
                                fprintf(stderr, "Bad port '%s'\n", optarg);
                                exit(1);
                        }
index 1883578..421783b 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh.1,v 1.277 2008/07/02 13:47:39 djm Exp $
-.Dd $Mdocdate: July 2 2008 $
+.\" $OpenBSD: ssh.1,v 1.282 2009/02/12 03:44:25 djm Exp $
+.Dd $Mdocdate: February 12 2009 $
 .Dt SSH 1
 .Os
 .Sh NAME
@@ -43,7 +43,7 @@
 .Nd OpenSSH SSH client (remote login program)
 .Sh SYNOPSIS
 .Nm ssh
-.Op Fl 1246AaCfgKkMNnqsTtVvXxY
+.Op Fl 1246AaCfgKkMNnqsTtVvXxYy
 .Op Fl b Ar bind_address
 .Op Fl c Ar cipher_spec
 .Oo Fl D\ \&
@@ -550,7 +550,7 @@ using an alternative syntax:
 .Pp
 By default, the listening socket on the server will be bound to the loopback
 interface only.
-This may be overriden by specifying a
+This may be overridden by specifying a
 .Ar bind_address .
 An empty
 .Ar bind_address ,
@@ -563,6 +563,13 @@ will only succeed if the server's
 .Cm GatewayPorts
 option is enabled (see
 .Xr sshd_config 5 ) .
+.Pp
+If the
+.Ar port
+argument is
+.Ql 0 ,
+the listen port will be dynamically allocated on the server and reported
+to the client at run time.
 .It Fl S Ar ctl_path
 Specifies the location of a control socket for connection sharing.
 Refer to the description of
@@ -658,6 +665,11 @@ Disables X11 forwarding.
 Enables trusted X11 forwarding.
 Trusted X11 forwardings are not subjected to the X11 SECURITY extension
 controls.
+.It Fl y
+Send log information using the
+.Xr syslog 3
+system module.
+By default this information is sent to stderr.
 .El
 .Pp
 .Nm
@@ -893,9 +905,10 @@ Send a BREAK to the remote system
 .It Cm ~C
 Open command line.
 Currently this allows the addition of port forwardings using the
-.Fl L
-and
+.Fl L ,
 .Fl R
+and
+.Fl D
 options (see above).
 It also allows the cancellation of existing remote port-forwardings
 using
index e2dd67d..9d43bb7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.318 2008/07/02 13:47:39 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.324 2009/02/12 03:00:56 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -179,7 +179,7 @@ static void
 usage(void)
 {
        fprintf(stderr,
-"usage: ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
+"usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
 "           [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
 "           [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
 "           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
@@ -203,7 +203,7 @@ void muxserver_listen(void);
 int
 main(int ac, char **av)
 {
-       int i, opt, exit_status;
+       int i, opt, exit_status, use_syslog;
        char *p, *cp, *line, buf[256];
        struct stat st;
        struct passwd *pw;
@@ -269,10 +269,11 @@ main(int ac, char **av)
 
        /* Parse command-line arguments. */
        host = NULL;
+       use_syslog = 0;
 
  again:
        while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
-           "ACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) {
+           "ACD:F:I:KL:MNO:PR:S:TVw:XYy")) != -1) {
                switch (opt) {
                case '1':
                        options.protocol = SSH_PROTO_1;
@@ -299,6 +300,9 @@ main(int ac, char **av)
                case 'X':
                        options.forward_x11 = 1;
                        break;
+               case 'y':
+                       use_syslog = 1;
+                       break;
                case 'Y':
                        options.forward_x11 = 1;
                        options.forward_x11_trusted = 1;
@@ -439,7 +443,7 @@ main(int ac, char **av)
                        break;
                case 'p':
                        options.port = a2port(optarg);
-                       if (options.port == 0) {
+                       if (options.port <= 0) {
                                fprintf(stderr, "Bad port '%s'\n", optarg);
                                exit(255);
                        }
@@ -449,7 +453,7 @@ main(int ac, char **av)
                        break;
 
                case 'L':
-                       if (parse_forward(&fwd, optarg))
+                       if (parse_forward(&fwd, optarg, 0, 0))
                                add_local_forward(&options, &fwd);
                        else {
                                fprintf(stderr,
@@ -460,7 +464,7 @@ main(int ac, char **av)
                        break;
 
                case 'R':
-                       if (parse_forward(&fwd, optarg)) {
+                       if (parse_forward(&fwd, optarg, 0, 1)) {
                                add_remote_forward(&options, &fwd);
                        } else {
                                fprintf(stderr,
@@ -471,30 +475,14 @@ main(int ac, char **av)
                        break;
 
                case 'D':
-                       cp = p = xstrdup(optarg);
-                       memset(&fwd, '\0', sizeof(fwd));
-                       fwd.connect_host = "socks";
-                       if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
-                               fprintf(stderr, "Bad dynamic forwarding "
-                                   "specification '%.100s'\n", optarg);
-                               exit(255);
-                       }
-                       if (cp != NULL) {
-                               fwd.listen_port = a2port(cp);
-                               fwd.listen_host =
-                                   cleanhostname(fwd.listen_host);
+                       if (parse_forward(&fwd, optarg, 1, 0)) {
+                               add_local_forward(&options, &fwd);
                        } else {
-                               fwd.listen_port = a2port(fwd.listen_host);
-                               fwd.listen_host = NULL;
-                       }
-
-                       if (fwd.listen_port == 0) {
-                               fprintf(stderr, "Bad dynamic port '%s'\n",
-                                   optarg);
+                               fprintf(stderr,
+                                   "Bad dynamic forwarding specification "
+                                   "'%s'\n", optarg);
                                exit(255);
                        }
-                       add_local_forward(&options, &fwd);
-                       xfree(p);
                        break;
 
                case 'C':
@@ -614,7 +602,7 @@ main(int ac, char **av)
         */
        log_init(av[0],
            options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
-           SYSLOG_FACILITY_USER, 1);
+           SYSLOG_FACILITY_USER, !use_syslog);
 
        /*
         * Read per-user configuration file.  Ignore the system wide config
@@ -640,7 +628,7 @@ main(int ac, char **av)
        channel_set_af(options.address_family);
 
        /* reinit */
-       log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1);
+       log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
 
        seed_rng();
 
@@ -849,9 +837,16 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
 {
        Forward *rfwd = (Forward *)ctxt;
 
+       /* XXX verbose() on failure? */
        debug("remote forward %s for: listen %d, connect %s:%d",
            type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
            rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
+       if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) {
+               logit("Allocated port %u for remote forward to %s:%d",
+                       packet_get_int(),
+                       rfwd->connect_host, rfwd->connect_port);
+       }
+       
        if (type == SSH2_MSG_REQUEST_FAILURE) {
                if (options.exit_on_forward_failure)
                        fatal("Error: remote port forwarding failed for "
@@ -1200,7 +1195,8 @@ ssh_session2(void)
                id = ssh_session2_open();
 
        /* If we don't expect to open a new session, then disallow it */
-       if (options.control_master == SSHCTL_MASTER_NO) {
+       if (options.control_master == SSHCTL_MASTER_NO &&
+           (datafellows & SSH_NEW_OPENSSH)) {
                debug("Requesting no-more-sessions@openssh.com");
                packet_start(SSH2_MSG_GLOBAL_REQUEST);
                packet_put_cstring("no-more-sessions@openssh.com");
index cf56bc4..1c33dc2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh2.h,v 1.10 2006/03/25 22:22:43 djm Exp $ */
+/* $OpenBSD: ssh2.h,v 1.11 2008/11/04 08:22:13 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
 #define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ             60
 #define SSH2_MSG_USERAUTH_INFO_REQUEST                 60
 #define SSH2_MSG_USERAUTH_INFO_RESPONSE                        61
+#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1           60
+#define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1           61
+#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2           62
+#define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2           63
+#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM         64
+#define SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM         65
 
 /* connection protocol: generic */
 
 #define SSH2_OPEN_RESOURCE_SHORTAGE                    4
 
 #define SSH2_EXTENDED_DATA_STDERR                      1
+
index 8cb0698..f28d595 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: ssh_config,v 1.23 2007/06/08 04:40:40 pvalchev Exp $
+#      $OpenBSD: ssh_config,v 1.25 2009/02/17 01:28:32 djm Exp $
 
 # This is the ssh client system-wide configuration file.  See
 # ssh_config(5) for more information.  This file provides defaults for
 #   Port 22
 #   Protocol 2,1
 #   Cipher 3des
-#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
 #   MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
 #   EscapeChar ~
 #   Tunnel no
 #   TunnelDevice any:any
 #   PermitLocalCommand no
+#   VisualHostKey no
index 85e7ba0..ea9a20b 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.111 2008/06/26 11:46:31 grunk Exp $
-.Dd $Mdocdate: June 26 2008 $
+.\" $OpenBSD: ssh_config.5,v 1.119 2009/02/22 23:50:57 djm Exp $
+.Dd $Mdocdate: February 22 2009 $
 .Dt SSH_CONFIG 5
 .Os
 .Sh NAME
@@ -103,7 +103,7 @@ Restricts the following declarations (up to the next
 .Cm Host
 keyword) to be only for those hosts that match one of the patterns
 given after the keyword.
-If more than one pattern is provided, they should be separated by whitepsace.
+If more than one pattern is provided, they should be separated by whitespace.
 A single
 .Ql *
 as a pattern can be used to provide global
@@ -204,9 +204,9 @@ and
 .Dq cast128-cbc .
 The default is:
 .Bd -literal -offset 3n
-aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-aes192-ctr,aes256-ctr
+aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,
+aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,
+aes256-cbc,arcfour
 .Ed
 .It Cm ClearAllForwardings
 Specifies that all local, remote, and dynamic port forwardings
@@ -811,7 +811,15 @@ and
 .Ar host Ns / Ns Ar hostport .
 Multiple forwardings may be specified, and additional
 forwardings can be given on the command line.
-Only the superuser can forward privileged ports.
+Privileged ports can be forwarded only when
+logging in as root on the remote machine.
+.Pp
+If the
+.Ar port
+argument is
+.Ql 0 ,
+the listen port will be dynamically allocated on the server and reported
+to the client at run time.
 .Pp
 If the
 .Ar bind_address
@@ -1064,10 +1072,12 @@ in
 If this flag is set to
 .Dq yes ,
 an ASCII art representation of the remote host key fingerprint is
-printed additionally to the hex fingerprint string.
+printed in addition to the hex fingerprint string at login and
+for unknown host keys.
 If this flag is set to
 .Dq no ,
-only the hex fingerprint string will be printed.
+no fingerprint strings are printed at login and
+only the hex fingerprint string will be printed for unknown host keys.
 The default is
 .Dq no .
 .It Cm XAuthLocation
index ec8ba33..c04aa10 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.211 2008/07/01 07:24:22 dtucker Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.212 2008/10/14 18:11:33 stevesk Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -70,10 +70,6 @@ extern uid_t original_real_uid;
 extern uid_t original_effective_uid;
 extern pid_t proxy_command_pid;
 
-#ifndef INET6_ADDRSTRLEN               /* for non IPv6 machines */
-#define INET6_ADDRSTRLEN 46
-#endif
-
 static int show_other_keys(const char *, Key *);
 static void warn_changed_key(Key *);
 
@@ -741,8 +737,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
                if (options.host_key_alias == NULL && port != 0 &&
                    port != SSH_DEFAULT_PORT) {
                        debug("checking without port identifier");
-                       if (check_host_key(hostname, hostaddr, 0, host_key, 2,
-                           user_hostfile, system_hostfile) == 0) {
+                       if (check_host_key(hostname, hostaddr, 0, host_key,
+                           ROQUIET, user_hostfile, system_hostfile) == 0) {
                                debug("found matching key w/out port");
                                break;
                        }
index 389bec9..a762eec 100644 (file)
@@ -1,6 +1,7 @@
-/* $OpenBSD: sshconnect2.c,v 1.166 2008/07/17 08:48:00 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.170 2008/11/04 08:22:13 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2008 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -67,6 +68,7 @@
 #include "msg.h"
 #include "pathnames.h"
 #include "uidswap.h"
+#include "jpake.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
@@ -201,6 +203,7 @@ struct Authctxt {
 struct Authmethod {
        char    *name;          /* string to compare against server's list */
        int     (*userauth)(Authctxt *authctxt);
+       void    (*cleanup)(Authctxt *authctxt);
        int     *enabled;       /* flag in option struct that enables method */
        int     *batch_flag;    /* flag in option struct that disables method */
 };
@@ -212,13 +215,18 @@ void      input_userauth_error(int, u_int32_t, void *);
 void   input_userauth_info_req(int, u_int32_t, void *);
 void   input_userauth_pk_ok(int, u_int32_t, void *);
 void   input_userauth_passwd_changereq(int, u_int32_t, void *);
+void   input_userauth_jpake_server_step1(int, u_int32_t, void *);
+void   input_userauth_jpake_server_step2(int, u_int32_t, void *);
+void   input_userauth_jpake_server_confirm(int, u_int32_t, void *);
 
 int    userauth_none(Authctxt *);
 int    userauth_pubkey(Authctxt *);
 int    userauth_passwd(Authctxt *);
 int    userauth_kbdint(Authctxt *);
 int    userauth_hostbased(Authctxt *);
-int    userauth_kerberos(Authctxt *);
+int    userauth_jpake(Authctxt *);
+
+void   userauth_jpake_cleanup(Authctxt *);
 
 #ifdef GSSAPI
 int    userauth_gssapi(Authctxt *authctxt);
@@ -244,30 +252,43 @@ Authmethod authmethods[] = {
 #ifdef GSSAPI
        {"gssapi-with-mic",
                userauth_gssapi,
+               NULL,
                &options.gss_authentication,
                NULL},
 #endif
        {"hostbased",
                userauth_hostbased,
+               NULL,
                &options.hostbased_authentication,
                NULL},
        {"publickey",
                userauth_pubkey,
+               NULL,
                &options.pubkey_authentication,
                NULL},
+#ifdef JPAKE
+       {"jpake-01@openssh.com",
+               userauth_jpake,
+               userauth_jpake_cleanup,
+               &options.zero_knowledge_password_authentication,
+               &options.batch_mode},
+#endif
        {"keyboard-interactive",
                userauth_kbdint,
+               NULL,
                &options.kbd_interactive_authentication,
                &options.batch_mode},
        {"password",
                userauth_passwd,
+               NULL,
                &options.password_authentication,
                &options.batch_mode},
        {"none",
                userauth_none,
                NULL,
+               NULL,
                NULL},
-       {NULL, NULL, NULL, NULL}
+       {NULL, NULL, NULL, NULL, NULL}
 };
 
 void
@@ -335,6 +356,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
 void
 userauth(Authctxt *authctxt, char *authlist)
 {
+       if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
+               authctxt->method->cleanup(authctxt);
+
        if (authctxt->methoddata) {
                xfree(authctxt->methoddata);
                authctxt->methoddata = NULL;
@@ -367,6 +391,7 @@ userauth(Authctxt *authctxt, char *authlist)
        }
 }
 
+/* ARGSUSED */
 void
 input_userauth_error(int type, u_int32_t seq, void *ctxt)
 {
@@ -374,6 +399,7 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
            "type %d", type);
 }
 
+/* ARGSUSED */
 void
 input_userauth_banner(int type, u_int32_t seq, void *ctxt)
 {
@@ -383,11 +409,11 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
        debug3("input_userauth_banner");
        raw = packet_get_string(&len);
        lang = packet_get_string(NULL);
-       if (options.log_level >= SYSLOG_LEVEL_INFO) {
+       if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) {
                if (len > 65536)
                        len = 65536;
-               msg = xmalloc(len * 4); /* max expansion from strnvis() */
-               strnvis(msg, raw, len * 4, VIS_SAFE|VIS_OCTAL);
+               msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
+               strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL);
                fprintf(stderr, "%s", msg);
                xfree(msg);
        }
@@ -395,6 +421,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
        xfree(lang);
 }
 
+/* ARGSUSED */
 void
 input_userauth_success(int type, u_int32_t seq, void *ctxt)
 {
@@ -412,6 +439,7 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
        authctxt->success = 1;                  /* break out */
 }
 
+/* ARGSUSED */
 void
 input_userauth_failure(int type, u_int32_t seq, void *ctxt)
 {
@@ -432,6 +460,8 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
 
        userauth(authctxt, authlist);
 }
+
+/* ARGSUSED */
 void
 input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
 {
@@ -614,6 +644,7 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
        return status;
 }
 
+/* ARGSUSED */
 void
 input_gssapi_response(int type, u_int32_t plen, void *ctxt)
 {
@@ -653,6 +684,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
        }
 }
 
+/* ARGSUSED */
 void
 input_gssapi_token(int type, u_int32_t plen, void *ctxt)
 {
@@ -680,6 +712,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
        }
 }
 
+/* ARGSUSED */
 void
 input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
 {
@@ -709,6 +742,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
        /* Server will be returning a failed packet after this one */
 }
 
+/* ARGSUSED */
 void
 input_gssapi_error(int type, u_int32_t plen, void *ctxt)
 {
@@ -773,9 +807,11 @@ userauth_passwd(Authctxt *authctxt)
 
        return 1;
 }
+
 /*
  * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
  */
+/* ARGSUSED */
 void
 input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
 {
@@ -840,6 +876,209 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
            &input_userauth_passwd_changereq);
 }
 
+#ifdef JPAKE
+static char *
+pw_encrypt(const char *password, const char *crypt_scheme, const char *salt)
+{
+       /* OpenBSD crypt(3) handles all of these */
+       if (strcmp(crypt_scheme, "crypt") == 0 ||
+           strcmp(crypt_scheme, "bcrypt") == 0 ||
+           strcmp(crypt_scheme, "md5crypt") == 0 ||
+           strcmp(crypt_scheme, "crypt-extended") == 0)
+               return xstrdup(crypt(password, salt));
+       error("%s: unsupported password encryption scheme \"%.100s\"",
+           __func__, crypt_scheme);
+       return NULL;
+}
+
+static BIGNUM *
+jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,
+    const char *salt)
+{
+       char prompt[256], *password, *crypted;
+       u_char *secret;
+       u_int secret_len;
+       BIGNUM *ret;
+
+       snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ",
+           authctxt->server_user, authctxt->host);
+       password = read_passphrase(prompt, 0);
+
+       if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) {
+               logit("Disabling %s authentication", authctxt->method->name);
+               authctxt->method->enabled = NULL;
+               /* Continue with an empty password to fail gracefully */
+               crypted = xstrdup("");
+       }
+
+#ifdef JPAKE_DEBUG
+       debug3("%s: salt = %s", __func__, salt);
+       debug3("%s: scheme = %s", __func__, crypt_scheme);
+       debug3("%s: crypted = %s", __func__, crypted);
+#endif
+
+       if (hash_buffer(crypted, strlen(crypted), EVP_sha256(),
+           &secret, &secret_len) != 0)
+               fatal("%s: hash_buffer", __func__);
+
+       bzero(password, strlen(password));
+       bzero(crypted, strlen(crypted));
+       xfree(password);
+       xfree(crypted);
+
+       if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL)
+               fatal("%s: BN_bin2bn (secret)", __func__);
+       bzero(secret, secret_len);
+       xfree(secret);
+
+       return ret;
+}
+
+/* ARGSUSED */
+void
+input_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       struct jpake_ctx *pctx = authctxt->methoddata;
+       u_char *x3_proof, *x4_proof, *x2_s_proof;
+       u_int x3_proof_len, x4_proof_len, x2_s_proof_len;
+       char *crypt_scheme, *salt;
+
+       /* Disable this message */
+       dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL);
+
+       if ((pctx->g_x3 = BN_new()) == NULL ||
+           (pctx->g_x4 = BN_new()) == NULL)
+               fatal("%s: BN_new", __func__);
+
+       /* Fetch step 1 values */
+       crypt_scheme = packet_get_string(NULL);
+       salt = packet_get_string(NULL);
+       pctx->server_id = packet_get_string(&pctx->server_id_len);
+       packet_get_bignum2(pctx->g_x3);
+       packet_get_bignum2(pctx->g_x4);
+       x3_proof = packet_get_string(&x3_proof_len);
+       x4_proof = packet_get_string(&x4_proof_len);
+       packet_check_eom();
+
+       JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));
+
+       /* Obtain password and derive secret */
+       pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt);
+       bzero(crypt_scheme, strlen(crypt_scheme));
+       bzero(salt, strlen(salt));
+       xfree(crypt_scheme);
+       xfree(salt);
+       JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__));
+
+       /* Calculate step 2 values */
+       jpake_step2(pctx->grp, pctx->s, pctx->g_x1,
+           pctx->g_x3, pctx->g_x4, pctx->x2,
+           pctx->server_id, pctx->server_id_len,
+           pctx->client_id, pctx->client_id_len,
+           x3_proof, x3_proof_len,
+           x4_proof, x4_proof_len,
+           &pctx->a,
+           &x2_s_proof, &x2_s_proof_len);
+
+       bzero(x3_proof, x3_proof_len);
+       bzero(x4_proof, x4_proof_len);
+       xfree(x3_proof);
+       xfree(x4_proof);
+
+       JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));
+
+       /* Send values for step 2 */
+       packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2);
+       packet_put_bignum2(pctx->a);
+       packet_put_string(x2_s_proof, x2_s_proof_len);
+       packet_send();
+
+       bzero(x2_s_proof, x2_s_proof_len);
+       xfree(x2_s_proof);
+
+       /* Expect step 2 packet from peer */
+       dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2,
+           input_userauth_jpake_server_step2);
+}
+
+/* ARGSUSED */
+void
+input_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       struct jpake_ctx *pctx = authctxt->methoddata;
+       u_char *x4_s_proof;
+       u_int x4_s_proof_len;
+
+       /* Disable this message */
+       dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL);
+
+       if ((pctx->b = BN_new()) == NULL)
+               fatal("%s: BN_new", __func__);
+
+       /* Fetch step 2 values */
+       packet_get_bignum2(pctx->b);
+       x4_s_proof = packet_get_string(&x4_s_proof_len);
+       packet_check_eom();
+
+       JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));
+
+       /* Derive shared key and calculate confirmation hash */
+       jpake_key_confirm(pctx->grp, pctx->s, pctx->b,
+           pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4,
+           pctx->client_id, pctx->client_id_len,
+           pctx->server_id, pctx->server_id_len,
+           session_id2, session_id2_len,
+           x4_s_proof, x4_s_proof_len,
+           &pctx->k,
+           &pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len);
+
+       bzero(x4_s_proof, x4_s_proof_len);
+       xfree(x4_s_proof);
+
+       JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));
+
+       /* Send key confirmation proof */
+       packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM);
+       packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
+       packet_send();
+
+       /* Expect confirmation from peer */
+       dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM,
+           input_userauth_jpake_server_confirm);
+}
+
+/* ARGSUSED */
+void
+input_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       struct jpake_ctx *pctx = authctxt->methoddata;
+
+       /* Disable this message */
+       dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL);
+
+       pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len);
+       packet_check_eom();
+
+       JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));
+
+       /* Verify expected confirmation hash */
+       if (jpake_check_confirm(pctx->k,
+           pctx->server_id, pctx->server_id_len,
+           session_id2, session_id2_len,
+           pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1)
+               debug("%s: %s success", __func__, authctxt->method->name);
+       else {
+               debug("%s: confirmation mismatch", __func__);
+               /* XXX stash this so if auth succeeds then we can warn/kill */
+       }
+
+       userauth_jpake_cleanup(authctxt);
+}
+#endif /* JPAKE */
+
 static int
 identity_sign(Identity *id, u_char **sigp, u_int *lenp,
     u_char *data, u_int datalen)
@@ -1414,6 +1653,76 @@ userauth_hostbased(Authctxt *authctxt)
        return 1;
 }
 
+#ifdef JPAKE
+int
+userauth_jpake(Authctxt *authctxt)
+{
+       struct jpake_ctx *pctx;
+       u_char *x1_proof, *x2_proof;
+       u_int x1_proof_len, x2_proof_len;
+       static int attempt = 0; /* XXX share with userauth_password's? */
+
+       if (attempt++ >= options.number_of_password_prompts)
+               return 0;
+       if (attempt != 1)
+               error("Permission denied, please try again.");
+
+       if (authctxt->methoddata != NULL)
+               fatal("%s: authctxt->methoddata already set (%p)",
+                   __func__, authctxt->methoddata);
+
+       authctxt->methoddata = pctx = jpake_new();
+
+       /*
+        * Send request immediately, to get the protocol going while
+        * we do the initial computations.
+        */
+       packet_start(SSH2_MSG_USERAUTH_REQUEST);
+       packet_put_cstring(authctxt->server_user);
+       packet_put_cstring(authctxt->service);
+       packet_put_cstring(authctxt->method->name);
+       packet_send();
+       packet_write_wait();
+
+       jpake_step1(pctx->grp,
+           &pctx->client_id, &pctx->client_id_len,
+           &pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2,
+           &x1_proof, &x1_proof_len,
+           &x2_proof, &x2_proof_len);
+
+       JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));
+
+       packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1);
+       packet_put_string(pctx->client_id, pctx->client_id_len);
+       packet_put_bignum2(pctx->g_x1);
+       packet_put_bignum2(pctx->g_x2);
+       packet_put_string(x1_proof, x1_proof_len);
+       packet_put_string(x2_proof, x2_proof_len);
+       packet_send();
+
+       bzero(x1_proof, x1_proof_len);
+       bzero(x2_proof, x2_proof_len);
+       xfree(x1_proof);
+       xfree(x2_proof);
+
+       /* Expect step 1 packet from peer */
+       dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1,
+           input_userauth_jpake_server_step1);
+
+       return 1;
+}
+
+void
+userauth_jpake_cleanup(Authctxt *authctxt)
+{
+       debug3("%s: clean up", __func__);
+       if (authctxt->methoddata != NULL) {
+               jpake_free(authctxt->methoddata);
+               authctxt->methoddata = NULL;
+       }
+}
+#endif /* JPAKE */
+
 /* find auth method */
 
 /*
@@ -1515,3 +1824,4 @@ authmethods_get(void)
        buffer_free(&b);
        return list;
 }
+
index c4c4181..a4b9e90 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd.8,v 1.246 2008/07/02 02:24:18 djm Exp $
-.Dd $Mdocdate: July 2 2008 $
+.\" $OpenBSD: sshd.8,v 1.247 2008/10/03 13:08:12 jmc Exp $
+.Dd $Mdocdate: October 3 2008 $
 .Dt SSHD 8
 .Os
 .Sh NAME
@@ -741,8 +741,6 @@ will not allow it to be used unless the
 .Cm StrictModes
 option has been set to
 .Dq no .
-The recommended permissions can be set by executing
-.Dq chmod go-w ~/ ~/.ssh ~/.ssh/authorized_keys .
 .Pp
 .It ~/.ssh/environment
 This file is read into the environment at login (if it exists).
index 6e5bb54..3b5cd3c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.364 2008/07/10 18:08:11 markus Exp $ */
+/* $OpenBSD: sshd.c,v 1.366 2009/01/22 10:02:34 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 "version.h"
 
 #ifdef LIBWRAP
@@ -1334,7 +1333,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);
                        }
index 7255b1c..dfd07b7 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd_config.5,v 1.96 2008/07/02 02:24:18 djm Exp $
-.Dd $Mdocdate: July 2 2008 $
+.\" $OpenBSD: sshd_config.5,v 1.102 2009/02/22 23:59:25 djm Exp $
+.Dd $Mdocdate: February 22 2009 $
 .Dt SSHD_CONFIG 5
 .Os
 .Sh NAME
@@ -240,9 +240,9 @@ and
 .Dq cast128-cbc .
 The default is:
 .Bd -literal -offset 3n
-aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-aes192-ctr,aes256-ctr
+aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,
+aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,
+aes256-cbc,arcfour
 .Ed
 .It Cm ClientAliveCountMax
 Sets the number of client alive messages (see below) which may be
@@ -593,6 +593,7 @@ Only a subset of keywords may be used on the lines following a
 .Cm Match
 keyword.
 Available keywords are
+.Cm AllowAgentForwarding ,
 .Cm AllowTcpForwarding ,
 .Cm Banner ,
 .Cm ChrootDirectory ,
@@ -605,12 +606,13 @@ Available keywords are
 .Cm MaxAuthTries ,
 .Cm MaxSessions ,
 .Cm PasswordAuthentication ,
+.Cm PermitEmptyPasswords ,
 .Cm PermitOpen ,
 .Cm PermitRootLogin ,
 .Cm RhostsRSAAuthentication ,
 .Cm RSAAuthentication ,
 .Cm X11DisplayOffset ,
-.Cm X11Forwarding ,
+.Cm X11Forwarding
 and
 .Cm X11UseLocalHost .
 .It Cm MaxAuthTries
index 5a0d1a7..bbbc0fe 100644 (file)
 #define O_NOCTTY 0
 #endif
 
+#ifdef __APPLE__
+# include <AvailabilityMacros.h>
+# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+#  define __APPLE_PRIVPTY__
+# endif
+#endif
+
 /*
  * Allocates and opens a pty.  Returns 0 if no pty could be allocated, or
  * nonzero if a pty was successfully allocated.  On success, open file
@@ -78,10 +85,12 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
 void
 pty_release(const char *tty)
 {
+#ifndef __APPLE_PRIVPTY__
        if (chown(tty, (uid_t) 0, (gid_t) 0) < 0)
                error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno));
        if (chmod(tty, (mode_t) 0666) < 0)
                error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno));
+#endif /* __APPLE_PRIVPTY__ */
 }
 
 /* Makes the tty the process's controlling tty and sets it to sane modes. */
index e116b19..6f51b8a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ttymodes.c,v 1.28 2008/07/07 00:31:41 stevesk Exp $ */
+/* $OpenBSD: ttymodes.c,v 1.29 2008/11/02 00:16:16 stevesk Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -311,11 +311,9 @@ tty_make_modes(int fd, struct termios *tiop)
 
        /* Store input and output baud rates. */
        baud = speed_to_baud(cfgetospeed(&tio));
-       debug3("tty_make_modes: ospeed %d", baud);
        buffer_put_char(&buf, tty_op_ospeed);
        buffer_put_int(&buf, baud);
        baud = speed_to_baud(cfgetispeed(&tio));
-       debug3("tty_make_modes: ispeed %d", baud);
        buffer_put_char(&buf, tty_op_ispeed);
        buffer_put_int(&buf, baud);
 
@@ -359,7 +357,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
 
        if (compat20) {
                *n_bytes_ptr = packet_get_int();
-               debug3("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr);
                if (*n_bytes_ptr == 0)
                        return;
                get_arg = packet_get_int;
@@ -391,7 +388,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
                case TTY_OP_ISPEED_PROTO2:
                        n_bytes += 4;
                        baud = packet_get_int();
-                       debug3("tty_parse_modes: ispeed %d", baud);
                        if (failure != -1 &&
                            cfsetispeed(&tio, baud_to_speed(baud)) == -1)
                                error("cfsetispeed failed for %d", baud);
@@ -402,7 +398,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
                case TTY_OP_OSPEED_PROTO2:
                        n_bytes += 4;
                        baud = packet_get_int();
-                       debug3("tty_parse_modes: ospeed %d", baud);
                        if (failure != -1 &&
                            cfsetospeed(&tio, baud_to_speed(baud)) == -1)
                                error("cfsetospeed failed for %d", baud);
index 91d878c..8376483 100644 (file)
@@ -233,6 +233,16 @@ permanently_set_uid(struct passwd *pw)
                fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
 #endif
 
+#ifdef __APPLE__
+       /*
+        * OS X requires initgroups after setgid to opt back into
+        * memberd support for >16 supplemental groups.
+        */
+       if (initgroups(pw->pw_name, pw->pw_gid) < 0)
+               fatal("initgroups %.100s %u: %.100s",
+                   pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
+#endif
+
 #if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
        if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)
                fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno));