Upgrade to OpenSSH 6.9p1.

This commit is contained in:
Dag-Erling Smørgrav 2016-01-19 18:55:44 +00:00
commit 557f75e54a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=294336
115 changed files with 3880 additions and 2313 deletions

File diff suppressed because it is too large Load diff

View file

@ -175,7 +175,7 @@ whitelisted to receive this message upon request.
OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com" OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
channel type. This channel type supports forwarding of network packets channel type. This channel type supports forwarding of network packets
with datagram boundaries intact between endpoints equipped with with datagram boundaries intact between endpoints equipped with
interfaces like the BSD tun(4) device. Tunnel forwarding channels are interfaces like the BSD tun(4) device. Tunnel forwarding channels are
requested by the client with the following packet: requested by the client with the following packet:
@ -453,4 +453,4 @@ respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version This extension is advertised in the SSH_FXP_VERSION hello with version
"1". "1".
$OpenBSD: PROTOCOL,v 1.27 2015/02/20 22:17:21 djm Exp $ $OpenBSD: PROTOCOL,v 1.28 2015/05/08 03:56:51 djm Exp $

View file

@ -413,7 +413,7 @@ It may be requested using this message:
"rsa_e" and "rsa_n" are used to identify which private key to use. "rsa_e" and "rsa_n" are used to identify which private key to use.
"encrypted_challenge" is a challenge blob that has (presumably) "encrypted_challenge" is a challenge blob that has (presumably)
been encrypted with the public key and must be in the range been encrypted with the public key and must be in the range
1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1 1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1
session ID (computed from the server host key, the server semi-ephemeral session ID (computed from the server host key, the server semi-ephemeral
key and the session cookie). key and the session cookie).
@ -557,4 +557,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys.
SSH_AGENT_CONSTRAIN_LIFETIME 1 SSH_AGENT_CONSTRAIN_LIFETIME 1
SSH_AGENT_CONSTRAIN_CONFIRM 2 SSH_AGENT_CONSTRAIN_CONFIRM 2
$OpenBSD: PROTOCOL.agent,v 1.7 2013/01/02 00:33:49 djm Exp $ $OpenBSD: PROTOCOL.agent,v 1.8 2015/05/08 03:56:51 djm Exp $

View file

@ -1,4 +1,4 @@
See http://www.openssh.com/txt/release-6.8 for the release notes. See http://www.openssh.com/txt/release-6.9 for the release notes.
- A Japanese translation of this document and of the OpenSSH FAQ is - A Japanese translation of this document and of the OpenSSH FAQ is
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html - available at http://www.unixuser.org/~haruyama/security/openssh/index.html

View file

@ -30,8 +30,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include "xmalloc.h" #include "xmalloc.h"
#include "key.h" #include "key.h"
#include "hostfile.h" #include "hostfile.h"

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.c,v 1.65 2015/01/14 10:30:34 markus Exp $ */ /* $OpenBSD: auth-options.c,v 1.67 2015/05/01 03:20:54 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -209,8 +209,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
goto next_option; goto next_option;
} }
cp = "environment=\""; cp = "environment=\"";
if (options.permit_user_env && if (strncasecmp(opts, cp, strlen(cp)) == 0) {
strncasecmp(opts, cp, strlen(cp)) == 0) {
char *s; char *s;
struct envstring *new_envstring; struct envstring *new_envstring;
@ -236,13 +235,19 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
goto bad_option; goto bad_option;
} }
s[i] = '\0'; s[i] = '\0';
auth_debug_add("Adding to environment: %.900s", s);
debug("Adding to environment: %.900s", s);
opts++; opts++;
new_envstring = xcalloc(1, sizeof(struct envstring)); if (options.permit_user_env) {
new_envstring->s = s; auth_debug_add("Adding to environment: "
new_envstring->next = custom_environment; "%.900s", s);
custom_environment = new_envstring; debug("Adding to environment: %.900s", s);
new_envstring = xcalloc(1,
sizeof(*new_envstring));
new_envstring->s = s;
new_envstring->next = custom_environment;
custom_environment = new_envstring;
s = NULL;
}
free(s);
goto next_option; goto next_option;
} }
cp = "from=\""; cp = "from=\"";
@ -603,7 +608,7 @@ auth_cert_options(struct sshkey *k, struct passwd *pw)
&cert_source_address_done) == -1) &cert_source_address_done) == -1)
return -1; return -1;
if (parse_option_list(k->cert->extensions, pw, if (parse_option_list(k->cert->extensions, pw,
OPTIONS_EXTENSIONS, 1, OPTIONS_EXTENSIONS, 0,
&cert_no_port_forwarding_flag, &cert_no_port_forwarding_flag,
&cert_no_agent_forwarding_flag, &cert_no_agent_forwarding_flag,
&cert_no_x11_forwarding_flag, &cert_no_x11_forwarding_flag,

View file

@ -738,7 +738,7 @@ sshpam_query(void *ctx, char **name, char **info,
case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_OFF:
*num = 1; *num = 1;
len = plen + mlen + 1; len = plen + mlen + 1;
**prompts = xrealloc(**prompts, 1, len); **prompts = xreallocarray(**prompts, 1, len);
strlcpy(**prompts + plen, msg, len - plen); strlcpy(**prompts + plen, msg, len - plen);
plen += mlen; plen += mlen;
**echo_on = (type == PAM_PROMPT_ECHO_ON); **echo_on = (type == PAM_PROMPT_ECHO_ON);
@ -748,7 +748,7 @@ sshpam_query(void *ctx, char **name, char **info,
case PAM_TEXT_INFO: case PAM_TEXT_INFO:
/* accumulate messages */ /* accumulate messages */
len = plen + mlen + 2; len = plen + mlen + 2;
**prompts = xrealloc(**prompts, 1, len); **prompts = xreallocarray(**prompts, 1, len);
strlcpy(**prompts + plen, msg, len - plen); strlcpy(**prompts + plen, msg, len - plen);
plen += mlen; plen += mlen;
strlcat(**prompts + plen, "\n", len - plen); strlcat(**prompts + plen, "\n", len - plen);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.110 2015/02/25 17:29:38 djm Exp $ */ /* $OpenBSD: auth.c,v 1.111 2015/05/01 04:17:51 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* *
@ -401,8 +401,7 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
char * char *
authorized_principals_file(struct passwd *pw) authorized_principals_file(struct passwd *pw)
{ {
if (options.authorized_principals_file == NULL || if (options.authorized_principals_file == NULL)
strcasecmp(options.authorized_principals_file, "none") == 0)
return NULL; return NULL;
return expand_authorized_keys(options.authorized_principals_file, pw); return expand_authorized_keys(options.authorized_principals_file, pw);
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.82 2015/02/16 22:13:32 djm Exp $ */ /* $OpenBSD: auth.h,v 1.84 2015/05/08 06:41:56 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -56,7 +56,7 @@ struct Authctxt {
int valid; /* user exists and is allowed to login */ int valid; /* user exists and is allowed to login */
int attempt; int attempt;
int failures; int failures;
int server_caused_failure; int server_caused_failure;
int force_pwchange; int force_pwchange;
char *user; /* username sent by the client */ char *user; /* username sent by the client */
char *service; char *service;
@ -126,7 +126,7 @@ int auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
int user_key_allowed(struct passwd *, Key *); int user_key_allowed(struct passwd *, Key *, int);
void pubkey_auth_info(Authctxt *, const Key *, const char *, ...) void pubkey_auth_info(Authctxt *, const Key *, const char *, ...)
__attribute__((__format__ (printf, 3, 4))); __attribute__((__format__ (printf, 3, 4)));
void auth2_record_userkey(Authctxt *, struct sshkey *); void auth2_record_userkey(Authctxt *, struct sshkey *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-hostbased.c,v 1.24 2015/01/28 22:36:00 djm Exp $ */ /* $OpenBSD: auth2-hostbased.c,v 1.25 2015/05/04 06:10:48 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* *
@ -109,8 +109,7 @@ userauth_hostbased(Authctxt *authctxt)
goto done; goto done;
} }
if (match_pattern_list(sshkey_ssh_name(key), if (match_pattern_list(sshkey_ssh_name(key),
options.hostbased_key_types, options.hostbased_key_types, 0) != 1) {
strlen(options.hostbased_key_types), 0) != 1) {
logit("%s: key type %s not in HostbasedAcceptedKeyTypes", logit("%s: key type %s not in HostbasedAcceptedKeyTypes",
__func__, sshkey_type(key)); __func__, sshkey_type(key));
goto done; goto done;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.47 2015/02/17 00:14:05 djm Exp $ */ /* $OpenBSD: auth2-pubkey.c,v 1.53 2015/06/15 18:44:22 jsing Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* *
@ -65,6 +65,9 @@
#include "monitor_wrap.h" #include "monitor_wrap.h"
#include "authfile.h" #include "authfile.h"
#include "match.h" #include "match.h"
#include "ssherr.h"
#include "channels.h" /* XXX for session.h */
#include "session.h" /* XXX for child_set_env(); refactor? */
/* import */ /* import */
extern ServerOptions options; extern ServerOptions options;
@ -127,8 +130,8 @@ userauth_pubkey(Authctxt *authctxt)
logit("refusing previously-used %s key", key_type(key)); logit("refusing previously-used %s key", key_type(key));
goto done; goto done;
} }
if (match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types, if (match_pattern_list(sshkey_ssh_name(key),
strlen(options.pubkey_key_types), 0) != 1) { options.pubkey_key_types, 0) != 1) {
logit("%s: key type %s not in PubkeyAcceptedKeyTypes", logit("%s: key type %s not in PubkeyAcceptedKeyTypes",
__func__, sshkey_ssh_name(key)); __func__, sshkey_ssh_name(key));
goto done; goto done;
@ -169,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt)
/* test for correct signature */ /* test for correct signature */
authenticated = 0; authenticated = 0;
if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
buffer_len(&b))) == 1) { buffer_len(&b))) == 1) {
authenticated = 1; authenticated = 1;
@ -191,7 +194,7 @@ userauth_pubkey(Authctxt *authctxt)
* if a user is not allowed to login. is this an * if a user is not allowed to login. is this an
* issue? -markus * issue? -markus
*/ */
if (PRIVSEP(user_key_allowed(authctxt->pw, key))) { if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
packet_start(SSH2_MSG_USERAUTH_PK_OK); packet_start(SSH2_MSG_USERAUTH_PK_OK);
packet_put_string(pkalg, alen); packet_put_string(pkalg, alen);
packet_put_string(pkblob, blen); packet_put_string(pkblob, blen);
@ -248,6 +251,288 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
free(extra); free(extra);
} }
/*
* Splits 's' into an argument vector. Handles quoted string and basic
* escape characters (\\, \", \'). Caller must free the argument vector
* and its members.
*/
static int
split_argv(const char *s, int *argcp, char ***argvp)
{
int r = SSH_ERR_INTERNAL_ERROR;
int argc = 0, quote, i, j;
char *arg, **argv = xcalloc(1, sizeof(*argv));
*argvp = NULL;
*argcp = 0;
for (i = 0; s[i] != '\0'; i++) {
/* Skip leading whitespace */
if (s[i] == ' ' || s[i] == '\t')
continue;
/* Start of a token */
quote = 0;
if (s[i] == '\\' &&
(s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\'))
i++;
else if (s[i] == '\'' || s[i] == '"')
quote = s[i++];
argv = xreallocarray(argv, (argc + 2), sizeof(*argv));
arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1);
argv[argc] = NULL;
/* Copy the token in, removing escapes */
for (j = 0; s[i] != '\0'; i++) {
if (s[i] == '\\') {
if (s[i + 1] == '\'' ||
s[i + 1] == '\"' ||
s[i + 1] == '\\') {
i++; /* Skip '\' */
arg[j++] = s[i];
} else {
/* Unrecognised escape */
arg[j++] = s[i];
}
} else if (quote == 0 && (s[i] == ' ' || s[i] == '\t'))
break; /* done */
else if (quote != 0 && s[i] == quote)
break; /* done */
else
arg[j++] = s[i];
}
if (s[i] == '\0') {
if (quote != 0) {
/* Ran out of string looking for close quote */
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
break;
}
}
/* Success */
*argcp = argc;
*argvp = argv;
argc = 0;
argv = NULL;
r = 0;
out:
if (argc != 0 && argv != NULL) {
for (i = 0; i < argc; i++)
free(argv[i]);
free(argv);
}
return r;
}
/*
* Reassemble an argument vector into a string, quoting and escaping as
* necessary. Caller must free returned string.
*/
static char *
assemble_argv(int argc, char **argv)
{
int i, j, ws, r;
char c, *ret;
struct sshbuf *buf, *arg;
if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
for (i = 0; i < argc; i++) {
ws = 0;
sshbuf_reset(arg);
for (j = 0; argv[i][j] != '\0'; j++) {
r = 0;
c = argv[i][j];
switch (c) {
case ' ':
case '\t':
ws = 1;
r = sshbuf_put_u8(arg, c);
break;
case '\\':
case '\'':
case '"':
if ((r = sshbuf_put_u8(arg, '\\')) != 0)
break;
/* FALLTHROUGH */
default:
r = sshbuf_put_u8(arg, c);
break;
}
if (r != 0)
fatal("%s: sshbuf_put_u8: %s",
__func__, ssh_err(r));
}
if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) ||
(ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) ||
(r = sshbuf_putb(buf, arg)) != 0 ||
(ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0))
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL)
fatal("%s: malloc failed", __func__);
memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf));
ret[sshbuf_len(buf)] = '\0';
sshbuf_free(buf);
sshbuf_free(arg);
return ret;
}
/*
* Runs command in a subprocess. Returns pid on success and a FILE* to the
* subprocess' stdout or 0 on failure.
* NB. "command" is only used for logging.
*/
static pid_t
subprocess(const char *tag, struct passwd *pw, const char *command,
int ac, char **av, FILE **child)
{
FILE *f;
struct stat st;
int devnull, p[2], i;
pid_t pid;
char *cp, errmsg[512];
u_int envsize;
char **child_env;
*child = NULL;
debug3("%s: %s command \"%s\" running as %s", __func__,
tag, command, pw->pw_name);
/* Verify the path exists and is safe-ish to execute */
if (*av[0] != '/') {
error("%s path is not absolute", tag);
return 0;
}
temporarily_use_uid(pw);
if (stat(av[0], &st) < 0) {
error("Could not stat %s \"%s\": %s", tag,
av[0], strerror(errno));
restore_uid();
return 0;
}
if (auth_secure_path(av[0], &st, NULL, 0,
errmsg, sizeof(errmsg)) != 0) {
error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
restore_uid();
return 0;
}
/*
* Run the command; stderr is left in place, stdout is the
* authorized_keys output.
*/
if (pipe(p) != 0) {
error("%s: pipe: %s", tag, strerror(errno));
restore_uid();
return 0;
}
/*
* Don't want to call this in the child, where it can fatal() and
* run cleanup_exit() code.
*/
restore_uid();
switch ((pid = fork())) {
case -1: /* error */
error("%s: fork: %s", tag, strerror(errno));
close(p[0]);
close(p[1]);
return 0;
case 0: /* child */
/* Prepare a minimal environment for the child. */
envsize = 5;
child_env = xcalloc(sizeof(*child_env), envsize);
child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH);
child_set_env(&child_env, &envsize, "USER", pw->pw_name);
child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name);
child_set_env(&child_env, &envsize, "HOME", pw->pw_dir);
if ((cp = getenv("LANG")) != NULL)
child_set_env(&child_env, &envsize, "LANG", cp);
for (i = 0; i < NSIG; i++)
signal(i, SIG_DFL);
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
error("%s: open %s: %s", tag, _PATH_DEVNULL,
strerror(errno));
_exit(1);
}
/* Keep stderr around a while longer to catch errors */
if (dup2(devnull, STDIN_FILENO) == -1 ||
dup2(p[1], STDOUT_FILENO) == -1) {
error("%s: dup2: %s", tag, strerror(errno));
_exit(1);
}
closefrom(STDERR_FILENO + 1);
/* Don't use permanently_set_uid() here to avoid fatal() */
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,
strerror(errno));
_exit(1);
}
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid,
strerror(errno));
_exit(1);
}
/* stdin is pointed to /dev/null at this point */
if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
error("%s: dup2: %s", tag, strerror(errno));
_exit(1);
}
execve(av[0], av, child_env);
error("%s exec \"%s\": %s", tag, command, strerror(errno));
_exit(127);
default: /* parent */
break;
}
close(p[1]);
if ((f = fdopen(p[0], "r")) == NULL) {
error("%s: fdopen: %s", tag, strerror(errno));
close(p[0]);
/* Don't leave zombie child */
kill(pid, SIGTERM);
while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
;
return 0;
}
/* Success */
debug3("%s: %s pid %ld", __func__, tag, (long)pid);
*child = f;
return pid;
}
/* Returns 0 if pid exited cleanly, non-zero otherwise */
static int
exited_cleanly(pid_t pid, const char *tag, const char *cmd)
{
int status;
while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR) {
error("%s: waitpid: %s", tag, strerror(errno));
return -1;
}
}
if (WIFSIGNALED(status)) {
error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status));
return -1;
} else if (WEXITSTATUS(status) != 0) {
error("%s %s failed, status %d", tag, cmd, WEXITSTATUS(status));
return -1;
}
return 0;
}
static int static int
match_principals_option(const char *principal_list, struct sshkey_cert *cert) match_principals_option(const char *principal_list, struct sshkey_cert *cert)
{ {
@ -269,19 +554,13 @@ match_principals_option(const char *principal_list, struct sshkey_cert *cert)
} }
static int static int
match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert) process_principals(FILE *f, char *file, struct passwd *pw,
struct sshkey_cert *cert)
{ {
FILE *f;
char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
u_long linenum = 0; u_long linenum = 0;
u_int i; u_int i;
temporarily_use_uid(pw);
debug("trying authorized principals file %s", file);
if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {
restore_uid();
return 0;
}
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
/* Skip leading whitespace. */ /* Skip leading whitespace. */
for (cp = line; *cp == ' ' || *cp == '\t'; cp++) for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@ -309,23 +588,127 @@ match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
} }
for (i = 0; i < cert->nprincipals; i++) { for (i = 0; i < cert->nprincipals; i++) {
if (strcmp(cp, cert->principals[i]) == 0) { if (strcmp(cp, cert->principals[i]) == 0) {
debug3("matched principal \"%.100s\" " debug3("%s:%lu: matched principal \"%.100s\"",
"from file \"%s\" on line %lu", file == NULL ? "(command)" : file,
cert->principals[i], file, linenum); linenum, cert->principals[i]);
if (auth_parse_options(pw, line_opts, if (auth_parse_options(pw, line_opts,
file, linenum) != 1) file, linenum) != 1)
continue; continue;
fclose(f);
restore_uid();
return 1; return 1;
} }
} }
} }
fclose(f);
restore_uid();
return 0; return 0;
} }
static int
match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
{
FILE *f;
int success;
temporarily_use_uid(pw);
debug("trying authorized principals file %s", file);
if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {
restore_uid();
return 0;
}
success = process_principals(f, file, pw, cert);
fclose(f);
restore_uid();
return success;
}
/*
* Checks whether principal is allowed in output of command.
* returns 1 if the principal is allowed or 0 otherwise.
*/
static int
match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert)
{
FILE *f = NULL;
int ok, found_principal = 0;
struct passwd *pw;
int i, ac = 0, uid_swapped = 0;
pid_t pid;
char *tmp, *username = NULL, *command = NULL, **av = NULL;
void (*osigchld)(int);
if (options.authorized_principals_command == NULL)
return 0;
if (options.authorized_principals_command_user == NULL) {
error("No user for AuthorizedPrincipalsCommand specified, "
"skipping");
return 0;
}
/*
* NB. all returns later this function should go via "out" to
* ensure the original SIGCHLD handler is restored properly.
*/
osigchld = signal(SIGCHLD, SIG_DFL);
/* Prepare and verify the user for the command */
username = percent_expand(options.authorized_principals_command_user,
"u", user_pw->pw_name, (char *)NULL);
pw = getpwnam(username);
if (pw == NULL) {
error("AuthorizedPrincipalsCommandUser \"%s\" not found: %s",
username, strerror(errno));
goto out;
}
/* Turn the command into an argument vector */
if (split_argv(options.authorized_principals_command, &ac, &av) != 0) {
error("AuthorizedPrincipalsCommand \"%s\" contains "
"invalid quotes", command);
goto out;
}
if (ac == 0) {
error("AuthorizedPrincipalsCommand \"%s\" yielded no arguments",
command);
goto out;
}
for (i = 1; i < ac; i++) {
tmp = percent_expand(av[i],
"u", user_pw->pw_name,
"h", user_pw->pw_dir,
(char *)NULL);
if (tmp == NULL)
fatal("%s: percent_expand failed", __func__);
free(av[i]);
av[i] = tmp;
}
/* Prepare a printable command for logs, etc. */
command = assemble_argv(ac, av);
if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command,
ac, av, &f)) == 0)
goto out;
uid_swapped = 1;
temporarily_use_uid(pw);
ok = process_principals(f, NULL, pw, cert);
if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0)
goto out;
/* Read completed successfully */
found_principal = ok;
out:
if (f != NULL)
fclose(f);
signal(SIGCHLD, osigchld);
for (i = 0; i < ac; i++)
free(av[i]);
free(av);
if (uid_swapped)
restore_uid();
free(command);
free(username);
return found_principal;
}
/* /*
* Checks whether key is allowed in authorized_keys-format file, * Checks whether key is allowed in authorized_keys-format file,
* returns 1 if the key is allowed or 0 otherwise. * returns 1 if the key is allowed or 0 otherwise.
@ -448,7 +831,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
{ {
char *ca_fp, *principals_file = NULL; char *ca_fp, *principals_file = NULL;
const char *reason; const char *reason;
int ret = 0; int ret = 0, found_principal = 0, use_authorized_principals;
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
return 0; return 0;
@ -470,17 +853,24 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
* against the username. * against the username.
*/ */
if ((principals_file = authorized_principals_file(pw)) != NULL) { if ((principals_file = authorized_principals_file(pw)) != NULL) {
if (!match_principals_file(principals_file, pw, key->cert)) { if (match_principals_file(principals_file, pw, key->cert))
reason = "Certificate does not contain an " found_principal = 1;
"authorized principal"; }
/* Try querying command if specified */
if (!found_principal && match_principals_command(pw, key->cert))
found_principal = 1;
/* If principals file or command is specified, then require a match */
use_authorized_principals = principals_file != NULL ||
options.authorized_principals_command != NULL;
if (!found_principal && use_authorized_principals) {
reason = "Certificate does not contain an authorized principal";
fail_reason: fail_reason:
error("%s", reason); error("%s", reason);
auth_debug_add("%s", reason); auth_debug_add("%s", reason);
goto out; goto out;
}
} }
if (key_cert_check_authority(key, 0, 1, if (key_cert_check_authority(key, 0, 1,
principals_file == NULL ? pw->pw_name : NULL, &reason) != 0) use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
goto fail_reason; goto fail_reason;
if (auth_cert_options(key, pw) != 0) if (auth_cert_options(key, pw) != 0)
goto out; goto out;
@ -526,144 +916,117 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
static int static int
user_key_command_allowed2(struct passwd *user_pw, Key *key) user_key_command_allowed2(struct passwd *user_pw, Key *key)
{ {
FILE *f; FILE *f = NULL;
int ok, found_key = 0; int r, ok, found_key = 0;
struct passwd *pw; struct passwd *pw;
struct stat st; int i, uid_swapped = 0, ac = 0;
int status, devnull, p[2], i;
pid_t pid; pid_t pid;
char *username, errmsg[512]; char *username = NULL, *key_fp = NULL, *keytext = NULL;
char *tmp, *command = NULL, **av = NULL;
void (*osigchld)(int);
if (options.authorized_keys_command == NULL || if (options.authorized_keys_command == NULL)
options.authorized_keys_command[0] != '/')
return 0; return 0;
if (options.authorized_keys_command_user == NULL) { if (options.authorized_keys_command_user == NULL) {
error("No user for AuthorizedKeysCommand specified, skipping"); error("No user for AuthorizedKeysCommand specified, skipping");
return 0; return 0;
} }
/*
* NB. all returns later this function should go via "out" to
* ensure the original SIGCHLD handler is restored properly.
*/
osigchld = signal(SIGCHLD, SIG_DFL);
/* Prepare and verify the user for the command */
username = percent_expand(options.authorized_keys_command_user, username = percent_expand(options.authorized_keys_command_user,
"u", user_pw->pw_name, (char *)NULL); "u", user_pw->pw_name, (char *)NULL);
pw = getpwnam(username); pw = getpwnam(username);
if (pw == NULL) { if (pw == NULL) {
error("AuthorizedKeysCommandUser \"%s\" not found: %s", error("AuthorizedKeysCommandUser \"%s\" not found: %s",
username, strerror(errno)); username, strerror(errno));
free(username);
return 0;
}
free(username);
temporarily_use_uid(pw);
if (stat(options.authorized_keys_command, &st) < 0) {
error("Could not stat AuthorizedKeysCommand \"%s\": %s",
options.authorized_keys_command, strerror(errno));
goto out;
}
if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
errmsg, sizeof(errmsg)) != 0) {
error("Unsafe AuthorizedKeysCommand: %s", errmsg);
goto out; goto out;
} }
if (pipe(p) != 0) { /* Prepare AuthorizedKeysCommand */
error("%s: pipe: %s", __func__, strerror(errno)); if ((key_fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL) {
error("%s: sshkey_fingerprint failed", __func__);
goto out;
}
if ((r = sshkey_to_base64(key, &keytext)) != 0) {
error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
goto out; goto out;
} }
debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"", /* Turn the command into an argument vector */
options.authorized_keys_command, user_pw->pw_name, pw->pw_name); if (split_argv(options.authorized_keys_command, &ac, &av) != 0) {
error("AuthorizedKeysCommand \"%s\" contains invalid quotes",
command);
goto out;
}
if (ac == 0) {
error("AuthorizedKeysCommand \"%s\" yielded no arguments",
command);
goto out;
}
for (i = 1; i < ac; i++) {
tmp = percent_expand(av[i],
"u", user_pw->pw_name,
"h", user_pw->pw_dir,
"t", sshkey_ssh_name(key),
"f", key_fp,
"k", keytext,
(char *)NULL);
if (tmp == NULL)
fatal("%s: percent_expand failed", __func__);
free(av[i]);
av[i] = tmp;
}
/* Prepare a printable command for logs, etc. */
command = assemble_argv(ac, av);
/* /*
* Don't want to call this in the child, where it can fatal() and * If AuthorizedKeysCommand was run without arguments
* run cleanup_exit() code. * then fall back to the old behaviour of passing the
* target username as a single argument.
*/ */
restore_uid(); if (ac == 1) {
av = xreallocarray(av, ac + 2, sizeof(*av));
switch ((pid = fork())) { av[1] = xstrdup(user_pw->pw_name);
case -1: /* error */ av[2] = NULL;
error("%s: fork: %s", __func__, strerror(errno)); /* Fix up command too, since it is used in log messages */
close(p[0]); free(command);
close(p[1]); xasprintf(&command, "%s %s", av[0], av[1]);
return 0;
case 0: /* child */
for (i = 0; i < NSIG; i++)
signal(i, SIG_DFL);
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
error("%s: open %s: %s", __func__, _PATH_DEVNULL,
strerror(errno));
_exit(1);
}
/* Keep stderr around a while longer to catch errors */
if (dup2(devnull, STDIN_FILENO) == -1 ||
dup2(p[1], STDOUT_FILENO) == -1) {
error("%s: dup2: %s", __func__, strerror(errno));
_exit(1);
}
closefrom(STDERR_FILENO + 1);
/* Don't use permanently_set_uid() here to avoid fatal() */
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
error("setresgid %u: %s", (u_int)pw->pw_gid,
strerror(errno));
_exit(1);
}
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
error("setresuid %u: %s", (u_int)pw->pw_uid,
strerror(errno));
_exit(1);
}
/* stdin is pointed to /dev/null at this point */
if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
error("%s: dup2: %s", __func__, strerror(errno));
_exit(1);
}
execl(options.authorized_keys_command,
options.authorized_keys_command, user_pw->pw_name, NULL);
error("AuthorizedKeysCommand %s exec failed: %s",
options.authorized_keys_command, strerror(errno));
_exit(127);
default: /* parent */
break;
} }
if ((pid = subprocess("AuthorizedKeysCommand", pw, command,
ac, av, &f)) == 0)
goto out;
uid_swapped = 1;
temporarily_use_uid(pw); temporarily_use_uid(pw);
close(p[1]);
if ((f = fdopen(p[0], "r")) == NULL) {
error("%s: fdopen: %s", __func__, strerror(errno));
close(p[0]);
/* Don't leave zombie child */
kill(pid, SIGTERM);
while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
;
goto out;
}
ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
fclose(f);
while (waitpid(pid, &status, 0) == -1) { if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0)
if (errno != EINTR) {
error("%s: waitpid: %s", __func__, strerror(errno));
goto out;
}
}
if (WIFSIGNALED(status)) {
error("AuthorizedKeysCommand %s exited on signal %d",
options.authorized_keys_command, WTERMSIG(status));
goto out; goto out;
} else if (WEXITSTATUS(status) != 0) {
error("AuthorizedKeysCommand %s returned status %d", /* Read completed successfully */
options.authorized_keys_command, WEXITSTATUS(status));
goto out;
}
found_key = ok; found_key = ok;
out: out:
restore_uid(); if (f != NULL)
fclose(f);
signal(SIGCHLD, osigchld);
for (i = 0; i < ac; i++)
free(av[i]);
free(av);
if (uid_swapped)
restore_uid();
free(command);
free(username);
free(key_fp);
free(keytext);
return found_key; return found_key;
} }
@ -671,7 +1034,7 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
* Check whether key authenticates and authorises the user. * Check whether key authenticates and authorises the user.
*/ */
int int
user_key_allowed(struct passwd *pw, Key *key) user_key_allowed(struct passwd *pw, Key *key, int auth_attempt)
{ {
u_int success, i; u_int success, i;
char *file; char *file;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: authfd.c,v 1.94 2015/01/14 20:05:27 djm Exp $ */ /* $OpenBSD: authfd.c,v 1.97 2015/03/26 19:32:19 markus Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -438,10 +438,8 @@ ssh_agent_sign(int sock, struct sshkey *key,
u_int flags = 0; u_int flags = 0;
int r = SSH_ERR_INTERNAL_ERROR; int r = SSH_ERR_INTERNAL_ERROR;
if (sigp != NULL) *sigp = NULL;
*sigp = NULL; *lenp = 0;
if (lenp != NULL)
*lenp = 0;
if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: authfile.c,v 1.111 2015/02/23 16:55:51 djm Exp $ */ /* $OpenBSD: authfile.c,v 1.114 2015/04/17 13:32:09 djm Exp $ */
/* /*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
* *
@ -186,7 +186,7 @@ sshkey_perm_ok(int fd, const char *filename)
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("Permissions 0%3.3o for '%s' are too open.", error("Permissions 0%3.3o for '%s' are too open.",
(u_int)st.st_mode & 0777, filename); (u_int)st.st_mode & 0777, filename);
error("It is recommended that your private key files are NOT accessible by others."); error("It is required that your private key files are NOT accessible by others.");
error("This private key will be ignored."); error("This private key will be ignored.");
return SSH_ERR_KEY_BAD_PERMISSIONS; return SSH_ERR_KEY_BAD_PERMISSIONS;
} }
@ -359,6 +359,8 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
case 0: case 0:
return r; return r;
} }
#else /* WITH_SSH1 */
close(fd);
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */
/* try ssh2 public key */ /* try ssh2 public key */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: channels.c,v 1.341 2015/02/06 23:21:59 millert Exp $ */ /* $OpenBSD: channels.c,v 1.347 2015/07/01 02:26:31 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -162,6 +162,9 @@ static char *x11_saved_proto = NULL;
static char *x11_saved_data = NULL; static char *x11_saved_data = NULL;
static u_int x11_saved_data_len = 0; static u_int x11_saved_data_len = 0;
/* Deadline after which all X11 connections are refused */
static u_int x11_refuse_time;
/* /*
* Fake X11 authentication data. This is what the server will be sending us; * Fake X11 authentication data. This is what the server will be sending us;
* we should replace any occurrences of this by the real data. * we should replace any occurrences of this by the real data.
@ -307,7 +310,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
if (channels_alloc > 10000) if (channels_alloc > 10000)
fatal("channel_new: internal error: channels_alloc %d " fatal("channel_new: internal error: channels_alloc %d "
"too big.", channels_alloc); "too big.", channels_alloc);
channels = xrealloc(channels, channels_alloc + 10, channels = xreallocarray(channels, channels_alloc + 10,
sizeof(Channel *)); sizeof(Channel *));
channels_alloc += 10; channels_alloc += 10;
debug2("channel: expanding %d", channels_alloc); debug2("channel: expanding %d", channels_alloc);
@ -913,6 +916,13 @@ x11_open_helper(Buffer *b)
u_char *ucp; u_char *ucp;
u_int proto_len, data_len; u_int proto_len, data_len;
/* Is this being called after the refusal deadline? */
if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) {
verbose("Rejected X11 connection after ForwardX11Timeout "
"expired");
return -1;
}
/* Check if the fixed size part of the packet is in buffer. */ /* Check if the fixed size part of the packet is in buffer. */
if (buffer_len(b) < 12) if (buffer_len(b) < 12)
return 0; return 0;
@ -1484,6 +1494,12 @@ channel_set_reuseaddr(int fd)
error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
} }
void
channel_set_x11_refuse_time(u_int refuse_time)
{
x11_refuse_time = refuse_time;
}
/* /*
* This socket is listening for connections to a forwarded TCP/IP port. * This socket is listening for connections to a forwarded TCP/IP port.
*/ */
@ -2193,8 +2209,8 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
/* perhaps check sz < nalloc/2 and shrink? */ /* perhaps check sz < nalloc/2 and shrink? */
if (*readsetp == NULL || sz > *nallocp) { if (*readsetp == NULL || sz > *nallocp) {
*readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask)); *readsetp = xreallocarray(*readsetp, nfdset, sizeof(fd_mask));
*writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask)); *writesetp = xreallocarray(*writesetp, nfdset, sizeof(fd_mask));
*nallocp = sz; *nallocp = sz;
} }
*maxfdp = n; *maxfdp = n;
@ -2271,7 +2287,7 @@ channel_output_poll(void)
packet_put_int(c->remote_id); packet_put_int(c->remote_id);
packet_put_string(data, dlen); packet_put_string(data, dlen);
packet_send(); packet_send();
c->remote_window -= dlen + 4; c->remote_window -= dlen;
free(data); free(data);
} }
continue; continue;
@ -2642,7 +2658,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
{ {
Channel *c; Channel *c;
int id; int id;
u_int adjust; u_int adjust, tmp;
if (!compat20) if (!compat20)
return 0; return 0;
@ -2658,7 +2674,10 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
adjust = packet_get_int(); adjust = packet_get_int();
packet_check_eom(); packet_check_eom();
debug2("channel %d: rcvd adjust %u", id, adjust); debug2("channel %d: rcvd adjust %u", id, adjust);
c->remote_window += adjust; if ((tmp = c->remote_window + adjust) < c->remote_window)
fatal("channel %d: adjust %u overflows remote window %u",
id, adjust, c->remote_window);
c->remote_window = tmp;
return 0; return 0;
} }
@ -2806,17 +2825,21 @@ channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd,
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; char ntop[NI_MAXHOST], strport[NI_MAXSERV];
in_port_t *lport_p; in_port_t *lport_p;
host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
fwd->listen_host : fwd->connect_host;
is_client = (type == SSH_CHANNEL_PORT_LISTENER); is_client = (type == SSH_CHANNEL_PORT_LISTENER);
if (host == NULL) { if (is_client && fwd->connect_path != NULL) {
error("No forward host name."); host = fwd->connect_path;
return 0; } else {
} host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
if (strlen(host) >= NI_MAXHOST) { fwd->listen_host : fwd->connect_host;
error("Forward host name too long."); if (host == NULL) {
return 0; error("No forward host name.");
return 0;
}
if (strlen(host) >= NI_MAXHOST) {
error("Forward host name too long.");
return 0;
}
} }
/* Determine the bind address, cf. channel_fwd_bind_addr() comment */ /* Determine the bind address, cf. channel_fwd_bind_addr() comment */
@ -3238,7 +3261,7 @@ channel_request_remote_forwarding(struct Forward *fwd)
} }
if (success) { if (success) {
/* Record that connection to this host/port is permitted. */ /* Record that connection to this host/port is permitted. */
permitted_opens = xrealloc(permitted_opens, permitted_opens = xreallocarray(permitted_opens,
num_permitted_opens + 1, sizeof(*permitted_opens)); num_permitted_opens + 1, sizeof(*permitted_opens));
idx = num_permitted_opens++; idx = num_permitted_opens++;
if (fwd->connect_path != NULL) { if (fwd->connect_path != NULL) {
@ -3469,7 +3492,7 @@ channel_add_permitted_opens(char *host, int port)
{ {
debug("allow port forwarding to host %s port %d", host, port); debug("allow port forwarding to host %s port %d", host, port);
permitted_opens = xrealloc(permitted_opens, permitted_opens = xreallocarray(permitted_opens,
num_permitted_opens + 1, sizeof(*permitted_opens)); num_permitted_opens + 1, sizeof(*permitted_opens));
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
permitted_opens[num_permitted_opens].port_to_connect = port; permitted_opens[num_permitted_opens].port_to_connect = port;
@ -3519,7 +3542,7 @@ channel_add_adm_permitted_opens(char *host, int port)
{ {
debug("config allows port forwarding to host %s port %d", host, port); debug("config allows port forwarding to host %s port %d", host, port);
permitted_adm_opens = xrealloc(permitted_adm_opens, permitted_adm_opens = xreallocarray(permitted_adm_opens,
num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens)); num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens));
permitted_adm_opens[num_adm_permitted_opens].host_to_connect permitted_adm_opens[num_adm_permitted_opens].host_to_connect
= xstrdup(host); = xstrdup(host);
@ -3534,7 +3557,7 @@ void
channel_disable_adm_local_opens(void) channel_disable_adm_local_opens(void)
{ {
channel_clear_adm_permitted_opens(); channel_clear_adm_permitted_opens();
permitted_adm_opens = xmalloc(sizeof(*permitted_adm_opens)); permitted_adm_opens = xcalloc(sizeof(*permitted_adm_opens), 1);
permitted_adm_opens[num_adm_permitted_opens].host_to_connect = NULL; permitted_adm_opens[num_adm_permitted_opens].host_to_connect = NULL;
num_adm_permitted_opens = 1; num_adm_permitted_opens = 1;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.116 2015/01/19 20:07:45 markus Exp $ */ /* $OpenBSD: channels.h,v 1.118 2015/07/01 02:26:31 djm Exp $ */
/* $FreeBSD$ */ /* $FreeBSD$ */
/* /*
@ -114,7 +114,7 @@ struct Channel {
time_t notbefore; /* Pause IO until deadline (time_t) */ time_t notbefore; /* Pause IO until deadline (time_t) */
int delayed; /* post-select handlers for newly created int delayed; /* post-select handlers for newly created
* channels are delayed until the first call * channels are delayed until the first call
* to a matching pre-select handler. * to a matching pre-select handler.
* this way post-select handlers are not * this way post-select handlers are not
* accidentally called if a FD gets reused */ * accidentally called if a FD gets reused */
Buffer input; /* data read from socket, to be sent over Buffer input; /* data read from socket, to be sent over
@ -285,6 +285,7 @@ int permitopen_port(const char *);
/* x11 forwarding */ /* x11 forwarding */
void channel_set_x11_refuse_time(u_int);
int x11_connect_display(void); int x11_connect_display(void);
int x11_create_display_inet(int, int, int, u_int *, int **); int x11_create_display_inet(int, int, int, u_int *, int **);
int x11_input_open(int, u_int32_t, void *); int x11_input_open(int, u_int32_t, void *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.272 2015/02/25 19:54:02 djm Exp $ */ /* $OpenBSD: clientloop.c,v 1.274 2015/07/01 02:26:31 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -164,7 +164,7 @@ static int connection_in; /* Connection to server (input). */
static int connection_out; /* Connection to server (output). */ static int connection_out; /* Connection to server (output). */
static int need_rekeying; /* Set to non-zero if rekeying is requested. */ static int need_rekeying; /* Set to non-zero if rekeying is requested. */
static int session_closed; /* In SSH2: login session closed. */ static int session_closed; /* In SSH2: login session closed. */
static int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
static void client_init_dispatch(void); static void client_init_dispatch(void);
int session_ident = -1; int session_ident = -1;
@ -299,7 +299,8 @@ client_x11_display_valid(const char *display)
return 1; return 1;
} }
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
#define X11_TIMEOUT_SLACK 60
void void
client_x11_get_proto(const char *display, const char *xauth_path, client_x11_get_proto(const char *display, const char *xauth_path,
u_int trusted, u_int timeout, char **_proto, char **_data) u_int trusted, u_int timeout, char **_proto, char **_data)
@ -312,7 +313,7 @@ client_x11_get_proto(const char *display, const char *xauth_path,
int got_data = 0, generated = 0, do_unlink = 0, i; int got_data = 0, generated = 0, do_unlink = 0, i;
char *xauthdir, *xauthfile; char *xauthdir, *xauthfile;
struct stat st; struct stat st;
u_int now; u_int now, x11_timeout_real;
xauthdir = xauthfile = NULL; xauthdir = xauthfile = NULL;
*_proto = proto; *_proto = proto;
@ -345,6 +346,15 @@ client_x11_get_proto(const char *display, const char *xauth_path,
xauthdir = xmalloc(PATH_MAX); xauthdir = xmalloc(PATH_MAX);
xauthfile = xmalloc(PATH_MAX); xauthfile = xmalloc(PATH_MAX);
mktemp_proto(xauthdir, PATH_MAX); mktemp_proto(xauthdir, PATH_MAX);
/*
* The authentication cookie should briefly outlive
* ssh's willingness to forward X11 connections to
* avoid nasty fail-open behaviour in the X server.
*/
if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK)
x11_timeout_real = UINT_MAX;
else
x11_timeout_real = timeout + X11_TIMEOUT_SLACK;
if (mkdtemp(xauthdir) != NULL) { if (mkdtemp(xauthdir) != NULL) {
do_unlink = 1; do_unlink = 1;
snprintf(xauthfile, PATH_MAX, "%s/xauthfile", snprintf(xauthfile, PATH_MAX, "%s/xauthfile",
@ -352,17 +362,20 @@ client_x11_get_proto(const char *display, const char *xauth_path,
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
"%s -f %s generate %s " SSH_X11_PROTO "%s -f %s generate %s " SSH_X11_PROTO
" untrusted timeout %u 2>" _PATH_DEVNULL, " untrusted timeout %u 2>" _PATH_DEVNULL,
xauth_path, xauthfile, display, timeout); xauth_path, xauthfile, display,
x11_timeout_real);
debug2("x11_get_proto: %s", cmd); debug2("x11_get_proto: %s", cmd);
if (system(cmd) == 0)
generated = 1;
if (x11_refuse_time == 0) { if (x11_refuse_time == 0) {
now = monotime() + 1; now = monotime() + 1;
if (UINT_MAX - timeout < now) if (UINT_MAX - timeout < now)
x11_refuse_time = UINT_MAX; x11_refuse_time = UINT_MAX;
else else
x11_refuse_time = now + timeout; x11_refuse_time = now + timeout;
channel_set_x11_refuse_time(
x11_refuse_time);
} }
if (system(cmd) == 0)
generated = 1;
} }
} }
@ -1890,7 +1903,7 @@ client_request_x11(const char *request_type, int rchan)
"malicious server."); "malicious server.");
return NULL; return NULL;
} }
if (x11_refuse_time != 0 && monotime() >= x11_refuse_time) { if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) {
verbose("Rejected X11 connection after ForwardX11Timeout " verbose("Rejected X11 connection after ForwardX11Timeout "
"expired"); "expired");
return NULL; return NULL;
@ -2353,8 +2366,7 @@ client_input_hostkeys(void)
/* Check that the key is accepted in HostkeyAlgorithms */ /* Check that the key is accepted in HostkeyAlgorithms */
if (options.hostkeyalgorithms != NULL && if (options.hostkeyalgorithms != NULL &&
match_pattern_list(sshkey_ssh_name(key), match_pattern_list(sshkey_ssh_name(key),
options.hostkeyalgorithms, options.hostkeyalgorithms, 0) != 1) {
strlen(options.hostkeyalgorithms), 0) != 1) {
debug3("%s: %s key not permitted by HostkeyAlgorithms", debug3("%s: %s key not permitted by HostkeyAlgorithms",
__func__, sshkey_ssh_name(key)); __func__, sshkey_ssh_name(key));
continue; continue;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: compat.c,v 1.87 2015/01/19 20:20:20 markus Exp $ */ /* $OpenBSD: compat.c,v 1.94 2015/05/26 23:23:40 dtucker Exp $ */
/* /*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
* *
@ -153,6 +153,7 @@ compat_datafellows(const char *version)
"1.2.22*", SSH_BUG_IGNOREMSG }, "1.2.22*", SSH_BUG_IGNOREMSG },
{ "1.3.2*", /* F-Secure */ { "1.3.2*", /* F-Secure */
SSH_BUG_IGNOREMSG }, SSH_BUG_IGNOREMSG },
{ "Cisco-1.*", SSH_BUG_DHGEX_LARGE },
{ "*SSH Compatible Server*", /* Netscreen */ { "*SSH Compatible Server*", /* Netscreen */
SSH_BUG_PASSWORDPAD }, SSH_BUG_PASSWORDPAD },
{ "*OSU_0*," { "*OSU_0*,"
@ -166,15 +167,34 @@ compat_datafellows(const char *version)
"OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, "OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD },
{ "*SSH_Version_Mapper*", { "*SSH_Version_Mapper*",
SSH_BUG_SCANNER }, SSH_BUG_SCANNER },
{ "PuTTY-Release-0.5*," /* 0.50-0.57, DH-GEX in >=0.52 */
"PuTTY_Release_0.5*," /* 0.58-0.59 */
"PuTTY_Release_0.60*,"
"PuTTY_Release_0.61*,"
"PuTTY_Release_0.62*,"
"PuTTY_Release_0.63*,"
"PuTTY_Release_0.64*",
SSH_OLD_DHGEX },
{ "Probe-*", { "Probe-*",
SSH_BUG_PROBE }, SSH_BUG_PROBE },
{ "TeraTerm SSH*,"
"TTSSH/1.5.*,"
"TTSSH/2.1*,"
"TTSSH/2.2*,"
"TTSSH/2.3*,"
"TTSSH/2.4*,"
"TTSSH/2.5*,"
"TTSSH/2.6*,"
"TTSSH/2.70*,"
"TTSSH/2.71*,"
"TTSSH/2.72*", SSH_BUG_HOSTKEYS },
{ "WinSCP*", SSH_OLD_DHGEX },
{ NULL, 0 } { NULL, 0 }
}; };
/* process table, return first match */ /* process table, return first match */
for (i = 0; check[i].pat; i++) { for (i = 0; check[i].pat; i++) {
if (match_pattern_list(version, check[i].pat, if (match_pattern_list(version, check[i].pat, 0) == 1) {
strlen(check[i].pat), 0) == 1) {
debug("match: %s pat %s compat 0x%08x", debug("match: %s pat %s compat 0x%08x",
version, check[i].pat, check[i].bugs); version, check[i].pat, check[i].bugs);
datafellows = check[i].bugs; /* XXX for now */ datafellows = check[i].bugs; /* XXX for now */
@ -200,9 +220,11 @@ proto_spec(const char *spec)
for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) {
switch (atoi(p)) { switch (atoi(p)) {
case 1: case 1:
#ifdef WITH_SSH1
if (ret == SSH_PROTO_UNKNOWN) if (ret == SSH_PROTO_UNKNOWN)
ret |= SSH_PROTO_1_PREFERRED; ret |= SSH_PROTO_1_PREFERRED;
ret |= SSH_PROTO_1; ret |= SSH_PROTO_1;
#endif
break; break;
case 2: case 2:
ret |= SSH_PROTO_2; ret |= SSH_PROTO_2;
@ -230,7 +252,7 @@ filter_proposal(char *proposal, const char *filter)
buffer_init(&b); buffer_init(&b);
tmp = orig_prop = xstrdup(proposal); tmp = orig_prop = xstrdup(proposal);
while ((cp = strsep(&tmp, ",")) != NULL) { while ((cp = strsep(&tmp, ",")) != NULL) {
if (match_pattern_list(cp, filter, strlen(cp), 0) != 1) { if (match_pattern_list(cp, filter, 0) != 1) {
if (buffer_len(&b) > 0) if (buffer_len(&b) > 0)
buffer_append(&b, ",", 1); buffer_append(&b, ",", 1);
buffer_append(&b, cp, strlen(cp)); buffer_append(&b, cp, strlen(cp));
@ -272,15 +294,20 @@ compat_pkalg_proposal(char *pkalg_prop)
} }
char * char *
compat_kex_proposal(char *kex_prop) compat_kex_proposal(char *p)
{ {
if (!(datafellows & SSH_BUG_CURVE25519PAD)) if ((datafellows & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
return kex_prop; return p;
debug2("%s: original KEX proposal: %s", __func__, kex_prop); debug2("%s: original KEX proposal: %s", __func__, p);
kex_prop = filter_proposal(kex_prop, "curve25519-sha256@libssh.org"); if ((datafellows & SSH_BUG_CURVE25519PAD) != 0)
debug2("%s: compat KEX proposal: %s", __func__, kex_prop); p = filter_proposal(p, "curve25519-sha256@libssh.org");
if (*kex_prop == '\0') if ((datafellows & SSH_OLD_DHGEX) != 0) {
p = filter_proposal(p, "diffie-hellman-group-exchange-sha256");
p = filter_proposal(p, "diffie-hellman-group-exchange-sha1");
}
debug2("%s: compat KEX proposal: %s", __func__, p);
if (*p == '\0')
fatal("No supported key exchange algorithms found"); fatal("No supported key exchange algorithms found");
return kex_prop; return p;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: compat.h,v 1.46 2015/01/19 20:20:20 markus Exp $ */ /* $OpenBSD: compat.h,v 1.48 2015/05/26 23:23:40 dtucker Exp $ */
/* $FreeBSD$ */ /* $FreeBSD$ */
/* /*
@ -61,6 +61,8 @@
#define SSH_NEW_OPENSSH 0x04000000 #define SSH_NEW_OPENSSH 0x04000000
#define SSH_BUG_DYNAMIC_RPORT 0x08000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000
#define SSH_BUG_CURVE25519PAD 0x10000000 #define SSH_BUG_CURVE25519PAD 0x10000000
#define SSH_BUG_HOSTKEYS 0x20000000
#define SSH_BUG_DHGEX_LARGE 0x40000000
void enable_compat13(void); void enable_compat13(void);
void enable_compat20(void); void enable_compat20(void);

View file

@ -982,6 +982,12 @@ EOF
ppc:Linux:*:*) ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu echo powerpc-unknown-linux-gnu
exit ;; exit ;;
ppc64le:Linux:*:*)
echo powerpc64le-unknown-linux-gnu
exit ;;
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-gnu
exit ;;
s390:Linux:*:* | s390x:Linux:*:*) s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux echo ${UNAME_MACHINE}-ibm-linux
exit ;; exit ;;

View file

@ -665,6 +665,7 @@ SED
PERL PERL
KILL KILL
CAT CAT
ac_ct_AR
AR AR
INSTALL_DATA INSTALL_DATA
INSTALL_SCRIPT INSTALL_SCRIPT
@ -1424,7 +1425,7 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL**
--without-ssh1 Disable support for SSH protocol 1 --without-ssh1 Enable support for SSH protocol 1
--without-stackprotect Don't use compiler's stack protection --without-stackprotect Don't use compiler's stack protection
--without-hardening Don't use toolchain hardening flags --without-hardening Don't use toolchain hardening flags
--without-rpath Disable auto-added -R linker paths --without-rpath Disable auto-added -R linker paths
@ -1460,8 +1461,8 @@ Optional Packages:
--with-mantype=man|cat|doc Set man page type --with-mantype=man|cat|doc Set man page type
--with-md5-passwords Enable use of MD5 passwords --with-md5-passwords Enable use of MD5 passwords
--without-shadow Disable shadow password support --without-shadow Disable shadow password support
--with-ipaddr-display Use ip address instead of hostname in \$DISPLAY --with-ipaddr-display Use ip address instead of hostname in $DISPLAY
--with-default-path= Specify default \$PATH environment for server --with-default-path= Specify default $PATH environment for server
--with-superuser-path= Specify different path for super-user --with-superuser-path= Specify different path for super-user
--with-4in6 Check for and convert IPv4 in IPv6 mapped addresses --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses
--with-bsd-auth Enable BSD auth support --with-bsd-auth Enable BSD auth support
@ -4556,26 +4557,27 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
EGREP="$ac_cv_path_EGREP" EGREP="$ac_cv_path_EGREP"
# Extract the first word of "ar", so it can be a program name with args. if test -n "$ac_tool_prefix"; then
set dummy ar; ac_word=$2 for ac_prog in ar
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; } $as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_AR+:} false; then : if ${ac_cv_prog_AR+:} false; then :
$as_echo_n "(cached) " >&6 $as_echo_n "(cached) " >&6
else else
case $AR in if test -n "$AR"; then
[\\/]* | ?:[\\/]*) ac_cv_prog_AR="$AR" # Let the user override the test.
ac_cv_path_AR="$AR" # Let the user override the test with a path. else
;; as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH for as_dir in $PATH
do do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
fi fi
@ -4583,10 +4585,9 @@ done
done done
IFS=$as_save_IFS IFS=$as_save_IFS
;;
esac
fi fi
AR=$ac_cv_path_AR fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then if test -n "$AR"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
$as_echo "$AR" >&6; } $as_echo "$AR" >&6; }
@ -4596,6 +4597,66 @@ $as_echo "no" >&6; }
fi fi
test -n "$AR" && break
done
fi
if test -z "$AR"; then
ac_ct_AR=$AR
for ac_prog in ar
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_AR"; then
ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
$as_echo "$ac_ct_AR" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$ac_ct_AR" && break
done
if test "x$ac_ct_AR" = x; then
AR=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
AR=$ac_ct_AR
fi
fi
# Extract the first word of "cat", so it can be a program name with args. # Extract the first word of "cat", so it can be a program name with args.
set dummy cat; ac_word=$2 set dummy cat; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@ -5655,10 +5716,15 @@ fi
# Check whether --with-ssh1 was given. # Check whether --with-ssh1 was given.
if test "${with_ssh1+set}" = set; then : if test "${with_ssh1+set}" = set; then :
withval=$with_ssh1; withval=$with_ssh1;
if test "x$withval" = "xno" ; then if test "x$withval" = "xyes" ; then
if test "x$openssl" = "xno" ; then
as_fn_error $? "Cannot enable SSH protocol 1 with OpenSSL disabled" "$LINENO" 5
fi
ssh1=yes
elif test "x$withval" = "xno" ; then
ssh1=no ssh1=no
elif test "x$openssl" = "xno" ; then else
as_fn_error $? "Cannot enable SSH protocol 1 with OpenSSL disabled" "$LINENO" 5 as_fn_error $? "unknown --with-ssh1 argument" "$LINENO" 5
fi fi
@ -7628,9 +7694,12 @@ $as_echo_n "checking for seccomp architecture... " >&6; }
i*86-*) i*86-*)
seccomp_audit_arch=AUDIT_ARCH_I386 seccomp_audit_arch=AUDIT_ARCH_I386
;; ;;
arm*-*) arm*-*)
seccomp_audit_arch=AUDIT_ARCH_ARM seccomp_audit_arch=AUDIT_ARCH_ARM
;; ;;
aarch64*-*)
seccomp_audit_arch=AUDIT_ARCH_AARCH64
;;
esac esac
if test "x$seccomp_audit_arch" != "x" ; then if test "x$seccomp_audit_arch" != "x" ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$seccomp_audit_arch\"" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$seccomp_audit_arch\"" >&5

View file

@ -30,7 +30,7 @@ AC_PROG_CPP
AC_PROG_RANLIB AC_PROG_RANLIB
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_EGREP AC_PROG_EGREP
AC_PATH_PROG([AR], [ar]) AC_CHECK_TOOLS([AR], [ar])
AC_PATH_PROG([CAT], [cat]) AC_PATH_PROG([CAT], [cat])
AC_PATH_PROG([KILL], [kill]) AC_PATH_PROG([KILL], [kill])
AC_PATH_PROGS([PERL], [perl5 perl]) AC_PATH_PROGS([PERL], [perl5 perl])
@ -140,12 +140,17 @@ else
fi fi
AC_ARG_WITH([ssh1], AC_ARG_WITH([ssh1],
[ --without-ssh1 Disable support for SSH protocol 1], [ --without-ssh1 Enable support for SSH protocol 1],
[ [
if test "x$withval" = "xno" ; then if test "x$withval" = "xyes" ; then
if test "x$openssl" = "xno" ; then
AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled])
fi
ssh1=yes
elif test "x$withval" = "xno" ; then
ssh1=no ssh1=no
elif test "x$openssl" = "xno" ; then else
AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled]) AC_MSG_ERROR([unknown --with-ssh1 argument])
fi fi
] ]
) )
@ -782,14 +787,17 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
i*86-*) i*86-*)
seccomp_audit_arch=AUDIT_ARCH_I386 seccomp_audit_arch=AUDIT_ARCH_I386
;; ;;
arm*-*) arm*-*)
seccomp_audit_arch=AUDIT_ARCH_ARM seccomp_audit_arch=AUDIT_ARCH_ARM
;; ;;
aarch64*-*)
seccomp_audit_arch=AUDIT_ARCH_AARCH64
;;
esac esac
if test "x$seccomp_audit_arch" != "x" ; then if test "x$seccomp_audit_arch" != "x" ; then
AC_MSG_RESULT(["$seccomp_audit_arch"]) AC_MSG_RESULT(["$seccomp_audit_arch"])
AC_DEFINE_UNQUOTED([SECCOMP_AUDIT_ARCH], [$seccomp_audit_arch], AC_DEFINE_UNQUOTED([SECCOMP_AUDIT_ARCH], [$seccomp_audit_arch],
[Specify the system call convention in use]) [Specify the system call convention in use])
else else
AC_MSG_RESULT([architecture not supported]) AC_MSG_RESULT([architecture not supported])
fi fi
@ -4413,7 +4421,7 @@ if test ! -z "$IPADDR_IN_DISPLAY" ; then
else else
DISPLAY_HACK_MSG="no" DISPLAY_HACK_MSG="no"
AC_ARG_WITH([ipaddr-display], AC_ARG_WITH([ipaddr-display],
[ --with-ipaddr-display Use ip address instead of hostname in \$DISPLAY], [ --with-ipaddr-display Use ip address instead of hostname in $DISPLAY],
[ [
if test "x$withval" != "xno" ; then if test "x$withval" != "xno" ; then
AC_DEFINE([IPADDR_IN_DISPLAY]) AC_DEFINE([IPADDR_IN_DISPLAY])
@ -4459,7 +4467,7 @@ fi
# Whether to mess with the default path # Whether to mess with the default path
SERVER_PATH_MSG="(default)" SERVER_PATH_MSG="(default)"
AC_ARG_WITH([default-path], AC_ARG_WITH([default-path],
[ --with-default-path= Specify default \$PATH environment for server], [ --with-default-path= Specify default $PATH environment for server],
[ [
if test "x$external_path_file" = "x/etc/login.conf" ; then if test "x$external_path_file" = "x/etc/login.conf" ; then
AC_MSG_WARN([ AC_MSG_WARN([

View file

@ -1,4 +1,4 @@
%define ver 6.8p1 %define ver 6.9p1
%define rel 1 %define rel 1
# OpenSSH privilege separation requires a user & group ID # OpenSSH privilege separation requires a user & group ID

View file

@ -13,7 +13,7 @@
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh Name: openssh
Version: 6.8p1 Version: 6.9p1
URL: http://www.openssh.com/ URL: http://www.openssh.com/
Release: 1 Release: 1
Source0: openssh-%{version}.tar.gz Source0: openssh-%{version}.tar.gz

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dh.c,v 1.55 2015/01/20 23:14:00 deraadt Exp $ */ /* $OpenBSD: dh.c,v 1.57 2015/05/27 23:39:18 dtucker Exp $ */
/* /*
* Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2000 Niels Provos. All rights reserved.
* *
@ -155,7 +155,7 @@ choose_dh(int min, int wantbits, int max)
(f = fopen(_PATH_DH_PRIMES, "r")) == NULL) { (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) {
logit("WARNING: %s does not exist, using fixed modulus", logit("WARNING: %s does not exist, using fixed modulus",
_PATH_DH_MODULI); _PATH_DH_MODULI);
return (dh_new_group14()); return (dh_new_group_fallback(max));
} }
linenum = 0; linenum = 0;
@ -183,7 +183,7 @@ choose_dh(int min, int wantbits, int max)
if (bestcount == 0) { if (bestcount == 0) {
fclose(f); fclose(f);
logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES);
return (dh_new_group14()); return (dh_new_group_fallback(max));
} }
linenum = 0; linenum = 0;
@ -204,7 +204,7 @@ choose_dh(int min, int wantbits, int max)
if (linenum != which+1) { if (linenum != which+1) {
logit("WARNING: line %d disappeared in %s, giving up", logit("WARNING: line %d disappeared in %s, giving up",
which, _PATH_DH_PRIMES); which, _PATH_DH_PRIMES);
return (dh_new_group14()); return (dh_new_group_fallback(max));
} }
return (dh_new_group(dhg.g, dhg.p)); return (dh_new_group(dhg.g, dhg.p));
@ -261,7 +261,7 @@ dh_gen_key(DH *dh, int need)
if (need < 0 || dh->p == NULL || if (need < 0 || dh->p == NULL ||
(pbits = BN_num_bits(dh->p)) <= 0 || (pbits = BN_num_bits(dh->p)) <= 0 ||
need > INT_MAX / 2 || 2 * need >= pbits) need > INT_MAX / 2 || 2 * need > pbits)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
dh->length = MIN(need * 2, pbits - 1); dh->length = MIN(need * 2, pbits - 1);
if (DH_generate_key(dh) == 0 || if (DH_generate_key(dh) == 0 ||
@ -338,6 +338,45 @@ dh_new_group14(void)
return (dh_new_group_asc(gen, group14)); return (dh_new_group_asc(gen, group14));
} }
/*
* 4k bit fallback group used by DH-GEX if moduli file cannot be read.
* Source: MODP group 16 from RFC3526.
*/
DH *
dh_new_group_fallback(int max)
{
static char *gen = "2", *group16 =
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
"C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
"83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
"670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
"E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
"DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
"15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
"ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
"ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
"F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
"BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
"43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
"88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
"2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
"287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
"1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
"93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
"FFFFFFFF" "FFFFFFFF";
if (max < 4096) {
debug3("requested max size %d, using 2k bit group 14", max);
return dh_new_group14();
}
debug3("using 4k bit group 16");
return (dh_new_group_asc(gen, group16));
}
/* /*
* Estimates the group order for a Diffie-Hellman group that has an * Estimates the group order for a Diffie-Hellman group that has an
* attack complexity approximately the same as O(2**bits). * attack complexity approximately the same as O(2**bits).

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dh.h,v 1.12 2015/01/19 20:16:15 markus Exp $ */ /* $OpenBSD: dh.h,v 1.13 2015/05/27 23:39:18 dtucker Exp $ */
/* /*
* Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2000 Niels Provos. All rights reserved.
@ -37,6 +37,7 @@ DH *dh_new_group_asc(const char *, const char *);
DH *dh_new_group(BIGNUM *, BIGNUM *); DH *dh_new_group(BIGNUM *, BIGNUM *);
DH *dh_new_group1(void); DH *dh_new_group1(void);
DH *dh_new_group14(void); DH *dh_new_group14(void);
DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int); int dh_gen_key(DH *, int);
int dh_pub_is_valid(DH *, BIGNUM *); int dh_pub_is_valid(DH *, BIGNUM *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: digest-libc.c,v 1.4 2014/12/21 22:27:56 djm Exp $ */ /* $OpenBSD: digest-libc.c,v 1.5 2015/05/05 02:48:17 jsg Exp $ */
/* /*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org> * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
* Copyright (c) 2014 Markus Friedl. All rights reserved. * Copyright (c) 2014 Markus Friedl. All rights reserved.

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dispatch.c,v 1.26 2015/02/12 20:34:19 dtucker Exp $ */ /* $OpenBSD: dispatch.c,v 1.27 2015/05/01 07:10:01 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* *
@ -137,22 +137,6 @@ ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
{ {
int r; int r;
if ((r = ssh_dispatch_run(ssh, mode, done, ctxt)) != 0) { if ((r = ssh_dispatch_run(ssh, mode, done, ctxt)) != 0)
switch (r) { sshpkt_fatal(ssh, __func__, r);
case SSH_ERR_CONN_CLOSED:
logit("Connection closed by %.200s",
ssh_remote_ipaddr(ssh));
cleanup_exit(255);
case SSH_ERR_CONN_TIMEOUT:
logit("Connection to %.200s timed out while "
"waiting to read", ssh_remote_ipaddr(ssh));
cleanup_exit(255);
case SSH_ERR_DISCONNECTED:
logit("Disconnected from %.200s",
ssh_remote_ipaddr(ssh));
cleanup_exit(255);
default:
fatal("%s: %s", __func__, ssh_err(r));
}
}
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dns.h,v 1.14 2015/01/15 09:40:00 djm Exp $ */ /* $OpenBSD: dns.h,v 1.15 2015/05/08 06:45:13 djm Exp $ */
/* /*
* Copyright (c) 2003 Wesley Griffin. All rights reserved. * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@ -33,7 +33,7 @@ enum sshfp_types {
SSHFP_KEY_RSA = 1, SSHFP_KEY_RSA = 1,
SSHFP_KEY_DSA = 2, SSHFP_KEY_DSA = 2,
SSHFP_KEY_ECDSA = 3, SSHFP_KEY_ECDSA = 3,
SSHFP_KEY_ED25519 = 4 SSHFP_KEY_ED25519 = 4
}; };
enum sshfp_hashes { enum sshfp_hashes {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: groupaccess.c,v 1.15 2015/01/20 23:14:00 deraadt Exp $ */ /* $OpenBSD: groupaccess.c,v 1.16 2015/05/04 06:10:48 djm Exp $ */
/* /*
* Copyright (c) 2001 Kevin Steves. All rights reserved. * Copyright (c) 2001 Kevin Steves. All rights reserved.
* *
@ -97,11 +97,9 @@ int
ga_match_pattern_list(const char *group_pattern) ga_match_pattern_list(const char *group_pattern)
{ {
int i, found = 0; int i, found = 0;
size_t len = strlen(group_pattern);
for (i = 0; i < ngroups; i++) { for (i = 0; i < ngroups; i++) {
switch (match_pattern_list(groups_byname[i], switch (match_pattern_list(groups_byname[i], group_pattern, 0)) {
group_pattern, len, 0)) {
case -1: case -1:
return 0; /* Negated match wins */ return 0; /* Negated match wins */
case 0: case 0:

View file

@ -34,6 +34,7 @@
#include <limits.h> #include <limits.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <signal.h>
#include <unistd.h> #include <unistd.h>
#include "xmalloc.h" #include "xmalloc.h"

View file

@ -1,4 +1,4 @@
/* $OpenBSD: gss-serv.c,v 1.28 2015/01/20 23:14:00 deraadt Exp $ */ /* $OpenBSD: gss-serv.c,v 1.29 2015/05/22 03:50:02 djm Exp $ */
/* /*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -44,9 +44,12 @@
#include "channels.h" #include "channels.h"
#include "session.h" #include "session.h"
#include "misc.h" #include "misc.h"
#include "servconf.h"
#include "ssh-gss.h" #include "ssh-gss.h"
extern ServerOptions options;
static ssh_gssapi_client gssapi_client = static ssh_gssapi_client gssapi_client =
{ GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}};
@ -99,25 +102,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
char lname[NI_MAXHOST]; char lname[NI_MAXHOST];
gss_OID_set oidset; gss_OID_set oidset;
gss_create_empty_oid_set(&status, &oidset); if (options.gss_strict_acceptor) {
gss_add_oid_set_member(&status, ctx->oid, &oidset); gss_create_empty_oid_set(&status, &oidset);
gss_add_oid_set_member(&status, ctx->oid, &oidset);
if (gethostname(lname, sizeof(lname))) { if (gethostname(lname, MAXHOSTNAMELEN)) {
gss_release_oid_set(&status, &oidset); gss_release_oid_set(&status, &oidset);
return (-1); return (-1);
} }
if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
gss_release_oid_set(&status, &oidset);
return (ctx->major);
}
if ((ctx->major = gss_acquire_cred(&ctx->minor,
ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds,
NULL, NULL)))
ssh_gssapi_error(ctx);
if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
gss_release_oid_set(&status, &oidset); gss_release_oid_set(&status, &oidset);
return (ctx->major); return (ctx->major);
} else {
ctx->name = GSS_C_NO_NAME;
ctx->creds = GSS_C_NO_CREDENTIAL;
} }
return GSS_S_COMPLETE;
if ((ctx->major = gss_acquire_cred(&ctx->minor,
ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
ssh_gssapi_error(ctx);
gss_release_oid_set(&status, &oidset);
return (ctx->major);
} }
/* Privileged */ /* Privileged */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: hmac.c,v 1.11 2015/01/15 21:37:14 markus Exp $ */ /* $OpenBSD: hmac.c,v 1.12 2015/03/24 20:03:44 markus Exp $ */
/* /*
* Copyright (c) 2014 Markus Friedl. All rights reserved. * Copyright (c) 2014 Markus Friedl. All rights reserved.
* *
@ -154,7 +154,7 @@ hmac_test(void *key, size_t klen, void *m, size_t mlen, u_char *e, size_t elen)
if (memcmp(e, digest, elen)) { if (memcmp(e, digest, elen)) {
for (i = 0; i < elen; i++) for (i = 0; i < elen; i++)
printf("[%zd] %2.2x %2.2x\n", i, e[i], digest[i]); printf("[%zu] %2.2x %2.2x\n", i, e[i], digest[i]);
printf("mismatch\n"); printf("mismatch\n");
} else } else
printf("ok\n"); printf("ok\n");

View file

@ -1,4 +1,4 @@
/* $OpenBSD: hostfile.c,v 1.64 2015/02/16 22:08:57 djm Exp $ */ /* $OpenBSD: hostfile.c,v 1.66 2015/05/04 06:10:48 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -242,7 +242,8 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
struct hostkey_entry *tmp; struct hostkey_entry *tmp;
if (l->status == HKF_STATUS_INVALID) { if (l->status == HKF_STATUS_INVALID) {
error("%s:%ld: parse error in hostkeys file", /* XXX make this verbose() in the future */
debug("%s:%ld: parse error in hostkeys file",
l->path, l->linenum); l->path, l->linenum);
return 0; return 0;
} }
@ -662,7 +663,7 @@ match_maybe_hashed(const char *host, const char *names, int *was_hashed)
return nlen == strlen(hashed_host) && return nlen == strlen(hashed_host) &&
strncmp(hashed_host, names, nlen) == 0; strncmp(hashed_host, names, nlen) == 0;
} }
return match_hostname(host, names, nlen) == 1; return match_hostname(host, names) == 1;
} }
int int
@ -810,7 +811,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
memcpy(ktype, lineinfo.rawkey, l); memcpy(ktype, lineinfo.rawkey, l);
ktype[l] = '\0'; ktype[l] = '\0';
lineinfo.keytype = sshkey_type_from_name(ktype); lineinfo.keytype = sshkey_type_from_name(ktype);
#ifdef WITH_SSH1
/* /*
* Assume RSA1 if the first component is a short * Assume RSA1 if the first component is a short
* decimal number. * decimal number.
@ -818,7 +819,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
if (lineinfo.keytype == KEY_UNSPEC && l < 8 && if (lineinfo.keytype == KEY_UNSPEC && l < 8 &&
strspn(ktype, "0123456789") == l) strspn(ktype, "0123456789") == l)
lineinfo.keytype = KEY_RSA1; lineinfo.keytype = KEY_RSA1;
#endif
/* /*
* Check that something other than whitespace follows * Check that something other than whitespace follows
* the key type. This won't catch all corruption, but * the key type. This won't catch all corruption, but

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kex.c,v 1.105 2015/01/30 00:22:25 djm Exp $ */ /* $OpenBSD: kex.c,v 1.106 2015/04/17 13:25:52 djm Exp $ */
/* /*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* *
@ -229,6 +229,8 @@ kex_prop_free(char **proposal)
{ {
u_int i; u_int i;
if (proposal == NULL)
return;
for (i = 0; i < PROPOSAL_MAX; i++) for (i = 0; i < PROPOSAL_MAX; i++)
free(proposal[i]); free(proposal[i]);
free(proposal); free(proposal);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kexc25519.c,v 1.8 2015/01/19 20:16:15 markus Exp $ */ /* $OpenBSD: kexc25519.c,v 1.9 2015/03/26 07:00:04 djm Exp $ */
/* /*
* Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved.
@ -66,6 +66,11 @@ kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
u_char shared_key[CURVE25519_SIZE]; u_char shared_key[CURVE25519_SIZE];
int r; int r;
/* Check for all-zero public key */
explicit_bzero(shared_key, CURVE25519_SIZE);
if (timingsafe_bcmp(pub, shared_key, CURVE25519_SIZE) == 0)
return SSH_ERR_KEY_INVALID_EC_VALUE;
crypto_scalarmult_curve25519(shared_key, key, pub); crypto_scalarmult_curve25519(shared_key, key, pub);
#ifdef DEBUG_KEXECDH #ifdef DEBUG_KEXECDH
dump_digest("shared secret", shared_key, CURVE25519_SIZE); dump_digest("shared secret", shared_key, CURVE25519_SIZE);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kexc25519s.c,v 1.8 2015/01/26 06:10:03 djm Exp $ */ /* $OpenBSD: kexc25519s.c,v 1.9 2015/04/27 00:37:53 dtucker Exp $ */
/* /*
* Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved.
@ -27,6 +27,7 @@
#include "includes.h" #include "includes.h"
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kexgexc.c,v 1.20 2015/01/26 06:10:03 djm Exp $ */ /* $OpenBSD: kexgexc.c,v 1.22 2015/05/26 23:23:40 dtucker Exp $ */
/* /*
* Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -28,6 +28,7 @@
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
#include <sys/param.h>
#include <sys/types.h> #include <sys/types.h>
#include <openssl/dh.h> #include <openssl/dh.h>
@ -65,25 +66,17 @@ kexgex_client(struct ssh *ssh)
kex->min = DH_GRP_MIN; kex->min = DH_GRP_MIN;
kex->max = DH_GRP_MAX; kex->max = DH_GRP_MAX;
kex->nbits = nbits; kex->nbits = nbits;
if (ssh->compat & SSH_OLD_DHGEX) { if (datafellows & SSH_BUG_DHGEX_LARGE)
/* Old GEX request */ kex->nbits = MIN(kex->nbits, 4096);
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)) /* New GEX request */
!= 0 || if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 ||
(r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || (r = sshpkt_put_u32(ssh, kex->min)) != 0 ||
(r = sshpkt_send(ssh)) != 0) (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 ||
goto out; (r = sshpkt_put_u32(ssh, kex->max)) != 0 ||
debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", kex->nbits); (r = sshpkt_send(ssh)) != 0)
} else { goto out;
/* New GEX request */ debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent",
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 || kex->min, kex->nbits, kex->max);
(r = sshpkt_put_u32(ssh, kex->min)) != 0 ||
(r = sshpkt_put_u32(ssh, kex->nbits)) != 0 ||
(r = sshpkt_put_u32(ssh, kex->max)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent",
kex->min, kex->nbits, kex->max);
}
#ifdef DEBUG_KEXDH #ifdef DEBUG_KEXDH
fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
kex->min, kex->nbits, kex->max); kex->min, kex->nbits, kex->max);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kexgexs.c,v 1.24 2015/01/26 06:10:03 djm Exp $ */ /* $OpenBSD: kexgexs.c,v 1.25 2015/04/13 02:04:08 djm Exp $ */
/* /*
* Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -60,8 +60,6 @@ static int input_kex_dh_gex_init(int, u_int32_t, void *);
int int
kexgex_server(struct ssh *ssh) kexgex_server(struct ssh *ssh)
{ {
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD,
&input_kex_dh_gex_request);
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST, ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST,
&input_kex_dh_gex_request); &input_kex_dh_gex_request);
debug("expecting SSH2_MSG_KEX_DH_GEX_REQUEST"); debug("expecting SSH2_MSG_KEX_DH_GEX_REQUEST");
@ -76,36 +74,19 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
int r; int r;
u_int min = 0, max = 0, nbits = 0; u_int min = 0, max = 0, nbits = 0;
switch (type) { debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
case SSH2_MSG_KEX_DH_GEX_REQUEST: if ((r = sshpkt_get_u32(ssh, &min)) != 0 ||
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); (r = sshpkt_get_u32(ssh, &nbits)) != 0 ||
if ((r = sshpkt_get_u32(ssh, &min)) != 0 || (r = sshpkt_get_u32(ssh, &max)) != 0 ||
(r = sshpkt_get_u32(ssh, &nbits)) != 0 || (r = sshpkt_get_end(ssh)) != 0)
(r = sshpkt_get_u32(ssh, &max)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
goto out;
kex->nbits = nbits;
kex->min = min;
kex->max = max;
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");
if ((r = sshpkt_get_u32(ssh, &nbits)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
goto out;
kex->nbits = nbits;
/* unused for old GEX */
kex->min = min = DH_GRP_MIN;
kex->max = max = DH_GRP_MAX;
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
goto out; goto out;
} kex->nbits = nbits;
kex->min = min;
kex->max = max;
min = MAX(DH_GRP_MIN, min);
max = MIN(DH_GRP_MAX, max);
nbits = MAX(DH_GRP_MIN, nbits);
nbits = MIN(DH_GRP_MAX, nbits);
if (kex->max < kex->min || kex->nbits < kex->min || if (kex->max < kex->min || kex->nbits < kex->min ||
kex->max < kex->nbits) { kex->max < kex->nbits) {
@ -131,10 +112,6 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
goto out; goto out;
/* old KEX does not use min/max in kexgex_hash() */
if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
kex->min = kex->max = -1;
debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); debug("expecting SSH2_MSG_KEX_DH_GEX_INIT");
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init);
r = 0; r = 0;

View file

@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $OpenBSD: krl.c,v 1.31 2015/01/30 01:10:33 djm Exp $ */ /* $OpenBSD: krl.c,v 1.32 2015/06/24 23:47:23 djm Exp $ */
#include "includes.h" #include "includes.h"
@ -772,7 +772,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
goto out; goto out;
if ((r = sshkey_sign(sign_keys[i], &sblob, &slen, if ((r = sshkey_sign(sign_keys[i], &sblob, &slen,
sshbuf_ptr(buf), sshbuf_len(buf), 0)) == -1) sshbuf_ptr(buf), sshbuf_len(buf), 0)) != 0)
goto out; goto out;
KRL_DBG(("%s: signature sig len %zu", __func__, slen)); KRL_DBG(("%s: signature sig len %zu", __func__, slen));
if ((r = sshbuf_put_string(buf, sblob, slen)) != 0) if ((r = sshbuf_put_string(buf, sblob, slen)) != 0)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: match.c,v 1.29 2013/11/20 20:54:10 deraadt Exp $ */ /* $OpenBSD: match.c,v 1.30 2015/05/04 06:10:48 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -115,15 +115,13 @@ match_pattern(const char *s, const char *pattern)
* indicate negation). Returns -1 if negation matches, 1 if there is * indicate negation). Returns -1 if negation matches, 1 if there is
* a positive match, 0 if there is no match at all. * a positive match, 0 if there is no match at all.
*/ */
int int
match_pattern_list(const char *string, const char *pattern, u_int len, match_pattern_list(const char *string, const char *pattern, int dolower)
int dolower)
{ {
char sub[1024]; char sub[1024];
int negated; int negated;
int got_positive; int got_positive;
u_int i, subi; u_int i, subi, len = strlen(pattern);
got_positive = 0; got_positive = 0;
for (i = 0; i < len;) { for (i = 0; i < len;) {
@ -177,9 +175,9 @@ match_pattern_list(const char *string, const char *pattern, u_int len,
* a positive match, 0 if there is no match at all. * a positive match, 0 if there is no match at all.
*/ */
int int
match_hostname(const char *host, const char *pattern, u_int len) match_hostname(const char *host, const char *pattern)
{ {
return match_pattern_list(host, pattern, len, 1); return match_pattern_list(host, pattern, 1);
} }
/* /*
@ -200,7 +198,7 @@ match_host_and_ip(const char *host, const char *ipaddr,
return 0; return 0;
/* negative hostname match */ /* negative hostname match */
if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1) if ((mhost = match_hostname(host, patterns)) == -1)
return 0; return 0;
/* no match at all */ /* no match at all */
if (mhost == 0 && mip == 0) if (mhost == 0 && mip == 0)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: match.h,v 1.15 2010/02/26 20:29:54 djm Exp $ */ /* $OpenBSD: match.h,v 1.16 2015/05/04 06:10:48 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -15,8 +15,8 @@
#define MATCH_H #define MATCH_H
int match_pattern(const char *, const char *); int match_pattern(const char *, const char *);
int match_pattern_list(const char *, const char *, u_int, int); int match_pattern_list(const char *, const char *, int);
int match_hostname(const char *, const char *, u_int); int match_hostname(const char *, const char *);
int match_host_and_ip(const char *, const char *, const char *); int match_host_and_ip(const char *, const char *, const char *);
int match_user(const char *, const char *, const char *, const char *); int match_user(const char *, const char *, const char *, const char *);
char *match_list(const char *, const char *, u_int *); char *match_list(const char *, const char *, u_int *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.96 2015/01/16 06:40:12 deraadt Exp $ */ /* $OpenBSD: misc.c,v 1.97 2015/04/24 01:36:00 deraadt Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@ -473,7 +473,7 @@ addargs(arglist *args, char *fmt, ...)
} else if (args->num+2 >= nalloc) } else if (args->num+2 >= nalloc)
nalloc *= 2; nalloc *= 2;
args->list = xrealloc(args->list, nalloc, sizeof(char *)); args->list = xreallocarray(args->list, nalloc, sizeof(char *));
args->nalloc = nalloc; args->nalloc = nalloc;
args->list[args->num++] = cp; args->list[args->num++] = cp;
args->list[args->num] = NULL; args->list[args->num] = NULL;

View file

@ -1,34 +1,5 @@
# $OpenBSD: moduli,v 1.12 2015/05/22 02:45:42 dtucker Exp $ # $OpenBSD: moduli,v 1.13 2015/05/28 00:03:06 dtucker Exp $
# Time Type Tests Tries Size Generator Modulus # Time Type Tests Tries Size Generator Modulus
20150520233853 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2AC62AF
20150520233854 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2BCC50F
20150520233854 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2C241F3
20150520233855 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2DDF347
20150520233856 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2E3FDBB
20150520233857 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3006603
20150520233858 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA31D9C37
20150520233859 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA333355B
20150520233900 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3428B23
20150520233902 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA37C9A43
20150520233903 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA384B367
20150520233903 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3903453
20150520233904 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3946C77
20150520233904 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA39F6A9B
20150520233904 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3A0E88B
20150520233905 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3A37763
20150520233906 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BBDD57
20150520233906 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BDCDD7
20150520233906 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BF5D73
20150520233907 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3C9BB83
20150520233908 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3E5ADCF
20150520233909 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3F82077
20150520233910 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA406944F
20150520233910 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA40F7457
20150520233912 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA438733B
20150520233913 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA44707FB
20150520233914 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA4588A2B
20150520233916 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA48CC01B
20150520233917 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA4960077
20150520234251 2 6 100 1535 2 F8F4A446A6C7196643612A6C5CC26A47E491FB737740D68BBEBF0130F7AAADC59075781FB1723B644C0ADCE548C02E726DE5233C484FB4481F3EF3ED0585A0D687B2E0A6987AD2BC910754FC1A1E06B87710CFF0BC2E9868BA15BA20C103D3DCA6B65D8D0182B277F7CAE61D83A785BDD0B3CE471B4B8FAB224438D7A6772130167110AFD1FF584861996117F67B41CF3D2D5FAB020F2EB7F53E299AACF98797AEB6BAC3F0BB892DB4E4F8CDDE28C112C73EB556D0C381C6B9CC78A740BE2123 20150520234251 2 6 100 1535 2 F8F4A446A6C7196643612A6C5CC26A47E491FB737740D68BBEBF0130F7AAADC59075781FB1723B644C0ADCE548C02E726DE5233C484FB4481F3EF3ED0585A0D687B2E0A6987AD2BC910754FC1A1E06B87710CFF0BC2E9868BA15BA20C103D3DCA6B65D8D0182B277F7CAE61D83A785BDD0B3CE471B4B8FAB224438D7A6772130167110AFD1FF584861996117F67B41CF3D2D5FAB020F2EB7F53E299AACF98797AEB6BAC3F0BB892DB4E4F8CDDE28C112C73EB556D0C381C6B9CC78A740BE2123
20150520234255 2 6 100 1535 5 F8F4A446A6C7196643612A6C5CC26A47E491FB737740D68BBEBF0130F7AAADC59075781FB1723B644C0ADCE548C02E726DE5233C484FB4481F3EF3ED0585A0D687B2E0A6987AD2BC910754FC1A1E06B87710CFF0BC2E9868BA15BA20C103D3DCA6B65D8D0182B277F7CAE61D83A785BDD0B3CE471B4B8FAB224438D7A6772130167110AFD1FF584861996117F67B41CF3D2D5FAB020F2EB7F53E299AACF98797AEB6BAC3F0BB892DB4E4F8CDDE28C112C73EB556D0C381C6B9CC78A740D85877 20150520234255 2 6 100 1535 5 F8F4A446A6C7196643612A6C5CC26A47E491FB737740D68BBEBF0130F7AAADC59075781FB1723B644C0ADCE548C02E726DE5233C484FB4481F3EF3ED0585A0D687B2E0A6987AD2BC910754FC1A1E06B87710CFF0BC2E9868BA15BA20C103D3DCA6B65D8D0182B277F7CAE61D83A785BDD0B3CE471B4B8FAB224438D7A6772130167110AFD1FF584861996117F67B41CF3D2D5FAB020F2EB7F53E299AACF98797AEB6BAC3F0BB892DB4E4F8CDDE28C112C73EB556D0C381C6B9CC78A740D85877
20150520234257 2 6 100 1535 2 F8F4A446A6C7196643612A6C5CC26A47E491FB737740D68BBEBF0130F7AAADC59075781FB1723B644C0ADCE548C02E726DE5233C484FB4481F3EF3ED0585A0D687B2E0A6987AD2BC910754FC1A1E06B87710CFF0BC2E9868BA15BA20C103D3DCA6B65D8D0182B277F7CAE61D83A785BDD0B3CE471B4B8FAB224438D7A6772130167110AFD1FF584861996117F67B41CF3D2D5FAB020F2EB7F53E299AACF98797AEB6BAC3F0BB892DB4E4F8CDDE28C112C73EB556D0C381C6B9CC78A740E6494B 20150520234257 2 6 100 1535 2 F8F4A446A6C7196643612A6C5CC26A47E491FB737740D68BBEBF0130F7AAADC59075781FB1723B644C0ADCE548C02E726DE5233C484FB4481F3EF3ED0585A0D687B2E0A6987AD2BC910754FC1A1E06B87710CFF0BC2E9868BA15BA20C103D3DCA6B65D8D0182B277F7CAE61D83A785BDD0B3CE471B4B8FAB224438D7A6772130167110AFD1FF584861996117F67B41CF3D2D5FAB020F2EB7F53E299AACF98797AEB6BAC3F0BB892DB4E4F8CDDE28C112C73EB556D0C381C6B9CC78A740E6494B

View file

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.145 2015/02/20 22:17:21 djm Exp $ */ /* $OpenBSD: monitor.c,v 1.150 2015/06/22 23:42:16 djm Exp $ */
/* /*
* Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org> * Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -404,7 +404,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
auth_log(authctxt, authenticated, partial, auth_log(authctxt, authenticated, partial,
auth_method, auth_submethod); auth_method, auth_submethod);
if (!authenticated) if (!partial && !authenticated)
authctxt->failures++; authctxt->failures++;
} }
} }
@ -1185,7 +1185,7 @@ mm_answer_keyallowed(int sock, Buffer *m)
Key *key; Key *key;
char *cuser, *chost; char *cuser, *chost;
u_char *blob; u_char *blob;
u_int bloblen; u_int bloblen, pubkey_auth_attempt;
enum mm_keytype type = 0; enum mm_keytype type = 0;
int allowed = 0; int allowed = 0;
@ -1195,6 +1195,7 @@ mm_answer_keyallowed(int sock, Buffer *m)
cuser = buffer_get_string(m, NULL); cuser = buffer_get_string(m, NULL);
chost = buffer_get_string(m, NULL); chost = buffer_get_string(m, NULL);
blob = buffer_get_string(m, &bloblen); blob = buffer_get_string(m, &bloblen);
pubkey_auth_attempt = buffer_get_int(m);
key = key_from_blob(blob, bloblen); key = key_from_blob(blob, bloblen);
@ -1215,19 +1216,19 @@ mm_answer_keyallowed(int sock, Buffer *m)
allowed = options.pubkey_authentication && allowed = options.pubkey_authentication &&
!auth2_userkey_already_used(authctxt, key) && !auth2_userkey_already_used(authctxt, key) &&
match_pattern_list(sshkey_ssh_name(key), match_pattern_list(sshkey_ssh_name(key),
options.pubkey_key_types, options.pubkey_key_types, 0) == 1 &&
strlen(options.pubkey_key_types), 0) == 1 && user_key_allowed(authctxt->pw, key,
user_key_allowed(authctxt->pw, key); pubkey_auth_attempt);
pubkey_auth_info(authctxt, key, NULL); pubkey_auth_info(authctxt, key, NULL);
auth_method = "publickey"; auth_method = "publickey";
if (options.pubkey_authentication && allowed != 1) if (options.pubkey_authentication &&
(!pubkey_auth_attempt || allowed != 1))
auth_clear_options(); auth_clear_options();
break; break;
case MM_HOSTKEY: case MM_HOSTKEY:
allowed = options.hostbased_authentication && allowed = options.hostbased_authentication &&
match_pattern_list(sshkey_ssh_name(key), match_pattern_list(sshkey_ssh_name(key),
options.hostbased_key_types, options.hostbased_key_types, 0) == 1 &&
strlen(options.hostbased_key_types), 0) == 1 &&
hostbased_key_allowed(authctxt->pw, hostbased_key_allowed(authctxt->pw,
cuser, chost, key); cuser, chost, key);
pubkey_auth_info(authctxt, key, pubkey_auth_info(authctxt, key,
@ -1474,6 +1475,9 @@ mm_record_login(Session *s, struct passwd *pw)
socklen_t fromlen; socklen_t fromlen;
struct sockaddr_storage from; struct sockaddr_storage from;
if (options.use_login)
return;
/* /*
* Get IP address of client. If the connection is not a socket, let * Get IP address of client. If the connection is not a socket, let
* the address be 0.0.0.0. * the address be 0.0.0.0.

View file

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.84 2015/02/16 22:13:32 djm Exp $ */ /* $OpenBSD: monitor_wrap.c,v 1.85 2015/05/01 03:23:51 djm Exp $ */
/* /*
* Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org> * Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -153,10 +153,8 @@ mm_request_receive(int sock, Buffer *m)
debug3("%s entering", __func__); debug3("%s entering", __func__);
if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
if (errno == EPIPE) { if (errno == EPIPE)
error("%s: socket closed", __func__);
cleanup_exit(255); cleanup_exit(255);
}
fatal("%s: read: %s", __func__, strerror(errno)); fatal("%s: read: %s", __func__, strerror(errno));
} }
msg_len = get_u32(buf); msg_len = get_u32(buf);
@ -373,16 +371,17 @@ mm_auth_password(Authctxt *authctxt, char *password)
} }
int int
mm_user_key_allowed(struct passwd *pw, Key *key) mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt)
{ {
return (mm_key_allowed(MM_USERKEY, NULL, NULL, key)); return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
pubkey_auth_attempt));
} }
int int
mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host, mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
Key *key) Key *key)
{ {
return (mm_key_allowed(MM_HOSTKEY, user, host, key)); return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0));
} }
int int
@ -392,13 +391,14 @@ mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
int ret; int ret;
key->type = KEY_RSA; /* XXX hack for key_to_blob */ key->type = KEY_RSA; /* XXX hack for key_to_blob */
ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key); ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key, 0);
key->type = KEY_RSA1; key->type = KEY_RSA1;
return (ret); return (ret);
} }
int int
mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key,
int pubkey_auth_attempt)
{ {
Buffer m; Buffer m;
u_char *blob; u_char *blob;
@ -416,6 +416,7 @@ mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
buffer_put_cstring(&m, user ? user : ""); buffer_put_cstring(&m, user ? user : "");
buffer_put_cstring(&m, host ? host : ""); buffer_put_cstring(&m, host ? host : "");
buffer_put_string(&m, blob, len); buffer_put_string(&m, blob, len);
buffer_put_int(&m, pubkey_auth_attempt);
free(blob); free(blob);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.h,v 1.26 2015/02/16 22:13:32 djm Exp $ */ /* $OpenBSD: monitor_wrap.h,v 1.27 2015/05/01 03:23:51 djm Exp $ */
/* /*
* Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -45,8 +45,8 @@ void mm_inform_authserv(char *, char *);
struct passwd *mm_getpwnamallow(const char *); struct passwd *mm_getpwnamallow(const char *);
char *mm_auth2_read_banner(void); char *mm_auth2_read_banner(void);
int mm_auth_password(struct Authctxt *, char *); int mm_auth_password(struct Authctxt *, char *);
int mm_key_allowed(enum mm_keytype, char *, char *, Key *); int mm_key_allowed(enum mm_keytype, char *, char *, Key *, int);
int mm_user_key_allowed(struct passwd *, Key *); int mm_user_key_allowed(struct passwd *, Key *, int);
int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: mux.c,v 1.50 2015/01/20 23:14:00 deraadt Exp $ */ /* $OpenBSD: mux.c,v 1.53 2015/05/01 04:03:20 djm Exp $ */
/* /*
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
* *
@ -351,7 +351,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
free(cp); free(cp);
continue; continue;
} }
cctx->env = xrealloc(cctx->env, env_len + 2, cctx->env = xreallocarray(cctx->env, env_len + 2,
sizeof(*cctx->env)); sizeof(*cctx->env));
cctx->env[env_len++] = cp; cctx->env[env_len++] = cp;
cctx->env[env_len] = NULL; cctx->env[env_len] = NULL;
@ -594,7 +594,9 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
return; return;
} }
buffer_init(&out); buffer_init(&out);
if (fctx->fid >= options.num_remote_forwards) { if (fctx->fid >= options.num_remote_forwards ||
(options.remote_forwards[fctx->fid].connect_path == NULL &&
options.remote_forwards[fctx->fid].connect_host == NULL)) {
xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid); xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid);
goto fail; goto fail;
} }
@ -606,7 +608,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
if (type == SSH2_MSG_REQUEST_SUCCESS) { if (type == SSH2_MSG_REQUEST_SUCCESS) {
if (rfwd->listen_port == 0) { if (rfwd->listen_port == 0) {
rfwd->allocated_port = packet_get_int(); rfwd->allocated_port = packet_get_int();
logit("Allocated port %u for mux remote forward" debug("Allocated port %u for mux remote forward"
" to %s:%d", rfwd->allocated_port, " to %s:%d", rfwd->allocated_port,
rfwd->connect_host, rfwd->connect_port); rfwd->connect_host, rfwd->connect_port);
buffer_put_int(&out, MUX_S_REMOTE_PORT); buffer_put_int(&out, MUX_S_REMOTE_PORT);
@ -628,6 +630,17 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
else else
xasprintf(&failmsg, "remote port forwarding failed for " xasprintf(&failmsg, "remote port forwarding failed for "
"listen port %d", rfwd->listen_port); "listen port %d", rfwd->listen_port);
debug2("%s: clearing registered forwarding for listen %d, "
"connect %s:%d", __func__, rfwd->listen_port,
rfwd->connect_path ? rfwd->connect_path :
rfwd->connect_host, rfwd->connect_port);
free(rfwd->listen_host);
free(rfwd->listen_path);
free(rfwd->connect_host);
free(rfwd->connect_path);
memset(rfwd, 0, sizeof(*rfwd));
} }
fail: fail:
error("%s: %s", __func__, failmsg); error("%s: %s", __func__, failmsg);
@ -1723,7 +1736,7 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
if (cancel_flag) if (cancel_flag)
fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__); fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__);
fwd->allocated_port = buffer_get_int(&m); fwd->allocated_port = buffer_get_int(&m);
logit("Allocated port %u for remote forward to %s:%d", verbose("Allocated port %u for remote forward to %s:%d",
fwd->allocated_port, fwd->allocated_port,
fwd->connect_host ? fwd->connect_host : "", fwd->connect_host ? fwd->connect_host : "",
fwd->connect_port); fwd->connect_port);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: myproposal.h,v 1.41 2014/07/11 13:54:34 tedu Exp $ */ /* $OpenBSD: myproposal.h,v 1.44 2015/05/27 23:51:10 dtucker Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -61,7 +61,7 @@
#ifdef OPENSSL_HAVE_EVPGCM #ifdef OPENSSL_HAVE_EVPGCM
# define AESGCM_CIPHER_MODES \ # define AESGCM_CIPHER_MODES \
"aes128-gcm@openssh.com,aes256-gcm@openssh.com," ",aes128-gcm@openssh.com,aes256-gcm@openssh.com"
#else #else
# define AESGCM_CIPHER_MODES # define AESGCM_CIPHER_MODES
#endif #endif
@ -83,14 +83,17 @@
# else # else
# define KEX_CURVE25519_METHODS "" # define KEX_CURVE25519_METHODS ""
# endif # endif
#define KEX_SERVER_KEX \ #define KEX_COMMON_KEX \
KEX_CURVE25519_METHODS \ KEX_CURVE25519_METHODS \
KEX_ECDH_METHODS \ KEX_ECDH_METHODS \
KEX_SHA256_METHODS \ KEX_SHA256_METHODS
"diffie-hellman-group14-sha1"
#define KEX_CLIENT_KEX KEX_SERVER_KEX "," \ #define KEX_SERVER_KEX KEX_COMMON_KEX \
"diffie-hellman-group14-sha1" \
#define KEX_CLIENT_KEX KEX_COMMON_KEX \
"diffie-hellman-group-exchange-sha1," \ "diffie-hellman-group-exchange-sha1," \
"diffie-hellman-group14-sha1," \
"diffie-hellman-group1-sha1" "diffie-hellman-group1-sha1"
#define KEX_DEFAULT_PK_ALG \ #define KEX_DEFAULT_PK_ALG \
@ -108,9 +111,9 @@
/* the actual algorithms */ /* the actual algorithms */
#define KEX_SERVER_ENCRYPT \ #define KEX_SERVER_ENCRYPT \
"aes128-ctr,aes192-ctr,aes256-ctr," \ "chacha20-poly1305@openssh.com," \
AESGCM_CIPHER_MODES \ "aes128-ctr,aes192-ctr,aes256-ctr" \
"chacha20-poly1305@openssh.com" AESGCM_CIPHER_MODES
#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \ #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \
"arcfour256,arcfour128," \ "arcfour256,arcfour128," \
@ -148,8 +151,8 @@
"ssh-ed25519-cert-v01@openssh.com," \ "ssh-ed25519-cert-v01@openssh.com," \
"ssh-ed25519" "ssh-ed25519"
#define KEX_SERVER_ENCRYPT \ #define KEX_SERVER_ENCRYPT \
"aes128-ctr,aes192-ctr,aes256-ctr," \ "chacha20-poly1305@openssh.com," \
"chacha20-poly1305@openssh.com" "aes128-ctr,aes192-ctr,aes256-ctr"
#define KEX_SERVER_MAC \ #define KEX_SERVER_MAC \
"umac-64-etm@openssh.com," \ "umac-64-etm@openssh.com," \
"umac-128-etm@openssh.com," \ "umac-128-etm@openssh.com," \

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bcrypt_pbkdf.c,v 1.9 2014/07/13 21:21:25 tedu Exp $ */ /* $OpenBSD: bcrypt_pbkdf.c,v 1.13 2015/01/12 03:20:04 tedu Exp $ */
/* /*
* Copyright (c) 2013 Ted Unangst <tedu@openbsd.org> * Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
* *
@ -37,6 +37,8 @@
#endif #endif
#define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES #define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES
#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b))
/* /*
* pkcs #5 pbkdf2 implementation using the "bcrypt" hash * pkcs #5 pbkdf2 implementation using the "bcrypt" hash
* *
@ -61,8 +63,8 @@
* wise caller could do; we just do it for you. * wise caller could do; we just do it for you.
*/ */
#define BCRYPT_BLOCKS 8 #define BCRYPT_WORDS 8
#define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4) #define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4)
static void static void
bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out) bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out)
@ -70,7 +72,7 @@ bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out)
blf_ctx state; blf_ctx state;
u_int8_t ciphertext[BCRYPT_HASHSIZE] = u_int8_t ciphertext[BCRYPT_HASHSIZE] =
"OxychromaticBlowfishSwatDynamite"; "OxychromaticBlowfishSwatDynamite";
uint32_t cdata[BCRYPT_BLOCKS]; uint32_t cdata[BCRYPT_WORDS];
int i; int i;
uint16_t j; uint16_t j;
size_t shalen = SHA512_DIGEST_LENGTH; size_t shalen = SHA512_DIGEST_LENGTH;
@ -85,14 +87,14 @@ bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out)
/* encryption */ /* encryption */
j = 0; j = 0;
for (i = 0; i < BCRYPT_BLOCKS; i++) for (i = 0; i < BCRYPT_WORDS; i++)
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
&j); &j);
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t)); blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
/* copy out */ /* copy out */
for (i = 0; i < BCRYPT_BLOCKS; i++) { for (i = 0; i < BCRYPT_WORDS; i++) {
out[4 * i + 3] = (cdata[i] >> 24) & 0xff; out[4 * i + 3] = (cdata[i] >> 24) & 0xff;
out[4 * i + 2] = (cdata[i] >> 16) & 0xff; out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
out[4 * i + 1] = (cdata[i] >> 8) & 0xff; out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
@ -156,9 +158,9 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const u_int8_t *salt, size_t salt
} }
/* /*
* pbkdf2 deviation: ouput the key material non-linearly. * pbkdf2 deviation: output the key material non-linearly.
*/ */
amt = MIN(amt, keylen); amt = MINIMUM(amt, keylen);
for (i = 0; i < amt; i++) { for (i = 0; i < amt; i++) {
size_t dest = i * stride + (count - 1); size_t dest = i * stride + (count - 1);
if (dest >= origkeylen) if (dest >= origkeylen)

View file

@ -68,7 +68,7 @@ cygwin_ssh_privsep_user()
if (cygwin_internal (CW_CYGNAME_FROM_WINNAME, "sshd", cyg_privsep_user, if (cygwin_internal (CW_CYGNAME_FROM_WINNAME, "sshd", cyg_privsep_user,
sizeof cyg_privsep_user) != 0) sizeof cyg_privsep_user) != 0)
#endif #endif
strcpy (cyg_privsep_user, "sshd"); strlcpy(cyg_privsep_user, "sshd", sizeof(cyg_privsep_user));
} }
return cyg_privsep_user; return cyg_privsep_user;
} }

