Upgrade to OpenSSH 5.2p1.

MFC after:	3 months
This commit is contained in:
Dag-Erling Smørgrav 2009-05-22 18:46:28 +00:00
commit cce7d3464f
78 changed files with 3914 additions and 4443 deletions

File diff suppressed because it is too large Load Diff

View File

@ -64,6 +64,12 @@ remain open after a "eow@openssh.com" has been sent and more data may
still be sent in the other direction. This message does not consume
window space and may be sent even if no window space is available.
NB. due to certain broken SSH implementations aborting upon receipt
of this message (in contravention of RFC4254 section 5.4), this
message is only sent to OpenSSH peers (identified by banner).
Other SSH implementations may be whitelisted to receive this message
upon request.
4. connection: disallow additional sessions extension
"no-more-sessions@openssh.com"
@ -87,6 +93,11 @@ connection.
Note that this is not a general defence against compromised clients
(that is impossible), but it thwarts a simple attack.
NB. due to certain broken SSH implementations aborting upon receipt
of this message, the no-more-sessions request is only sent to OpenSSH
servers (identified by banner). Other SSH implementations may be
whitelisted to receive this message upon request.
5. connection: Tunnel forward extension "tun@openssh.com"
OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
@ -240,4 +251,4 @@ The values of the f_flag bitmask are as follows:
Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
advertised in the SSH_FXP_VERSION hello with version "2".
$OpenBSD: PROTOCOL,v 1.11 2008/07/05 05:16:01 djm Exp $
$OpenBSD: PROTOCOL,v 1.12 2009/02/14 06:35:49 djm Exp $

View File

