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