View file

@ -111,7 +111,7 @@ pid_t getpgid(pid_t);
#endif #endif
#ifndef HAVE_ENDGRENT #ifndef HAVE_ENDGRENT
# define endgrent() do { } while (0) # define endgrent() do { } while(0)
#endif #endif
#ifndef HAVE_KRB5_GET_ERROR_MESSAGE #ifndef HAVE_KRB5_GET_ERROR_MESSAGE

View file

@ -221,7 +221,7 @@ long long strtonum(const char *, long long, long long, const char **);
/* multibyte character support */ /* multibyte character support */
#ifndef HAVE_MBLEN #ifndef HAVE_MBLEN
# define mblen(x, y) 1 # define mblen(x, y) (1)
#endif #endif
#if !defined(HAVE_VASPRINTF) || !defined(HAVE_VSNPRINTF) #if !defined(HAVE_VASPRINTF) || !defined(HAVE_VSNPRINTF)

View file

@ -32,7 +32,9 @@
#ifndef WITH_OPENSSL #ifndef WITH_OPENSSL
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_ENDIAN_H
#include <endian.h> #include <endian.h>
#endif
#include <string.h> #include <string.h>
#include <rmd160.h> #include <rmd160.h>

View file

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.208 2015/02/13 18:57:00 markus Exp $ */ /* $OpenBSD: packet.c,v 1.212 2015/05/01 07:10:01 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -291,6 +291,7 @@ ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)
(r = cipher_init(&state->receive_context, none, (r = cipher_init(&state->receive_context, none,
(const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) { (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) {
error("%s: cipher_init failed: %s", __func__, ssh_err(r)); error("%s: cipher_init failed: %s", __func__, ssh_err(r));
free(ssh);
return NULL; return NULL;
} }
state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL; state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL;
@ -792,7 +793,9 @@ ssh_packet_set_compress_hooks(struct ssh *ssh, void *ctx,
void void
ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number) ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number)
{ {
#ifdef WITH_SSH1 #ifndef WITH_SSH1
fatal("no SSH protocol 1 support");
#else /* WITH_SSH1 */
struct session_state *state = ssh->state; struct session_state *state = ssh->state;
const struct sshcipher *cipher = cipher_by_number(number); const struct sshcipher *cipher = cipher_by_number(number);
int r; int r;
@ -1280,7 +1283,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
* been sent. * been sent.
*/ */
if ((r = ssh_packet_write_wait(ssh)) != 0) if ((r = ssh_packet_write_wait(ssh)) != 0)
return r; goto out;
/* Stay in the loop until we have received a complete packet. */ /* Stay in the loop until we have received a complete packet. */
for (;;) { for (;;) {
@ -1338,15 +1341,20 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
len = roaming_read(state->connection_in, buf, len = roaming_read(state->connection_in, buf,
sizeof(buf), &cont); sizeof(buf), &cont);
} while (len == 0 && cont); } while (len == 0 && cont);
if (len == 0) if (len == 0) {
return SSH_ERR_CONN_CLOSED; r = SSH_ERR_CONN_CLOSED;
if (len < 0) goto out;
return SSH_ERR_SYSTEM_ERROR; }
if (len < 0) {
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
/* Append it to the buffer. */ /* Append it to the buffer. */
if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0) if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0)
return r; goto out;
} }
out:
free(setp); free(setp);
return r; return r;
} }
@ -1913,9 +1921,19 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
logit("Connection closed by %.200s", ssh_remote_ipaddr(ssh)); logit("Connection closed by %.200s", ssh_remote_ipaddr(ssh));
cleanup_exit(255); cleanup_exit(255);
case SSH_ERR_CONN_TIMEOUT: case SSH_ERR_CONN_TIMEOUT:
logit("Connection to %.200s timed out while " logit("Connection to %.200s timed out", ssh_remote_ipaddr(ssh));
"waiting to write", ssh_remote_ipaddr(ssh));
cleanup_exit(255); cleanup_exit(255);
case SSH_ERR_DISCONNECTED:
logit("Disconnected from %.200s",
ssh_remote_ipaddr(ssh));
cleanup_exit(255);
case SSH_ERR_SYSTEM_ERROR:
if (errno == ECONNRESET) {
logit("Connection reset by %.200s",
ssh_remote_ipaddr(ssh));
cleanup_exit(255);
}
/* FALLTHROUGH */
default: default:
fatal("%s%sConnection to %.200s: %s", fatal("%s%sConnection to %.200s: %s",
tag != NULL ? tag : "", tag != NULL ? ": " : "", tag != NULL ? tag : "", tag != NULL ? ": " : "",
@ -2728,13 +2746,14 @@ sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v)
return sshbuf_put_stringb(ssh->state->outgoing_packet, v); return sshbuf_put_stringb(ssh->state->outgoing_packet, v);
} }
#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #ifdef WITH_OPENSSL
#ifdef OPENSSL_HAS_ECC
int int
sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g) sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g)
{ {
return sshbuf_put_ec(ssh->state->outgoing_packet, v, g); return sshbuf_put_ec(ssh->state->outgoing_packet, v, g);
} }
#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ #endif /* OPENSSL_HAS_ECC */
#ifdef WITH_SSH1 #ifdef WITH_SSH1
int int
@ -2744,7 +2763,6 @@ sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v)
} }
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */
#ifdef WITH_OPENSSL
int int
sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v)
{ {
@ -2796,13 +2814,14 @@ sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp)
return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp); return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp);
} }
#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #ifdef WITH_OPENSSL
#ifdef OPENSSL_HAS_ECC
int int
sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g) sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g)
{ {
return sshbuf_get_ec(ssh->state->incoming_packet, v, g); return sshbuf_get_ec(ssh->state->incoming_packet, v, g);
} }
#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ #endif /* OPENSSL_HAS_ECC */
#ifdef WITH_SSH1 #ifdef WITH_SSH1
int int
@ -2812,7 +2831,6 @@ sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v)
} }
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */
#ifdef WITH_OPENSSL
int int
sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v)
{ {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.232 2015/02/16 22:13:32 djm Exp $ */ /* $OpenBSD: readconf.c,v 1.237 2015/06/26 05:13:20 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -317,7 +317,7 @@ add_local_forward(Options *options, const struct Forward *newfwd)
newfwd->listen_path == NULL) newfwd->listen_path == NULL)
fatal("Privileged ports can only be forwarded by root."); fatal("Privileged ports can only be forwarded by root.");
#endif #endif
options->local_forwards = xrealloc(options->local_forwards, options->local_forwards = xreallocarray(options->local_forwards,
options->num_local_forwards + 1, options->num_local_forwards + 1,
sizeof(*options->local_forwards)); sizeof(*options->local_forwards));
fwd = &options->local_forwards[options->num_local_forwards++]; fwd = &options->local_forwards[options->num_local_forwards++];
@ -340,7 +340,7 @@ add_remote_forward(Options *options, const struct Forward *newfwd)
{ {
struct Forward *fwd; struct Forward *fwd;
options->remote_forwards = xrealloc(options->remote_forwards, options->remote_forwards = xreallocarray(options->remote_forwards,
options->num_remote_forwards + 1, options->num_remote_forwards + 1,
sizeof(*options->remote_forwards)); sizeof(*options->remote_forwards));
fwd = &options->remote_forwards[options->num_remote_forwards++]; fwd = &options->remote_forwards[options->num_remote_forwards++];
@ -514,7 +514,6 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
const char *ruser; const char *ruser;
int r, port, this_result, result = 1, attributes = 0, negate; int r, port, this_result, result = 1, attributes = 0, negate;
size_t len;
char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
/* /*
@ -567,25 +566,24 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
result = -1; result = -1;
goto out; goto out;
} }
len = strlen(arg);
if (strcasecmp(attrib, "host") == 0) { if (strcasecmp(attrib, "host") == 0) {
criteria = xstrdup(host); criteria = xstrdup(host);
r = match_hostname(host, arg, len) == 1; r = match_hostname(host, arg) == 1;
if (r == (negate ? 1 : 0)) if (r == (negate ? 1 : 0))
this_result = result = 0; this_result = result = 0;
} else if (strcasecmp(attrib, "originalhost") == 0) { } else if (strcasecmp(attrib, "originalhost") == 0) {
criteria = xstrdup(original_host); criteria = xstrdup(original_host);
r = match_hostname(original_host, arg, len) == 1; r = match_hostname(original_host, arg) == 1;
if (r == (negate ? 1 : 0)) if (r == (negate ? 1 : 0))
this_result = result = 0; this_result = result = 0;
} else if (strcasecmp(attrib, "user") == 0) { } else if (strcasecmp(attrib, "user") == 0) {
criteria = xstrdup(ruser); criteria = xstrdup(ruser);
r = match_pattern_list(ruser, arg, len, 0) == 1; r = match_pattern_list(ruser, arg, 0) == 1;
if (r == (negate ? 1 : 0)) if (r == (negate ? 1 : 0))
this_result = result = 0; this_result = result = 0;
} else if (strcasecmp(attrib, "localuser") == 0) { } else if (strcasecmp(attrib, "localuser") == 0) {
criteria = xstrdup(pw->pw_name); criteria = xstrdup(pw->pw_name);
r = match_pattern_list(pw->pw_name, arg, len, 0) == 1; r = match_pattern_list(pw->pw_name, arg, 0) == 1;
if (r == (negate ? 1 : 0)) if (r == (negate ? 1 : 0))
this_result = result = 0; this_result = result = 0;
} else if (strcasecmp(attrib, "exec") == 0) { } else if (strcasecmp(attrib, "exec") == 0) {
@ -687,8 +685,8 @@ parse_token(const char *cp, const char *filename, int linenum,
for (i = 0; keywords[i].name; i++) for (i = 0; keywords[i].name; i++)
if (strcmp(cp, keywords[i].name) == 0) if (strcmp(cp, keywords[i].name) == 0)
return keywords[i].opcode; return keywords[i].opcode;
if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown, if (ignored_unknown != NULL &&
strlen(ignored_unknown), 1) == 1) match_pattern_list(cp, ignored_unknown, 1) == 1)
return oIgnoredUnknownOption; return oIgnoredUnknownOption;
error("%s: line %d: Bad configuration option: %s", error("%s: line %d: Bad configuration option: %s",
filename, linenum, cp); filename, linenum, cp);
@ -785,7 +783,9 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
} }
/* Strip trailing whitespace */ /* Strip trailing whitespace */
for (len = strlen(line) - 1; len > 0; len--) { if ((len = strlen(line)) == 0)
return 0;
for (len--; len > 0; len--) {
if (strchr(WHITESPACE, line[len]) == NULL) if (strchr(WHITESPACE, line[len]) == NULL)
break; break;
line[len] = '\0'; line[len] = '\0';
@ -1258,13 +1258,13 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
arg = strdelim(&s); arg = strdelim(&s);
if (!arg || *arg == '\0') if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum); fatal("%.200s line %d: Missing argument.", filename, linenum);
if (arg[0] == '^' && arg[2] == 0 && if (strcmp(arg, "none") == 0)
value = SSH_ESCAPECHAR_NONE;
else if (arg[1] == '\0')
value = (u_char) arg[0];
else if (arg[0] == '^' && arg[2] == 0 &&
(u_char) arg[1] >= 64 && (u_char) arg[1] < 128) (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
value = (u_char) arg[1] & 31; value = (u_char) arg[1] & 31;
else if (strlen(arg) == 1)
value = (u_char) arg[0];
else if (strcmp(arg, "none") == 0)
value = SSH_ESCAPECHAR_NONE;
else { else {
fatal("%.200s line %d: Bad escape character.", fatal("%.200s line %d: Bad escape character.",
filename, linenum); filename, linenum);
@ -1973,7 +1973,8 @@ parse_fwd_field(char **p, struct fwdarg *fwd)
switch (*cp) { switch (*cp) {
case '\\': case '\\':
memmove(cp, cp + 1, strlen(cp + 1) + 1); memmove(cp, cp + 1, strlen(cp + 1) + 1);
cp++; if (*cp == '\0')
return -1;
break; break;
case '/': case '/':
ispath = 1; ispath = 1;

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.78 2015/01/26 06:12:18 djm Exp $ # $OpenBSD: Makefile,v 1.81 2015/05/21 06:44:25 djm Exp $
REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec
tests: prep $(REGRESS_TARGETS) tests: prep $(REGRESS_TARGETS)
@ -54,6 +54,7 @@ LTESTS= connect \
multiplex \ multiplex \
reexec \ reexec \
brokenkeys \ brokenkeys \
cfgparse \
cfgmatch \ cfgmatch \
addrmatch \ addrmatch \
localcommand \ localcommand \
@ -72,7 +73,8 @@ LTESTS= connect \
limit-keytype \ limit-keytype \
hostkey-agent \ hostkey-agent \
keygen-knownhosts \ keygen-knownhosts \
hostkey-rotate hostkey-rotate \
principals-command
# dhgex \ # dhgex \
@ -180,10 +182,10 @@ t11:
${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\ ${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\
awk '{print $$2}' | diff - ${.CURDIR}/t11.ok awk '{print $$2}' | diff - ${.CURDIR}/t11.ok
t12.out: $(OBJ)/t12.out:
${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -C 'test-comment-1234' -f $(OBJ)/$@ ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -C 'test-comment-1234' -f $@
t12: t12.out t12: $(OBJ)/t12.out
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t12.out.pub | grep test-comment-1234 >/dev/null ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t12.out.pub | grep test-comment-1234 >/dev/null
t-exec: ${LTESTS:=.sh} t-exec: ${LTESTS:=.sh}

View file

@ -31,7 +31,7 @@ TEST_SHELL: shell used for running the test scripts.
TEST_SSH_PORT: TCP port to be used for the listening tests. TEST_SSH_PORT: TCP port to be used for the listening tests.
TEST_SSH_SSH_CONFOPTS: Configuration directives to be added to ssh_config TEST_SSH_SSH_CONFOPTS: Configuration directives to be added to ssh_config
before running each test. before running each test.
TEST_SSH_SSHD_CONFOTPS: Configuration directives to be added to sshd_config TEST_SSH_SSHD_CONFOPTS: Configuration directives to be added to sshd_config
before running each test. before running each test.

View file

@ -0,0 +1,75 @@
# $OpenBSD: cfgparse.sh,v 1.5 2015/05/29 03:05:13 djm Exp $
# Placed in the Public Domain.
tid="config parse"
# This is a reasonable proxy for IPv6 support.
if ! config_defined HAVE_STRUCT_IN6_ADDR ; then
SKIP_IPV6=yes
fi
# We need to use the keys generated for the regression test because sshd -T
# will fail if we're not running with SUDO (no permissions for real keys) or
# if we are # running tests on a system that has never had sshd installed
# (keys won't exist).
grep "HostKey " $OBJ/sshd_config > $OBJ/sshd_config_minimal
SSHD_KEYS="`cat $OBJ/sshd_config_minimal`"
verbose "reparse minimal config"
($SUDO ${SSHD} -T -f $OBJ/sshd_config_minimal >$OBJ/sshd_config.1 &&
$SUDO ${SSHD} -T -f $OBJ/sshd_config.1 >$OBJ/sshd_config.2 &&
diff $OBJ/sshd_config.1 $OBJ/sshd_config.2) || fail "reparse minimal config"
verbose "reparse regress config"
($SUDO ${SSHD} -T -f $OBJ/sshd_config >$OBJ/sshd_config.1 &&
$SUDO ${SSHD} -T -f $OBJ/sshd_config.1 >$OBJ/sshd_config.2 &&
diff $OBJ/sshd_config.1 $OBJ/sshd_config.2) || fail "reparse regress config"
verbose "listenaddress order"
# expected output
cat > $OBJ/sshd_config.0 <<EOD
listenaddress 1.2.3.4:1234
listenaddress 1.2.3.4:5678
EOD
[ X${SKIP_IPV6} = Xyes ] || cat >> $OBJ/sshd_config.0 <<EOD
listenaddress [::1]:1234
listenaddress [::1]:5678
EOD
# test input sets. should all result in the output above.
# test 1: addressfamily and port first
cat > $OBJ/sshd_config.1 <<EOD
${SSHD_KEYS}
addressfamily any
port 1234
port 5678
listenaddress 1.2.3.4
EOD
[ X${SKIP_IPV6} = Xyes ] || cat >> $OBJ/sshd_config.1 <<EOD
listenaddress ::1
EOD
($SUDO ${SSHD} -T -f $OBJ/sshd_config.1 | \
grep 'listenaddress ' >$OBJ/sshd_config.2 &&
diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \
fail "listenaddress order 1"
# test 2: listenaddress first
cat > $OBJ/sshd_config.1 <<EOD
${SSHD_KEYS}
listenaddress 1.2.3.4
port 1234
port 5678
addressfamily any
EOD
[ X${SKIP_IPV6} = Xyes ] || cat >> $OBJ/sshd_config.1 <<EOD
listenaddress ::1
EOD
($SUDO ${SSHD} -T -f $OBJ/sshd_config.1 | \
grep 'listenaddress ' >$OBJ/sshd_config.2 &&
diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \
fail "listenaddress order 2"
# cleanup
rm -f $OBJ/sshd_config.[012]

View file

@ -1,4 +1,4 @@
# $OpenBSD: cipher-speed.sh,v 1.12 2015/03/03 22:35:19 markus Exp $ # $OpenBSD: cipher-speed.sh,v 1.13 2015/03/24 20:22:17 markus Exp $
# Placed in the Public Domain. # Placed in the Public Domain.
tid="cipher speed" tid="cipher speed"
@ -25,7 +25,7 @@ for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do
fi fi
done done
# No point trying all MACs for AEAD ciphers since they are ignored. # No point trying all MACs for AEAD ciphers since they are ignored.
if ssh -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then if ${SSH} -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then
break break
fi fi
n=`expr $n + 1` n=`expr $n + 1`

View file

@ -1,4 +1,4 @@
# $OpenBSD: hostkey-rotate.sh,v 1.2 2015/03/03 17:53:40 djm Exp $ # $OpenBSD: hostkey-rotate.sh,v 1.3 2015/03/24 20:22:17 markus Exp $
# Placed in the Public Domain. # Placed in the Public Domain.
tid="hostkey rotate" tid="hostkey rotate"
@ -15,7 +15,7 @@ rm $OBJ/known_hosts
trace "prepare hostkeys" trace "prepare hostkeys"
nkeys=0 nkeys=0
all_algs="" all_algs=""
for k in `ssh -Q key-plain` ; do for k in `${SSH} -Q key-plain` ; do
${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k" ${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k"
echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig
nkeys=`expr $nkeys + 1` nkeys=`expr $nkeys + 1`
@ -62,7 +62,7 @@ expect_nkeys $nkeys "learn hostkeys"
check_key_present ssh-rsa || fail "didn't learn keys" check_key_present ssh-rsa || fail "didn't learn keys"
# Check each key type # Check each key type
for k in `ssh -Q key-plain` ; do for k in `${SSH} -Q key-plain` ; do
verbose "learn additional hostkeys, type=$k" verbose "learn additional hostkeys, type=$k"
dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs
expect_nkeys $nkeys "learn hostkeys $k" expect_nkeys $nkeys "learn hostkeys $k"
@ -109,7 +109,7 @@ dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa
expect_nkeys 1 "learn hostkeys" expect_nkeys 1 "learn hostkeys"
check_key_present ssh-rsa || fail "didn't learn changed key" check_key_present ssh-rsa || fail "didn't learn changed key"
# $OpenBSD: hostkey-rotate.sh,v 1.2 2015/03/03 17:53:40 djm Exp $ # $OpenBSD: hostkey-rotate.sh,v 1.3 2015/03/24 20:22:17 markus Exp $
# Placed in the Public Domain. # Placed in the Public Domain.
tid="hostkey rotate" tid="hostkey rotate"

View file

@ -1,4 +1,4 @@
# $OpenBSD: integrity.sh,v 1.15 2015/01/19 20:42:31 markus Exp $ # $OpenBSD: integrity.sh,v 1.16 2015/03/24 20:22:17 markus Exp $
# Placed in the Public Domain. # Placed in the Public Domain.
tid="integrity" tid="integrity"
@ -38,7 +38,7 @@ for m in $macs; do
cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
# modify output from sshd at offset $off # modify output from sshd at offset $off
pxy="proxycommand=$cmd | $OBJ/modpipe -wm xor:$off:1" pxy="proxycommand=$cmd | $OBJ/modpipe -wm xor:$off:1"
if ssh -Q cipher-auth | grep "^${m}\$" >/dev/null 2>&1 ; then if ${SSH} -Q cipher-auth | grep "^${m}\$" >/dev/null 2>&1 ; then
echo "Ciphers=$m" >> $OBJ/sshd_proxy echo "Ciphers=$m" >> $OBJ/sshd_proxy
macopt="-c $m" macopt="-c $m"
else else

View file

@ -1,4 +1,4 @@
# $OpenBSD: kextype.sh,v 1.5 2014/04/21 22:15:37 djm Exp $ # $OpenBSD: kextype.sh,v 1.6 2015/03/24 20:19:15 markus Exp $
# Placed in the Public Domain. # Placed in the Public Domain.
tid="login with different key exchange algorithms" tid="login with different key exchange algorithms"
@ -8,7 +8,7 @@ cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
# Make server accept all key exchanges. # Make server accept all key exchanges.
ALLKEX=`ssh -Q kex` ALLKEX=`${SSH} -Q kex`
KEXOPT=`echo $ALLKEX | tr ' ' ,` KEXOPT=`echo $ALLKEX | tr ' ' ,`
echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy

View file

@ -1,4 +1,4 @@
# $OpenBSD: keys-command.sh,v 1.2 2012/12/06 06:06:54 dtucker Exp $ # $OpenBSD: keys-command.sh,v 1.3 2015/05/21 06:40:02 djm Exp $
# Placed in the Public Domain. # Placed in the Public Domain.
tid="authorized keys from command" tid="authorized keys from command"
@ -9,26 +9,63 @@ if test -z "$SUDO" ; then
exit 0 exit 0
fi fi
rm -f $OBJ/keys-command-args
touch $OBJ/keys-command-args
chmod a+rw $OBJ/keys-command-args
expected_key_text=`awk '{ print $2 }' < $OBJ/rsa.pub`
expected_key_fp=`$SSHKEYGEN -lf $OBJ/rsa.pub | awk '{ print $2 }'`
# Establish a AuthorizedKeysCommand in /var/run where it will have # Establish a AuthorizedKeysCommand in /var/run where it will have
# acceptable directory permissions. # acceptable directory permissions.
KEY_COMMAND="/var/run/keycommand_${LOGNAME}" KEY_COMMAND="/var/run/keycommand_${LOGNAME}"
cat << _EOF | $SUDO sh -c "cat > '$KEY_COMMAND'" cat << _EOF | $SUDO sh -c "rm -f '$KEY_COMMAND' ; cat > '$KEY_COMMAND'"
#!/bin/sh #!/bin/sh
echo args: "\$@" >> $OBJ/keys-command-args
echo "$PATH" | grep -q mekmitasdigoat && exit 7
test "x\$1" != "x${LOGNAME}" && exit 1 test "x\$1" != "x${LOGNAME}" && exit 1
if test $# -eq 6 ; then
test "x\$2" != "xblah" && exit 2
test "x\$3" != "x${expected_key_text}" && exit 3
test "x\$4" != "xssh-rsa" && exit 4
test "x\$5" != "x${expected_key_fp}" && exit 5
test "x\$6" != "xblah" && exit 6
fi
exec cat "$OBJ/authorized_keys_${LOGNAME}" exec cat "$OBJ/authorized_keys_${LOGNAME}"
_EOF _EOF
$SUDO chmod 0755 "$KEY_COMMAND" $SUDO chmod 0755 "$KEY_COMMAND"
cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak
(
grep -vi AuthorizedKeysFile $OBJ/sshd_proxy.bak
echo AuthorizedKeysFile none
echo AuthorizedKeysCommand $KEY_COMMAND
echo AuthorizedKeysCommandUser ${LOGNAME}
) > $OBJ/sshd_proxy
if [ -x $KEY_COMMAND ]; then if [ -x $KEY_COMMAND ]; then
${SSH} -F $OBJ/ssh_proxy somehost true cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak
verbose "AuthorizedKeysCommand with arguments"
(
grep -vi AuthorizedKeysFile $OBJ/sshd_proxy.bak
echo AuthorizedKeysFile none
echo AuthorizedKeysCommand $KEY_COMMAND %u blah %k %t %f blah
echo AuthorizedKeysCommandUser ${LOGNAME}
) > $OBJ/sshd_proxy
# Ensure that $PATH is sanitised in sshd
env PATH=$PATH:/sbin/mekmitasdigoat \
${SSH} -F $OBJ/ssh_proxy somehost true
if [ $? -ne 0 ]; then
fail "connect failed"
fi
verbose "AuthorizedKeysCommand without arguments"
# Check legacy behavior of no-args resulting in username being passed.
(
grep -vi AuthorizedKeysFile $OBJ/sshd_proxy.bak
echo AuthorizedKeysFile none
echo AuthorizedKeysCommand $KEY_COMMAND
echo AuthorizedKeysCommandUser ${LOGNAME}
) > $OBJ/sshd_proxy
# Ensure that $PATH is sanitised in sshd
env PATH=$PATH:/sbin/mekmitasdigoat \
${SSH} -F $OBJ/ssh_proxy somehost true
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
fail "connect failed" fail "connect failed"
fi fi

View file

@ -42,7 +42,6 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <arpa/telnet.h>
#include <errno.h> #include <errno.h>
#include <netdb.h> #include <netdb.h>
@ -63,6 +62,13 @@
# endif # endif
#endif #endif
/* Telnet options from arpa/telnet.h */
#define IAC 255
#define DONT 254
#define DO 253
#define WONT 252
#define WILL 251
#ifndef SUN_LEN #ifndef SUN_LEN
#define SUN_LEN(su) \ #define SUN_LEN(su) \
(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))

View file

@ -0,0 +1,141 @@
# $OpenBSD: principals-command.sh,v 1.1 2015/05/21 06:44:25 djm Exp $
# Placed in the Public Domain.
tid="authorized principals command"
rm -f $OBJ/user_ca_key* $OBJ/cert_user_key*
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
if test -z "$SUDO" ; then
echo "skipped (SUDO not set)"
echo "need SUDO to create file in /var/run, test won't work without"
exit 0
fi
# Establish a AuthorizedPrincipalsCommand in /var/run where it will have
# acceptable directory permissions.
PRINCIPALS_COMMAND="/var/run/principals_command_${LOGNAME}"
cat << _EOF | $SUDO sh -c "cat > '$PRINCIPALS_COMMAND'"
#!/bin/sh
test "x\$1" != "x${LOGNAME}" && exit 1
test -f "$OBJ/authorized_principals_${LOGNAME}" &&
exec cat "$OBJ/authorized_principals_${LOGNAME}"
_EOF
test $? -eq 0 || fatal "couldn't prepare principals command"
$SUDO chmod 0755 "$PRINCIPALS_COMMAND"
# Create a CA key and a user certificate.
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key || \
fatal "ssh-keygen of user_ca_key failed"
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/cert_user_key || \
fatal "ssh-keygen of cert_user_key failed"
${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \
-z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key || \
fatal "couldn't sign cert_user_key"
# Test explicitly-specified principals
for privsep in yes no ; do
_prefix="privsep $privsep"
# Setup for AuthorizedPrincipalsCommand
rm -f $OBJ/authorized_keys_$USER
(
cat $OBJ/sshd_proxy_bak
echo "UsePrivilegeSeparation $privsep"
echo "AuthorizedKeysFile none"
echo "AuthorizedPrincipalsCommand $PRINCIPALS_COMMAND %u"
echo "AuthorizedPrincipalsCommandUser ${LOGNAME}"
echo "TrustedUserCAKeys $OBJ/user_ca_key.pub"
) > $OBJ/sshd_proxy
# XXX test missing command
# XXX test failing command
# Empty authorized_principals
verbose "$tid: ${_prefix} empty authorized_principals"
echo > $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
fi
# Wrong authorized_principals
verbose "$tid: ${_prefix} wrong authorized_principals"
echo gregorsamsa > $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
fi
# Correct authorized_principals
verbose "$tid: ${_prefix} correct authorized_principals"
echo mekmitasdigoat > $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
fi
# authorized_principals with bad key option
verbose "$tid: ${_prefix} authorized_principals bad key opt"
echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
fi
# authorized_principals with command=false
verbose "$tid: ${_prefix} authorized_principals command=false"
echo 'command="false" mekmitasdigoat' > \
$OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
fi
# authorized_principals with command=true
verbose "$tid: ${_prefix} authorized_principals command=true"
echo 'command="true" mekmitasdigoat' > \
$OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key \
-F $OBJ/ssh_proxy somehost false >/dev/null 2>&1
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
fi
# Setup for principals= key option
rm -f $OBJ/authorized_principals_$USER
(
cat $OBJ/sshd_proxy_bak
echo "UsePrivilegeSeparation $privsep"
) > $OBJ/sshd_proxy
# Wrong principals list
verbose "$tid: ${_prefix} wrong principals key option"
(
printf 'cert-authority,principals="gregorsamsa" '
cat $OBJ/user_ca_key.pub
) > $OBJ/authorized_keys_$USER
${SSH} -2i $OBJ/cert_user_key \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
fi
# Correct principals list
verbose "$tid: ${_prefix} correct principals key option"
(
printf 'cert-authority,principals="mekmitasdigoat" '
cat $OBJ/user_ca_key.pub
) > $OBJ/authorized_keys_$USER
${SSH} -2i $OBJ/cert_user_key \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
fi
done

View file

@ -1,4 +1,4 @@
# $OpenBSD: ssh-com.sh,v 1.8 2013/05/17 00:37:40 dtucker Exp $ # $OpenBSD: ssh-com.sh,v 1.9 2015/05/08 07:29:00 djm Exp $
# Placed in the Public Domain. # Placed in the Public Domain.
tid="connect to ssh.com server" tid="connect to ssh.com server"
@ -44,14 +44,14 @@ cat << EOF > $OBJ/sshd2_config
HostKeyFile ${SRC}/dsa_ssh2.prv HostKeyFile ${SRC}/dsa_ssh2.prv
PublicHostKeyFile ${SRC}/dsa_ssh2.pub PublicHostKeyFile ${SRC}/dsa_ssh2.pub
RandomSeedFile ${OBJ}/random_seed RandomSeedFile ${OBJ}/random_seed
MaxConnections 0 MaxConnections 0
PermitRootLogin yes PermitRootLogin yes
VerboseMode no VerboseMode no
CheckMail no CheckMail no
Ssh1Compatibility no Ssh1Compatibility no
EOF EOF
# create client config # create client config
sed "s/HostKeyAlias.*/HostKeyAlias ssh2-localhost-with-alias/" \ sed "s/HostKeyAlias.*/HostKeyAlias ssh2-localhost-with-alias/" \
< $OBJ/ssh_config > $OBJ/ssh_config_com < $OBJ/ssh_config > $OBJ/ssh_config_com

View file

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
# $OpenBSD: ssh2putty.sh,v 1.2 2009/10/06 23:51:49 dtucker Exp $ # $OpenBSD: ssh2putty.sh,v 1.3 2015/05/08 07:26:13 djm Exp $
if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then
echo "Usage: ssh2putty hostname port ssh-private-key" echo "Usage: ssh2putty hostname port ssh-private-key"
@ -19,13 +19,13 @@ else
fi fi
public_exponent=` public_exponent=`
openssl rsa -noout -text -in $KEYFILE | grep ^publicExponent | openssl rsa -noout -text -in $KEYFILE | grep ^publicExponent |
sed 's/.*(//;s/).*//' sed 's/.*(//;s/).*//'
` `
test $? -ne 0 && exit 1 test $? -ne 0 && exit 1
modulus=` modulus=`
openssl rsa -noout -modulus -in $KEYFILE | grep ^Modulus= | openssl rsa -noout -modulus -in $KEYFILE | grep ^Modulus= |
sed 's/^Modulus=/0x/' | tr A-Z a-z sed 's/^Modulus=/0x/' | tr A-Z a-z
` `
test $? -ne 0 && exit 1 test $? -ne 0 && exit 1

View file

@ -444,7 +444,7 @@ Host *
EOF EOF
if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then
trace "adding ssh_config option $TEST_SSH_SSHD_CONFOPTS" trace "adding ssh_config option $TEST_SSH_SSH_CONFOPTS"
echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config
fi fi

View file

@ -1,4 +1,4 @@
# $OpenBSD: try-ciphers.sh,v 1.24 2015/03/03 22:35:19 markus Exp $ # $OpenBSD: try-ciphers.sh,v 1.25 2015/03/24 20:22:17 markus Exp $
# Placed in the Public Domain. # Placed in the Public Domain.
tid="try ciphers" tid="try ciphers"
@ -19,7 +19,7 @@ for c in `${SSH} -Q cipher`; do
fi fi
# No point trying all MACs for AEAD ciphers since they # No point trying all MACs for AEAD ciphers since they
# are ignored. # are ignored.
if ssh -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then if ${SSH} -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then
break break
fi fi
n=`expr $n + 1` n=`expr $n + 1`

View file

@ -1,4 +1,4 @@
/* $OpenBSD: test_iterate.c,v 1.3 2015/03/07 04:41:48 djm Exp $ */ /* $OpenBSD: test_iterate.c,v 1.4 2015/03/31 22:59:01 djm Exp $ */
/* /*
* Regress test for hostfile.h hostkeys_foreach() * Regress test for hostfile.h hostkeys_foreach()
* *
@ -91,8 +91,8 @@ check(struct hostkey_foreach_line *l, void *_ctx)
expected->l.keytype : expected->no_parse_keytype; expected->l.keytype : expected->no_parse_keytype;
#ifndef WITH_SSH1 #ifndef WITH_SSH1
if (expected->l.keytype == KEY_RSA1 || if (parse_key && (expected->l.keytype == KEY_RSA1 ||
expected->no_parse_keytype == KEY_RSA1) { expected->no_parse_keytype == KEY_RSA1)) {
expected_status = HKF_STATUS_INVALID; expected_status = HKF_STATUS_INVALID;
expected_keytype = KEY_UNSPEC; expected_keytype = KEY_UNSPEC;
parse_key = 0; parse_key = 0;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: test_sshkey.c,v 1.3 2015/01/26 06:11:28 djm Exp $ */ /* $OpenBSD: test_sshkey.c,v 1.4 2015/04/22 01:38:36 djm Exp $ */
/* /*
* Regress test for sshkey.h key management API * Regress test for sshkey.h key management API
* *
@ -505,7 +505,7 @@ sshkey_tests(void)
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
NULL), 0); NULL), 0);
k3 = get_private("ed25519_2"); k3 = get_private("rsa_1");
build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: rijndael.c,v 1.19 2014/11/18 22:38:48 mikeb Exp $ */ /* $OpenBSD: rijndael.c,v 1.20 2015/03/16 11:09:52 djm Exp $ */
/** /**
* rijndael-alg-fst.c * rijndael-alg-fst.c

View file

@ -43,6 +43,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <linux/net.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/seccomp.h> #include <linux/seccomp.h>
@ -79,6 +80,16 @@
#define SC_ALLOW(_nr) \ #define SC_ALLOW(_nr) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
#define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \
/* load first syscall argument */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)])), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \
/* reload syscall number; all rules expect it in accumulator */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, nr))
/* Syscall filtering set for preauth. */ /* Syscall filtering set for preauth. */
static const struct sock_filter preauth_insns[] = { static const struct sock_filter preauth_insns[] = {
@ -90,45 +101,105 @@ static const struct sock_filter preauth_insns[] = {
/* Load the syscall number for checking. */ /* Load the syscall number for checking. */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
offsetof(struct seccomp_data, nr)), offsetof(struct seccomp_data, nr)),
/* Syscalls to non-fatally deny */
#ifdef __NR_fstat
SC_DENY(fstat, EACCES),
#endif
#ifdef __NR_fstat64
SC_DENY(fstat64, EACCES),
#endif
#ifdef __NR_open
SC_DENY(open, EACCES), SC_DENY(open, EACCES),
#endif
#ifdef __NR_openat
SC_DENY(openat, EACCES),
#endif
#ifdef __NR_newfstatat
SC_DENY(newfstatat, EACCES),
#endif
#ifdef __NR_stat
SC_DENY(stat, EACCES), SC_DENY(stat, EACCES),
SC_ALLOW(getpid),
SC_ALLOW(gettimeofday),
SC_ALLOW(clock_gettime),
#ifdef __NR_time /* not defined on EABI ARM */
SC_ALLOW(time),
#endif #endif
SC_ALLOW(read), #ifdef __NR_stat64
SC_ALLOW(write), SC_DENY(stat64, EACCES),
SC_ALLOW(close),
#ifdef __NR_shutdown /* not defined on archs that go via socketcall(2) */
SC_ALLOW(shutdown),
#endif #endif
/* Syscalls to permit */
#ifdef __NR_brk
SC_ALLOW(brk), SC_ALLOW(brk),
SC_ALLOW(poll),
#ifdef __NR__newselect
SC_ALLOW(_newselect),
#else
SC_ALLOW(select),
#endif #endif
#ifdef __NR_clock_gettime
SC_ALLOW(clock_gettime),
#endif
#ifdef __NR_close
SC_ALLOW(close),
#endif
#ifdef __NR_exit
SC_ALLOW(exit),
#endif
#ifdef __NR_exit_group
SC_ALLOW(exit_group),
#endif
#ifdef __NR_getpgid
SC_ALLOW(getpgid),
#endif
#ifdef __NR_getpid
SC_ALLOW(getpid),
#endif
#ifdef __NR_gettimeofday
SC_ALLOW(gettimeofday),
#endif
#ifdef __NR_madvise
SC_ALLOW(madvise), SC_ALLOW(madvise),
#ifdef __NR_mmap2 /* EABI ARM only has mmap2() */
SC_ALLOW(mmap2),
#endif #endif
#ifdef __NR_mmap #ifdef __NR_mmap
SC_ALLOW(mmap), SC_ALLOW(mmap),
#endif #endif
#ifdef __dietlibc__ #ifdef __NR_mmap2
SC_ALLOW(mremap), SC_ALLOW(mmap2),
SC_ALLOW(exit),
#endif #endif
#ifdef __NR_mremap
SC_ALLOW(mremap),
#endif
#ifdef __NR_munmap
SC_ALLOW(munmap), SC_ALLOW(munmap),
SC_ALLOW(exit_group), #endif
#ifdef __NR__newselect
SC_ALLOW(_newselect),
#endif
#ifdef __NR_poll
SC_ALLOW(poll),
#endif
#ifdef __NR_pselect6
SC_ALLOW(pselect6),
#endif
#ifdef __NR_read
SC_ALLOW(read),
#endif
#ifdef __NR_rt_sigprocmask #ifdef __NR_rt_sigprocmask
SC_ALLOW(rt_sigprocmask), SC_ALLOW(rt_sigprocmask),
#else #endif
#ifdef __NR_select
SC_ALLOW(select),
#endif
#ifdef __NR_shutdown
SC_ALLOW(shutdown),
#endif
#ifdef __NR_sigprocmask
SC_ALLOW(sigprocmask), SC_ALLOW(sigprocmask),
#endif #endif
#ifdef __NR_time
SC_ALLOW(time),
#endif
#ifdef __NR_write
SC_ALLOW(write),
#endif
#ifdef __NR_socketcall
SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN),
#endif
/* Default deny */
BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL),
}; };

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sandbox-systrace.c,v 1.14 2015/01/20 23:14:00 deraadt Exp $ */ /* $OpenBSD: sandbox-systrace.c,v 1.16 2015/06/29 22:35:12 djm Exp $ */
/* /*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org> * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
* *
@ -50,8 +50,9 @@ struct sandbox_policy {
/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */ /* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */
static const struct sandbox_policy preauth_policy[] = { static const struct sandbox_policy preauth_policy[] = {
{ SYS_open, SYSTR_POLICY_NEVER }, { SYS_clock_gettime, SYSTR_POLICY_PERMIT },
{ SYS_close, SYSTR_POLICY_PERMIT },
{ SYS_exit, SYSTR_POLICY_PERMIT },
#ifdef SYS_getentropy #ifdef SYS_getentropy
/* OpenBSD 5.6 and newer use getentropy(2) to seed arc4random(3). */ /* OpenBSD 5.6 and newer use getentropy(2) to seed arc4random(3). */
{ SYS_getentropy, SYSTR_POLICY_PERMIT }, { SYS_getentropy, SYSTR_POLICY_PERMIT },
@ -59,23 +60,21 @@ static const struct sandbox_policy preauth_policy[] = {
/* Previous releases used sysctl(3)'s kern.arnd variable. */ /* Previous releases used sysctl(3)'s kern.arnd variable. */
{ SYS___sysctl, SYSTR_POLICY_PERMIT }, { SYS___sysctl, SYSTR_POLICY_PERMIT },
#endif #endif
#ifdef SYS_sendsyslog
{ SYS_sendsyslog, SYSTR_POLICY_PERMIT },
#endif
{ SYS_close, SYSTR_POLICY_PERMIT },
{ SYS_exit, SYSTR_POLICY_PERMIT },
{ SYS_getpid, SYSTR_POLICY_PERMIT }, { SYS_getpid, SYSTR_POLICY_PERMIT },
{ SYS_getpgid, SYSTR_POLICY_PERMIT },
{ SYS_gettimeofday, SYSTR_POLICY_PERMIT }, { SYS_gettimeofday, SYSTR_POLICY_PERMIT },
{ SYS_clock_gettime, SYSTR_POLICY_PERMIT },
{ SYS_madvise, SYSTR_POLICY_PERMIT }, { SYS_madvise, SYSTR_POLICY_PERMIT },
{ SYS_mmap, SYSTR_POLICY_PERMIT }, { SYS_mmap, SYSTR_POLICY_PERMIT },
{ SYS_mprotect, SYSTR_POLICY_PERMIT }, { SYS_mprotect, SYSTR_POLICY_PERMIT },
{ SYS_mquery, SYSTR_POLICY_PERMIT }, { SYS_mquery, SYSTR_POLICY_PERMIT },
{ SYS_poll, SYSTR_POLICY_PERMIT },
{ SYS_munmap, SYSTR_POLICY_PERMIT }, { SYS_munmap, SYSTR_POLICY_PERMIT },
{ SYS_open, SYSTR_POLICY_NEVER },
{ SYS_poll, SYSTR_POLICY_PERMIT },
{ SYS_read, SYSTR_POLICY_PERMIT }, { SYS_read, SYSTR_POLICY_PERMIT },
{ SYS_select, SYSTR_POLICY_PERMIT }, { SYS_select, SYSTR_POLICY_PERMIT },
#ifdef SYS_sendsyslog
{ SYS_sendsyslog, SYSTR_POLICY_PERMIT },
#endif
{ SYS_shutdown, SYSTR_POLICY_PERMIT }, { SYS_shutdown, SYSTR_POLICY_PERMIT },
{ SYS_sigprocmask, SYSTR_POLICY_PERMIT }, { SYS_sigprocmask, SYSTR_POLICY_PERMIT },
{ SYS_write, SYSTR_POLICY_PERMIT }, { SYS_write, SYSTR_POLICY_PERMIT },

View file

@ -1,4 +1,4 @@
/* $OpenBSD: scp.c,v 1.181 2015/01/16 06:40:12 deraadt Exp $ */ /* $OpenBSD: scp.c,v 1.182 2015/04/24 01:36:00 deraadt Exp $ */
/* /*
* scp - secure remote copy. This is basically patched BSD rcp which * scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd). * uses ssh to do the data transfer (instead of using rcmd).
@ -1333,7 +1333,7 @@ allocbuf(BUF *bp, int fd, int blksize)
if (bp->buf == NULL) if (bp->buf == NULL)
bp->buf = xmalloc(size); bp->buf = xmalloc(size);
else else
bp->buf = xrealloc(bp->buf, 1, size); bp->buf = xreallocarray(bp->buf, 1, size);
memset(bp->buf, 0, size); memset(bp->buf, 0, size);
bp->cnt = size; bp->cnt = size;
return (bp); return (bp);

View file

@ -1,5 +1,4 @@
/* $OpenBSD: servconf.c,v 1.274 2015/07/01 02:32:17 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.260 2015/02/02 01:57:44 deraadt Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -80,6 +79,8 @@ initialize_server_options(ServerOptions *options)
/* Standard Options */ /* Standard Options */
options->num_ports = 0; options->num_ports = 0;
options->ports_from_cmdline = 0; options->ports_from_cmdline = 0;
options->queued_listen_addrs = NULL;
options->num_queued_listens = 0;
options->listen_addrs = NULL; options->listen_addrs = NULL;
options->address_family = -1; options->address_family = -1;
options->num_host_key_files = 0; options->num_host_key_files = 0;
@ -117,6 +118,7 @@ initialize_server_options(ServerOptions *options)
options->kerberos_get_afs_token = -1; options->kerberos_get_afs_token = -1;
options->gss_authentication=-1; options->gss_authentication=-1;
options->gss_cleanup_creds = -1; options->gss_cleanup_creds = -1;
options->gss_strict_acceptor = -1;
options->password_authentication = -1; options->password_authentication = -1;
options->kbd_interactive_authentication = -1; options->kbd_interactive_authentication = -1;
options->challenge_response_authentication = -1; options->challenge_response_authentication = -1;
@ -161,6 +163,8 @@ initialize_server_options(ServerOptions *options)
options->revoked_keys_file = NULL; options->revoked_keys_file = NULL;
options->trusted_user_ca_keys = NULL; options->trusted_user_ca_keys = NULL;
options->authorized_principals_file = NULL; options->authorized_principals_file = NULL;
options->authorized_principals_command = NULL;
options->authorized_principals_command_user = NULL;
options->ip_qos_interactive = -1; options->ip_qos_interactive = -1;
options->ip_qos_bulk = -1; options->ip_qos_bulk = -1;
options->version_addendum = NULL; options->version_addendum = NULL;
@ -207,6 +211,8 @@ fill_default_server_options(ServerOptions *options)
/* No certificates by default */ /* No certificates by default */
if (options->num_ports == 0) if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT; options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
if (options->listen_addrs == NULL) if (options->listen_addrs == NULL)
add_listen_addr(options, NULL, 0); add_listen_addr(options, NULL, 0);
if (options->pid_file == NULL) if (options->pid_file == NULL)
@ -273,6 +279,8 @@ fill_default_server_options(ServerOptions *options)
options->gss_authentication = 0; options->gss_authentication = 0;
if (options->gss_cleanup_creds == -1) if (options->gss_cleanup_creds == -1)
options->gss_cleanup_creds = 1; options->gss_cleanup_creds = 1;
if (options->gss_strict_acceptor == -1)
options->gss_strict_acceptor = 0;
if (options->password_authentication == -1) if (options->password_authentication == -1)
options->password_authentication = 0; options->password_authentication = 0;
if (options->kbd_interactive_authentication == -1) if (options->kbd_interactive_authentication == -1)
@ -351,6 +359,7 @@ fill_default_server_options(ServerOptions *options)
CLEAR_ON_NONE(options->banner); CLEAR_ON_NONE(options->banner);
CLEAR_ON_NONE(options->trusted_user_ca_keys); CLEAR_ON_NONE(options->trusted_user_ca_keys);
CLEAR_ON_NONE(options->revoked_keys_file); CLEAR_ON_NONE(options->revoked_keys_file);
CLEAR_ON_NONE(options->authorized_principals_file);
for (i = 0; i < options->num_host_key_files; i++) for (i = 0; i < options->num_host_key_files; i++)
CLEAR_ON_NONE(options->host_key_files[i]); CLEAR_ON_NONE(options->host_key_files[i]);
for (i = 0; i < options->num_host_cert_files; i++) for (i = 0; i < options->num_host_cert_files; i++)
@ -393,11 +402,13 @@ typedef enum {
sBanner, sUseDNS, sHostbasedAuthentication, sBanner, sUseDNS, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
sAcceptEnv, sPermitTunnel,
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding, sUsePrivilegeSeparation, sAllowAgentForwarding,
sHostCertificate, sHostCertificate,
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
sKexAlgorithms, sIPQoS, sVersionAddendum, sKexAlgorithms, sIPQoS, sVersionAddendum,
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
@ -464,9 +475,11 @@ static struct {
#ifdef GSSAPI #ifdef GSSAPI
{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
#else #else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
#endif #endif
{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
@ -530,6 +543,8 @@ static struct {
{ "ipqos", sIPQoS, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL },
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
@ -596,10 +611,6 @@ add_listen_addr(ServerOptions *options, char *addr, int port)
{ {
u_int i; u_int i;
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
if (port == 0) if (port == 0)
for (i = 0; i < options->num_ports; i++) for (i = 0; i < options->num_ports; i++)
add_one_listen_addr(options, addr, options->ports[i]); add_one_listen_addr(options, addr, options->ports[i]);
@ -629,6 +640,51 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
options->listen_addrs = aitop; options->listen_addrs = aitop;
} }
/*
* Queue a ListenAddress to be processed once we have all of the Ports
* and AddressFamily options.
*/
static void
queue_listen_addr(ServerOptions *options, char *addr, int port)
{
options->queued_listen_addrs = xreallocarray(
options->queued_listen_addrs, options->num_queued_listens + 1,
sizeof(addr));
options->queued_listen_ports = xreallocarray(
options->queued_listen_ports, options->num_queued_listens + 1,
sizeof(port));
options->queued_listen_addrs[options->num_queued_listens] =
xstrdup(addr);
options->queued_listen_ports[options->num_queued_listens] = port;
options->num_queued_listens++;
}
/*
* Process queued (text) ListenAddress entries.
*/
static void
process_queued_listen_addrs(ServerOptions *options)
{
u_int i;
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
for (i = 0; i < options->num_queued_listens; i++) {
add_listen_addr(options, options->queued_listen_addrs[i],
options->queued_listen_ports[i]);
free(options->queued_listen_addrs[i]);
options->queued_listen_addrs[i] = NULL;
}
free(options->queued_listen_addrs);
options->queued_listen_addrs = NULL;
free(options->queued_listen_ports);
options->queued_listen_ports = NULL;
options->num_queued_listens = 0;
}
struct connection_info * struct connection_info *
get_connection_info(int populate, int use_dns) get_connection_info(int populate, int use_dns)
{ {
@ -714,7 +770,6 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
{ {
int result = 1, attributes = 0, port; int result = 1, attributes = 0, port;
char *arg, *attrib, *cp = *condition; char *arg, *attrib, *cp = *condition;
size_t len;
if (ci == NULL) if (ci == NULL)
debug3("checking syntax for 'Match %s'", cp); debug3("checking syntax for 'Match %s'", cp);
@ -741,13 +796,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
error("Missing Match criteria for %s", attrib); error("Missing Match criteria for %s", attrib);
return -1; return -1;
} }
len = strlen(arg);
if (strcasecmp(attrib, "user") == 0) { if (strcasecmp(attrib, "user") == 0) {
if (ci == NULL || ci->user == NULL) { if (ci == NULL || ci->user == NULL) {
result = 0; result = 0;
continue; continue;
} }
if (match_pattern_list(ci->user, arg, len, 0) != 1) if (match_pattern_list(ci->user, arg, 0) != 1)
result = 0; result = 0;
else else
debug("user %.100s matched 'User %.100s' at " debug("user %.100s matched 'User %.100s' at "
@ -768,7 +822,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
result = 0; result = 0;
continue; continue;
} }
if (match_hostname(ci->host, arg, len) != 1) if (match_hostname(ci->host, arg) != 1)
result = 0; result = 0;
else else
debug("connection from %.100s matched 'Host " debug("connection from %.100s matched 'Host "
@ -945,9 +999,6 @@ process_server_config_line(ServerOptions *options, char *line,
/* ignore ports from configfile if cmdline specifies ports */ /* ignore ports from configfile if cmdline specifies ports */
if (options->ports_from_cmdline) if (options->ports_from_cmdline)
return 0; return 0;
if (options->listen_addrs != NULL)
fatal("%s line %d: ports must be specified before "
"ListenAddress.", filename, linenum);
if (options->num_ports >= MAX_PORTS) if (options->num_ports >= MAX_PORTS)
fatal("%s line %d: too many ports.", fatal("%s line %d: too many ports.",
filename, linenum); filename, linenum);
@ -983,7 +1034,7 @@ process_server_config_line(ServerOptions *options, char *line,
if ((value = convtime(arg)) == -1) if ((value = convtime(arg)) == -1)
fatal("%s line %d: invalid time value.", fatal("%s line %d: invalid time value.",
filename, linenum); filename, linenum);
if (*intptr == -1) if (*activep && *intptr == -1)
*intptr = value; *intptr = value;
break; break;
@ -999,7 +1050,7 @@ process_server_config_line(ServerOptions *options, char *line,
/* check for bare IPv6 address: no "[]" and 2 or more ":" */ /* check for bare IPv6 address: no "[]" and 2 or more ":" */
if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
&& strchr(p+1, ':') != NULL) { && strchr(p+1, ':') != NULL) {
add_listen_addr(options, arg, 0); queue_listen_addr(options, arg, 0);
break; break;
} }
p = hpdelim(&arg); p = hpdelim(&arg);
@ -1012,16 +1063,13 @@ process_server_config_line(ServerOptions *options, char *line,
else if ((port = a2port(arg)) <= 0) else if ((port = a2port(arg)) <= 0)
fatal("%s line %d: bad port number", filename, linenum); fatal("%s line %d: bad port number", filename, linenum);
add_listen_addr(options, p, port); queue_listen_addr(options, p, port);
break; break;
case sAddressFamily: case sAddressFamily:
intptr = &options->address_family; intptr = &options->address_family;
multistate_ptr = multistate_addressfamily; multistate_ptr = multistate_addressfamily;
if (options->listen_addrs != NULL)
fatal("%s line %d: address family must be specified "
"before ListenAddress.", filename, linenum);
parse_multistate: parse_multistate:
arg = strdelim(&cp); arg = strdelim(&cp);
if (!arg || *arg == '\0') if (!arg || *arg == '\0')
@ -1175,6 +1223,10 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->gss_cleanup_creds; intptr = &options->gss_cleanup_creds;
goto parse_flag; goto parse_flag;
case sGssStrictAcceptor:
intptr = &options->gss_strict_acceptor;
goto parse_flag;
case sPasswordAuthentication: case sPasswordAuthentication:
intptr = &options->password_authentication; intptr = &options->password_authentication;
goto parse_flag; goto parse_flag;
@ -1449,7 +1501,7 @@ process_server_config_line(ServerOptions *options, char *line,
len = strlen(p) + 1; len = strlen(p) + 1;
while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
len += 1 + strlen(arg); len += 1 + strlen(arg);
p = xrealloc(p, 1, len); p = xreallocarray(p, 1, len);
strlcat(p, " ", len); strlcat(p, " ", len);
strlcat(p, arg, len); strlcat(p, arg, len);
} }
@ -1564,7 +1616,7 @@ process_server_config_line(ServerOptions *options, char *line,
if (value == -1) if (value == -1)
fatal("%s line %d: Bad yes/point-to-point/ethernet/" fatal("%s line %d: Bad yes/point-to-point/ethernet/"
"no argument: %s", filename, linenum, arg); "no argument: %s", filename, linenum, arg);
if (*intptr == -1) if (*activep && *intptr == -1)
*intptr = value; *intptr = value;
break; break;
@ -1617,7 +1669,7 @@ process_server_config_line(ServerOptions *options, char *line,
break; break;
case sForceCommand: case sForceCommand:
if (cp == NULL) if (cp == NULL || *cp == '\0')
fatal("%.200s line %d: Missing argument.", filename, fatal("%.200s line %d: Missing argument.", filename,
linenum); linenum);
len = strspn(cp, WHITESPACE); len = strspn(cp, WHITESPACE);
@ -1662,7 +1714,7 @@ process_server_config_line(ServerOptions *options, char *line,
break; break;
case sVersionAddendum: case sVersionAddendum:
if (cp == NULL) if (cp == NULL || *cp == '\0')
fatal("%.200s line %d: Missing argument.", filename, fatal("%.200s line %d: Missing argument.", filename,
linenum); linenum);
len = strspn(cp, WHITESPACE); len = strspn(cp, WHITESPACE);
@ -1702,8 +1754,36 @@ process_server_config_line(ServerOptions *options, char *line,
*charptr = xstrdup(arg); *charptr = xstrdup(arg);
break; break;
case sAuthorizedPrincipalsCommand:
if (cp == NULL)
fatal("%.200s line %d: Missing argument.", filename,
linenum);
len = strspn(cp, WHITESPACE);
if (*activep &&
options->authorized_principals_command == NULL) {
if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
fatal("%.200s line %d: "
"AuthorizedPrincipalsCommand must be "
"an absolute path", filename, linenum);
options->authorized_principals_command =
xstrdup(cp + len);
}
return 0;
case sAuthorizedPrincipalsCommandUser:
charptr = &options->authorized_principals_command_user;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing "
"AuthorizedPrincipalsCommandUser argument.",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case sAuthenticationMethods: case sAuthenticationMethods:
if (*activep && options->num_auth_methods == 0) { if (options->num_auth_methods == 0) {
while ((arg = strdelim(&cp)) && *arg != '\0') { while ((arg = strdelim(&cp)) && *arg != '\0') {
if (options->num_auth_methods >= if (options->num_auth_methods >=
MAX_AUTH_METHODS) MAX_AUTH_METHODS)
@ -1714,6 +1794,8 @@ process_server_config_line(ServerOptions *options, char *line,
fatal("%s line %d: invalid " fatal("%s line %d: invalid "
"authentication method list.", "authentication method list.",
filename, linenum); filename, linenum);
if (!*activep)
continue;
options->auth_methods[ options->auth_methods[
options->num_auth_methods++] = xstrdup(arg); options->num_auth_methods++] = xstrdup(arg);
} }
@ -1723,13 +1805,14 @@ process_server_config_line(ServerOptions *options, char *line,
case sStreamLocalBindMask: case sStreamLocalBindMask:
arg = strdelim(&cp); arg = strdelim(&cp);
if (!arg || *arg == '\0') if (!arg || *arg == '\0')
fatal("%s line %d: missing StreamLocalBindMask argument.", fatal("%s line %d: missing StreamLocalBindMask "
filename, linenum); "argument.", filename, linenum);
/* Parse mode in octal format */ /* Parse mode in octal format */
value = strtol(arg, &p, 8); value = strtol(arg, &p, 8);
if (arg == p || value < 0 || value > 0777) if (arg == p || value < 0 || value > 0777)
fatal("%s line %d: Bad mask.", filename, linenum); fatal("%s line %d: Bad mask.", filename, linenum);
options->fwd_opts.streamlocal_bind_mask = (mode_t)value; if (*activep)
options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
break; break;
case sStreamLocalBindUnlink: case sStreamLocalBindUnlink:
@ -1956,6 +2039,7 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
if (bad_options > 0) if (bad_options > 0)
fatal("%s: terminating, %d bad configuration options", fatal("%s: terminating, %d bad configuration options",
filename, bad_options); filename, bad_options);
process_queued_listen_addrs(options);
} }
static const char * static const char *
@ -2032,6 +2116,12 @@ dump_cfg_int(ServerOpCodes code, int val)
printf("%s %d\n", lookup_opcode_name(code), val); printf("%s %d\n", lookup_opcode_name(code), val);
} }
static void
dump_cfg_oct(ServerOpCodes code, int val)
{
printf("%s 0%o\n", lookup_opcode_name(code), val);
}
static void static void
dump_cfg_fmtint(ServerOpCodes code, int val) dump_cfg_fmtint(ServerOpCodes code, int val)
{ {
@ -2061,6 +2151,8 @@ dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
{ {
u_int i; u_int i;
if (count <= 0)
return;
printf("%s", lookup_opcode_name(code)); printf("%s", lookup_opcode_name(code));
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
printf(" %s", vals[i]); printf(" %s", vals[i]);
@ -2074,6 +2166,7 @@ dump_config(ServerOptions *o)
int ret; int ret;
struct addrinfo *ai; struct addrinfo *ai;
char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
char *laddr1 = xstrdup(""), *laddr2 = NULL;
/* these are usually at the top of the config */ /* these are usually at the top of the config */
for (i = 0; i < o->num_ports; i++) for (i = 0; i < o->num_ports; i++)
@ -2081,7 +2174,11 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sProtocol, o->protocol); dump_cfg_fmtint(sProtocol, o->protocol);
dump_cfg_fmtint(sAddressFamily, o->address_family); dump_cfg_fmtint(sAddressFamily, o->address_family);
/* ListenAddress must be after Port */ /*
* ListenAddress must be after Port. add_one_listen_addr pushes
* addresses onto a stack, so to maintain ordering we need to
* print these in reverse order.
*/
for (ai = o->listen_addrs; ai; ai = ai->ai_next) { for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
sizeof(addr), port, sizeof(port), sizeof(addr), port, sizeof(port),
@ -2090,16 +2187,22 @@ dump_config(ServerOptions *o)
(ret != EAI_SYSTEM) ? gai_strerror(ret) : (ret != EAI_SYSTEM) ? gai_strerror(ret) :
strerror(errno)); strerror(errno));
} else { } else {
laddr2 = laddr1;
if (ai->ai_family == AF_INET6) if (ai->ai_family == AF_INET6)
printf("listenaddress [%s]:%s\n", addr, port); xasprintf(&laddr1, "listenaddress [%s]:%s\n%s",
addr, port, laddr2);
else else
printf("listenaddress %s:%s\n", addr, port); xasprintf(&laddr1, "listenaddress %s:%s\n%s",
addr, port, laddr2);
free(laddr2);
} }
} }
printf("%s", laddr1);
free(laddr1);
/* integer arguments */ /* integer arguments */
#ifdef USE_PAM #ifdef USE_PAM
dump_cfg_int(sUsePAM, o->use_pam); dump_cfg_fmtint(sUsePAM, o->use_pam);
#endif #endif
dump_cfg_int(sServerKeyBits, o->server_key_bits); dump_cfg_int(sServerKeyBits, o->server_key_bits);
dump_cfg_int(sLoginGraceTime, o->login_grace_time); dump_cfg_int(sLoginGraceTime, o->login_grace_time);
@ -2109,6 +2212,7 @@ dump_config(ServerOptions *o)
dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sMaxSessions, o->max_sessions);
dump_cfg_int(sClientAliveInterval, o->client_alive_interval); dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
/* formatted integer arguments */ /* formatted integer arguments */
dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
@ -2152,6 +2256,7 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sUseDNS, o->use_dns);
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
@ -2168,9 +2273,12 @@ dump_config(ServerOptions *o)
dump_cfg_string(sRevokedKeys, o->revoked_keys_file); dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
dump_cfg_string(sAuthorizedPrincipalsFile, dump_cfg_string(sAuthorizedPrincipalsFile,
o->authorized_principals_file); o->authorized_principals_file);
dump_cfg_string(sVersionAddendum, o->version_addendum); dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
? "none" : o->version_addendum);
dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
dump_cfg_string(sHostKeyAgent, o->host_key_agent); dump_cfg_string(sHostKeyAgent, o->host_key_agent);
dump_cfg_string(sKexAlgorithms, dump_cfg_string(sKexAlgorithms,
o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
@ -2188,7 +2296,7 @@ dump_config(ServerOptions *o)
o->authorized_keys_files); o->authorized_keys_files);
dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
o->host_key_files); o->host_key_files);
dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files, dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
o->host_cert_files); o->host_cert_files);
dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.116 2015/01/13 07:39:19 djm Exp $ */ /* $OpenBSD: servconf.h,v 1.119 2015/05/22 03:50:02 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -58,7 +58,9 @@ typedef struct {
u_int num_ports; u_int num_ports;
u_int ports_from_cmdline; u_int ports_from_cmdline;
int ports[MAX_PORTS]; /* Port number to listen on. */ int ports[MAX_PORTS]; /* Port number to listen on. */
char *listen_addr; /* Address on which the server listens. */ u_int num_queued_listens;
char **queued_listen_addrs;
int *queued_listen_ports;
struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ struct addrinfo *listen_addrs; /* Addresses on which the server listens. */
int address_family; /* Address family used by the server. */ int address_family; /* Address family used by the server. */
char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */ char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */
@ -116,6 +118,7 @@ typedef struct {
* authenticated with Kerberos. */ * authenticated with Kerberos. */
int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_authentication; /* If true, permit GSSAPI authentication */
int gss_cleanup_creds; /* If true, destroy cred cache on logout */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */
int password_authentication; /* If true, permit password int password_authentication; /* If true, permit password
* authentication. */ * authentication. */
int kbd_interactive_authentication; /* If true, permit */ int kbd_interactive_authentication; /* If true, permit */
@ -176,9 +179,11 @@ typedef struct {
char *chroot_directory; char *chroot_directory;
char *revoked_keys_file; char *revoked_keys_file;
char *trusted_user_ca_keys; char *trusted_user_ca_keys;
char *authorized_principals_file;
char *authorized_keys_command; char *authorized_keys_command;
char *authorized_keys_command_user; char *authorized_keys_command_user;
char *authorized_principals_file;
char *authorized_principals_command;
char *authorized_principals_command_user;
int64_t rekey_limit; int64_t rekey_limit;
int rekey_interval; int rekey_interval;
@ -214,9 +219,11 @@ struct connection_info {
M_CP_STROPT(banner); \ M_CP_STROPT(banner); \
M_CP_STROPT(trusted_user_ca_keys); \ M_CP_STROPT(trusted_user_ca_keys); \
M_CP_STROPT(revoked_keys_file); \ M_CP_STROPT(revoked_keys_file); \
M_CP_STROPT(authorized_principals_file); \
M_CP_STROPT(authorized_keys_command); \ M_CP_STROPT(authorized_keys_command); \
M_CP_STROPT(authorized_keys_command_user); \ M_CP_STROPT(authorized_keys_command_user); \
M_CP_STROPT(authorized_principals_file); \
M_CP_STROPT(authorized_principals_command); \
M_CP_STROPT(authorized_principals_command_user); \
M_CP_STROPT(hostbased_key_types); \ M_CP_STROPT(hostbased_key_types); \
M_CP_STROPT(pubkey_key_types); \ M_CP_STROPT(pubkey_key_types); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \

View file

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.277 2015/01/16 06:40:12 deraadt Exp $ */ /* $OpenBSD: session.c,v 1.278 2015/04/24 01:36:00 deraadt Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -998,7 +998,7 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
if (envsize >= 1000) if (envsize >= 1000)
fatal("child_set_env: too many env vars"); fatal("child_set_env: too many env vars");
envsize += 50; envsize += 50;
env = (*envp) = xrealloc(env, envsize, sizeof(char *)); env = (*envp) = xreallocarray(env, envsize, sizeof(char *));
*envsizep = envsize; *envsizep = envsize;
} }
/* Need to set the NULL pointer at end of array beyond the new slot. */ /* Need to set the NULL pointer at end of array beyond the new slot. */
@ -1926,7 +1926,7 @@ session_new(void)
return NULL; return NULL;
debug2("%s: allocate (allocated %d max %d)", debug2("%s: allocate (allocated %d max %d)",
__func__, sessions_nalloc, options.max_sessions); __func__, sessions_nalloc, options.max_sessions);
tmp = xrealloc(sessions, sessions_nalloc + 1, tmp = xreallocarray(sessions, sessions_nalloc + 1,
sizeof(*sessions)); sizeof(*sessions));
if (tmp == NULL) { if (tmp == NULL) {
error("%s: cannot allocate %d sessions", error("%s: cannot allocate %d sessions",
@ -2253,7 +2253,7 @@ session_env_req(Session *s)
for (i = 0; i < options.num_accept_env; i++) { for (i = 0; i < options.num_accept_env; i++) {
if (match_pattern(name, options.accept_env[i])) { if (match_pattern(name, options.accept_env[i])) {
debug2("Setting env %d: %s=%s", s->num_env, name, val); debug2("Setting env %d: %s=%s", s->num_env, name, val);
s->env = xrealloc(s->env, s->num_env + 1, s->env = xreallocarray(s->env, s->num_env + 1,
sizeof(*s->env)); sizeof(*s->env));
s->env[s->num_env].name = name; s->env[s->num_env].name = name;
s->env[s->num_env].val = val; s->env[s->num_env].val = val;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-client.c,v 1.117 2015/01/20 23:14:00 deraadt Exp $ */ /* $OpenBSD: sftp-client.c,v 1.120 2015/05/28 04:50:53 djm Exp $ */
/* /*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
* *
@ -408,6 +408,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
error("Invalid packet back from SSH2_FXP_INIT (type %u)", error("Invalid packet back from SSH2_FXP_INIT (type %u)",
type); type);
sshbuf_free(msg); sshbuf_free(msg);
free(ret);
return(NULL); return(NULL);
} }
if ((r = sshbuf_get_u32(msg, &ret->version)) != 0) if ((r = sshbuf_get_u32(msg, &ret->version)) != 0)
@ -621,7 +622,7 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
error("Server sent suspect path \"%s\" " error("Server sent suspect path \"%s\" "
"during readdir of \"%s\"", filename, path); "during readdir of \"%s\"", filename, path);
} else if (dir) { } else if (dir) {
*dir = xrealloc(*dir, ents + 2, sizeof(**dir)); *dir = xreallocarray(*dir, ents + 2, sizeof(**dir));
(*dir)[ents] = xcalloc(1, sizeof(***dir)); (*dir)[ents] = xcalloc(1, sizeof(***dir));
(*dir)[ents]->filename = xstrdup(filename); (*dir)[ents]->filename = xstrdup(filename);
(*dir)[ents]->longname = xstrdup(longname); (*dir)[ents]->longname = xstrdup(longname);
@ -1384,7 +1385,9 @@ do_download(struct sftp_conn *conn, const char *remote_path,
"server reordered requests", local_path); "server reordered requests", local_path);
} }
debug("truncating at %llu", (unsigned long long)highwater); debug("truncating at %llu", (unsigned long long)highwater);
ftruncate(local_fd, highwater); if (ftruncate(local_fd, highwater) == -1)
error("ftruncate \"%s\": %s", local_path,
strerror(errno));
} }
if (read_error) { if (read_error) {
error("Couldn't read from remote file \"%s\" : %s", error("Couldn't read from remote file \"%s\" : %s",

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-client.h,v 1.26 2015/01/14 13:54:13 djm Exp $ */ /* $OpenBSD: sftp-client.h,v 1.27 2015/05/08 06:45:13 djm Exp $ */
/* /*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
@ -111,7 +111,7 @@ int do_download(struct sftp_conn *, const char *, const char *,
Attrib *, int, int, int); Attrib *, int, int, int);
/* /*
* Recursively download 'remote_directory' to 'local_directory'. Preserve * Recursively download 'remote_directory' to 'local_directory'. Preserve
* times if 'pflag' is set * times if 'pflag' is set
*/ */
int download_dir(struct sftp_conn *, const char *, const char *, int download_dir(struct sftp_conn *, const char *, const char *,
@ -124,7 +124,7 @@ int download_dir(struct sftp_conn *, const char *, const char *,
int do_upload(struct sftp_conn *, const char *, const char *, int, int, int); int do_upload(struct sftp_conn *, const char *, const char *, int, int, int);
/* /*
* Recursively upload 'local_directory' to 'remote_directory'. Preserve * Recursively upload 'local_directory' to 'remote_directory'. Preserve
* times if 'pflag' is set * times if 'pflag' is set
*/ */
int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-server.c,v 1.105 2015/01/20 23:14:00 deraadt Exp $ */ /* $OpenBSD: sftp-server.c,v 1.106 2015/04/24 01:36:01 deraadt Exp $ */
/* /*
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
* *
@ -40,7 +40,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <pwd.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <stdarg.h> #include <stdarg.h>
@ -310,7 +309,7 @@ handle_new(int use, const char *name, int fd, int flags, DIR *dirp)
if (num_handles + 1 <= num_handles) if (num_handles + 1 <= num_handles)
return -1; return -1;
num_handles++; num_handles++;
handles = xrealloc(handles, num_handles, sizeof(Handle)); handles = xreallocarray(handles, num_handles, sizeof(Handle));
handle_unused(num_handles - 1); handle_unused(num_handles - 1);
} }
@ -1063,7 +1062,7 @@ process_readdir(u_int32_t id)
while ((dp = readdir(dirp)) != NULL) { while ((dp = readdir(dirp)) != NULL) {
if (count >= nstats) { if (count >= nstats) {
nstats *= 2; nstats *= 2;
stats = xrealloc(stats, nstats, sizeof(Stat)); stats = xreallocarray(stats, nstats, sizeof(Stat));
} }
/* XXX OVERFLOW ? */ /* XXX OVERFLOW ? */
snprintf(pathname, sizeof pathname, "%s%s%s", path, snprintf(pathname, sizeof pathname, "%s%s%s", path,

View file

@ -29,9 +29,9 @@ DESCRIPTION
-c Indicates that added identities should be subject to confirmation -c Indicates that added identities should be subject to confirmation
before being used for authentication. Confirmation is performed before being used for authentication. Confirmation is performed
by the SSH_ASKPASS program mentioned below. Successful by ssh-askpass(1). Successful confirmation is signaled by a zero
confirmation is signaled by a zero exit status from the exit status from ssh-askpass(1), rather than text entered into
SSH_ASKPASS program, rather than text entered into the requester. the requester.
-D Deletes all identities from the agent. -D Deletes all identities from the agent.
@ -78,10 +78,11 @@ ENVIRONMENT
the current terminal if it was run from a terminal. If ssh-add the current terminal if it was run from a terminal. If ssh-add
does not have a terminal associated with it but DISPLAY and does not have a terminal associated with it but DISPLAY and
SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS are set, it will execute the program specified by
SSH_ASKPASS and open an X11 window to read the passphrase. This SSH_ASKPASS (by default M-bM-^@M-^\ssh-askpassM-bM-^@M-^]) and open an X11 window to
is particularly useful when calling ssh-add from a .xsession or read the passphrase. This is particularly useful when calling
related script. (Note that on some machines it may be necessary ssh-add from a .xsession or related script. (Note that on some
to redirect the input from /dev/null to make this work.) machines it may be necessary to redirect the input from /dev/null
to make this work.)
SSH_AUTH_SOCK SSH_AUTH_SOCK
Identifies the path of a UNIX-domain socket used to communicate Identifies the path of a UNIX-domain socket used to communicate
@ -116,7 +117,7 @@ EXIT STATUS
ssh-add is unable to contact the authentication agent. ssh-add is unable to contact the authentication agent.
SEE ALSO SEE ALSO
ssh(1), ssh-agent(1), ssh-keygen(1), sshd(8) ssh(1), ssh-agent(1), ssh-askpass(1), ssh-keygen(1), sshd(8)
AUTHORS AUTHORS
OpenSSH is a derivative of the original and free ssh 1.2.12 release by OpenSSH is a derivative of the original and free ssh 1.2.12 release by
@ -125,4 +126,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0. versions 1.5 and 2.0.
OpenBSD 5.7 December 21, 2014 OpenBSD 5.7 OpenBSD 5.7 March 30, 2015 OpenBSD 5.7

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-add.1,v 1.61 2014/12/21 22:27:56 djm Exp $ .\" $OpenBSD: ssh-add.1,v 1.62 2015/03/30 18:28:37 jmc Exp $
.\" .\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: December 21 2014 $ .Dd $Mdocdate: March 30 2015 $
.Dt SSH-ADD 1 .Dt SSH-ADD 1
.Os .Os
.Sh NAME .Sh NAME
@ -88,12 +88,11 @@ The options are as follows:
.It Fl c .It Fl c
Indicates that added identities should be subject to confirmation before Indicates that added identities should be subject to confirmation before
being used for authentication. being used for authentication.
Confirmation is performed by the Confirmation is performed by
.Ev SSH_ASKPASS .Xr ssh-askpass 1 .
program mentioned below. Successful confirmation is signaled by a zero exit status from
Successful confirmation is signaled by a zero exit status from the .Xr ssh-askpass 1 ,
.Ev SSH_ASKPASS rather than text entered into the requester.
program, rather than text entered into the requester.
.It Fl D .It Fl D
Deletes all identities from the agent. Deletes all identities from the agent.
.It Fl d .It Fl d
@ -156,6 +155,8 @@ and
.Ev SSH_ASKPASS .Ev SSH_ASKPASS
are set, it will execute the program specified by are set, it will execute the program specified by
.Ev SSH_ASKPASS .Ev SSH_ASKPASS
(by default
.Dq ssh-askpass )
and open an X11 window to read the passphrase. and open an X11 window to read the passphrase.
This is particularly useful when calling This is particularly useful when calling
.Nm .Nm
@ -197,6 +198,7 @@ is unable to contact the authentication agent.
.Sh SEE ALSO .Sh SEE ALSO
.Xr ssh 1 , .Xr ssh 1 ,
.Xr ssh-agent 1 , .Xr ssh-agent 1 ,
.Xr ssh-askpass 1 ,
.Xr ssh-keygen 1 , .Xr ssh-keygen 1 ,
.Xr sshd 8 .Xr sshd 8
.Sh AUTHORS .Sh AUTHORS

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-add.c,v 1.120 2015/02/21 21:46:57 halex Exp $ */ /* $OpenBSD: ssh-add.c,v 1.122 2015/03/26 12:32:38 naddy Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -79,7 +79,9 @@ static char *default_files[] = {
#endif #endif
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
_PATH_SSH_CLIENT_ID_ED25519, _PATH_SSH_CLIENT_ID_ED25519,
#ifdef WITH_SSH1
_PATH_SSH_CLIENT_IDENTITY, _PATH_SSH_CLIENT_IDENTITY,
#endif
NULL NULL
}; };
@ -164,11 +166,10 @@ delete_all(int agent_fd)
{ {
int ret = -1; int ret = -1;
if (ssh_remove_all_identities(agent_fd, 1) == 0) if (ssh_remove_all_identities(agent_fd, 2) == 0)
ret = 0; ret = 0;
/* ignore error-code for ssh2 */ /* ignore error-code for ssh1 */
/* XXX revisit */ ssh_remove_all_identities(agent_fd, 1);
ssh_remove_all_identities(agent_fd, 2);
if (ret == 0) if (ret == 0)
fprintf(stderr, "All identities removed.\n"); fprintf(stderr, "All identities removed.\n");
@ -364,11 +365,16 @@ static int
list_identities(int agent_fd, int do_fp) list_identities(int agent_fd, int do_fp)
{ {
char *fp; char *fp;
int version, r, had_identities = 0; int r, had_identities = 0;
struct ssh_identitylist *idlist; struct ssh_identitylist *idlist;
size_t i; size_t i;
#ifdef WITH_SSH1
int version = 1;
#else
int version = 2;
#endif
for (version = 1; version <= 2; version++) { for (; version <= 2; version++) {
if ((r = ssh_fetch_identitylist(agent_fd, version, if ((r = ssh_fetch_identitylist(agent_fd, version,
&idlist)) != 0) { &idlist)) != 0) {
if (r != SSH_ERR_AGENT_NO_IDENTITIES) if (r != SSH_ERR_AGENT_NO_IDENTITIES)

View file

@ -4,7 +4,7 @@ NAME
ssh-agent M-bM-^@M-^S authentication agent ssh-agent M-bM-^@M-^S authentication agent
SYNOPSIS SYNOPSIS
ssh-agent [-c | -s] [-d] [-a bind_address] [-E fingerprint_hash] ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]
[-t life] [command [arg ...]] [-t life] [command [arg ...]]
ssh-agent [-c | -s] -k ssh-agent [-c | -s] -k
@ -32,8 +32,11 @@ DESCRIPTION
-c Generate C-shell commands on stdout. This is the default if -c Generate C-shell commands on stdout. This is the default if
SHELL looks like it's a csh style of shell. SHELL looks like it's a csh style of shell.
-D Foreground mode. When this option is specified ssh-agent will
not fork.
-d Debug mode. When this option is specified ssh-agent will not -d Debug mode. When this option is specified ssh-agent will not
fork. fork and will write debug information to standard error.
-E fingerprint_hash -E fingerprint_hash
Specifies the hash algorithm used when displaying key Specifies the hash algorithm used when displaying key
@ -106,4 +109,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0. versions 1.5 and 2.0.
OpenBSD 5.7 December 21, 2014 OpenBSD 5.7 OpenBSD 5.7 April 24, 2015 OpenBSD 5.7

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-agent.1,v 1.57 2014/12/21 22:27:56 djm Exp $ .\" $OpenBSD: ssh-agent.1,v 1.59 2015/04/24 06:26:49 jmc Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: December 21 2014 $ .Dd $Mdocdate: April 24 2015 $
.Dt SSH-AGENT 1 .Dt SSH-AGENT 1
.Os .Os
.Sh NAME .Sh NAME
@ -44,7 +44,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm ssh-agent .Nm ssh-agent
.Op Fl c | s .Op Fl c | s
.Op Fl dx .Op Fl Ddx
.Op Fl a Ar bind_address .Op Fl a Ar bind_address
.Op Fl E Ar fingerprint_hash .Op Fl E Ar fingerprint_hash
.Op Fl t Ar life .Op Fl t Ar life
@ -93,11 +93,16 @@ Generate C-shell commands on
This is the default if This is the default if
.Ev SHELL .Ev SHELL
looks like it's a csh style of shell. looks like it's a csh style of shell.
.It Fl D
Foreground mode.
When this option is specified
.Nm
will not fork.
.It Fl d .It Fl d
Debug mode. Debug mode.
When this option is specified When this option is specified
.Nm .Nm
will not fork. will not fork and will write debug information to standard error.
.It Fl E Ar fingerprint_hash .It Fl E Ar fingerprint_hash
Specifies the hash algorithm used when displaying key fingerprints. Specifies the hash algorithm used when displaying key fingerprints.
Valid options are: Valid options are:

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-agent.c,v 1.199 2015/03/04 21:12:59 djm Exp $ */ /* $OpenBSD: ssh-agent.c,v 1.203 2015/05/15 05:44:21 dtucker Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -69,6 +69,9 @@ __RCSID("$FreeBSD$");
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
#include "key.h" /* XXX for typedef */ #include "key.h" /* XXX for typedef */
#include "buffer.h" /* XXX for typedef */ #include "buffer.h" /* XXX for typedef */
@ -141,8 +144,12 @@ char socket_name[PATH_MAX];
char socket_dir[PATH_MAX]; char socket_dir[PATH_MAX];
/* locking */ /* locking */
#define LOCK_SIZE 32
#define LOCK_SALT_SIZE 16
#define LOCK_ROUNDS 1
int locked = 0; int locked = 0;
char *lock_passwd = NULL; char lock_passwd[LOCK_SIZE];
char lock_salt[LOCK_SALT_SIZE];
extern char *__progname; extern char *__progname;
@ -680,23 +687,45 @@ process_add_identity(SocketEntry *e, int version)
static void static void
process_lock_agent(SocketEntry *e, int lock) process_lock_agent(SocketEntry *e, int lock)
{ {
int r, success = 0; int r, success = 0, delay;
char *passwd; char *passwd, passwdhash[LOCK_SIZE];
static u_int fail_count = 0;
size_t pwlen;
if ((r = sshbuf_get_cstring(e->request, &passwd, NULL)) != 0) if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r)); fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { if (pwlen == 0) {
locked = 0; debug("empty password not supported");
explicit_bzero(lock_passwd, strlen(lock_passwd)); } else if (locked && !lock) {
free(lock_passwd); if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
lock_passwd = NULL; passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
success = 1; fatal("bcrypt_pbkdf");
if (timingsafe_bcmp(passwdhash, lock_passwd, LOCK_SIZE) == 0) {
debug("agent unlocked");
locked = 0;
fail_count = 0;
explicit_bzero(lock_passwd, sizeof(lock_passwd));
success = 1;
} else {
/* delay in 0.1s increments up to 10s */
if (fail_count < 100)
fail_count++;
delay = 100000 * fail_count;
debug("unlock failed, delaying %0.1lf seconds",
(double)delay/1000000);
usleep(delay);
}
explicit_bzero(passwdhash, sizeof(passwdhash));
} else if (!locked && lock) { } else if (!locked && lock) {
debug("agent locked");
locked = 1; locked = 1;
lock_passwd = xstrdup(passwd); arc4random_buf(lock_salt, sizeof(lock_salt));
if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
lock_passwd, sizeof(lock_passwd), LOCK_ROUNDS) < 0)
fatal("bcrypt_pbkdf");
success = 1; success = 1;
} }
explicit_bzero(passwd, strlen(passwd)); explicit_bzero(passwd, pwlen);
free(passwd); free(passwd);
send_status(e, success); send_status(e, success);
} }
@ -953,7 +982,7 @@ new_socket(sock_type type, int fd)
} }
old_alloc = sockets_alloc; old_alloc = sockets_alloc;
new_alloc = sockets_alloc + 10; new_alloc = sockets_alloc + 10;
sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0])); sockets = xreallocarray(sockets, new_alloc, sizeof(sockets[0]));
for (i = old_alloc; i < new_alloc; i++) for (i = old_alloc; i < new_alloc; i++)
sockets[i].type = AUTH_UNUSED; sockets[i].type = AUTH_UNUSED;
sockets_alloc = new_alloc; sockets_alloc = new_alloc;
@ -1161,7 +1190,7 @@ static void
usage(void) usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-E fingerprint_hash]\n" "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
" [-t life] [command [arg ...]]\n" " [-t life] [command [arg ...]]\n"
" ssh-agent [-c | -s] -k\n"); " ssh-agent [-c | -s] -k\n");
fprintf(stderr, " -x Exit when the last client disconnects.\n"); fprintf(stderr, " -x Exit when the last client disconnects.\n");
@ -1171,7 +1200,7 @@ usage(void)
int int
main(int ac, char **av) main(int ac, char **av)
{ {
int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
int sock, fd, ch, result, saved_errno; int sock, fd, ch, result, saved_errno;
u_int nalloc; u_int nalloc;
char *shell, *format, *pidstr, *agentsocket = NULL; char *shell, *format, *pidstr, *agentsocket = NULL;
@ -1207,7 +1236,7 @@ main(int ac, char **av)
__progname = ssh_get_progname(av[0]); __progname = ssh_get_progname(av[0]);
seed_rng(); seed_rng();
while ((ch = getopt(ac, av, "cdksE:a:t:x")) != -1) { while ((ch = getopt(ac, av, "cDdksE:a:t:x")) != -1) {
switch (ch) { switch (ch) {
case 'E': case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg); fingerprint_hash = ssh_digest_alg_by_name(optarg);
@ -1228,10 +1257,15 @@ main(int ac, char **av)
s_flag++; s_flag++;
break; break;
case 'd': case 'd':
if (d_flag) if (d_flag || D_flag)
usage(); usage();
d_flag++; d_flag++;
break; break;
case 'D':
if (d_flag || D_flag)
usage();
D_flag++;
break;
case 'a': case 'a':
agentsocket = optarg; agentsocket = optarg;
break; break;
@ -1251,7 +1285,7 @@ main(int ac, char **av)
ac -= optind; ac -= optind;
av += optind; av += optind;
if (ac > 0 && (c_flag || k_flag || s_flag || d_flag)) if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
usage(); usage();
if (ac == 0 && !c_flag && !s_flag) { if (ac == 0 && !c_flag && !s_flag) {
@ -1320,8 +1354,10 @@ main(int ac, char **av)
* Fork, and have the parent execute the command, if any, or present * Fork, and have the parent execute the command, if any, or present
* the socket data. The child continues as the authentication agent. * the socket data. The child continues as the authentication agent.
*/ */
if (d_flag) { if (D_flag || d_flag) {
log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1); log_init(__progname,
d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
SYSLOG_FACILITY_AUTH, 1);
format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
SSH_AUTHSOCKET_ENV_NAME); SSH_AUTHSOCKET_ENV_NAME);
@ -1393,7 +1429,7 @@ main(int ac, char **av)
parent_alive_interval = 10; parent_alive_interval = 10;
idtab_init(); idtab_init();
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
signal(SIGINT, d_flag ? cleanup_handler : SIG_IGN); signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
signal(SIGHUP, cleanup_handler); signal(SIGHUP, cleanup_handler);
signal(SIGTERM, cleanup_handler); signal(SIGTERM, cleanup_handler);
nalloc = 0; nalloc = 0;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.266 2015/02/26 20:45:47 djm Exp $ */ /* $OpenBSD: ssh-keygen.c,v 1.274 2015/05/28 07:37:31 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -58,6 +58,12 @@
#include "krl.h" #include "krl.h"
#include "digest.h" #include "digest.h"
#ifdef WITH_OPENSSL
# define DEFAULT_KEY_TYPE_NAME "rsa"
#else
# define DEFAULT_KEY_TYPE_NAME "ed25519"
#endif
/* Number of bits in the RSA/DSA key. This value can be set on the command line. */ /* Number of bits in the RSA/DSA key. This value can be set on the command line. */
#define DEFAULT_BITS 2048 #define DEFAULT_BITS 2048
#define DEFAULT_BITS_DSA 1024 #define DEFAULT_BITS_DSA 1024
@ -174,23 +180,22 @@ extern char *__progname;
char hostname[NI_MAXHOST]; char hostname[NI_MAXHOST];
#ifdef WITH_OPENSSL
/* moduli.c */ /* moduli.c */
int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
unsigned long); unsigned long);
#endif
static void static void
type_bits_valid(int type, const char *name, u_int32_t *bitsp) type_bits_valid(int type, const char *name, u_int32_t *bitsp)
{ {
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
u_int maxbits; u_int maxbits, nid;
int nid;
#endif #endif
if (type == KEY_UNSPEC) { if (type == KEY_UNSPEC)
fprintf(stderr, "unknown key type %s\n", key_type_name); fatal("unknown key type %s", key_type_name);
exit(1);
}
if (*bitsp == 0) { if (*bitsp == 0) {
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
if (type == KEY_DSA) if (type == KEY_DSA)
@ -208,10 +213,8 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
maxbits = (type == KEY_DSA) ? maxbits = (type == KEY_DSA) ?
OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
if (*bitsp > maxbits) { if (*bitsp > maxbits)
fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); fatal("key bits exceeds maximum %d", maxbits);
exit(1);
}
if (type == KEY_DSA && *bitsp != 1024) if (type == KEY_DSA && *bitsp != 1024)
fatal("DSA keys must be 1024 bits"); fatal("DSA keys must be 1024 bits");
else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768)
@ -256,13 +259,13 @@ ask_filename(struct passwd *pw, const char *prompt)
name = _PATH_SSH_CLIENT_ID_ED25519; name = _PATH_SSH_CLIENT_ID_ED25519;
break; break;
default: default:
fprintf(stderr, "bad key type\n"); fatal("bad key type");
exit(1);
break;
} }
} }
snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name); snprintf(identity_file, sizeof(identity_file),
fprintf(stderr, "%s (%s): ", prompt, identity_file); "%s/%s", pw->pw_dir, name);
printf("%s (%s): ", prompt, identity_file);
fflush(stdout);
if (fgets(buf, sizeof(buf), stdin) == NULL) if (fgets(buf, sizeof(buf), stdin) == NULL)
exit(1); exit(1);
buf[strcspn(buf, "\n")] = '\0'; buf[strcspn(buf, "\n")] = '\0';
@ -308,14 +311,10 @@ do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
char comment[61]; char comment[61];
int r; int r;
if (k->type == KEY_RSA1) { if (k->type == KEY_RSA1)
fprintf(stderr, "version 1 keys are not supported\n"); fatal("version 1 keys are not supported");
exit(1); if ((r = sshkey_to_blob(k, &blob, &len)) != 0)
} fatal("key_to_blob failed: %s", ssh_err(r));
if ((r = sshkey_to_blob(k, &blob, &len)) != 0) {
fprintf(stderr, "key_to_blob failed: %s\n", ssh_err(r));
exit(1);
}
/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
snprintf(comment, sizeof(comment), snprintf(comment, sizeof(comment),
"%u-bit %s, converted by %s@%s from OpenSSH", "%u-bit %s, converted by %s@%s from OpenSSH",
@ -544,17 +543,13 @@ get_line(FILE *fp, char *line, size_t len)
line[0] = '\0'; line[0] = '\0';
while ((c = fgetc(fp)) != EOF) { while ((c = fgetc(fp)) != EOF) {
if (pos >= len - 1) { if (pos >= len - 1)
fprintf(stderr, "input line too long.\n"); fatal("input line too long.");
exit(1);
}
switch (c) { switch (c) {
case '\r': case '\r':
c = fgetc(fp); c = fgetc(fp);
if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) { if (c != EOF && c != '\n' && ungetc(c, fp) == EOF)
fprintf(stderr, "unget: %s\n", strerror(errno)); fatal("unget: %s", strerror(errno));
exit(1);
}
return pos; return pos;
case '\n': case '\n':
return pos; return pos;
@ -606,16 +601,12 @@ do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
(encoded[len-3] == '=')) (encoded[len-3] == '='))
encoded[len-3] = '\0'; encoded[len-3] = '\0';
blen = uudecode(encoded, blob, sizeof(blob)); blen = uudecode(encoded, blob, sizeof(blob));
if (blen < 0) { if (blen < 0)
fprintf(stderr, "uudecode failed.\n"); fatal("uudecode failed.");
exit(1);
}
if (*private) if (*private)
*k = do_convert_private_ssh2_from_blob(blob, blen); *k = do_convert_private_ssh2_from_blob(blob, blen);
else if ((r = sshkey_from_blob(blob, blen, k)) != 0) { else if ((r = sshkey_from_blob(blob, blen, k)) != 0)
fprintf(stderr, "decode blob failed: %s\n", ssh_err(r)); fatal("decode blob failed: %s", ssh_err(r));
exit(1);
}
fclose(fp); fclose(fp);
} }
@ -749,10 +740,8 @@ do_convert_from(struct passwd *pw)
} }
} }
if (!ok) { if (!ok)
fprintf(stderr, "key write failed\n"); fatal("key write failed");
exit(1);
}
sshkey_free(k); sshkey_free(k);
exit(0); exit(0);
} }
@ -767,13 +756,11 @@ do_print_public(struct passwd *pw)
if (!have_identity) if (!have_identity)
ask_filename(pw, "Enter file in which the key is"); ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) < 0) { if (stat(identity_file, &st) < 0)
perror(identity_file); fatal("%s: %s", identity_file, strerror(errno));
exit(1);
}
prv = load_identity(identity_file); prv = load_identity(identity_file);
if ((r = sshkey_write(prv, stdout)) != 0) if ((r = sshkey_write(prv, stdout)) != 0)
fprintf(stderr, "key_write failed: %s", ssh_err(r)); error("key_write failed: %s", ssh_err(r));
sshkey_free(prv); sshkey_free(prv);
fprintf(stdout, "\n"); fprintf(stdout, "\n");
exit(0); exit(0);
@ -838,10 +825,8 @@ do_fingerprint(struct passwd *pw)
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
if (!have_identity) if (!have_identity)
ask_filename(pw, "Enter file in which the key is"); ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) < 0) { if (stat(identity_file, &st) < 0)
perror(identity_file); fatal("%s: %s", identity_file, strerror(errno));
exit(1);
}
if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0) if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0)
debug2("Error loading public key \"%s\": %s", debug2("Error loading public key \"%s\": %s",
identity_file, ssh_err(r)); identity_file, ssh_err(r));
@ -933,10 +918,8 @@ do_fingerprint(struct passwd *pw)
} }
fclose(f); fclose(f);
if (invalid) { if (invalid)
printf("%s is not a public key file.\n", identity_file); fatal("%s is not a public key file.", identity_file);
exit(1);
}
exit(0); exit(0);
} }
@ -948,12 +931,16 @@ do_gen_all_hostkeys(struct passwd *pw)
char *key_type_display; char *key_type_display;
char *path; char *path;
} key_types[] = { } key_types[] = {
#ifdef WITH_OPENSSL
#ifdef WITH_SSH1
{ "rsa1", "RSA1", _PATH_HOST_KEY_FILE }, { "rsa1", "RSA1", _PATH_HOST_KEY_FILE },
#endif /* WITH_SSH1 */
{ "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
{ "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE }, { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },
#ifdef OPENSSL_HAS_ECC #ifdef OPENSSL_HAS_ECC
{ "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE }, { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
#endif #endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
{ "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE }, { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE },
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}; };
@ -969,7 +956,7 @@ do_gen_all_hostkeys(struct passwd *pw)
if (stat(key_types[i].path, &st) == 0) if (stat(key_types[i].path, &st) == 0)
continue; continue;
if (errno != ENOENT) { if (errno != ENOENT) {
printf("Could not stat %s: %s", key_types[i].path, error("Could not stat %s: %s", key_types[i].path,
strerror(errno)); strerror(errno));
first = 0; first = 0;
continue; continue;
@ -986,8 +973,7 @@ do_gen_all_hostkeys(struct passwd *pw)
bits = 0; bits = 0;
type_bits_valid(type, NULL, &bits); type_bits_valid(type, NULL, &bits);
if ((r = sshkey_generate(type, bits, &private)) != 0) { if ((r = sshkey_generate(type, bits, &private)) != 0) {
fprintf(stderr, "key_generate failed: %s\n", error("key_generate failed: %s", ssh_err(r));
ssh_err(r));
first = 0; first = 0;
continue; continue;
} }
@ -997,8 +983,8 @@ do_gen_all_hostkeys(struct passwd *pw)
hostname); hostname);
if ((r = sshkey_save_private(private, identity_file, "", if ((r = sshkey_save_private(private, identity_file, "",
comment, use_new_format, new_format_cipher, rounds)) != 0) { comment, use_new_format, new_format_cipher, rounds)) != 0) {
printf("Saving key \"%s\" failed: %s\n", identity_file, error("Saving key \"%s\" failed: %s",
ssh_err(r)); identity_file, ssh_err(r));
sshkey_free(private); sshkey_free(private);
sshkey_free(public); sshkey_free(public);
first = 0; first = 0;
@ -1008,7 +994,7 @@ do_gen_all_hostkeys(struct passwd *pw)
strlcat(identity_file, ".pub", sizeof(identity_file)); strlcat(identity_file, ".pub", sizeof(identity_file));
fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) { if (fd == -1) {
printf("Could not save your public key in %s\n", error("Could not save your public key in %s",
identity_file); identity_file);
sshkey_free(public); sshkey_free(public);
first = 0; first = 0;
@ -1016,14 +1002,14 @@ do_gen_all_hostkeys(struct passwd *pw)
} }
f = fdopen(fd, "w"); f = fdopen(fd, "w");
if (f == NULL) { if (f == NULL) {
printf("fdopen %s failed\n", identity_file); error("fdopen %s failed", identity_file);
close(fd); close(fd);
sshkey_free(public); sshkey_free(public);
first = 0; first = 0;
continue; continue;
} }
if ((r = sshkey_write(public, f)) != 0) { if ((r = sshkey_write(public, f)) != 0) {
fprintf(stderr, "write key failed: %s\n", ssh_err(r)); error("write key failed: %s", ssh_err(r));
fclose(f); fclose(f);
sshkey_free(public); sshkey_free(public);
first = 0; first = 0;
@ -1064,8 +1050,8 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
has_wild || l->marker != MRK_NONE) { has_wild || l->marker != MRK_NONE) {
fprintf(ctx->out, "%s\n", l->line); fprintf(ctx->out, "%s\n", l->line);
if (has_wild && !find_host) { if (has_wild && !find_host) {
fprintf(stderr, "%s:%ld: ignoring host name " logit("%s:%ld: ignoring host name "
"with wildcard: %.64s\n", l->path, "with wildcard: %.64s", l->path,
l->linenum, l->hosts); l->linenum, l->hosts);
} }
return 0; return 0;
@ -1086,7 +1072,7 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
case HKF_STATUS_INVALID: case HKF_STATUS_INVALID:
/* Retain invalid lines, but mark file as invalid. */ /* Retain invalid lines, but mark file as invalid. */
ctx->invalid = 1; ctx->invalid = 1;
fprintf(stderr, "%s:%ld: invalid line\n", l->path, l->linenum); logit("%s:%ld: invalid line", l->path, l->linenum);
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
fprintf(ctx->out, "%s\n", l->line); fprintf(ctx->out, "%s\n", l->line);
@ -1100,6 +1086,12 @@ static int
known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
{ {
struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
enum sshkey_fp_rep rep;
int fptype;
char *fp;
fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
if (l->status == HKF_STATUS_MATCHED) { if (l->status == HKF_STATUS_MATCHED) {
if (delete_host) { if (delete_host) {
@ -1128,7 +1120,12 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
} }
if (hash_hosts) if (hash_hosts)
known_hosts_hash(l, ctx); known_hosts_hash(l, ctx);
else else if (print_fingerprint) {
fp = sshkey_fingerprint(l->key, fptype, rep);
printf("%s %s %s %s\n", ctx->host,
sshkey_type(l->key), fp, l->comment);
free(fp);
} else
fprintf(ctx->out, "%s\n", l->line); fprintf(ctx->out, "%s\n", l->line);
return 0; return 0;
} }
@ -1136,8 +1133,7 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
/* Retain non-matching hosts when deleting */ /* Retain non-matching hosts when deleting */
if (l->status == HKF_STATUS_INVALID) { if (l->status == HKF_STATUS_INVALID) {
ctx->invalid = 1; ctx->invalid = 1;
fprintf(stderr, "%s:%ld: invalid line\n", logit("%s:%ld: invalid line", l->path, l->linenum);
l->path, l->linenum);
} }
fprintf(ctx->out, "%s\n", l->line); fprintf(ctx->out, "%s\n", l->line);
} }
@ -1150,6 +1146,7 @@ do_known_hosts(struct passwd *pw, const char *name)
char *cp, tmp[PATH_MAX], old[PATH_MAX]; char *cp, tmp[PATH_MAX], old[PATH_MAX];
int r, fd, oerrno, inplace = 0; int r, fd, oerrno, inplace = 0;
struct known_hosts_ctx ctx; struct known_hosts_ctx ctx;
u_int foreach_options;
if (!have_identity) { if (!have_identity) {
cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
@ -1186,26 +1183,26 @@ do_known_hosts(struct passwd *pw, const char *name)
} }
/* XXX support identity_file == "-" for stdin */ /* XXX support identity_file == "-" for stdin */
foreach_options = find_host ? HKF_WANT_MATCH : 0;
foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0;
if ((r = hostkeys_foreach(identity_file, if ((r = hostkeys_foreach(identity_file,
hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx, hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx,
name, NULL, find_host ? HKF_WANT_MATCH : 0)) != 0) name, NULL, foreach_options)) != 0)
fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
if (inplace) if (inplace)
fclose(ctx.out); fclose(ctx.out);
if (ctx.invalid) { if (ctx.invalid) {
fprintf(stderr, "%s is not a valid known_hosts file.\n", error("%s is not a valid known_hosts file.", identity_file);
identity_file);
if (inplace) { if (inplace) {
fprintf(stderr, "Not replacing existing known_hosts " error("Not replacing existing known_hosts "
"file because of errors\n"); "file because of errors");
unlink(tmp); unlink(tmp);
} }
exit(1); exit(1);
} else if (delete_host && !ctx.found_key) { } else if (delete_host && !ctx.found_key) {
fprintf(stderr, "Host %s not found in %s\n", logit("Host %s not found in %s", name, identity_file);
name, identity_file);
unlink(tmp); unlink(tmp);
} else if (inplace) { } else if (inplace) {
/* Backup existing file */ /* Backup existing file */
@ -1223,13 +1220,12 @@ do_known_hosts(struct passwd *pw, const char *name)
exit(1); exit(1);
} }
fprintf(stderr, "%s updated.\n", identity_file); printf("%s updated.\n", identity_file);
fprintf(stderr, "Original contents retained as %s\n", old); printf("Original contents retained as %s\n", old);
if (ctx.has_unhashed) { if (ctx.has_unhashed) {
fprintf(stderr, "WARNING: %s contains unhashed " logit("WARNING: %s contains unhashed entries", old);
"entries\n", old); logit("Delete this file to ensure privacy "
fprintf(stderr, "Delete this file to ensure privacy " "of hostnames");
"of hostnames\n");
} }
} }
@ -1251,10 +1247,8 @@ do_change_passphrase(struct passwd *pw)
if (!have_identity) if (!have_identity)
ask_filename(pw, "Enter file in which the key is"); ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) < 0) { if (stat(identity_file, &st) < 0)
perror(identity_file); fatal("%s: %s", identity_file, strerror(errno));
exit(1);
}
/* Try to load the file with empty passphrase. */ /* Try to load the file with empty passphrase. */
r = sshkey_load_private(identity_file, "", &private, &comment); r = sshkey_load_private(identity_file, "", &private, &comment);
if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) { if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
@ -1272,9 +1266,7 @@ do_change_passphrase(struct passwd *pw)
goto badkey; goto badkey;
} else if (r != 0) { } else if (r != 0) {
badkey: badkey:
fprintf(stderr, "Failed to load key \"%s\": %s\n", fatal("Failed to load key %s: %s", identity_file, ssh_err(r));
identity_file, ssh_err(r));
exit(1);
} }
if (comment) if (comment)
printf("Key has comment '%s'\n", comment); printf("Key has comment '%s'\n", comment);
@ -1307,7 +1299,7 @@ do_change_passphrase(struct passwd *pw)
/* Save the file using the new passphrase. */ /* Save the file using the new passphrase. */
if ((r = sshkey_save_private(private, identity_file, passphrase1, if ((r = sshkey_save_private(private, identity_file, passphrase1,
comment, use_new_format, new_format_cipher, rounds)) != 0) { comment, use_new_format, new_format_cipher, rounds)) != 0) {
printf("Saving key \"%s\" failed: %s.\n", error("Saving key \"%s\" failed: %s.",
identity_file, ssh_err(r)); identity_file, ssh_err(r));
explicit_bzero(passphrase1, strlen(passphrase1)); explicit_bzero(passphrase1, strlen(passphrase1));
free(passphrase1); free(passphrase1);
@ -1341,14 +1333,11 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname)
if (stat(fname, &st) < 0) { if (stat(fname, &st) < 0) {
if (errno == ENOENT) if (errno == ENOENT)
return 0; return 0;
perror(fname); fatal("%s: %s", fname, strerror(errno));
exit(1);
} }
if ((r = sshkey_load_public(fname, &public, &comment)) != 0) { if ((r = sshkey_load_public(fname, &public, &comment)) != 0)
printf("Failed to read v2 public key from \"%s\": %s.\n", fatal("Failed to read v2 public key from \"%s\": %s.",
fname, ssh_err(r)); fname, ssh_err(r));
exit(1);
}
export_dns_rr(hname, public, stdout, print_generic); export_dns_rr(hname, public, stdout, print_generic);
sshkey_free(public); sshkey_free(public);
free(comment); free(comment);
@ -1370,18 +1359,15 @@ do_change_comment(struct passwd *pw)
if (!have_identity) if (!have_identity)
ask_filename(pw, "Enter file in which the key is"); ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) < 0) { if (stat(identity_file, &st) < 0)
perror(identity_file); fatal("%s: %s", identity_file, strerror(errno));
exit(1);
}
if ((r = sshkey_load_private(identity_file, "", if ((r = sshkey_load_private(identity_file, "",
&private, &comment)) == 0) &private, &comment)) == 0)
passphrase = xstrdup(""); passphrase = xstrdup("");
else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) { else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
printf("Cannot load private key \"%s\": %s.\n", fatal("Cannot load private key \"%s\": %s.",
identity_file, ssh_err(r)); identity_file, ssh_err(r));
exit(1); else {
} else {
if (identity_passphrase) if (identity_passphrase)
passphrase = xstrdup(identity_passphrase); passphrase = xstrdup(identity_passphrase);
else if (identity_new_passphrase) else if (identity_new_passphrase)
@ -1394,13 +1380,14 @@ do_change_comment(struct passwd *pw)
&private, &comment)) != 0) { &private, &comment)) != 0) {
explicit_bzero(passphrase, strlen(passphrase)); explicit_bzero(passphrase, strlen(passphrase));
free(passphrase); free(passphrase);
printf("Cannot load private key \"%s\": %s.\n", fatal("Cannot load private key \"%s\": %s.",
identity_file, ssh_err(r)); identity_file, ssh_err(r));
exit(1);
} }
} }
/* XXX what about new-format keys? */
if (private->type != KEY_RSA1) { if (private->type != KEY_RSA1) {
fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); error("Comments are only supported for RSA1 keys.");
explicit_bzero(passphrase, strlen(passphrase));
sshkey_free(private); sshkey_free(private);
exit(1); exit(1);
} }
@ -1422,7 +1409,7 @@ do_change_comment(struct passwd *pw)
/* Save the file using the new passphrase. */ /* Save the file using the new passphrase. */
if ((r = sshkey_save_private(private, identity_file, passphrase, if ((r = sshkey_save_private(private, identity_file, passphrase,
new_comment, use_new_format, new_format_cipher, rounds)) != 0) { new_comment, use_new_format, new_format_cipher, rounds)) != 0) {
printf("Saving key \"%s\" failed: %s\n", error("Saving key \"%s\" failed: %s",
identity_file, ssh_err(r)); identity_file, ssh_err(r));
explicit_bzero(passphrase, strlen(passphrase)); explicit_bzero(passphrase, strlen(passphrase));
free(passphrase); free(passphrase);
@ -1438,17 +1425,13 @@ do_change_comment(struct passwd *pw)
strlcat(identity_file, ".pub", sizeof(identity_file)); strlcat(identity_file, ".pub", sizeof(identity_file));
fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) { if (fd == -1)
printf("Could not save your public key in %s\n", identity_file); fatal("Could not save your public key in %s", identity_file);
exit(1);
}
f = fdopen(fd, "w"); f = fdopen(fd, "w");
if (f == NULL) { if (f == NULL)
printf("fdopen %s failed\n", identity_file); fatal("fdopen %s failed: %s", identity_file, strerror(errno));
exit(1);
}
if ((r = sshkey_write(public, f)) != 0) if ((r = sshkey_write(public, f)) != 0)
fprintf(stderr, "write key failed: %s\n", ssh_err(r)); fatal("write key failed: %s", ssh_err(r));
sshkey_free(public); sshkey_free(public);
fprintf(f, " %s\n", new_comment); fprintf(f, " %s\n", new_comment);
fclose(f); fclose(f);
@ -1608,8 +1591,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
break; break;
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
fprintf(stderr, "unknown key type %s\n", key_type_name); fatal("unknown key type %s", key_type_name);
exit(1);
} }
} }
@ -1631,7 +1613,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
otmp = tmp = xstrdup(cert_principals); otmp = tmp = xstrdup(cert_principals);
plist = NULL; plist = NULL;
for (; (cp = strsep(&tmp, ",")) != NULL; n++) { for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
plist = xrealloc(plist, n + 1, sizeof(*plist)); plist = xreallocarray(plist, n + 1, sizeof(*plist));
if (*(plist[n] = xstrdup(cp)) == '\0') if (*(plist[n] = xstrdup(cp)) == '\0')
fatal("Empty principal name"); fatal("Empty principal name");
} }
@ -2216,9 +2198,11 @@ usage(void)
" ssh-keygen -H [-f known_hosts_file]\n" " ssh-keygen -H [-f known_hosts_file]\n"
" ssh-keygen -R hostname [-f known_hosts_file]\n" " ssh-keygen -R hostname [-f known_hosts_file]\n"
" ssh-keygen -r hostname [-f input_keyfile] [-g]\n" " ssh-keygen -r hostname [-f input_keyfile] [-g]\n"
#ifdef WITH_OPENSSL
" ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n" " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n"
" ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n" " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"
" [-j start_line] [-K checkpt] [-W generator]\n" " [-j start_line] [-K checkpt] [-W generator]\n"
#endif
" ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n" " ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n"
" [-O option] [-V validity_interval] [-z serial_number] file ...\n" " [-O option] [-V validity_interval] [-z serial_number] file ...\n"
" ssh-keygen -L [-f input_keyfile]\n" " ssh-keygen -L [-f input_keyfile]\n"
@ -2236,19 +2220,22 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2; char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2;
char *checkpoint = NULL; char *rr_hostname = NULL, *ep, *fp, *ra;
char out_file[PATH_MAX], *rr_hostname = NULL, *ep, *fp, *ra;
struct sshkey *private, *public; struct sshkey *private, *public;
struct passwd *pw; struct passwd *pw;
struct stat st; struct stat st;
int r, opt, type, fd; int r, opt, type, fd;
u_int32_t memory = 0, generator_wanted = 0;
int do_gen_candidates = 0, do_screen_candidates = 0;
int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
unsigned long start_lineno = 0, lines_to_process = 0;
BIGNUM *start = NULL;
FILE *f; FILE *f;
const char *errstr; const char *errstr;
#ifdef WITH_OPENSSL
/* Moduli generation/screening */
char out_file[PATH_MAX], *checkpoint = NULL;
u_int32_t memory = 0, generator_wanted = 0;
int do_gen_candidates = 0, do_screen_candidates = 0;
unsigned long start_lineno = 0, lines_to_process = 0;
BIGNUM *start = NULL;
#endif
extern int optind; extern int optind;
extern char *optarg; extern char *optarg;
@ -2267,14 +2254,10 @@ main(int argc, char **argv)
/* we need this for the home * directory. */ /* we need this for the home * directory. */
pw = getpwuid(getuid()); pw = getpwuid(getuid());
if (!pw) { if (!pw)
printf("No user exists for uid %lu\n", (u_long)getuid()); fatal("No user exists for uid %lu", (u_long)getuid());
exit(1); if (gethostname(hostname, sizeof(hostname)) < 0)
} fatal("gethostname: %s", strerror(errno));
if (gethostname(hostname, sizeof(hostname)) < 0) {
perror("gethostname");
exit(1);
}
/* Remaining characters: UYdw */ /* Remaining characters: UYdw */
while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy"
@ -2305,12 +2288,6 @@ main(int argc, char **argv)
case 'I': case 'I':
cert_key_id = optarg; cert_key_id = optarg;
break; break;
case 'J':
lines_to_process = strtoul(optarg, NULL, 10);
break;
case 'j':
start_lineno = strtoul(optarg, NULL, 10);
break;
case 'R': case 'R':
delete_host = 1; delete_host = 1;
rr_hostname = optarg; rr_hostname = optarg;
@ -2352,8 +2329,8 @@ main(int argc, char **argv)
change_comment = 1; change_comment = 1;
break; break;
case 'f': case 'f':
if (strlcpy(identity_file, optarg, sizeof(identity_file)) >= if (strlcpy(identity_file, optarg,
sizeof(identity_file)) sizeof(identity_file)) >= sizeof(identity_file))
fatal("Identity filename too long"); fatal("Identity filename too long");
have_identity = 1; have_identity = 1;
break; break;
@ -2425,6 +2402,24 @@ main(int argc, char **argv)
case 'r': case 'r':
rr_hostname = optarg; rr_hostname = optarg;
break; break;
case 'a':
rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr)
fatal("Invalid number: %s (%s)",
optarg, errstr);
break;
case 'V':
parse_cert_times(optarg);
break;
case 'z':
errno = 0;
cert_serial = strtoull(optarg, &ep, 10);
if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
(errno == ERANGE && cert_serial == ULLONG_MAX))
fatal("Invalid serial number \"%s\"", optarg);
break;
#ifdef WITH_OPENSSL
/* Moduli generation/screening */
case 'W': case 'W':
generator_wanted = (u_int32_t)strtonum(optarg, 1, generator_wanted = (u_int32_t)strtonum(optarg, 1,
UINT_MAX, &errstr); UINT_MAX, &errstr);
@ -2432,13 +2427,6 @@ main(int argc, char **argv)
fatal("Desired generator has bad value: %s (%s)", fatal("Desired generator has bad value: %s (%s)",
optarg, errstr); optarg, errstr);
break; break;
case 'a':
rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr)
fatal("Invalid number: %s (%s)",
optarg, errstr);
break;
#ifdef WITH_OPENSSL
case 'M': case 'M':
memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
if (errstr) if (errstr)
@ -2467,16 +2455,6 @@ main(int argc, char **argv)
fatal("Invalid start point."); fatal("Invalid start point.");
break; break;
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
case 'V':
parse_cert_times(optarg);
break;
case 'z':
errno = 0;
cert_serial = strtoull(optarg, &ep, 10);
if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
(errno == ERANGE && cert_serial == ULLONG_MAX))
fatal("Invalid serial number \"%s\"", optarg);
break;
case '?': case '?':
default: default:
usage(); usage();
@ -2491,19 +2469,19 @@ main(int argc, char **argv)
if (ca_key_path != NULL) { if (ca_key_path != NULL) {
if (argc < 1 && !gen_krl) { if (argc < 1 && !gen_krl) {
printf("Too few arguments.\n"); error("Too few arguments.");
usage(); usage();
} }
} else if (argc > 0 && !gen_krl && !check_krl) { } else if (argc > 0 && !gen_krl && !check_krl) {
printf("Too many arguments.\n"); error("Too many arguments.");
usage(); usage();
} }
if (change_passphrase && change_comment) { if (change_passphrase && change_comment) {
printf("Can only have one of -p and -c.\n"); error("Can only have one of -p and -c.");
usage(); usage();
} }
if (print_fingerprint && (delete_host || hash_hosts)) { if (print_fingerprint && (delete_host || hash_hosts)) {
printf("Cannot use -l with -H or -R.\n"); error("Cannot use -l with -H or -R.");
usage(); usage();
} }
if (gen_krl) { if (gen_krl) {
@ -2545,10 +2523,8 @@ main(int argc, char **argv)
if (have_identity) { if (have_identity) {
n = do_print_resource_record(pw, n = do_print_resource_record(pw,
identity_file, rr_hostname); identity_file, rr_hostname);
if (n == 0) { if (n == 0)
perror(identity_file); fatal("%s: %s", identity_file, strerror(errno));
exit(1);
}
exit(0); exit(0);
} else { } else {
@ -2566,6 +2542,7 @@ main(int argc, char **argv)
} }
} }
#ifdef WITH_OPENSSL
if (do_gen_candidates) { if (do_gen_candidates) {
FILE *out = fopen(out_file, "w"); FILE *out = fopen(out_file, "w");
@ -2605,6 +2582,7 @@ main(int argc, char **argv)
fatal("modulus screening failed"); fatal("modulus screening failed");
return (0); return (0);
} }
#endif
if (gen_all_hostkeys) { if (gen_all_hostkeys) {
do_gen_all_hostkeys(pw); do_gen_all_hostkeys(pw);
@ -2612,7 +2590,7 @@ main(int argc, char **argv)
} }
if (key_type_name == NULL) if (key_type_name == NULL)
key_type_name = "rsa"; key_type_name = DEFAULT_KEY_TYPE_NAME;
type = sshkey_type_from_name(key_type_name); type = sshkey_type_from_name(key_type_name);
type_bits_valid(type, key_type_name, &bits); type_bits_valid(type, key_type_name, &bits);
@ -2620,14 +2598,10 @@ main(int argc, char **argv)
if (!quiet) if (!quiet)
printf("Generating public/private %s key pair.\n", printf("Generating public/private %s key pair.\n",
key_type_name); key_type_name);
if ((r = sshkey_generate(type, bits, &private)) != 0) { if ((r = sshkey_generate(type, bits, &private)) != 0)
fprintf(stderr, "key_generate failed\n"); fatal("key_generate failed");
exit(1); if ((r = sshkey_from_private(private, &public)) != 0)
} fatal("key_from_private failed: %s\n", ssh_err(r));
if ((r = sshkey_from_private(private, &public)) != 0) {
fprintf(stderr, "key_from_private failed: %s\n", ssh_err(r));
exit(1);
}
if (!have_identity) if (!have_identity)
ask_filename(pw, "Enter file in which to save the key"); ask_filename(pw, "Enter file in which to save the key");
@ -2697,7 +2671,7 @@ main(int argc, char **argv)
/* Save the key with the given passphrase and comment. */ /* Save the key with the given passphrase and comment. */
if ((r = sshkey_save_private(private, identity_file, passphrase1, if ((r = sshkey_save_private(private, identity_file, passphrase1,
comment, use_new_format, new_format_cipher, rounds)) != 0) { comment, use_new_format, new_format_cipher, rounds)) != 0) {
printf("Saving key \"%s\" failed: %s\n", error("Saving key \"%s\" failed: %s",
identity_file, ssh_err(r)); identity_file, ssh_err(r));
explicit_bzero(passphrase1, strlen(passphrase1)); explicit_bzero(passphrase1, strlen(passphrase1));
free(passphrase1); free(passphrase1);
@ -2714,18 +2688,13 @@ main(int argc, char **argv)
printf("Your identification has been saved in %s.\n", identity_file); printf("Your identification has been saved in %s.\n", identity_file);
strlcat(identity_file, ".pub", sizeof(identity_file)); strlcat(identity_file, ".pub", sizeof(identity_file));
fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
if (fd == -1) { fatal("Unable to save public key to %s: %s",
printf("Could not save your public key in %s\n", identity_file); identity_file, strerror(errno));
exit(1); if ((f = fdopen(fd, "w")) == NULL)
} fatal("fdopen %s failed: %s", identity_file, strerror(errno));
f = fdopen(fd, "w");
if (f == NULL) {
printf("fdopen %s failed\n", identity_file);
exit(1);
}
if ((r = sshkey_write(public, f)) != 0) if ((r = sshkey_write(public, f)) != 0)
fprintf(stderr, "write key failed: %s\n", ssh_err(r)); error("write key failed: %s", ssh_err(r));
fprintf(f, " %s\n", comment); fprintf(f, " %s\n", comment);
fclose(f); fclose(f);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.99 2015/01/30 10:44:49 djm Exp $ */ /* $OpenBSD: ssh-keyscan.c,v 1.101 2015/04/10 00:08:55 djm Exp $ */
/* /*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
* *
@ -94,7 +94,7 @@ typedef struct Connection {
int c_len; /* Total bytes which must be read. */ int c_len; /* Total bytes which must be read. */
int c_off; /* Length of data read so far. */ int c_off; /* Length of data read so far. */
int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */ int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */
int c_done; /* SSH2 done */ sig_atomic_t c_done; /* SSH2 done */
char *c_namebase; /* Address to free for c_name and c_namelist */ char *c_namebase; /* Address to free for c_name and c_namelist */
char *c_name; /* Hostname of connection for errors */ char *c_name; /* Hostname of connection for errors */
char *c_namelist; /* Pointer to other possible addresses */ char *c_namelist; /* Pointer to other possible addresses */
@ -299,15 +299,18 @@ static void
keyprint(con *c, struct sshkey *key) keyprint(con *c, struct sshkey *key)
{ {
char *host = c->c_output_name ? c->c_output_name : c->c_name; char *host = c->c_output_name ? c->c_output_name : c->c_name;
char *hostport = NULL;
if (!key) if (!key)
return; return;
if (hash_hosts && (host = host_hash(host, NULL, 0)) == NULL) if (hash_hosts && (host = host_hash(host, NULL, 0)) == NULL)
fatal("host_hash failed"); fatal("host_hash failed");
fprintf(stdout, "%s ", host); hostport = put_host_port(host, ssh_port);
fprintf(stdout, "%s ", hostport);
sshkey_write(key, stdout); sshkey_write(key, stdout);
fputs("\n", stdout); fputs("\n", stdout);
free(hostport);
} }
static int static int
@ -488,7 +491,7 @@ congreet(int s)
confree(s); confree(s);
return; return;
} }
fprintf(stderr, "# %s %s\n", c->c_name, chop(buf)); fprintf(stderr, "# %s:%d %s\n", c->c_name, ssh_port, chop(buf));
n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2,
c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2); c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keysign.c,v 1.47 2015/01/28 22:36:00 djm Exp $ */ /* $OpenBSD: ssh-keysign.c,v 1.48 2015/03/24 20:09:11 markus Exp $ */
/* /*
* Copyright (c) 2002 Markus Friedl. All rights reserved. * Copyright (c) 2002 Markus Friedl. All rights reserved.
* *
@ -157,7 +157,7 @@ valid_request(struct passwd *pw, char *host, struct sshkey **ret,
if (fail && key != NULL) if (fail && key != NULL)
sshkey_free(key); sshkey_free(key);
else else if (ret != NULL)
*ret = key; *ret = key;
return (fail ? -1 : 0); return (fail ? -1 : 0);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-pkcs11.c,v 1.17 2015/02/03 08:07:20 deraadt Exp $ */ /* $OpenBSD: ssh-pkcs11.c,v 1.19 2015/05/27 05:15:02 djm Exp $ */
/* /*
* Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2010 Markus Friedl. All rights reserved.
* *
@ -237,7 +237,7 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
{CKA_ID, NULL, 0}, {CKA_ID, NULL, 0},
{CKA_SIGN, NULL, sizeof(true_val) } {CKA_SIGN, NULL, sizeof(true_val) }
}; };
char *pin, prompt[1024]; char *pin = NULL, prompt[1024];
int rval = -1; int rval = -1;
key_filter[0].pValue = &private_key_class; key_filter[0].pValue = &private_key_class;
@ -255,22 +255,30 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
si = &k11->provider->slotinfo[k11->slotidx]; si = &k11->provider->slotinfo[k11->slotidx];
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
if (!pkcs11_interactive) { if (!pkcs11_interactive) {
error("need pin"); error("need pin entry%s", (si->token.flags &
CKF_PROTECTED_AUTHENTICATION_PATH) ?
" on reader keypad" : "");
return (-1); return (-1);
} }
snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
si->token.label); verbose("Deferring PIN entry to reader keypad.");
pin = read_passphrase(prompt, RP_ALLOW_EOF); else {
if (pin == NULL) snprintf(prompt, sizeof(prompt),
return (-1); /* bail out */ "Enter PIN for '%s': ", si->token.label);
rv = f->C_Login(si->session, CKU_USER, pin = read_passphrase(prompt, RP_ALLOW_EOF);
(u_char *)pin, strlen(pin)); if (pin == NULL)
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { return (-1); /* bail out */
}
rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
(pin != NULL) ? strlen(pin) : 0);
if (pin != NULL) {
explicit_bzero(pin, strlen(pin));
free(pin); free(pin);
}
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
error("C_Login failed: %lu", rv); error("C_Login failed: %lu", rv);
return (-1); return (-1);
} }
free(pin);
si->logged_in = 1; si->logged_in = 1;
} }
key_filter[1].pValue = k11->keyid; key_filter[1].pValue = k11->keyid;
@ -527,7 +535,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
sshkey_free(key); sshkey_free(key);
} else { } else {
/* expand key array and add key */ /* expand key array and add key */
*keysp = xrealloc(*keysp, *nkeys + 1, *keysp = xreallocarray(*keysp, *nkeys + 1,
sizeof(struct sshkey *)); sizeof(struct sshkey *));
(*keysp)[*nkeys] = key; (*keysp)[*nkeys] = key;
*nkeys = *nkeys + 1; *nkeys = *nkeys + 1;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-rsa.c,v 1.52 2014/06/24 01:13:21 djm Exp $ */ /* $OpenBSD: ssh-rsa.c,v 1.53 2015/06/15 01:32:50 djm Exp $ */
/* /*
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
* *
@ -113,7 +113,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
} }
if (b != NULL) if (b != NULL)
sshbuf_free(b); sshbuf_free(b);
return 0; return ret;
} }
int int

View file

@ -354,9 +354,9 @@ DESCRIPTION
applications (eg. sftp(1)). The subsystem is specified as the applications (eg. sftp(1)). The subsystem is specified as the
remote command. remote command.
-T Disable pseudo-tty allocation. -T Disable pseudo-terminal allocation.
-t Force pseudo-tty allocation. This can be used to execute -t Force pseudo-terminal allocation. This can be used to execute
arbitrary screen-based programs on a remote machine, which can be arbitrary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty. options force tty allocation, even if ssh has no local tty.
@ -510,17 +510,22 @@ AUTHENTICATION
whose host key is not known or has changed. whose host key is not known or has changed.
When the user's identity has been accepted by the server, the server When the user's identity has been accepted by the server, the server
either executes the given command, or logs into the machine and gives the either executes the given command in a non-interactive session or, if no
user a normal shell on the remote machine. All communication with the command has been specified, logs into the machine and gives the user a
normal shell as an interactive session. All communication with the
remote command or shell will be automatically encrypted. remote command or shell will be automatically encrypted.
If a pseudo-terminal has been allocated (normal login session), the user If an interactive session is requested ssh by default will only request a
may use the escape characters noted below. pseudo-terminal (pty) for interactive sessions when the client has one.
The flags -T and -t can be used to override this behaviour.
If no pseudo-tty has been allocated, the session is transparent and can If a pseudo-terminal has been allocated the user may use the escape
be used to reliably transfer binary data. On most systems, setting the characters noted below.
escape character to M-bM-^@M-^\noneM-bM-^@M-^] will also make the session transparent even if
a tty is used. If no pseudo-terminal has been allocated, the session is transparent and
can be used to reliably transfer binary data. On most systems, setting
the escape character to M-bM-^@M-^\noneM-bM-^@M-^] will also make the session transparent
even if a tty is used.
The session terminates when the command or shell on the remote machine The session terminates when the command or shell on the remote machine
exits and all X11 and TCP connections have been closed. exits and all X11 and TCP connections have been closed.
@ -638,16 +643,20 @@ VERIFYING HOST KEYS
$ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key
If the fingerprint is already known, it can be matched and the key can be If the fingerprint is already known, it can be matched and the key can be
accepted or rejected. Because of the difficulty of comparing host keys accepted or rejected. If only legacy (MD5) fingerprints for the server
just by looking at fingerprint strings, there is also support to compare are available, the ssh-keygen(1) -E option may be used to downgrade the
host keys visually, using random art. By setting the VisualHostKey fingerprint algorithm to match.
option to M-bM-^@M-^\yesM-bM-^@M-^], a small ASCII graphic gets displayed on every login to a
server, no matter if the session itself is interactive or not. By Because of the difficulty of comparing host keys just by looking at
learning the pattern a known server produces, a user can easily find out fingerprint strings, there is also support to compare host keys visually,
that the host key has changed when a completely different pattern is using random art. By setting the VisualHostKey option to M-bM-^@M-^\yesM-bM-^@M-^], a small
displayed. Because these patterns are not unambiguous however, a pattern ASCII graphic gets displayed on every login to a server, no matter if the
that looks similar to the pattern remembered only gives a good session itself is interactive or not. By learning the pattern a known
probability that the host key is the same, not guaranteed proof. server produces, a user can easily find out that the host key has changed
when a completely different pattern is displayed. Because these patterns
are not unambiguous however, a pattern that looks similar to the pattern
remembered only gives a good probability that the host key is the same,
not guaranteed proof.
To get a listing of the fingerprints along with their random art for all To get a listing of the fingerprints along with their random art for all
known hosts, the following command line can be used: known hosts, the following command line can be used:
@ -948,4 +957,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0. versions 1.5 and 2.0.
OpenBSD 5.7 March 3, 2015 OpenBSD 5.7 OpenBSD 5.7 May 22, 2015 OpenBSD 5.7

View file

@ -33,9 +33,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: ssh.1,v 1.356 2015/03/03 06:48:58 djm Exp $ .\" $OpenBSD: ssh.1,v 1.358 2015/05/22 05:28:45 djm Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.Dd $Mdocdate: March 3 2015 $ .Dd $Mdocdate: May 22 2015 $
.Dt SSH 1 .Dt SSH 1
.Os .Os
.Sh NAME .Sh NAME
@ -586,9 +586,9 @@ of SSH as a secure transport for other applications (eg.\&
.Xr sftp 1 ) . .Xr sftp 1 ) .
The subsystem is specified as the remote command. The subsystem is specified as the remote command.
.It Fl T .It Fl T
Disable pseudo-tty allocation. Disable pseudo-terminal allocation.
.It Fl t .It Fl t
Force pseudo-tty allocation. Force pseudo-terminal allocation.
This can be used to execute arbitrary This can be used to execute arbitrary
screen-based programs on a remote machine, which can be very useful, screen-based programs on a remote machine, which can be very useful,
e.g. when implementing menu services. e.g. when implementing menu services.
@ -878,15 +878,26 @@ option can be used to control logins to machines whose
host key is not known or has changed. host key is not known or has changed.
.Pp .Pp
When the user's identity has been accepted by the server, the server When the user's identity has been accepted by the server, the server
either executes the given command, or logs into the machine and gives either executes the given command in a non-interactive session or,
the user a normal shell on the remote machine. if no command has been specified, logs into the machine and gives
the user a normal shell as an interactive session.
All communication with All communication with
the remote command or shell will be automatically encrypted. the remote command or shell will be automatically encrypted.
.Pp .Pp
If a pseudo-terminal has been allocated (normal login session), the If an interactive session is requested
.Nm
by default will only request a pseudo-terminal (pty) for interactive
sessions when the client has one.
The flags
.Fl T
and
.Fl t
can be used to override this behaviour.
.Pp
If a pseudo-terminal has been allocated the
user may use the escape characters noted below. user may use the escape characters noted below.
.Pp .Pp
If no pseudo-tty has been allocated, If no pseudo-terminal has been allocated,
the session is transparent and can be used to reliably transfer binary data. the session is transparent and can be used to reliably transfer binary data.
On most systems, setting the escape character to On most systems, setting the escape character to
.Dq none .Dq none
@ -1097,6 +1108,11 @@ Fingerprints can be determined using
.Pp .Pp
If the fingerprint is already known, it can be matched If the fingerprint is already known, it can be matched
and the key can be accepted or rejected. and the key can be accepted or rejected.
If only legacy (MD5) fingerprints for the server are available, the
.Xr ssh-keygen 1
.Fl E
option may be used to downgrade the fingerprint algorithm to match.
.Pp
Because of the difficulty of comparing host keys Because of the difficulty of comparing host keys
just by looking at fingerprint strings, just by looking at fingerprint strings,
there is also support to compare host keys visually, there is also support to compare host keys visually,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.416 2015/03/03 06:48:58 djm Exp $ */ /* $OpenBSD: ssh.c,v 1.418 2015/05/04 06:10:48 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -357,10 +357,8 @@ check_follow_cname(char **namep, const char *cname)
debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname);
for (i = 0; i < options.num_permitted_cnames; i++) { for (i = 0; i < options.num_permitted_cnames; i++) {
rule = options.permitted_cnames + i; rule = options.permitted_cnames + i;
if (match_pattern_list(*namep, rule->source_list, if (match_pattern_list(*namep, rule->source_list, 1) != 1 ||
strlen(rule->source_list), 1) != 1 || match_pattern_list(cname, rule->target_list, 1) != 1)
match_pattern_list(cname, rule->target_list,
strlen(rule->target_list), 1) != 1)
continue; continue;
verbose("Canonicalized DNS aliased hostname " verbose("Canonicalized DNS aliased hostname "
"\"%s\" => \"%s\"", *namep, cname); "\"%s\" => \"%s\"", *namep, cname);
@ -1685,6 +1683,8 @@ ssh_session(void)
} }
/* Request X11 forwarding if enabled and DISPLAY is set. */ /* Request X11 forwarding if enabled and DISPLAY is set. */
display = getenv("DISPLAY"); display = getenv("DISPLAY");
if (display == NULL && options.forward_x11)
debug("X11 forwarding requested but DISPLAY not set");
if (options.forward_x11 && display != NULL) { if (options.forward_x11 && display != NULL) {
char *proto, *data; char *proto, *data;
/* Get reasonable local authentication information. */ /* Get reasonable local authentication information. */
@ -1786,6 +1786,8 @@ ssh_session2_setup(int id, int success, void *arg)
return; /* No need for error message, channels code sens one */ return; /* No need for error message, channels code sens one */
display = getenv("DISPLAY"); display = getenv("DISPLAY");
if (display == NULL && options.forward_x11)
debug("X11 forwarding requested but DISPLAY not set");
if (options.forward_x11 && display != NULL) { if (options.forward_x11 && display != NULL) {
char *proto, *data; char *proto, *data;
/* Get reasonable local authentication information. */ /* Get reasonable local authentication information. */

View file

@ -67,7 +67,7 @@ DESCRIPTION
require an argument. Criteria may be negated by prepending an require an argument. Criteria may be negated by prepending an
exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y).
The canonical keywork matches only when the configuration file is The canonical keyword matches only when the configuration file is
being re-parsed after hostname canonicalization (see the being re-parsed after hostname canonicalization (see the
CanonicalizeHostname option.) This may be useful to specify CanonicalizeHostname option.) This may be useful to specify
conditions that work with canonical host names only. The exec conditions that work with canonical host names only. The exec
@ -165,9 +165,11 @@ DESCRIPTION
CheckHostIP CheckHostIP
If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will additionally check the If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will additionally check the
host IP address in the known_hosts file. This allows ssh to host IP address in the known_hosts file. This allows ssh to
detect if a host key changed due to DNS spoofing. If the option detect if a host key changed due to DNS spoofing and will add
is set to M-bM-^@M-^\noM-bM-^@M-^], the check will not be executed. The default is addresses of destination hosts to ~/.ssh/known_hosts in the
M-bM-^@M-^\yesM-bM-^@M-^]. process, regardless of the setting of StrictHostKeyChecking. If
the option is set to M-bM-^@M-^\noM-bM-^@M-^], the check will not be executed. The
default is M-bM-^@M-^\yesM-bM-^@M-^].
Cipher Specifies the cipher to use for encrypting the session in Cipher Specifies the cipher to use for encrypting the session in
protocol version 1. Currently, M-bM-^@M-^\blowfishM-bM-^@M-^], M-bM-^@M-^\3desM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^] are protocol version 1. Currently, M-bM-^@M-^\blowfishM-bM-^@M-^], M-bM-^@M-^\3desM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^] are
@ -252,9 +254,8 @@ DESCRIPTION
or is not listening. or is not listening.
Setting this to M-bM-^@M-^\askM-bM-^@M-^] will cause ssh to listen for control Setting this to M-bM-^@M-^\askM-bM-^@M-^] will cause ssh to listen for control
connections, but require confirmation using the SSH_ASKPASS connections, but require confirmation using ssh-askpass(1). If
program before they are accepted (see ssh-add(1) for details). the ControlPath cannot be opened, ssh will continue without
If the ControlPath cannot be opened, ssh will continue without
connecting to a master instance. connecting to a master instance.
X11 and ssh-agent(1) forwarding is supported over these X11 and ssh-agent(1) forwarding is supported over these
@ -552,8 +553,8 @@ DESCRIPTION
curve25519-sha256@libssh.org, curve25519-sha256@libssh.org,
ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha256,
diffie-hellman-group14-sha1,
diffie-hellman-group-exchange-sha1, diffie-hellman-group-exchange-sha1,
diffie-hellman-group14-sha1,
diffie-hellman-group1-sha1 diffie-hellman-group1-sha1
The list of available key exchange algorithms may also be The list of available key exchange algorithms may also be
@ -768,12 +769,15 @@ DESCRIPTION
Specifies what variables from the local environ(7) should be sent Specifies what variables from the local environ(7) should be sent
to the server. Note that environment passing is only supported to the server. Note that environment passing is only supported
for protocol 2. The server must also support it, and the server for protocol 2. The server must also support it, and the server
must be configured to accept these environment variables. Refer must be configured to accept these environment variables. Note
to AcceptEnv in sshd_config(5) for how to configure the server. that the TERM environment variable is always sent whenever a
Variables are specified by name, which may contain wildcard pseudo-terminal is requested as it is required by the protocol.
characters. Multiple environment variables may be separated by Refer to AcceptEnv in sshd_config(5) for how to configure the
whitespace or spread across multiple SendEnv directives. The server. Variables are specified by name, which may contain
default is not to send any environment variables. wildcard characters. Multiple environment variables may be
separated by whitespace or spread across multiple SendEnv
directives. The default is not to send any environment
variables.
See PATTERNS for more information on patterns. See PATTERNS for more information on patterns.
@ -978,4 +982,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0. versions 1.5 and 2.0.
OpenBSD 5.7 February 20, 2015 OpenBSD 5.7 OpenBSD 5.7 June 2, 2015 OpenBSD 5.7

View file

@ -33,9 +33,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: ssh_config.5,v 1.205 2015/02/20 22:17:21 djm Exp $ .\" $OpenBSD: ssh_config.5,v 1.211 2015/06/02 09:10:40 djm Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.Dd $Mdocdate: February 20 2015 $ .Dd $Mdocdate: June 2 2015 $
.Dt SSH_CONFIG 5 .Dt SSH_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -167,7 +167,7 @@ Criteria may be negated by prepending an exclamation mark
.Pp .Pp
The The
.Cm canonical .Cm canonical
keywork matches only when the configuration file is being re-parsed keyword matches only when the configuration file is being re-parsed
after hostname canonicalization (see the after hostname canonicalization (see the
.Cm CanonicalizeHostname .Cm CanonicalizeHostname
option.) option.)
@ -341,7 +341,11 @@ If this flag is set to
will additionally check the host IP address in the will additionally check the host IP address in the
.Pa known_hosts .Pa known_hosts
file. file.
This allows ssh to detect if a host key changed due to DNS spoofing. This allows ssh to detect if a host key changed due to DNS spoofing
and will add addresses of destination hosts to
.Pa ~/.ssh/known_hosts
in the process, regardless of the setting of
.Cm StrictHostKeyChecking .
If the option is set to If the option is set to
.Dq no , .Dq no ,
the check will not be executed. the check will not be executed.
@ -485,11 +489,8 @@ if the control socket does not exist, or is not listening.
Setting this to Setting this to
.Dq ask .Dq ask
will cause ssh will cause ssh
to listen for control connections, but require confirmation using the to listen for control connections, but require confirmation using
.Ev SSH_ASKPASS .Xr ssh-askpass 1 .
program before they are accepted (see
.Xr ssh-add 1
for details).
If the If the
.Cm ControlPath .Cm ControlPath
cannot be opened, cannot be opened,
@ -979,8 +980,8 @@ The default is:
curve25519-sha256@libssh.org, curve25519-sha256@libssh.org,
ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha256,
diffie-hellman-group14-sha1,
diffie-hellman-group-exchange-sha1, diffie-hellman-group-exchange-sha1,
diffie-hellman-group14-sha1,
diffie-hellman-group1-sha1 diffie-hellman-group1-sha1
.Ed .Ed
.Pp .Pp
@ -1337,6 +1338,10 @@ should be sent to the server.
Note that environment passing is only supported for protocol 2. Note that environment passing is only supported for protocol 2.
The server must also support it, and the server must be configured to The server must also support it, and the server must be configured to
accept these environment variables. accept these environment variables.
Note that the
.Ev TERM
environment variable is always sent whenever a
pseudo-terminal is requested as it is required by the protocol.
Refer to Refer to
.Cm AcceptEnv .Cm AcceptEnv
in in