@ -1,4 +1,4 @@
See http://www.openssh.com/txt/release-5.1 for the release notes.
See http://www.openssh.com/txt/release-5.2 for the release notes.
- A Japanese translation of this document and of the OpenSSH FAQ is
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
@ -62,4 +62,4 @@ References -
[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
[7] http://www.openssh.com/faq.html
$Id: README,v 1.69 2008/07/21 08:21:52 djm Exp $
$Id: README,v 1.70 2009/02/23 00:11:57 djm Exp $

View File

@ -1,4 +1,4 @@
/* $OpenBSD: addrmatch.c,v 1.3 2008/06/10 23:06:19 djm Exp $ */
/* $OpenBSD: addrmatch.c,v 1.4 2008/12/10 03:55:20 stevesk Exp $ */
/*
* Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
@ -31,6 +31,7 @@
#include "match.h"
#include "log.h"
#include "xmalloc.h"
struct xaddr {
sa_family_t af;
@ -97,7 +98,9 @@ addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa)
return -1;
xa->af = AF_INET6;
memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6));
#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
xa->scope_id = in6->sin6_scope_id;
#endif
break;
default:
return -1;
@ -415,7 +418,7 @@ addr_match_list(const char *addr, const char *_list)
goto foundit;
}
}
free(o);
xfree(o);
return ret;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.c,v 1.43 2008/06/10 23:06:19 djm Exp $ */
/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -255,7 +255,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
cp = "permitopen=\"";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
char *host, *p;
u_short port;
int port;
char *patterns = xmalloc(strlen(opts) + 1);
opts += strlen(cp);
@ -293,7 +293,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
goto bad_option;
}
host = cleanhostname(host);
if (p == NULL || (port = a2port(p)) == 0) {
if (p == NULL || (port = a2port(p)) <= 0) {
debug("%.100s, line %lu: Bad permitopen port "
"<%.100s>", file, linenum, p ? p : "");
auth_debug_add("%.100s, line %lu: "

View File

@ -45,7 +45,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
/* Based on $FreeBSD$ */
#include "includes.h"
#include <sys/types.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.79 2008/07/02 12:03:51 dtucker Exp $ */
/* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.61 2008/07/02 12:03:51 dtucker Exp $ */
/* $OpenBSD: auth.h,v 1.62 2008/11/04 08:22:12 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -59,6 +59,7 @@ struct Authctxt {
struct passwd *pw; /* set if 'valid' */
char *style;
void *kbdintctxt;
void *jpake_ctx;
#ifdef BSD_AUTH
auth_session_t *as;
#endif
@ -156,6 +157,9 @@ int bsdauth_respond(void *, u_int, char **);
int skey_query(void *, char **, char **, u_int *, char ***, u_int **);
int skey_respond(void *, u_int, char **);
void auth2_jpake_get_pwdata(Authctxt *, BIGNUM **, char **, char **);
void auth2_jpake_stop(Authctxt *);
int allowed_user(struct passwd *);
struct passwd * getpwnamallow(const char *user);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-chall.c,v 1.33 2007/09/21 08:15:29 djm Exp $ */
/* $OpenBSD: auth2-chall.c,v 1.34 2008/12/09 04:32:22 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Per Allansson. All rights reserved.
@ -281,7 +281,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
KbdintAuthctxt *kbdintctxt;
int authenticated = 0, res, len;
int authenticated = 0, res;
u_int i, nresp;
char **response = NULL, *method;
@ -330,11 +330,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
break;
}
len = strlen("keyboard-interactive") + 2 +
strlen(kbdintctxt->device->name);
method = xmalloc(len);
snprintf(method, len, "keyboard-interactive/%s",
kbdintctxt->device->name);
xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name);
if (!authctxt->postponed) {
if (authenticated) {

View File

@ -0,0 +1,557 @@
/* $OpenBSD: auth2-jpake.c,v 1.2 2008/11/07 23:34:48 dtucker Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Server side of zero-knowledge password auth using J-PAKE protocol
* as described in:
*
* F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling",
* 16th Workshop on Security Protocols, Cambridge, April 2008
*
* http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
*/
#ifdef JPAKE
#include <sys/types.h>
#include <sys/param.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <login_cap.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include "xmalloc.h"
#include "ssh2.h"
#include "key.h"
#include "hostfile.h"
#include "buffer.h"
#include "auth.h"
#include "packet.h"
#include "dispatch.h"
#include "log.h"
#include "servconf.h"
#include "auth-options.h"
#include "canohost.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "jpake.h"
/*
* XXX options->permit_empty_passwd (at the moment, they will be refused
* anyway because they will mismatch on fake salt.
*/
/* Dispatch handlers */
static void input_userauth_jpake_client_step1(int, u_int32_t, void *);
static void input_userauth_jpake_client_step2(int, u_int32_t, void *);
static void input_userauth_jpake_client_confirm(int, u_int32_t, void *);
static int auth2_jpake_start(Authctxt *);
/* import */
extern ServerOptions options;
extern u_char *session_id2;
extern u_int session_id2_len;
/*
* Attempt J-PAKE authentication.
*/
static int
userauth_jpake(Authctxt *authctxt)
{
int authenticated = 0;
packet_check_eom();
debug("jpake-01@openssh.com requested");
if (authctxt->user != NULL) {
if (authctxt->jpake_ctx == NULL)
authctxt->jpake_ctx = jpake_new();
if (options.zero_knowledge_password_authentication)
authenticated = auth2_jpake_start(authctxt);
}
return authenticated;
}
Authmethod method_jpake = {
"jpake-01@openssh.com",
userauth_jpake,
&options.zero_knowledge_password_authentication
};
/* Clear context and callbacks */
void
auth2_jpake_stop(Authctxt *authctxt)
{
/* unregister callbacks */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL);
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL);
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL);
if (authctxt->jpake_ctx != NULL) {
jpake_free(authctxt->jpake_ctx);
authctxt->jpake_ctx = NULL;
}
}
/* Returns 1 if 'c' is a valid crypt(3) salt character, 0 otherwise */
static int
valid_crypt_salt(int c)
{
if (c >= 'A' && c <= 'Z')
return 1;
if (c >= 'a' && c <= 'z')
return 1;
if (c >= '.' && c <= '9')
return 1;
return 0;
}
/*
* Derive fake salt as H(username || first_private_host_key)
* This provides relatively stable fake salts for non-existent
* users and avoids the jpake method becoming an account validity
* oracle.
*/
static void
derive_rawsalt(const char *username, u_char *rawsalt, u_int len)
{
u_char *digest;
u_int digest_len;
Buffer b;
Key *k;
buffer_init(&b);
buffer_put_cstring(&b, username);
if ((k = get_hostkey_by_index(0)) == NULL ||
(k->flags & KEY_FLAG_EXT))
fatal("%s: no hostkeys", __func__);
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
if (k->rsa->p == NULL || k->rsa->q == NULL)
fatal("%s: RSA key missing p and/or q", __func__);
buffer_put_bignum2(&b, k->rsa->p);
buffer_put_bignum2(&b, k->rsa->q);
break;
case KEY_DSA:
if (k->dsa->priv_key == NULL)
fatal("%s: DSA key missing priv_key", __func__);
buffer_put_bignum2(&b, k->dsa->priv_key);
break;
default:
fatal("%s: unknown key type %d", __func__, k->type);
}
if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
&digest, &digest_len) != 0)
fatal("%s: hash_buffer", __func__);
buffer_free(&b);
if (len > digest_len)
fatal("%s: not enough bytes for rawsalt (want %u have %u)",
__func__, len, digest_len);
memcpy(rawsalt, digest, len);
bzero(digest, digest_len);
xfree(digest);
}
/* ASCII an integer [0, 64) for inclusion in a password/salt */
static char
pw_encode64(u_int i64)
{
const u_char e64[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
return e64[i64 % 64];
}
/* Generate ASCII salt bytes for user */
static char *
makesalt(u_int want, const char *user)
{
u_char rawsalt[32];
static char ret[33];
u_int i;
if (want > sizeof(ret) - 1)
fatal("%s: want %u", __func__, want);
derive_rawsalt(user, rawsalt, sizeof(rawsalt));
bzero(ret, sizeof(ret));
for (i = 0; i < want; i++)
ret[i] = pw_encode64(rawsalt[i]);
bzero(rawsalt, sizeof(rawsalt));
return ret;
}
/*
* Select the system's default password hashing scheme and generate
* a stable fake salt under it for use by a non-existent account.
* Prevents jpake method being used to infer the validity of accounts.
*/
static void
fake_salt_and_scheme(Authctxt *authctxt, char **salt, char **scheme)
{
char *rounds_s, *style;
long long rounds;
login_cap_t *lc;
if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL &&
(lc = login_getclass(NULL)) == NULL)
fatal("%s: login_getclass failed", __func__);
style = login_getcapstr(lc, "localcipher", NULL, NULL);
if (style == NULL)
style = xstrdup("blowfish,6");
login_close(lc);
if ((rounds_s = strchr(style, ',')) != NULL)
*rounds_s++ = '\0';
rounds = strtonum(rounds_s, 1, 1<<31, NULL);
if (strcmp(style, "md5") == 0) {
xasprintf(salt, "$1$%s$", makesalt(8, authctxt->user));
*scheme = xstrdup("md5");
} else if (strcmp(style, "old") == 0) {
*salt = xstrdup(makesalt(2, authctxt->user));
*scheme = xstrdup("crypt");
} else if (strcmp(style, "newsalt") == 0) {
rounds = MAX(rounds, 7250);
rounds = MIN(rounds, (1<<24) - 1);
xasprintf(salt, "_%c%c%c%c%s",
pw_encode64(rounds), pw_encode64(rounds >> 6),
pw_encode64(rounds >> 12), pw_encode64(rounds >> 18),
makesalt(4, authctxt->user));
*scheme = xstrdup("crypt-extended");
} else {
/* Default to blowfish */
rounds = MAX(rounds, 3);
rounds = MIN(rounds, 31);
xasprintf(salt, "$2a$%02lld$%s", rounds,
makesalt(22, authctxt->user));
*scheme = xstrdup("bcrypt");
}
xfree(style);
debug3("%s: fake %s salt for user %s: %s",
__func__, *scheme, authctxt->user, *salt);
}
/*
* Fetch password hashing scheme, password salt and derive shared secret
* for user. If user does not exist, a fake but stable and user-unique
* salt will be returned.
*/
void
auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
char **hash_scheme, char **salt)
{
char *cp;
u_char *secret;
u_int secret_len, salt_len;
#ifdef JPAKE_DEBUG
debug3("%s: valid %d pw %.5s...", __func__,
authctxt->valid, authctxt->pw->pw_passwd);
#endif
*salt = NULL;
*hash_scheme = NULL;
if (authctxt->valid) {
if (strncmp(authctxt->pw->pw_passwd, "$2$", 3) == 0 &&
strlen(authctxt->pw->pw_passwd) > 28) {
/*
* old-variant bcrypt:
* "$2$", 2 digit rounds, "$", 22 bytes salt
*/
salt_len = 3 + 2 + 1 + 22 + 1;
*salt = xmalloc(salt_len);
strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
*hash_scheme = xstrdup("bcrypt");
} else if (strncmp(authctxt->pw->pw_passwd, "$2a$", 4) == 0 &&
strlen(authctxt->pw->pw_passwd) > 29) {
/*
* current-variant bcrypt:
* "$2a$", 2 digit rounds, "$", 22 bytes salt
*/
salt_len = 4 + 2 + 1 + 22 + 1;
*salt = xmalloc(salt_len);
strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
*hash_scheme = xstrdup("bcrypt");
} else if (strncmp(authctxt->pw->pw_passwd, "$1$", 3) == 0 &&
strlen(authctxt->pw->pw_passwd) > 5) {
/*
* md5crypt:
* "$1$", salt until "$"
*/
cp = strchr(authctxt->pw->pw_passwd + 3, '$');
if (cp != NULL) {
salt_len = (cp - authctxt->pw->pw_passwd) + 1;
*salt = xmalloc(salt_len);
strlcpy(*salt, authctxt->pw->pw_passwd,
salt_len);
*hash_scheme = xstrdup("md5crypt");
}
} else if (strncmp(authctxt->pw->pw_passwd, "_", 1) == 0 &&
strlen(authctxt->pw->pw_passwd) > 9) {
/*
* BSDI extended crypt:
* "_", 4 digits count, 4 chars salt
*/
salt_len = 1 + 4 + 4 + 1;
*salt = xmalloc(salt_len);
strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
*hash_scheme = xstrdup("crypt-extended");
} else if (strlen(authctxt->pw->pw_passwd) == 13 &&
valid_crypt_salt(authctxt->pw->pw_passwd[0]) &&
valid_crypt_salt(authctxt->pw->pw_passwd[1])) {
/*
* traditional crypt:
* 2 chars salt
*/
salt_len = 2 + 1;
*salt = xmalloc(salt_len);
strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
*hash_scheme = xstrdup("crypt");
}
if (*salt == NULL) {
debug("%s: unrecognised crypt scheme for user %s",
__func__, authctxt->pw->pw_name);
}
}
if (*salt == NULL)
fake_salt_and_scheme(authctxt, salt, hash_scheme);
if (hash_buffer(authctxt->pw->pw_passwd,
strlen(authctxt->pw->pw_passwd), EVP_sha256(),
&secret, &secret_len) != 0)
fatal("%s: hash_buffer", __func__);
if ((*s = BN_bin2bn(secret, secret_len, NULL)) == NULL)
fatal("%s: BN_bin2bn (secret)", __func__);
#ifdef JPAKE_DEBUG
debug3("%s: salt = %s (len %u)", __func__,
*salt, (u_int)strlen(*salt));
debug3("%s: scheme = %s", __func__, *hash_scheme);
JPAKE_DEBUG_BN((*s, "%s: s = ", __func__));
#endif
bzero(secret, secret_len);
xfree(secret);
}
/*
* Being authentication attempt.
* Note, sets authctxt->postponed while in subprotocol
*/
static int
auth2_jpake_start(Authctxt *authctxt)
{
struct jpake_ctx *pctx = authctxt->jpake_ctx;
u_char *x3_proof, *x4_proof;
u_int x3_proof_len, x4_proof_len;
char *salt, *hash_scheme;
debug("%s: start", __func__);
PRIVSEP(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));
PRIVSEP(auth2_jpake_get_pwdata(authctxt, &pctx->s,
&hash_scheme, &salt));
if (!use_privsep)
JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));
packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1);
packet_put_cstring(hash_scheme);
packet_put_cstring(salt);
packet_put_string(pctx->server_id, pctx->server_id_len);
packet_put_bignum2(pctx->g_x3);
packet_put_bignum2(pctx->g_x4);
packet_put_string(x3_proof, x3_proof_len);
packet_put_string(x4_proof, x4_proof_len);
packet_send();
packet_write_wait();
bzero(hash_scheme, strlen(hash_scheme));
bzero(salt, strlen(salt));
xfree(hash_scheme);
xfree(salt);
bzero(x3_proof, x3_proof_len);
bzero(x4_proof, x4_proof_len);
xfree(x3_proof);
xfree(x4_proof);
/* Expect step 1 packet from peer */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1,
input_userauth_jpake_client_step1);
authctxt->postponed = 1;
return 0;
}
/* ARGSUSED */
static void
input_userauth_jpake_client_step1(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
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;
/* Disable this message */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL);
/* Fetch step 1 values */
if ((pctx->g_x1 = BN_new()) == NULL ||
(pctx->g_x2 = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
pctx->client_id = packet_get_string(&pctx->client_id_len);
packet_get_bignum2(pctx->g_x1);
packet_get_bignum2(pctx->g_x2);
x1_proof = packet_get_string(&x1_proof_len);
x2_proof = packet_get_string(&x2_proof_len);
packet_check_eom();
if (!use_privsep)
JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));
PRIVSEP(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));
bzero(x1_proof, x1_proof_len);
bzero(x2_proof, x2_proof_len);
xfree(x1_proof);
xfree(x2_proof);
if (!use_privsep)
JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));
/* Send values for step 2 */
packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2);
packet_put_bignum2(pctx->b);
packet_put_string(x4_s_proof, x4_s_proof_len);
packet_send();
packet_write_wait();
bzero(x4_s_proof, x4_s_proof_len);
xfree(x4_s_proof);
/* Expect step 2 packet from peer */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2,
input_userauth_jpake_client_step2);
}
/* ARGSUSED */
static void
input_userauth_jpake_client_step2(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
struct jpake_ctx *pctx = authctxt->jpake_ctx;
u_char *x2_s_proof;
u_int x2_s_proof_len;
/* Disable this message */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL);
if ((pctx->a = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
/* Fetch step 2 values */
packet_get_bignum2(pctx->a);
x2_s_proof = packet_get_string(&x2_s_proof_len);
packet_check_eom();
if (!use_privsep)
JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));
/* Derive shared key and calculate confirmation hash */
PRIVSEP(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));
bzero(x2_s_proof, x2_s_proof_len);
xfree(x2_s_proof);
if (!use_privsep)
JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));
/* Send key confirmation proof */
packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM);
packet_put_string(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
packet_send();
packet_write_wait();
/* Expect confirmation from peer */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM,
input_userauth_jpake_client_confirm);
}
/* ARGSUSED */
static void
input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
struct jpake_ctx *pctx = authctxt->jpake_ctx;
int authenticated = 0;
/* Disable this message */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL);
pctx->h_k_cid_sessid = packet_get_string(&pctx->h_k_cid_sessid_len);
packet_check_eom();
if (!use_privsep)
JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));
/* Verify expected confirmation hash */
if (PRIVSEP(jpake_check_confirm(pctx->k,
pctx->client_id, pctx->client_id_len,
session_id2, session_id2_len,
pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len)) == 1)
authenticated = authctxt->valid ? 1 : 0;
else
debug("%s: confirmation mismatch", __func__);
/* done */
authctxt->postponed = 0;
jpake_free(authctxt->jpake_ctx);
authctxt->jpake_ctx = NULL;
userauth_finish(authctxt, authenticated, method_jpake.name);
}
#endif /* JPAKE */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2.c,v 1.119 2008/07/04 23:30:16 djm Exp $ */
/* $OpenBSD: auth2.c,v 1.120 2008/11/04 08:22:12 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -73,12 +73,18 @@ extern Authmethod method_hostbased;
#ifdef GSSAPI
extern Authmethod method_gssapi;
#endif
#ifdef JPAKE
extern Authmethod method_jpake;
#endif
Authmethod *authmethods[] = {
&method_none,
&method_pubkey,
#ifdef GSSAPI
&method_gssapi,
#endif
#ifdef JPAKE
&method_jpake,
#endif
&method_passwd,
&method_kbdint,
@ -287,8 +293,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

View File

@ -1,4 +1,4 @@
/* $OpenBSD: canohost.c,v 1.63 2008/06/12 00:03:49 dtucker Exp $ */
/* $OpenBSD: canohost.c,v 1.64 2009/02/12 03:00:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -342,7 +342,7 @@ get_remote_name_or_ip(u_int utmp_len, int use_dns)
/* Returns the local/remote port for the socket. */
static int
int
get_sock_port(int sock, int local)
{
struct sockaddr_storage from;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: canohost.h,v 1.9 2006/03/25 22:22:42 djm Exp $ */
/* $OpenBSD: canohost.h,v 1.10 2009/02/12 03:00:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -23,5 +23,7 @@ char *get_local_name(int);
int get_remote_port(void);
int get_local_port(void);
int get_sock_port(int, int);
void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.c,v 1.286 2008/07/16 11:52:19 djm Exp $ */
/* $OpenBSD: channels.c,v 1.295 2009/02/12 03:00:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -296,6 +296,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
buffer_init(&c->input);
buffer_init(&c->output);
buffer_init(&c->extended);
c->path = NULL;
c->ostate = CHAN_OUTPUT_OPEN;
c->istate = CHAN_INPUT_OPEN;
c->flags = 0;
@ -402,6 +403,10 @@ channel_free(Channel *c)
xfree(c->remote_name);
c->remote_name = NULL;
}
if (c->path) {
xfree(c->path);
c->path = NULL;
}
while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
if (cc->abandon_cb != NULL)
cc->abandon_cb(c, cc->ctx);
@ -691,7 +696,7 @@ channel_register_open_confirm(int id, channel_callback_fn *fn, void *ctx)
Channel *c = channel_lookup(id);
if (c == NULL) {
logit("channel_register_open_comfirm: %d: bad id", id);
logit("channel_register_open_confirm: %d: bad id", id);
return;
}
c->open_confirm = fn;
@ -980,7 +985,7 @@ static int
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
{
char *p, *host;
u_int len, have, i, found;
u_int len, have, i, found, need;
char username[256];
struct {
u_int8_t version;
@ -996,10 +1001,20 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
if (have < len)
return 0;
p = buffer_ptr(&c->input);
need = 1;
/* SOCKS4A uses an invalid IP address 0.0.0.x */
if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) {
debug2("channel %d: socks4a request", c->self);
/* ... and needs an extra string (the hostname) */
need = 2;
}
/* Check for terminating NUL on the string(s) */
for (found = 0, i = len; i < have; i++) {
if (p[i] == '\0') {
found = 1;
break;
found++;
if (found == need)
break;
}
if (i > 1024) {
/* the peer is probably sending garbage */
@ -1008,7 +1023,7 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
return -1;
}
}
if (!found)
if (found < need)
return 0;
buffer_get(&c->input, (char *)&s4_req.version, 1);
buffer_get(&c->input, (char *)&s4_req.command, 1);
@ -1018,23 +1033,46 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
p = buffer_ptr(&c->input);
len = strlen(p);
debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
len++; /* trailing '\0' */
if (len > have)
fatal("channel %d: decode socks4: len %d > have %d",
c->self, len, have);
strlcpy(username, p, sizeof(username));
buffer_consume(&c->input, len);
buffer_consume(&c->input, 1); /* trailing '\0' */
host = inet_ntoa(s4_req.dest_addr);
strlcpy(c->path, host, sizeof(c->path));
if (c->path != NULL) {
xfree(c->path);
c->path = NULL;
}
if (need == 1) { /* SOCKS4: one string */
host = inet_ntoa(s4_req.dest_addr);
c->path = xstrdup(host);
} else { /* SOCKS4A: two strings */
have = buffer_len(&c->input);
p = buffer_ptr(&c->input);
len = strlen(p);
debug2("channel %d: decode socks4a: host %s/%d",
c->self, p, len);
len++; /* trailing '\0' */
if (len > have)
fatal("channel %d: decode socks4a: len %d > have %d",
c->self, len, have);
if (len > NI_MAXHOST) {
error("channel %d: hostname \"%.100s\" too long",
c->self, p);
return -1;
}
c->path = xstrdup(p);
buffer_consume(&c->input, len);
}
c->host_port = ntohs(s4_req.dest_port);
debug2("channel %d: dynamic request: socks4 host %s port %u command %u",
c->self, host, c->host_port, s4_req.command);
c->self, c->path, c->host_port, s4_req.command);
if (s4_req.command != 1) {
debug("channel %d: cannot handle: socks4 cn %d",
c->self, s4_req.command);
debug("channel %d: cannot handle: %s cn %d",
c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command);
return -1;
}
s4_rsp.version = 0; /* vn: 0 for reply */
@ -1065,7 +1103,7 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
u_int8_t atyp;
} s5_req, s5_rsp;
u_int16_t dest_port;
u_char *p, dest_addr[255+1];
u_char *p, dest_addr[255+1], ntop[INET6_ADDRSTRLEN];
u_int have, need, i, found, nmethods, addrlen, af;
debug2("channel %d: decode socks5", c->self);
@ -1138,10 +1176,22 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
buffer_get(&c->input, (char *)&dest_addr, addrlen);
buffer_get(&c->input, (char *)&dest_port, 2);
dest_addr[addrlen] = '\0';
if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
strlcpy(c->path, (char *)dest_addr, sizeof(c->path));
else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
return -1;
if (c->path != NULL) {
xfree(c->path);
c->path = NULL;
}
if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
if (addrlen >= NI_MAXHOST) {
error("channel %d: dynamic request: socks5 hostname "
"\"%.100s\" too long", c->self, dest_addr);
return -1;
}
c->path = xstrdup(dest_addr);
} else {
if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL)
return -1;
c->path = xstrdup(ntop);
}
c->host_port = ntohs(dest_port);
debug2("channel %d: dynamic request: socks5 host %s port %u command %u",
@ -1370,7 +1420,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
c->local_window_max, c->local_maxpacket, 0, rtype, 1);
nc->listening_port = c->listening_port;
nc->host_port = c->host_port;
strlcpy(nc->path, c->path, sizeof(nc->path));
if (c->path != NULL)
nc->path = xstrdup(c->path);
if (nextstate == SSH_CHANNEL_DYNAMIC) {
/*
@ -2311,8 +2362,8 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
xfree(lang);
}
packet_check_eom();
/* Free the channel. This will also close the socket. */
channel_free(c);
/* Schedule the channel for cleanup/deletion. */
chan_mark_dead(c);
}
/* ARGSUSED */
@ -2377,18 +2428,18 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
{
Channel *c;
struct channel_confirm *cc;
int remote_id;
int id;
/* Reset keepalive timeout */
keep_alive_timeouts = 0;
remote_id = packet_get_int();
id = packet_get_int();
packet_check_eom();
debug2("channel_input_confirm: type %d id %d", type, remote_id);
debug2("channel_input_status_confirm: type %d id %d", type, id);
if ((c = channel_lookup(remote_id)) == NULL) {
logit("channel_input_success_failure: %d: unknown", remote_id);
if ((c = channel_lookup(id)) == NULL) {
logit("channel_input_status_confirm: %d: unknown", id);
return;
}
;
@ -2409,7 +2460,8 @@ channel_set_af(int af)
}
static int
channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
channel_setup_fwd_listener(int type, const char *listen_addr,
u_short listen_port, int *allocated_listen_port,
const char *host_to_connect, u_short port_to_connect, int gateway_ports)
{
Channel *c;
@ -2417,6 +2469,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
struct addrinfo hints, *ai, *aitop;
const char *host, *addr;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
in_port_t *lport_p;
host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
listen_addr : host_to_connect;
@ -2426,7 +2479,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
error("No forward host name.");
return 0;
}
if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
if (strlen(host) >= NI_MAXHOST) {
error("Forward host name too long.");
return 0;
}
@ -2485,10 +2538,29 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
}
return 0;
}
if (allocated_listen_port != NULL)
*allocated_listen_port = 0;
for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
switch (ai->ai_family) {
case AF_INET:
lport_p = &((struct sockaddr_in *)ai->ai_addr)->
sin_port;
break;
case AF_INET6:
lport_p = &((struct sockaddr_in6 *)ai->ai_addr)->
sin6_port;
break;
default:
continue;
}
/*
* If allocating a port for -R forwards, then use the
* same port for all address families.
*/
if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
allocated_listen_port != NULL && *allocated_listen_port > 0)
*lport_p = htons(*allocated_listen_port);
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
error("channel_setup_fwd_listener: getnameinfo failed");
@ -2504,7 +2576,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
channel_set_reuseaddr(sock);
debug("Local forwarding listening on %s port %s.", ntop, strport);
debug("Local forwarding listening on %s port %s.",
ntop, strport);
/* Bind the socket to the address. */
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
@ -2523,11 +2596,24 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
close(sock);
continue;
}
/*
* listen_port == 0 requests a dynamically allocated port -
* record what we got.
*/
if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
allocated_listen_port != NULL &&
*allocated_listen_port == 0) {
*allocated_listen_port = get_sock_port(sock, 1);
debug("Allocated listen port %d",
*allocated_listen_port);
}
/* Allocate a channel number for the socket. */
c = channel_new("port listener", type, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, "port listener", 1);
strlcpy(c->path, host, sizeof(c->path));
c->path = xstrdup(host);
c->host_port = port_to_connect;
c->listening_port = listen_port;
success = 1;
@ -2549,8 +2635,7 @@ channel_cancel_rport_listener(const char *host, u_short port)
Channel *c = channels[i];
if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
strncmp(c->path, host, sizeof(c->path)) == 0 &&
c->listening_port == port) {
strcmp(c->path, host) == 0 && c->listening_port == port) {
debug2("%s: close channel %d", __func__, i);
channel_free(c);
found = 1;
@ -2566,17 +2651,18 @@ channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
const char *host_to_connect, u_short port_to_connect, int gateway_ports)
{
return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
listen_host, listen_port, host_to_connect, port_to_connect,
listen_host, listen_port, NULL, host_to_connect, port_to_connect,
gateway_ports);
}
/* protocol v2 remote port fwd, used by sshd */
int
channel_setup_remote_fwd_listener(const char *listen_address,
u_short listen_port, int gateway_ports)
u_short listen_port, int *allocated_listen_port, int gateway_ports)
{
return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
listen_address, listen_port, NULL, 0, gateway_ports);
listen_address, listen_port, allocated_listen_port,
NULL, 0, gateway_ports);
}
/*
@ -2791,10 +2877,16 @@ channel_print_adm_permitted_opens(void)
{
int i;
printf("permitopen");
if (num_adm_permitted_opens == 0) {
printf(" any\n");
return;
}
for (i = 0; i < num_adm_permitted_opens; i++)
if (permitted_adm_opens[i].host_to_connect != NULL)
printf(" %s:%d", permitted_adm_opens[i].host_to_connect,
permitted_adm_opens[i].port_to_connect);
printf("\n");
}
/* Try to start non-blocking connect to next host in cctx list */
@ -3074,7 +3166,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
}
static int
connect_local_xsocket(u_int dnr)
connect_local_xsocket_path(const char *pathname)
{
int sock;
struct sockaddr_un addr;
@ -3084,7 +3176,7 @@ connect_local_xsocket(u_int dnr)
error("socket: %.100s", strerror(errno));
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
return sock;
close(sock);
@ -3092,6 +3184,14 @@ connect_local_xsocket(u_int dnr)
return -1;
}
static int
connect_local_xsocket(u_int dnr)
{
char buf[1024];
snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);
return connect_local_xsocket_path(buf);
}
int
x11_connect_display(void)
{
@ -3113,6 +3213,17 @@ x11_connect_display(void)
* connection to the real X server.
*/
/* Check if the display is from launchd. */
#ifdef __APPLE__
if (strncmp(display, "/tmp/launch", 11) == 0) {
sock = connect_local_xsocket_path(display);
if (sock < 0)
return -1;
/* OK, we now have a connection to the display. */
return sock;
}
#endif
/*
* Check if it is a unix domain socket. Unix domain displays are in
* one of the following formats: unix:d[.s], :d[.s], ::d[.s]

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.96 2008/06/15 20:06:26 djm Exp $ */
/* $OpenBSD: channels.h,v 1.98 2009/02/12 03:00:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -55,8 +55,6 @@
#define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */
#define SSH_CHANNEL_MAX_TYPE 15
#define SSH_CHANNEL_PATH_LEN 256
struct Channel;
typedef struct Channel Channel;
@ -105,7 +103,7 @@ struct Channel {
Buffer output; /* data received over encrypted connection for
* send on socket */
Buffer extended;
char path[SSH_CHANNEL_PATH_LEN];
char *path;
/* path for unix domain sockets, or host name for forwards */
int listening_port; /* port being listened for forwards */
int host_port; /* remote port to connect for forwards */
@ -247,7 +245,7 @@ int channel_request_remote_forwarding(const char *, u_short,
int channel_setup_local_fwd_listener(const char *, u_short,
const char *, u_short, int);
void channel_request_rforward_cancel(const char *host, u_short port);
int channel_setup_remote_fwd_listener(const char *, u_short, int);
int channel_setup_remote_fwd_listener(const char *, u_short, int *, int);
int channel_cancel_rport_listener(const char *, u_short);
/* x11 forwarding */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cipher.c,v 1.81 2006/08/03 03:34:42 deraadt Exp $ */
/* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -63,31 +63,32 @@ struct Cipher {
u_int block_size;
u_int key_len;
u_int discard_len;
u_int cbc_mode;
const EVP_CIPHER *(*evptype)(void);
} ciphers[] = {
{ "none", SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null },
{ "des", SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc },
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des },
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf },
{ "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, 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 },
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc },
{ "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc },
{ "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc },
{ "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 },
{ "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 },
{ "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 },
{ "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc },
{ "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc },
{ "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
{ "rijndael-cbc@lysator.liu.se",
SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr },
#ifdef USE_CIPHER_ACSS
{ "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
{ "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss },
#endif
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, NULL }
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL }
};
/*--*/
@ -110,6 +111,12 @@ cipher_get_number(const Cipher *c)
return (c->number);
}
u_int
cipher_is_cbc(const Cipher *c)
{
return (c->cbc_mode);
}
u_int
cipher_mask_ssh1(int client)
{

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cipher.h,v 1.36 2006/03/25 22:22:42 djm Exp $ */
/* $OpenBSD: cipher.h,v 1.37 2009/01/26 09:58:15 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -81,6 +81,7 @@ void cipher_cleanup(CipherContext *);
void cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
u_int cipher_blocksize(const Cipher *);
u_int cipher_keylen(const Cipher *);
u_int cipher_is_cbc(const Cipher *);
u_int cipher_get_number(const Cipher *);
void cipher_get_keyiv(CipherContext *, u_char *, u_int);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.201 2008/07/16 11:51:14 djm Exp $ */
/* $OpenBSD: clientloop.c,v 1.209 2009/02/12 03:00:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -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) {
@ -1722,7 +1728,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
return 0;
if (!compat20) {
error("Tunnel forwarding is not support for protocol 1");
error("Tunnel forwarding is not supported for protocol 1");
return -1;
}
@ -1846,7 +1852,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
if (reply) {
packet_start(success ?
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
packet_put_int(id);
packet_put_int(c->remote_id);
packet_send();
}
xfree(rtype);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: compat.c,v 1.77 2006/12/12 03:58:42 djm Exp $ */
/* $OpenBSD: compat.c,v 1.78 2008/09/11 14:22:37 markus Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@ -91,7 +91,8 @@ compat_datafellows(const char *version)
"OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR },
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
{ "OpenSSH*", 0 },
{ "OpenSSH_4*", 0 },
{ "OpenSSH*", SSH_NEW_OPENSSH },
{ "*MindTerm*", 0 },
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|

View File

@ -1,4 +1,4 @@
/* $OpenBSD: compat.h,v 1.41 2006/12/12 03:58:42 djm Exp $ */
/* $OpenBSD: compat.h,v 1.42 2008/09/11 14:22:37 markus Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@ -57,6 +57,7 @@
#define SSH_BUG_FIRSTKEX 0x00800000
#define SSH_OLD_FORWARD_ADDR 0x01000000
#define SSH_BUG_RFWD_ADDR 0x02000000
#define SSH_NEW_OPENSSH 0x04000000
void enable_compat13(void);
void enable_compat20(void);

View File

@ -1,9 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
timestamp='2005-05-27'
timestamp='2008-04-14'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -55,8 +56,8 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -106,7 +107,7 @@ set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
@ -125,7 +126,7 @@ case $CC_FOR_BUILD,$HOST_CC,$CC in
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac ;'
esac ; set_cc_for_build= ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
@ -160,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
@ -199,50 +201,18 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
amd64:OpenBSD:*:*)
echo x86_64-unknown-openbsd${UNAME_RELEASE}
exit ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit ;;
cats:OpenBSD:*:*)
echo arm-unknown-openbsd${UNAME_RELEASE}
exit ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit ;;
luna88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit ;;
macppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit ;;
mvmeppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit ;;
sgi:OpenBSD:*:*)
echo mips64-unknown-openbsd${UNAME_RELEASE}
exit ;;
sun3:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
*:SolidBSD:*:*)
echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
exit ;;
macppc:MirBSD:*:*)
echo powerppc-unknown-mirbsd${UNAME_RELEASE}
echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
@ -360,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:SunOS:5.*:*)
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
@ -562,7 +532,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[45])
*:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@ -658,8 +628,7 @@ EOF
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
# avoid double evaluation of $set_cc_for_build
test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
eval $set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
@ -800,12 +769,19 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
case ${UNAME_MACHINE} in
pc98)
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
i*:MINGW*:*)
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
@ -815,9 +791,18 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
x86:Interix*:[34]*)
echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
exit ;;
*:Interix*:[3456]*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
@ -830,7 +815,7 @@ EOF
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit ;;
amd64:CYGWIN*:*:*)
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
p*:CYGWIN*:*)
@ -851,6 +836,16 @@ EOF
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
@ -887,7 +882,11 @@ EOF
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
@ -906,9 +905,16 @@ EOF
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
echo or32-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
@ -952,9 +958,15 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
@ -973,9 +985,6 @@ EOF
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
@ -997,7 +1006,7 @@ EOF
LIBC=gnulibc1
# endif
#else
#ifdef __INTEL_COMPILER
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu
#else
LIBC=gnuaout
@ -1007,7 +1016,11 @@ EOF
LIBC=dietlibc
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^LIBC/{
s: ::g
p
}'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
@ -1200,6 +1213,9 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@ -1209,6 +1225,15 @@ EOF
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
SX-7:SUPER-UX:*:*)
echo sx7-nec-superux${UNAME_RELEASE}
exit ;;
SX-8:SUPER-UX:*:*)
echo sx8-nec-superux${UNAME_RELEASE}
exit ;;
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@ -1218,7 +1243,6 @@ EOF
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
*86) UNAME_PROCESSOR=i686 ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@ -1297,6 +1321,9 @@ EOF
i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@ -1457,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be

View File

@ -292,7 +292,7 @@
#define HAVE_DECL__GETSHORT 0
/* Define if you have /dev/ptmx */
/* #undef HAVE_DEV_PTMX */
#define HAVE_DEV_PTMX 1
/* Define if you have /dev/ptc */
/* #undef HAVE_DEV_PTS_AND_PTC */
@ -381,6 +381,9 @@
/* Define to 1 if you have the `getgrset' function. */
/* #undef HAVE_GETGRSET */
/* Define to 1 if you have the `getlastlogxbyname' function. */
/* #undef HAVE_GETLASTLOGXBYNAME */
/* Define to 1 if you have the `getluid' function. */
/* #undef HAVE_GETLUID */
@ -898,6 +901,9 @@
/* define if you have struct sockaddr_in6 data type */
#define HAVE_STRUCT_SOCKADDR_IN6 1
/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */
#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1
/* define if you have struct sockaddr_storage data type */
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
@ -1159,6 +1165,9 @@
/* Define if you want Kerberos 5 support */
/* #undef KRB5 */
/* Define if pututxline updates lastlog too */
/* #undef LASTLOG_WRITE_PUTUTXLINE */
/* Define if you want TCP Wrappers support */
#define LIBWRAP 1

View File

@ -380,6 +380,9 @@
/* Define to 1 if you have the `getgrset' function. */
#undef HAVE_GETGRSET
/* Define to 1 if you have the `getlastlogxbyname' function. */
#undef HAVE_GETLASTLOGXBYNAME
/* Define to 1 if you have the `getluid' function. */
#undef HAVE_GETLUID
@ -897,6 +900,9 @@
/* define if you have struct sockaddr_in6 data type */
#undef HAVE_STRUCT_SOCKADDR_IN6
/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */
#undef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
/* define if you have struct sockaddr_storage data type */
#undef HAVE_STRUCT_SOCKADDR_STORAGE
@ -1158,6 +1164,9 @@
/* Define if you want Kerberos 5 support */
#undef KRB5
/* Define if pututxline updates lastlog too */
#undef LASTLOG_WRITE_PUTUTXLINE
/* Define if you want TCP Wrappers support */
#undef LIBWRAP

View File

@ -25,7 +25,7 @@
#ifndef _DEFINES_H
#define _DEFINES_H
/* $Id: defines.h,v 1.151 2008/07/04 13:10:49 djm Exp $ */
/* $Id: defines.h,v 1.153 2009/02/01 11:19:54 dtucker Exp $ */
/* Constants */
@ -698,7 +698,7 @@ struct winsize {
# define CUSTOM_SYS_AUTH_PASSWD 1
#endif
#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID)
#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(HAVE_SECUREWARE)
# define CUSTOM_SYS_AUTH_PASSWD 1
#endif
#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF)
@ -738,4 +738,8 @@ struct winsize {
# define EWOULDBLOCK EAGAIN
#endif
#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */
#define INET6_ADDRSTRLEN 46
#endif
#endif /* _DEFINES_H */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dispatch.c,v 1.21 2006/08/03 03:34:42 deraadt Exp $ */
/* $OpenBSD: dispatch.c,v 1.22 2008/10/31 15:05:34 stevesk Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -37,7 +37,6 @@
#include "packet.h"
#include "compat.h"
#define DISPATCH_MIN 0
#define DISPATCH_MAX 255
dispatch_fn *dispatch[DISPATCH_MAX];

604
crypto/openssh/jpake.c Normal file
View File

@ -0,0 +1,604 @@
/* $OpenBSD: jpake.c,v 1.1 2008/11/04 08:22:12 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Shared components of zero-knowledge password auth using J-PAKE protocol
* as described in:
*
* F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling",
* 16th Workshop on Security Protocols, Cambridge, April 2008
*
* http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
*/
#include "includes.h"
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include "xmalloc.h"
#include "ssh2.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "buffer.h"
#include "packet.h"
#include "dispatch.h"
#include "log.h"
#include "jpake.h"
#ifdef JPAKE
/* RFC3526 group 5, 1536 bits */
#define JPAKE_GROUP_G "2"
#define JPAKE_GROUP_P \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74" \
"020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437" \
"4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05" \
"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" \
"9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
struct jpake_group *
jpake_default_group(void)
{
struct jpake_group *ret;
ret = xmalloc(sizeof(*ret));
ret->p = ret->q = ret->g = NULL;
if (BN_hex2bn(&ret->p, JPAKE_GROUP_P) == 0 ||
BN_hex2bn(&ret->g, JPAKE_GROUP_G) == 0)
fatal("%s: BN_hex2bn", __func__);
/* Subgroup order is p/2 (p is a safe prime) */
if ((ret->q = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
if (BN_rshift1(ret->q, ret->p) != 1)
fatal("%s: BN_rshift1", __func__);
return ret;
}
/*
* Generate uniformly distributed random number in range (1, high).
* Return number on success, NULL on failure.
*/
BIGNUM *
bn_rand_range_gt_one(const BIGNUM *high)
{
BIGNUM *r, *tmp;
int success = -1;
if ((tmp = BN_new()) == NULL) {
error("%s: BN_new", __func__);
return NULL;
}
if ((r = BN_new()) == NULL) {
error("%s: BN_new failed", __func__);
goto out;
}
if (BN_set_word(tmp, 2) != 1) {
error("%s: BN_set_word(tmp, 2)", __func__);
goto out;
}
if (BN_sub(tmp, high, tmp) == -1) {
error("%s: BN_sub failed (tmp = high - 2)", __func__);
goto out;
}
if (BN_rand_range(r, tmp) == -1) {
error("%s: BN_rand_range failed", __func__);
goto out;
}
if (BN_set_word(tmp, 2) != 1) {
error("%s: BN_set_word(tmp, 2)", __func__);
goto out;
}
if (BN_add(r, r, tmp) == -1) {
error("%s: BN_add failed (r = r + 2)", __func__);
goto out;
}
success = 0;
out:
BN_clear_free(tmp);
if (success == 0)
return r;
BN_clear_free(r);
return NULL;
}
/*
* Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
* with digest via 'digestp' (caller to free) and length via 'lenp'.
* Returns -1 on failure.
*/
int
hash_buffer(const u_char *buf, u_int len, const EVP_MD *md,
u_char **digestp, u_int *lenp)
{
u_char digest[EVP_MAX_MD_SIZE];
u_int digest_len;
EVP_MD_CTX evp_md_ctx;
int success = -1;
EVP_MD_CTX_init(&evp_md_ctx);
if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) {
error("%s: EVP_DigestInit_ex", __func__);
goto out;
}
if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
error("%s: EVP_DigestUpdate", __func__);
goto out;
}
if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) {
error("%s: EVP_DigestFinal_ex", __func__);
goto out;
}
*digestp = xmalloc(digest_len);
*lenp = digest_len;
memcpy(*digestp, digest, *lenp);
success = 0;
out:
EVP_MD_CTX_cleanup(&evp_md_ctx);
bzero(digest, sizeof(digest));
digest_len = 0;
return success;
}
/* print formatted string followed by bignum */
void
jpake_debug3_bn(const BIGNUM *n, const char *fmt, ...)
{
char *out, *h;
va_list args;
out = NULL;
va_start(args, fmt);
vasprintf(&out, fmt, args);
va_end(args);
if (out == NULL)
fatal("%s: vasprintf failed", __func__);
if (n == NULL)
debug3("%s(null)", out);
else {
h = BN_bn2hex(n);
debug3("%s0x%s", out, h);
free(h);
}
free(out);
}
/* print formatted string followed by buffer contents in hex */
void
jpake_debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
{
char *out, h[65];
u_int i, j;
va_list args;
out = NULL;
va_start(args, fmt);
vasprintf(&out, fmt, args);
va_end(args);
if (out == NULL)
fatal("%s: vasprintf failed", __func__);
debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
free(out);
if (buf == NULL)
return;
*h = '\0';
for (i = j = 0; i < len; i++) {
snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
j += 2;
if (j >= sizeof(h) - 1 || i == len - 1) {
debug3(" %s", h);
*h = '\0';
j = 0;
}
}
}
struct jpake_ctx *
jpake_new(void)
{
struct jpake_ctx *ret;
ret = xcalloc(1, sizeof(*ret));
ret->grp = jpake_default_group();
ret->s = ret->k = NULL;
ret->x1 = ret->x2 = ret->x3 = ret->x4 = NULL;
ret->g_x1 = ret->g_x2 = ret->g_x3 = ret->g_x4 = NULL;
ret->a = ret->b = NULL;
ret->client_id = ret->server_id = NULL;
ret->h_k_cid_sessid = ret->h_k_sid_sessid = NULL;
debug3("%s: alloc %p", __func__, ret);
return ret;
}
void
jpake_free(struct jpake_ctx *pctx)
{
debug3("%s: free %p", __func__, pctx);
#define JPAKE_BN_CLEAR_FREE(v) \
do { \
if ((v) != NULL) { \
BN_clear_free(v); \
(v) = NULL; \
} \
} while (0)
#define JPAKE_BUF_CLEAR_FREE(v, l) \
do { \
if ((v) != NULL) { \
bzero((v), (l)); \
xfree(v); \
(v) = NULL; \
(l) = 0; \
} \
} while (0)
JPAKE_BN_CLEAR_FREE(pctx->s);
JPAKE_BN_CLEAR_FREE(pctx->k);
JPAKE_BN_CLEAR_FREE(pctx->x1);
JPAKE_BN_CLEAR_FREE(pctx->x2);
JPAKE_BN_CLEAR_FREE(pctx->x3);
JPAKE_BN_CLEAR_FREE(pctx->x4);
JPAKE_BN_CLEAR_FREE(pctx->g_x1);
JPAKE_BN_CLEAR_FREE(pctx->g_x2);
JPAKE_BN_CLEAR_FREE(pctx->g_x3);
JPAKE_BN_CLEAR_FREE(pctx->g_x4);
JPAKE_BN_CLEAR_FREE(pctx->a);
JPAKE_BN_CLEAR_FREE(pctx->b);
JPAKE_BUF_CLEAR_FREE(pctx->client_id, pctx->client_id_len);
JPAKE_BUF_CLEAR_FREE(pctx->server_id, pctx->server_id_len);
JPAKE_BUF_CLEAR_FREE(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
JPAKE_BUF_CLEAR_FREE(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
#undef JPAKE_BN_CLEAR_FREE
#undef JPAKE_BUF_CLEAR_FREE
bzero(pctx, sizeof(pctx));
xfree(pctx);
}
/* dump entire jpake_ctx. NB. includes private values! */
void
jpake_dump(struct jpake_ctx *pctx, const char *fmt, ...)
{
char *out;
va_list args;
out = NULL;
va_start(args, fmt);
vasprintf(&out, fmt, args);
va_end(args);
if (out == NULL)
fatal("%s: vasprintf failed", __func__);
debug3("%s: %s (ctx at %p)", __func__, out, pctx);
if (pctx == NULL) {
free(out);
return;
}
#define JPAKE_DUMP_BN(a) do { \
if ((a) != NULL) \
JPAKE_DEBUG_BN(((a), "%s = ", #a)); \
} while (0)
#define JPAKE_DUMP_BUF(a, b) do { \
if ((a) != NULL) \
JPAKE_DEBUG_BUF((a, b, "%s", #a)); \
} while (0)
JPAKE_DUMP_BN(pctx->s);
JPAKE_DUMP_BN(pctx->k);
JPAKE_DUMP_BN(pctx->x1);
JPAKE_DUMP_BN(pctx->x2);
JPAKE_DUMP_BN(pctx->x3);
JPAKE_DUMP_BN(pctx->x4);
JPAKE_DUMP_BN(pctx->g_x1);
JPAKE_DUMP_BN(pctx->g_x2);
JPAKE_DUMP_BN(pctx->g_x3);
JPAKE_DUMP_BN(pctx->g_x4);
JPAKE_DUMP_BN(pctx->a);
JPAKE_DUMP_BN(pctx->b);
JPAKE_DUMP_BUF(pctx->client_id, pctx->client_id_len);
JPAKE_DUMP_BUF(pctx->server_id, pctx->server_id_len);
JPAKE_DUMP_BUF(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
JPAKE_DUMP_BUF(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
debug3("%s: %s done", __func__, out);
free(out);
}
/* Shared parts of step 1 exchange calculation */
void
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)
{
BN_CTX *bn_ctx;
if ((bn_ctx = BN_CTX_new()) == NULL)
fatal("%s: BN_CTX_new", __func__);
/* Random nonce to prevent replay */
*id = xmalloc(KZP_ID_LEN);
*id_len = KZP_ID_LEN;
arc4random_buf(*id, *id_len);
/*
* x1/x3 is a random element of Zq
* x2/x4 is a random element of Z*q
* We also exclude [1] from x1/x3 candidates and [0, 1] from
* x2/x4 candiates to avoid possible degeneracy (i.e. g^0, g^1).
*/
if ((*priv1 = bn_rand_range_gt_one(grp->q)) == NULL ||
(*priv2 = bn_rand_range_gt_one(grp->q)) == NULL)
fatal("%s: bn_rand_range_gt_one", __func__);
/*
* client: g_x1 = g^x1 mod p / server: g_x3 = g^x3 mod p
* client: g_x2 = g^x2 mod p / server: g_x4 = g^x4 mod p
*/
if ((*g_priv1 = BN_new()) == NULL ||
(*g_priv2 = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
if (BN_mod_exp(*g_priv1, grp->g, *priv1, grp->p, bn_ctx) == -1)
fatal("%s: BN_mod_exp", __func__);
if (BN_mod_exp(*g_priv2, grp->g, *priv2, grp->p, bn_ctx) == -1)
fatal("%s: BN_mod_exp", __func__);
/* Generate proofs for holding x1/x3 and x2/x4 */
if (schnorr_sign(grp->p, grp->q, grp->g,
*priv1, *g_priv1, *id, *id_len,
priv1_proof, priv1_proof_len) != 0)
fatal("%s: schnorr_sign", __func__);
if (schnorr_sign(grp->p, grp->q, grp->g,
*priv2, *g_priv2, *id, *id_len,
priv2_proof, priv2_proof_len) != 0)
fatal("%s: schnorr_sign", __func__);
BN_CTX_free(bn_ctx);
}
/* Shared parts of step 2 exchange calculation */
void
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)
{
BN_CTX *bn_ctx;
BIGNUM *tmp, *exponent;
/* Validate peer's step 1 values */
if (BN_cmp(theirpub1, BN_value_one()) <= 0)
fatal("%s: theirpub1 <= 1", __func__);
if (BN_cmp(theirpub2, BN_value_one()) <= 0)
fatal("%s: theirpub2 <= 1", __func__);
if (schnorr_verify(grp->p, grp->q, grp->g, theirpub1,
theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1)
fatal("%s: schnorr_verify theirpub1 failed", __func__);
if (schnorr_verify(grp->p, grp->q, grp->g, theirpub2,
theirid, theirid_len, theirpub2_proof, theirpub2_proof_len) != 1)
fatal("%s: schnorr_verify theirpub2 failed", __func__);
if ((bn_ctx = BN_CTX_new()) == NULL)
fatal("%s: BN_CTX_new", __func__);
if ((*newpub = BN_new()) == NULL ||
(tmp = BN_new()) == NULL ||
(exponent = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
/*
* client: exponent = x2 * s mod p
* server: exponent = x4 * s mod p
*/
if (BN_mod_mul(exponent, mypriv2, s, grp->q, bn_ctx) != 1)
fatal("%s: BN_mod_mul (exponent = mypriv2 * s mod p)",
__func__);
/*
* client: tmp = g^(x1 + x3 + x4) mod p
* server: tmp = g^(x1 + x2 + x3) mod p
*/
if (BN_mod_mul(tmp, mypub1, theirpub1, grp->p, bn_ctx) != 1)
fatal("%s: BN_mod_mul (tmp = mypub1 * theirpub1 mod p)",
__func__);
if (BN_mod_mul(tmp, tmp, theirpub2, grp->p, bn_ctx) != 1)
fatal("%s: BN_mod_mul (tmp = tmp * theirpub2 mod p)", __func__);
/*
* client: a = tmp^exponent = g^((x1+x3+x4) * x2 * s) mod p
* server: b = tmp^exponent = g^((x1+x2+x3) * x4 * s) mod p
*/
if (BN_mod_exp(*newpub, tmp, exponent, grp->p, bn_ctx) != 1)
fatal("%s: BN_mod_mul (newpub = tmp^exponent mod p)", __func__);
JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__));
JPAKE_DEBUG_BN((exponent, "%s: exponent = ", __func__));
/* Note the generator here is 'tmp', not g */
if (schnorr_sign(grp->p, grp->q, tmp, exponent, *newpub,
myid, myid_len,
newpub_exponent_proof, newpub_exponent_proof_len) != 0)
fatal("%s: schnorr_sign newpub", __func__);
BN_clear_free(tmp); /* XXX stash for later use? */
BN_clear_free(exponent); /* XXX stash for later use? (yes, in conf) */
BN_CTX_free(bn_ctx);
}
/* Confirmation hash calculation */
void
jpake_confirm_hash(const BIGNUM *k,
const u_char *endpoint_id, u_int endpoint_id_len,
const u_char *sess_id, u_int sess_id_len,
u_char **confirm_hash, u_int *confirm_hash_len)
{
Buffer b;
/*
* Calculate confirmation proof:
* client: H(k || client_id || session_id)
* server: H(k || server_id || session_id)
*/
buffer_init(&b);
buffer_put_bignum2(&b, k);
buffer_put_string(&b, endpoint_id, endpoint_id_len);
buffer_put_string(&b, sess_id, sess_id_len);
if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
confirm_hash, confirm_hash_len) != 0)
fatal("%s: hash_buffer", __func__);
buffer_free(&b);
}
/* Shared parts of key derivation and confirmation calculation */
void
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)
{
BN_CTX *bn_ctx;
BIGNUM *tmp;
if ((bn_ctx = BN_CTX_new()) == NULL)
fatal("%s: BN_CTX_new", __func__);
if ((tmp = BN_new()) == NULL ||
(*k = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
/* Validate step 2 values */
if (BN_cmp(step2_val, BN_value_one()) <= 0)
fatal("%s: step2_val <= 1", __func__);
/*
* theirpriv2_s_proof is calculated with a different generator:
* tmp = g^(mypriv1+mypriv2+theirpub1) = g^mypub1*g^mypub2*g^theirpub1
* Calculate it here so we can check the signature.
*/
if (BN_mod_mul(tmp, mypub1, mypub2, grp->p, bn_ctx) != 1)
fatal("%s: BN_mod_mul (tmp = mypub1 * mypub2 mod p)", __func__);
if (BN_mod_mul(tmp, tmp, theirpub1, grp->p, bn_ctx) != 1)
fatal("%s: BN_mod_mul (tmp = tmp * theirpub1 mod p)", __func__);
JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__));
if (schnorr_verify(grp->p, grp->q, tmp, step2_val,
their_id, their_id_len,
theirpriv2_s_proof, theirpriv2_s_proof_len) != 1)
fatal("%s: schnorr_verify theirpriv2_s_proof failed", __func__);
/*
* Derive shared key:
* client: k = (b / g^(x2*x4*s))^x2 = g^((x1+x3)*x2*x4*s)
* server: k = (a / g^(x2*x4*s))^x4 = g^((x1+x3)*x2*x4*s)
*
* Computed as:
* client: k = (g_x4^(q - (x2 * s)) * b)^x2 mod p
* server: k = (g_x2^(q - (x4 * s)) * b)^x4 mod p
*/
if (BN_mul(tmp, mypriv2, s, bn_ctx) != 1)
fatal("%s: BN_mul (tmp = mypriv2 * s)", __func__);
if (BN_mod_sub(tmp, grp->q, tmp, grp->q, bn_ctx) != 1)
fatal("%s: BN_mod_sub (tmp = q - tmp mod q)", __func__);
if (BN_mod_exp(tmp, theirpub2, tmp, grp->p, bn_ctx) != 1)
fatal("%s: BN_mod_exp (tmp = theirpub2^tmp) mod p", __func__);
if (BN_mod_mul(tmp, tmp, step2_val, grp->p, bn_ctx) != 1)
fatal("%s: BN_mod_mul (tmp = tmp * step2_val) mod p", __func__);
if (BN_mod_exp(*k, tmp, mypriv2, grp->p, bn_ctx) != 1)
fatal("%s: BN_mod_exp (k = tmp^mypriv2) mod p", __func__);
BN_CTX_free(bn_ctx);
BN_clear_free(tmp);
jpake_confirm_hash(*k, my_id, my_id_len, sess_id, sess_id_len,
confirm_hash, confirm_hash_len);
}
/*
* Calculate and check confirmation hash from peer. Returns 1 on success
* 0 on failure/mismatch.
*/
int
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)
{
u_char *expected_confirm_hash;
u_int expected_confirm_hash_len;
int success = 0;
/* Calculate and verify expected confirmation hash */
jpake_confirm_hash(k, peer_id, peer_id_len, sess_id, sess_id_len,
&expected_confirm_hash, &expected_confirm_hash_len);
JPAKE_DEBUG_BUF((expected_confirm_hash, expected_confirm_hash_len,
"%s: expected confirm hash", __func__));
JPAKE_DEBUG_BUF((peer_confirm_hash, peer_confirm_hash_len,
"%s: received confirm hash", __func__));
if (peer_confirm_hash_len != expected_confirm_hash_len)
error("%s: confirmation length mismatch (my %u them %u)",
__func__, expected_confirm_hash_len, peer_confirm_hash_len);
else if (memcmp(peer_confirm_hash, expected_confirm_hash,
expected_confirm_hash_len) == 0)
success = 1;
bzero(expected_confirm_hash, expected_confirm_hash_len);
xfree(expected_confirm_hash);
debug3("%s: success = %d", __func__, success);
return success;
}
/* XXX main() function with tests */
#endif /* JPAKE */

134
crypto/openssh/jpake.h Normal file
View File

@ -0,0 +1,134 @@
/* $OpenBSD: jpake.h,v 1.1 2008/11/04 08:22:13 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef JPAKE_H
#define JPAKE_H
#include <sys/types.h>
#include <openssl/bn.h>
/* Set JPAKE_DEBUG in CFLAGS for privacy-violating debugging */
#ifndef JPAKE_DEBUG
# define JPAKE_DEBUG_BN(a)
# define JPAKE_DEBUG_BUF(a)
# define JPAKE_DEBUG_CTX(a)
#else
# define JPAKE_DEBUG_BN(a) jpake_debug3_bn a
# define JPAKE_DEBUG_BUF(a) jpake_debug3_buf a
# define JPAKE_DEBUG_CTX(a) jpake_dump a
#endif /* SCHNORR_DEBUG */
struct jpake_group {
BIGNUM *p, *q, *g;
};
#define KZP_ID_LEN 16 /* Length of client and server IDs */
struct jpake_ctx {
/* Parameters */
struct jpake_group *grp;
/* Private values shared by client and server */
BIGNUM *s; /* Secret (salted, crypted password) */
BIGNUM *k; /* Derived key */
/* Client private values (NULL for server) */
BIGNUM *x1; /* random in Zq */
BIGNUM *x2; /* random in Z*q */
/* Server private values (NULL for server) */
BIGNUM *x3; /* random in Zq */
BIGNUM *x4; /* random in Z*q */
/* Step 1: C->S */
u_char *client_id; /* Anti-replay nonce */
u_int client_id_len;
BIGNUM *g_x1; /* g^x1 */
BIGNUM *g_x2; /* g^x2 */
/* Step 1: S->C */
u_char *server_id; /* Anti-replay nonce */
u_int server_id_len;
BIGNUM *g_x3; /* g^x3 */
BIGNUM *g_x4; /* g^x4 */
/* Step 2: C->S */
BIGNUM *a; /* g^((x1+x3+x4)*x2*s) */
/* Step 2: S->C */
BIGNUM *b; /* g^((x1+x2+x3)*x4*s) */
/* Confirmation: C->S */
u_char *h_k_cid_sessid; /* H(k || client_id || session_id) */
u_int h_k_cid_sessid_len;
/* Confirmation: S->C */
u_char *h_k_sid_sessid; /* H(k || server_id || session_id) */
u_int h_k_sid_sessid_len;
};
/* jpake.c */
struct jpake_group *jpake_default_group(void);
BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *);
void jpake_debug3_bn(const BIGNUM *, const char *, ...)
__attribute__((__nonnull__ (2)))
__attribute__((format(printf, 2, 3)));
void jpake_debug3_buf(const u_char *, u_int, const char *, ...)
__attribute__((__nonnull__ (3)))
__attribute__((format(printf, 3, 4)));
void jpake_dump(struct jpake_ctx *, const char *, ...)
__attribute__((__nonnull__ (2)))
__attribute__((format(printf, 2, 3)));
struct jpake_ctx *jpake_new(void);
void jpake_free(struct jpake_ctx *);
void jpake_step1(struct jpake_group *, u_char **, u_int *,
BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
u_char **, u_int *, u_char **, u_int *);
void jpake_step2(struct jpake_group *, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int,
BIGNUM **, u_char **, u_int *);
void jpake_confirm_hash(const BIGNUM *,
const u_char *, u_int,
const u_char *, u_int,
u_char **, u_int *);
void jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int,
BIGNUM **, u_char **, u_int *);
int jpake_check_confirm(const BIGNUM *, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int);
/* schnorr.c */
int schnorr_sign(const BIGNUM *, const BIGNUM *, const BIGNUM *,
const BIGNUM *, const BIGNUM *, const u_char *, u_int ,
u_char **, u_int *);
int schnorr_verify(const BIGNUM *, const BIGNUM *, const BIGNUM *,
const BIGNUM *, const u_char *, u_int,
const u_char *, u_int);
#endif /* JPAKE_H */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.c,v 1.79 2007/06/05 06:52:37 djm Exp $ */
/* $OpenBSD: kex.c,v 1.80 2008/09/06 12:24:13 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexgexs.c,v 1.10 2006/11/06 21:25:28 markus Exp $ */
/* $OpenBSD: kexgexs.c,v 1.11 2009/01/01 21:17:36 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -56,7 +56,8 @@ kexgex_server(Kex *kex)
DH *dh;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, slen, hashlen;
int min = -1, max = -1, nbits = -1, type, kout;
int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1;
int type, kout;
if (kex->load_host_key == NULL)
fatal("Cannot load hostkey");
@ -68,27 +69,29 @@ kexgex_server(Kex *kex)
switch (type) {
case SSH2_MSG_KEX_DH_GEX_REQUEST:
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
min = packet_get_int();
nbits = packet_get_int();
max = packet_get_int();
omin = min = packet_get_int();
onbits = nbits = packet_get_int();
omax = max = packet_get_int();
min = MAX(DH_GRP_MIN, min);
max = MIN(DH_GRP_MAX, max);
nbits = MAX(DH_GRP_MIN, nbits);
nbits = MIN(DH_GRP_MAX, nbits);
break;
case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD:
debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received");
nbits = packet_get_int();
min = DH_GRP_MIN;
max = DH_GRP_MAX;
onbits = nbits = packet_get_int();
/* unused for old GEX */
omin = min = DH_GRP_MIN;
omax = max = DH_GRP_MAX;
break;
default:
fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type);
}
packet_check_eom();
if (max < min || nbits < min || max < nbits)
if (omax < omin || onbits < omin || omax < onbits)
fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
min, nbits, max);
omin, onbits, omax);
/* Contact privileged parent */
dh = PRIVSEP(choose_dh(min, nbits, max));
@ -149,7 +152,7 @@ kexgex_server(Kex *kex)
key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
min = max = -1;
omin = min = omax = max = -1;
/* calc H */
kexgex_hash(
@ -159,7 +162,7 @@ kexgex_server(Kex *kex)
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
buffer_ptr(&kex->my), buffer_len(&kex->my),
server_host_key_blob, sbloblen,
min, nbits, max,
omin, onbits, omax,
dh->p, dh->g,
dh_client_pub,
dh->pub_key,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.c,v 1.78 2008/07/07 23:32:51 stevesk Exp $ */
/* $OpenBSD: key.c,v 1.80 2008/10/10 05:00:12 stevesk Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -369,7 +369,8 @@ key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
y = MIN(y, FLDSIZE_Y - 1);
/* augment the field */
field[x][y]++;
if (field[x][y] < len - 2)
field[x][y]++;
input = input >> 2;
}
}
@ -427,7 +428,7 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k);
break;
default:
fatal("key_fingerprint_ex: bad digest representation %d",
fatal("key_fingerprint: bad digest representation %d",
dgst_rep);
break;
}

