Merge branch 'master' of https://github.com/openssh/openssh-portable into m_temp
This commit is contained in:
commit
2846d75e56
|
@ -1,3 +1,7 @@
|
|||
# Commit IDs against the new CVS->GIT translation go here (and delete this line)
|
||||
|
||||
Old upstream tree:
|
||||
|
||||
321065a95a7ccebdd5fd08482a1e19afbf524e35 Update DH groups
|
||||
d4f699a421504df35254cf1c6f1a7c304fb907ca Remove 1k bit groups
|
||||
aafe246655b53b52bc32c8a24002bc262f4230f7 Remove intermediate moduli
|
||||
|
|
|
@ -100,9 +100,9 @@ DSA certificate
|
|||
|
||||
ECDSA certificate
|
||||
|
||||
string "ecdsa-sha2-nistp256-v01@openssh.com" |
|
||||
"ecdsa-sha2-nistp384-v01@openssh.com" |
|
||||
"ecdsa-sha2-nistp521-v01@openssh.com"
|
||||
string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com" |
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||
string nonce
|
||||
string curve
|
||||
string public_key
|
||||
|
@ -291,4 +291,4 @@ permit-user-rc empty Flag indicating that execution of
|
|||
of this script will not be permitted if
|
||||
this option is not present.
|
||||
|
||||
$OpenBSD: PROTOCOL.certkeys,v 1.12 2017/05/31 04:29:44 djm Exp $
|
||||
$OpenBSD: PROTOCOL.certkeys,v 1.13 2017/11/03 02:32:19 djm Exp $
|
||||
|
|
1
bitmap.c
1
bitmap.c
|
@ -1,3 +1,4 @@
|
|||
/* $OpenBSD: bitmap.c,v 1.9 2017/10/20 01:56:39 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
|
|
1
bitmap.h
1
bitmap.h
|
@ -1,3 +1,4 @@
|
|||
/* $OpenBSD: bitmap.h,v 1.2 2017/10/20 01:56:39 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
|
|
19
channels.c
19
channels.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: channels.c,v 1.375 2017/09/24 13:45:34 djm Exp $ */
|
||||
/* $OpenBSD: channels.c,v 1.376 2017/10/25 00:15:35 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1668,19 +1668,6 @@ port_open_helper(struct ssh *ssh, Channel *c, char *rtype)
|
|||
free(local_ipaddr);
|
||||
}
|
||||
|
||||
static void
|
||||
channel_set_reuseaddr(int fd)
|
||||
{
|
||||
int on = 1;
|
||||
|
||||
/*
|
||||
* Set socket options.
|
||||
* Allow local port reuse in TIME_WAIT.
|
||||
*/
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
|
||||
error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time)
|
||||
{
|
||||
|
@ -3370,7 +3357,7 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
|
|||
continue;
|
||||
}
|
||||
|
||||
channel_set_reuseaddr(sock);
|
||||
set_reuseaddr(sock);
|
||||
if (ai->ai_family == AF_INET6)
|
||||
sock_set_v6only(sock);
|
||||
|
||||
|
@ -4443,7 +4430,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
|
|||
if (ai->ai_family == AF_INET6)
|
||||
sock_set_v6only(sock);
|
||||
if (x11_use_localhost)
|
||||
channel_set_reuseaddr(sock);
|
||||
set_reuseaddr(sock);
|
||||
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
debug2("%s: bind port %d: %.100s", __func__,
|
||||
port, strerror(errno));
|
||||
|
|
6
cipher.c
6
cipher.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: cipher.c,v 1.107 2017/05/07 23:12:57 djm Exp $ */
|
||||
/* $OpenBSD: cipher.c,v 1.108 2017/11/03 02:22:41 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -449,8 +449,8 @@ cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
|
|||
int
|
||||
cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
|
||||
{
|
||||
const struct sshcipher *c = cc->cipher;
|
||||
#ifdef WITH_OPENSSL
|
||||
const struct sshcipher *c = cc->cipher;
|
||||
int evplen;
|
||||
#endif
|
||||
|
||||
|
@ -494,8 +494,8 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
|
|||
int
|
||||
cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
|
||||
{
|
||||
const struct sshcipher *c = cc->cipher;
|
||||
#ifdef WITH_OPENSSL
|
||||
const struct sshcipher *c = cc->cipher;
|
||||
int evplen = 0;
|
||||
#endif
|
||||
|
||||
|
|
12
clientloop.c
12
clientloop.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: clientloop.c,v 1.305 2017/09/19 04:24:22 djm Exp $ */
|
||||
/* $OpenBSD: clientloop.c,v 1.306 2017/10/23 05:08:00 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1605,12 +1605,13 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
|
|||
return c;
|
||||
}
|
||||
|
||||
int
|
||||
char *
|
||||
client_request_tun_fwd(struct ssh *ssh, int tun_mode,
|
||||
int local_tun, int remote_tun)
|
||||
{
|
||||
Channel *c;
|
||||
int fd;
|
||||
char *ifname = NULL;
|
||||
|
||||
if (tun_mode == SSH_TUNMODE_NO)
|
||||
return 0;
|
||||
|
@ -1618,10 +1619,11 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
|
|||
debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);
|
||||
|
||||
/* Open local tunnel device */
|
||||
if ((fd = tun_open(local_tun, tun_mode)) == -1) {
|
||||
if ((fd = tun_open(local_tun, tun_mode, &ifname)) == -1) {
|
||||
error("Tunnel device open failed.");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
debug("Tunnel forwarding using interface %s", ifname);
|
||||
|
||||
c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
|
||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
|
||||
|
@ -1642,7 +1644,7 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
|
|||
packet_put_int(remote_tun);
|
||||
packet_send();
|
||||
|
||||
return 0;
|
||||
return ifname;
|
||||
}
|
||||
|
||||
/* XXXX move to generic input handler */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: clientloop.h,v 1.34 2017/09/12 06:32:07 djm Exp $ */
|
||||
/* $OpenBSD: clientloop.h,v 1.35 2017/10/23 05:08:00 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -46,7 +46,7 @@ int client_x11_get_proto(struct ssh *, const char *, const char *,
|
|||
void client_global_request_reply_fwd(int, u_int32_t, void *);
|
||||
void client_session2_setup(struct ssh *, int, int, int,
|
||||
const char *, struct termios *, int, Buffer *, char **);
|
||||
int client_request_tun_fwd(struct ssh *, int, int, int);
|
||||
char *client_request_tun_fwd(struct ssh *, int, int, int);
|
||||
void client_stop_mux(void);
|
||||
|
||||
/* Escape filter for protocol 2 sessions */
|
||||
|
|
13
configure.ac
13
configure.ac
|
@ -427,6 +427,16 @@ AC_CHECK_HEADERS([sys/capsicum.h], [], [], [
|
|||
#endif
|
||||
])
|
||||
|
||||
# net/route.h requires sys/socket.h and sys/types.h.
|
||||
# sys/sysctl.h also requires sys/param.h
|
||||
AC_CHECK_HEADERS([net/route.h sys/sysctl.h], [], [], [
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
|
||||
# lastlog.h requires sys/time.h to be included first on Solaris
|
||||
AC_CHECK_HEADERS([lastlog.h], [], [], [
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
|
@ -769,6 +779,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
|||
AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
|
||||
[Prepend the address family to IP tunnel traffic])
|
||||
fi
|
||||
AC_CHECK_HEADER([linux/if.h],
|
||||
AC_DEFINE([SYS_RDOMAIN_LINUX], [1],
|
||||
[Support routing domains using Linux VRF]))
|
||||
AC_CHECK_HEADERS([linux/seccomp.h linux/filter.h linux/audit.h], [],
|
||||
[], [#include <linux/types.h>])
|
||||
AC_MSG_CHECKING([for seccomp architecture])
|
||||
|
|
3
dh.c
3
dh.c
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
|
@ -465,3 +466,5 @@ dh_estimate(int bits)
|
|||
return 7680;
|
||||
return 8192;
|
||||
}
|
||||
|
||||
#endif /* WITH_OPENSSL */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexc25519s.c,v 1.10 2015/12/04 16:41:28 markus Exp $ */
|
||||
/* $OpenBSD: kexc25519s.c,v 1.11 2017/05/31 04:19:28 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
|
375
misc.c
375
misc.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: misc.c,v 1.113 2017/08/18 05:48:04 djm Exp $ */
|
||||
/* $OpenBSD: misc.c,v 1.118 2017/10/25 00:17:08 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
|
||||
|
@ -167,6 +167,73 @@ set_nodelay(int fd)
|
|||
error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Allow local port reuse in TIME_WAIT */
|
||||
int
|
||||
set_reuseaddr(int fd)
|
||||
{
|
||||
int on = 1;
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
|
||||
error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get/set routing domain */
|
||||
char *
|
||||
get_rdomain(int fd)
|
||||
{
|
||||
#if defined(HAVE_SYS_GET_RDOMAIN)
|
||||
return sys_get_rdomain(fd);
|
||||
#elif defined(__OpenBSD__)
|
||||
int rtable;
|
||||
char *ret;
|
||||
socklen_t len = sizeof(rtable);
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_RTABLE, &rtable, &len) == -1) {
|
||||
error("Failed to get routing domain for fd %d: %s",
|
||||
fd, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
xasprintf(&ret, "%d", rtable);
|
||||
return ret;
|
||||
#else /* defined(__OpenBSD__) */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
set_rdomain(int fd, const char *name)
|
||||
{
|
||||
#if defined(HAVE_SYS_SET_RDOMAIN)
|
||||
return sys_set_rdomain(fd, name);
|
||||
#elif defined(__OpenBSD__)
|
||||
int rtable;
|
||||
const char *errstr;
|
||||
|
||||
if (name == NULL)
|
||||
return 0; /* default table */
|
||||
|
||||
rtable = (int)strtonum(name, 0, 255, &errstr);
|
||||
if (errstr != NULL) {
|
||||
/* Shouldn't happen */
|
||||
error("Invalid routing domain \"%s\": %s", name, errstr);
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RTABLE,
|
||||
&rtable, sizeof(rtable)) == -1) {
|
||||
error("Failed to set routing domain %d on fd %d: %s",
|
||||
rtable, fd, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else /* defined(__OpenBSD__) */
|
||||
error("Setting routing domain is not supported on this platform");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Characters considered whitespace in strsep calls. */
|
||||
#define WHITESPACE " \t\r\n"
|
||||
#define QUOTE "\""
|
||||
|
@ -399,11 +466,12 @@ put_host_port(const char *host, u_short port)
|
|||
* Search for next delimiter between hostnames/addresses and ports.
|
||||
* Argument may be modified (for termination).
|
||||
* Returns *cp if parsing succeeds.
|
||||
* *cp is set to the start of the next delimiter, if one was found.
|
||||
* *cp is set to the start of the next field, if one was found.
|
||||
* The delimiter char, if present, is stored in delim.
|
||||
* If this is the last field, *cp is set to NULL.
|
||||
*/
|
||||
char *
|
||||
hpdelim(char **cp)
|
||||
static char *
|
||||
hpdelim2(char **cp, char *delim)
|
||||
{
|
||||
char *s, *old;
|
||||
|
||||
|
@ -426,6 +494,8 @@ hpdelim(char **cp)
|
|||
|
||||
case ':':
|
||||
case '/':
|
||||
if (delim != NULL)
|
||||
*delim = *s;
|
||||
*s = '\0'; /* terminate */
|
||||
*cp = s + 1;
|
||||
break;
|
||||
|
@ -437,6 +507,12 @@ hpdelim(char **cp)
|
|||
return old;
|
||||
}
|
||||
|
||||
char *
|
||||
hpdelim(char **cp)
|
||||
{
|
||||
return hpdelim2(cp, NULL);
|
||||
}
|
||||
|
||||
char *
|
||||
cleanhostname(char *host)
|
||||
{
|
||||
|
@ -481,6 +557,75 @@ colon(char *cp)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a [user@]host:[path] string.
|
||||
* Caller must free returned user, host and path.
|
||||
* Any of the pointer return arguments may be NULL (useful for syntax checking).
|
||||
* If user was not specified then *userp will be set to NULL.
|
||||
* If host was not specified then *hostp will be set to NULL.
|
||||
* If path was not specified then *pathp will be set to ".".
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
parse_user_host_path(const char *s, char **userp, char **hostp, char **pathp)
|
||||
{
|
||||
char *user = NULL, *host = NULL, *path = NULL;
|
||||
char *sdup, *tmp;
|
||||
int ret = -1;
|
||||
|
||||
if (userp != NULL)
|
||||
*userp = NULL;
|
||||
if (hostp != NULL)
|
||||
*hostp = NULL;
|
||||
if (pathp != NULL)
|
||||
*pathp = NULL;
|
||||
|
||||
sdup = xstrdup(s);
|
||||
|
||||
/* Check for remote syntax: [user@]host:[path] */
|
||||
if ((tmp = colon(sdup)) == NULL)
|
||||
goto out;
|
||||
|
||||
/* Extract optional path */
|
||||
*tmp++ = '\0';
|
||||
if (*tmp == '\0')
|
||||
tmp = ".";
|
||||
path = xstrdup(tmp);
|
||||
|
||||
/* Extract optional user and mandatory host */
|
||||
tmp = strrchr(sdup, '@');
|
||||
if (tmp != NULL) {
|
||||
*tmp++ = '\0';
|
||||
host = xstrdup(cleanhostname(tmp));
|
||||
if (*sdup != '\0')
|
||||
user = xstrdup(sdup);
|
||||
} else {
|
||||
host = xstrdup(cleanhostname(sdup));
|
||||
user = NULL;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (userp != NULL) {
|
||||
*userp = user;
|
||||
user = NULL;
|
||||
}
|
||||
if (hostp != NULL) {
|
||||
*hostp = host;
|
||||
host = NULL;
|
||||
}
|
||||
if (pathp != NULL) {
|
||||
*pathp = path;
|
||||
path = NULL;
|
||||
}
|
||||
ret = 0;
|
||||
out:
|
||||
free(sdup);
|
||||
free(user);
|
||||
free(host);
|
||||
free(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a [user@]host[:port] string.
|
||||
* Caller must free returned user and host.
|
||||
|
@ -506,7 +651,7 @@ parse_user_host_port(const char *s, char **userp, char **hostp, int *portp)
|
|||
if ((sdup = tmp = strdup(s)) == NULL)
|
||||
return -1;
|
||||
/* Extract optional username */
|
||||
if ((cp = strchr(tmp, '@')) != NULL) {
|
||||
if ((cp = strrchr(tmp, '@')) != NULL) {
|
||||
*cp = '\0';
|
||||
if (*tmp == '\0')
|
||||
goto out;
|
||||
|
@ -542,6 +687,168 @@ parse_user_host_port(const char *s, char **userp, char **hostp, int *portp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts a two-byte hex string to decimal.
|
||||
* Returns the decimal value or -1 for invalid input.
|
||||
*/
|
||||
static int
|
||||
hexchar(const char *s)
|
||||
{
|
||||
unsigned char result[2];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (s[i] >= '0' && s[i] <= '9')
|
||||
result[i] = (unsigned char)(s[i] - '0');
|
||||
else if (s[i] >= 'a' && s[i] <= 'f')
|
||||
result[i] = (unsigned char)(s[i] - 'a') + 10;
|
||||
else if (s[i] >= 'A' && s[i] <= 'F')
|
||||
result[i] = (unsigned char)(s[i] - 'A') + 10;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
return (result[0] << 4) | result[1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode an url-encoded string.
|
||||
* Returns a newly allocated string on success or NULL on failure.
|
||||
*/
|
||||
static char *
|
||||
urldecode(const char *src)
|
||||
{
|
||||
char *ret, *dst;
|
||||
int ch;
|
||||
|
||||
ret = xmalloc(strlen(src) + 1);
|
||||
for (dst = ret; *src != '\0'; src++) {
|
||||
switch (*src) {
|
||||
case '+':
|
||||
*dst++ = ' ';
|
||||
break;
|
||||
case '%':
|
||||
if (!isxdigit((unsigned char)src[1]) ||
|
||||
!isxdigit((unsigned char)src[2]) ||
|
||||
(ch = hexchar(src + 1)) == -1) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
*dst++ = ch;
|
||||
src += 2;
|
||||
break;
|
||||
default:
|
||||
*dst++ = *src;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse an (scp|ssh|sftp)://[user@]host[:port][/path] URI.
|
||||
* See https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04
|
||||
* Either user or path may be url-encoded (but not host or port).
|
||||
* Caller must free returned user, host and path.
|
||||
* Any of the pointer return arguments may be NULL (useful for syntax checking)
|
||||
* but the scheme must always be specified.
|
||||
* If user was not specified then *userp will be set to NULL.
|
||||
* If port was not specified then *portp will be -1.
|
||||
* If path was not specified then *pathp will be set to NULL.
|
||||
* Returns 0 on success, 1 if non-uri/wrong scheme, -1 on error/invalid uri.
|
||||
*/
|
||||
int
|
||||
parse_uri(const char *scheme, const char *uri, char **userp, char **hostp,
|
||||
int *portp, char **pathp)
|
||||
{
|
||||
char *uridup, *cp, *tmp, ch;
|
||||
char *user = NULL, *host = NULL, *path = NULL;
|
||||
int port = -1, ret = -1;
|
||||
size_t len;
|
||||
|
||||
len = strlen(scheme);
|
||||
if (strncmp(uri, scheme, len) != 0 || strncmp(uri + len, "://", 3) != 0)
|
||||
return 1;
|
||||
uri += len + 3;
|
||||
|
||||
if (userp != NULL)
|
||||
*userp = NULL;
|
||||
if (hostp != NULL)
|
||||
*hostp = NULL;
|
||||
if (portp != NULL)
|
||||
*portp = -1;
|
||||
if (pathp != NULL)
|
||||
*pathp = NULL;
|
||||
|
||||
uridup = tmp = xstrdup(uri);
|
||||
|
||||
/* Extract optional ssh-info (username + connection params) */
|
||||
if ((cp = strchr(tmp, '@')) != NULL) {
|
||||
char *delim;
|
||||
|
||||
*cp = '\0';
|
||||
/* Extract username and connection params */
|
||||
if ((delim = strchr(tmp, ';')) != NULL) {
|
||||
/* Just ignore connection params for now */
|
||||
*delim = '\0';
|
||||
}
|
||||
if (*tmp == '\0') {
|
||||
/* Empty username */
|
||||
goto out;
|
||||
}
|
||||
if ((user = urldecode(tmp)) == NULL)
|
||||
goto out;
|
||||
tmp = cp + 1;
|
||||
}
|
||||
|
||||
/* Extract mandatory hostname */
|
||||
if ((cp = hpdelim2(&tmp, &ch)) == NULL || *cp == '\0')
|
||||
goto out;
|
||||
host = xstrdup(cleanhostname(cp));
|
||||
if (!valid_domain(host, 0, NULL))
|
||||
goto out;
|
||||
|
||||
if (tmp != NULL && *tmp != '\0') {
|
||||
if (ch == ':') {
|
||||
/* Convert and verify port. */
|
||||
if ((cp = strchr(tmp, '/')) != NULL)
|
||||
*cp = '\0';
|
||||
if ((port = a2port(tmp)) <= 0)
|
||||
goto out;
|
||||
tmp = cp ? cp + 1 : NULL;
|
||||
}
|
||||
if (tmp != NULL && *tmp != '\0') {
|
||||
/* Extract optional path */
|
||||
if ((path = urldecode(tmp)) == NULL)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (userp != NULL) {
|
||||
*userp = user;
|
||||
user = NULL;
|
||||
}
|
||||
if (hostp != NULL) {
|
||||
*hostp = host;
|
||||
host = NULL;
|
||||
}
|
||||
if (portp != NULL)
|
||||
*portp = port;
|
||||
if (pathp != NULL) {
|
||||
*pathp = path;
|
||||
path = NULL;
|
||||
}
|
||||
ret = 0;
|
||||
out:
|
||||
free(uridup);
|
||||
free(user);
|
||||
free(host);
|
||||
free(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* function to assist building execv() arguments */
|
||||
void
|
||||
addargs(arglist *args, char *fmt, ...)
|
||||
|
@ -739,16 +1046,19 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
|
|||
}
|
||||
|
||||
int
|
||||
tun_open(int tun, int mode)
|
||||
tun_open(int tun, int mode, char **ifname)
|
||||
{
|
||||
#if defined(CUSTOM_SYS_TUN_OPEN)
|
||||
return (sys_tun_open(tun, mode));
|
||||
return (sys_tun_open(tun, mode, ifname));
|
||||
#elif defined(SSH_TUN_OPENBSD)
|
||||
struct ifreq ifr;
|
||||
char name[100];
|
||||
int fd = -1, sock;
|
||||
const char *tunbase = "tun";
|
||||
|
||||
if (ifname != NULL)
|
||||
*ifname = NULL;
|
||||
|
||||
if (mode == SSH_TUNMODE_ETHERNET)
|
||||
tunbase = "tap";
|
||||
|
||||
|
@ -795,6 +1105,9 @@ tun_open(int tun, int mode)
|
|||
}
|
||||
}
|
||||
|
||||
if (ifname != NULL)
|
||||
*ifname = xstrdup(ifr.ifr_name);
|
||||
|
||||
close(sock);
|
||||
return fd;
|
||||
|
||||
|
@ -1775,3 +2088,51 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
|
|||
env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
|
||||
snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check and optionally lowercase a domain name, also removes trailing '.'
|
||||
* Returns 1 on success and 0 on failure, storing an error message in errstr.
|
||||
*/
|
||||
int
|
||||
valid_domain(char *name, int makelower, const char **errstr)
|
||||
{
|
||||
size_t i, l = strlen(name);
|
||||
u_char c, last = '\0';
|
||||
static char errbuf[256];
|
||||
|
||||
if (l == 0) {
|
||||
strlcpy(errbuf, "empty domain name", sizeof(errbuf));
|
||||
goto bad;
|
||||
}
|
||||
if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) {
|
||||
snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" "
|
||||
"starts with invalid character", name);
|
||||
goto bad;
|
||||
}
|
||||
for (i = 0; i < l; i++) {
|
||||
c = tolower((u_char)name[i]);
|
||||
if (makelower)
|
||||
name[i] = (char)c;
|
||||
if (last == '.' && c == '.') {
|
||||
snprintf(errbuf, sizeof(errbuf), "domain name "
|
||||
"\"%.100s\" contains consecutive separators", name);
|
||||
goto bad;
|
||||
}
|
||||
if (c != '.' && c != '-' && !isalnum(c) &&
|
||||
c != '_') /* technically invalid, but common */ {
|
||||
snprintf(errbuf, sizeof(errbuf), "domain name "
|
||||
"\"%.100s\" contains invalid characters", name);
|
||||
goto bad;
|
||||
}
|
||||
last = c;
|
||||
}
|
||||
if (name[l - 1] == '.')
|
||||
name[l - 1] = '\0';
|
||||
if (errstr != NULL)
|
||||
*errstr = NULL;
|
||||
return 1;
|
||||
bad:
|
||||
if (errstr != NULL)
|
||||
*errstr = errbuf;
|
||||
return 0;
|
||||
}
|
||||
|
|
10
misc.h
10
misc.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: misc.h,v 1.63 2017/08/18 05:48:04 djm Exp $ */
|
||||
/* $OpenBSD: misc.h,v 1.67 2017/10/25 00:17:08 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -48,13 +48,18 @@ char *strdelim(char **);
|
|||
int set_nonblock(int);
|
||||
int unset_nonblock(int);
|
||||
void set_nodelay(int);
|
||||
int set_reuseaddr(int);
|
||||
char *get_rdomain(int);
|
||||
int set_rdomain(int, const char *);
|
||||
int a2port(const char *);
|
||||
int a2tun(const char *, int *);
|
||||
char *put_host_port(const char *, u_short);
|
||||
char *hpdelim(char **);
|
||||
char *cleanhostname(char *);
|
||||
char *colon(char *);
|
||||
int parse_user_host_path(const char *, char **, char **, char **);
|
||||
int parse_user_host_port(const char *, char **, char **, int *);
|
||||
int parse_uri(const char *, const char *, char **, char **, int *, char **);
|
||||
long convtime(const char *);
|
||||
char *tilde_expand_filename(const char *, uid_t);
|
||||
char *percent_expand(const char *, ...) __attribute__((__sentinel__));
|
||||
|
@ -66,6 +71,7 @@ time_t monotime(void);
|
|||
double monotime_double(void);
|
||||
void lowercase(char *s);
|
||||
int unix_listener(const char *, int, int);
|
||||
int valid_domain(char *, int, const char **);
|
||||
|
||||
void sock_set_v6only(int);
|
||||
|
||||
|
@ -84,7 +90,7 @@ void replacearg(arglist *, u_int, char *, ...)
|
|||
__attribute__((format(printf, 3, 4)));
|
||||
void freeargs(arglist *);
|
||||
|
||||
int tun_open(int, int);
|
||||
int tun_open(int, int, char **);
|
||||
|
||||
/* Common definitions for ssh tunnel device forwarding */
|
||||
#define SSH_TUNMODE_NO 0x00
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor.c,v 1.174 2017/10/02 19:33:20 djm Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.175 2017/10/05 15:52:03 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
|
@ -760,12 +760,10 @@ mm_answer_pwnamallow(int sock, Buffer *m)
|
|||
for (i = 0; i < options.nx; i++) \
|
||||
buffer_put_cstring(m, options.x[i]); \
|
||||
} while (0)
|
||||
#define M_CP_STRARRAYOPT_ALLOC(x, nx) M_CP_STRARRAYOPT(x, nx)
|
||||
/* See comment in servconf.h */
|
||||
COPY_MATCH_STRING_OPTS();
|
||||
#undef M_CP_STROPT
|
||||
#undef M_CP_STRARRAYOPT
|
||||
#undef M_CP_STRARRAYOPT_ALLOC
|
||||
|
||||
/* Create valid auth method lists */
|
||||
if (auth2_setup_methods_lists(authctxt) != 0) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor_wrap.c,v 1.94 2017/10/02 19:33:20 djm Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.95 2017/10/05 15:52:03 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
|
@ -287,19 +287,15 @@ out:
|
|||
newopts->x = buffer_get_string(&m, NULL); \
|
||||
} while (0)
|
||||
#define M_CP_STRARRAYOPT(x, nx) do { \
|
||||
for (i = 0; i < newopts->nx; i++) \
|
||||
newopts->x[i] = buffer_get_string(&m, NULL); \
|
||||
} while (0)
|
||||
#define M_CP_STRARRAYOPT_ALLOC(x, nx) do { \
|
||||
newopts->x = newopts->nx == 0 ? \
|
||||
NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
|
||||
M_CP_STRARRAYOPT(x, nx); \
|
||||
for (i = 0; i < newopts->nx; i++) \
|
||||
newopts->x[i] = buffer_get_string(&m, NULL); \
|
||||
} while (0)
|
||||
/* See comment in servconf.h */
|
||||
COPY_MATCH_STRING_OPTS();
|
||||
#undef M_CP_STROPT
|
||||
#undef M_CP_STRARRAYOPT
|
||||
#undef M_CP_STRARRAYOPT_ALLOC
|
||||
|
||||
copy_set_server_options(&options, newopts, 1);
|
||||
log_change_level(options.log_level);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* $OpenBSD: opacket.c,v 1.7 2017/10/20 01:56:39 djm Exp $ */
|
||||
/* Written by Markus Friedl. Placed in the public domain. */
|
||||
|
||||
#include "includes.h"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* $OpenBSD: opacket.h,v 1.12 2017/10/20 01:56:39 djm Exp $ */
|
||||
#ifndef _OPACKET_H
|
||||
/* Written by Markus Friedl. Placed in the public domain. */
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di
|
|||
|
||||
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
|
||||
|
||||
PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
|
||||
PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-net.o port-uw.o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* Placed in the public domain */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifndef HAVE_GETPAGESIZE
|
||||
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -325,7 +325,7 @@ char *shadow_pw(struct passwd *pw);
|
|||
#include "port-irix.h"
|
||||
#include "port-linux.h"
|
||||
#include "port-solaris.h"
|
||||
#include "port-tun.h"
|
||||
#include "port-net.h"
|
||||
#include "port-uw.h"
|
||||
|
||||
/* _FORTIFY_SOURCE breaks FD_ISSET(n)/FD_SET(n) for n > FD_SETSIZE. Avoid. */
|
||||
|
|
|
@ -36,6 +36,90 @@
|
|||
#include "channels.h"
|
||||
#include "ssherr.h"
|
||||
|
||||
/*
|
||||
* This file contains various portability code for network support,
|
||||
* including tun/tap forwarding and routing domains.
|
||||
*/
|
||||
|
||||
#if defined(SYS_RDOMAIN_LINUX) || defined(SSH_TUN_LINUX)
|
||||
#include <linux/if.h>
|
||||
#endif
|
||||
|
||||
#if defined(SYS_RDOMAIN_LINUX)
|
||||
char *
|
||||
sys_get_rdomain(int fd)
|
||||
{
|
||||
char dev[IFNAMSIZ + 1];
|
||||
socklen_t len = sizeof(dev) - 1;
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, dev, &len) == -1) {
|
||||
error("%s: cannot determine VRF for fd=%d : %s",
|
||||
__func__, fd, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
dev[len] = '\0';
|
||||
return strdup(dev);
|
||||
}
|
||||
|
||||
int
|
||||
sys_set_rdomain(int fd, const char *name)
|
||||
{
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
name, strlen(name)) == -1) {
|
||||
error("%s: setsockopt(%d, SO_BINDTODEVICE, %s): %s",
|
||||
__func__, fd, name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sys_valid_rdomain(const char *name)
|
||||
{
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* This is a pretty crappy way to test. It would be better to
|
||||
* check whether "name" represents a VRF device, but apparently
|
||||
* that requires an rtnetlink transaction.
|
||||
*/
|
||||
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
return 0;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
name, strlen(name)) == -1) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
#elif defined(SYS_RDOMAIN_XXX)
|
||||
/* XXX examples */
|
||||
char *
|
||||
sys_get_rdomain(int fd)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
sys_set_rdomain(int fd, const char *name)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
valid_rdomain(const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sys_set_process_rdomain(const char *name)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
#endif /* defined(SYS_RDOMAIN_XXX) */
|
||||
|
||||
/*
|
||||
* This is the portable version of the SSH tunnel forwarding, it
|
||||
* uses some preprocessor definitions for various platform-specific
|
||||
|
@ -52,16 +136,18 @@
|
|||
*/
|
||||
|
||||
#if defined(SSH_TUN_LINUX)
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
|
||||
int
|
||||
sys_tun_open(int tun, int mode)
|
||||
sys_tun_open(int tun, int mode, char **ifname)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int fd = -1;
|
||||
const char *name = NULL;
|
||||
|
||||
if (ifname != NULL)
|
||||
*ifname = NULL;
|
||||
|
||||
if ((fd = open("/dev/net/tun", O_RDWR)) == -1) {
|
||||
debug("%s: failed to open tunnel control interface: %s",
|
||||
__func__, strerror(errno));
|
||||
|
@ -99,6 +185,9 @@ sys_tun_open(int tun, int mode)
|
|||
else
|
||||
debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd);
|
||||
|
||||
if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)))
|
||||
goto failed;
|
||||
|
||||
return (fd);
|
||||
|
||||
failed:
|
||||
|
@ -116,13 +205,16 @@ sys_tun_open(int tun, int mode)
|
|||
#endif
|
||||
|
||||
int
|
||||
sys_tun_open(int tun, int mode)
|
||||
sys_tun_open(int tun, int mode, char **ifname)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
char name[100];
|
||||
int fd = -1, sock, flag;
|
||||
const char *tunbase = "tun";
|
||||
|
||||
if (ifname != NULL)
|
||||
*ifname = NULL;
|
||||
|
||||
if (mode == SSH_TUNMODE_ETHERNET) {
|
||||
#ifdef SSH_TUN_NO_L2
|
||||
debug("%s: no layer 2 tunnelling support", __func__);
|
||||
|
@ -180,6 +272,9 @@ sys_tun_open(int tun, int mode)
|
|||
goto failed;
|
||||
}
|
||||
|
||||
if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)))
|
||||
goto failed;
|
||||
|
||||
close(sock);
|
||||
return (fd);
|
||||
|
|
@ -22,7 +22,7 @@ struct ssh;
|
|||
|
||||
#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
|
||||
# define CUSTOM_SYS_TUN_OPEN
|
||||
int sys_tun_open(int, int);
|
||||
int sys_tun_open(int, int, char **);
|
||||
#endif
|
||||
|
||||
#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF)
|
||||
|
@ -31,4 +31,18 @@ int sys_tun_infilter(struct ssh *, struct Channel *, char *, int);
|
|||
u_char *sys_tun_outfilter(struct ssh *, struct Channel *, u_char **, size_t *);
|
||||
#endif
|
||||
|
||||
#if defined(SYS_RDOMAIN_LINUX)
|
||||
# define HAVE_SYS_GET_RDOMAIN
|
||||
# define HAVE_SYS_SET_RDOMAIN
|
||||
# define HAVE_SYS_VALID_RDOMAIN
|
||||
char *sys_get_rdomain(int fd);
|
||||
int sys_set_rdomain(int fd, const char *name);
|
||||
int sys_valid_rdomain(const char *name);
|
||||
#endif
|
||||
|
||||
#if defined(SYS_RDOMAIN_XXX)
|
||||
# define HAVE_SYS_SET_PROCESS_RDOMAIN
|
||||
void sys_set_process_rdomain(const char *name);
|
||||
#endif
|
||||
|
||||
#endif
|
16
packet.c
16
packet.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: packet.c,v 1.264 2017/09/12 06:32:07 djm Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.266 2017/10/25 00:17:08 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -557,6 +557,18 @@ ssh_local_port(struct ssh *ssh)
|
|||
return ssh->local_port;
|
||||
}
|
||||
|
||||
/* Returns the routing domain of the input socket, or NULL if unavailable */
|
||||
const char *
|
||||
ssh_packet_rdomain_in(struct ssh *ssh)
|
||||
{
|
||||
if (ssh->rdomain_in != NULL)
|
||||
return ssh->rdomain_in;
|
||||
if (!ssh_packet_connection_is_on_socket(ssh))
|
||||
return NULL;
|
||||
ssh->rdomain_in = get_rdomain(ssh->state->connection_in);
|
||||
return ssh->rdomain_in;
|
||||
}
|
||||
|
||||
/* Closes the connection and clears and frees internal data structures. */
|
||||
|
||||
static void
|
||||
|
@ -1774,6 +1786,8 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...)
|
|||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
debug3("sending debug message: %s", buf);
|
||||
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 ||
|
||||
(r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */
|
||||
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
|
||||
|
|
4
packet.h
4
packet.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: packet.h,v 1.82 2017/09/12 06:32:07 djm Exp $ */
|
||||
/* $OpenBSD: packet.h,v 1.83 2017/10/25 00:17:08 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -61,6 +61,7 @@ struct ssh {
|
|||
int remote_port;
|
||||
char *local_ipaddr;
|
||||
int local_port;
|
||||
char *rdomain_in;
|
||||
|
||||
/* Optional preamble for log messages (e.g. username) */
|
||||
char *log_preamble;
|
||||
|
@ -162,6 +163,7 @@ const char *ssh_remote_ipaddr(struct ssh *);
|
|||
int ssh_remote_port(struct ssh *);
|
||||
const char *ssh_local_ipaddr(struct ssh *);
|
||||
int ssh_local_port(struct ssh *);
|
||||
const char *ssh_packet_rdomain_in(struct ssh *);
|
||||
|
||||
void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, u_int32_t);
|
||||
time_t ssh_packet_get_rekey_timeout(struct ssh *);
|
||||
|
|
54
readconf.c
54
readconf.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: readconf.c,v 1.279 2017/09/21 19:16:53 markus Exp $ */
|
||||
/* $OpenBSD: readconf.c,v 1.280 2017/10/21 23:06:24 millert Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -689,34 +689,6 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Check and prepare a domain name: removes trailing '.' and lowercases */
|
||||
static void
|
||||
valid_domain(char *name, const char *filename, int linenum)
|
||||
{
|
||||
size_t i, l = strlen(name);
|
||||
u_char c, last = '\0';
|
||||
|
||||
if (l == 0)
|
||||
fatal("%s line %d: empty hostname suffix", filename, linenum);
|
||||
if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
|
||||
fatal("%s line %d: hostname suffix \"%.100s\" "
|
||||
"starts with invalid character", filename, linenum, name);
|
||||
for (i = 0; i < l; i++) {
|
||||
c = tolower((u_char)name[i]);
|
||||
name[i] = (char)c;
|
||||
if (last == '.' && c == '.')
|
||||
fatal("%s line %d: hostname suffix \"%.100s\" contains "
|
||||
"consecutive separators", filename, linenum, name);
|
||||
if (c != '.' && c != '-' && !isalnum(c) &&
|
||||
c != '_') /* technically invalid, but common */
|
||||
fatal("%s line %d: hostname suffix \"%.100s\" contains "
|
||||
"invalid characters", filename, linenum, name);
|
||||
last = c;
|
||||
}
|
||||
if (name[l - 1] == '.')
|
||||
name[l - 1] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of the token pointed to by cp or oBadOption.
|
||||
*/
|
||||
|
@ -1568,7 +1540,11 @@ parse_keytypes:
|
|||
case oCanonicalDomains:
|
||||
value = options->num_canonical_domains != 0;
|
||||
while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
|
||||
valid_domain(arg, filename, linenum);
|
||||
const char *errstr;
|
||||
if (!valid_domain(arg, 1, &errstr)) {
|
||||
fatal("%s line %d: %s", filename, linenum,
|
||||
errstr);
|
||||
}
|
||||
if (!*activep || value)
|
||||
continue;
|
||||
if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
|
||||
|
@ -2311,11 +2287,13 @@ parse_jump(const char *s, Options *o, int active)
|
|||
|
||||
if (first) {
|
||||
/* First argument and configuration is active */
|
||||
if (parse_user_host_port(cp, &user, &host, &port) != 0)
|
||||
if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
|
||||
parse_user_host_port(cp, &user, &host, &port) != 0)
|
||||
goto out;
|
||||
} else {
|
||||
/* Subsequent argument or inactive configuration */
|
||||
if (parse_user_host_port(cp, NULL, NULL, NULL) != 0)
|
||||
if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
|
||||
parse_user_host_port(cp, NULL, NULL, NULL) != 0)
|
||||
goto out;
|
||||
}
|
||||
first = 0; /* only check syntax for subsequent hosts */
|
||||
|
@ -2340,6 +2318,18 @@ parse_jump(const char *s, Options *o, int active)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
|
||||
{
|
||||
char *path;
|
||||
int r;
|
||||
|
||||
r = parse_uri("ssh", uri, userp, hostp, portp, &path);
|
||||
if (r == 0 && path != NULL)
|
||||
r = -1; /* path not allowed */
|
||||
return r;
|
||||
}
|
||||
|
||||
/* XXX the following is a near-vebatim copy from servconf.c; refactor */
|
||||
static const char *
|
||||
fmt_multistate_int(int val, const struct multistate *m)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: readconf.h,v 1.123 2017/09/03 23:33:13 djm Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.124 2017/10/21 23:06:24 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -204,6 +204,7 @@ int read_config_file(const char *, struct passwd *, const char *,
|
|||
const char *, Options *, int);
|
||||
int parse_forward(struct Forward *, const char *, int, int);
|
||||
int parse_jump(const char *, Options *, int);
|
||||
int parse_ssh_uri(const char *, char **, char **, int *);
|
||||
int default_ssh_port(void);
|
||||
int option_clear_or_none(const char *);
|
||||
void dump_client_config(Options *o, const char *host);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: Makefile,v 1.95 2017/06/24 06:35:24 djm Exp $
|
||||
# $OpenBSD: Makefile,v 1.96 2017/10/24 19:33:32 millert Exp $
|
||||
|
||||
REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec
|
||||
tests: prep $(REGRESS_TARGETS)
|
||||
|
@ -19,6 +19,7 @@ distclean: clean
|
|||
LTESTS= connect \
|
||||
proxy-connect \
|
||||
connect-privsep \
|
||||
connect-uri \
|
||||
proto-version \
|
||||
proto-mismatch \
|
||||
exit-status \
|
||||
|
@ -42,6 +43,7 @@ LTESTS= connect \
|
|||
keygen-moduli \
|
||||
key-options \
|
||||
scp \
|
||||
scp-uri \
|
||||
sftp \
|
||||
sftp-chroot \
|
||||
sftp-cmds \
|
||||
|
@ -49,6 +51,7 @@ LTESTS= connect \
|
|||
sftp-batch \
|
||||
sftp-glob \
|
||||
sftp-perm \
|
||||
sftp-uri \
|
||||
reconfigure \
|
||||
dynamic-forward \
|
||||
forwarding \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: agent-ptrace.sh,v 1.2 2014/02/27 21:21:25 djm Exp $
|
||||
# $OpenBSD: agent-ptrace.sh,v 1.3 2015/09/11 04:55:01 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="disallow agent ptrace attach"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Public Domain
|
||||
# Zev Weiss, 2016
|
||||
# $OpenBSD: allow-deny-users.sh,v 1.4 2017/10/20 02:13:41 djm Exp $
|
||||
|
||||
tid="AllowUsers/DenyUsers"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: authinfo.sh,v 1.1 2017/06/24 06:35:24 djm Exp $
|
||||
# $OpenBSD: authinfo.sh,v 1.2 2017/10/25 20:08:36 millert Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="authinfo"
|
||||
|
@ -6,7 +6,7 @@ tid="authinfo"
|
|||
# Ensure the environment variable doesn't leak when ExposeAuthInfo=no.
|
||||
verbose "ExposeAuthInfo=no"
|
||||
env SSH_USER_AUTH=blah ${SSH} -F $OBJ/ssh_proxy x \
|
||||
'test -z "$SSH_USER_AUTH"' || fail "SSH_USER_AUTH present"
|
||||
'printenv SSH_USER_AUTH >/dev/null' && fail "SSH_USER_AUTH present"
|
||||
|
||||
verbose "ExposeAuthInfo=yes"
|
||||
echo ExposeAuthInfo=yes >> $OBJ/sshd_proxy
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: cfgmatch.sh,v 1.10 2017/04/30 23:34:55 djm Exp $
|
||||
# $OpenBSD: cfgmatch.sh,v 1.11 2017/10/04 18:50:23 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="sshd_config match"
|
||||
|
@ -41,7 +41,7 @@ stop_client()
|
|||
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
|
||||
echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_config
|
||||
echo "Match Address 127.0.0.1" >>$OBJ/sshd_config
|
||||
echo "PermitOpen 127.0.0.1:$PORT" >>$OBJ/sshd_config
|
||||
echo "PermitOpen 127.0.0.1:2 127.0.0.1:3 127.0.0.1:$PORT" >>$OBJ/sshd_config
|
||||
|
||||
grep -v AuthorizedKeysFile $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
|
||||
echo "AuthorizedKeysFile /dev/null" >>$OBJ/sshd_proxy
|
||||
|
@ -49,7 +49,7 @@ echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_proxy
|
|||
echo "Match user $USER" >>$OBJ/sshd_proxy
|
||||
echo "AuthorizedKeysFile /dev/null $OBJ/authorized_keys_%u" >>$OBJ/sshd_proxy
|
||||
echo "Match Address 127.0.0.1" >>$OBJ/sshd_proxy
|
||||
echo "PermitOpen 127.0.0.1:$PORT" >>$OBJ/sshd_proxy
|
||||
echo "PermitOpen 127.0.0.1:2 127.0.0.1:3 127.0.0.1:$PORT" >>$OBJ/sshd_proxy
|
||||
|
||||
start_sshd
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# $OpenBSD: connect-uri.sh,v 1.1 2017/10/24 19:33:32 millert Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="uri connect"
|
||||
|
||||
# Remove Port and User from ssh_config, we want to rely on the URI
|
||||
cp $OBJ/ssh_config $OBJ/ssh_config.orig
|
||||
egrep -v '^ +(Port|User) +.*$' $OBJ/ssh_config.orig > $OBJ/ssh_config
|
||||
|
||||
start_sshd
|
||||
|
||||
verbose "$tid: no trailing slash"
|
||||
${SSH} -F $OBJ/ssh_config "ssh://${USER}@somehost:${PORT}" true
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh connection failed"
|
||||
fi
|
||||
|
||||
verbose "$tid: trailing slash"
|
||||
${SSH} -F $OBJ/ssh_config "ssh://${USER}@somehost:${PORT}/" true
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh connection failed"
|
||||
fi
|
||||
|
||||
verbose "$tid: with path name"
|
||||
${SSH} -F $OBJ/ssh_config "ssh://${USER}@somehost:${PORT}/${DATA}" true \
|
||||
> /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
fail "ssh connection succeeded, expected failure"
|
||||
fi
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: keys-command.sh,v 1.3 2015/05/21 06:40:02 djm Exp $
|
||||
# $OpenBSD: keys-command.sh,v 1.4 2016/09/26 21:34:38 bluhm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="authorized keys from command"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: keytype.sh,v 1.5 2017/03/20 22:08:06 djm Exp $
|
||||
# $OpenBSD: keytype.sh,v 1.6 2017/10/30 22:01:52 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="login with different key types"
|
||||
|
@ -17,7 +17,7 @@ for i in `$SSH -Q key`; do
|
|||
esac
|
||||
done
|
||||
|
||||
for kt in $ktypes; do
|
||||
for kt in $ktypes; do
|
||||
rm -f $OBJ/key.$kt
|
||||
bits=`echo ${kt} | awk -F- '{print $2}'`
|
||||
type=`echo ${kt} | awk -F- '{print $1}'`
|
||||
|
@ -27,10 +27,10 @@ for kt in $ktypes; do
|
|||
done
|
||||
|
||||
tries="1 2 3"
|
||||
for ut in $ktypes; do
|
||||
for ut in $ktypes; do
|
||||
htypes=$ut
|
||||
#htypes=$ktypes
|
||||
for ht in $htypes; do
|
||||
for ht in $htypes; do
|
||||
case $ht in
|
||||
dsa-1024) t=ssh-dss;;
|
||||
ecdsa-256) t=ecdsa-sha2-nistp256;;
|
||||
|
@ -42,13 +42,13 @@ for ut in $ktypes; do
|
|||
trace "ssh connect, userkey $ut, hostkey $ht"
|
||||
(
|
||||
grep -v HostKey $OBJ/sshd_proxy_bak
|
||||
echo HostKey $OBJ/key.$ht
|
||||
echo HostKey $OBJ/key.$ht
|
||||
echo PubkeyAcceptedKeyTypes $t
|
||||
echo HostKeyAlgorithms $t
|
||||
) > $OBJ/sshd_proxy
|
||||
(
|
||||
grep -v IdentityFile $OBJ/ssh_proxy_bak
|
||||
echo IdentityFile $OBJ/key.$ut
|
||||
echo IdentityFile $OBJ/key.$ut
|
||||
echo PubkeyAcceptedKeyTypes $t
|
||||
echo HostKeyAlgorithms $t
|
||||
) > $OBJ/ssh_proxy
|
||||
|
|
|
@ -30,3 +30,5 @@ Limitations: kexfuzz can't change the ordering of packets at
|
|||
present. It is limited to replacing individual packets with
|
||||
fuzzed variants with the same type. It really should allow
|
||||
insertion, deletion on replacement of packets too.
|
||||
|
||||
$OpenBSD: README,v 1.3 2017/10/20 02:13:41 djm Exp $
|
||||
|
|
|
@ -1,25 +1,19 @@
|
|||
# $OpenBSD: proxy-connect.sh,v 1.10 2017/04/30 23:34:55 djm Exp $
|
||||
# $OpenBSD: proxy-connect.sh,v 1.11 2017/09/26 22:39:25 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="proxy connect"
|
||||
|
||||
mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
|
||||
|
||||
for ps in no yes; do
|
||||
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
|
||||
echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy
|
||||
for c in no yes; do
|
||||
verbose "plain username privsep=$ps comp=$c"
|
||||
opts="-oCompression=$c -F $OBJ/ssh_proxy"
|
||||
SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'`
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh proxyconnect privsep=$ps comp=$c failed"
|
||||
fi
|
||||
if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
|
||||
fail "bad SSH_CONNECTION privsep=$ps comp=$c: " \
|
||||
"$SSH_CONNECTION"
|
||||
fi
|
||||
done
|
||||
for c in no yes; do
|
||||
verbose "plain username comp=$c"
|
||||
opts="-oCompression=$c -F $OBJ/ssh_proxy"
|
||||
SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'`
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh proxyconnect comp=$c failed"
|
||||
fi
|
||||
if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
|
||||
fail "bad SSH_CONNECTION comp=$c: " \
|
||||
"$SSH_CONNECTION"
|
||||
fi
|
||||
done
|
||||
|
||||
verbose "username with style"
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
# $OpenBSD: scp-uri.sh,v 1.1 2017/10/24 19:33:32 millert Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="scp-uri"
|
||||
|
||||
#set -x
|
||||
|
||||
COPY2=${OBJ}/copy2
|
||||
DIR=${COPY}.dd
|
||||
DIR2=${COPY}.dd2
|
||||
|
||||
SRC=`dirname ${SCRIPT}`
|
||||
cp ${SRC}/scp-ssh-wrapper.sh ${OBJ}/scp-ssh-wrapper.scp
|
||||
chmod 755 ${OBJ}/scp-ssh-wrapper.scp
|
||||
scpopts="-q -S ${OBJ}/scp-ssh-wrapper.scp"
|
||||
export SCP # used in scp-ssh-wrapper.scp
|
||||
|
||||
scpclean() {
|
||||
rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2}
|
||||
mkdir ${DIR} ${DIR2}
|
||||
}
|
||||
|
||||
# Remove Port and User from ssh_config, we want to rely on the URI
|
||||
cp $OBJ/ssh_config $OBJ/ssh_config.orig
|
||||
egrep -v '^ +(Port|User) +.*$' $OBJ/ssh_config.orig > $OBJ/ssh_config
|
||||
|
||||
verbose "$tid: simple copy local file to remote file"
|
||||
scpclean
|
||||
$SCP $scpopts ${DATA} "scp://${USER}@somehost:${PORT}/${COPY}" || fail "copy failed"
|
||||
cmp ${DATA} ${COPY} || fail "corrupted copy"
|
||||
|
||||
verbose "$tid: simple copy remote file to local file"
|
||||
scpclean
|
||||
$SCP $scpopts "scp://${USER}@somehost:${PORT}/${DATA}" ${COPY} || fail "copy failed"
|
||||
cmp ${DATA} ${COPY} || fail "corrupted copy"
|
||||
|
||||
verbose "$tid: simple copy local file to remote dir"
|
||||
scpclean
|
||||
cp ${DATA} ${COPY}
|
||||
$SCP $scpopts ${COPY} "scp://${USER}@somehost:${PORT}/${DIR}" || fail "copy failed"
|
||||
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
|
||||
|
||||
verbose "$tid: simple copy remote file to local dir"
|
||||
scpclean
|
||||
cp ${DATA} ${COPY}
|
||||
$SCP $scpopts "scp://${USER}@somehost:${PORT}/${COPY}" ${DIR} || fail "copy failed"
|
||||
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
|
||||
|
||||
verbose "$tid: recursive local dir to remote dir"
|
||||
scpclean
|
||||
rm -rf ${DIR2}
|
||||
cp ${DATA} ${DIR}/copy
|
||||
$SCP $scpopts -r ${DIR} "scp://${USER}@somehost:${PORT}/${DIR2}" || fail "copy failed"
|
||||
diff -rN ${DIR} ${DIR2} || fail "corrupted copy"
|
||||
|
||||
verbose "$tid: recursive remote dir to local dir"
|
||||
scpclean
|
||||
rm -rf ${DIR2}
|
||||
cp ${DATA} ${DIR}/copy
|
||||
$SCP $scpopts -r "scp://${USER}@somehost:${PORT}/${DIR}" ${DIR2} || fail "copy failed"
|
||||
diff -rN ${DIR} ${DIR2} || fail "corrupted copy"
|
||||
|
||||
# TODO: scp -3
|
||||
|
||||
scpclean
|
||||
rm -f ${OBJ}/scp-ssh-wrapper.exe
|
|
@ -0,0 +1,63 @@
|
|||
# $OpenBSD: sftp-uri.sh,v 1.1 2017/10/24 19:33:32 millert Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="sftp-uri"
|
||||
|
||||
#set -x
|
||||
|
||||
COPY2=${OBJ}/copy2
|
||||
DIR=${COPY}.dd
|
||||
DIR2=${COPY}.dd2
|
||||
SRC=`dirname ${SCRIPT}`
|
||||
|
||||
sftpclean() {
|
||||
rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2}
|
||||
mkdir ${DIR} ${DIR2}
|
||||
}
|
||||
|
||||
start_sshd -oForceCommand="internal-sftp -d /"
|
||||
|
||||
# Remove Port and User from ssh_config, we want to rely on the URI
|
||||
cp $OBJ/ssh_config $OBJ/ssh_config.orig
|
||||
egrep -v '^ +(Port|User) +.*$' $OBJ/ssh_config.orig > $OBJ/ssh_config
|
||||
|
||||
verbose "$tid: non-interactive fetch to local file"
|
||||
sftpclean
|
||||
${SFTP} -q -S "$SSH" -F $OBJ/ssh_config "sftp://${USER}@somehost:${PORT}/${DATA}" ${COPY} || fail "copy failed"
|
||||
cmp ${DATA} ${COPY} || fail "corrupted copy"
|
||||
|
||||
verbose "$tid: non-interactive fetch to local dir"
|
||||
sftpclean
|
||||
cp ${DATA} ${COPY}
|
||||
${SFTP} -q -S "$SSH" -F $OBJ/ssh_config "sftp://${USER}@somehost:${PORT}/${COPY}" ${DIR} || fail "copy failed"
|
||||
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
|
||||
|
||||
verbose "$tid: put to remote directory (trailing slash)"
|
||||
sftpclean
|
||||
${SFTP} -q -S "$SSH" -F $OBJ/ssh_config -b /dev/stdin \
|
||||
"sftp://${USER}@somehost:${PORT}/${DIR}/" > /dev/null 2>&1 << EOF
|
||||
version
|
||||
put ${DATA} copy
|
||||
EOF
|
||||
r=$?
|
||||
if [ $r -ne 0 ]; then
|
||||
fail "sftp failed with $r"
|
||||
else
|
||||
cmp ${DATA} ${DIR}/copy || fail "corrupted copy"
|
||||
fi
|
||||
|
||||
verbose "$tid: put to remote directory (no slash)"
|
||||
sftpclean
|
||||
${SFTP} -q -S "$SSH" -F $OBJ/ssh_config -b /dev/stdin \
|
||||
"sftp://${USER}@somehost:${PORT}/${DIR}" > /dev/null 2>&1 << EOF
|
||||
version
|
||||
put ${DATA} copy
|
||||
EOF
|
||||
r=$?
|
||||
if [ $r -ne 0 ]; then
|
||||
fail "sftp failed with $r"
|
||||
else
|
||||
cmp ${DATA} ${DIR}/copy || fail "corrupted copy"
|
||||
fi
|
||||
|
||||
sftpclean
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: sftp.sh,v 1.5 2013/05/17 10:28:11 dtucker Exp $
|
||||
# $OpenBSD: sftp.sh,v 1.6 2017/10/30 21:59:43 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="basic sftp put/get"
|
||||
|
@ -22,11 +22,11 @@ for B in ${BUFFERSIZE}; do
|
|||
r=$?
|
||||
if [ $r -ne 0 ]; then
|
||||
fail "sftp failed with $r"
|
||||
else
|
||||
else
|
||||
cmp $DATA ${COPY}.1 || fail "corrupted copy after get"
|
||||
cmp $DATA ${COPY}.2 || fail "corrupted copy after put"
|
||||
fi
|
||||
done
|
||||
done
|
||||
rm -f ${COPY}.1 ${COPY}.2
|
||||
rm -f ${COPY}.1 ${COPY}.2
|
||||
rm -f $SFTPCMDFILE
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
# $OpenBSD: sshd-log-wrapper.sh,v 1.3 2013/04/07 02:16:03 dtucker Exp $
|
||||
# $OpenBSD: sshd-log-wrapper.sh,v 1.4 2016/11/25 02:56:49 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
#
|
||||
# simple wrapper for sshd proxy mode to catch stderr output
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: yes-head.sh,v 1.5 2015/03/03 22:35:19 markus Exp $
|
||||
# $OpenBSD: yes-head.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="yes pipe head"
|
||||
|
|
44
scp.1
44
scp.1
|
@ -8,9 +8,9 @@
|
|||
.\"
|
||||
.\" Created: Sun May 7 00:14:37 1995 ylo
|
||||
.\"
|
||||
.\" $OpenBSD: scp.1,v 1.74 2017/05/03 21:49:18 naddy Exp $
|
||||
.\" $OpenBSD: scp.1,v 1.76 2017/10/25 06:19:46 jmc Exp $
|
||||
.\"
|
||||
.Dd $Mdocdate: May 3 2017 $
|
||||
.Dd $Mdocdate: October 25 2017 $
|
||||
.Dt SCP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -18,7 +18,6 @@
|
|||
.Nd secure copy (remote file copy program)
|
||||
.Sh SYNOPSIS
|
||||
.Nm scp
|
||||
.Bk -words
|
||||
.Op Fl 346BCpqrv
|
||||
.Op Fl c Ar cipher
|
||||
.Op Fl F Ar ssh_config
|
||||
|
@ -27,20 +26,7 @@
|
|||
.Op Fl o Ar ssh_option
|
||||
.Op Fl P Ar port
|
||||
.Op Fl S Ar program
|
||||
.Sm off
|
||||
.Oo
|
||||
.Op Ar user No @
|
||||
.Ar host1 :
|
||||
.Oc Ar file1
|
||||
.Sm on
|
||||
.Ar ...
|
||||
.Sm off
|
||||
.Oo
|
||||
.Op Ar user No @
|
||||
.Ar host2 :
|
||||
.Oc Ar file2
|
||||
.Sm on
|
||||
.Ek
|
||||
.Ar source ... target
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
copies files between hosts on a network.
|
||||
|
@ -53,15 +39,33 @@ same security as
|
|||
will ask for passwords or passphrases if they are needed for
|
||||
authentication.
|
||||
.Pp
|
||||
File names may contain a user and host specification to indicate
|
||||
that the file is to be copied to/from that host.
|
||||
The
|
||||
.Ar source
|
||||
and
|
||||
.Ar target
|
||||
may be specified as a local pathname, a remote host with optional path
|
||||
in the form
|
||||
.Sm off
|
||||
.Oo user @ Oc host : Op path ,
|
||||
.Sm on
|
||||
or a URI in the form
|
||||
.Sm off
|
||||
.No scp:// Oo user @ Oc host Oo : port Oc Op / path .
|
||||
.Sm on
|
||||
Local file names can be made explicit using absolute or relative pathnames
|
||||
to avoid
|
||||
.Nm
|
||||
treating file names containing
|
||||
.Sq :\&
|
||||
as host specifiers.
|
||||
Copies between two remote hosts are also permitted.
|
||||
.Pp
|
||||
When copying between two remote hosts, if the URI format is used, a
|
||||
.Ar port
|
||||
may only be specified on the
|
||||
.Ar target
|
||||
if the
|
||||
.Fl 3
|
||||
option is used.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
|
|
197
scp.c
197
scp.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: scp.c,v 1.192 2017/05/31 09:15:42 deraadt Exp $ */
|
||||
/* $OpenBSD: scp.c,v 1.193 2017/10/21 23:06:24 millert Exp $ */
|
||||
/*
|
||||
* scp - secure remote copy. This is basically patched BSD rcp which
|
||||
* uses ssh to do the data transfer (instead of using rcmd).
|
||||
|
@ -112,6 +112,7 @@
|
|||
#endif
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "atomicio.h"
|
||||
#include "pathnames.h"
|
||||
#include "log.h"
|
||||
|
@ -123,8 +124,8 @@ extern char *__progname;
|
|||
|
||||
#define COPY_BUFLEN 16384
|
||||
|
||||
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
|
||||
int do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout);
|
||||
int do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout);
|
||||
int do_cmd2(char *host, char *remuser, int port, char *cmd, int fdin, int fdout);
|
||||
|
||||
/* Struct for addargs */
|
||||
arglist args;
|
||||
|
@ -149,6 +150,9 @@ int showprogress = 1;
|
|||
*/
|
||||
int throughlocal = 0;
|
||||
|
||||
/* Non-standard port to use for the ssh connection or -1. */
|
||||
int sshport = -1;
|
||||
|
||||
/* This is the program to execute for the secured connection. ("ssh" or -S) */
|
||||
char *ssh_program = _PATH_SSH_PROGRAM;
|
||||
|
||||
|
@ -252,7 +256,7 @@ do_local_cmd(arglist *a)
|
|||
*/
|
||||
|
||||
int
|
||||
do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
|
||||
do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
|
||||
{
|
||||
int pin[2], pout[2], reserved[2];
|
||||
|
||||
|
@ -262,6 +266,9 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
|
|||
ssh_program, host,
|
||||
remuser ? remuser : "(unspecified)", cmd);
|
||||
|
||||
if (port == -1)
|
||||
port = sshport;
|
||||
|
||||
/*
|
||||
* Reserve two descriptors so that the real pipes won't get
|
||||
* descriptors 0 and 1 because that will screw up dup2 below.
|
||||
|
@ -313,6 +320,10 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
|
|||
close(pout[1]);
|
||||
|
||||
replacearg(&args, 0, "%s", ssh_program);
|
||||
if (port != -1) {
|
||||
addargs(&args, "-p");
|
||||
addargs(&args, "%d", port);
|
||||
}
|
||||
if (remuser != NULL) {
|
||||
addargs(&args, "-l");
|
||||
addargs(&args, "%s", remuser);
|
||||
|
@ -344,7 +355,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
|
|||
* This way the input and output of two commands can be connected.
|
||||
*/
|
||||
int
|
||||
do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
|
||||
do_cmd2(char *host, char *remuser, int port, char *cmd, int fdin, int fdout)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
@ -355,6 +366,9 @@ do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
|
|||
ssh_program, host,
|
||||
remuser ? remuser : "(unspecified)", cmd);
|
||||
|
||||
if (port == -1)
|
||||
port = sshport;
|
||||
|
||||
/* Fork a child to execute the command on the remote host using ssh. */
|
||||
#ifdef WINDOWS
|
||||
/* generate command line and spawn_child */
|
||||
|
@ -377,6 +391,10 @@ do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
|
|||
dup2(fdout, 1);
|
||||
|
||||
replacearg(&args, 0, "%s", ssh_program);
|
||||
if (port != -1) {
|
||||
addargs(&args, "-p");
|
||||
addargs(&args, "%d", port);
|
||||
}
|
||||
if (remuser != NULL) {
|
||||
addargs(&args, "-l");
|
||||
addargs(&args, "%s", remuser);
|
||||
|
@ -421,14 +439,14 @@ void rsource(char *, struct stat *);
|
|||
void sink(int, char *[]);
|
||||
void source(int, char *[]);
|
||||
void tolocal(int, char *[]);
|
||||
void toremote(char *, int, char *[]);
|
||||
void toremote(int, char *[]);
|
||||
void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, fflag, tflag, status, n;
|
||||
char *targ, **newargv;
|
||||
char **newargv;
|
||||
const char *errstr;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
@ -484,10 +502,9 @@ main(int argc, char **argv)
|
|||
addargs(&args, "%s", optarg);
|
||||
break;
|
||||
case 'P':
|
||||
addargs(&remote_remote_args, "-p");
|
||||
addargs(&remote_remote_args, "%s", optarg);
|
||||
addargs(&args, "-p");
|
||||
addargs(&args, "%s", optarg);
|
||||
sshport = a2port(optarg);
|
||||
if (sshport <= 0)
|
||||
fatal("bad port \"%s\"\n", optarg);
|
||||
break;
|
||||
case 'B':
|
||||
addargs(&remote_remote_args, "-oBatchmode=yes");
|
||||
|
@ -604,8 +621,8 @@ main(int argc, char **argv)
|
|||
|
||||
(void) signal(SIGPIPE, lostconn);
|
||||
|
||||
if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */
|
||||
toremote(targ, argc, argv);
|
||||
if (colon(argv[argc - 1])) /* Dest is remote host. */
|
||||
toremote(argc, argv);
|
||||
else {
|
||||
if (targetshouldbedirectory)
|
||||
verifydir(argv[argc - 1]);
|
||||
|
@ -661,71 +678,65 @@ do_times(int fd, int verb, const struct stat *sb)
|
|||
}
|
||||
|
||||
void
|
||||
toremote(char *targ, int argc, char **argv)
|
||||
toremote(int argc, char **argv)
|
||||
{
|
||||
char *bp, *host, *src, *suser, *thost, *tuser, *arg;
|
||||
char *suser = NULL, *host = NULL, *src = NULL;
|
||||
char *bp, *tuser, *thost, *targ;
|
||||
int sport = -1, tport = -1;
|
||||
arglist alist;
|
||||
int i;
|
||||
int i, r;
|
||||
u_int j;
|
||||
|
||||
memset(&alist, '\0', sizeof(alist));
|
||||
alist.list = NULL;
|
||||
|
||||
*targ++ = 0;
|
||||
if (*targ == 0)
|
||||
targ = ".";
|
||||
|
||||
arg = xstrdup(argv[argc - 1]);
|
||||
if ((thost = strrchr(arg, '@'))) {
|
||||
/* user@host */
|
||||
*thost++ = 0;
|
||||
tuser = arg;
|
||||
if (*tuser == '\0')
|
||||
tuser = NULL;
|
||||
} else {
|
||||
thost = arg;
|
||||
tuser = NULL;
|
||||
}
|
||||
|
||||
if (tuser != NULL && !okname(tuser)) {
|
||||
free(arg);
|
||||
return;
|
||||
/* Parse target */
|
||||
r = parse_uri("scp", argv[argc - 1], &tuser, &thost, &tport, &targ);
|
||||
if (r == -1)
|
||||
goto out; /* invalid URI */
|
||||
if (r != 0) {
|
||||
if (parse_user_host_path(argv[argc - 1], &tuser, &thost,
|
||||
&targ) == -1)
|
||||
goto out;
|
||||
}
|
||||
if (tuser != NULL && !okname(tuser))
|
||||
goto out;
|
||||
|
||||
/* Parse source files */
|
||||
for (i = 0; i < argc - 1; i++) {
|
||||
src = colon(argv[i]);
|
||||
if (src && throughlocal) { /* extended remote to remote */
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = ".";
|
||||
host = strrchr(argv[i], '@');
|
||||
if (host) {
|
||||
*host++ = 0;
|
||||
host = cleanhostname(host);
|
||||
suser = argv[i];
|
||||
if (*suser == '\0')
|
||||
suser = pwd->pw_name;
|
||||
else if (!okname(suser))
|
||||
continue;
|
||||
} else {
|
||||
host = cleanhostname(argv[i]);
|
||||
suser = NULL;
|
||||
}
|
||||
free(suser);
|
||||
free(host);
|
||||
free(src);
|
||||
r = parse_uri("scp", argv[i], &suser, &host, &sport, &src);
|
||||
if (r == -1)
|
||||
continue; /* invalid URI */
|
||||
if (r != 0)
|
||||
parse_user_host_path(argv[i], &suser, &host, &src);
|
||||
if (suser != NULL && !okname(suser)) {
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
if (host && throughlocal) { /* extended remote to remote */
|
||||
xasprintf(&bp, "%s -f %s%s", cmd,
|
||||
*src == '-' ? "-- " : "", src);
|
||||
if (do_cmd(host, suser, bp, &remin, &remout) < 0)
|
||||
if (do_cmd(host, suser, sport, bp, &remin, &remout) < 0)
|
||||
exit(1);
|
||||
free(bp);
|
||||
host = cleanhostname(thost);
|
||||
xasprintf(&bp, "%s -t %s%s", cmd,
|
||||
*targ == '-' ? "-- " : "", targ);
|
||||
if (do_cmd2(host, tuser, bp, remin, remout) < 0)
|
||||
if (do_cmd2(thost, tuser, tport, bp, remin, remout) < 0)
|
||||
exit(1);
|
||||
free(bp);
|
||||
(void) close(remin);
|
||||
(void) close(remout);
|
||||
remin = remout = -1;
|
||||
} else if (src) { /* standard remote to remote */
|
||||
} else if (host) { /* standard remote to remote */
|
||||
if (tport != -1 && tport != SSH_DEFAULT_PORT) {
|
||||
/* This would require the remote support URIs */
|
||||
fatal("target port not supported with two "
|
||||
"remote hosts without the -3 option");
|
||||
}
|
||||
|
||||
freeargs(&alist);
|
||||
addargs(&alist, "%s", ssh_program);
|
||||
addargs(&alist, "-x");
|
||||
|
@ -735,23 +746,14 @@ toremote(char *targ, int argc, char **argv)
|
|||
addargs(&alist, "%s",
|
||||
remote_remote_args.list[j]);
|
||||
}
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = ".";
|
||||
host = strrchr(argv[i], '@');
|
||||
|
||||
if (host) {
|
||||
*host++ = 0;
|
||||
host = cleanhostname(host);
|
||||
suser = argv[i];
|
||||
if (*suser == '\0')
|
||||
suser = pwd->pw_name;
|
||||
else if (!okname(suser))
|
||||
continue;
|
||||
if (sport != -1) {
|
||||
addargs(&alist, "-p");
|
||||
addargs(&alist, "%d", sport);
|
||||
}
|
||||
if (suser) {
|
||||
addargs(&alist, "-l");
|
||||
addargs(&alist, "%s", suser);
|
||||
} else {
|
||||
host = cleanhostname(argv[i]);
|
||||
}
|
||||
addargs(&alist, "--");
|
||||
addargs(&alist, "%s", host);
|
||||
|
@ -766,8 +768,7 @@ toremote(char *targ, int argc, char **argv)
|
|||
if (remin == -1) {
|
||||
xasprintf(&bp, "%s -t %s%s", cmd,
|
||||
*targ == '-' ? "-- " : "", targ);
|
||||
host = cleanhostname(thost);
|
||||
if (do_cmd(host, tuser, bp, &remin,
|
||||
if (do_cmd(thost, tuser, tport, bp, &remin,
|
||||
&remout) < 0)
|
||||
exit(1);
|
||||
if (response() < 0)
|
||||
|
@ -777,21 +778,41 @@ toremote(char *targ, int argc, char **argv)
|
|||
source(1, argv + i);
|
||||
}
|
||||
}
|
||||
free(arg);
|
||||
out:
|
||||
free(tuser);
|
||||
free(thost);
|
||||
free(targ);
|
||||
free(suser);
|
||||
free(host);
|
||||
free(src);
|
||||
}
|
||||
|
||||
void
|
||||
tolocal(int argc, char **argv)
|
||||
{
|
||||
char *bp, *host, *src, *suser;
|
||||
char *bp, *host = NULL, *src = NULL, *suser = NULL;
|
||||
arglist alist;
|
||||
int i;
|
||||
int i, r, sport = -1;
|
||||
|
||||
memset(&alist, '\0', sizeof(alist));
|
||||
alist.list = NULL;
|
||||
|
||||
for (i = 0; i < argc - 1; i++) {
|
||||
if (!(src = colon(argv[i]))) { /* Local to local. */
|
||||
free(suser);
|
||||
free(host);
|
||||
free(src);
|
||||
r = parse_uri("scp", argv[i], &suser, &host, &sport, &src);
|
||||
if (r == -1) {
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
if (r != 0)
|
||||
parse_user_host_path(argv[i], &suser, &host, &src);
|
||||
if (suser != NULL && !okname(suser)) {
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
if (!host) { /* Local to local. */
|
||||
freeargs(&alist);
|
||||
#ifdef WINDOWS
|
||||
#define _PATH_XCOPY "xcopy"
|
||||
|
@ -841,22 +862,10 @@ tolocal(int argc, char **argv)
|
|||
++errs;
|
||||
continue;
|
||||
}
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = ".";
|
||||
if ((host = strrchr(argv[i], '@')) == NULL) {
|
||||
host = argv[i];
|
||||
suser = NULL;
|
||||
} else {
|
||||
*host++ = 0;
|
||||
suser = argv[i];
|
||||
if (*suser == '\0')
|
||||
suser = pwd->pw_name;
|
||||
}
|
||||
host = cleanhostname(host);
|
||||
/* Remote to local. */
|
||||
xasprintf(&bp, "%s -f %s%s",
|
||||
cmd, *src == '-' ? "-- " : "", src);
|
||||
if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
|
||||
if (do_cmd(host, suser, sport, bp, &remin, &remout) < 0) {
|
||||
free(bp);
|
||||
++errs;
|
||||
continue;
|
||||
|
@ -866,6 +875,9 @@ tolocal(int argc, char **argv)
|
|||
(void) close(remin);
|
||||
remin = remout = -1;
|
||||
}
|
||||
free(suser);
|
||||
free(host);
|
||||
free(src);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1387,8 +1399,7 @@ usage(void)
|
|||
{
|
||||
(void) fprintf(stderr,
|
||||
"usage: scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
|
||||
" [-l limit] [-o ssh_option] [-P port] [-S program]\n"
|
||||
" [[user@]host1:]file1 ... [[user@]host2:]file2\n");
|
||||
" [-l limit] [-o ssh_option] [-P port] [-S program] source ... target\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
555
servconf.c
555
servconf.c
|
@ -1,5 +1,5 @@
|
|||
|
||||
/* $OpenBSD: servconf.c,v 1.312 2017/10/02 19:33:20 djm Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.320 2017/11/03 05:18:44 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
|
@ -15,10 +15,16 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_SYSCTL_H
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#ifdef HAVE_NET_ROUTE_H
|
||||
#include <net/route.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
|
@ -58,8 +64,10 @@
|
|||
#include "myproposal.h"
|
||||
#include "digest.h"
|
||||
|
||||
static void add_listen_addr(ServerOptions *, char *, int);
|
||||
static void add_one_listen_addr(ServerOptions *, char *, int);
|
||||
static void add_listen_addr(ServerOptions *, const char *,
|
||||
const char *, int);
|
||||
static void add_one_listen_addr(ServerOptions *, const char *,
|
||||
const char *, int);
|
||||
|
||||
/* Use of privilege separation or not */
|
||||
extern int use_privsep;
|
||||
|
@ -81,7 +89,9 @@ initialize_server_options(ServerOptions *options)
|
|||
options->queued_listen_addrs = NULL;
|
||||
options->num_queued_listens = 0;
|
||||
options->listen_addrs = NULL;
|
||||
options->num_listen_addrs = 0;
|
||||
options->address_family = -1;
|
||||
options->routing_domain = NULL;
|
||||
options->num_host_key_files = 0;
|
||||
options->num_host_cert_files = 0;
|
||||
options->host_key_agent = NULL;
|
||||
|
@ -188,10 +198,45 @@ assemble_algorithms(ServerOptions *o)
|
|||
fatal("kex_assemble_names failed");
|
||||
}
|
||||
|
||||
static void
|
||||
array_append(const char *file, const int line, const char *directive,
|
||||
char ***array, u_int *lp, const char *s)
|
||||
{
|
||||
|
||||
if (*lp >= INT_MAX)
|
||||
fatal("%s line %d: Too many %s entries", file, line, directive);
|
||||
|
||||
*array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
|
||||
(*array)[*lp] = xstrdup(s);
|
||||
(*lp)++;
|
||||
}
|
||||
|
||||
void
|
||||
servconf_add_hostkey(const char *file, const int line,
|
||||
ServerOptions *options, const char *path)
|
||||
{
|
||||
char *apath = derelativise_path(path);
|
||||
|
||||
array_append(file, line, "HostKey",
|
||||
&options->host_key_files, &options->num_host_key_files, apath);
|
||||
free(apath);
|
||||
}
|
||||
|
||||
void
|
||||
servconf_add_hostcert(const char *file, const int line,
|
||||
ServerOptions *options, const char *path)
|
||||
{
|
||||
char *apath = derelativise_path(path);
|
||||
|
||||
array_append(file, line, "HostCertificate",
|
||||
&options->host_cert_files, &options->num_host_cert_files, apath);
|
||||
free(apath);
|
||||
}
|
||||
|
||||
void
|
||||
fill_default_server_options(ServerOptions *options)
|
||||
{
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
/* Portable-specific options */
|
||||
if (options->use_pam == -1)
|
||||
|
@ -200,16 +245,16 @@ fill_default_server_options(ServerOptions *options)
|
|||
/* Standard Options */
|
||||
if (options->num_host_key_files == 0) {
|
||||
/* fill default hostkeys for protocols */
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_RSA_KEY_FILE;
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_DSA_KEY_FILE;
|
||||
servconf_add_hostkey("[default]", 0, options,
|
||||
_PATH_HOST_RSA_KEY_FILE);
|
||||
servconf_add_hostkey("[default]", 0, options,
|
||||
_PATH_HOST_DSA_KEY_FILE);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_ECDSA_KEY_FILE;
|
||||
servconf_add_hostkey("[default]", 0, options,
|
||||
_PATH_HOST_ECDSA_KEY_FILE);
|
||||
#endif
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_ED25519_KEY_FILE;
|
||||
servconf_add_hostkey("[default]", 0, options,
|
||||
_PATH_HOST_ED25519_KEY_FILE);
|
||||
}
|
||||
/* No certificates by default */
|
||||
if (options->num_ports == 0)
|
||||
|
@ -217,7 +262,7 @@ fill_default_server_options(ServerOptions *options)
|
|||
if (options->address_family == -1)
|
||||
options->address_family = AF_UNSPEC;
|
||||
if (options->listen_addrs == NULL)
|
||||
add_listen_addr(options, NULL, 0);
|
||||
add_listen_addr(options, NULL, NULL, 0);
|
||||
if (options->pid_file == NULL)
|
||||
options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
|
||||
if (options->login_grace_time == -1)
|
||||
|
@ -313,10 +358,14 @@ fill_default_server_options(ServerOptions *options)
|
|||
if (options->client_alive_count_max == -1)
|
||||
options->client_alive_count_max = 3;
|
||||
if (options->num_authkeys_files == 0) {
|
||||
options->authorized_keys_files[options->num_authkeys_files++] =
|
||||
xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
|
||||
options->authorized_keys_files[options->num_authkeys_files++] =
|
||||
xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
|
||||
array_append("[default]", 0, "AuthorizedKeysFiles",
|
||||
&options->authorized_keys_files,
|
||||
&options->num_authkeys_files,
|
||||
_PATH_SSH_USER_PERMITTED_KEYS);
|
||||
array_append("[default]", 0, "AuthorizedKeysFiles",
|
||||
&options->authorized_keys_files,
|
||||
&options->num_authkeys_files,
|
||||
_PATH_SSH_USER_PERMITTED_KEYS2);
|
||||
}
|
||||
if (options->permit_tun == -1)
|
||||
options->permit_tun = SSH_TUNMODE_NO;
|
||||
|
@ -358,6 +407,7 @@ fill_default_server_options(ServerOptions *options)
|
|||
CLEAR_ON_NONE(options->authorized_principals_file);
|
||||
CLEAR_ON_NONE(options->adm_forced_command);
|
||||
CLEAR_ON_NONE(options->chroot_directory);
|
||||
CLEAR_ON_NONE(options->routing_domain);
|
||||
for (i = 0; i < options->num_host_key_files; i++)
|
||||
CLEAR_ON_NONE(options->host_key_files[i]);
|
||||
for (i = 0; i < options->num_host_cert_files; i++)
|
||||
|
@ -421,7 +471,7 @@ typedef enum {
|
|||
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
|
||||
sStreamLocalBindMask, sStreamLocalBindUnlink,
|
||||
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
|
||||
sExposeAuthInfo,
|
||||
sExposeAuthInfo, sRDomain,
|
||||
sDeprecated, sIgnore, sUnsupported
|
||||
} ServerOpCodes;
|
||||
|
||||
|
@ -566,6 +616,7 @@ static struct {
|
|||
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
|
||||
{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
|
||||
{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
|
||||
{ "rdomain", sRDomain, SSHCFG_ALL },
|
||||
{ NULL, sBadOption, 0 }
|
||||
};
|
||||
|
||||
|
@ -625,23 +676,51 @@ derelativise_path(const char *path)
|
|||
}
|
||||
|
||||
static void
|
||||
add_listen_addr(ServerOptions *options, char *addr, int port)
|
||||
add_listen_addr(ServerOptions *options, const char *addr,
|
||||
const char *rdomain, int port)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
if (port == 0)
|
||||
for (i = 0; i < options->num_ports; i++)
|
||||
add_one_listen_addr(options, addr, options->ports[i]);
|
||||
else
|
||||
add_one_listen_addr(options, addr, port);
|
||||
if (port > 0)
|
||||
add_one_listen_addr(options, addr, rdomain, port);
|
||||
else {
|
||||
for (i = 0; i < options->num_ports; i++) {
|
||||
add_one_listen_addr(options, addr, rdomain,
|
||||
options->ports[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_one_listen_addr(ServerOptions *options, char *addr, int port)
|
||||
add_one_listen_addr(ServerOptions *options, const char *addr,
|
||||
const char *rdomain, int port)
|
||||
{
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
char strport[NI_MAXSERV];
|
||||
int gaierr;
|
||||
u_int i;
|
||||
|
||||
/* Find listen_addrs entry for this rdomain */
|
||||
for (i = 0; i < options->num_listen_addrs; i++) {
|
||||
if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
|
||||
break;
|
||||
if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
|
||||
continue;
|
||||
if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
|
||||
break;
|
||||
}
|
||||
if (i >= options->num_listen_addrs) {
|
||||
/* No entry for this rdomain; allocate one */
|
||||
if (i >= INT_MAX)
|
||||
fatal("%s: too many listen addresses", __func__);
|
||||
options->listen_addrs = xrecallocarray(options->listen_addrs,
|
||||
options->num_listen_addrs, options->num_listen_addrs + 1,
|
||||
sizeof(*options->listen_addrs));
|
||||
i = options->num_listen_addrs++;
|
||||
if (rdomain != NULL)
|
||||
options->listen_addrs[i].rdomain = xstrdup(rdomain);
|
||||
}
|
||||
/* options->listen_addrs[i] points to the addresses for this rdomain */
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = options->address_family;
|
||||
|
@ -654,8 +733,44 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
|
|||
ssh_gai_strerror(gaierr));
|
||||
for (ai = aitop; ai->ai_next; ai = ai->ai_next)
|
||||
;
|
||||
ai->ai_next = options->listen_addrs;
|
||||
options->listen_addrs = aitop;
|
||||
ai->ai_next = options->listen_addrs[i].addrs;
|
||||
options->listen_addrs[i].addrs = aitop;
|
||||
}
|
||||
|
||||
/* Returns nonzero if the routing domain name is valid */
|
||||
static int
|
||||
valid_rdomain(const char *name)
|
||||
{
|
||||
#if defined(HAVE_SYS_VALID_RDOMAIN)
|
||||
return sys_valid_rdomain(name);
|
||||
#elif defined(__OpenBSD__)
|
||||
const char *errstr;
|
||||
long long num;
|
||||
struct rt_tableinfo info;
|
||||
int mib[6];
|
||||
size_t miblen = sizeof(mib);
|
||||
|
||||
if (name == NULL)
|
||||
return 1;
|
||||
|
||||
num = strtonum(name, 0, 255, &errstr);
|
||||
if (errstr != NULL)
|
||||
return 0;
|
||||
|
||||
/* Check whether the table actually exists */
|
||||
memset(mib, 0, sizeof(mib));
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[4] = NET_RT_TABLE;
|
||||
mib[5] = (int)num;
|
||||
if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
#else /* defined(__OpenBSD__) */
|
||||
error("Routing domains are not supported on this platform");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -663,18 +778,19 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
|
|||
* and AddressFamily options.
|
||||
*/
|
||||
static void
|
||||
queue_listen_addr(ServerOptions *options, char *addr, int port)
|
||||
queue_listen_addr(ServerOptions *options, const char *addr,
|
||||
const char *rdomain, 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++;
|
||||
struct queued_listenaddr *qla;
|
||||
|
||||
options->queued_listen_addrs = xrecallocarray(
|
||||
options->queued_listen_addrs,
|
||||
options->num_queued_listens, options->num_queued_listens + 1,
|
||||
sizeof(*options->queued_listen_addrs));
|
||||
qla = &options->queued_listen_addrs[options->num_queued_listens++];
|
||||
qla->addr = xstrdup(addr);
|
||||
qla->port = port;
|
||||
qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -684,6 +800,7 @@ static void
|
|||
process_queued_listen_addrs(ServerOptions *options)
|
||||
{
|
||||
u_int i;
|
||||
struct queued_listenaddr *qla;
|
||||
|
||||
if (options->num_ports == 0)
|
||||
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
|
||||
|
@ -691,15 +808,13 @@ process_queued_listen_addrs(ServerOptions *options)
|
|||
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;
|
||||
qla = &options->queued_listen_addrs[i];
|
||||
add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
|
||||
free(qla->addr);
|
||||
free(qla->rdomain);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -753,6 +868,7 @@ get_connection_info(int populate, int use_dns)
|
|||
ci.address = ssh_remote_ipaddr(ssh);
|
||||
ci.laddress = ssh_local_ipaddr(ssh);
|
||||
ci.lport = ssh_local_port(ssh);
|
||||
ci.rdomain = ssh_packet_rdomain_in(ssh);
|
||||
return &ci;
|
||||
}
|
||||
|
||||
|
@ -817,6 +933,13 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
match_test_missing_fatal(const char *criteria, const char *attrib)
|
||||
{
|
||||
fatal("'Match %s' in configuration but '%s' not in connection "
|
||||
"test specification.", criteria, attrib);
|
||||
}
|
||||
|
||||
/*
|
||||
* All of the attributes on a single Match line are ANDed together, so we need
|
||||
* to check every attribute and set the result to zero if any attribute does
|
||||
|
@ -854,20 +977,24 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
|||
return -1;
|
||||
}
|
||||
if (strcasecmp(attrib, "user") == 0) {
|
||||
if (ci == NULL || ci->user == NULL) {
|
||||
if (ci == NULL) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
if (ci->user == NULL)
|
||||
match_test_missing_fatal("User", "user");
|
||||
if (match_pattern_list(ci->user, arg, 0) != 1)
|
||||
result = 0;
|
||||
else
|
||||
debug("user %.100s matched 'User %.100s' at "
|
||||
"line %d", ci->user, arg, line);
|
||||
} else if (strcasecmp(attrib, "group") == 0) {
|
||||
if (ci == NULL || ci->user == NULL) {
|
||||
if (ci == NULL) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
if (ci->user == NULL)
|
||||
match_test_missing_fatal("Group", "user");
|
||||
switch (match_cfg_line_group(arg, line, ci->user)) {
|
||||
case -1:
|
||||
return -1;
|
||||
|
@ -875,20 +1002,24 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
|||
result = 0;
|
||||
}
|
||||
} else if (strcasecmp(attrib, "host") == 0) {
|
||||
if (ci == NULL || ci->host == NULL) {
|
||||
if (ci == NULL) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
if (ci->host == NULL)
|
||||
match_test_missing_fatal("Host", "host");
|
||||
if (match_hostname(ci->host, arg) != 1)
|
||||
result = 0;
|
||||
else
|
||||
debug("connection from %.100s matched 'Host "
|
||||
"%.100s' at line %d", ci->host, arg, line);
|
||||
} else if (strcasecmp(attrib, "address") == 0) {
|
||||
if (ci == NULL || ci->address == NULL) {
|
||||
if (ci == NULL) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
if (ci->address == NULL)
|
||||
match_test_missing_fatal("Address", "addr");
|
||||
switch (addr_match_list(ci->address, arg)) {
|
||||
case 1:
|
||||
debug("connection from %.100s matched 'Address "
|
||||
|
@ -902,10 +1033,13 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
|||
return -1;
|
||||
}
|
||||
} else if (strcasecmp(attrib, "localaddress") == 0){
|
||||
if (ci == NULL || ci->laddress == NULL) {
|
||||
if (ci == NULL) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
if (ci->laddress == NULL)
|
||||
match_test_missing_fatal("LocalAddress",
|
||||
"laddr");
|
||||
switch (addr_match_list(ci->laddress, arg)) {
|
||||
case 1:
|
||||
debug("connection from %.100s matched "
|
||||
|
@ -925,10 +1059,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
|||
arg);
|
||||
return -1;
|
||||
}
|
||||
if (ci == NULL || ci->lport == 0) {
|
||||
if (ci == NULL) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
if (ci->lport == 0)
|
||||
match_test_missing_fatal("LocalPort", "lport");
|
||||
/* TODO support port lists */
|
||||
if (port == ci->lport)
|
||||
debug("connection from %.100s matched "
|
||||
|
@ -936,6 +1072,16 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
|||
ci->laddress, port, line);
|
||||
else
|
||||
result = 0;
|
||||
} else if (strcasecmp(attrib, "rdomain") == 0) {
|
||||
if (ci == NULL || ci->rdomain == NULL) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
if (match_pattern_list(ci->rdomain, arg, 0) != 1)
|
||||
result = 0;
|
||||
else
|
||||
debug("user %.100s matched 'RDomain %.100s' at "
|
||||
"line %d", ci->rdomain, arg, line);
|
||||
} else {
|
||||
error("Unsupported Match attribute %s", attrib);
|
||||
return -1;
|
||||
|
@ -958,6 +1104,11 @@ struct multistate {
|
|||
char *key;
|
||||
int value;
|
||||
};
|
||||
static const struct multistate multistate_flag[] = {
|
||||
{ "yes", 1 },
|
||||
{ "no", 0 },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
static const struct multistate multistate_addressfamily[] = {
|
||||
{ "inet", AF_INET },
|
||||
{ "inet6", AF_INET6 },
|
||||
|
@ -1094,20 +1245,33 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
/* check for bare IPv6 address: no "[]" and 2 or more ":" */
|
||||
if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
|
||||
&& strchr(p+1, ':') != NULL) {
|
||||
queue_listen_addr(options, arg, 0);
|
||||
break;
|
||||
}
|
||||
p = hpdelim(&arg);
|
||||
if (p == NULL)
|
||||
fatal("%s line %d: bad address:port usage",
|
||||
filename, linenum);
|
||||
p = cleanhostname(p);
|
||||
if (arg == NULL)
|
||||
port = 0;
|
||||
else if ((port = a2port(arg)) <= 0)
|
||||
fatal("%s line %d: bad port number", filename, linenum);
|
||||
p = arg;
|
||||
} else {
|
||||
p = hpdelim(&arg);
|
||||
if (p == NULL)
|
||||
fatal("%s line %d: bad address:port usage",
|
||||
filename, linenum);
|
||||
p = cleanhostname(p);
|
||||
if (arg == NULL)
|
||||
port = 0;
|
||||
else if ((port = a2port(arg)) <= 0)
|
||||
fatal("%s line %d: bad port number",
|
||||
filename, linenum);
|
||||
}
|
||||
/* Optional routing table */
|
||||
arg2 = NULL;
|
||||
if ((arg = strdelim(&cp)) != NULL) {
|
||||
if (strcmp(arg, "rdomain") != 0 ||
|
||||
(arg2 = strdelim(&cp)) == NULL)
|
||||
fatal("%s line %d: bad ListenAddress syntax",
|
||||
filename, linenum);
|
||||
if (!valid_rdomain(arg2))
|
||||
fatal("%s line %d: bad routing domain",
|
||||
filename, linenum);
|
||||
}
|
||||
|
||||
queue_listen_addr(options, p, port);
|
||||
queue_listen_addr(options, p, arg2, port);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -1134,22 +1298,12 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
break;
|
||||
|
||||
case sHostKeyFile:
|
||||
intptr = &options->num_host_key_files;
|
||||
if (*intptr >= MAX_HOSTKEYS)
|
||||
fatal("%s line %d: too many host keys specified (max %d).",
|
||||
filename, linenum, MAX_HOSTKEYS);
|
||||
charptr = &options->host_key_files[*intptr];
|
||||
parse_filename:
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing file name.",
|
||||
filename, linenum);
|
||||
if (*activep && *charptr == NULL) {
|
||||
*charptr = derelativise_path(arg);
|
||||
/* increase optional counter */
|
||||
if (intptr != NULL)
|
||||
*intptr = *intptr + 1;
|
||||
}
|
||||
if (*activep)
|
||||
servconf_add_hostkey(filename, linenum, options, arg);
|
||||
break;
|
||||
|
||||
case sHostKeyAgent:
|
||||
|
@ -1164,17 +1318,28 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
break;
|
||||
|
||||
case sHostCertificate:
|
||||
intptr = &options->num_host_cert_files;
|
||||
if (*intptr >= MAX_HOSTKEYS)
|
||||
fatal("%s line %d: too many host certificates "
|
||||
"specified (max %d).", filename, linenum,
|
||||
MAX_HOSTCERTS);
|
||||
charptr = &options->host_cert_files[*intptr];
|
||||
goto parse_filename;
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing file name.",
|
||||
filename, linenum);
|
||||
if (*activep)
|
||||
servconf_add_hostcert(filename, linenum, options, arg);
|
||||
break;
|
||||
|
||||
case sPidFile:
|
||||
charptr = &options->pid_file;
|
||||
goto parse_filename;
|
||||
parse_filename:
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing file name.",
|
||||
filename, linenum);
|
||||
if (*activep && *charptr == NULL) {
|
||||
*charptr = derelativise_path(arg);
|
||||
/* increase optional counter */
|
||||
if (intptr != NULL)
|
||||
*intptr = *intptr + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case sPermitRootLogin:
|
||||
intptr = &options->permit_root_login;
|
||||
|
@ -1184,21 +1349,8 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
case sIgnoreRhosts:
|
||||
intptr = &options->ignore_rhosts;
|
||||
parse_flag:
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing yes/no argument.",
|
||||
filename, linenum);
|
||||
value = 0; /* silence compiler */
|
||||
if (strcmp(arg, "yes") == 0)
|
||||
value = 1;
|
||||
else if (strcmp(arg, "no") == 0)
|
||||
value = 0;
|
||||
else
|
||||
fatal("%s line %d: Bad yes/no argument: %s",
|
||||
filename, linenum, arg);
|
||||
if (*activep && *intptr == -1)
|
||||
*intptr = value;
|
||||
break;
|
||||
multistate_ptr = multistate_flag;
|
||||
goto parse_multistate;
|
||||
|
||||
case sIgnoreUserKnownHosts:
|
||||
intptr = &options->ignore_user_known_hosts;
|
||||
|
@ -1418,55 +1570,47 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
|
||||
case sAllowUsers:
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (options->num_allow_users >= MAX_ALLOW_USERS)
|
||||
fatal("%s line %d: too many allow users.",
|
||||
filename, linenum);
|
||||
if (match_user(NULL, NULL, NULL, arg) == -1)
|
||||
fatal("%s line %d: invalid AllowUsers pattern: "
|
||||
"\"%.100s\"", filename, linenum, arg);
|
||||
if (!*activep)
|
||||
continue;
|
||||
options->allow_users[options->num_allow_users++] =
|
||||
xstrdup(arg);
|
||||
array_append(filename, linenum, "AllowUsers",
|
||||
&options->allow_users, &options->num_allow_users,
|
||||
arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case sDenyUsers:
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (options->num_deny_users >= MAX_DENY_USERS)
|
||||
fatal("%s line %d: too many deny users.",
|
||||
filename, linenum);
|
||||
if (match_user(NULL, NULL, NULL, arg) == -1)
|
||||
fatal("%s line %d: invalid DenyUsers pattern: "
|
||||
"\"%.100s\"", filename, linenum, arg);
|
||||
if (!*activep)
|
||||
continue;
|
||||
options->deny_users[options->num_deny_users++] =
|
||||
xstrdup(arg);
|
||||
array_append(filename, linenum, "DenyUsers",
|
||||
&options->deny_users, &options->num_deny_users,
|
||||
arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case sAllowGroups:
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
|
||||
fatal("%s line %d: too many allow groups.",
|
||||
filename, linenum);
|
||||
if (!*activep)
|
||||
continue;
|
||||
options->allow_groups[options->num_allow_groups++] =
|
||||
xstrdup(arg);
|
||||
array_append(filename, linenum, "AllowGroups",
|
||||
&options->allow_groups, &options->num_allow_groups,
|
||||
arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case sDenyGroups:
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (options->num_deny_groups >= MAX_DENY_GROUPS)
|
||||
fatal("%s line %d: too many deny groups.",
|
||||
filename, linenum);
|
||||
if (!*activep)
|
||||
continue;
|
||||
options->deny_groups[options->num_deny_groups++] =
|
||||
xstrdup(arg);
|
||||
array_append(filename, linenum, "DenyGroups",
|
||||
&options->deny_groups, &options->num_deny_groups,
|
||||
arg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1585,14 +1729,12 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
case sAuthorizedKeysFile:
|
||||
if (*activep && options->num_authkeys_files == 0) {
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (options->num_authkeys_files >=
|
||||
MAX_AUTHKEYS_FILES)
|
||||
fatal("%s line %d: "
|
||||
"too many authorized keys files.",
|
||||
filename, linenum);
|
||||
options->authorized_keys_files[
|
||||
options->num_authkeys_files++] =
|
||||
tilde_expand_filename(arg, getuid());
|
||||
arg = tilde_expand_filename(arg, getuid());
|
||||
array_append(filename, linenum,
|
||||
"AuthorizedKeysFile",
|
||||
&options->authorized_keys_files,
|
||||
&options->num_authkeys_files, arg);
|
||||
free(arg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1624,13 +1766,11 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
if (strchr(arg, '=') != NULL)
|
||||
fatal("%s line %d: Invalid environment name.",
|
||||
filename, linenum);
|
||||
if (options->num_accept_env >= MAX_ACCEPT_ENV)
|
||||
fatal("%s line %d: too many allow env.",
|
||||
filename, linenum);
|
||||
if (!*activep)
|
||||
continue;
|
||||
options->accept_env[options->num_accept_env++] =
|
||||
xstrdup(arg);
|
||||
array_append(filename, linenum, "AcceptEnv",
|
||||
&options->accept_env, &options->num_accept_env,
|
||||
arg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1669,9 +1809,9 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing PermitOpen specification",
|
||||
filename, linenum);
|
||||
i = options->num_permitted_opens; /* modified later */
|
||||
value = options->num_permitted_opens; /* modified later */
|
||||
if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
|
||||
if (*activep && i == 0) {
|
||||
if (*activep && value == 0) {
|
||||
options->num_permitted_opens = 1;
|
||||
options->permitted_opens = xcalloc(1,
|
||||
sizeof(*options->permitted_opens));
|
||||
|
@ -1689,16 +1829,13 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
|
||||
fatal("%s line %d: bad port number in "
|
||||
"PermitOpen", filename, linenum);
|
||||
if (*activep && i == 0) {
|
||||
options->permitted_opens = xrecallocarray(
|
||||
options->permitted_opens,
|
||||
options->num_permitted_opens,
|
||||
options->num_permitted_opens + 1,
|
||||
sizeof(*options->permitted_opens));
|
||||
i = options->num_permitted_opens++;
|
||||
options->permitted_opens[i] = arg2;
|
||||
} else
|
||||
free(arg2);
|
||||
if (*activep && value == 0) {
|
||||
array_append(filename, linenum,
|
||||
"PermitOpen",
|
||||
&options->permitted_opens,
|
||||
&options->num_permitted_opens, arg2);
|
||||
}
|
||||
free(arg2);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1821,11 +1958,6 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
value = 0; /* seen "any" pseudo-method */
|
||||
value2 = 0; /* sucessfully parsed any method */
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (options->num_auth_methods >=
|
||||
MAX_AUTH_METHODS)
|
||||
fatal("%s line %d: "
|
||||
"too many authentication methods.",
|
||||
filename, linenum);
|
||||
if (strcmp(arg, "any") == 0) {
|
||||
if (options->num_auth_methods > 0) {
|
||||
fatal("%s line %d: \"any\" "
|
||||
|
@ -1846,8 +1978,10 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
value2 = 1;
|
||||
if (!*activep)
|
||||
continue;
|
||||
options->auth_methods[
|
||||
options->num_auth_methods++] = xstrdup(arg);
|
||||
array_append(filename, linenum,
|
||||
"AuthenticationMethods",
|
||||
&options->auth_methods,
|
||||
&options->num_auth_methods, arg);
|
||||
}
|
||||
if (value2 == 0) {
|
||||
fatal("%s line %d: no AuthenticationMethods "
|
||||
|
@ -1889,6 +2023,19 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
intptr = &options->expose_userauth_info;
|
||||
goto parse_flag;
|
||||
|
||||
case sRDomain:
|
||||
charptr = &options->routing_domain;
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing argument.",
|
||||
filename, linenum);
|
||||
if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
|
||||
!valid_rdomain(arg))
|
||||
fatal("%s line %d: bad routing domain",
|
||||
filename, linenum);
|
||||
if (*activep && *charptr == NULL)
|
||||
*charptr = xstrdup(arg);
|
||||
|
||||
case sDeprecated:
|
||||
case sIgnore:
|
||||
case sUnsupported:
|
||||
|
@ -1969,6 +2116,8 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
|
|||
ci->user = xstrdup(p + 5);
|
||||
} else if (strncmp(p, "laddr=", 6) == 0) {
|
||||
ci->laddress = xstrdup(p + 6);
|
||||
} else if (strncmp(p, "rdomain=", 8) == 0) {
|
||||
ci->rdomain = xstrdup(p + 8);
|
||||
} else if (strncmp(p, "lport=", 6) == 0) {
|
||||
ci->lport = a2port(p + 6);
|
||||
if (ci->lport == -1) {
|
||||
|
@ -1985,19 +2134,6 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns 1 for a complete spec, 0 for partial spec and -1 for an
|
||||
* empty spec.
|
||||
*/
|
||||
int server_match_spec_complete(struct connection_info *ci)
|
||||
{
|
||||
if (ci->user && ci->host && ci->address)
|
||||
return 1; /* complete */
|
||||
if (!ci->user && !ci->host && !ci->address)
|
||||
return -1; /* empty */
|
||||
return 0; /* partial */
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy any supported values that are set.
|
||||
*
|
||||
|
@ -2063,17 +2199,16 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
|||
dst->n = src->n; \
|
||||
} \
|
||||
} while(0)
|
||||
#define M_CP_STRARRAYOPT(n, num_n) do {\
|
||||
if (src->num_n != 0) { \
|
||||
for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \
|
||||
dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
|
||||
} \
|
||||
} while(0)
|
||||
#define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \
|
||||
if (src->num_n != 0) { \
|
||||
dst->n = xcalloc(src->num_n, sizeof(*dst->n)); \
|
||||
M_CP_STRARRAYOPT(n, num_n); \
|
||||
dst->num_n = src->num_n; \
|
||||
#define M_CP_STRARRAYOPT(s, num_s) do {\
|
||||
u_int i; \
|
||||
if (src->num_s != 0) { \
|
||||
for (i = 0; i < dst->num_s; i++) \
|
||||
free(dst->s[i]); \
|
||||
free(dst->s); \
|
||||
dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
|
||||
for (i = 0; i < src->num_s; i++) \
|
||||
dst->s[i] = xstrdup(src->s[i]); \
|
||||
dst->num_s = src->num_s; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
@ -2106,7 +2241,6 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
|||
#undef M_CP_INTOPT
|
||||
#undef M_CP_STROPT
|
||||
#undef M_CP_STRARRAYOPT
|
||||
#undef M_CP_STRARRAYOPT_ALLOC
|
||||
|
||||
void
|
||||
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
|
||||
|
@ -2263,45 +2397,61 @@ dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
dump_config(ServerOptions *o)
|
||||
static char *
|
||||
format_listen_addrs(struct listenaddr *la)
|
||||
{
|
||||
u_int i;
|
||||
int ret;
|
||||
int r;
|
||||
struct addrinfo *ai;
|
||||
char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
|
||||
char addr[NI_MAXHOST], port[NI_MAXSERV];
|
||||
char *laddr1 = xstrdup(""), *laddr2 = NULL;
|
||||
|
||||
/* these are usually at the top of the config */
|
||||
for (i = 0; i < o->num_ports; i++)
|
||||
printf("port %d\n", o->ports[i]);
|
||||
dump_cfg_fmtint(sAddressFamily, o->address_family);
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
|
||||
for (ai = la->addrs; ai; ai = ai->ai_next) {
|
||||
if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
|
||||
sizeof(addr), port, sizeof(port),
|
||||
NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
|
||||
error("getnameinfo failed: %.100s",
|
||||
(ret != EAI_SYSTEM) ? gai_strerror(ret) :
|
||||
strerror(errno));
|
||||
} else {
|
||||
laddr2 = laddr1;
|
||||
if (ai->ai_family == AF_INET6)
|
||||
xasprintf(&laddr1, "listenaddress [%s]:%s\n%s",
|
||||
addr, port, laddr2);
|
||||
else
|
||||
xasprintf(&laddr1, "listenaddress %s:%s\n%s",
|
||||
addr, port, laddr2);
|
||||
free(laddr2);
|
||||
error("getnameinfo: %.100s", ssh_gai_strerror(r));
|
||||
continue;
|
||||
}
|
||||
laddr2 = laddr1;
|
||||
if (ai->ai_family == AF_INET6) {
|
||||
xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
|
||||
addr, port,
|
||||
la->rdomain == NULL ? "" : " rdomain ",
|
||||
la->rdomain == NULL ? "" : la->rdomain,
|
||||
laddr2);
|
||||
} else {
|
||||
xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
|
||||
addr, port,
|
||||
la->rdomain == NULL ? "" : " rdomain ",
|
||||
la->rdomain == NULL ? "" : la->rdomain,
|
||||
laddr2);
|
||||
}
|
||||
free(laddr2);
|
||||
}
|
||||
return laddr1;
|
||||
}
|
||||
|
||||
void
|
||||
dump_config(ServerOptions *o)
|
||||
{
|
||||
char *s;
|
||||
u_int i;
|
||||
|
||||
/* these are usually at the top of the config */
|
||||
for (i = 0; i < o->num_ports; i++)
|
||||
printf("port %d\n", o->ports[i]);
|
||||
dump_cfg_fmtint(sAddressFamily, o->address_family);
|
||||
|
||||
for (i = 0; i < o->num_listen_addrs; i++) {
|
||||
s = format_listen_addrs(&o->listen_addrs[i]);
|
||||
printf("%s", s);
|
||||
free(s);
|
||||
}
|
||||
printf("%s", laddr1);
|
||||
free(laddr1);
|
||||
|
||||
/* integer arguments */
|
||||
#ifdef USE_PAM
|
||||
|
@ -2390,6 +2540,7 @@ dump_config(ServerOptions *o)
|
|||
o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
|
||||
dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
|
||||
o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
|
||||
dump_cfg_string(sRDomain, o->routing_domain);
|
||||
|
||||
/* string arguments requiring a lookup */
|
||||
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
|
||||
|
@ -2418,11 +2569,13 @@ dump_config(ServerOptions *o)
|
|||
printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
|
||||
o->max_startups_rate, o->max_startups);
|
||||
|
||||
for (i = 0; tunmode_desc[i].val != -1; i++)
|
||||
s = NULL;
|
||||
for (i = 0; tunmode_desc[i].val != -1; i++) {
|
||||
if (tunmode_desc[i].val == o->permit_tun) {
|
||||
s = tunmode_desc[i].text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dump_cfg_string(sPermitTunnel, s);
|
||||
|
||||
printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
|
||||
|
|
77
servconf.h
77
servconf.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: servconf.h,v 1.126 2017/10/02 19:33:20 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.130 2017/10/25 00:19:47 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -18,17 +18,7 @@
|
|||
|
||||
#define MAX_PORTS 256 /* Max # ports. */
|
||||
|
||||
#define MAX_ALLOW_USERS 256 /* Max # users on allow list. */
|
||||
#define MAX_DENY_USERS 256 /* Max # users on deny list. */
|
||||
#define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */
|
||||
#define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */
|
||||
#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
|
||||
#define MAX_HOSTKEYS 256 /* Max # hostkeys. */
|
||||
#define MAX_HOSTCERTS 256 /* Max # host certificates. */
|
||||
#define MAX_ACCEPT_ENV 256 /* Max # of env vars. */
|
||||
#define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */
|
||||
#define MAX_AUTHKEYS_FILES 256 /* Max # of authorized_keys files. */
|
||||
#define MAX_AUTH_METHODS 256 /* Max # of AuthenticationMethods. */
|
||||
|
||||
/* permit_root_login */
|
||||
#define PERMIT_NOT_SET -1
|
||||
|
@ -61,21 +51,42 @@
|
|||
struct ssh;
|
||||
struct fwd_perm_list;
|
||||
|
||||
/*
|
||||
* Used to store addresses from ListenAddr directives. These may be
|
||||
* incomplete, as they may specify addresses that need to be merged
|
||||
* with any ports requested by ListenPort.
|
||||
*/
|
||||
struct queued_listenaddr {
|
||||
char *addr;
|
||||
int port; /* <=0 if unspecified */
|
||||
char *rdomain;
|
||||
};
|
||||
|
||||
/* Resolved listen addresses, grouped by optional routing domain */
|
||||
struct listenaddr {
|
||||
char *rdomain;
|
||||
struct addrinfo *addrs;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u_int num_ports;
|
||||
u_int ports_from_cmdline;
|
||||
int ports[MAX_PORTS]; /* Port number to listen on. */
|
||||
struct queued_listenaddr *queued_listen_addrs;
|
||||
u_int num_queued_listens;
|
||||
char **queued_listen_addrs;
|
||||
int *queued_listen_ports;
|
||||
struct addrinfo *listen_addrs; /* Addresses on which the server listens. */
|
||||
int address_family; /* Address family used by the server. */
|
||||
char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */
|
||||
int num_host_key_files; /* Number of files for host keys. */
|
||||
char *host_cert_files[MAX_HOSTCERTS]; /* Files containing host certs. */
|
||||
int num_host_cert_files; /* Number of files for host certs. */
|
||||
char *host_key_agent; /* ssh-agent socket for host keys. */
|
||||
char *pid_file; /* Where to put our pid */
|
||||
struct listenaddr *listen_addrs;
|
||||
u_int num_listen_addrs;
|
||||
int address_family; /* Address family used by the server. */
|
||||
|
||||
char *routing_domain; /* Bind session to routing domain */
|
||||
|
||||
char **host_key_files; /* Files containing host keys. */
|
||||
u_int num_host_key_files; /* Number of files for host keys. */
|
||||
char **host_cert_files; /* Files containing host certs. */
|
||||
u_int num_host_cert_files; /* Number of files for host certs. */
|
||||
|
||||
char *host_key_agent; /* ssh-agent socket for host keys. */
|
||||
char *pid_file; /* Where to put our pid */
|
||||
int login_grace_time; /* Disconnect if no auth in this time
|
||||
* (sec). */
|
||||
int permit_root_login; /* PERMIT_*, see above */
|
||||
|
@ -134,13 +145,13 @@ typedef struct {
|
|||
int allow_agent_forwarding;
|
||||
int disable_forwarding;
|
||||
u_int num_allow_users;
|
||||
char *allow_users[MAX_ALLOW_USERS];
|
||||
char **allow_users;
|
||||
u_int num_deny_users;
|
||||
char *deny_users[MAX_DENY_USERS];
|
||||
char **deny_users;
|
||||
u_int num_allow_groups;
|
||||
char *allow_groups[MAX_ALLOW_GROUPS];
|
||||
char **allow_groups;
|
||||
u_int num_deny_groups;
|
||||
char *deny_groups[MAX_DENY_GROUPS];
|
||||
char **deny_groups;
|
||||
|
||||
u_int num_subsystems;
|
||||
char *subsystem_name[MAX_SUBSYSTEMS];
|
||||
|
@ -148,7 +159,7 @@ typedef struct {
|
|||
char *subsystem_args[MAX_SUBSYSTEMS];
|
||||
|
||||
u_int num_accept_env;
|
||||
char *accept_env[MAX_ACCEPT_ENV];
|
||||
char **accept_env;
|
||||
|
||||
int max_startups_begin;
|
||||
int max_startups_rate;
|
||||
|
@ -167,8 +178,8 @@ typedef struct {
|
|||
* disconnect the session
|
||||
*/
|
||||
|
||||
u_int num_authkeys_files; /* Files containing public keys */
|
||||
char *authorized_keys_files[MAX_AUTHKEYS_FILES];
|
||||
u_int num_authkeys_files; /* Files containing public keys */
|
||||
char **authorized_keys_files;
|
||||
|
||||
char *adm_forced_command;
|
||||
|
||||
|
@ -194,7 +205,7 @@ typedef struct {
|
|||
char *version_addendum; /* Appended to SSH banner */
|
||||
|
||||
u_int num_auth_methods;
|
||||
char *auth_methods[MAX_AUTH_METHODS];
|
||||
char **auth_methods;
|
||||
|
||||
int fingerprint_hash;
|
||||
int expose_userauth_info;
|
||||
|
@ -207,6 +218,7 @@ struct connection_info {
|
|||
const char *address; /* remote address */
|
||||
const char *laddress; /* local address */
|
||||
int lport; /* local port */
|
||||
const char *rdomain; /* routing domain if available */
|
||||
};
|
||||
|
||||
|
||||
|
@ -230,6 +242,7 @@ struct connection_info {
|
|||
M_CP_STROPT(authorized_principals_command_user); \
|
||||
M_CP_STROPT(hostbased_key_types); \
|
||||
M_CP_STROPT(pubkey_key_types); \
|
||||
M_CP_STROPT(routing_domain); \
|
||||
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
|
||||
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
|
||||
M_CP_STRARRAYOPT(deny_users, num_deny_users); \
|
||||
|
@ -237,7 +250,7 @@ struct connection_info {
|
|||
M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
|
||||
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
|
||||
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
|
||||
M_CP_STRARRAYOPT_ALLOC(permitted_opens, num_permitted_opens); \
|
||||
M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \
|
||||
} while (0)
|
||||
|
||||
struct connection_info *get_connection_info(int, int);
|
||||
|
@ -255,5 +268,9 @@ int server_match_spec_complete(struct connection_info *);
|
|||
void copy_set_server_options(ServerOptions *, ServerOptions *, int);
|
||||
void dump_config(ServerOptions *);
|
||||
char *derelativise_path(const char *);
|
||||
void servconf_add_hostkey(const char *, const int,
|
||||
ServerOptions *, const char *path);
|
||||
void servconf_add_hostcert(const char *, const int,
|
||||
ServerOptions *, const char *path);
|
||||
|
||||
#endif /* SERVCONF_H */
|
||||
|
|
22
serverloop.c
22
serverloop.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 djm Exp $ */
|
||||
/* $OpenBSD: serverloop.c,v 1.199 2017/10/23 05:08:00 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -99,6 +99,9 @@ static volatile sig_atomic_t received_sigterm = 0;
|
|||
/* prototypes */
|
||||
static void server_init_dispatch(void);
|
||||
|
||||
/* requested tunnel forwarding interface(s), shared with session.c */
|
||||
char *tun_fwd_ifnames = NULL;
|
||||
|
||||
/*
|
||||
* we write to this pipe if a SIGCHLD is caught in order to avoid
|
||||
* the race between select() and child_terminated
|
||||
|
@ -519,6 +522,7 @@ server_request_tun(struct ssh *ssh)
|
|||
Channel *c = NULL;
|
||||
int mode, tun;
|
||||
int sock;
|
||||
char *tmp, *ifname = NULL;
|
||||
|
||||
mode = packet_get_int();
|
||||
switch (mode) {
|
||||
|
@ -541,9 +545,10 @@ server_request_tun(struct ssh *ssh)
|
|||
goto done;
|
||||
tun = forced_tun_device;
|
||||
}
|
||||
sock = tun_open(tun, mode);
|
||||
sock = tun_open(tun, mode, &ifname);
|
||||
if (sock < 0)
|
||||
goto done;
|
||||
debug("Tunnel forwarding using interface %s", ifname);
|
||||
c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
|
||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
|
||||
c->datagram = 1;
|
||||
|
@ -553,6 +558,19 @@ server_request_tun(struct ssh *ssh)
|
|||
sys_tun_outfilter, NULL, NULL);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update the list of names exposed to the session
|
||||
* XXX remove these if the tunnels are closed (won't matter
|
||||
* much if they are already in the environment though)
|
||||
*/
|
||||
tmp = tun_fwd_ifnames;
|
||||
xasprintf(&tun_fwd_ifnames, "%s%s%s",
|
||||
tun_fwd_ifnames == NULL ? "" : tun_fwd_ifnames,
|
||||
tun_fwd_ifnames == NULL ? "" : ",",
|
||||
ifname);
|
||||
free(tmp);
|
||||
free(ifname);
|
||||
|
||||
done:
|
||||
if (c == NULL)
|
||||
packet_send_debug("Failed to open the tunnel device.");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: session.c,v 1.292 2017/09/12 06:32:07 djm Exp $ */
|
||||
/* $OpenBSD: session.c,v 1.293 2017/10/23 05:08:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
|
@ -140,6 +140,7 @@ extern u_int utmp_len;
|
|||
extern int startup_pipe;
|
||||
extern void destroy_sensitive_data(void);
|
||||
extern Buffer loginmsg;
|
||||
char *tun_fwd_ifnames; /* serverloop.c */
|
||||
|
||||
/* original command from peer. */
|
||||
const char *original_command = NULL;
|
||||
|
@ -1344,6 +1345,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
|
|||
free(laddr);
|
||||
child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
|
||||
|
||||
if (tun_fwd_ifnames != NULL)
|
||||
child_set_env(&env, &envsize, "SSH_TUNNEL", tun_fwd_ifnames);
|
||||
if (auth_info_file != NULL)
|
||||
child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
|
||||
if (s->ttyfd != -1)
|
||||
|
|
91
sftp.1
91
sftp.1
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: sftp.1,v 1.110 2017/05/03 21:49:18 naddy Exp $
|
||||
.\" $OpenBSD: sftp.1,v 1.113 2017/11/03 03:46:52 djm Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||
.\"
|
||||
|
@ -22,7 +22,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 3 2017 $
|
||||
.Dd $Mdocdate: November 3 2017 $
|
||||
.Dt SFTP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -30,7 +30,6 @@
|
|||
.Nd secure file transfer program
|
||||
.Sh SYNOPSIS
|
||||
.Nm sftp
|
||||
.Bk -words
|
||||
.Op Fl 46aCfpqrv
|
||||
.Op Fl B Ar buffer_size
|
||||
.Op Fl b Ar batchfile
|
||||
|
@ -44,54 +43,55 @@
|
|||
.Op Fl R Ar num_requests
|
||||
.Op Fl S Ar program
|
||||
.Op Fl s Ar subsystem | sftp_server
|
||||
.Ar host
|
||||
.Ek
|
||||
.Nm sftp
|
||||
.Oo Ar user Ns @ Oc Ns
|
||||
.Ar host Ns Op : Ns Ar
|
||||
.Nm sftp
|
||||
.Oo
|
||||
.Ar user Ns @ Oc Ns
|
||||
.Ar host Ns Oo : Ns Ar dir Ns
|
||||
.Op Ar /
|
||||
.Oc
|
||||
.Nm sftp
|
||||
.Fl b Ar batchfile
|
||||
.Oo Ar user Ns @ Oc Ns Ar host
|
||||
.Ar destination
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is an interactive file transfer program, similar to
|
||||
is a file transfer program, similar to
|
||||
.Xr ftp 1 ,
|
||||
which performs all operations over an encrypted
|
||||
.Xr ssh 1
|
||||
transport.
|
||||
It may also use many features of ssh, such as public key authentication and
|
||||
compression.
|
||||
.Nm
|
||||
connects and logs into the specified
|
||||
.Ar host ,
|
||||
then enters an interactive command mode.
|
||||
.Pp
|
||||
The second usage format will retrieve files automatically if a non-interactive
|
||||
The
|
||||
.Ar destination
|
||||
may be specified either as
|
||||
.Sm off
|
||||
.Oo user @ Oc host Op : path
|
||||
.Sm on
|
||||
or as a URI in the form
|
||||
.Sm off
|
||||
.No sftp:// Oo user @ Oc host Oo : port Oc Op / path .
|
||||
.Sm on
|
||||
.Pp
|
||||
If the
|
||||
.Ar destination
|
||||
includes a
|
||||
.Ar path
|
||||
and it is not a directory,
|
||||
.Nm
|
||||
will retrieve files automatically if a non-interactive
|
||||
authentication method is used; otherwise it will do so after
|
||||
successful interactive authentication.
|
||||
.Pp
|
||||
The third usage format allows
|
||||
If no
|
||||
.Ar path
|
||||
is specified, or if the
|
||||
.Ar path
|
||||
is a directory,
|
||||
.Nm
|
||||
to start in a remote directory.
|
||||
will log in to the specified
|
||||
.Ar host
|
||||
and enter interactive command mode, changing to the remote directory
|
||||
if one was specified.
|
||||
An optional trailing slash can be used to force the
|
||||
.Ar path
|
||||
to be interpreted as a directory.
|
||||
.Pp
|
||||
The final usage format allows for automated sessions using the
|
||||
.Fl b
|
||||
option.
|
||||
In such cases, it is necessary to configure non-interactive authentication
|
||||
to obviate the need to enter a password at connection time (see
|
||||
.Xr sshd 8
|
||||
and
|
||||
.Xr ssh-keygen 1
|
||||
for details).
|
||||
.Pp
|
||||
Since some usage formats use colon characters to delimit host names from path
|
||||
names, IPv6 addresses must be enclosed in square brackets to avoid ambiguity.
|
||||
Since the destination formats use colon characters to delimit host
|
||||
names from path names or port numbers, IPv6 addresses must be
|
||||
enclosed in square brackets to avoid ambiguity.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
|
@ -121,7 +121,12 @@ Batch mode reads a series of commands from an input
|
|||
instead of
|
||||
.Em stdin .
|
||||
Since it lacks user interaction it should be used in conjunction with
|
||||
non-interactive authentication.
|
||||
non-interactive authentication to obviate the need to enter a password
|
||||
at connection time (see
|
||||
.Xr sshd 8
|
||||
and
|
||||
.Xr ssh-keygen 1
|
||||
for details).
|
||||
A
|
||||
.Ar batchfile
|
||||
of
|
||||
|
@ -296,9 +301,12 @@ must be escaped with backslashes
|
|||
.It Ic bye
|
||||
Quit
|
||||
.Nm sftp .
|
||||
.It Ic cd Ar path
|
||||
.It Ic cd Op Ar path
|
||||
Change remote directory to
|
||||
.Ar path .
|
||||
If
|
||||
.Ar path
|
||||
is not specified, then change directory to the one the session started in.
|
||||
.It Ic chgrp Ar grp Ar path
|
||||
Change group of file
|
||||
.Ar path
|
||||
|
@ -402,9 +410,12 @@ Note that
|
|||
does not follow symbolic links when performing recursive transfers.
|
||||
.It Ic help
|
||||
Display help text.
|
||||
.It Ic lcd Ar path
|
||||
.It Ic lcd Op Ar path
|
||||
Change local directory to
|
||||
.Ar path .
|
||||
If
|
||||
.Ar path
|
||||
is not specified, then change directory to the local user's home directory.
|
||||
.It Ic lls Op Ar ls-options Op Ar path
|
||||
Display local directory listing of either
|
||||
.Ar path
|
||||
|
|
90
sftp.c
90
sftp.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sftp.c,v 1.180 2017/06/10 06:33:34 djm Exp $ */
|
||||
/* $OpenBSD: sftp.c,v 1.182 2017/11/03 03:46:52 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
|
@ -217,8 +217,6 @@ static const struct CMD cmds[] = {
|
|||
{ NULL, -1, -1 }
|
||||
};
|
||||
|
||||
int interactive_loop(struct sftp_conn *, char *file1, char *file2);
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
killchild(int signo)
|
||||
|
@ -1336,7 +1334,7 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
|
|||
char *cp2, **argv;
|
||||
int base = 0;
|
||||
long l;
|
||||
int i, cmdnum, optidx, argc;
|
||||
int path1_mandatory = 0, i, cmdnum, optidx, argc;
|
||||
|
||||
/* Skip leading whitespace */
|
||||
cp = cp + strspn(cp, WHITESPACE);
|
||||
|
@ -1426,13 +1424,17 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
|
|||
case I_RM:
|
||||
case I_MKDIR:
|
||||
case I_RMDIR:
|
||||
case I_LMKDIR:
|
||||
path1_mandatory = 1;
|
||||
/* FALLTHROUGH */
|
||||
case I_CHDIR:
|
||||
case I_LCHDIR:
|
||||
case I_LMKDIR:
|
||||
if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
|
||||
return -1;
|
||||
/* Get pathname (mandatory) */
|
||||
if (argc - optidx < 1) {
|
||||
if (!path1_mandatory)
|
||||
break; /* return a NULL path1 */
|
||||
error("You must specify a path after a %s command.",
|
||||
cmd);
|
||||
return -1;
|
||||
|
@ -1517,7 +1519,7 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
|
|||
|
||||
static int
|
||||
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
int err_abort)
|
||||
const char *startdir, int err_abort)
|
||||
{
|
||||
char *path1, *path2, *tmp;
|
||||
int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0,
|
||||
|
@ -1604,6 +1606,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
|||
err = do_rmdir(conn, path1);
|
||||
break;
|
||||
case I_CHDIR:
|
||||
if (path1 == NULL || *path1 == '\0')
|
||||
path1 = xstrdup(startdir);
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
if ((tmp = do_realpath(conn, path1)) == NULL) {
|
||||
err = 1;
|
||||
|
@ -1652,6 +1656,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
|||
err = do_df(conn, path1, hflag, iflag);
|
||||
break;
|
||||
case I_LCHDIR:
|
||||
if (path1 == NULL || *path1 == '\0')
|
||||
path1 = xstrdup("~");
|
||||
tmp = tilde_expand_filename(path1, getuid());
|
||||
free(path1);
|
||||
path1 = tmp;
|
||||
|
@ -2138,11 +2144,11 @@ complete(EditLine *el, int ch)
|
|||
}
|
||||
#endif /* USE_LIBEDIT */
|
||||
|
||||
int
|
||||
static int
|
||||
interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
||||
{
|
||||
char *remote_path;
|
||||
char *dir = NULL;
|
||||
char *dir = NULL, *startdir = NULL;
|
||||
char cmd[2048];
|
||||
int err, interactive;
|
||||
EditLine *el = NULL;
|
||||
|
@ -2186,6 +2192,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
|||
remote_path = do_realpath(conn, ".");
|
||||
if (remote_path == NULL)
|
||||
fatal("Need cwd");
|
||||
startdir = xstrdup(remote_path);
|
||||
|
||||
if (file1 != NULL) {
|
||||
dir = xstrdup(file1);
|
||||
|
@ -2196,8 +2203,9 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
|||
mprintf("Changing to: %s\n", dir);
|
||||
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
|
||||
if (parse_dispatch_command(conn, cmd,
|
||||
&remote_path, 1) != 0) {
|
||||
&remote_path, startdir, 1) != 0) {
|
||||
free(dir);
|
||||
free(startdir);
|
||||
free(remote_path);
|
||||
free(conn);
|
||||
return (-1);
|
||||
|
@ -2209,8 +2217,9 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
|||
file2 == NULL ? "" : " ",
|
||||
file2 == NULL ? "" : file2);
|
||||
err = parse_dispatch_command(conn, cmd,
|
||||
&remote_path, 1);
|
||||
&remote_path, startdir, 1);
|
||||
free(dir);
|
||||
free(startdir);
|
||||
free(remote_path);
|
||||
free(conn);
|
||||
return (err);
|
||||
|
@ -2269,11 +2278,12 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
|||
signal(SIGINT, cmd_interrupt);
|
||||
|
||||
err = parse_dispatch_command(conn, cmd, &remote_path,
|
||||
batchmode);
|
||||
startdir, batchmode);
|
||||
if (err != 0)
|
||||
break;
|
||||
}
|
||||
free(remote_path);
|
||||
free(startdir);
|
||||
free(conn);
|
||||
|
||||
#ifdef USE_LIBEDIT
|
||||
|
@ -2366,19 +2376,16 @@ usage(void)
|
|||
"[-i identity_file] [-l limit]\n"
|
||||
" [-o ssh_option] [-P port] [-R num_requests] "
|
||||
"[-S program]\n"
|
||||
" [-s subsystem | sftp_server] host\n"
|
||||
" %s [user@]host[:file ...]\n"
|
||||
" %s [user@]host[:dir[/]]\n"
|
||||
" %s -b batchfile [user@]host\n",
|
||||
__progname, __progname, __progname, __progname);
|
||||
" [-s subsystem | sftp_server] destination\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int in, out, ch, err;
|
||||
char *host = NULL, *userhost, *cp, *file2 = NULL;
|
||||
int in, out, ch, err, tmp, port = -1;
|
||||
char *host = NULL, *user, *cp, *file2 = NULL;
|
||||
int debug_level = 0, sshver = 2;
|
||||
char *file1 = NULL, *sftp_server = NULL;
|
||||
char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
|
||||
|
@ -2433,7 +2440,9 @@ main(int argc, char **argv)
|
|||
addargs(&args, "-%c", ch);
|
||||
break;
|
||||
case 'P':
|
||||
addargs(&args, "-oPort %s", optarg);
|
||||
port = a2port(optarg);
|
||||
if (port <= 0)
|
||||
fatal("Bad port \"%s\"\n", optarg);
|
||||
break;
|
||||
case 'v':
|
||||
if (debug_level < 3) {
|
||||
|
@ -2516,34 +2525,39 @@ main(int argc, char **argv)
|
|||
if (sftp_direct == NULL) {
|
||||
if (optind == argc || argc > (optind + 2))
|
||||
usage();
|
||||
argv += optind;
|
||||
|
||||
userhost = xstrdup(argv[optind]);
|
||||
if(argc > optind + 1)
|
||||
file2 = argv[optind+1];
|
||||
|
||||
if ((host = strrchr(userhost, '@')) == NULL)
|
||||
host = userhost;
|
||||
else {
|
||||
*host++ = '\0';
|
||||
if (!userhost[0]) {
|
||||
fprintf(stderr, "Missing username\n");
|
||||
usage();
|
||||
switch (parse_uri("sftp", *argv, &user, &host, &tmp, &file1)) {
|
||||
case -1:
|
||||
usage();
|
||||
break;
|
||||
case 0:
|
||||
if (tmp != -1)
|
||||
port = tmp;
|
||||
break;
|
||||
default:
|
||||
if (parse_user_host_path(*argv, &user, &host,
|
||||
&file1) == -1) {
|
||||
/* Treat as a plain hostname. */
|
||||
host = xstrdup(*argv);
|
||||
host = cleanhostname(host);
|
||||
}
|
||||
addargs(&args, "-l");
|
||||
addargs(&args, "%s", userhost);
|
||||
break;
|
||||
}
|
||||
if (argv + 1)
|
||||
file2 = *(argv + 1);
|
||||
|
||||
if ((cp = colon(host)) != NULL) {
|
||||
*cp++ = '\0';
|
||||
file1 = cp;
|
||||
}
|
||||
|
||||
host = cleanhostname(host);
|
||||
if (!*host) {
|
||||
fprintf(stderr, "Missing hostname\n");
|
||||
usage();
|
||||
}
|
||||
|
||||
if (port != -1)
|
||||
addargs(&args, "-oPort %d", port);
|
||||
if (user != NULL) {
|
||||
addargs(&args, "-l");
|
||||
addargs(&args, "%s", user);
|
||||
}
|
||||
addargs(&args, "-oProtocol %d", sshver);
|
||||
|
||||
/* no subsystem if the server-spec contains a '/' */
|
||||
|
|
40
ssh-agent.c
40
ssh-agent.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-agent.c,v 1.224 2017/07/24 04:34:28 djm Exp $ */
|
||||
/* $OpenBSD: ssh-agent.c,v 1.226 2017/11/15 02:10:16 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -287,8 +287,11 @@ process_sign_request2(SocketEntry *e)
|
|||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((r = sshkey_froms(e->request, &key)) != 0 ||
|
||||
(r = sshbuf_get_string_direct(e->request, &data, &dlen)) != 0 ||
|
||||
(r = sshbuf_get_u32(e->request, &flags)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
(r = sshbuf_get_u32(e->request, &flags)) != 0) {
|
||||
error("%s: couldn't parse request: %s", __func__, ssh_err(r));
|
||||
goto send;
|
||||
}
|
||||
|
||||
if (flags & SSH_AGENT_OLD_SIGNATURE)
|
||||
compat = SSH_BUG_SIGBLOB;
|
||||
if ((id = lookup_identity(key)) == NULL) {
|
||||
|
@ -472,6 +475,11 @@ process_lock_agent(SocketEntry *e, int lock)
|
|||
static u_int fail_count = 0;
|
||||
size_t pwlen;
|
||||
|
||||
/*
|
||||
* This is deliberately fatal: the user has requested that we lock,
|
||||
* but we can't parse their request properly. The only safe thing to
|
||||
* do is abort.
|
||||
*/
|
||||
if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if (pwlen == 0) {
|
||||
|
@ -529,7 +537,7 @@ no_identities(SocketEntry *e)
|
|||
static void
|
||||
process_add_smartcard_key(SocketEntry *e)
|
||||
{
|
||||
char *provider = NULL, *pin, canonical_provider[PATH_MAX];
|
||||
char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
|
||||
int r, i, count = 0, success = 0, confirm = 0;
|
||||
u_int seconds;
|
||||
time_t death = 0;
|
||||
|
@ -538,17 +546,23 @@ process_add_smartcard_key(SocketEntry *e)
|
|||
Identity *id;
|
||||
|
||||
if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
|
||||
error("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
goto send;
|
||||
}
|
||||
|
||||
while (sshbuf_len(e->request)) {
|
||||
if ((r = sshbuf_get_u8(e->request, &type)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if ((r = sshbuf_get_u8(e->request, &type)) != 0) {
|
||||
error("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
goto send;
|
||||
}
|
||||
switch (type) {
|
||||
case SSH_AGENT_CONSTRAIN_LIFETIME:
|
||||
if ((r = sshbuf_get_u32(e->request, &seconds)) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) {
|
||||
error("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
goto send;
|
||||
}
|
||||
death = monotime() + seconds;
|
||||
break;
|
||||
case SSH_AGENT_CONSTRAIN_CONFIRM:
|
||||
|
@ -606,8 +620,10 @@ process_remove_smartcard_key(SocketEntry *e)
|
|||
Identity *id, *nxt;
|
||||
|
||||
if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
|
||||
error("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
goto send;
|
||||
}
|
||||
free(pin);
|
||||
|
||||
if (realpath(provider, canonical_provider) == NULL) {
|
||||
|
|
23
ssh-keygen.1
23
ssh-keygen.1
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: ssh-keygen.1,v 1.144 2017/07/08 18:32:54 jmc Exp $
|
||||
.\" $OpenBSD: ssh-keygen.1,v 1.145 2017/11/03 05:14:04 djm Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" 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
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 8 2017 $
|
||||
.Dd $Mdocdate: November 3 2017 $
|
||||
.Dt SSH-KEYGEN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -584,13 +584,20 @@ Specify a validity interval when signing a certificate.
|
|||
A validity interval may consist of a single time, indicating that the
|
||||
certificate is valid beginning now and expiring at that time, or may consist
|
||||
of two times separated by a colon to indicate an explicit time interval.
|
||||
The start time may be specified as a date in YYYYMMDD format, a time
|
||||
in YYYYMMDDHHMMSS format or a relative time (to the current time) consisting
|
||||
of a minus sign followed by a relative time in the format described in the
|
||||
.Pp
|
||||
The start time may be specified as the string
|
||||
.Dq always
|
||||
to indicate the certificate has no specified start time,
|
||||
a date in YYYYMMDD format, a time in YYYYMMDDHHMMSS format,
|
||||
a relative time (to the current time) consisting of a minus sign followed by
|
||||
an interval in the format described in the
|
||||
TIME FORMATS section of
|
||||
.Xr sshd_config 5 .
|
||||
The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or
|
||||
a relative time starting with a plus character.
|
||||
.Pp
|
||||
The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time,
|
||||
a relative time starting with a plus character or the string
|
||||
.Dq forever
|
||||
to indicate that the certificate has no expirty date.
|
||||
.Pp
|
||||
For example:
|
||||
.Dq +52w1d
|
||||
|
@ -601,6 +608,8 @@ For example:
|
|||
(valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011),
|
||||
.Dq -1d:20110101
|
||||
(valid from yesterday to midnight, January 1st, 2011).
|
||||
.Dq -1m:forever
|
||||
(valid from one minute ago and never expiring).
|
||||
.It Fl v
|
||||
Verbose mode.
|
||||
Causes
|
||||
|
|
12
ssh-keygen.c
12
ssh-keygen.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-keygen.c,v 1.307 2017/07/07 03:53:12 djm Exp $ */
|
||||
/* $OpenBSD: ssh-keygen.c,v 1.308 2017/11/03 05:14:04 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1861,7 +1861,7 @@ parse_absolute_time(const char *s)
|
|||
s, s + 4, s + 6, s + 8, s + 10, s + 12);
|
||||
break;
|
||||
default:
|
||||
fatal("Invalid certificate time format %s", s);
|
||||
fatal("Invalid certificate time format \"%s\"", s);
|
||||
}
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
|
@ -1894,8 +1894,8 @@ parse_cert_times(char *timespec)
|
|||
|
||||
/*
|
||||
* from:to, where
|
||||
* from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
|
||||
* to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
|
||||
* from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "always"
|
||||
* to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "forever"
|
||||
*/
|
||||
from = xstrdup(timespec);
|
||||
to = strchr(from, ':');
|
||||
|
@ -1905,11 +1905,15 @@ parse_cert_times(char *timespec)
|
|||
|
||||
if (*from == '-' || *from == '+')
|
||||
cert_valid_from = parse_relative_time(from, now);
|
||||
else if (strcmp(from, "always") == 0)
|
||||
cert_valid_from = 0;
|
||||
else
|
||||
cert_valid_from = parse_absolute_time(from);
|
||||
|
||||
if (*to == '-' || *to == '+')
|
||||
cert_valid_to = parse_relative_time(to, now);
|
||||
else if (strcmp(to, "forever") == 0)
|
||||
cert_valid_to = ~(u_int64_t)0;
|
||||
else
|
||||
cert_valid_to = parse_absolute_time(to);
|
||||
|
||||
|
|
50
ssh.1
50
ssh.1
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh.1,v 1.384 2017/09/21 19:16:53 markus Exp $
|
||||
.Dd $Mdocdate: September 21 2017 $
|
||||
.\" $OpenBSD: ssh.1,v 1.389 2017/11/03 02:29:17 djm Exp $
|
||||
.Dd $Mdocdate: November 3 2017 $
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -42,7 +42,6 @@
|
|||
.Nd OpenSSH SSH client (remote login program)
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh
|
||||
.Bk -words
|
||||
.Op Fl 46AaCfGgKkMNnqsTtVvXxYy
|
||||
.Op Fl b Ar bind_address
|
||||
.Op Fl c Ar cipher_spec
|
||||
|
@ -52,7 +51,7 @@
|
|||
.Op Fl F Ar configfile
|
||||
.Op Fl I Ar pkcs11
|
||||
.Op Fl i Ar identity_file
|
||||
.Op Fl J Oo Ar user Ns @ Oc Ns Ar host Ns Op : Ns Ar port
|
||||
.Op Fl J Ar destination
|
||||
.Op Fl L Ar address
|
||||
.Op Fl l Ar login_name
|
||||
.Op Fl m Ar mac_spec
|
||||
|
@ -64,9 +63,8 @@
|
|||
.Op Fl S Ar ctl_path
|
||||
.Op Fl W Ar host : Ns Ar port
|
||||
.Op Fl w Ar local_tun Ns Op : Ns Ar remote_tun
|
||||
.Oo Ar user Ns @ Oc Ns Ar hostname
|
||||
.Ar destination
|
||||
.Op Ar command
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
(SSH client) is a program for logging into a remote machine and for
|
||||
|
@ -79,15 +77,20 @@ sockets can also be forwarded over the secure channel.
|
|||
.Pp
|
||||
.Nm
|
||||
connects and logs into the specified
|
||||
.Ar hostname
|
||||
(with optional
|
||||
.Ar user
|
||||
name).
|
||||
.Ar destination ,
|
||||
which may be specified as either
|
||||
.Sm off
|
||||
.Oo user @ Oc hostname
|
||||
.Sm on
|
||||
or a URI of the form
|
||||
.Sm off
|
||||
.No ssh:// Oo user @ Oc hostname Op : port .
|
||||
.Sm on
|
||||
The user must prove
|
||||
his/her identity to the remote machine using one of several methods
|
||||
(see below).
|
||||
.Pp
|
||||
If
|
||||
If a
|
||||
.Ar command
|
||||
is specified,
|
||||
it is executed on the remote host instead of a login shell.
|
||||
|
@ -287,17 +290,11 @@ by appending
|
|||
.Pa -cert.pub
|
||||
to identity filenames.
|
||||
.Pp
|
||||
.It Fl J Xo
|
||||
.Sm off
|
||||
.Op Ar user No @
|
||||
.Ar host
|
||||
.Op : Ar port
|
||||
.Sm on
|
||||
.Xc
|
||||
.It Fl J Ar destination
|
||||
Connect to the target host by first making a
|
||||
.Nm
|
||||
connection to the jump
|
||||
.Ar host
|
||||
connection to the jump host described by
|
||||
.Ar destination
|
||||
and then establishing a TCP forwarding to the ultimate destination from
|
||||
there.
|
||||
Multiple jump hops may be specified separated by comma characters.
|
||||
|
@ -1393,6 +1390,17 @@ This is set to the name of the tty (path to the device) associated
|
|||
with the current shell or command.
|
||||
If the current session has no tty,
|
||||
this variable is not set.
|
||||
.It Ev SSH_TUNNEL
|
||||
Optionally set by
|
||||
.Xr sshd 8
|
||||
to contain the interface names assigned if tunnel forwarding was
|
||||
requested by the client.
|
||||
.It Ev SSH_USER_AUTH
|
||||
Optionally set by
|
||||
.Xr sshd 8 ,
|
||||
this variable may contain a pathname to a file that lists the authentication
|
||||
methods successfully used when the session was established, including any
|
||||
public keys that were used.
|
||||
.It Ev TZ
|
||||
This variable is set to indicate the present time zone if it
|
||||
was set when the daemon was started (i.e. the daemon passes the value
|
||||
|
@ -1474,7 +1482,7 @@ accessible by others (read/write/execute).
|
|||
will simply ignore a private key file if it is accessible by others.
|
||||
It is possible to specify a passphrase when
|
||||
generating the key which will be used to encrypt the
|
||||
sensitive part of this file using 3DES.
|
||||
sensitive part of this file using AES-128.
|
||||
.Pp
|
||||
.It Pa ~/.ssh/id_dsa.pub
|
||||
.It Pa ~/.ssh/id_ecdsa.pub
|
||||
|
|
190
ssh.c
190
ssh.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh.c,v 1.464 2017/09/21 19:16:53 markus Exp $ */
|
||||
/* $OpenBSD: ssh.c,v 1.469 2017/11/01 00:04:15 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -168,6 +168,10 @@ char *config = NULL;
|
|||
*/
|
||||
char *host;
|
||||
|
||||
/* Various strings used to to percent_expand() arguments */
|
||||
static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
|
||||
static char uidstr[32], *host_arg, *conn_hash_hex;
|
||||
|
||||
/* socket address the host resolves to */
|
||||
struct sockaddr_storage hostaddr;
|
||||
|
||||
|
@ -203,13 +207,13 @@ usage(void)
|
|||
" [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n"
|
||||
" [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]\n"
|
||||
" [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]\n"
|
||||
" [user@]hostname [command]\n"
|
||||
" destination [command]\n"
|
||||
);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
static int ssh_session2(struct ssh *);
|
||||
static void load_public_identity_files(void);
|
||||
static int ssh_session2(struct ssh *, struct passwd *);
|
||||
static void load_public_identity_files(struct passwd *);
|
||||
static void main_sigchld_handler(int);
|
||||
|
||||
/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
|
||||
|
@ -456,14 +460,14 @@ resolve_canonicalize(char **hostp, int port)
|
|||
* file if the user specifies a config file on the command line.
|
||||
*/
|
||||
static void
|
||||
process_config_files(const char *host_arg, struct passwd *pw, int post_canon)
|
||||
process_config_files(const char *host_name, struct passwd *pw, int post_canon)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
int r;
|
||||
|
||||
if (config != NULL) {
|
||||
if (strcasecmp(config, "none") != 0 &&
|
||||
!read_config_file(config, pw, host, host_arg, &options,
|
||||
!read_config_file(config, pw, host, host_name, &options,
|
||||
SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))
|
||||
fatal("Can't open user config file %.100s: "
|
||||
"%.100s", config, strerror(errno));
|
||||
|
@ -471,13 +475,13 @@ process_config_files(const char *host_arg, struct passwd *pw, int post_canon)
|
|||
r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
|
||||
_PATH_SSH_USER_CONFFILE);
|
||||
if (r > 0 && (size_t)r < sizeof(buf))
|
||||
(void)read_config_file(buf, pw, host, host_arg,
|
||||
(void)read_config_file(buf, pw, host, host_name,
|
||||
&options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
|
||||
(post_canon ? SSHCONF_POSTCANON : 0));
|
||||
|
||||
/* Read systemwide configuration file after user config. */
|
||||
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
|
||||
host, host_arg, &options,
|
||||
host, host_name, &options,
|
||||
post_canon ? SSHCONF_POSTCANON : 0);
|
||||
}
|
||||
}
|
||||
|
@ -511,9 +515,8 @@ main(int ac, char **av)
|
|||
struct ssh *ssh = NULL;
|
||||
int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
|
||||
int config_test = 0, opt_terminated = 0;
|
||||
char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile;
|
||||
char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
|
||||
char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex;
|
||||
char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile;
|
||||
char cname[NI_MAXHOST];
|
||||
struct stat st;
|
||||
struct passwd *pw;
|
||||
extern int optind, optreset;
|
||||
|
@ -846,14 +849,18 @@ main(int ac, char **av)
|
|||
options.control_master = SSHCTL_MASTER_YES;
|
||||
break;
|
||||
case 'p':
|
||||
options.port = a2port(optarg);
|
||||
if (options.port <= 0) {
|
||||
fprintf(stderr, "Bad port '%s'\n", optarg);
|
||||
exit(255);
|
||||
if (options.port == -1) {
|
||||
options.port = a2port(optarg);
|
||||
if (options.port <= 0) {
|
||||
fprintf(stderr, "Bad port '%s'\n",
|
||||
optarg);
|
||||
exit(255);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
options.user = optarg;
|
||||
if (options.user == NULL)
|
||||
options.user = optarg;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
|
@ -933,16 +940,38 @@ main(int ac, char **av)
|
|||
av += optind;
|
||||
|
||||
if (ac > 0 && !host) {
|
||||
if (strrchr(*av, '@')) {
|
||||
int tport;
|
||||
char *tuser;
|
||||
switch (parse_ssh_uri(*av, &tuser, &host, &tport)) {
|
||||
case -1:
|
||||
usage();
|
||||
break;
|
||||
case 0:
|
||||
if (options.user == NULL) {
|
||||
options.user = tuser;
|
||||
tuser = NULL;
|
||||
}
|
||||
free(tuser);
|
||||
if (options.port == -1 && tport != -1)
|
||||
options.port = tport;
|
||||
break;
|
||||
default:
|
||||
p = xstrdup(*av);
|
||||
cp = strrchr(p, '@');
|
||||
if (cp == NULL || cp == p)
|
||||
usage();
|
||||
options.user = p;
|
||||
*cp = '\0';
|
||||
host = xstrdup(++cp);
|
||||
} else
|
||||
host = xstrdup(*av);
|
||||
if (cp != NULL) {
|
||||
if (cp == p)
|
||||
usage();
|
||||
if (options.user == NULL) {
|
||||
options.user = p;
|
||||
p = NULL;
|
||||
}
|
||||
*cp++ = '\0';
|
||||
host = xstrdup(cp);
|
||||
free(p);
|
||||
} else
|
||||
host = p;
|
||||
break;
|
||||
}
|
||||
if (ac > 1 && !opt_terminated) {
|
||||
optind = optreset = 1;
|
||||
goto again;
|
||||
|
@ -994,9 +1023,9 @@ main(int ac, char **av)
|
|||
if (logfile != NULL)
|
||||
log_redirect_stderr_to(logfile);
|
||||
log_init(argv0,
|
||||
options.log_level == SYSLOG_LEVEL_NOT_SET ?
|
||||
options.log_level == SYSLOG_LEVEL_NOT_SET ?
|
||||
SYSLOG_LEVEL_INFO : options.log_level,
|
||||
options.log_facility == SYSLOG_FACILITY_NOT_SET ?
|
||||
options.log_facility == SYSLOG_FACILITY_NOT_SET ?
|
||||
SYSLOG_FACILITY_USER : options.log_facility,
|
||||
!use_syslog);
|
||||
|
||||
|
@ -1035,7 +1064,7 @@ main(int ac, char **av)
|
|||
* If CanonicalizePermittedCNAMEs have been specified but
|
||||
* other canonicalization did not happen (by not being requested
|
||||
* or by failing with fallback) then the hostname may still be changed
|
||||
* as a result of CNAME following.
|
||||
* as a result of CNAME following.
|
||||
*
|
||||
* Try to resolve the bare hostname name using the system resolver's
|
||||
* usual search rules and then apply the CNAME follow rules.
|
||||
|
@ -1177,6 +1206,7 @@ main(int ac, char **av)
|
|||
if (options.user == NULL)
|
||||
options.user = xstrdup(pw->pw_name);
|
||||
|
||||
/* Set up strings used to percent_expand() arguments */
|
||||
if (gethostname(thishost, sizeof(thishost)) == -1)
|
||||
fatal("gethostname: %s", strerror(errno));
|
||||
strlcpy(shorthost, thishost, sizeof(shorthost));
|
||||
|
@ -1194,24 +1224,11 @@ main(int ac, char **av)
|
|||
ssh_digest_free(md);
|
||||
conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
|
||||
|
||||
if (options.local_command != NULL) {
|
||||
debug3("expanding LocalCommand: %s", options.local_command);
|
||||
cp = options.local_command;
|
||||
options.local_command = percent_expand(cp,
|
||||
"C", conn_hash_hex,
|
||||
"L", shorthost,
|
||||
"d", pw->pw_dir,
|
||||
"h", host,
|
||||
"l", thishost,
|
||||
"n", host_arg,
|
||||
"p", portstr,
|
||||
"r", options.user,
|
||||
"u", pw->pw_name,
|
||||
(char *)NULL);
|
||||
debug3("expanded LocalCommand: %s", options.local_command);
|
||||
free(cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand tokens in arguments. NB. LocalCommand is expanded later,
|
||||
* after port-forwarding is set up, so it may pick up any local
|
||||
* tunnel interface name allocated.
|
||||
*/
|
||||
if (options.remote_command != NULL) {
|
||||
debug3("expanding RemoteCommand: %s", options.remote_command);
|
||||
cp = options.remote_command;
|
||||
|
@ -1230,7 +1247,6 @@ main(int ac, char **av)
|
|||
free(cp);
|
||||
buffer_append(&command, options.remote_command,
|
||||
strlen(options.remote_command));
|
||||
|
||||
}
|
||||
|
||||
if (options.control_path != NULL) {
|
||||
|
@ -1401,7 +1417,7 @@ main(int ac, char **av)
|
|||
}
|
||||
}
|
||||
/* load options.identity_files */
|
||||
load_public_identity_files();
|
||||
load_public_identity_files(pw);
|
||||
|
||||
/* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */
|
||||
if (options.identity_agent &&
|
||||
|
@ -1465,7 +1481,7 @@ main(int ac, char **av)
|
|||
}
|
||||
|
||||
skip_connect:
|
||||
exit_status = ssh_session2(ssh);
|
||||
exit_status = ssh_session2(ssh, pw);
|
||||
packet_close();
|
||||
|
||||
if (options.control_path != NULL && muxserver_sock != -1)
|
||||
|
@ -1571,7 +1587,7 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
|
|||
channel_update_permitted_opens(ssh, rfwd->handle, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (type == SSH2_MSG_REQUEST_FAILURE) {
|
||||
if (options.exit_on_forward_failure) {
|
||||
if (rfwd->listen_path != NULL)
|
||||
|
@ -1633,7 +1649,7 @@ ssh_init_stdio_forwarding(struct ssh *ssh)
|
|||
}
|
||||
|
||||
static void
|
||||
ssh_init_forwarding(struct ssh *ssh)
|
||||
ssh_init_forwarding(struct ssh *ssh, char **ifname)
|
||||
{
|
||||
int success = 0;
|
||||
int i;
|
||||
|
@ -1691,14 +1707,15 @@ ssh_init_forwarding(struct ssh *ssh)
|
|||
|
||||
/* Initiate tunnel forwarding. */
|
||||
if (options.tun_open != SSH_TUNMODE_NO) {
|
||||
if (client_request_tun_fwd(ssh, options.tun_open,
|
||||
options.tun_local, options.tun_remote) == -1) {
|
||||
if ((*ifname = client_request_tun_fwd(ssh,
|
||||
options.tun_open, options.tun_local,
|
||||
options.tun_remote)) == NULL) {
|
||||
if (options.exit_on_forward_failure)
|
||||
fatal("Could not request tunnel forwarding.");
|
||||
else
|
||||
error("Could not request tunnel forwarding.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1807,14 +1824,35 @@ ssh_session2_open(struct ssh *ssh)
|
|||
}
|
||||
|
||||
static int
|
||||
ssh_session2(struct ssh *ssh)
|
||||
ssh_session2(struct ssh *ssh, struct passwd *pw)
|
||||
{
|
||||
int id = -1;
|
||||
int devnull, id = -1;
|
||||
char *cp, *tun_fwd_ifname = NULL;
|
||||
|
||||
/* XXX should be pre-session */
|
||||
if (!options.control_persist)
|
||||
ssh_init_stdio_forwarding(ssh);
|
||||
ssh_init_forwarding(ssh);
|
||||
|
||||
ssh_init_forwarding(ssh, &tun_fwd_ifname);
|
||||
|
||||
if (options.local_command != NULL) {
|
||||
debug3("expanding LocalCommand: %s", options.local_command);
|
||||
cp = options.local_command;
|
||||
options.local_command = percent_expand(cp,
|
||||
"C", conn_hash_hex,
|
||||
"L", shorthost,
|
||||
"d", pw->pw_dir,
|
||||
"h", host,
|
||||
"l", thishost,
|
||||
"n", host_arg,
|
||||
"p", portstr,
|
||||
"r", options.user,
|
||||
"u", pw->pw_name,
|
||||
"T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname,
|
||||
(char *)NULL);
|
||||
debug3("expanded LocalCommand: %s", options.local_command);
|
||||
free(cp);
|
||||
}
|
||||
|
||||
/* Start listening for multiplex clients */
|
||||
if (!packet_get_mux())
|
||||
|
@ -1871,6 +1909,22 @@ ssh_session2(struct ssh *ssh)
|
|||
options.permit_local_command)
|
||||
ssh_local_cmd(options.local_command);
|
||||
|
||||
/*
|
||||
* stdout is now owned by the session channel; clobber it here
|
||||
* so future channel closes are propagated to the local fd.
|
||||
* NB. this can only happen after LocalCommand has completed,
|
||||
* as it may want to write to stdout.
|
||||
*/
|
||||
if (!need_controlpersist_detach) {
|
||||
if ((devnull = open(_PATH_DEVNULL, O_WRONLY)) == -1)
|
||||
error("%s: open %s: %s", __func__,
|
||||
_PATH_DEVNULL, strerror(errno));
|
||||
if (dup2(devnull, STDOUT_FILENO) < 0)
|
||||
fatal("%s: dup2() stdout failed", __func__);
|
||||
if (devnull > STDERR_FILENO)
|
||||
close(devnull);
|
||||
}
|
||||
|
||||
/*
|
||||
* If requested and we are not interested in replies to remote
|
||||
* forwarding requests, then let ssh continue in the background.
|
||||
|
@ -1890,12 +1944,10 @@ ssh_session2(struct ssh *ssh)
|
|||
|
||||
/* Loads all IdentityFile and CertificateFile keys */
|
||||
static void
|
||||
load_public_identity_files(void)
|
||||
load_public_identity_files(struct passwd *pw)
|
||||
{
|
||||
char *filename, *cp, thishost[NI_MAXHOST];
|
||||
char *pwdir = NULL, *pwname = NULL;
|
||||
char *filename, *cp;
|
||||
struct sshkey *public;
|
||||
struct passwd *pw;
|
||||
int i;
|
||||
u_int n_ids, n_certs;
|
||||
char *identity_files[SSH_MAX_IDENTITY_FILES];
|
||||
|
@ -1934,11 +1986,6 @@ load_public_identity_files(void)
|
|||
#endif /* ENABLE_PKCS11 */
|
||||
if ((pw = getpwuid(original_real_uid)) == NULL)
|
||||
fatal("load_public_identity_files: getpwuid failed");
|
||||
pwname = xstrdup(pw->pw_name);
|
||||
pwdir = xstrdup(pw->pw_dir);
|
||||
if (gethostname(thishost, sizeof(thishost)) == -1)
|
||||
fatal("load_public_identity_files: gethostname: %s",
|
||||
strerror(errno));
|
||||
for (i = 0; i < options.num_identity_files; i++) {
|
||||
if (n_ids >= SSH_MAX_IDENTITY_FILES ||
|
||||
strcasecmp(options.identity_files[i], "none") == 0) {
|
||||
|
@ -1948,8 +1995,8 @@ load_public_identity_files(void)
|
|||
}
|
||||
cp = tilde_expand_filename(options.identity_files[i],
|
||||
original_real_uid);
|
||||
filename = percent_expand(cp, "d", pwdir,
|
||||
"u", pwname, "l", thishost, "h", host,
|
||||
filename = percent_expand(cp, "d", pw->pw_dir,
|
||||
"u", pw->pw_name, "l", thishost, "h", host,
|
||||
"r", options.user, (char *)NULL);
|
||||
free(cp);
|
||||
public = key_load_public(filename, NULL);
|
||||
|
@ -1994,8 +2041,8 @@ load_public_identity_files(void)
|
|||
for (i = 0; i < options.num_certificate_files; i++) {
|
||||
cp = tilde_expand_filename(options.certificate_files[i],
|
||||
original_real_uid);
|
||||
filename = percent_expand(cp, "d", pwdir,
|
||||
"u", pwname, "l", thishost, "h", host,
|
||||
filename = percent_expand(cp, "d", pw->pw_dir,
|
||||
"u", pw->pw_name, "l", thishost, "h", host,
|
||||
"r", options.user, (char *)NULL);
|
||||
free(cp);
|
||||
|
||||
|
@ -2028,11 +2075,6 @@ load_public_identity_files(void)
|
|||
memcpy(options.certificate_files,
|
||||
certificate_files, sizeof(certificate_files));
|
||||
memcpy(options.certificates, certificates, sizeof(certificates));
|
||||
|
||||
explicit_bzero(pwname, strlen(pwname));
|
||||
free(pwname);
|
||||
explicit_bzero(pwdir, strlen(pwdir));
|
||||
free(pwdir);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
32
ssh_config.5
32
ssh_config.5
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh_config.5,v 1.256 2017/09/21 19:16:53 markus Exp $
|
||||
.Dd $Mdocdate: September 21 2017 $
|
||||
.\" $OpenBSD: ssh_config.5,v 1.262 2017/10/24 06:27:42 jmc Exp $
|
||||
.Dd $Mdocdate: October 24 2017 $
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -1198,13 +1198,14 @@ For example, the following directive would connect via an HTTP proxy at
|
|||
ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p
|
||||
.Ed
|
||||
.It Cm ProxyJump
|
||||
Specifies one or more jump proxies as
|
||||
Specifies one or more jump proxies as either
|
||||
.Xo
|
||||
.Sm off
|
||||
.Op Ar user No @
|
||||
.Ar host
|
||||
.Op : Ns Ar port
|
||||
.Sm on
|
||||
or an ssh URI
|
||||
.Xc .
|
||||
Multiple proxies may be separated by comma characters and will be visited
|
||||
sequentially.
|
||||
|
@ -1674,6 +1675,18 @@ pool,
|
|||
the following entry (in authorized_keys) could be used:
|
||||
.Pp
|
||||
.Dl from=\&"!*.dialup.example.com,*.example.com\&"
|
||||
.Pp
|
||||
Note that a negated match will never produce a positive result by itself.
|
||||
For example, attempting to match
|
||||
.Qq host3
|
||||
against the following pattern-list will fail:
|
||||
.Pp
|
||||
.Dl from=\&"!host1,!host2\&"
|
||||
.Pp
|
||||
The solution here is to include a term that will yield a positive match,
|
||||
such as a wildcard:
|
||||
.Pp
|
||||
.Dl from=\&"!host1,!host2,*\&"
|
||||
.Sh TOKENS
|
||||
Arguments to some keywords can make use of tokens,
|
||||
which are expanded at runtime:
|
||||
|
@ -1683,7 +1696,7 @@ which are expanded at runtime:
|
|||
A literal
|
||||
.Sq % .
|
||||
.It \&%C
|
||||
Shorthand for %l%h%p%r.
|
||||
Hash of %l%h%p%r.
|
||||
.It %d
|
||||
Local user's home directory.
|
||||
.It %h
|
||||
|
@ -1700,6 +1713,15 @@ The original remote hostname, as given on the command line.
|
|||
The remote port.
|
||||
.It %r
|
||||
The remote username.
|
||||
.It \&%T
|
||||
The local
|
||||
.Xr tun 4
|
||||
or
|
||||
.Xr tap 4
|
||||
network interface assigned if
|
||||
tunnel forwarding was requested, or
|
||||
.Qq NONE
|
||||
otherwise.
|
||||
.It %u
|
||||
The local username.
|
||||
.El
|
||||
|
@ -1722,7 +1744,7 @@ and
|
|||
accept the tokens %%, %d, %h, %l, %r, and %u.
|
||||
.Pp
|
||||
.Cm LocalCommand
|
||||
accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u.
|
||||
accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, %T, and %u.
|
||||
.Pp
|
||||
.Cm ProxyCommand
|
||||
accepts the tokens %%, %h, %p, and %r.
|
||||
|
|
22
sshd.8
22
sshd.8
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd.8,v 1.291 2017/06/24 06:28:50 jmc Exp $
|
||||
.Dd $Mdocdate: June 24 2017 $
|
||||
.\" $OpenBSD: sshd.8,v 1.293 2017/11/03 03:18:53 dtucker Exp $
|
||||
.Dd $Mdocdate: November 3 2017 $
|
||||
.Dt SSHD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -100,20 +100,22 @@ Specify the connection parameters to use for the
|
|||
extended test mode.
|
||||
If provided, any
|
||||
.Cm Match
|
||||
directives in the configuration file
|
||||
that would apply to the specified user, host, and address will be set before
|
||||
the configuration is written to standard output.
|
||||
The connection parameters are supplied as keyword=value pairs.
|
||||
directives in the configuration file that would apply are applied before the
|
||||
configuration is written to standard output.
|
||||
The connection parameters are supplied as keyword=value pairs and may be
|
||||
supplied in any order, either with multiple
|
||||
.Fl C
|
||||
options or as a comma-separated list.
|
||||
The keywords are
|
||||
.Dq addr,
|
||||
.Dq user ,
|
||||
.Dq host ,
|
||||
.Dq laddr ,
|
||||
.Dq lport ,
|
||||
and
|
||||
.Dq addr .
|
||||
All are required and may be supplied in any order, either with multiple
|
||||
.Fl C
|
||||
options or as a comma-separated list.
|
||||
.Dq rdomain
|
||||
and correspond to source address, user, resolved source host name,
|
||||
local address, local port number and routing domain respectively.
|
||||
.It Fl c Ar host_certificate_file
|
||||
Specifies a path to a certificate file to identify
|
||||
.Nm
|
||||
|
|
182
sshd.c
182
sshd.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshd.c,v 1.492 2017/09/12 06:32:07 djm Exp $ */
|
||||
/* $OpenBSD: sshd.c,v 1.499 2017/11/14 00:45:29 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -144,7 +144,12 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE;
|
|||
*/
|
||||
int debug_flag = 0;
|
||||
|
||||
/* Flag indicating that the daemon should only test the configuration and keys. */
|
||||
/*
|
||||
* Indicating that the daemon should only test the configuration and keys.
|
||||
* If test_flag > 1 ("-T" flag), then sshd will also dump the effective
|
||||
* configuration, optionally using connection information provided by the
|
||||
* "-C" flag.
|
||||
*/
|
||||
int test_flag = 0;
|
||||
|
||||
/* Flag indicating that the daemon is being started from inetd. */
|
||||
|
@ -485,7 +490,7 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
|
|||
void
|
||||
destroy_sensitive_data(void)
|
||||
{
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
if (sensitive_data.host_keys[i]) {
|
||||
|
@ -504,7 +509,7 @@ void
|
|||
demote_sensitive_data(void)
|
||||
{
|
||||
struct sshkey *tmp;
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
if (sensitive_data.host_keys[i]) {
|
||||
|
@ -728,7 +733,7 @@ list_hostkey_types(void)
|
|||
Buffer b;
|
||||
const char *p;
|
||||
char *ret;
|
||||
int i;
|
||||
u_int i;
|
||||
struct sshkey *key;
|
||||
|
||||
buffer_init(&b);
|
||||
|
@ -788,7 +793,7 @@ list_hostkey_types(void)
|
|||
static struct sshkey *
|
||||
get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
|
||||
{
|
||||
int i;
|
||||
u_int i;
|
||||
struct sshkey *key;
|
||||
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
|
@ -828,7 +833,7 @@ get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
|
|||
struct sshkey *
|
||||
get_hostkey_by_index(int ind)
|
||||
{
|
||||
if (ind < 0 || ind >= options.num_host_key_files)
|
||||
if (ind < 0 || (u_int)ind >= options.num_host_key_files)
|
||||
return (NULL);
|
||||
return (sensitive_data.host_keys[ind]);
|
||||
}
|
||||
|
@ -836,7 +841,7 @@ get_hostkey_by_index(int ind)
|
|||
struct sshkey *
|
||||
get_hostkey_public_by_index(int ind, struct ssh *ssh)
|
||||
{
|
||||
if (ind < 0 || ind >= options.num_host_key_files)
|
||||
if (ind < 0 || (u_int)ind >= options.num_host_key_files)
|
||||
return (NULL);
|
||||
return (sensitive_data.host_pubkeys[ind]);
|
||||
}
|
||||
|
@ -844,7 +849,7 @@ get_hostkey_public_by_index(int ind, struct ssh *ssh)
|
|||
int
|
||||
get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh)
|
||||
{
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
if (key_is_cert(key)) {
|
||||
|
@ -873,7 +878,8 @@ notify_hostkeys(struct ssh *ssh)
|
|||
{
|
||||
struct sshbuf *buf;
|
||||
struct sshkey *key;
|
||||
int i, nkeys, r;
|
||||
u_int i, nkeys;
|
||||
int r;
|
||||
char *fp;
|
||||
|
||||
/* Some clients cannot cope with the hostkeys message, skip those. */
|
||||
|
@ -904,7 +910,7 @@ notify_hostkeys(struct ssh *ssh)
|
|||
packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf));
|
||||
nkeys++;
|
||||
}
|
||||
debug3("%s: sent %d hostkeys", __func__, nkeys);
|
||||
debug3("%s: sent %u hostkeys", __func__, nkeys);
|
||||
if (nkeys == 0)
|
||||
fatal("%s: no hostkeys", __func__);
|
||||
packet_send();
|
||||
|
@ -1057,13 +1063,13 @@ server_accept_inetd(int *sock_in, int *sock_out)
|
|||
* Listen for TCP connections
|
||||
*/
|
||||
static void
|
||||
server_listen(void)
|
||||
listen_on_addrs(struct listenaddr *la)
|
||||
{
|
||||
int ret, listen_sock, on = 1;
|
||||
int ret, listen_sock;
|
||||
struct addrinfo *ai;
|
||||
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
|
||||
|
||||
for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
|
||||
for (ai = la->addrs; ai; ai = ai->ai_next) {
|
||||
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
|
||||
continue;
|
||||
if (num_listen_socks >= MAX_LISTEN_SOCKS)
|
||||
|
@ -1093,13 +1099,13 @@ server_listen(void)
|
|||
close(listen_sock);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Set socket options.
|
||||
* Allow local port reuse in TIME_WAIT.
|
||||
*/
|
||||
if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
&on, sizeof(on)) == -1)
|
||||
error("setsockopt SO_REUSEADDR: %s", strerror(errno));
|
||||
/* Socket options */
|
||||
set_reuseaddr(listen_sock);
|
||||
if (la->rdomain != NULL &&
|
||||
set_rdomain(listen_sock, la->rdomain) == -1) {
|
||||
close(listen_sock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only communicate in IPv6 over AF_INET6 sockets. */
|
||||
if (ai->ai_family == AF_INET6)
|
||||
|
@ -1121,9 +1127,28 @@ server_listen(void)
|
|||
if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
|
||||
fatal("listen on [%s]:%s: %.100s",
|
||||
ntop, strport, strerror(errno));
|
||||
logit("Server listening on %s port %s.", ntop, strport);
|
||||
logit("Server listening on %s port %s%s%s.",
|
||||
ntop, strport,
|
||||
la->rdomain == NULL ? "" : " rdomain ",
|
||||
la->rdomain == NULL ? "" : la->rdomain);
|
||||
}
|
||||
freeaddrinfo(options.listen_addrs);
|
||||
}
|
||||
|
||||
static void
|
||||
server_listen(void)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < options.num_listen_addrs; i++) {
|
||||
listen_on_addrs(&options.listen_addrs[i]);
|
||||
freeaddrinfo(options.listen_addrs[i].addrs);
|
||||
free(options.listen_addrs[i].rdomain);
|
||||
memset(&options.listen_addrs[i], 0,
|
||||
sizeof(options.listen_addrs[i]));
|
||||
}
|
||||
free(options.listen_addrs);
|
||||
options.listen_addrs = NULL;
|
||||
options.num_listen_addrs = 0;
|
||||
|
||||
if (!num_listen_socks)
|
||||
fatal("Cannot bind any address.");
|
||||
|
@ -1432,6 +1457,46 @@ check_ip_options(struct ssh *ssh)
|
|||
#endif /* IP_OPTIONS */
|
||||
}
|
||||
|
||||
/* Set the routing domain for this process */
|
||||
static void
|
||||
set_process_rdomain(struct ssh *ssh, const char *name)
|
||||
{
|
||||
#if defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
|
||||
if (name == NULL)
|
||||
return; /* default */
|
||||
|
||||
if (strcmp(name, "%D") == 0) {
|
||||
/* "expands" to routing domain of connection */
|
||||
if ((name = ssh_packet_rdomain_in(ssh)) == NULL)
|
||||
return;
|
||||
}
|
||||
/* NB. We don't pass 'ssh' to sys_set_process_rdomain() */
|
||||
return sys_set_process_rdomain(name);
|
||||
#elif defined(__OpenBSD__)
|
||||
int rtable, ortable = getrtable();
|
||||
const char *errstr;
|
||||
|
||||
if (name == NULL)
|
||||
return; /* default */
|
||||
|
||||
if (strcmp(name, "%D") == 0) {
|
||||
/* "expands" to routing domain of connection */
|
||||
if ((name = ssh_packet_rdomain_in(ssh)) == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
rtable = (int)strtonum(name, 0, 255, &errstr);
|
||||
if (errstr != NULL) /* Shouldn't happen */
|
||||
fatal("Invalid routing domain \"%s\": %s", name, errstr);
|
||||
if (rtable != ortable && setrtable(rtable) != 0)
|
||||
fatal("Unable to set routing domain %d: %s",
|
||||
rtable, strerror(errno));
|
||||
debug("%s: set routing domain %d (was %d)", __func__, rtable, ortable);
|
||||
#else /* defined(__OpenBSD__) */
|
||||
fatal("Unable to set routing domain: not supported in this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Main program for the daemon.
|
||||
*/
|
||||
|
@ -1441,20 +1506,19 @@ main(int ac, char **av)
|
|||
struct ssh *ssh = NULL;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
int r, opt, i, j, on = 1, already_daemon;
|
||||
int r, opt, on = 1, already_daemon, remote_port;
|
||||
int sock_in = -1, sock_out = -1, newsock = -1;
|
||||
const char *remote_ip;
|
||||
int remote_port;
|
||||
const char *remote_ip, *rdomain;
|
||||
char *fp, *line, *laddr, *logfile = NULL;
|
||||
int config_s[2] = { -1 , -1 };
|
||||
u_int n;
|
||||
u_int i, j;
|
||||
u_int64_t ibytes, obytes;
|
||||
mode_t new_umask;
|
||||
struct sshkey *key;
|
||||
struct sshkey *pubkey;
|
||||
int keytype;
|
||||
Authctxt *authctxt;
|
||||
struct connection_info *connection_info = get_connection_info(0, 0);
|
||||
struct connection_info *connection_info = NULL;
|
||||
|
||||
ssh_malloc_init(); /* must be called before any mallocs */
|
||||
|
||||
|
@ -1467,7 +1531,7 @@ main(int ac, char **av)
|
|||
saved_argc = ac;
|
||||
rexec_argc = ac;
|
||||
saved_argv = xcalloc(ac + 1, sizeof(*saved_argv));
|
||||
for (i = 0; i < ac; i++)
|
||||
for (i = 0; (int)i < ac; i++)
|
||||
saved_argv[i] = xstrdup(av[i]);
|
||||
saved_argv[i] = NULL;
|
||||
|
||||
|
@ -1500,12 +1564,8 @@ main(int ac, char **av)
|
|||
config_file_name = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
if (options.num_host_cert_files >= MAX_HOSTCERTS) {
|
||||
fprintf(stderr, "too many host certificates.\n");
|
||||
exit(1);
|
||||
}
|
||||
options.host_cert_files[options.num_host_cert_files++] =
|
||||
derelativise_path(optarg);
|
||||
servconf_add_hostcert("[command-line]", 0,
|
||||
&options, optarg);
|
||||
break;
|
||||
case 'd':
|
||||
if (debug_flag == 0) {
|
||||
|
@ -1564,12 +1624,8 @@ main(int ac, char **av)
|
|||
/* protocol 1, ignored */
|
||||
break;
|
||||
case 'h':
|
||||
if (options.num_host_key_files >= MAX_HOSTKEYS) {
|
||||
fprintf(stderr, "too many host keys.\n");
|
||||
exit(1);
|
||||
}
|
||||
options.host_key_files[options.num_host_key_files++] =
|
||||
derelativise_path(optarg);
|
||||
servconf_add_hostkey("[command-line]", 0,
|
||||
&options, optarg);
|
||||
break;
|
||||
case 't':
|
||||
test_flag = 1;
|
||||
|
@ -1578,6 +1634,7 @@ main(int ac, char **av)
|
|||
test_flag = 2;
|
||||
break;
|
||||
case 'C':
|
||||
connection_info = get_connection_info(0, 0);
|
||||
if (parse_server_match_testspec(connection_info,
|
||||
optarg) == -1)
|
||||
exit(1);
|
||||
|
@ -1646,14 +1703,10 @@ main(int ac, char **av)
|
|||
sensitive_data.have_ssh2_key = 0;
|
||||
|
||||
/*
|
||||
* If we're doing an extended config test, make sure we have all of
|
||||
* the parameters we need. If we're not doing an extended test,
|
||||
* do not silently ignore connection test params.
|
||||
* If we're not doing an extended test do not silently ignore connection
|
||||
* test params.
|
||||
*/
|
||||
if (test_flag >= 2 && server_match_spec_complete(connection_info) == 0)
|
||||
fatal("user, host and addr are all required when testing "
|
||||
"Match configs");
|
||||
if (test_flag < 2 && server_match_spec_complete(connection_info) >= 0)
|
||||
if (test_flag < 2 && connection_info != NULL)
|
||||
fatal("Config test connection parameter (-C) provided without "
|
||||
"test mode (-T)");
|
||||
|
||||
|
@ -1704,12 +1757,12 @@ main(int ac, char **av)
|
|||
* and warns for trivial misconfigurations that could break login.
|
||||
*/
|
||||
if (options.num_auth_methods != 0) {
|
||||
for (n = 0; n < options.num_auth_methods; n++) {
|
||||
if (auth2_methods_valid(options.auth_methods[n],
|
||||
for (i = 0; i < options.num_auth_methods; i++) {
|
||||
if (auth2_methods_valid(options.auth_methods[i],
|
||||
1) == 0)
|
||||
break;
|
||||
}
|
||||
if (n >= options.num_auth_methods)
|
||||
if (i >= options.num_auth_methods)
|
||||
fatal("AuthenticationMethods cannot be satisfied by "
|
||||
"enabled authentication methods");
|
||||
}
|
||||
|
@ -1847,7 +1900,7 @@ main(int ac, char **av)
|
|||
continue;
|
||||
}
|
||||
sensitive_data.host_certificates[j] = key;
|
||||
debug("host certificate: #%d type %d %s", j, key->type,
|
||||
debug("host certificate: #%u type %d %s", j, key->type,
|
||||
key_type(key));
|
||||
}
|
||||
|
||||
|
@ -1871,8 +1924,13 @@ main(int ac, char **av)
|
|||
}
|
||||
|
||||
if (test_flag > 1) {
|
||||
if (server_match_spec_complete(connection_info) == 1)
|
||||
parse_server_match_config(&options, connection_info);
|
||||
/*
|
||||
* If no connection info was provided by -C then use
|
||||
* use a blank one that will cause no predicate to match.
|
||||
*/
|
||||
if (connection_info == NULL)
|
||||
connection_info = get_connection_info(0, 0);
|
||||
parse_server_match_config(&options, connection_info);
|
||||
dump_config(&options);
|
||||
}
|
||||
|
||||
|
@ -1891,8 +1949,10 @@ main(int ac, char **av)
|
|||
debug("setgroups() failed: %.200s", strerror(errno));
|
||||
|
||||
if (rexec_flag) {
|
||||
if (rexec_argc < 0)
|
||||
fatal("rexec_argc %d < 0", rexec_argc);
|
||||
rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *));
|
||||
for (i = 0; i < rexec_argc; i++) {
|
||||
for (i = 0; i < (u_int)rexec_argc; i++) {
|
||||
debug("rexec_argv[%d]='%s'", i, saved_argv[i]);
|
||||
rexec_argv[i] = saved_argv[i];
|
||||
}
|
||||
|
@ -2090,6 +2150,9 @@ main(int ac, char **av)
|
|||
cleanup_exit(255);
|
||||
}
|
||||
|
||||
if (options.routing_domain != NULL)
|
||||
set_process_rdomain(ssh, options.routing_domain);
|
||||
|
||||
/*
|
||||
* The rest of the code depends on the fact that
|
||||
* ssh_remote_ipaddr() caches the remote ip, even if
|
||||
|
@ -2101,10 +2164,15 @@ main(int ac, char **av)
|
|||
audit_connection_from(remote_ip, remote_port);
|
||||
#endif
|
||||
|
||||
rdomain = ssh_packet_rdomain_in(ssh);
|
||||
|
||||
/* Log the connection. */
|
||||
laddr = get_local_ipaddr(sock_in);
|
||||
verbose("Connection from %s port %d on %s port %d",
|
||||
remote_ip, remote_port, laddr, ssh_local_port(ssh));
|
||||
verbose("Connection from %s port %d on %s port %d%s%s%s",
|
||||
remote_ip, remote_port, laddr, ssh_local_port(ssh),
|
||||
rdomain == NULL ? "" : " rdomain \"",
|
||||
rdomain == NULL ? "" : rdomain,
|
||||
rdomain == NULL ? "" : "\"");
|
||||
free(laddr);
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.253 2017/09/27 06:45:53 jmc Exp $
|
||||
.Dd $Mdocdate: September 27 2017 $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.260 2017/10/26 06:44:01 jmc Exp $
|
||||
.Dd $Mdocdate: October 26 2017 $
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -48,6 +48,7 @@ reads configuration data from
|
|||
.Fl f
|
||||
on the command line).
|
||||
The file contains keyword-argument pairs, one per line.
|
||||
For each keyword, the first obtained value will be used.
|
||||
Lines starting with
|
||||
.Ql #
|
||||
and empty lines are interpreted as comments.
|
||||
|
@ -908,31 +909,47 @@ The following forms may be used:
|
|||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Ar host | Ar IPv4_addr | Ar IPv6_addr
|
||||
.Ar hostname | address
|
||||
.Sm on
|
||||
.Op Cm rdomain Ar domain
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Ar host | Ar IPv4_addr : Ar port
|
||||
.Ar hostname : port
|
||||
.Sm on
|
||||
.Op Cm rdomain Ar domain
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Oo
|
||||
.Ar host | Ar IPv6_addr Oc : Ar port
|
||||
.Ar IPv4_address : port
|
||||
.Sm on
|
||||
.Op Cm rdomain Ar domain
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Oo Ar hostname | address Oc : Ar port
|
||||
.Sm on
|
||||
.Op Cm rdomain Ar domain
|
||||
.El
|
||||
.Pp
|
||||
The optional
|
||||
.Cm rdomain
|
||||
qualifier requests
|
||||
.Xr sshd 8
|
||||
listen in an explicit routing domain.
|
||||
If
|
||||
.Ar port
|
||||
is not specified,
|
||||
sshd will listen on the address and all
|
||||
.Cm Port
|
||||
options specified.
|
||||
The default is to listen on all local addresses.
|
||||
The default is to listen on all local addresses on the current default
|
||||
routing domain.
|
||||
Multiple
|
||||
.Cm ListenAddress
|
||||
options are permitted.
|
||||
For more information on routing domains, see
|
||||
.Xr rdomain 4 .
|
||||
.It Cm LoginGraceTime
|
||||
The server disconnects after this time if the user has not
|
||||
successfully logged in.
|
||||
|
@ -1036,8 +1053,15 @@ The available criteria are
|
|||
.Cm Host ,
|
||||
.Cm LocalAddress ,
|
||||
.Cm LocalPort ,
|
||||
.Cm RDomain ,
|
||||
and
|
||||
.Cm Address .
|
||||
.Cm Address
|
||||
(with
|
||||
.Cm RDomain
|
||||
representing the
|
||||
.Xr rdomain 4
|
||||
on which the connection was received.)
|
||||
.Pp
|
||||
The match patterns may consist of single entries or comma-separated
|
||||
lists and may use the wildcard and negation operators described in the
|
||||
.Sx PATTERNS
|
||||
|
@ -1100,6 +1124,7 @@ Available keywords are
|
|||
.Cm PubkeyAuthentication ,
|
||||
.Cm RekeyLimit ,
|
||||
.Cm RevokedKeys ,
|
||||
.Cm RDomain ,
|
||||
.Cm StreamLocalBindMask ,
|
||||
.Cm StreamLocalBindUnlink ,
|
||||
.Cm TrustedUserCAKeys ,
|
||||
|
@ -1188,7 +1213,6 @@ Specifies whether root can log in using
|
|||
The argument must be
|
||||
.Cm yes ,
|
||||
.Cm prohibit-password ,
|
||||
.Cm without-password ,
|
||||
.Cm forced-commands-only ,
|
||||
or
|
||||
.Cm no .
|
||||
|
@ -1197,8 +1221,8 @@ The default is
|
|||
.Pp
|
||||
If this option is set to
|
||||
.Cm prohibit-password
|
||||
or
|
||||
.Cm without-password ,
|
||||
(or its deprecated alias,
|
||||
.Cm without-password ) ,
|
||||
password and keyboard-interactive authentication are disabled for root.
|
||||
.Pp
|
||||
If this option is set to
|
||||
|
@ -1361,6 +1385,15 @@ an OpenSSH Key Revocation List (KRL) as generated by
|
|||
.Xr ssh-keygen 1 .
|
||||
For more information on KRLs, see the KEY REVOCATION LISTS section in
|
||||
.Xr ssh-keygen 1 .
|
||||
.It Cm RDomain
|
||||
Specifies an explicit routing domain that is applied after authentication
|
||||
has completed.
|
||||
The user session, as well and any forwarded or listening IP sockets,
|
||||
will be bound to this
|
||||
.Xr rdomain 4 .
|
||||
If the routing domain is set to
|
||||
.Cm \&%D ,
|
||||
then the domain in which the incoming connection was received will be applied.
|
||||
.It Cm StreamLocalBindMask
|
||||
Sets the octal file creation mode mask
|
||||
.Pq umask
|
||||
|
@ -1626,6 +1659,8 @@ which are expanded at runtime:
|
|||
.It %%
|
||||
A literal
|
||||
.Sq % .
|
||||
.It \&%D
|
||||
The routing domain in which the incoming connection was received.
|
||||
.It %F
|
||||
The fingerprint of the CA key.
|
||||
.It %f
|
||||
|
@ -1662,6 +1697,9 @@ accepts the tokens %%, %h, and %u.
|
|||
.Pp
|
||||
.Cm ChrootDirectory
|
||||
accepts the tokens %%, %h, and %u.
|
||||
.Pp
|
||||
.Cm RoutingDomain
|
||||
accepts the token %D.
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa /etc/ssh/sshd_config
|
||||
|
|
4
sshkey.c
4
sshkey.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshkey.c,v 1.56 2017/08/12 06:42:52 djm Exp $ */
|
||||
/* $OpenBSD: sshkey.c,v 1.57 2017/10/13 06:24:51 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
|
||||
|
@ -3304,7 +3304,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
|
|||
int blen, len = strlen(_passphrase);
|
||||
u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
|
||||
const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
|
||||
const u_char *bptr;
|
||||
char *bptr;
|
||||
BIO *bio = NULL;
|
||||
|
||||
if (len > 0 && len <= 4)
|
||||
|
|
106
umac.c
106
umac.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: umac.c,v 1.12 2017/05/31 08:09:45 markus Exp $ */
|
||||
/* $OpenBSD: umac.c,v 1.13 2017/10/27 01:01:17 djm Exp $ */
|
||||
/* -----------------------------------------------------------------------
|
||||
*
|
||||
* umac.c -- C Implementation UMAC Message Authentication
|
||||
|
@ -21,7 +21,7 @@
|
|||
* Comments should be directed to Ted Krovetz (tdk@acm.org)
|
||||
*
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* ////////////////////// IMPORTANT NOTES /////////////////////////////////
|
||||
*
|
||||
* 1) This version does not work properly on messages larger than 16MB
|
||||
|
@ -47,7 +47,7 @@
|
|||
* produced under gcc with optimizations set -O3 or higher. Dunno why.
|
||||
*
|
||||
/////////////////////////////////////////////////////////////////////// */
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* --- User Switches ---------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
@ -187,11 +187,11 @@ static void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes)
|
|||
UINT8 out_buf[AES_BLOCK_LEN];
|
||||
UINT8 *dst_buf = (UINT8 *)bufp;
|
||||
int i;
|
||||
|
||||
|
||||
/* Setup the initial value */
|
||||
in_buf[AES_BLOCK_LEN-9] = ndx;
|
||||
in_buf[AES_BLOCK_LEN-1] = i = 1;
|
||||
|
||||
|
||||
while (nbytes >= AES_BLOCK_LEN) {
|
||||
aes_encryption(in_buf, out_buf, key);
|
||||
memcpy(dst_buf,out_buf,AES_BLOCK_LEN);
|
||||
|
@ -222,10 +222,10 @@ typedef struct {
|
|||
static void pdf_init(pdf_ctx *pc, aes_int_key prf_key)
|
||||
{
|
||||
UINT8 buf[UMAC_KEY_LEN];
|
||||
|
||||
|
||||
kdf(buf, prf_key, 0, UMAC_KEY_LEN);
|
||||
aes_key_setup(buf, pc->prf_key);
|
||||
|
||||
|
||||
/* Initialize pdf and cache */
|
||||
memset(pc->nonce, 0, sizeof(pc->nonce));
|
||||
aes_encryption(pc->nonce, pc->cache, pc->prf_key);
|
||||
|
@ -238,7 +238,7 @@ static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])
|
|||
* of the AES output. If last time around we returned the ndx-1st
|
||||
* element, then we may have the result in the cache already.
|
||||
*/
|
||||
|
||||
|
||||
#if (UMAC_OUTPUT_LEN == 4)
|
||||
#define LOW_BIT_MASK 3
|
||||
#elif (UMAC_OUTPUT_LEN == 8)
|
||||
|
@ -255,7 +255,7 @@ static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])
|
|||
#endif
|
||||
*(UINT32 *)t.tmp_nonce_lo = ((const UINT32 *)nonce)[1];
|
||||
t.tmp_nonce_lo[3] &= ~LOW_BIT_MASK; /* zero last bit */
|
||||
|
||||
|
||||
if ( (((UINT32 *)t.tmp_nonce_lo)[0] != ((UINT32 *)pc->nonce)[1]) ||
|
||||
(((const UINT32 *)nonce)[0] != ((UINT32 *)pc->nonce)[0]) )
|
||||
{
|
||||
|
@ -263,7 +263,7 @@ static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])
|
|||
((UINT32 *)pc->nonce)[1] = ((UINT32 *)t.tmp_nonce_lo)[0];
|
||||
aes_encryption(pc->nonce, pc->cache, pc->prf_key);
|
||||
}
|
||||
|
||||
|
||||
#if (UMAC_OUTPUT_LEN == 4)
|
||||
*((UINT32 *)buf) ^= ((UINT32 *)pc->cache)[ndx];
|
||||
#elif (UMAC_OUTPUT_LEN == 8)
|
||||
|
@ -302,7 +302,7 @@ static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])
|
|||
* The routine nh_init() initializes the nh_ctx data structure and
|
||||
* must be called once, before any other PDF routine.
|
||||
*/
|
||||
|
||||
|
||||
/* The "nh_aux" routines do the actual NH hashing work. They
|
||||
* expect buffers to be multiples of L1_PAD_BOUNDARY. These routines
|
||||
* produce output for all STREAMS NH iterations in one call,
|
||||
|
@ -340,7 +340,7 @@ static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
|
|||
const UINT32 *d = (const UINT32 *)dp;
|
||||
UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
|
||||
UINT32 k0,k1,k2,k3,k4,k5,k6,k7;
|
||||
|
||||
|
||||
h = *((UINT64 *)hp);
|
||||
do {
|
||||
d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);
|
||||
|
@ -353,7 +353,7 @@ static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
|
|||
h += MUL64((k1 + d1), (k5 + d5));
|
||||
h += MUL64((k2 + d2), (k6 + d6));
|
||||
h += MUL64((k3 + d3), (k7 + d7));
|
||||
|
||||
|
||||
d += 8;
|
||||
k += 8;
|
||||
} while (--c);
|
||||
|
@ -421,7 +421,7 @@ static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
|
|||
UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
|
||||
UINT32 k0,k1,k2,k3,k4,k5,k6,k7,
|
||||
k8,k9,k10,k11,k12,k13,k14,k15;
|
||||
|
||||
|
||||
h1 = *((UINT64 *)hp);
|
||||
h2 = *((UINT64 *)hp + 1);
|
||||
h3 = *((UINT64 *)hp + 2);
|
||||
|
@ -434,26 +434,26 @@ static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
|
|||
d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);
|
||||
k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);
|
||||
k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15);
|
||||
|
||||
|
||||
h1 += MUL64((k0 + d0), (k4 + d4));
|
||||
h2 += MUL64((k4 + d0), (k8 + d4));
|
||||
h3 += MUL64((k8 + d0), (k12 + d4));
|
||||
|
||||
|
||||
h1 += MUL64((k1 + d1), (k5 + d5));
|
||||
h2 += MUL64((k5 + d1), (k9 + d5));
|
||||
h3 += MUL64((k9 + d1), (k13 + d5));
|
||||
|
||||
|
||||
h1 += MUL64((k2 + d2), (k6 + d6));
|
||||
h2 += MUL64((k6 + d2), (k10 + d6));
|
||||
h3 += MUL64((k10 + d2), (k14 + d6));
|
||||
|
||||
|
||||
h1 += MUL64((k3 + d3), (k7 + d7));
|
||||
h2 += MUL64((k7 + d3), (k11 + d7));
|
||||
h3 += MUL64((k11 + d3), (k15 + d7));
|
||||
|
||||
|
||||
k0 = k8; k1 = k9; k2 = k10; k3 = k11;
|
||||
k4 = k12; k5 = k13; k6 = k14; k7 = k15;
|
||||
|
||||
|
||||
d += 8;
|
||||
k += 8;
|
||||
} while (--c);
|
||||
|
@ -477,7 +477,7 @@ static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
|
|||
UINT32 k0,k1,k2,k3,k4,k5,k6,k7,
|
||||
k8,k9,k10,k11,k12,k13,k14,k15,
|
||||
k16,k17,k18,k19;
|
||||
|
||||
|
||||
h1 = *((UINT64 *)hp);
|
||||
h2 = *((UINT64 *)hp + 1);
|
||||
h3 = *((UINT64 *)hp + 2);
|
||||
|
@ -492,31 +492,31 @@ static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
|
|||
k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);
|
||||
k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15);
|
||||
k16 = *(k+16); k17 = *(k+17); k18 = *(k+18); k19 = *(k+19);
|
||||
|
||||
|
||||
h1 += MUL64((k0 + d0), (k4 + d4));
|
||||
h2 += MUL64((k4 + d0), (k8 + d4));
|
||||
h3 += MUL64((k8 + d0), (k12 + d4));
|
||||
h4 += MUL64((k12 + d0), (k16 + d4));
|
||||
|
||||
|
||||
h1 += MUL64((k1 + d1), (k5 + d5));
|
||||
h2 += MUL64((k5 + d1), (k9 + d5));
|
||||
h3 += MUL64((k9 + d1), (k13 + d5));
|
||||
h4 += MUL64((k13 + d1), (k17 + d5));
|
||||
|
||||
|
||||
h1 += MUL64((k2 + d2), (k6 + d6));
|
||||
h2 += MUL64((k6 + d2), (k10 + d6));
|
||||
h3 += MUL64((k10 + d2), (k14 + d6));
|
||||
h4 += MUL64((k14 + d2), (k18 + d6));
|
||||
|
||||
|
||||
h1 += MUL64((k3 + d3), (k7 + d7));
|
||||
h2 += MUL64((k7 + d3), (k11 + d7));
|
||||
h3 += MUL64((k11 + d3), (k15 + d7));
|
||||
h4 += MUL64((k15 + d3), (k19 + d7));
|
||||
|
||||
|
||||
k0 = k8; k1 = k9; k2 = k10; k3 = k11;
|
||||
k4 = k12; k5 = k13; k6 = k14; k7 = k15;
|
||||
k8 = k16; k9 = k17; k10 = k18; k11 = k19;
|
||||
|
||||
|
||||
d += 8;
|
||||
k += 8;
|
||||
} while (--c);
|
||||
|
@ -541,7 +541,7 @@ static void nh_transform(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes)
|
|||
*/
|
||||
{
|
||||
UINT8 *key;
|
||||
|
||||
|
||||
key = hc->nh_key + hc->bytes_hashed;
|
||||
nh_aux(key, buf, hc->state, nbytes);
|
||||
}
|
||||
|
@ -613,7 +613,7 @@ static void nh_update(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes)
|
|||
/* even multiple of HASH_BUF_BYTES. */
|
||||
{
|
||||
UINT32 i,j;
|
||||
|
||||
|
||||
j = hc->next_data_empty;
|
||||
if ((j + nbytes) >= HASH_BUF_BYTES) {
|
||||
if (j) {
|
||||
|
@ -711,10 +711,10 @@ static void nh(nh_ctx *hc, const UINT8 *buf, UINT32 padded_len,
|
|||
*/
|
||||
{
|
||||
UINT32 nbits;
|
||||
|
||||
|
||||
/* Initialize the hash state */
|
||||
nbits = (unpadded_len << 3);
|
||||
|
||||
|
||||
((UINT64 *)result)[0] = nbits;
|
||||
#if (UMAC_OUTPUT_LEN >= 8)
|
||||
((UINT64 *)result)[1] = nbits;
|
||||
|
@ -725,7 +725,7 @@ static void nh(nh_ctx *hc, const UINT8 *buf, UINT32 padded_len,
|
|||
#if (UMAC_OUTPUT_LEN == 16)
|
||||
((UINT64 *)result)[3] = nbits;
|
||||
#endif
|
||||
|
||||
|
||||
nh_aux(hc->nh_key, buf, result, padded_len);
|
||||
}
|
||||
|
||||
|
@ -802,13 +802,13 @@ static UINT64 poly64(UINT64 cur, UINT64 key, UINT64 data)
|
|||
x_lo,
|
||||
x_hi;
|
||||
UINT64 X,T,res;
|
||||
|
||||
|
||||
X = MUL64(key_hi, cur_lo) + MUL64(cur_hi, key_lo);
|
||||
x_lo = (UINT32)X;
|
||||
x_hi = (UINT32)(X >> 32);
|
||||
|
||||
|
||||
res = (MUL64(key_hi, cur_hi) + x_hi) * 59 + MUL64(key_lo, cur_lo);
|
||||
|
||||
|
||||
T = ((UINT64)x_lo << 32);
|
||||
res += T;
|
||||
if (res < T)
|
||||
|
@ -832,7 +832,7 @@ static void poly_hash(uhash_ctx_t hc, UINT32 data_in[])
|
|||
{
|
||||
int i;
|
||||
UINT64 *data=(UINT64*)data_in;
|
||||
|
||||
|
||||
for (i = 0; i < STREAMS; i++) {
|
||||
if ((UINT32)(data[i] >> 32) == 0xfffffffful) {
|
||||
hc->poly_accum[i] = poly64(hc->poly_accum[i],
|
||||
|
@ -862,7 +862,7 @@ static UINT64 ip_aux(UINT64 t, UINT64 *ipkp, UINT64 data)
|
|||
t = t + ipkp[1] * (UINT64)(UINT16)(data >> 32);
|
||||
t = t + ipkp[2] * (UINT64)(UINT16)(data >> 16);
|
||||
t = t + ipkp[3] * (UINT64)(UINT16)(data);
|
||||
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -870,7 +870,7 @@ static UINT32 ip_reduce_p36(UINT64 t)
|
|||
{
|
||||
/* Divisionless modular reduction */
|
||||
UINT64 ret;
|
||||
|
||||
|
||||
ret = (t & m36) + 5 * (t >> 36);
|
||||
if (ret >= p36)
|
||||
ret -= p36;
|
||||
|
@ -888,7 +888,7 @@ static void ip_short(uhash_ctx_t ahc, UINT8 *nh_res, u_char *res)
|
|||
{
|
||||
UINT64 t;
|
||||
UINT64 *nhp = (UINT64 *)nh_res;
|
||||
|
||||
|
||||
t = ip_aux(0,ahc->ip_keys, nhp[0]);
|
||||
STORE_UINT32_BIG((UINT32 *)res+0, ip_reduce_p36(t) ^ ahc->ip_trans[0]);
|
||||
#if (UMAC_OUTPUT_LEN >= 8)
|
||||
|
@ -958,13 +958,13 @@ static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key)
|
|||
{
|
||||
int i;
|
||||
UINT8 buf[(8*STREAMS+4)*sizeof(UINT64)];
|
||||
|
||||
|
||||
/* Zero the entire uhash context */
|
||||
memset(ahc, 0, sizeof(uhash_ctx));
|
||||
|
||||
/* Initialize the L1 hash */
|
||||
nh_init(&ahc->hash, prf_key);
|
||||
|
||||
|
||||
/* Setup L2 hash variables */
|
||||
kdf(buf, prf_key, 2, sizeof(buf)); /* Fill buffer with index 1 key */
|
||||
for (i = 0; i < STREAMS; i++) {
|
||||
|
@ -978,7 +978,7 @@ static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key)
|
|||
ahc->poly_key_8[i] &= ((UINT64)0x01ffffffu << 32) + 0x01ffffffu;
|
||||
ahc->poly_accum[i] = 1; /* Our polyhash prepends a non-zero word */
|
||||
}
|
||||
|
||||
|
||||
/* Setup L3-1 hash variables */
|
||||
kdf(buf, prf_key, 3, sizeof(buf)); /* Fill buffer with index 2 key */
|
||||
for (i = 0; i < STREAMS; i++)
|
||||
|
@ -988,7 +988,7 @@ static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key)
|
|||
sizeof(ahc->ip_keys));
|
||||
for (i = 0; i < STREAMS*4; i++)
|
||||
ahc->ip_keys[i] %= p36; /* Bring into Z_p36 */
|
||||
|
||||
|
||||
/* Setup L3-2 hash variables */
|
||||
/* Fill buffer with index 4 key */
|
||||
kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32));
|
||||
|
@ -1006,7 +1006,7 @@ static uhash_ctx_t uhash_alloc(u_char key[])
|
|||
uhash_ctx_t ctx;
|
||||
u_char bytes_to_add;
|
||||
aes_int_key prf_key;
|
||||
|
||||
|
||||
ctx = (uhash_ctx_t)malloc(sizeof(uhash_ctx)+ALLOC_BOUNDARY);
|
||||
if (ctx) {
|
||||
if (ALLOC_BOUNDARY) {
|
||||
|
@ -1029,7 +1029,7 @@ static int uhash_free(uhash_ctx_t ctx)
|
|||
{
|
||||
/* Free memory allocated by uhash_alloc */
|
||||
u_char bytes_to_sub;
|
||||
|
||||
|
||||
if (ctx) {
|
||||
if (ALLOC_BOUNDARY) {
|
||||
bytes_to_sub = *((u_char *)ctx - 1);
|
||||
|
@ -1050,12 +1050,12 @@ static int uhash_update(uhash_ctx_t ctx, const u_char *input, long len)
|
|||
UWORD bytes_hashed, bytes_remaining;
|
||||
UINT64 result_buf[STREAMS];
|
||||
UINT8 *nh_result = (UINT8 *)&result_buf;
|
||||
|
||||
|
||||
if (ctx->msg_len + len <= L1_KEY_LEN) {
|
||||
nh_update(&ctx->hash, (const UINT8 *)input, len);
|
||||
ctx->msg_len += len;
|
||||
} else {
|
||||
|
||||
|
||||
bytes_hashed = ctx->msg_len % L1_KEY_LEN;
|
||||
if (ctx->msg_len == L1_KEY_LEN)
|
||||
bytes_hashed = L1_KEY_LEN;
|
||||
|
@ -1128,7 +1128,7 @@ static int uhash(uhash_ctx_t ahc, u_char *msg, long len, u_char *res)
|
|||
UINT8 nh_result[STREAMS*sizeof(UINT64)];
|
||||
UINT32 nh_len;
|
||||
int extra_zeroes_needed;
|
||||
|
||||
|
||||
/* If the message to be hashed is no longer than L1_HASH_LEN, we skip
|
||||
* the polyhash.
|
||||
*/
|
||||
|
@ -1161,7 +1161,7 @@ static int uhash(uhash_ctx_t ahc, u_char *msg, long len, u_char *res)
|
|||
|
||||
ip_long(ahc, res);
|
||||
}
|
||||
|
||||
|
||||
uhash_reset(ahc);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1220,7 +1220,7 @@ struct umac_ctx *umac_new(const u_char key[])
|
|||
struct umac_ctx *ctx, *octx;
|
||||
size_t bytes_to_add;
|
||||
aes_int_key prf_key;
|
||||
|
||||
|
||||
octx = ctx = xcalloc(1, sizeof(*ctx) + ALLOC_BOUNDARY);
|
||||
if (ctx) {
|
||||
if (ALLOC_BOUNDARY) {
|
||||
|
@ -1234,7 +1234,7 @@ struct umac_ctx *umac_new(const u_char key[])
|
|||
uhash_init(&ctx->hash, prf_key);
|
||||
explicit_bzero(prf_key, sizeof(prf_key));
|
||||
}
|
||||
|
||||
|
||||
return (ctx);
|
||||
}
|
||||
|
||||
|
@ -1245,7 +1245,7 @@ int umac_final(struct umac_ctx *ctx, u_char tag[], const u_char nonce[8])
|
|||
{
|
||||
uhash_final(&ctx->hash, (u_char *)tag);
|
||||
pdf_gen_xor(&ctx->pdf, (const UINT8 *)nonce, (UINT8 *)tag);
|
||||
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -1270,7 +1270,7 @@ int umac(struct umac_ctx *ctx, u_char *input,
|
|||
{
|
||||
uhash(&ctx->hash, input, len, (u_char *)tag);
|
||||
pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag);
|
||||
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue