From: basney Date: Wed, 25 Feb 2009 17:14:22 +0000 (+0000) Subject: merged OpenSSH 5.2p1 to trunk X-Git-Tag: OPENSSH_5_2P1_GSSAPI_20090401~8 X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/commitdiff_plain/5262cbfbbd270876de2cd547ff0032d85b1d2640 merged OpenSSH 5.2p1 to trunk --- diff --git a/openssh/Makefile.in b/openssh/Makefile.in index 6d1d69d..d448c75 100644 --- a/openssh/Makefile.in +++ b/openssh/Makefile.in @@ -73,7 +73,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ kexgssc.o \ - entropy.o scard-opensc.o gss-genr.o umac.o + entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o @@ -83,7 +83,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth.o auth1.o auth2.o auth-options.o session.o \ auth-chall.o auth2-chall.o groupaccess.o \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ diff --git a/openssh/auth.c b/openssh/auth.c index f95c91f..2106dfc 100644 --- a/openssh/auth.c +++ b/openssh/auth.c @@ -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. * diff --git a/openssh/auth.h b/openssh/auth.h index 49246c7..3f09416 100644 --- a/openssh/auth.h +++ b/openssh/auth.h @@ -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. @@ -63,6 +63,7 @@ struct Authctxt { struct passwd *pw; /* set if 'valid' */ char *style; void *kbdintctxt; + void *jpake_ctx; #ifdef BSD_AUTH auth_session_t *as; #endif @@ -164,6 +165,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); diff --git a/openssh/auth2.c b/openssh/auth2.c index 9227c63..2e46638 100644 --- a/openssh/auth2.c +++ b/openssh/auth2.c @@ -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. * @@ -75,6 +75,9 @@ extern Authmethod method_gsskeyex; extern Authmethod method_gssapi; extern Authmethod method_gssapi_compat; #endif +#ifdef JPAKE +extern Authmethod method_jpake; +#endif static int log_flag = 0; @@ -87,6 +90,9 @@ Authmethod *authmethods[] = { &method_external, &method_gssapi, &method_gssapi_compat, +#endif +#ifdef JPAKE + &method_jpake, #endif &method_passwd, &method_kbdint, @@ -320,8 +326,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 diff --git a/openssh/canohost.c b/openssh/canohost.c index 4c0738a..d154ab8 100644 --- a/openssh/canohost.c +++ b/openssh/canohost.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -344,7 +344,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; diff --git a/openssh/canohost.h b/openssh/canohost.h index 0a293e7..690ee80 100644 --- a/openssh/canohost.h +++ b/openssh/canohost.h @@ -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 @@ -23,6 +23,8 @@ char *get_local_name(int); int get_remote_port(void); int get_local_port(void); +int get_sock_port(int, int); + void resolve_localhost(char **host); diff --git a/openssh/channels.c b/openssh/channels.c index 9dd954a..6996bde 100644 --- a/openssh/channels.c +++ b/openssh/channels.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -302,6 +302,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; @@ -409,6 +410,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); @@ -698,7 +703,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; @@ -813,8 +818,6 @@ int channel_tcpwinsz () { /* return no more than 64MB */ if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN) tcpwinsz = BUFFER_MAX_LEN_HPN; - debug2("tcpwinsz: %d for connection: %d", tcpwinsz, - packet_get_connection_in()); return(tcpwinsz); } @@ -1011,7 +1014,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; @@ -1027,10 +1030,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 */ @@ -1039,7 +1052,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); @@ -1049,23 +1062,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 */ @@ -1096,7 +1132,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); @@ -1169,10 +1205,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", @@ -1401,7 +1449,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) { /* @@ -2351,8 +2400,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 */ @@ -2417,18 +2466,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; } ; @@ -2458,7 +2507,8 @@ channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size) } 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; @@ -2466,6 +2516,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; @@ -2475,7 +2526,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; } @@ -2534,10 +2585,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"); @@ -2553,7 +2623,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) { @@ -2572,6 +2643,19 @@ 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. */ /* explicitly test for hpn disabled option. if true use smaller window size */ if (hpn_disabled) @@ -2582,7 +2666,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por c = channel_new("port listener", type, sock, sock, -1, hpn_buffer_size, 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; @@ -2604,8 +2688,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; @@ -2621,17 +2704,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); } /* @@ -2846,10 +2930,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 */ @@ -3136,7 +3226,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; @@ -3146,7 +3236,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); @@ -3154,6 +3244,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) { @@ -3175,6 +3273,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] diff --git a/openssh/channels.h b/openssh/channels.h index 419c009..64c2e3d 100644 --- a/openssh/channels.h +++ b/openssh/channels.h @@ -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 @@ -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 */ @@ -251,7 +249,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 */ diff --git a/openssh/cipher.c b/openssh/cipher.c index 7551292..bbb2805 100644 --- a/openssh/cipher.c +++ b/openssh/cipher.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -64,31 +64,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_ctr_mt }, - { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_ctr_mt }, - { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_ctr_mt }, + SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_ctr_mt }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_ctr_mt }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_ctr_mt }, #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 } }; /*--*/ @@ -111,6 +112,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) { diff --git a/openssh/clientloop.c b/openssh/clientloop.c index d1f2f46..38028d5 100644 --- a/openssh/clientloop.c +++ b/openssh/clientloop.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -107,7 +107,6 @@ #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) { @@ -1734,7 +1740,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; } @@ -1866,7 +1872,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); diff --git a/openssh/compat.c b/openssh/compat.c index d1addc8..0b3df86 100644 --- a/openssh/compat.c +++ b/openssh/compat.c @@ -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| diff --git a/openssh/compat.h b/openssh/compat.h index ec00fd3..e303d33 100644 --- a/openssh/compat.h +++ b/openssh/compat.h @@ -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,7 +57,8 @@ #define SSH_BUG_FIRSTKEX 0x00800000 #define SSH_OLD_FORWARD_ADDR 0x01000000 #define SSH_BUG_RFWD_ADDR 0x02000000 -#define SSH_BUG_LARGEWINDOW 0x04000000 +#define SSH_NEW_OPENSSH 0x04000000 +#define SSH_BUG_LARGEWINDOW 0x08000000 void enable_compat13(void); void enable_compat20(void); diff --git a/openssh/configure.ac b/openssh/configure.ac index 6125936..6302923 100644 --- a/openssh/configure.ac +++ b/openssh/configure.ac @@ -235,7 +235,7 @@ int main(void){char b[10]; memset(b, 0, sizeof(b));} # -fstack-protector-all doesn't always work for some GCC versions # and/or platforms, so we test if we can. If it's not supported - # on a give platform gcc will emit a warning so we use -Werror. + # on a given platform gcc will emit a warning so we use -Werror. if test "x$use_stack_protector" = "x1"; then for t in -fstack-protector-all -fstack-protector; do AC_MSG_CHECKING(if $CC supports $t) @@ -245,8 +245,8 @@ int main(void){char b[10]; memset(b, 0, sizeof(b));} LDFLAGS="$LDFLAGS $t -Werror" AC_LINK_IFELSE( [AC_LANG_SOURCE([ -#include -int main(void){return 0;} +#include +int main(void){char x[[256]]; snprintf(x, sizeof(x), "XXX"); return 0;} ])], [ AC_MSG_RESULT(yes) CFLAGS="$saved_CFLAGS $t" @@ -254,8 +254,8 @@ int main(void){return 0;} AC_MSG_CHECKING(if $t works) AC_RUN_IFELSE( [AC_LANG_SOURCE([ -#include -int main(void){exit(0);} +#include +int main(void){char x[[256]]; snprintf(x, sizeof(x), "XXX"); return 0;} ])], [ AC_MSG_RESULT(yes) break ], @@ -578,6 +578,8 @@ int main(void) { exit(0); } AC_CHECK_DECL(AU_IPv4, [], AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records]) [#include ] + AC_DEFINE(LASTLOG_WRITE_PUTUTXLINE, 1, + [Define if pututxline updates lastlog too]) ) AC_MSG_CHECKING(if we have the Security Authorization Session API) AC_TRY_COMPILE([#include ], @@ -686,6 +688,14 @@ int main(void) { exit(0); } AC_DEFINE(WITH_ABBREV_NO_TTY) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; +*-*-k*bsd*-gnu | *-*-kopensolaris*-gnu) + check_for_libcrypt_later=1 + AC_DEFINE(PAM_TTY_KLUDGE) + AC_DEFINE(LOCKED_PASSWD_PREFIX, "!") + AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) + AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts]) + AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins]) + ;; *-*-linux*) no_dev_ptmx=1 check_for_libcrypt_later=1 @@ -853,7 +863,6 @@ mips-sony-bsd|mips-sony-newsos4) ;; # UnixWare 7.x, OpenUNIX 8 *-*-sysv5*) - check_for_libcrypt_later=1 AC_DEFINE(UNIXWARE_LONG_PASSWORDS, 1, [Support passwords > 8 chars]) AC_DEFINE(USE_PIPES) AC_DEFINE(SETEUID_BREAKS_SETUID) @@ -866,8 +875,14 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(BROKEN_LIBIAF, 1, [ia_uinfo routines not supported by OS yet]) AC_DEFINE(BROKEN_UPDWTMPX) + AC_CHECK_LIB(prot, getluid,[ LIBS="$LIBS -lprot" + AC_CHECK_FUNCS(getluid setluid,,,-lprot) + AC_DEFINE(HAVE_SECUREWARE) + AC_DEFINE(DISABLE_SHADOW) + ],,) ;; *) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") + check_for_libcrypt_later=1 ;; esac ;; @@ -1628,6 +1643,8 @@ AC_CHECK_FUNCS(utmpname) dnl Checks for utmpx functions AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline ) AC_CHECK_FUNCS(setutxent utmpxname) +dnl Checks for lastlog functions +AC_CHECK_FUNCS(getlastlogxbyname) AC_CHECK_FUNC(daemon, [AC_DEFINE(HAVE_DAEMON, 1, [Define if your libraries define daemon()])], @@ -2951,6 +2968,15 @@ AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_IN6_ADDR, 1, [define if you have struct in6_addr data type]) + +dnl Now check for sin6_scope_id + AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id],,, + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + ]) fi AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ diff --git a/openssh/contrib/cygwin/Makefile b/openssh/contrib/cygwin/Makefile index 3e2d264..2ebd143 100644 --- a/openssh/contrib/cygwin/Makefile +++ b/openssh/contrib/cygwin/Makefile @@ -38,11 +38,13 @@ install-sshdoc: $(INSTALL) -m 644 $(srcdir)/ChangeLog $(DESTDIR)$(sshdocdir)/ChangeLog $(INSTALL) -m 644 $(srcdir)/LICENCE $(DESTDIR)$(sshdocdir)/LICENCE $(INSTALL) -m 644 $(srcdir)/OVERVIEW $(DESTDIR)$(sshdocdir)/OVERVIEW + $(INSTALL) -m 644 $(srcdir)/PROTOCOL $(DESTDIR)$(sshdocdir)/PROTOCOL + $(INSTALL) -m 644 $(srcdir)/PROTOCOL.agent $(DESTDIR)$(sshdocdir)/PROTOCOL.agent $(INSTALL) -m 644 $(srcdir)/README $(DESTDIR)$(sshdocdir)/README $(INSTALL) -m 644 $(srcdir)/README.dns $(DESTDIR)$(sshdocdir)/README.dns + $(INSTALL) -m 644 $(srcdir)/README.platform $(DESTDIR)$(sshdocdir)/README.platform $(INSTALL) -m 644 $(srcdir)/README.privsep $(DESTDIR)$(sshdocdir)/README.privsep $(INSTALL) -m 644 $(srcdir)/README.smartcard $(DESTDIR)$(sshdocdir)/README.smartcard - $(INSTALL) -m 644 $(srcdir)/RFC.nroff $(DESTDIR)$(sshdocdir)/RFC.nroff $(INSTALL) -m 644 $(srcdir)/TODO $(DESTDIR)$(sshdocdir)/TODO $(INSTALL) -m 644 $(srcdir)/WARNING.RNG $(DESTDIR)$(sshdocdir)/WARNING.RNG diff --git a/openssh/defines.h b/openssh/defines.h index 4820ef4..7487597 100644 --- a/openssh/defines.h +++ b/openssh/defines.h @@ -702,7 +702,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) @@ -742,4 +742,8 @@ struct winsize { # define EWOULDBLOCK EAGAIN #endif +#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ +#define INET6_ADDRSTRLEN 46 +#endif + #endif /* _DEFINES_H */ diff --git a/openssh/kex.c b/openssh/kex.c index 2633171..38db004 100644 --- a/openssh/kex.c +++ b/openssh/kex.c @@ -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. * diff --git a/openssh/kexgexs.c b/openssh/kexgexs.c index a037f57..76a0f8c 100644 --- a/openssh/kexgexs.c +++ b/openssh/kexgexs.c @@ -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, diff --git a/openssh/key.c b/openssh/key.c index 484b97f..327aa4e 100644 --- a/openssh/key.c +++ b/openssh/key.c @@ -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 , 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; } diff --git a/openssh/misc.c b/openssh/misc.c index 2225984..83efded 100644 --- a/openssh/misc.c +++ b/openssh/misc.c @@ -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. @@ -239,23 +239,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 @@ -736,7 +732,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) { @@ -744,7 +741,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); } } diff --git a/openssh/monitor.c b/openssh/monitor.c index f92fd70..bc018a4 100644 --- a/openssh/monitor.c +++ b/openssh/monitor.c @@ -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 * Copyright 2002 Markus Friedl @@ -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 *); @@ -241,6 +247,13 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error}, {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs}, {MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname}, +#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} }; @@ -407,6 +420,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) @@ -1515,7 +1537,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); @@ -2114,3 +2138,206 @@ mm_answer_gss_localname(int socket, Buffer *m) { return(0); } #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 */ diff --git a/openssh/monitor.h b/openssh/monitor.h index c1b32a3..9ebf826 100644 --- a/openssh/monitor.h +++ b/openssh/monitor.h @@ -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 @@ -64,7 +64,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; diff --git a/openssh/monitor_fdpass.c b/openssh/monitor_fdpass.c index cab538b..4b9a066 100644 --- a/openssh/monitor_fdpass.c +++ b/openssh/monitor_fdpass.c @@ -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 * 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__, diff --git a/openssh/monitor_wrap.c b/openssh/monitor_wrap.c index 54000e0..368738f 100644 --- a/openssh/monitor_wrap.c +++ b/openssh/monitor_wrap.c @@ -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 * Copyright 2002 Markus Friedl @@ -40,6 +40,7 @@ #include #include +#include #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" @@ -1356,3 +1357,165 @@ mm_ssh_gssapi_localname(char **lname) } #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 */ diff --git a/openssh/monitor_wrap.h b/openssh/monitor_wrap.h index 46fd2a5..a190a26 100644 --- a/openssh/monitor_wrap.h +++ b/openssh/monitor_wrap.h @@ -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 @@ -106,6 +106,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); diff --git a/openssh/myproposal.h b/openssh/myproposal.h index 46bd6df..df9c1dd 100644 --- a/openssh/myproposal.h +++ b/openssh/myproposal.h @@ -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. @@ -41,11 +41,12 @@ #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_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \ ",none" #define KEX_DEFAULT_MAC \ diff --git a/openssh/openbsd-compat/xcrypt.c b/openssh/openbsd-compat/xcrypt.c index d8636bb..6291e28 100644 --- a/openssh/openbsd-compat/xcrypt.c +++ b/openssh/openbsd-compat/xcrypt.c @@ -28,7 +28,7 @@ #include #include -# ifdef HAVE_CRYPT_H +# if defined(HAVE_CRYPT_H) && !defined(HAVE_SECUREWARE) # include # endif diff --git a/openssh/openbsd-compat/xmmap.c b/openssh/openbsd-compat/xmmap.c index 322ffc2..e0395e3 100644 --- a/openssh/openbsd-compat/xmmap.c +++ b/openssh/openbsd-compat/xmmap.c @@ -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); diff --git a/openssh/packet.c b/openssh/packet.c index 695a0b3..7b77e29 100644 --- a/openssh/packet.c +++ b/openssh/packet.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , 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 @@ -1132,6 +1168,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; @@ -1153,11 +1192,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); @@ -1166,9 +1208,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 @@ -1190,11 +1236,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) @@ -1327,6 +1381,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); } diff --git a/openssh/readconf.c b/openssh/readconf.c index 7d248fe..6d05b4e 100644 --- a/openssh/readconf.c +++ b/openssh/readconf.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -132,7 +132,7 @@ typedef enum { oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, - oVisualHostKey, + oVisualHostKey, oZeroKnowledgePasswordAuthentication, oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled, oHPNBufferSize, oDeprecated, oUnsupported @@ -180,7 +180,7 @@ static struct { { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, { "identityfile", oIdentityFile }, - { "identityfile2", oIdentityFile }, /* alias */ + { "identityfile2", oIdentityFile }, /* obsolete */ { "identitiesonly", oIdentitiesOnly }, { "hostname", oHostName }, { "hostkeyalias", oHostKeyAlias }, @@ -196,8 +196,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 }, @@ -248,6 +248,12 @@ static struct { { "noneswitch", oNoneSwitch }, { "hpndisabled", oHPNDisabled }, { "hpnbuffersize", oHPNBufferSize }, +#ifdef JPAKE + { "zeroknowledgepasswordauthentication", + oZeroKnowledgePasswordAuthentication }, +#else + { "zeroknowledgepasswordauthentication", oUnsupported }, +#endif { NULL, oBadOption } }; @@ -269,10 +275,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; } @@ -290,10 +295,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; } @@ -432,6 +436,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; @@ -769,56 +777,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); - if (parse_forward(&fwd, fwdarg) == 0) + /* 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, + 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; @@ -1022,7 +1014,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; @@ -1149,6 +1140,7 @@ initialize_options(Options * options) options->hpn_buffer_size = -1; options->tcp_rcv_buf_poll = -1; options->tcp_rcv_buf = -1; + options->zero_knowledge_password_authentication = -1; } /* @@ -1312,6 +1304,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 */ @@ -1323,11 +1317,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]; @@ -1344,11 +1341,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]); @@ -1368,19 +1377,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); } diff --git a/openssh/readconf.h b/openssh/readconf.h index a1fb309..9396f17 100644 --- a/openssh/readconf.h +++ b/openssh/readconf.h @@ -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 @@ -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. */ @@ -51,6 +51,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. */ @@ -144,7 +145,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 *); diff --git a/openssh/scp.c b/openssh/scp.c index 411dc8b..25d7597 100644 --- a/openssh/scp.c +++ b/openssh/scp.c @@ -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) diff --git a/openssh/servconf.c b/openssh/servconf.c index 8b8b995..a693e05 100644 --- a/openssh/servconf.c +++ b/openssh/servconf.c @@ -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 , 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; @@ -140,6 +140,7 @@ initialize_server_options(ServerOptions *options) options->tcp_rcv_buf_poll = -1; options->hpn_disabled = -1; options->hpn_buffer_size = -1; + options->zero_knowledge_password_authentication = -1; } void @@ -284,6 +285,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; if (options->hpn_disabled == -1) options->hpn_disabled = 0; @@ -374,6 +377,7 @@ typedef enum { sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize, + sZeroKnowledgePasswordAuthentication, sDeprecated, sUnsupported } ServerOpCodes; @@ -459,6 +463,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 }, @@ -471,7 +480,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 }, @@ -547,7 +556,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; @@ -563,7 +572,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]; @@ -573,7 +582,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 : "", @@ -729,7 +738,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; @@ -786,7 +795,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; @@ -839,7 +848,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); @@ -1039,6 +1048,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; @@ -1401,7 +1414,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) @@ -1527,7 +1540,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); @@ -1589,7 +1604,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: @@ -1694,11 +1709,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); @@ -1712,12 +1731,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); @@ -1776,7 +1805,5 @@ dump_config(ServerOptions *o) } dump_cfg_string(sPermitTunnel, s); - printf("permitopen"); channel_print_adm_permitted_opens(); - printf("\n"); } diff --git a/openssh/servconf.h b/openssh/servconf.h index 898d11b..6ca0980 100644 --- a/openssh/servconf.h +++ b/openssh/servconf.h @@ -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 @@ -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. */ @@ -106,6 +106,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 */ diff --git a/openssh/serverloop.c b/openssh/serverloop.c index 2955e11..49e4c79 100644 --- a/openssh/serverloop.c +++ b/openssh/serverloop.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -965,7 +965,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(); @@ -1124,7 +1124,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(); @@ -1146,7 +1146,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 @@ -1156,7 +1157,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) { @@ -1178,6 +1180,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(); } @@ -1231,9 +1235,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 */ diff --git a/openssh/session.c b/openssh/session.c index 940e722..b06bf38 100644 --- a/openssh/session.c +++ b/openssh/session.c @@ -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 , Espoo, Finland * All rights reserved @@ -95,6 +95,12 @@ #include #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); @@ -234,7 +240,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: @@ -802,7 +808,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; @@ -810,7 +816,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; @@ -967,7 +973,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, @@ -2005,7 +2011,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; diff --git a/openssh/sftp.1 b/openssh/sftp.1 index c574430..86232b7 100644 --- a/openssh/sftp.1 +++ b/openssh/sftp.1 @@ -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 @@ -43,13 +43,12 @@ .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 @@ -443,7 +442,7 @@ to Display the .Nm protocol version. -.It Ic \&! Ar command +.It Ic \&! Ns Ar command Execute .Ar command in local shell. diff --git a/openssh/sftp.c b/openssh/sftp.c index e7cb9cf..a9f035f 100644 --- a/openssh/sftp.c +++ b/openssh/sftp.c @@ -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 * @@ -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); } diff --git a/openssh/ssh-keyscan.c b/openssh/ssh-keyscan.c index d810777..9a91be4 100644 --- a/openssh/ssh-keyscan.c +++ b/openssh/ssh-keyscan.c @@ -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 . * @@ -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); } diff --git a/openssh/ssh.1 b/openssh/ssh.1 index 1883578..421783b 100644 --- a/openssh/ssh.1 +++ b/openssh/ssh.1 @@ -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 diff --git a/openssh/ssh.c b/openssh/ssh.c index 3fed774..f112134 100644 --- a/openssh/ssh.c +++ b/openssh/ssh.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , 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': @@ -618,7 +606,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 @@ -667,7 +655,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(); @@ -879,9 +867,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 " @@ -1302,7 +1297,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"); diff --git a/openssh/ssh_config b/openssh/ssh_config index 873acdf..6a148a2 100644 --- a/openssh/ssh_config +++ b/openssh/ssh_config @@ -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 @@ -39,9 +39,10 @@ # 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 diff --git a/openssh/ssh_config.5 b/openssh/ssh_config.5 index e5e5ed0..073d038 100644 --- a/openssh/ssh_config.5 +++ b/openssh/ssh_config.5 @@ -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 @@ -109,7 +109,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 @@ -210,9 +210,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 @@ -836,7 +836,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 @@ -1089,10 +1097,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 diff --git a/openssh/sshconnect.c b/openssh/sshconnect.c index 2a7766f..706318d 100644 --- a/openssh/sshconnect.c +++ b/openssh/sshconnect.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , 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 *); @@ -776,8 +772,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; } diff --git a/openssh/sshconnect2.c b/openssh/sshconnect2.c index a61b99c..7c4e84e 100644 --- a/openssh/sshconnect2.c +++ b/openssh/sshconnect2.c @@ -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" @@ -257,6 +259,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 */ }; @@ -268,13 +271,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_external(Authctxt *authctxt); @@ -312,6 +320,7 @@ Authmethod authmethods[] = { NULL}, {"gssapi-with-mic", userauth_gssapi, + NULL, &options.gss_authentication, NULL}, {"gssapi", @@ -321,25 +330,37 @@ Authmethod authmethods[] = { #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 @@ -429,6 +450,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; @@ -461,6 +485,7 @@ userauth(Authctxt *authctxt, char *authlist) } } +/* ARGSUSED */ void input_userauth_error(int type, u_int32_t seq, void *ctxt) { @@ -468,6 +493,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) { @@ -477,11 +503,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); } @@ -489,6 +515,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) { @@ -506,6 +533,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) { @@ -526,6 +554,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) { @@ -720,6 +750,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) { @@ -759,6 +790,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) { @@ -786,6 +818,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) { @@ -815,6 +848,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) { @@ -979,9 +1013,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) { @@ -1046,6 +1082,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) @@ -1620,6 +1859,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 */ /* @@ -1721,3 +2030,4 @@ authmethods_get(void) buffer_free(&b); return list; } + diff --git a/openssh/sshd.8 b/openssh/sshd.8 index c4c4181..a4b9e90 100644 --- a/openssh/sshd.8 +++ b/openssh/sshd.8 @@ -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). diff --git a/openssh/sshd.c b/openssh/sshd.c index ac1d469..5db24fd 100644 --- a/openssh/sshd.c +++ b/openssh/sshd.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -117,7 +117,6 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" -#include "monitor_fdpass.h" #include "version.h" #ifdef USE_SECURITY_SESSION_API @@ -1351,7 +1350,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); } diff --git a/openssh/sshd_config.5 b/openssh/sshd_config.5 index 439abdb..6649d32 100644 --- a/openssh/sshd_config.5 +++ b/openssh/sshd_config.5 @@ -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 @@ -636,6 +636,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 , @@ -648,12 +649,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 diff --git a/openssh/version.h b/openssh/version.h index bad7d4e..b39d6f4 100644 --- a/openssh/version.h +++ b/openssh/version.h @@ -1,4 +1,4 @@ -/* $OpenBSD: version.h,v 1.54 2008/07/21 08:19:07 djm Exp $ */ +/* $OpenBSD: version.h,v 1.55 2009/02/23 00:06:15 djm Exp $ */ #ifdef GSI #define GSI_VERSION " GSI" @@ -18,9 +18,9 @@ #define MGLUE_VERSION "" #endif -#define NCSA_VERSION " GLOBUS_GSSAPI_20080923" +#define NCSA_VERSION " GLOBUS_GSSAPI_20090225" -#define SSH_VERSION "OpenSSH_5.1" +#define SSH_VERSION "OpenSSH_5.2" #define SSH_PORTABLE "p1" #define SSH_HPN "-hpn13v5"