View File

@ -1456,25 +1456,14 @@ syslogin_write_entry(struct logininfo *li)
**/
#ifdef USE_LASTLOG
#define LL_FILE 1
#define LL_DIR 2
#define LL_OTHER 3
static void
lastlog_construct(struct logininfo *li, struct lastlog *last)
{
/* clear the structure */
memset(last, '\0', sizeof(*last));
line_stripname(last->ll_line, li->line, sizeof(last->ll_line));
strlcpy(last->ll_host, li->hostname,
MIN_SIZEOF(last->ll_host, li->hostname));
last->ll_time = li->tv_sec;
}
#if !defined(LASTLOG_WRITE_PUTUTXLINE) || !defined(HAVE_GETLASTLOGXBYNAME)
/* open the file (using filemode) and seek to the login entry */
static int
lastlog_filetype(char *filename)
lastlog_openseek(struct logininfo *li, int *fd, int filemode)
{
off_t offset;
char lastlog_file[1024];
struct stat st;
if (stat(LASTLOG_FILE, &st) != 0) {
@ -1482,34 +1471,12 @@ lastlog_filetype(char *filename)
LASTLOG_FILE, strerror(errno));
return (0);
}
if (S_ISDIR(st.st_mode))
return (LL_DIR);
else if (S_ISREG(st.st_mode))
return (LL_FILE);
else
return (LL_OTHER);
}
/* open the file (using filemode) and seek to the login entry */
static int
lastlog_openseek(struct logininfo *li, int *fd, int filemode)
{
off_t offset;
int type;
char lastlog_file[1024];
type = lastlog_filetype(LASTLOG_FILE);
switch (type) {
case LL_FILE:
strlcpy(lastlog_file, LASTLOG_FILE,
sizeof(lastlog_file));
break;
case LL_DIR:
if (S_ISDIR(st.st_mode)) {
snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s",
LASTLOG_FILE, li->username);
break;
default:
} else if (S_ISREG(st.st_mode)) {
strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file));
} else {
logit("%s: %.100s is not a file or directory!", __func__,
LASTLOG_FILE);
return (0);
@ -1522,7 +1489,7 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
return (0);
}
if (type == LL_FILE) {
if (S_ISREG(st.st_mode)) {
/* find this uid's offset in the lastlog file */
offset = (off_t) ((long)li->uid * sizeof(struct lastlog));
@ -1535,52 +1502,74 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
return (1);
}
#endif /* !LASTLOG_WRITE_PUTUTXLINE || !HAVE_GETLASTLOGXBYNAME */
static int
lastlog_perform_login(struct logininfo *li)
{
struct lastlog last;
int fd;
/* create our struct lastlog */
lastlog_construct(li, &last);
if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT))
return (0);
/* write the entry */
if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) {
close(fd);
logit("%s: Error writing to %s: %s", __func__,
LASTLOG_FILE, strerror(errno));
return (0);
}
close(fd);
return (1);
}
#ifdef LASTLOG_WRITE_PUTUTXLINE
int
lastlog_write_entry(struct logininfo *li)
{
switch(li->type) {
case LTYPE_LOGIN:
return (lastlog_perform_login(li));
return 1; /* lastlog written by pututxline */
default:
logit("lastlog_write_entry: Invalid type field");
return 0;
}
}
#else /* LASTLOG_WRITE_PUTUTXLINE */
int
lastlog_write_entry(struct logininfo *li)
{
struct lastlog last;
int fd;
switch(li->type) {
case LTYPE_LOGIN:
/* create our struct lastlog */
memset(&last, '\0', sizeof(last));
line_stripname(last.ll_line, li->line, sizeof(last.ll_line));
strlcpy(last.ll_host, li->hostname,
MIN_SIZEOF(last.ll_host, li->hostname));
last.ll_time = li->tv_sec;
if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT))
return (0);
/* write the entry */
if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) {
close(fd);
logit("%s: Error writing to %s: %s", __func__,
LASTLOG_FILE, strerror(errno));
return (0);
}
close(fd);
return (1);
default:
logit("%s: Invalid type field", __func__);
return (0);
}
}
#endif /* LASTLOG_WRITE_PUTUTXLINE */
static void
lastlog_populate_entry(struct logininfo *li, struct lastlog *last)
#ifdef HAVE_GETLASTLOGXBYNAME
int
lastlog_get_entry(struct logininfo *li)
{
line_fullname(li->line, last->ll_line, sizeof(li->line));
strlcpy(li->hostname, last->ll_host,
MIN_SIZEOF(li->hostname, last->ll_host));
li->tv_sec = last->ll_time;
}
struct lastlogx l, *ll;
if ((ll = getlastlogxbyname(li->username, &l)) == NULL) {
memset(&l, '\0', sizeof(l));
ll = &l;
}
line_fullname(li->line, ll->ll_line, sizeof(li->line));
strlcpy(li->hostname, ll->ll_host,
MIN_SIZEOF(li->hostname, ll->ll_host));
li->tv_sec = ll->ll_tv.tv_sec;
li->tv_usec = ll->ll_tv.tv_usec;
return (1);
}
#else /* HAVE_GETLASTLOGXBYNAME */
int
lastlog_get_entry(struct logininfo *li)
{
@ -1598,7 +1587,10 @@ lastlog_get_entry(struct logininfo *li)
memset(&last, '\0', sizeof(last));
/* FALLTHRU */
case sizeof(last):
lastlog_populate_entry(li, &last);
line_fullname(li->line, last.ll_line, sizeof(li->line));
strlcpy(li->hostname, last.ll_host,
MIN_SIZEOF(li->hostname, last.ll_host));
li->tv_sec = last.ll_time;
return (1);
case -1:
error("%s: Error reading from %s: %s", __func__,
@ -1613,6 +1605,7 @@ lastlog_get_entry(struct logininfo *li)
/* NOTREACHED */
return (0);
}
#endif /* HAVE_GETLASTLOGXBYNAME */
#endif /* USE_LASTLOG */
#ifdef USE_BTMP

View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.69 2008/06/13 01:38:23 dtucker Exp $ */
/* $OpenBSD: misc.c,v 1.71 2009/02/21 19:32:04 tobias Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@ -221,23 +221,19 @@ pwcopy(struct passwd *pw)
/*
* Convert ASCII string to TCP/IP port number.
* Port must be >0 and <=65535.
* Return 0 if invalid.
* Port must be >=0 and <=65535.
* Return -1 if invalid.
*/
int
a2port(const char *s)
{
long port;
char *endp;
long long port;
const char *errstr;
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;
return port;
port = strtonum(s, 0, 65535, &errstr);
if (errstr != NULL)
return -1;
return (int)port;
}
int
@ -718,7 +714,8 @@ sanitise_stdfd(void)
int nullfd, dupfd;
if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
fprintf(stderr, "Couldn't open /dev/null: %s\n",
strerror(errno));
exit(1);
}
while (++dupfd <= 2) {
@ -726,7 +723,7 @@ sanitise_stdfd(void)
if (fcntl(dupfd, F_GETFL, 0) >= 0)
continue;
if (dup2(nullfd, dupfd) == -1) {
fprintf(stderr, "dup2: %s", strerror(errno));
fprintf(stderr, "dup2: %s\n", strerror(errno));
exit(1);
}
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.99 2008/07/10 18:08:11 markus Exp $ */
/* $OpenBSD: monitor.c,v 1.101 2009/02/12 03:26:22 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -87,6 +87,7 @@
#include "misc.h"
#include "compat.h"
#include "ssh2.h"
#include "jpake.h"
#ifdef GSSAPI
static Gssctxt *gsscontext = NULL;
@ -149,6 +150,11 @@ int mm_answer_rsa_challenge(int, Buffer *);
int mm_answer_rsa_response(int, Buffer *);
int mm_answer_sesskey(int, Buffer *);
int mm_answer_sessid(int, Buffer *);
int mm_answer_jpake_get_pwdata(int, Buffer *);
int mm_answer_jpake_step1(int, Buffer *);
int mm_answer_jpake_step2(int, Buffer *);
int mm_answer_jpake_key_confirm(int, Buffer *);
int mm_answer_jpake_check_confirm(int, Buffer *);
#ifdef USE_PAM
int mm_answer_pam_start(int, Buffer *);
@ -233,6 +239,13 @@ struct mon_table mon_dispatch_proto20[] = {
{MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
{MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
{MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
#endif
#ifdef JPAKE
{MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
{MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1},
{MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2},
{MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm},
{MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm},
#endif
{0, 0, NULL}
};
@ -379,6 +392,15 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
if (!authenticated)
authctxt->failures++;
}
#ifdef JPAKE
/* Cleanup JPAKE context after authentication */
if (ent->flags & MON_AUTHDECIDE) {
if (authctxt->jpake_ctx != NULL) {
jpake_free(authctxt->jpake_ctx);
authctxt->jpake_ctx = NULL;
}
}
#endif
}
if (!authctxt->valid)
@ -1478,7 +1500,9 @@ mm_answer_rsa_challenge(int sock, Buffer *m)
fatal("%s: key type mismatch", __func__);
if ((key = key_from_blob(blob, blen)) == NULL)
fatal("%s: received bad key", __func__);
if (key->type != KEY_RSA)
fatal("%s: received bad key type %d", __func__, key->type);
key->type = KEY_RSA1;
if (ssh1_challenge)
BN_clear_free(ssh1_challenge);
ssh1_challenge = auth_rsa_generate_challenge(key);
@ -1969,3 +1993,206 @@ mm_answer_gss_userok(int sock, Buffer *m)
return (authenticated);
}
#endif /* GSSAPI */
#ifdef JPAKE
int
mm_answer_jpake_step1(int sock, Buffer *m)
{
struct jpake_ctx *pctx;
u_char *x3_proof, *x4_proof;
u_int x3_proof_len, x4_proof_len;
if (!options.zero_knowledge_password_authentication)
fatal("zero_knowledge_password_authentication disabled");
if (authctxt->jpake_ctx != NULL)
fatal("%s: authctxt->jpake_ctx already set (%p)",
__func__, authctxt->jpake_ctx);
authctxt->jpake_ctx = pctx = jpake_new();
jpake_step1(pctx->grp,
&pctx->server_id, &pctx->server_id_len,
&pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4,
&x3_proof, &x3_proof_len,
&x4_proof, &x4_proof_len);
JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__));
buffer_clear(m);
buffer_put_string(m, pctx->server_id, pctx->server_id_len);
buffer_put_bignum2(m, pctx->g_x3);
buffer_put_bignum2(m, pctx->g_x4);
buffer_put_string(m, x3_proof, x3_proof_len);
buffer_put_string(m, x4_proof, x4_proof_len);
debug3("%s: sending step1", __func__);
mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m);
bzero(x3_proof, x3_proof_len);
bzero(x4_proof, x4_proof_len);
xfree(x3_proof);
xfree(x4_proof);
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1);
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0);
return 0;
}
int
mm_answer_jpake_get_pwdata(int sock, Buffer *m)
{
struct jpake_ctx *pctx = authctxt->jpake_ctx;
char *hash_scheme, *salt;
if (pctx == NULL)
fatal("%s: pctx == NULL", __func__);
auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt);
buffer_clear(m);
/* pctx->s is sensitive, not returned to slave */
buffer_put_cstring(m, hash_scheme);
buffer_put_cstring(m, salt);
debug3("%s: sending pwdata", __func__);
mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m);
bzero(hash_scheme, strlen(hash_scheme));
bzero(salt, strlen(salt));
xfree(hash_scheme);
xfree(salt);
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1);
return 0;
}
int
mm_answer_jpake_step2(int sock, Buffer *m)
{
struct jpake_ctx *pctx = authctxt->jpake_ctx;
u_char *x1_proof, *x2_proof, *x4_s_proof;
u_int x1_proof_len, x2_proof_len, x4_s_proof_len;
if (pctx == NULL)
fatal("%s: pctx == NULL", __func__);
if ((pctx->g_x1 = BN_new()) == NULL ||
(pctx->g_x2 = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
buffer_get_bignum2(m, pctx->g_x1);
buffer_get_bignum2(m, pctx->g_x2);
pctx->client_id = buffer_get_string(m, &pctx->client_id_len);
x1_proof = buffer_get_string(m, &x1_proof_len);
x2_proof = buffer_get_string(m, &x2_proof_len);
jpake_step2(pctx->grp, pctx->s, pctx->g_x3,
pctx->g_x1, pctx->g_x2, pctx->x4,
pctx->client_id, pctx->client_id_len,
pctx->server_id, pctx->server_id_len,
x1_proof, x1_proof_len,
x2_proof, x2_proof_len,
&pctx->b,
&x4_s_proof, &x4_s_proof_len);
JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__));
bzero(x1_proof, x1_proof_len);
bzero(x2_proof, x2_proof_len);
xfree(x1_proof);
xfree(x2_proof);
buffer_clear(m);
buffer_put_bignum2(m, pctx->b);
buffer_put_string(m, x4_s_proof, x4_s_proof_len);
debug3("%s: sending step2", __func__);
mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m);
bzero(x4_s_proof, x4_s_proof_len);
xfree(x4_s_proof);
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1);
return 0;
}
int
mm_answer_jpake_key_confirm(int sock, Buffer *m)
{
struct jpake_ctx *pctx = authctxt->jpake_ctx;
u_char *x2_s_proof;
u_int x2_s_proof_len;
if (pctx == NULL)
fatal("%s: pctx == NULL", __func__);
if ((pctx->a = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
buffer_get_bignum2(m, pctx->a);
x2_s_proof = buffer_get_string(m, &x2_s_proof_len);
jpake_key_confirm(pctx->grp, pctx->s, pctx->a,
pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2,
pctx->server_id, pctx->server_id_len,
pctx->client_id, pctx->client_id_len,
session_id2, session_id2_len,
x2_s_proof, x2_s_proof_len,
&pctx->k,
&pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len);
JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__));
bzero(x2_s_proof, x2_s_proof_len);
buffer_clear(m);
/* pctx->k is sensitive, not sent */
buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
debug3("%s: sending confirmation hash", __func__);
mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m);
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1);
return 0;
}
int
mm_answer_jpake_check_confirm(int sock, Buffer *m)
{
int authenticated = 0;
u_char *peer_confirm_hash;
u_int peer_confirm_hash_len;
struct jpake_ctx *pctx = authctxt->jpake_ctx;
if (pctx == NULL)
fatal("%s: pctx == NULL", __func__);
peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len);
authenticated = jpake_check_confirm(pctx->k,
pctx->client_id, pctx->client_id_len,
session_id2, session_id2_len,
peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid;
JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__));
bzero(peer_confirm_hash, peer_confirm_hash_len);
xfree(peer_confirm_hash);
buffer_clear(m);
buffer_put_int(m, authenticated);
debug3("%s: sending result %d", __func__, authenticated);
mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m);
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1);
auth_method = "jpake-01@openssh.com";
return authenticated;
}
#endif /* JPAKE */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.h,v 1.14 2006/03/25 22:22:43 djm Exp $ */
/* $OpenBSD: monitor.h,v 1.15 2008/11/04 08:22:13 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -60,7 +60,12 @@ enum monitor_reqtype {
MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND,
MONITOR_REQ_TERM
MONITOR_REQ_TERM,
MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2,
MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM,
MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM,
};
struct mm_master;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_fdpass.c,v 1.17 2008/03/24 16:11:07 deraadt Exp $ */
/* $OpenBSD: monitor_fdpass.c,v 1.18 2008/11/30 11:59:26 dtucker Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -45,17 +45,16 @@ mm_send_fd(int sock, int fd)
{
#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
struct msghdr msg;
struct iovec vec;
char ch = '\0';
ssize_t n;
#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
union {
struct cmsghdr hdr;
char tmp[CMSG_SPACE(sizeof(int))];
char buf[CMSG_SPACE(sizeof(int))];
} cmsgbuf;
struct cmsghdr *cmsg;
#endif
struct iovec vec;
char ch = '\0';
ssize_t n;
memset(&msg, 0, sizeof(msg));
#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
@ -76,7 +75,10 @@ mm_send_fd(int sock, int fd)
msg.msg_iov = &vec;
msg.msg_iovlen = 1;
if ((n = sendmsg(sock, &msg, 0)) == -1) {
while ((n = sendmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN ||
errno == EINTR))
debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno));
if (n == -1) {
error("%s: sendmsg(%d): %s", __func__, fd,
strerror(errno));
return -1;
@ -99,10 +101,6 @@ mm_receive_fd(int sock)
{
#if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
struct msghdr msg;
struct iovec vec;
ssize_t n;
char ch;
int fd;
#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
union {
struct cmsghdr hdr;
@ -110,6 +108,10 @@ mm_receive_fd(int sock)
} cmsgbuf;
struct cmsghdr *cmsg;
#endif
struct iovec vec;
ssize_t n;
char ch;
int fd;
memset(&msg, 0, sizeof(msg));
vec.iov_base = &ch;
@ -124,10 +126,14 @@ mm_receive_fd(int sock)
msg.msg_controllen = sizeof(cmsgbuf.buf);
#endif
if ((n = recvmsg(sock, &msg, 0)) == -1) {
while ((n = recvmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN ||
errno == EINTR))
debug3("%s: recvmsg: %s", __func__, strerror(errno));
if (n == -1) {
error("%s: recvmsg: %s", __func__, strerror(errno));
return -1;
}
if (n != 1) {
error("%s: recvmsg: expected received 1 got %ld",
__func__, (long)n);
@ -145,6 +151,7 @@ mm_receive_fd(int sock)
error("%s: no message header", __func__);
return -1;
}
#ifndef BROKEN_CMSG_TYPE
if (cmsg->cmsg_type != SCM_RIGHTS) {
error("%s: expected type %d got %d", __func__,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.63 2008/07/10 18:08:11 markus Exp $ */
/* $OpenBSD: monitor_wrap.c,v 1.64 2008/11/04 08:22:13 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -40,6 +40,7 @@
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
@ -70,7 +71,7 @@
#include "atomicio.h"
#include "monitor_fdpass.h"
#include "misc.h"
#include "servconf.h"
#include "jpake.h"
#include "channels.h"
#include "session.h"
@ -1256,3 +1257,165 @@ mm_ssh_gssapi_userok(char *user)
return (authenticated);
}
#endif /* GSSAPI */
#ifdef JPAKE
void
mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
char **hash_scheme, char **salt)
{
Buffer m;
debug3("%s entering", __func__);
buffer_init(&m);
mm_request_send(pmonitor->m_recvfd,
MONITOR_REQ_JPAKE_GET_PWDATA, &m);
debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_JPAKE_GET_PWDATA, &m);
*hash_scheme = buffer_get_string(&m, NULL);
*salt = buffer_get_string(&m, NULL);
buffer_free(&m);
}
void
mm_jpake_step1(struct jpake_group *grp,
u_char **id, u_int *id_len,
BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
u_char **priv1_proof, u_int *priv1_proof_len,
u_char **priv2_proof, u_int *priv2_proof_len)
{
Buffer m;
debug3("%s entering", __func__);
buffer_init(&m);
mm_request_send(pmonitor->m_recvfd,
MONITOR_REQ_JPAKE_STEP1, &m);
debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP1", __func__);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_JPAKE_STEP1, &m);
if ((*priv1 = BN_new()) == NULL ||
(*priv2 = BN_new()) == NULL ||
(*g_priv1 = BN_new()) == NULL ||
(*g_priv2 = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
*id = buffer_get_string(&m, id_len);
/* priv1 and priv2 are, well, private */
buffer_get_bignum2(&m, *g_priv1);
buffer_get_bignum2(&m, *g_priv2);
*priv1_proof = buffer_get_string(&m, priv1_proof_len);
*priv2_proof = buffer_get_string(&m, priv2_proof_len);
buffer_free(&m);
}
void
mm_jpake_step2(struct jpake_group *grp, BIGNUM *s,
BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
const u_char *theirid, u_int theirid_len,
const u_char *myid, u_int myid_len,
const u_char *theirpub1_proof, u_int theirpub1_proof_len,
const u_char *theirpub2_proof, u_int theirpub2_proof_len,
BIGNUM **newpub,
u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len)
{
Buffer m;
debug3("%s entering", __func__);
buffer_init(&m);
/* monitor already has all bignums except theirpub1, theirpub2 */
buffer_put_bignum2(&m, theirpub1);
buffer_put_bignum2(&m, theirpub2);
/* monitor already knows our id */
buffer_put_string(&m, theirid, theirid_len);
buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len);
buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len);
mm_request_send(pmonitor->m_recvfd,
MONITOR_REQ_JPAKE_STEP2, &m);
debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_JPAKE_STEP2, &m);
if ((*newpub = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
buffer_get_bignum2(&m, *newpub);
*newpub_exponent_proof = buffer_get_string(&m,
newpub_exponent_proof_len);
buffer_free(&m);
}
void
mm_jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
BIGNUM *theirpub1, BIGNUM *theirpub2,
const u_char *my_id, u_int my_id_len,
const u_char *their_id, u_int their_id_len,
const u_char *sess_id, u_int sess_id_len,
const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len,
BIGNUM **k,
u_char **confirm_hash, u_int *confirm_hash_len)
{
Buffer m;
debug3("%s entering", __func__);
buffer_init(&m);
/* monitor already has all bignums except step2_val */
buffer_put_bignum2(&m, step2_val);
/* monitor already knows all the ids */
buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len);
mm_request_send(pmonitor->m_recvfd,
MONITOR_REQ_JPAKE_KEY_CONFIRM, &m);
debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_JPAKE_KEY_CONFIRM, &m);
/* 'k' is sensitive and stays in the monitor */
*confirm_hash = buffer_get_string(&m, confirm_hash_len);
buffer_free(&m);
}
int
mm_jpake_check_confirm(const BIGNUM *k,
const u_char *peer_id, u_int peer_id_len,
const u_char *sess_id, u_int sess_id_len,
const u_char *peer_confirm_hash, u_int peer_confirm_hash_len)
{
Buffer m;
int success = 0;
debug3("%s entering", __func__);
buffer_init(&m);
/* k is dummy in slave, ignored */
/* monitor knows all the ids */
buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len);
mm_request_send(pmonitor->m_recvfd,
MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m);
debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m);
success = buffer_get_int(&m);
buffer_free(&m);
debug3("%s: success = %d", __func__, success);
return success;
}
#endif /* JPAKE */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.h,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */
/* $OpenBSD: monitor_wrap.h,v 1.21 2008/11/04 08:22:13 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -101,6 +101,26 @@ int mm_bsdauth_respond(void *, u_int, char **);
int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
int mm_skey_respond(void *, u_int, char **);
/* jpake */
struct jpake_group;
void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **);
void mm_jpake_step1(struct jpake_group *, u_char **, u_int *,
BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
u_char **, u_int *, u_char **, u_int *);
void mm_jpake_step2(struct jpake_group *, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int,
BIGNUM **, u_char **, u_int *);
void mm_jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int,
BIGNUM **, u_char **, u_int *);
int mm_jpake_check_confirm(const BIGNUM *,
const u_char *, u_int, const u_char *, u_int, const u_char *, u_int);
/* zlib allocation hooks */
void *mm_zalloc(struct mm_master *, u_int, u_int);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: myproposal.h,v 1.22 2007/06/07 19:37:34 pvalchev Exp $ */
/* $OpenBSD: myproposal.h,v 1.23 2009/01/23 07:58:11 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -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_DEFAULT_MAC \
"hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
"hmac-ripemd160@openssh.com," \

View File

@ -1,4 +1,4 @@
/* $OpenBSD: nchan.c,v 1.60 2008/06/30 12:16:02 djm Exp $ */
/* $OpenBSD: nchan.c,v 1.62 2008/11/07 18:50:18 stevesk Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@ -387,6 +387,8 @@ chan_send_eow2(Channel *c)
c->self);
return;
}
if (!(datafellows & SSH_NEW_OPENSSH))
return;
packet_start(SSH2_MSG_CHANNEL_REQUEST);
packet_put_int(c->remote_id);
packet_put_cstring("eow@openssh.com");
@ -484,12 +486,12 @@ chan_shutdown_write(Channel *c)
if (c->sock != -1) {
if (shutdown(c->sock, SHUT_WR) < 0)
debug2("channel %d: chan_shutdown_write: "
"shutdown() failed for fd%d: %.100s",
"shutdown() failed for fd %d: %.100s",
c->self, c->sock, strerror(errno));
} else {
if (channel_close_fd(&c->wfd) < 0)
logit("channel %d: chan_shutdown_write: "
"close() failed for fd%d: %.100s",
"close() failed for fd %d: %.100s",
c->self, c->wfd, strerror(errno));
}
}
@ -508,13 +510,13 @@ chan_shutdown_read(Channel *c)
if (shutdown(c->sock, SHUT_RD) < 0
&& errno != ENOTCONN)
error("channel %d: chan_shutdown_read: "
"shutdown() failed for fd%d [i%d o%d]: %.100s",
"shutdown() failed for fd %d [i%d o%d]: %.100s",
c->self, c->sock, c->istate, c->ostate,
strerror(errno));
} else {
if (channel_close_fd(&c->rfd) < 0)
logit("channel %d: chan_shutdown_read: "
"close() failed for fd%d: %.100s",
"close() failed for fd %d: %.100s",
c->self, c->rfd, strerror(errno));
}
}

View File

@ -1,4 +1,4 @@
/* $Id: bsd-poll.c,v 1.3 2008/04/04 05:16:36 djm Exp $ */
/* $Id: bsd-poll.c,v 1.4 2008/08/29 21:32:38 dtucker Exp $ */
/*
* Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au).
@ -46,11 +46,12 @@ poll(struct pollfd *fds, nfds_t nfds, int timeout)
struct timeval tv, *tvp = NULL;
for (i = 0; i < nfds; i++) {
fd = fds[i].fd;
if (fd >= FD_SETSIZE) {
errno = EINVAL;
return -1;
}
maxfd = MAX(maxfd, fds[i].fd);
maxfd = MAX(maxfd, fd);
}
nmemb = howmany(maxfd + 1 , NFDBITS);

View File

@ -25,7 +25,7 @@
#include "includes.h"
#ifdef HAVE_LIBIAF
#if defined(HAVE_LIBIAF) && !defined(HAVE_SECUREWARE)
#include <sys/types.h>
#ifdef HAVE_CRYPT_H
# include <crypt.h>
@ -145,5 +145,5 @@ get_iaf_password(struct passwd *pw)
fatal("ia_openinfo: Unable to open the shadow passwd file");
}
#endif /* USE_LIBIAF */
#endif /* HAVE_LIBIAF */
#endif /* HAVE_LIBIAF and not HAVE_SECUREWARE */