View file

@ -1,6 +1,6 @@
/* /*
* Namespace munging inspired by an equivalent hack in NetBSD's tree: add * Namespace munging inspired by an equivalent hack in NetBSD's tree: add
* the "ssh_" prefix to every symbol in libssh which doesn't already have * the "Fssh_" prefix to every symbol in libssh which doesn't already have
* it. This prevents collisions between symbols in libssh and symbols in * it. This prevents collisions between symbols in libssh and symbols in
* other libraries or applications which link with libssh, either directly * other libraries or applications which link with libssh, either directly
* or indirectly (e.g. through PAM loading pam_ssh). * or indirectly (e.g. through PAM loading pam_ssh).
@ -205,6 +205,7 @@
#define channel_send_window_changes Fssh_channel_send_window_changes #define channel_send_window_changes Fssh_channel_send_window_changes
#define channel_set_af Fssh_channel_set_af #define channel_set_af Fssh_channel_set_af
#define channel_set_fds Fssh_channel_set_fds #define channel_set_fds Fssh_channel_set_fds
#define channel_set_x11_refuse_time Fssh_channel_set_x11_refuse_time
#define channel_setup_fwd_listener_streamlocal Fssh_channel_setup_fwd_listener_streamlocal #define channel_setup_fwd_listener_streamlocal Fssh_channel_setup_fwd_listener_streamlocal
#define channel_setup_fwd_listener_tcpip Fssh_channel_setup_fwd_listener_tcpip #define channel_setup_fwd_listener_tcpip Fssh_channel_setup_fwd_listener_tcpip
#define channel_setup_local_fwd_listener Fssh_channel_setup_local_fwd_listener #define channel_setup_local_fwd_listener Fssh_channel_setup_local_fwd_listener
@ -314,6 +315,7 @@
#define dh_new_group1 Fssh_dh_new_group1 #define dh_new_group1 Fssh_dh_new_group1
#define dh_new_group14 Fssh_dh_new_group14 #define dh_new_group14 Fssh_dh_new_group14
#define dh_new_group_asc Fssh_dh_new_group_asc #define dh_new_group_asc Fssh_dh_new_group_asc
#define dh_new_group_fallback Fssh_dh_new_group_fallback
#define dh_pub_is_valid Fssh_dh_pub_is_valid #define dh_pub_is_valid Fssh_dh_pub_is_valid
#define dispatch_protocol_error Fssh_dispatch_protocol_error #define dispatch_protocol_error Fssh_dispatch_protocol_error
#define dispatch_protocol_ignore Fssh_dispatch_protocol_ignore #define dispatch_protocol_ignore Fssh_dispatch_protocol_ignore
@ -846,6 +848,7 @@
#define sshkey_size Fssh_sshkey_size #define sshkey_size Fssh_sshkey_size
#define sshkey_ssh_name Fssh_sshkey_ssh_name #define sshkey_ssh_name Fssh_sshkey_ssh_name
#define sshkey_ssh_name_plain Fssh_sshkey_ssh_name_plain #define sshkey_ssh_name_plain Fssh_sshkey_ssh_name_plain
#define sshkey_to_base64 Fssh_sshkey_to_base64
#define sshkey_to_blob Fssh_sshkey_to_blob #define sshkey_to_blob Fssh_sshkey_to_blob
#define sshkey_to_certified Fssh_sshkey_to_certified #define sshkey_to_certified Fssh_sshkey_to_certified
#define sshkey_try_load_public Fssh_sshkey_try_load_public #define sshkey_try_load_public Fssh_sshkey_try_load_public
@ -928,4 +931,5 @@
#define xmalloc Fssh_xmalloc #define xmalloc Fssh_xmalloc
#define xmmap Fssh_xmmap #define xmmap Fssh_xmmap
#define xrealloc Fssh_xrealloc #define xrealloc Fssh_xrealloc
#define xreallocarray Fssh_xreallocarray
#define xstrdup Fssh_xstrdup #define xstrdup Fssh_xstrdup

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf-misc.c,v 1.3 2015/02/05 12:59:57 millert Exp $ */ /* $OpenBSD: sshbuf-misc.c,v 1.4 2015/03/24 20:03:44 markus Exp $ */
/* /*
* Copyright (c) 2011 Damien Miller * Copyright (c) 2011 Damien Miller
* *
@ -42,7 +42,7 @@ sshbuf_dump_data(const void *s, size_t len, FILE *f)
const u_char *p = (const u_char *)s; const u_char *p = (const u_char *)s;
for (i = 0; i < len; i += 16) { for (i = 0; i < len; i += 16) {
fprintf(f, "%.4zd: ", i); fprintf(f, "%.4zu: ", i);
for (j = i; j < i + 16; j++) { for (j = i; j < i + 16; j++) {
if (j < len) if (j < len)
fprintf(f, "%02x ", p[j]); fprintf(f, "%02x ", p[j]);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.259 2015/01/28 22:36:00 djm Exp $ */ /* $OpenBSD: sshconnect.c,v 1.262 2015/05/28 05:41:29 dtucker Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -913,7 +913,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
host_key, options.hash_known_hosts)) host_key, options.hash_known_hosts))
logit("Failed to add the %s host key for IP " logit("Failed to add the %s host key for IP "
"address '%.128s' to the list of known " "address '%.128s' to the list of known "
"hosts (%.30s).", type, ip, "hosts (%.500s).", type, ip,
user_hostfiles[0]); user_hostfiles[0]);
else else
logit("Warning: Permanently added the %s host " logit("Warning: Permanently added the %s host "
@ -1351,6 +1351,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
/* key exchange */ /* key exchange */
/* authenticate user */ /* authenticate user */
debug("Authenticating to %s:%d as '%s'", host, port, server_user);
if (compat20) { if (compat20) {
ssh_kex2(host, hostaddr, port); ssh_kex2(host, hostaddr, port);
ssh_userauth2(local_user, server_user, host, sensitive); ssh_userauth2(local_user, server_user, host, sensitive);
@ -1359,7 +1360,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
ssh_kex(host, hostaddr); ssh_kex(host, hostaddr);
ssh_userauth1(local_user, server_user, host, sensitive); ssh_userauth1(local_user, server_user, host, sensitive);
#else #else
fatal("ssh1 is not unsupported"); fatal("ssh1 is not supported");
#endif #endif
} }
free(local_user); free(local_user);

Some files were not shown because too many files have changed in this diff Show more