View File

@ -28,7 +28,7 @@
#include <unistd.h>
#include <pwd.h>
# ifdef HAVE_CRYPT_H
# if defined(HAVE_CRYPT_H) && !defined(HAVE_SECUREWARE)
# include <crypt.h>
# endif

View File

@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id: xmmap.c,v 1.14 2007/06/11 02:52:24 djm Exp $ */
/* $Id: xmmap.c,v 1.15 2009/02/16 04:21:40 djm Exp $ */
#include "includes.h"
@ -71,7 +71,8 @@ xmmap(size_t size)
fatal("mkstemp(\"%s\"): %s",
MM_SWAP_TEMPLATE, strerror(errno));
unlink(tmpname);
ftruncate(tmpfd, size);
if (ftruncate(tmpfd, size) != 0)
fatal("%s: ftruncate: %s", __func__, strerror(errno));
address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
tmpfd, (off_t)0);
close(tmpfd);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.157 2008/07/10 18:08:11 markus Exp $ */
/* $OpenBSD: packet.c,v 1.160 2009/02/13 11:50:21 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -84,6 +84,8 @@
#define DBG(x)
#endif
#define PACKET_MAX_SIZE (256 * 1024)
/*
* This variable contains the file descriptors used for communicating with
* the other side. connection_in is used for reading; connection_out for
@ -160,6 +162,10 @@ static u_int ssh1_keylen;
/* roundup current message to extra_pad bytes */
static u_char extra_pad = 0;
/* XXX discard incoming data after MAC error */
static u_int packet_discard = 0;
static Mac *packet_discard_mac = NULL;
struct packet {
TAILQ_ENTRY(packet) next;
u_char type;
@ -209,6 +215,36 @@ packet_set_timeout(int timeout, int count)
packet_timeout_ms = timeout * count * 1000;
}
static void
packet_stop_discard(void)
{
if (packet_discard_mac) {
char buf[1024];
memset(buf, 'a', sizeof(buf));
while (buffer_len(&incoming_packet) < PACKET_MAX_SIZE)
buffer_append(&incoming_packet, buf, sizeof(buf));
(void) mac_compute(packet_discard_mac,
p_read.seqnr,
buffer_ptr(&incoming_packet),
PACKET_MAX_SIZE);
}
logit("Finished discarding for %.200s", get_remote_ipaddr());
cleanup_exit(255);
}
static void
packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
{
if (enc == NULL || !cipher_is_cbc(enc->cipher))
packet_disconnect("Packet corrupt");
if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
packet_discard_mac = mac;
if (buffer_len(&input) >= discard)
packet_stop_discard();
packet_discard = discard - buffer_len(&input);
}
/* Returns 1 if remote host is connected via socket, 0 if not. */
int
@ -1127,6 +1163,9 @@ packet_read_poll2(u_int32_t *seqnr_p)
Mac *mac = NULL;
Comp *comp = NULL;
if (packet_discard)
return SSH_MSG_NONE;
if (newkeys[MODE_IN] != NULL) {
enc = &newkeys[MODE_IN]->enc;
mac = &newkeys[MODE_IN]->mac;
@ -1148,11 +1187,14 @@ packet_read_poll2(u_int32_t *seqnr_p)
block_size);
cp = buffer_ptr(&incoming_packet);
packet_length = get_u32(cp);
if (packet_length < 1 + 4 || packet_length > 256 * 1024) {
if (packet_length < 1 + 4 || packet_length > PACKET_MAX_SIZE) {
#ifdef PACKET_DEBUG
buffer_dump(&incoming_packet);
#endif
packet_disconnect("Bad packet length %u.", packet_length);
logit("Bad packet length %u.", packet_length);
packet_start_discard(enc, mac, packet_length,
PACKET_MAX_SIZE);
return SSH_MSG_NONE;
}
DBG(debug("input: packet len %u", packet_length+4));
buffer_consume(&input, block_size);
@ -1161,9 +1203,13 @@ packet_read_poll2(u_int32_t *seqnr_p)
need = 4 + packet_length - block_size;
DBG(debug("partial packet %d, need %d, maclen %d", block_size,
need, maclen));
if (need % block_size != 0)
fatal("padding error: need %d block %d mod %d",
if (need % block_size != 0) {
logit("padding error: need %d block %d mod %d",
need, block_size, need % block_size);
packet_start_discard(enc, mac, packet_length,
PACKET_MAX_SIZE - block_size);
return SSH_MSG_NONE;
}
/*
* check if the entire packet has been received and
* decrypt into incoming_packet
@ -1185,11 +1231,19 @@ packet_read_poll2(u_int32_t *seqnr_p)
macbuf = mac_compute(mac, p_read.seqnr,
buffer_ptr(&incoming_packet),
buffer_len(&incoming_packet));
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
packet_disconnect("Corrupted MAC on input.");
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) {
logit("Corrupted MAC on input.");
if (need > PACKET_MAX_SIZE)
fatal("internal error need %d", need);
packet_start_discard(enc, mac, packet_length,
PACKET_MAX_SIZE - need);
return SSH_MSG_NONE;
}
DBG(debug("MAC #%d ok", p_read.seqnr));
buffer_consume(&input, mac->mac_len);
}
/* XXX now it's safe to use fatal/packet_disconnect */
if (seqnr_p != NULL)
*seqnr_p = p_read.seqnr;
if (++p_read.seqnr == 0)
@ -1322,6 +1376,13 @@ packet_read_poll(void)
void
packet_process_incoming(const char *buf, u_int len)
{
if (packet_discard) {
keep_alive_timeouts = 0; /* ?? */
if (len >= packet_discard)
packet_stop_discard();
packet_discard -= len;
return;
}
buffer_append(&input, buf, len);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */
/* $OpenBSD: pathnames.h,v 1.17 2008/12/29 02:23:26 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -54,7 +54,7 @@
#define _PATH_SSH_DAEMON_PID_FILE _PATH_SSH_PIDDIR "/sshd.pid"
/*
* The directory in user\'s home directory in which the files reside. The
* The directory in user's home directory in which the files reside. The
* directory should be world-readable (though not all files are).
*/
#define _PATH_SSH_USER_DIR ".ssh"
@ -77,9 +77,9 @@
#define _PATH_SSH_CLIENT_ID_RSA ".ssh/id_rsa"
/*
* Configuration file in user\'s home directory. This file need not be
* Configuration file in user's home directory. This file need not be
* readable by anyone but the user him/herself, but does not contain anything
* particularly secret. If the user\'s home directory resides on an NFS
* particularly secret. If the user's home directory resides on an NFS
* volume where root is mapped to nobody, this may need to be world-readable.
*/
#define _PATH_SSH_USER_CONFFILE ".ssh/config"
@ -87,7 +87,7 @@
/*
* File containing a list of those rsa keys that permit logging in as this
* user. This file need not be readable by anyone but the user him/herself,
* but does not contain anything particularly secret. If the user\'s home
* but does not contain anything particularly secret. If the user's home
* directory resides on an NFS volume where root is mapped to nobody, this
* may need to be world-readable. (This file is read by the daemon which is
* running as root.)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.167 2008/06/26 11:46:31 grunk Exp $ */
/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -44,6 +44,7 @@ __RCSID("$FreeBSD$");
#include "buffer.h"
#include "kex.h"
#include "mac.h"
#include "version.h"
/* Format of the configuration file:
@ -132,7 +133,7 @@ typedef enum {
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
oVisualHostKey,
oVisualHostKey, oZeroKnowledgePasswordAuthentication,
oVersionAddendum,
oDeprecated, oUnsupported
} OpCodes;
@ -175,7 +176,7 @@ static struct {
{ "fallbacktorsh", oDeprecated },
{ "usersh", oDeprecated },
{ "identityfile", oIdentityFile },
{ "identityfile2", oIdentityFile }, /* alias */
{ "identityfile2", oIdentityFile }, /* obsolete */
{ "identitiesonly", oIdentitiesOnly },
{ "hostname", oHostName },
{ "hostkeyalias", oHostKeyAlias },
@ -191,8 +192,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 },
@ -231,6 +232,13 @@ static struct {
{ "localcommand", oLocalCommand },
{ "permitlocalcommand", oPermitLocalCommand },
{ "visualhostkey", oVisualHostKey },
#ifdef JPAKE
{ "zeroknowledgepasswordauthentication",
oZeroKnowledgePasswordAuthentication },
#else
{ "zeroknowledgepasswordauthentication", oUnsupported },
#endif
{ "versionaddendum", oVersionAddendum },
{ NULL, oBadOption }
};
@ -265,10 +273,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;
}
@ -286,10 +293,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;
}
@ -428,6 +434,10 @@ process_config_line(Options *options, const char *host,
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;
@ -722,56 +732,40 @@ process_config_line(Options *options, const char *host,
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;
@ -982,7 +976,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;
@ -1095,6 +1088,7 @@ initialize_options(Options * options)
options->local_command = NULL;
options->permit_local_command = -1;
options->visual_host_key = -1;
options->zero_knowledge_password_authentication = -1;
}
/*
@ -1231,6 +1225,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 */
@ -1242,11 +1238,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];
@ -1263,11 +1262,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]);
@ -1287,19 +1298,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);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.74 2008/06/26 11:46:31 grunk Exp $ */
/* $OpenBSD: readconf.h,v 1.78 2009/02/12 03:00:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -20,9 +20,9 @@
typedef struct {
char *listen_host; /* Host (address) to listen on. */
u_short listen_port; /* Port to forward. */
int listen_port; /* Port to forward. */
char *connect_host; /* Host to connect. */
u_short connect_port; /* Port to connect on connect_host. */
int connect_port; /* Port to connect on connect_host. */
} Forward;
/* Data structure for representing option data. */
@ -49,6 +49,7 @@ typedef struct {
* authentication. */
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
int zero_knowledge_password_authentication; /* Try jpake */
int batch_mode; /* Batch mode: do not ask for passwords. */
int check_host_ip; /* Also keep track of keys for IP address */
int strict_host_key_checking; /* Strict host key checking. */
@ -133,7 +134,7 @@ typedef struct {
void initialize_options(Options *);
void fill_default_options(Options *);
int read_config_file(const char *, const char *, Options *, int);
int parse_forward(Forward *, const char *);
int parse_forward(Forward *, const char *, int, int);
int
process_config_line(Options *, const char *, char *, const char *, int, int *);

413
crypto/openssh/schnorr.c Normal file
View File

@ -0,0 +1,413 @@
/* $OpenBSD: schnorr.c,v 1.2 2009/02/18 04:31:21 djm Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Implementation of Schnorr signatures / zero-knowledge proofs, based on
* description in:
*
* F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling",
* 16th Workshop on Security Protocols, Cambridge, April 2008
*
* http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
*/
#include "includes.h"
#include <sys/types.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/bn.h>
#include "xmalloc.h"
#include "buffer.h"
#include "log.h"
#include "jpake.h"
#ifdef JPAKE
/* #define SCHNORR_DEBUG */ /* Privacy-violating debugging */
/* #define SCHNORR_MAIN */ /* Include main() selftest */
/* XXX */
/* Parametise signature hash? (sha256, sha1, etc.) */
/* Signature format - include type name, hash type, group params? */
#ifndef SCHNORR_DEBUG
# define SCHNORR_DEBUG_BN(a)
# define SCHNORR_DEBUG_BUF(a)
#else
# define SCHNORR_DEBUG_BN(a) jpake_debug3_bn a
# define SCHNORR_DEBUG_BUF(a) jpake_debug3_buf a
#endif /* SCHNORR_DEBUG */
/*
* Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
* using SHA1. Returns signature as bignum or NULL on error.
*/
static BIGNUM *
schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
const BIGNUM *g_v, const BIGNUM *g_x,
const u_char *id, u_int idlen)
{
u_char *digest;
u_int digest_len;
BIGNUM *h;
EVP_MD_CTX evp_md_ctx;
Buffer b;
int success = -1;
if ((h = BN_new()) == NULL) {
error("%s: BN_new", __func__);
return NULL;
}
buffer_init(&b);
EVP_MD_CTX_init(&evp_md_ctx);
/* h = H(g || p || q || g^v || g^x || id) */
buffer_put_bignum2(&b, g);
buffer_put_bignum2(&b, p);
buffer_put_bignum2(&b, q);
buffer_put_bignum2(&b, g_v);
buffer_put_bignum2(&b, g_x);
buffer_put_string(&b, id, idlen);
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
"%s: hashblob", __func__));
if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
&digest, &digest_len) != 0) {
error("%s: hash_buffer", __func__);
goto out;
}
if (BN_bin2bn(digest, (int)digest_len, h) == NULL) {
error("%s: BN_bin2bn", __func__);
goto out;
}
success = 0;
SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
out:
buffer_free(&b);
EVP_MD_CTX_cleanup(&evp_md_ctx);
bzero(digest, digest_len);
xfree(digest);
digest_len = 0;
if (success == 0)
return h;
BN_clear_free(h);
return NULL;
}
/*
* Generate Schnorr signature to prove knowledge of private value 'x' used
* in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
* 'idlen' bytes from 'id' will be included in the signature hash as an anti-
* replay salt.
* On success, 0 is returned and *siglen bytes of signature are returned in
* *sig (caller to free). Returns -1 on failure.
*/
int
schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
u_char **sig, u_int *siglen)
{
int success = -1;
Buffer b;
BIGNUM *h, *tmp, *v, *g_v, *r;
BN_CTX *bn_ctx;
SCHNORR_DEBUG_BN((x, "%s: x = ", __func__));
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
/* Avoid degenerate cases: g^0 yields a spoofable signature */
if (BN_cmp(g_x, BN_value_one()) <= 0) {
error("%s: g_x < 1", __func__);
return -1;
}
h = g_v = r = tmp = v = NULL;
if ((bn_ctx = BN_CTX_new()) == NULL) {
error("%s: BN_CTX_new", __func__);
goto out;
}
if ((g_v = BN_new()) == NULL ||
(r = BN_new()) == NULL ||
(tmp = BN_new()) == NULL) {
error("%s: BN_new", __func__);
goto out;
}
/*
* v must be a random element of Zq, so 1 <= v < q
* we also exclude v = 1, since g^1 looks dangerous
*/
if ((v = bn_rand_range_gt_one(grp_p)) == NULL) {
error("%s: bn_rand_range2", __func__);
goto out;
}
SCHNORR_DEBUG_BN((v, "%s: v = ", __func__));
/* g_v = g^v mod p */
if (BN_mod_exp(g_v, grp_g, v, grp_p, bn_ctx) == -1) {
error("%s: BN_mod_exp (g^v mod p)", __func__);
goto out;
}
SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
/* h = H(g || g^v || g^x || id) */
if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
id, idlen)) == NULL) {
error("%s: schnorr_hash failed", __func__);
goto out;
}
/* r = v - xh mod q */
if (BN_mod_mul(tmp, x, h, grp_q, bn_ctx) == -1) {
error("%s: BN_mod_mul (tmp = xv mod q)", __func__);
goto out;
}
if (BN_mod_sub(r, v, tmp, grp_q, bn_ctx) == -1) {
error("%s: BN_mod_mul (r = v - tmp)", __func__);
goto out;
}
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
/* Signature is (g_v, r) */
buffer_init(&b);
/* XXX sigtype-hash as string? */
buffer_put_bignum2(&b, g_v);
buffer_put_bignum2(&b, r);
*siglen = buffer_len(&b);
*sig = xmalloc(*siglen);
memcpy(*sig, buffer_ptr(&b), *siglen);
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
"%s: sigblob", __func__));
buffer_free(&b);
success = 0;
out:
BN_CTX_free(bn_ctx);
if (h != NULL)
BN_clear_free(h);
if (v != NULL)
BN_clear_free(v);
BN_clear_free(r);
BN_clear_free(g_v);
BN_clear_free(tmp);
return success;
}
/*
* Verify Schnorr signature 'sig' of length 'siglen' against public exponent
* g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g'.
* Signature hash will be salted with 'idlen' bytes from 'id'.
* Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
*/
int
schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
const BIGNUM *g_x, const u_char *id, u_int idlen,
const u_char *sig, u_int siglen)
{
int success = -1;
Buffer b;
BIGNUM *g_v, *h, *r, *g_xh, *g_r, *expected;
BN_CTX *bn_ctx;
u_int rlen;
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
/* Avoid degenerate cases: g^0 yields a spoofable signature */
if (BN_cmp(g_x, BN_value_one()) <= 0) {
error("%s: g_x < 1", __func__);
return -1;
}
g_v = h = r = g_xh = g_r = expected = NULL;
if ((bn_ctx = BN_CTX_new()) == NULL) {
error("%s: BN_CTX_new", __func__);
goto out;
}
if ((g_v = BN_new()) == NULL ||
(r = BN_new()) == NULL ||
(g_xh = BN_new()) == NULL ||
(g_r = BN_new()) == NULL ||
(expected = BN_new()) == NULL) {
error("%s: BN_new", __func__);
goto out;
}
/* Extract g^v and r from signature blob */
buffer_init(&b);
buffer_append(&b, sig, siglen);
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
"%s: sigblob", __func__));
buffer_get_bignum2(&b, g_v);
buffer_get_bignum2(&b, r);
rlen = buffer_len(&b);
buffer_free(&b);
if (rlen != 0) {
error("%s: remaining bytes in signature %d", __func__, rlen);
goto out;
}
buffer_free(&b);
SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
/* h = H(g || g^v || g^x || id) */
if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
id, idlen)) == NULL) {
error("%s: schnorr_hash failed", __func__);
goto out;
}
/* g_xh = (g^x)^h */
if (BN_mod_exp(g_xh, g_x, h, grp_p, bn_ctx) == -1) {
error("%s: BN_mod_exp (g_x^h mod p)", __func__);
goto out;
}
SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
/* g_r = g^r */
if (BN_mod_exp(g_r, grp_g, r, grp_p, bn_ctx) == -1) {
error("%s: BN_mod_exp (g_x^h mod p)", __func__);
goto out;
}
SCHNORR_DEBUG_BN((g_r, "%s: g_r = ", __func__));
/* expected = g^r * g_xh */
if (BN_mod_mul(expected, g_r, g_xh, grp_p, bn_ctx) == -1) {
error("%s: BN_mod_mul (expected = g_r mod p)", __func__);
goto out;
}
SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
/* Check g_v == expected */
success = BN_cmp(expected, g_v) == 0;
out:
BN_CTX_free(bn_ctx);
if (h != NULL)
BN_clear_free(h);
BN_clear_free(g_v);
BN_clear_free(r);
BN_clear_free(g_xh);
BN_clear_free(g_r);
BN_clear_free(expected);
return success;
}
#ifdef SCHNORR_MAIN
static void
schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
const BIGNUM *grp_g, const BIGNUM *x)
{
BIGNUM *g_x;
u_char *sig;
u_int siglen;
BN_CTX *bn_ctx;
if ((bn_ctx = BN_CTX_new()) == NULL)
fatal("%s: BN_CTX_new", __func__);
if ((g_x = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
fatal("%s: g_x", __func__);
if (schnorr_sign(grp_p, grp_q, grp_g, x, g_x, "junk", 4, &sig, &siglen))
fatal("%s: schnorr_sign", __func__);
if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
sig, siglen) != 1)
fatal("%s: verify fail", __func__);
if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
sig, siglen) != 0)
fatal("%s: verify should have failed (bad ID)", __func__);
sig[4] ^= 1;
if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
sig, siglen) != 0)
fatal("%s: verify should have failed (bit error)", __func__);
xfree(sig);
BN_free(g_x);
BN_CTX_free(bn_ctx);
}
static void
schnorr_selftest(void)
{
BIGNUM *x;
struct jpake_group *grp;
u_int i;
char *hh;
grp = jpake_default_group();
if ((x = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
SCHNORR_DEBUG_BN((grp->p, "%s: grp->p = ", __func__));
SCHNORR_DEBUG_BN((grp->q, "%s: grp->q = ", __func__));
SCHNORR_DEBUG_BN((grp->g, "%s: grp->g = ", __func__));
/* [1, 20) */
for (i = 1; i < 20; i++) {
printf("x = %u\n", i);
fflush(stdout);
if (BN_set_word(x, i) != 1)
fatal("%s: set x word", __func__);
schnorr_selftest_one(grp->p, grp->q, grp->g, x);
}
/* 100 x random [0, p) */
for (i = 0; i < 100; i++) {
if (BN_rand_range(x, grp->p) != 1)
fatal("%s: BN_rand_range", __func__);
hh = BN_bn2hex(x);
printf("x = (random) 0x%s\n", hh);
free(hh);
fflush(stdout);
schnorr_selftest_one(grp->p, grp->q, grp->g, x);
}
/* [q-20, q) */
if (BN_set_word(x, 20) != 1)
fatal("%s: BN_set_word (x = 20)", __func__);
if (BN_sub(x, grp->q, x) != 1)
fatal("%s: BN_sub (q - x)", __func__);
for (i = 0; i < 19; i++) {
hh = BN_bn2hex(x);
printf("x = (q - %d) 0x%s\n", 20 - i, hh);
free(hh);
fflush(stdout);
schnorr_selftest_one(grp->p, grp->q, grp->g, x);
if (BN_add(x, x, BN_value_one()) != 1)
fatal("%s: BN_add (x + 1)", __func__);
}
BN_free(x);
}
int
main(int argc, char **argv)
{
log_init(argv[0], SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_USER, 1);
schnorr_selftest();
return 0;
}
#endif
#endif

View File

@ -1,4 +1,4 @@
/* $OpenBSD: scp.c,v 1.163 2008/06/13 18:55:22 dtucker Exp $ */
/* $OpenBSD: scp.c,v 1.164 2008/10/10 04:55:16 stevesk Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@ -434,7 +434,7 @@ main(int argc, char **argv)
}
/*
* Finally check the exit status of the ssh process, if one was forked
* and no error has occured yet
* and no error has occurred yet
*/
if (do_cmd_pid != -1 && errs == 0) {
if (remin != -1)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.194 2009/01/22 10:02:34 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -43,8 +43,8 @@ __RCSID("$FreeBSD$");
#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;
@ -128,6 +128,7 @@ initialize_server_options(ServerOptions *options)
options->num_permitted_opens = -1;
options->adm_forced_command = NULL;
options->chroot_directory = NULL;
options->zero_knowledge_password_authentication = -1;
}
void
@ -259,6 +260,8 @@ fill_default_server_options(ServerOptions *options)
options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
if (options->permit_tun == -1)
options->permit_tun = SSH_TUNMODE_NO;
if (options->zero_knowledge_password_authentication == -1)
options->zero_knowledge_password_authentication = 0;
/* Turn privilege separation on by default */
if (use_privsep == -1)
@ -303,6 +306,7 @@ typedef enum {
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
sZeroKnowledgePasswordAuthentication,
sVersionAddendum,
sDeprecated, sUnsupported
} ServerOpCodes;
@ -370,6 +374,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 },
@ -382,7 +391,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 },
@ -454,7 +463,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;
@ -470,7 +479,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];
@ -480,7 +489,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
hints.ai_family = options->address_family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
snprintf(strport, sizeof strport, "%u", port);
snprintf(strport, sizeof strport, "%d", port);
if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
fatal("bad addr or host: %s (%s)",
addr ? addr : "<NULL>",
@ -636,7 +645,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;
@ -693,7 +702,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;
@ -746,7 +755,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);
@ -893,6 +902,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;
@ -1255,7 +1268,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)
@ -1387,7 +1400,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);
@ -1449,7 +1464,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:
@ -1554,11 +1569,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);
@ -1572,12 +1591,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);
@ -1636,7 +1665,5 @@ dump_config(ServerOptions *o)
}
dump_cfg_string(sPermitTunnel, s);
printf("permitopen");
channel_print_adm_permitted_opens();
printf("\n");
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.85 2008/06/10 04:50:25 dtucker Exp $ */
/* $OpenBSD: servconf.h,v 1.87 2009/01/22 10:02:34 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -41,9 +41,9 @@
#define INTERNAL_SFTP_NAME "internal-sftp"
typedef struct {
u_int num_ports;
u_int ports_from_cmdline;
u_short ports[MAX_PORTS]; /* Port number to listen on. */
u_int num_ports;
u_int ports_from_cmdline;
int ports[MAX_PORTS]; /* Port number to listen on. */
char *listen_addr; /* Address on which the server listens. */
struct addrinfo *listen_addrs; /* Addresses on which the server listens. */
int address_family; /* Address family used by the server. */
@ -96,6 +96,8 @@ typedef struct {
* authentication. */
int kbd_interactive_authentication; /* If true, permit */
int challenge_response_authentication;
int zero_knowledge_password_authentication;
/* If true, permit jpake auth */
int permit_empty_passwd; /* If false, do not permit empty
* passwords. */
int permit_user_env; /* If true, read ~/.ssh/environment */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: serverloop.c,v 1.153 2008/06/30 12:15:39 djm Exp $ */
/* $OpenBSD: serverloop.c,v 1.157 2009/02/12 03:16:01 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -942,7 +942,7 @@ server_request_direct_tcpip(void)
{
Channel *c;
char *target, *originator;
int target_port, originator_port;
u_short target_port, originator_port;
target = packet_get_string(NULL);
target_port = packet_get_int();
@ -1095,7 +1095,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
{
char *rtype;
int want_reply;
int success = 0;
int success = 0, allocated_listen_port = 0;
rtype = packet_get_string(NULL);
want_reply = packet_get_char();
@ -1117,7 +1117,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
/* check permissions */
if (!options.allow_tcp_forwarding ||
no_port_forwarding_flag
no_port_forwarding_flag ||
(!want_reply && listen_port == 0)
#ifndef NO_IPPORT_RESERVED_CONCEPT
|| (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)
#endif
@ -1127,7 +1128,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
} else {
/* Start listening on the port */
success = channel_setup_remote_fwd_listener(
listen_address, listen_port, options.gateway_ports);
listen_address, listen_port,
&allocated_listen_port, options.gateway_ports);
}
xfree(listen_address);
} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
@ -1149,6 +1151,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
if (want_reply) {
packet_start(success ?
SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
if (success && allocated_listen_port > 0)
packet_put_int(allocated_listen_port);
packet_send();
packet_write_wait();
}
@ -1202,9 +1206,9 @@ server_init_dispatch_20(void)
dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
/* client_alive */
dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive);
dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
/* rekeying */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.241 2008/06/16 13:22:53 dtucker Exp $ */
/* $OpenBSD: session.c,v 1.245 2009/01/22 09:46:01 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -96,6 +96,12 @@ __RCSID("$FreeBSD$");
#include <kafs.h>
#endif
#define IS_INTERNAL_SFTP(c) \
(!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
(c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
c[sizeof(INTERNAL_SFTP_NAME) - 1] == ' ' || \
c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\t'))
/* func */
Session *session_new(void);
@ -229,7 +235,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:
@ -782,7 +788,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;
@ -790,7 +796,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;
@ -945,7 +951,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,
@ -1819,7 +1825,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;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-server-main.c,v 1.3 2008/03/26 23:44:41 djm Exp $ */
/* $OpenBSD: sftp-server-main.c,v 1.4 2009/02/21 19:32:04 tobias Exp $ */
/*
* Copyright (c) 2008 Markus Friedl. All rights reserved.
*
@ -42,7 +42,8 @@ main(int argc, char **argv)
sanitise_stdfd();
if ((user_pw = getpwuid(getuid())) == NULL) {
fprintf(stderr, "No user found for uid %lu", (u_long)getuid());
fprintf(stderr, "No user found for uid %lu\n",
(u_long)getuid());
return 1;
}

View File

@ -1,4 +1,5 @@
.\" $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 $
.\" $FreeBSD$
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@ -22,7 +23,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 July 15 2008
.Dd December 9 2008
.Dt SFTP 1
.Os
.Sh NAME
@ -43,13 +44,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
@ -442,7 +442,7 @@ to
Display the
.Nm
protocol version.
.It Ic \&! Ar command
.It Ic \&! Ns Ar command
Execute
.Ar command
in local shell.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sftp.c,v 1.103 2008/07/13 22:16:03 djm Exp $ */
/* $OpenBSD: sftp.c,v 1.107 2009/02/02 11:15:14 dtucker Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -207,36 +207,37 @@ cmd_interrupt(int signo)
static void
help(void)
{
printf("Available commands:\n");
printf("cd path Change remote directory to 'path'\n");
printf("lcd path Change local directory to 'path'\n");
printf("chgrp grp path Change group of file 'path' to 'grp'\n");
printf("chmod mode path Change permissions of file 'path' to 'mode'\n");
printf("chown own path Change owner of file 'path' to 'own'\n");
printf("df [path] Display statistics for current directory or\n");
printf(" filesystem containing 'path'\n");
printf("help Display this help text\n");
printf("get remote-path [local-path] Download file\n");
printf("lls [ls-options [path]] Display local directory listing\n");
printf("ln oldpath newpath Symlink remote file\n");
printf("lmkdir path Create local directory\n");
printf("lpwd Print local working directory\n");
printf("ls [path] Display remote directory listing\n");
printf("lumask umask Set local umask to 'umask'\n");
printf("mkdir path Create remote directory\n");
printf("progress Toggle display of progress meter\n");
printf("put local-path [remote-path] Upload file\n");
printf("pwd Display remote working directory\n");
printf("exit Quit sftp\n");
printf("quit Quit sftp\n");
printf("rename oldpath newpath Rename remote file\n");
printf("rmdir path Remove remote directory\n");
printf("rm path Delete remote file\n");
printf("symlink oldpath newpath Symlink remote file\n");
printf("version Show SFTP version\n");
printf("!command Execute 'command' in local shell\n");
printf("! Escape to local shell\n");
printf("? Synonym for help\n");
printf("Available commands:\n"
"bye Quit sftp\n"
"cd path Change remote directory to 'path'\n"
"chgrp grp path Change group of file 'path' to 'grp'\n"
"chmod mode path Change permissions of file 'path' to 'mode'\n"
"chown own path Change owner of file 'path' to 'own'\n"
"df [-hi] [path] Display statistics for current directory or\n"
" filesystem containing 'path'\n"
"exit Quit sftp\n"
"get [-P] remote-path [local-path] Download file\n"
"help Display this help text\n"
"lcd path Change local directory to 'path'\n"
"lls [ls-options [path]] Display local directory listing\n"
"lmkdir path Create local directory\n"
"ln oldpath newpath Symlink remote file\n"
"lpwd Print local working directory\n"
"ls [-1aflnrSt] [path] Display remote directory listing\n"
"lumask umask Set local umask to 'umask'\n"
"mkdir path Create remote directory\n"
"progress Toggle display of progress meter\n"
"put [-P] local-path [remote-path] Upload file\n"
"pwd Display remote working directory\n"
"quit Quit sftp\n"
"rename oldpath newpath Rename remote file\n"
"rm path Delete remote file\n"
"rmdir path Remove remote directory\n"
"symlink oldpath newpath Symlink remote file\n"
"version Show SFTP version\n"
"!command Execute 'command' in local shell\n"
"! Escape to local shell\n"
"? Synonym for help\n");
}
static void
@ -1234,8 +1235,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
int err_abort)
{
char *path1, *path2, *tmp;
int pflag, lflag, iflag, hflag, cmdnum, i;
unsigned long n_arg;
int pflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i;
unsigned long n_arg = 0;
Attrib a, *aa;
char path_buf[MAXPATHLEN];
int err = 0;
@ -1386,17 +1387,19 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
if (err != 0 && err_abort)
if (err_abort) {
err = -1;
break;
else
} else
continue;
}
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", g.gl_pathv[i]);
if (err != 0 && err_abort)
if (err_abort) {
err = -1;
break;
else
} else
continue;
}
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
@ -1668,8 +1671,8 @@ usage(void)
"usage: %s [-1Cv] [-B buffer_size] [-b batchfile] [-F ssh_config]\n"
" [-o ssh_option] [-P sftp_server_path] [-R num_requests]\n"
" [-S program] [-s subsystem | sftp_server] host\n"
" %s [[user@]host[:file [file]]]\n"
" %s [[user@]host[:dir[/]]]\n"
" %s [user@]host[:file ...]\n"
" %s [user@]host[:dir[/]]\n"
" %s -b batchfile [user@]host\n", __progname, __progname, __progname, __progname);
exit(1);
}

View File

@ -1,4 +1,5 @@
.\" $OpenBSD: ssh-keygen.1,v 1.78 2008/06/12 19:10:09 jmc Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.79 2008/07/24 23:55:30 sthen Exp $
.\" $FreeBSD$
.\"
.\" -*- nroff -*-
.\"
@ -37,7 +38,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 June 12 2008
.Dd July 24 2008
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@ -83,6 +84,7 @@
.Nm ssh-keygen
.Fl F Ar hostname
.Op Fl f Ar known_hosts_file
.Op Fl l
.Nm ssh-keygen
.Fl H
.Op Fl f Ar known_hosts_file

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.171 2008/07/13 21:22:52 sthen Exp $ */
/* $OpenBSD: ssh-keygen.c,v 1.173 2009/02/21 19:32:04 tobias Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -135,7 +135,7 @@ ask_filename(struct passwd *pw, const char *prompt)
name = _PATH_SSH_CLIENT_ID_RSA;
break;
default:
fprintf(stderr, "bad key type");
fprintf(stderr, "bad key type\n");
exit(1);
break;
}
@ -421,7 +421,7 @@ do_convert_from_ssh2(struct passwd *pw)
PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) :
key_write(k, stdout);
if (!ok) {
fprintf(stderr, "key write failed");
fprintf(stderr, "key write failed\n");
exit(1);
}
key_free(k);
@ -1015,11 +1015,11 @@ do_change_comment(struct passwd *pw)
}
f = fdopen(fd, "w");
if (f == NULL) {
printf("fdopen %s failed", identity_file);
printf("fdopen %s failed\n", identity_file);
exit(1);
}
if (!key_write(public, f))
fprintf(stderr, "write key failed");
fprintf(stderr, "write key failed\n");
key_free(public);
fprintf(f, " %s\n", new_comment);
fclose(f);
@ -1366,7 +1366,7 @@ main(int argc, char **argv)
printf("Generating public/private %s key pair.\n", key_type_name);
private = key_generate(type, bits);
if (private == NULL) {
fprintf(stderr, "key_generate failed");
fprintf(stderr, "key_generate failed\n");
exit(1);
}
public = key_from_private(private);
@ -1426,7 +1426,7 @@ main(int argc, char **argv)
if (identity_comment) {
strlcpy(comment, identity_comment, sizeof(comment));
} else {
/* Create default commend field for the passphrase. */
/* Create default comment field for the passphrase. */
snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
}
@ -1456,11 +1456,11 @@ main(int argc, char **argv)
}
f = fdopen(fd, "w");
if (f == NULL) {
printf("fdopen %s failed", identity_file);
printf("fdopen %s failed\n", identity_file);
exit(1);
}
if (!key_write(public, f))
fprintf(stderr, "write key failed");
fprintf(stderr, "write key failed\n");
fprintf(f, " %s\n", comment);
fclose(f);

View File

@ -1,4 +1,5 @@
.\" $OpenBSD: ssh-keyscan.1,v 1.24 2008/04/30 10:14:03 djm Exp $
.\" $OpenBSD: ssh-keyscan.1,v 1.26 2008/12/29 01:12:36 stevesk Exp $
.\" $FreeBSD$
.\"
.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
.\"
@ -6,7 +7,7 @@
.\" permitted provided that due credit is given to the author and the
.\" OpenBSD project by leaving this copyright notice intact.
.\"
.Dd April 30 2008
.Dd December 29 2008
.Dt SSH-KEYSCAN 1
.Os
.Sh NAME
@ -21,7 +22,7 @@
.Op Fl T Ar timeout
.Op Fl t Ar type
.Op Ar host | addrlist namelist
.Op Ar ...
.Ar ...
.Ek
.Sh DESCRIPTION
.Nm
@ -137,7 +138,7 @@ or
.Pa /etc/ssh/ssh_known_hosts
.Sh EXAMPLES
Print the
.Pa rsa1
.Pa rsa
host key for machine
.Pa hostname :
.Bd -literal

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.76 2008/04/30 10:14:03 djm Exp $ */
/* $OpenBSD: ssh-keyscan.c,v 1.78 2009/01/22 10:02:34 djm Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@ -713,8 +713,9 @@ fatal(const char *fmt,...)
static void
usage(void)
{
fprintf(stderr, "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n"
"\t\t [host | addrlist namelist] [...]\n",
fprintf(stderr,
"usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n"
"\t\t [host | addrlist namelist] ...\n",
__progname);
exit(1);
}
@ -747,7 +748,7 @@ main(int argc, char **argv)
break;
case 'p':
ssh_port = a2port(optarg);
if (ssh_port == 0) {
if (ssh_port <= 0) {
fprintf(stderr, "Bad port '%s'\n", optarg);
exit(1);
}

View File

@ -34,9 +34,9 @@
.\" (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 $
.\" $OpenBSD: ssh.1,v 1.282 2009/02/12 03:44:25 djm Exp $
.\" $FreeBSD$
.Dd July 2 2008
.Dd February 12 2009
.Dt SSH 1
.Os
.Sh NAME
@ -44,7 +44,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\ \&
@ -552,7 +552,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 ,
@ -565,6 +565,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
@ -660,6 +667,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
@ -895,9 +907,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

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.318 2008/07/02 13:47:39 djm Exp $ */
/* $OpenBSD: ssh.c,v 1.324 2009/02/12 03:00:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -180,7 +180,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"
@ -204,7 +204,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;
@ -270,10 +270,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;
@ -300,6 +301,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;
@ -440,7 +444,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);
}
@ -450,7 +454,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,
@ -461,7 +465,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,
@ -472,30 +476,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':
@ -615,7 +603,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
@ -641,7 +629,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();
@ -867,9 +855,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 "
@ -1218,7 +1213,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");

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh2.h,v 1.10 2006/03/25 22:22:43 djm Exp $ */
/* $OpenBSD: ssh2.h,v 1.11 2008/11/04 08:22:13 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -111,6 +111,12 @@
#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60
#define SSH2_MSG_USERAUTH_INFO_REQUEST 60
#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61
#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1 60
#define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1 61
#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2 62
#define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2 63
#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM 64
#define SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM 65
/* connection protocol: generic */
@ -159,3 +165,4 @@
#define SSH2_OPEN_RESOURCE_SHORTAGE 4
#define SSH2_EXTENDED_DATA_STDERR 1

View File

@ -1,4 +1,4 @@
# $OpenBSD: ssh_config,v 1.23 2007/06/08 04:40:40 pvalchev Exp $
# $OpenBSD: ssh_config,v 1.25 2009/02/17 01:28:32 djm Exp $
# $FreeBSD$
# This is the ssh client system-wide configuration file. See
@ -38,10 +38,11 @@
# 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
# VersionAddendum FreeBSD-20080801
# VisualHostKey no
# VersionAddendum FreeBSD-20090522

View File

@ -34,9 +34,9 @@
.\" (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 $
.\" $OpenBSD: ssh_config.5,v 1.119 2009/02/22 23:50:57 djm Exp $
.\" $FreeBSD$
.Dd June 26 2008
.Dd February 22 2009
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@ -104,7 +104,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
@ -205,9 +205,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
@ -812,7 +812,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
@ -1065,15 +1073,17 @@ in
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
.Dq FreeBSD-20080801 .
.Dq FreeBSD-20090522 .
.It Cm VisualHostKey
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

View File

@ -19,6 +19,7 @@
#define acss_setsubkey ssh_acss_setsubkey
#define add_host_to_hostfile ssh_add_host_to_hostfile
#define addargs ssh_addargs
#define addr_match_list ssh_addr_match_list
#define ask_permission ssh_ask_permission
#define atomicio ssh_atomicio
#define atomiciov ssh_atomiciov
@ -52,6 +53,7 @@
#define buffer_get_short ssh_buffer_get_short
#define buffer_get_short_ret ssh_buffer_get_short_ret
#define buffer_get_string ssh_buffer_get_string
#define buffer_get_string_ptr ssh_buffer_get_string_ptr
#define buffer_get_string_ret ssh_buffer_get_string_ret
#define buffer_init ssh_buffer_init
#define buffer_len ssh_buffer_len
@ -71,6 +73,7 @@
#define chan_is_dead ssh_chan_is_dead
#define chan_mark_dead ssh_chan_mark_dead
#define chan_obuf_empty ssh_chan_obuf_empty
#define chan_rcvd_eow ssh_chan_rcvd_eow
#define chan_rcvd_ieof ssh_chan_rcvd_ieof
#define chan_rcvd_oclose ssh_chan_rcvd_oclose
#define chan_read_failed ssh_chan_read_failed
@ -100,6 +103,7 @@
#define channel_input_open_failure ssh_channel_input_open_failure
#define channel_input_port_forward_request ssh_channel_input_port_forward_request
#define channel_input_port_open ssh_channel_input_port_open
#define channel_input_status_confirm ssh_channel_input_status_confirm
#define channel_input_window_adjust ssh_channel_input_window_adjust
#define channel_lookup ssh_channel_lookup
#define channel_new ssh_channel_new
@ -108,9 +112,12 @@
#define channel_output_poll ssh_channel_output_poll
#define channel_permit_all_opens ssh_channel_permit_all_opens
#define channel_prepare_select ssh_channel_prepare_select
#define channel_print_adm_permitted_opens ssh_channel_print_adm_permitted_opens
#define channel_register_cleanup ssh_channel_register_cleanup
#define channel_register_confirm ssh_channel_register_confirm
#define channel_register_filter ssh_channel_register_filter
#define channel_register_open_confirm ssh_channel_register_open_confirm
#define channel_register_status_confirm ssh_channel_register_status_confirm
#define channel_request_remote_forwarding ssh_channel_request_remote_forwarding
#define channel_request_rforward_cancel ssh_channel_request_rforward_cancel
#define channel_request_start ssh_channel_request_start
@ -135,6 +142,7 @@
#define cipher_get_keyiv_len ssh_cipher_get_keyiv_len
#define cipher_get_number ssh_cipher_get_number
#define cipher_init ssh_cipher_init
#define cipher_is_cbc ssh_cipher_is_cbc
#define cipher_keylen ssh_cipher_keylen
#define cipher_mask_ssh1 ssh_cipher_mask_ssh1
#define cipher_name ssh_cipher_name
@ -151,7 +159,10 @@
#define compat_datafellows ssh_compat_datafellows
#define convtime ssh_convtime
#define debug ssh_debug
#define debug ssh_debug
#define debug2 ssh_debug2
#define debug2 ssh_debug2
#define debug3 ssh_debug3
#define debug3 ssh_debug3
#define decode_reply ssh_decode_reply
#define deny_input_open ssh_deny_input_open
@ -175,6 +186,7 @@
#define enable_compat13 ssh_enable_compat13
#define enable_compat20 ssh_enable_compat20
#define error ssh_error
#define error ssh_error
#define evp_acss ssh_evp_acss
#define evp_aes_128_ctr ssh_evp_aes_128_ctr
#define evp_rijndael ssh_evp_rijndael
@ -182,6 +194,8 @@
#define evp_ssh1_bf ssh_evp_ssh1_bf
#define export_dns_rr ssh_export_dns_rr
#define fatal ssh_fatal
#define fatal ssh_fatal
#define fmt_scaled ssh_fmt_scaled
#define freeargs ssh_freeargs
#define freerrset ssh_freerrset
#define gen_candidates ssh_gen_candidates
@ -194,6 +208,7 @@
#define get_remote_ipaddr ssh_get_remote_ipaddr
#define get_remote_name_or_ip ssh_get_remote_name_or_ip
#define get_remote_port ssh_get_remote_port
#define get_sock_port ssh_get_sock_port
#define get_u16 ssh_get_u16
#define get_u32 ssh_get_u32
#define get_u64 ssh_get_u64
@ -240,13 +255,18 @@
#define key_type_from_name ssh_key_type_from_name
#define key_verify ssh_key_verify
#define key_write ssh_key_write
#define log_facility_name ssh_log_facility_name
#define log_facility_number ssh_log_facility_number
#define log_init ssh_log_init
#define log_level_name ssh_log_level_name
#define log_level_number ssh_log_level_number
#define logit ssh_logit
#define logit ssh_logit
#define lookup_key_in_hostfile_by_type ssh_lookup_key_in_hostfile_by_type
#define mac_clear ssh_mac_clear
#define mac_compute ssh_mac_compute
#define mac_init ssh_mac_init
#define mac_setup ssh_mac_setup
#define mac_valid ssh_mac_valid
#define match_host_and_ip ssh_match_host_and_ip
#define match_hostname ssh_match_hostname
@ -256,6 +276,8 @@
#define match_user ssh_match_user
#define mm_receive_fd ssh_mm_receive_fd
#define mm_send_fd ssh_mm_send_fd
#define ms_subtract_diff ssh_ms_subtract_diff
#define ms_to_timeval ssh_ms_to_timeval
#define mysignal ssh_mysignal
#define packet_add_padding ssh_packet_add_padding
#define packet_close ssh_packet_close
@ -277,6 +299,7 @@
#define packet_get_ssh1_cipher ssh_packet_get_ssh1_cipher
#define packet_get_state ssh_packet_get_state
#define packet_get_string ssh_packet_get_string
#define packet_get_string_ptr ssh_packet_get_string_ptr
#define packet_have_data_to_write ssh_packet_have_data_to_write
#define packet_is_interactive ssh_packet_is_interactive
#define packet_need_rekeying ssh_packet_need_rekeying
@ -310,6 +333,7 @@
#define packet_set_rekey_limit ssh_packet_set_rekey_limit
#define packet_set_server ssh_packet_set_server
#define packet_set_state ssh_packet_set_state
#define packet_set_timeout ssh_packet_set_timeout
#define packet_start ssh_packet_start
#define packet_start_compression ssh_packet_start_compression
#define packet_write_poll ssh_packet_write_poll
@ -336,6 +360,9 @@
#define rsa_private_decrypt ssh_rsa_private_decrypt
#define rsa_public_encrypt ssh_rsa_public_encrypt
#define sanitise_stdfd ssh_sanitise_stdfd
#define scan_scaled ssh_scan_scaled
#define schnorr_sign ssh_schnorr_sign
#define schnorr_verify ssh_schnorr_verify
#define seed_rng ssh_seed_rng
#define set_newkeys ssh_set_newkeys
#define set_nodelay ssh_set_nodelay
@ -356,10 +383,15 @@
#define tty_make_modes ssh_tty_make_modes
#define tty_parse_modes ssh_tty_parse_modes
#define tun_open ssh_tun_open
#define umac_delete ssh_umac_delete
#define umac_final ssh_umac_final
#define umac_new ssh_umac_new
#define umac_update ssh_umac_update
#define unset_nonblock ssh_unset_nonblock
#define uudecode ssh_uudecode
#define uuencode ssh_uuencode
#define verbose ssh_verbose
#define verbose ssh_verbose
#define verify_host_key_dns ssh_verify_host_key_dns
#define vis ssh_vis
#define x11_connect_display ssh_x11_connect_display
@ -374,31 +406,3 @@
#define xmmap ssh_xmmap
#define xrealloc ssh_xrealloc
#define xstrdup ssh_xstrdup
#define fmt_scaled ssh_fmt_scaled
#define scan_scaled ssh_scan_scaled
#define addr_match_list ssh_addr_match_list
#define packet_get_string_ptr ssh_packet_get_string_ptr
#define packet_set_timeout ssh_packet_set_timeout
#define mac_clear ssh_mac_clear
#define mac_setup ssh_mac_setup
#define umac_delete ssh_umac_delete
#define umac_final ssh_umac_final
#define umac_new ssh_umac_new
#define umac_update ssh_umac_update
#define chan_rcvd_eow ssh_chan_rcvd_eow
#define channel_input_status_confirm ssh_channel_input_status_confirm
#define channel_print_adm_permitted_opens ssh_channel_print_adm_permitted_opens
#define channel_register_open_confirm ssh_channel_register_open_confirm
#define channel_register_status_confirm ssh_channel_register_status_confirm
#define buffer_get_string_ptr ssh_buffer_get_string_ptr
#define ms_subtract_diff ssh_ms_subtract_diff
#define ms_to_timeval ssh_ms_to_timeval
#define fatal ssh_fatal
#define debug ssh_debug
#define debug2 ssh_debug2
#define debug3 ssh_debug3
#define error ssh_error
#define log_facility_name ssh_log_facility_name
#define log_level_name ssh_log_level_name
#define logit ssh_logit
#define verbose ssh_verbose

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.211 2008/07/01 07:24:22 dtucker Exp $ */
/* $OpenBSD: sshconnect.c,v 1.212 2008/10/14 18:11:33 stevesk Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -71,10 +71,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 *);
@ -742,8 +738,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;
}

View File

@ -1,6 +1,7 @@
/* $OpenBSD: sshconnect2.c,v 1.166 2008/07/17 08:48:00 djm Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.170 2008/11/04 08:22:13 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -67,6 +68,7 @@
#include "msg.h"
#include "pathnames.h"
#include "uidswap.h"
#include "jpake.h"
#ifdef GSSAPI
#include "ssh-gss.h"
@ -201,6 +203,7 @@ struct Authctxt {
struct Authmethod {
char *name; /* string to compare against server's list */
int (*userauth)(Authctxt *authctxt);
void (*cleanup)(Authctxt *authctxt);
int *enabled; /* flag in option struct that enables method */
int *batch_flag; /* flag in option struct that disables method */
};
@ -212,13 +215,18 @@ void input_userauth_error(int, u_int32_t, void *);
void input_userauth_info_req(int, u_int32_t, void *);
void input_userauth_pk_ok(int, u_int32_t, void *);
void input_userauth_passwd_changereq(int, u_int32_t, void *);
void input_userauth_jpake_server_step1(int, u_int32_t, void *);
void input_userauth_jpake_server_step2(int, u_int32_t, void *);
void input_userauth_jpake_server_confirm(int, u_int32_t, void *);
int userauth_none(Authctxt *);
int userauth_pubkey(Authctxt *);
int userauth_passwd(Authctxt *);
int userauth_kbdint(Authctxt *);
int userauth_hostbased(Authctxt *);
int userauth_kerberos(Authctxt *);
int userauth_jpake(Authctxt *);
void userauth_jpake_cleanup(Authctxt *);
#ifdef GSSAPI
int userauth_gssapi(Authctxt *authctxt);
@ -244,30 +252,43 @@ Authmethod authmethods[] = {
#ifdef GSSAPI
{"gssapi-with-mic",
userauth_gssapi,
NULL,
&options.gss_authentication,
NULL},
#endif
{"hostbased",
userauth_hostbased,
NULL,
&options.hostbased_authentication,
NULL},
{"publickey",
userauth_pubkey,
NULL,
&options.pubkey_authentication,
NULL},
#ifdef JPAKE
{"jpake-01@openssh.com",
userauth_jpake,
userauth_jpake_cleanup,
&options.zero_knowledge_password_authentication,
&options.batch_mode},
#endif
{"keyboard-interactive",
userauth_kbdint,
NULL,
&options.kbd_interactive_authentication,
&options.batch_mode},
{"password",
userauth_passwd,
NULL,
&options.password_authentication,
&options.batch_mode},
{"none",
userauth_none,
NULL,
NULL,
NULL},
{NULL, NULL, NULL, NULL}
{NULL, NULL, NULL, NULL, NULL}
};
void
@ -335,6 +356,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
void
userauth(Authctxt *authctxt, char *authlist)
{
if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
authctxt->method->cleanup(authctxt);
if (authctxt->methoddata) {
xfree(authctxt->methoddata);
authctxt->methoddata = NULL;
@ -367,6 +391,7 @@ userauth(Authctxt *authctxt, char *authlist)
}
}
/* ARGSUSED */
void
input_userauth_error(int type, u_int32_t seq, void *ctxt)
{
@ -374,6 +399,7 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
"type %d", type);
}
/* ARGSUSED */
void
input_userauth_banner(int type, u_int32_t seq, void *ctxt)
{
@ -383,12 +409,11 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
debug3("input_userauth_banner");
raw = packet_get_string(&len);
lang = packet_get_string(NULL);
if (options.log_level >= SYSLOG_LEVEL_INFO) {
if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) {
if (len > 65536)
len = 65536;
msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
strnvis(msg, raw, len * 4, VIS_SAFE|VIS_OCTAL);
msg[len*4] = '\0';
strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL);
fprintf(stderr, "%s", msg);
xfree(msg);
}
@ -396,6 +421,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
xfree(lang);
}
/* ARGSUSED */
void
input_userauth_success(int type, u_int32_t seq, void *ctxt)
{
@ -413,6 +439,7 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
authctxt->success = 1; /* break out */
}
/* ARGSUSED */
void
input_userauth_failure(int type, u_int32_t seq, void *ctxt)
{
@ -433,6 +460,8 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
userauth(authctxt, authlist);
}
/* ARGSUSED */
void
input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
{
@ -615,6 +644,7 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
return status;
}
/* ARGSUSED */
void
input_gssapi_response(int type, u_int32_t plen, void *ctxt)
{
@ -654,6 +684,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
}
}
/* ARGSUSED */
void
input_gssapi_token(int type, u_int32_t plen, void *ctxt)
{
@ -681,6 +712,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
}
}
/* ARGSUSED */
void
input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
{
@ -710,6 +742,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
/* Server will be returning a failed packet after this one */
}
/* ARGSUSED */
void
input_gssapi_error(int type, u_int32_t plen, void *ctxt)
{
@ -774,9 +807,11 @@ userauth_passwd(Authctxt *authctxt)
return 1;
}
/*
* parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
*/
/* ARGSUSED */
void
input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
{
@ -841,6 +876,209 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
&input_userauth_passwd_changereq);
}
#ifdef JPAKE
static char *
pw_encrypt(const char *password, const char *crypt_scheme, const char *salt)
{
/* OpenBSD crypt(3) handles all of these */
if (strcmp(crypt_scheme, "crypt") == 0 ||
strcmp(crypt_scheme, "bcrypt") == 0 ||
strcmp(crypt_scheme, "md5crypt") == 0 ||
strcmp(crypt_scheme, "crypt-extended") == 0)
return xstrdup(crypt(password, salt));
error("%s: unsupported password encryption scheme \"%.100s\"",
__func__, crypt_scheme);
return NULL;
}
static BIGNUM *
jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,
const char *salt)
{
char prompt[256], *password, *crypted;
u_char *secret;
u_int secret_len;
BIGNUM *ret;
snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ",
authctxt->server_user, authctxt->host);
password = read_passphrase(prompt, 0);
if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) {
logit("Disabling %s authentication", authctxt->method->name);
authctxt->method->enabled = NULL;
/* Continue with an empty password to fail gracefully */
crypted = xstrdup("");
}
#ifdef JPAKE_DEBUG
debug3("%s: salt = %s", __func__, salt);
debug3("%s: scheme = %s", __func__, crypt_scheme);
debug3("%s: crypted = %s", __func__, crypted);
#endif
if (hash_buffer(crypted, strlen(crypted), EVP_sha256(),
&secret, &secret_len) != 0)
fatal("%s: hash_buffer", __func__);
bzero(password, strlen(password));
bzero(crypted, strlen(crypted));
xfree(password);
xfree(crypted);
if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL)
fatal("%s: BN_bin2bn (secret)", __func__);
bzero(secret, secret_len);
xfree(secret);
return ret;
}
/* ARGSUSED */
void
input_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
struct jpake_ctx *pctx = authctxt->methoddata;
u_char *x3_proof, *x4_proof, *x2_s_proof;
u_int x3_proof_len, x4_proof_len, x2_s_proof_len;
char *crypt_scheme, *salt;
/* Disable this message */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL);
if ((pctx->g_x3 = BN_new()) == NULL ||
(pctx->g_x4 = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
/* Fetch step 1 values */
crypt_scheme = packet_get_string(NULL);
salt = packet_get_string(NULL);
pctx->server_id = packet_get_string(&pctx->server_id_len);
packet_get_bignum2(pctx->g_x3);
packet_get_bignum2(pctx->g_x4);
x3_proof = packet_get_string(&x3_proof_len);
x4_proof = packet_get_string(&x4_proof_len);
packet_check_eom();
JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));
/* Obtain password and derive secret */
pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt);
bzero(crypt_scheme, strlen(crypt_scheme));
bzero(salt, strlen(salt));
xfree(crypt_scheme);
xfree(salt);
JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__));
/* Calculate step 2 values */
jpake_step2(pctx->grp, pctx->s, pctx->g_x1,
pctx->g_x3, pctx->g_x4, pctx->x2,
pctx->server_id, pctx->server_id_len,
pctx->client_id, pctx->client_id_len,
x3_proof, x3_proof_len,
x4_proof, x4_proof_len,
&pctx->a,
&x2_s_proof, &x2_s_proof_len);
bzero(x3_proof, x3_proof_len);
bzero(x4_proof, x4_proof_len);
xfree(x3_proof);
xfree(x4_proof);
JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));
/* Send values for step 2 */
packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2);
packet_put_bignum2(pctx->a);
packet_put_string(x2_s_proof, x2_s_proof_len);
packet_send();
bzero(x2_s_proof, x2_s_proof_len);
xfree(x2_s_proof);
/* Expect step 2 packet from peer */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2,
input_userauth_jpake_server_step2);
}
/* ARGSUSED */
void
input_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
struct jpake_ctx *pctx = authctxt->methoddata;
u_char *x4_s_proof;
u_int x4_s_proof_len;
/* Disable this message */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL);
if ((pctx->b = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
/* Fetch step 2 values */
packet_get_bignum2(pctx->b);
x4_s_proof = packet_get_string(&x4_s_proof_len);
packet_check_eom();
JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));
/* Derive shared key and calculate confirmation hash */
jpake_key_confirm(pctx->grp, pctx->s, pctx->b,
pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4,
pctx->client_id, pctx->client_id_len,
pctx->server_id, pctx->server_id_len,
session_id2, session_id2_len,
x4_s_proof, x4_s_proof_len,
&pctx->k,
&pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len);
bzero(x4_s_proof, x4_s_proof_len);
xfree(x4_s_proof);
JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));
/* Send key confirmation proof */
packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM);
packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
packet_send();
/* Expect confirmation from peer */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM,
input_userauth_jpake_server_confirm);
}
/* ARGSUSED */
void
input_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
struct jpake_ctx *pctx = authctxt->methoddata;
/* Disable this message */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL);
pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len);
packet_check_eom();
JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));
/* Verify expected confirmation hash */
if (jpake_check_confirm(pctx->k,
pctx->server_id, pctx->server_id_len,
session_id2, session_id2_len,
pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1)
debug("%s: %s success", __func__, authctxt->method->name);
else {
debug("%s: confirmation mismatch", __func__);
/* XXX stash this so if auth succeeds then we can warn/kill */
}
userauth_jpake_cleanup(authctxt);
}
#endif /* JPAKE */
static int
identity_sign(Identity *id, u_char **sigp, u_int *lenp,
u_char *data, u_int datalen)
@ -1415,6 +1653,76 @@ userauth_hostbased(Authctxt *authctxt)
return 1;
}
#ifdef JPAKE
int
userauth_jpake(Authctxt *authctxt)
{
struct jpake_ctx *pctx;
u_char *x1_proof, *x2_proof;
u_int x1_proof_len, x2_proof_len;
static int attempt = 0; /* XXX share with userauth_password's? */
if (attempt++ >= options.number_of_password_prompts)
return 0;
if (attempt != 1)
error("Permission denied, please try again.");
if (authctxt->methoddata != NULL)
fatal("%s: authctxt->methoddata already set (%p)",
__func__, authctxt->methoddata);
authctxt->methoddata = pctx = jpake_new();
/*
* Send request immediately, to get the protocol going while
* we do the initial computations.
*/
packet_start(SSH2_MSG_USERAUTH_REQUEST);
packet_put_cstring(authctxt->server_user);
packet_put_cstring(authctxt->service);
packet_put_cstring(authctxt->method->name);
packet_send();
packet_write_wait();
jpake_step1(pctx->grp,
&pctx->client_id, &pctx->client_id_len,
&pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2,
&x1_proof, &x1_proof_len,
&x2_proof, &x2_proof_len);
JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));
packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1);
packet_put_string(pctx->client_id, pctx->client_id_len);
packet_put_bignum2(pctx->g_x1);
packet_put_bignum2(pctx->g_x2);
packet_put_string(x1_proof, x1_proof_len);
packet_put_string(x2_proof, x2_proof_len);
packet_send();
bzero(x1_proof, x1_proof_len);
bzero(x2_proof, x2_proof_len);
xfree(x1_proof);
xfree(x2_proof);
/* Expect step 1 packet from peer */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1,
input_userauth_jpake_server_step1);
return 1;
}
void
userauth_jpake_cleanup(Authctxt *authctxt)
{
debug3("%s: clean up", __func__);
if (authctxt->methoddata != NULL) {
jpake_free(authctxt->methoddata);
authctxt->methoddata = NULL;
}
}
#endif /* JPAKE */
/* find auth method */
/*
@ -1516,3 +1824,4 @@ authmethods_get(void)
buffer_free(&b);
return list;
}

View File

@ -34,9 +34,9 @@
.\" (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 $
.\" $OpenBSD: sshd.8,v 1.247 2008/10/03 13:08:12 jmc Exp $
.\" $FreeBSD$
.Dd July 2 2008
.Dd October 3 2008
.Dt SSHD 8
.Os
.Sh NAME
@ -744,8 +744,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).

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.364 2008/07/10 18:08:11 markus Exp $ */
/* $OpenBSD: sshd.c,v 1.366 2009/01/22 10:02:34 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -128,7 +128,6 @@ __RCSID("$FreeBSD$");
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "monitor_fdpass.h"
#include "version.h"
#ifdef LIBWRAP
@ -1345,7 +1344,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);
}

View File

@ -14,7 +14,7 @@
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
# FreeBSD has a few additional options.
#VersionAddendum FreeBSD-20080801
#VersionAddendum FreeBSD-20090522
#Port 22
#Protocol 2

View File

@ -34,9 +34,9 @@
.\" (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 $
.\" $OpenBSD: sshd_config.5,v 1.102 2009/02/22 23:59:25 djm Exp $
.\" $FreeBSD$
.Dd July 2 2008
.Dd February 22 2009
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -240,9 +240,9 @@ and
.Dq cast128-cbc .
The default is:
.Bd -literal -offset 3n
aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
aes192-ctr,aes256-ctr
aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,
aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,
aes256-cbc,arcfour
.Ed
.It Cm ClientAliveCountMax
Sets the number of client alive messages (see below) which may be
@ -593,6 +593,7 @@ Only a subset of keywords may be used on the lines following a
.Cm Match
keyword.
Available keywords are
.Cm AllowAgentForwarding ,
.Cm AllowTcpForwarding ,
.Cm Banner ,
.Cm ChrootDirectory ,
@ -605,12 +606,13 @@ Available keywords are
.Cm MaxAuthTries ,
.Cm MaxSessions ,
.Cm PasswordAuthentication ,
.Cm PermitEmptyPasswords ,
.Cm PermitOpen ,
.Cm PermitRootLogin ,
.Cm RhostsRSAAuthentication ,
.Cm RSAAuthentication ,
.Cm X11DisplayOffset ,
.Cm X11Forwarding ,
.Cm X11Forwarding
and
.Cm X11UseLocalHost .
.It Cm MaxAuthTries
@ -947,7 +949,7 @@ The default is
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
.Dq FreeBSD-20080801 .
.Dq FreeBSD-20090522 .
.It Cm X11DisplayOffset
Specifies the first display number available for
.Xr sshd 8 Ns 's

View File

@ -46,6 +46,13 @@
#define O_NOCTTY 0
#endif
#ifdef __APPLE__
# include <AvailabilityMacros.h>
# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
# define __APPLE_PRIVPTY__
# endif
#endif
/*
* Allocates and opens a pty. Returns 0 if no pty could be allocated, or
* nonzero if a pty was successfully allocated. On success, open file
@ -78,10 +85,12 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
void
pty_release(const char *tty)
{
#ifndef __APPLE_PRIVPTY__
if (chown(tty, (uid_t) 0, (gid_t) 0) < 0)
error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno));
if (chmod(tty, (mode_t) 0666) < 0)
error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno));
#endif /* __APPLE_PRIVPTY__ */
}
/* Makes the tty the process's controlling tty and sets it to sane modes. */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ttymodes.c,v 1.28 2008/07/07 00:31:41 stevesk Exp $ */
/* $OpenBSD: ttymodes.c,v 1.29 2008/11/02 00:16:16 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -311,11 +311,9 @@ tty_make_modes(int fd, struct termios *tiop)
/* Store input and output baud rates. */
baud = speed_to_baud(cfgetospeed(&tio));
debug3("tty_make_modes: ospeed %d", baud);
buffer_put_char(&buf, tty_op_ospeed);
buffer_put_int(&buf, baud);
baud = speed_to_baud(cfgetispeed(&tio));
debug3("tty_make_modes: ispeed %d", baud);
buffer_put_char(&buf, tty_op_ispeed);
buffer_put_int(&buf, baud);
@ -359,7 +357,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
if (compat20) {
*n_bytes_ptr = packet_get_int();
debug3("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr);
if (*n_bytes_ptr == 0)
return;
get_arg = packet_get_int;
@ -391,7 +388,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
case TTY_OP_ISPEED_PROTO2:
n_bytes += 4;
baud = packet_get_int();
debug3("tty_parse_modes: ispeed %d", baud);
if (failure != -1 &&
cfsetispeed(&tio, baud_to_speed(baud)) == -1)
error("cfsetispeed failed for %d", baud);
@ -402,7 +398,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
case TTY_OP_OSPEED_PROTO2:
n_bytes += 4;
baud = packet_get_int();
debug3("tty_parse_modes: ospeed %d", baud);
if (failure != -1 &&
cfsetospeed(&tio, baud_to_speed(baud)) == -1)
error("cfsetospeed failed for %d", baud);

View File

@ -233,6 +233,16 @@ permanently_set_uid(struct passwd *pw)
fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
#endif
#ifdef __APPLE__
/*
* OS X requires initgroups after setgid to opt back into
* memberd support for >16 supplemental groups.
*/
if (initgroups(pw->pw_name, pw->pw_gid) < 0)
fatal("initgroups %.100s %u: %.100s",
pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
#endif
#if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)
fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno));

View File

@ -1,13 +1,13 @@
/* $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 $ */
/* $FreeBSD$ */
#ifndef SSH_VERSION
#define SSH_VERSION (ssh_version_get())
#define SSH_RELEASE (ssh_version_get())
#define SSH_VERSION_BASE "OpenSSH_5.1p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20080801"
#define SSH_VERSION_BASE "OpenSSH_5.2p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20090522"
const char *ssh_version_get(void);
void ssh_version_set_addendum(const char *add);
void ssh_version_set_addendum(const char *);
#endif /* SSH_VERSION */

View File

@ -13,7 +13,7 @@ SRCS= acss.c authfd.c authfile.c bufaux.c bufbn.c buffer.c \
atomicio.c key.c dispatch.c kex.c mac.c uidswap.c uuencode.c misc.c \
monitor_fdpass.c rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c \
kexgex.c kexdhc.c kexgexc.c scard.c msg.c progressmeter.c dns.c \
entropy.c scard-opensc.c umac.c
entropy.c scard-opensc.c umac.c jpake.c schnorr.c
# gss-genr.c should be in $SRCS but causes linking problems, so it is
# compiled directly into sshd instead.

View File

@ -9,7 +9,7 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
auth.c auth1.c auth2.c auth-options.c session.c \
auth-chall.c auth2-chall.c groupaccess.c \
auth-skey.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \
auth2-none.c auth2-passwd.c auth2-pubkey.c \
auth2-none.c auth2-passwd.c auth2-pubkey.c auth2-jpake.c \
monitor_mm.c monitor.c monitor_wrap.c kexdhs.c kexgexs.c \
auth-krb5.c \
auth2-gss.c gss-serv.c gss-serv-krb5.c \