- djm@cvs.openbsd.org 2005/03/01 10:09:52
[auth-options.c channels.c channels.h clientloop.c compat.c compat.h] [misc.c misc.h readconf.c readconf.h servconf.c ssh.1 ssh.c ssh_config.5] [sshd_config.5] bz#413: allow optional specification of bind address for port forwardings. Patch originally by Dan Astorian, but worked on by several people Adds GatewayPorts=clientspecified option on server to allow remote forwards to bind to client-specified ports.
This commit is contained in:
parent
1717fd422f
commit
f91ee4c3de
10
ChangeLog
10
ChangeLog
|
@ -19,6 +19,14 @@
|
|||
[ssh_config.5]
|
||||
bz#849: document timeout on untrusted x11 forwarding sessions. Reported by
|
||||
orion AT cora.nwra.com; ok markus@
|
||||
- djm@cvs.openbsd.org 2005/03/01 10:09:52
|
||||
[auth-options.c channels.c channels.h clientloop.c compat.c compat.h]
|
||||
[misc.c misc.h readconf.c readconf.h servconf.c ssh.1 ssh.c ssh_config.5]
|
||||
[sshd_config.5]
|
||||
bz#413: allow optional specification of bind address for port forwardings.
|
||||
Patch originally by Dan Astorian, but worked on by several people
|
||||
Adds GatewayPorts=clientspecified option on server to allow remote
|
||||
forwards to bind to client-specified ports.
|
||||
|
||||
20050226
|
||||
- (dtucker) [openbsd-compat/bsd-openpty.c openbsd-compat/inet_ntop.c]
|
||||
|
@ -2195,4 +2203,4 @@
|
|||
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
|
||||
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
|
||||
|
||||
$Id: ChangeLog,v 1.3671 2005/03/01 10:17:31 djm Exp $
|
||||
$Id: ChangeLog,v 1.3672 2005/03/01 10:24:33 djm Exp $
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-options.c,v 1.28 2003/06/02 09:17:34 markus Exp $");
|
||||
RCSID("$OpenBSD: auth-options.c,v 1.29 2005/03/01 10:09:52 djm Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "match.h"
|
||||
|
@ -217,7 +217,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
|||
}
|
||||
cp = "permitopen=\"";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
char host[256], sport[6];
|
||||
char *host, *p;
|
||||
u_short port;
|
||||
char *patterns = xmalloc(strlen(opts) + 1);
|
||||
|
||||
|
@ -236,25 +236,29 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
|||
if (!*opts) {
|
||||
debug("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
auth_debug_add("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
auth_debug_add("%.100s, line %lu: missing "
|
||||
"end quote", file, linenum);
|
||||
xfree(patterns);
|
||||
goto bad_option;
|
||||
}
|
||||
patterns[i] = 0;
|
||||
opts++;
|
||||
if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 &&
|
||||
sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) {
|
||||
debug("%.100s, line %lu: Bad permitopen specification "
|
||||
"<%.100s>", file, linenum, patterns);
|
||||
p = patterns;
|
||||
host = hpdelim(&p);
|
||||
if (host == NULL || strlen(host) >= NI_MAXHOST) {
|
||||
debug("%.100s, line %lu: Bad permitopen "
|
||||
"specification <%.100s>", file, linenum,
|
||||
patterns);
|
||||
auth_debug_add("%.100s, line %lu: "
|
||||
"Bad permitopen specification", file, linenum);
|
||||
"Bad permitopen specification", file,
|
||||
linenum);
|
||||
xfree(patterns);
|
||||
goto bad_option;
|
||||
}
|
||||
if ((port = a2port(sport)) == 0) {
|
||||
debug("%.100s, line %lu: Bad permitopen port <%.100s>",
|
||||
file, linenum, sport);
|
||||
host = cleanhostname(host);
|
||||
if (p == NULL || (port = a2port(p)) == 0) {
|
||||
debug("%.100s, line %lu: Bad permitopen port "
|
||||
"<%.100s>", file, linenum, p ? p : "");
|
||||
auth_debug_add("%.100s, line %lu: "
|
||||
"Bad permitopen port", file, linenum);
|
||||
xfree(patterns);
|
||||
|
|
82
channels.c
82
channels.c
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: channels.c,v 1.211 2004/10/29 21:47:15 djm Exp $");
|
||||
RCSID("$OpenBSD: channels.c,v 1.212 2005/03/01 10:09:52 djm Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
|
@ -2179,14 +2179,14 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
|
|||
const char *host_to_connect, u_short port_to_connect, int gateway_ports)
|
||||
{
|
||||
Channel *c;
|
||||
int success, sock, on = 1;
|
||||
int sock, r, success = 0, on = 1, wildcard = 0, is_client;
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
const char *host;
|
||||
const char *host, *addr;
|
||||
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
|
||||
|
||||
success = 0;
|
||||
host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
|
||||
listen_addr : host_to_connect;
|
||||
is_client = (type == SSH_CHANNEL_PORT_LISTENER);
|
||||
|
||||
if (host == NULL) {
|
||||
error("No forward host name.");
|
||||
|
@ -2197,17 +2197,61 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
|
|||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether or not a port forward listens to loopback,
|
||||
* specified address or wildcard. On the client, a specified bind
|
||||
* address will always override gateway_ports. On the server, a
|
||||
* gateway_ports of 1 (``yes'') will override the client's
|
||||
* specification and force a wildcard bind, whereas a value of 2
|
||||
* (``clientspecified'') will bind to whatever address the client
|
||||
* asked for.
|
||||
*
|
||||
* Special-case listen_addrs are:
|
||||
*
|
||||
* "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
|
||||
* "" (empty string), "*" -> wildcard v4/v6
|
||||
* "localhost" -> loopback v4/v6
|
||||
*/
|
||||
addr = NULL;
|
||||
if (listen_addr == NULL) {
|
||||
/* No address specified: default to gateway_ports setting */
|
||||
if (gateway_ports)
|
||||
wildcard = 1;
|
||||
} else if (gateway_ports || is_client) {
|
||||
if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
|
||||
strcmp(listen_addr, "0.0.0.0") == 0) ||
|
||||
*listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
|
||||
(!is_client && gateway_ports == 1))
|
||||
wildcard = 1;
|
||||
else if (strcmp(listen_addr, "localhost") != 0)
|
||||
addr = listen_addr;
|
||||
}
|
||||
|
||||
debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s",
|
||||
type, wildcard, (addr == NULL) ? "NULL" : addr);
|
||||
|
||||
/*
|
||||
* getaddrinfo returns a loopback address if the hostname is
|
||||
* set to NULL and hints.ai_flags is not AI_PASSIVE
|
||||
*/
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = IPv4or6;
|
||||
hints.ai_flags = gateway_ports ? AI_PASSIVE : 0;
|
||||
hints.ai_flags = wildcard ? AI_PASSIVE : 0;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
snprintf(strport, sizeof strport, "%d", listen_port);
|
||||
if (getaddrinfo(NULL, strport, &hints, &aitop) != 0)
|
||||
packet_disconnect("getaddrinfo: fatal error");
|
||||
if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
|
||||
if (addr == NULL) {
|
||||
/* This really shouldn't happen */
|
||||
packet_disconnect("getaddrinfo: fatal error: %s",
|
||||
gai_strerror(r));
|
||||
} else {
|
||||
verbose("channel_setup_fwd_listener: "
|
||||
"getaddrinfo(%.64s): %s", addr, gai_strerror(r));
|
||||
packet_send_debug("channel_setup_fwd_listener: "
|
||||
"getaddrinfo(%.64s): %s", addr, gai_strerror(r));
|
||||
}
|
||||
aitop = NULL;
|
||||
}
|
||||
|
||||
for (ai = aitop; ai; ai = ai->ai_next) {
|
||||
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
|
||||
|
@ -2290,11 +2334,12 @@ channel_cancel_rport_listener(const char *host, u_short port)
|
|||
|
||||
/* protocol local port fwd, used by ssh (and sshd in v1) */
|
||||
int
|
||||
channel_setup_local_fwd_listener(u_short listen_port,
|
||||
channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
|
||||
const char *host_to_connect, u_short port_to_connect, int gateway_ports)
|
||||
{
|
||||
return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
|
||||
NULL, listen_port, host_to_connect, port_to_connect, gateway_ports);
|
||||
listen_host, listen_port, host_to_connect, port_to_connect,
|
||||
gateway_ports);
|
||||
}
|
||||
|
||||
/* protocol v2 remote port fwd, used by sshd */
|
||||
|
@ -2312,7 +2357,7 @@ channel_setup_remote_fwd_listener(const char *listen_address,
|
|||
*/
|
||||
|
||||
void
|
||||
channel_request_remote_forwarding(u_short listen_port,
|
||||
channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
|
||||
const char *host_to_connect, u_short port_to_connect)
|
||||
{
|
||||
int type, success = 0;
|
||||
|
@ -2323,7 +2368,14 @@ channel_request_remote_forwarding(u_short listen_port,
|
|||
|
||||
/* Send the forward request to the remote side. */
|
||||
if (compat20) {
|
||||
const char *address_to_bind = "0.0.0.0";
|
||||
const char *address_to_bind;
|
||||
if (listen_host == NULL)
|
||||
address_to_bind = "localhost";
|
||||
else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0)
|
||||
address_to_bind = "";
|
||||
else
|
||||
address_to_bind = listen_host;
|
||||
|
||||
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
||||
packet_put_cstring("tcpip-forward");
|
||||
packet_put_char(1); /* boolean: want reply */
|
||||
|
@ -2369,10 +2421,9 @@ channel_request_remote_forwarding(u_short listen_port,
|
|||
* local side.
|
||||
*/
|
||||
void
|
||||
channel_request_rforward_cancel(u_short port)
|
||||
channel_request_rforward_cancel(const char *host, u_short port)
|
||||
{
|
||||
int i;
|
||||
const char *address_to_bind = "0.0.0.0";
|
||||
|
||||
if (!compat20)
|
||||
return;
|
||||
|
@ -2389,7 +2440,7 @@ channel_request_rforward_cancel(u_short port)
|
|||
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
||||
packet_put_cstring("cancel-tcpip-forward");
|
||||
packet_put_char(0);
|
||||
packet_put_cstring(address_to_bind);
|
||||
packet_put_cstring(host == NULL ? "" : host);
|
||||
packet_put_int(port);
|
||||
packet_send();
|
||||
|
||||
|
@ -2430,7 +2481,8 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
|
|||
#endif
|
||||
|
||||
/* Initiate forwarding */
|
||||
channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports);
|
||||
channel_setup_local_fwd_listener(NULL, port, hostname,
|
||||
host_port, gateway_ports);
|
||||
|
||||
/* Free the argument string. */
|
||||
xfree(hostname);
|
||||
|
|
10
channels.h
10
channels.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: channels.h,v 1.75 2004/10/29 21:47:15 djm Exp $ */
|
||||
/* $OpenBSD: channels.h,v 1.76 2005/03/01 10:09:52 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -203,9 +203,11 @@ void channel_clear_permitted_opens(void);
|
|||
void channel_input_port_forward_request(int, int);
|
||||
int channel_connect_to(const char *, u_short);
|
||||
int channel_connect_by_listen_address(u_short);
|
||||
void channel_request_remote_forwarding(u_short, const char *, u_short);
|
||||
void channel_request_rforward_cancel(u_short port);
|
||||
int channel_setup_local_fwd_listener(u_short, const char *, u_short, int);
|
||||
void channel_request_remote_forwarding(const char *, u_short,
|
||||
const char *, u_short);
|
||||
int channel_setup_local_fwd_listener(const char *, u_short,
|
||||
const char *, u_short, int);
|
||||
void channel_request_rforward_cancel(const char *host, u_short port);
|
||||
int channel_setup_remote_fwd_listener(const char *, u_short, int);
|
||||
int channel_cancel_rport_listener(const char *, u_short);
|
||||
|
||||
|
|
53
clientloop.c
53
clientloop.c
|
@ -59,7 +59,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: clientloop.c,v 1.134 2004/11/07 00:01:46 djm Exp $");
|
||||
RCSID("$OpenBSD: clientloop.c,v 1.135 2005/03/01 10:09:52 djm Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
|
@ -763,11 +763,11 @@ static void
|
|||
process_cmdline(void)
|
||||
{
|
||||
void (*handler)(int);
|
||||
char *s, *cmd;
|
||||
u_short fwd_port, fwd_host_port;
|
||||
char buf[1024], sfwd_port[6], sfwd_host_port[6];
|
||||
char *s, *cmd, *cancel_host;
|
||||
int delete = 0;
|
||||
int local = 0;
|
||||
u_short cancel_port;
|
||||
Forward fwd;
|
||||
|
||||
leave_raw_mode();
|
||||
handler = signal(SIGINT, SIG_IGN);
|
||||
|
@ -813,37 +813,38 @@ process_cmdline(void)
|
|||
s++;
|
||||
|
||||
if (delete) {
|
||||
if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) {
|
||||
logit("Bad forwarding specification.");
|
||||
goto out;
|
||||
}
|
||||
if ((fwd_host_port = a2port(sfwd_host_port)) == 0) {
|
||||
logit("Bad forwarding port(s).");
|
||||
goto out;
|
||||
}
|
||||
channel_request_rforward_cancel(fwd_host_port);
|
||||
cancel_port = 0;
|
||||
cancel_host = hpdelim(&s); /* may be NULL */
|
||||
if (s != NULL) {
|
||||
cancel_port = a2port(s);
|
||||
cancel_host = cleanhostname(cancel_host);
|
||||
} else {
|
||||
if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
|
||||
sfwd_port, buf, sfwd_host_port) != 3 &&
|
||||
sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
|
||||
sfwd_port, buf, sfwd_host_port) != 3) {
|
||||
logit("Bad forwarding specification.");
|
||||
cancel_port = a2port(cancel_host);
|
||||
cancel_host = NULL;
|
||||
}
|
||||
if (cancel_port == 0) {
|
||||
logit("Bad forwarding close port");
|
||||
goto out;
|
||||
}
|
||||
if ((fwd_port = a2port(sfwd_port)) == 0 ||
|
||||
(fwd_host_port = a2port(sfwd_host_port)) == 0) {
|
||||
logit("Bad forwarding port(s).");
|
||||
channel_request_rforward_cancel(cancel_host, cancel_port);
|
||||
} else {
|
||||
if (!parse_forward(&fwd, s)) {
|
||||
logit("Bad forwarding specification.");
|
||||
goto out;
|
||||
}
|
||||
if (local) {
|
||||
if (channel_setup_local_fwd_listener(fwd_port, buf,
|
||||
fwd_host_port, options.gateway_ports) < 0) {
|
||||
if (channel_setup_local_fwd_listener(fwd.listen_host,
|
||||
fwd.listen_port, fwd.connect_host,
|
||||
fwd.connect_port, options.gateway_ports) < 0) {
|
||||
logit("Port forwarding failed.");
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
channel_request_remote_forwarding(fwd_port, buf,
|
||||
fwd_host_port);
|
||||
} else {
|
||||
channel_request_remote_forwarding(fwd.listen_host,
|
||||
fwd.listen_port, fwd.connect_host,
|
||||
fwd.connect_port);
|
||||
}
|
||||
|
||||
logit("Forwarding port.");
|
||||
}
|
||||
|
||||
|
|
20
compat.c
20
compat.c
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: compat.c,v 1.70 2003/11/02 11:01:03 markus Exp $");
|
||||
RCSID("$OpenBSD: compat.c,v 1.71 2005/03/01 10:09:52 djm Exp $");
|
||||
|
||||
#include "buffer.h"
|
||||
#include "packet.h"
|
||||
|
@ -62,24 +62,28 @@ compat_datafellows(const char *version)
|
|||
"OpenSSH_2.1*,"
|
||||
"OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER|
|
||||
SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||
SSH_BUG_EXTEOF},
|
||||
SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
|
||||
SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||
SSH_BUG_EXTEOF},
|
||||
SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
|
||||
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
|
||||
SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.5.0p1*,"
|
||||
"OpenSSH_2.5.1p1*",
|
||||
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
|
||||
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
|
||||
SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.5.0*,"
|
||||
"OpenSSH_2.5.1*,"
|
||||
"OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||
SSH_BUG_EXTEOF},
|
||||
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||
SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
|
||||
SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.*,"
|
||||
"OpenSSH_3.0*,"
|
||||
"OpenSSH_3.1*", SSH_BUG_EXTEOF},
|
||||
"OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR },
|
||||
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||
{ "OpenSSH*", 0 },
|
||||
{ "*MindTerm*", 0 },
|
||||
|
|
3
compat.h
3
compat.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: compat.h,v 1.38 2004/07/11 17:48:47 deraadt Exp $ */
|
||||
/* $OpenBSD: compat.h,v 1.39 2005/03/01 10:09:52 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -55,6 +55,7 @@
|
|||
#define SSH_BUG_EXTEOF 0x00200000
|
||||
#define SSH_BUG_PROBE 0x00400000
|
||||
#define SSH_BUG_FIRSTKEX 0x00800000
|
||||
#define SSH_OLD_FORWARD_ADDR 0x01000000
|
||||
|
||||
void enable_compat13(void);
|
||||
void enable_compat20(void);
|
||||
|
|
44
misc.c
44
misc.c
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: misc.c,v 1.27 2004/12/11 01:48:56 dtucker Exp $");
|
||||
RCSID("$OpenBSD: misc.c,v 1.28 2005/03/01 10:09:52 djm Exp $");
|
||||
|
||||
#include "misc.h"
|
||||
#include "log.h"
|
||||
|
@ -275,6 +275,48 @@ convtime(const char *s)
|
|||
return total;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for next delimiter between hostnames/addresses and ports.
|
||||
* Argument may be modified (for termination).
|
||||
* Returns *cp if parsing succeeds.
|
||||
* *cp is set to the start of the next delimiter, if one was found.
|
||||
* If this is the last field, *cp is set to NULL.
|
||||
*/
|
||||
char *
|
||||
hpdelim(char **cp)
|
||||
{
|
||||
char *s, *old;
|
||||
|
||||
if (cp == NULL || *cp == NULL)
|
||||
return NULL;
|
||||
|
||||
old = s = *cp;
|
||||
if (*s == '[') {
|
||||
if ((s = strchr(s, ']')) == NULL)
|
||||
return NULL;
|
||||
else
|
||||
s++;
|
||||
} else if ((s = strpbrk(s, ":/")) == NULL)
|
||||
s = *cp + strlen(*cp); /* skip to end (see first case below) */
|
||||
|
||||
switch (*s) {
|
||||
case '\0':
|
||||
*cp = NULL; /* no more fields*/
|
||||
break;
|
||||
|
||||
case ':':
|
||||
case '/':
|
||||
*s = '\0'; /* terminate */
|
||||
*cp = s + 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
char *
|
||||
cleanhostname(char *host)
|
||||
{
|
||||
|
|
3
misc.h
3
misc.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: misc.h,v 1.20 2004/12/11 01:48:56 dtucker Exp $ */
|
||||
/* $OpenBSD: misc.h,v 1.21 2005/03/01 10:09:52 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -20,6 +20,7 @@ int set_nonblock(int);
|
|||
int unset_nonblock(int);
|
||||
void set_nodelay(int);
|
||||
int a2port(const char *);
|
||||
char *hpdelim(char **);
|
||||
char *cleanhostname(char *);
|
||||
char *colon(char *);
|
||||
long convtime(const char *);
|
||||
|
|
157
readconf.c
157
readconf.c
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: readconf.c,v 1.134 2004/07/11 17:48:47 deraadt Exp $");
|
||||
RCSID("$OpenBSD: readconf.c,v 1.135 2005/03/01 10:09:52 djm Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
|
@ -206,21 +206,23 @@ static struct {
|
|||
*/
|
||||
|
||||
void
|
||||
add_local_forward(Options *options, u_short port, const char *host,
|
||||
u_short host_port)
|
||||
add_local_forward(Options *options, const Forward *newfwd)
|
||||
{
|
||||
Forward *fwd;
|
||||
#ifndef NO_IPPORT_RESERVED_CONCEPT
|
||||
extern uid_t original_real_uid;
|
||||
if (port < IPPORT_RESERVED && original_real_uid != 0)
|
||||
if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
|
||||
fatal("Privileged ports can only be forwarded by root.");
|
||||
#endif
|
||||
if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
|
||||
fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
|
||||
fwd = &options->local_forwards[options->num_local_forwards++];
|
||||
fwd->port = port;
|
||||
fwd->host = xstrdup(host);
|
||||
fwd->host_port = host_port;
|
||||
|
||||
fwd->listen_host = (newfwd->listen_host == NULL) ?
|
||||
NULL : xstrdup(newfwd->listen_host);
|
||||
fwd->listen_port = newfwd->listen_port;
|
||||
fwd->connect_host = xstrdup(newfwd->connect_host);
|
||||
fwd->connect_port = newfwd->connect_port;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -229,17 +231,19 @@ add_local_forward(Options *options, u_short port, const char *host,
|
|||
*/
|
||||
|
||||
void
|
||||
add_remote_forward(Options *options, u_short port, const char *host,
|
||||
u_short host_port)
|
||||
add_remote_forward(Options *options, const Forward *newfwd)
|
||||
{
|
||||
Forward *fwd;
|
||||
if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
|
||||
fatal("Too many remote forwards (max %d).",
|
||||
SSH_MAX_FORWARDS_PER_DIRECTION);
|
||||
fwd = &options->remote_forwards[options->num_remote_forwards++];
|
||||
fwd->port = port;
|
||||
fwd->host = xstrdup(host);
|
||||
fwd->host_port = host_port;
|
||||
|
||||
fwd->listen_host = (newfwd->listen_host == NULL) ?
|
||||
NULL : xstrdup(newfwd->listen_host);
|
||||
fwd->listen_port = newfwd->listen_port;
|
||||
fwd->connect_host = xstrdup(newfwd->connect_host);
|
||||
fwd->connect_port = newfwd->connect_port;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -247,11 +251,15 @@ clear_forwardings(Options *options)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < options->num_local_forwards; i++)
|
||||
xfree(options->local_forwards[i].host);
|
||||
for (i = 0; i < options->num_local_forwards; i++) {
|
||||
xfree(options->local_forwards[i].listen_host);
|
||||
xfree(options->local_forwards[i].connect_host);
|
||||
}
|
||||
options->num_local_forwards = 0;
|
||||
for (i = 0; i < options->num_remote_forwards; i++)
|
||||
xfree(options->remote_forwards[i].host);
|
||||
for (i = 0; i < options->num_remote_forwards; i++) {
|
||||
xfree(options->remote_forwards[i].listen_host);
|
||||
xfree(options->remote_forwards[i].connect_host);
|
||||
}
|
||||
options->num_remote_forwards = 0;
|
||||
}
|
||||
|
||||
|
@ -284,11 +292,10 @@ process_config_line(Options *options, const char *host,
|
|||
char *line, const char *filename, int linenum,
|
||||
int *activep)
|
||||
{
|
||||
char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
|
||||
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
|
||||
int opcode, *intptr, value;
|
||||
size_t len;
|
||||
u_short fwd_port, fwd_host_port;
|
||||
char sfwd_host_port[6];
|
||||
Forward fwd;
|
||||
|
||||
/* Strip trailing whitespace */
|
||||
for(len = strlen(line) - 1; len > 0; len--) {
|
||||
|
@ -645,30 +652,26 @@ parse_int:
|
|||
case oLocalForward:
|
||||
case oRemoteForward:
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
if (arg == NULL || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing port argument.",
|
||||
filename, linenum);
|
||||
if ((fwd_port = a2port(arg)) == 0)
|
||||
fatal("%.200s line %d: Bad listen port.",
|
||||
arg2 = strdelim(&s);
|
||||
if (arg2 == NULL || *arg2 == '\0')
|
||||
fatal("%.200s line %d: Missing target argument.",
|
||||
filename, linenum);
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing second argument.",
|
||||
filename, linenum);
|
||||
if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
|
||||
sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
|
||||
|
||||
/* construct a string for parse_forward */
|
||||
snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
|
||||
|
||||
if (parse_forward(&fwd, fwdarg) == 0)
|
||||
fatal("%.200s line %d: Bad forwarding specification.",
|
||||
filename, linenum);
|
||||
if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
|
||||
fatal("%.200s line %d: Bad forwarding port.",
|
||||
filename, linenum);
|
||||
|
||||
if (*activep) {
|
||||
if (opcode == oLocalForward)
|
||||
add_local_forward(options, fwd_port, buf,
|
||||
fwd_host_port);
|
||||
add_local_forward(options, &fwd);
|
||||
else if (opcode == oRemoteForward)
|
||||
add_remote_forward(options, fwd_port, buf,
|
||||
fwd_host_port);
|
||||
add_remote_forward(options, &fwd);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -677,12 +680,25 @@ parse_int:
|
|||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing port argument.",
|
||||
filename, linenum);
|
||||
fwd_port = a2port(arg);
|
||||
if (fwd_port == 0)
|
||||
memset(&fwd, '\0', sizeof(fwd));
|
||||
fwd.connect_host = "socks";
|
||||
fwd.listen_host = hpdelim(&arg);
|
||||
if (fwd.listen_host == NULL ||
|
||||
strlen(fwd.listen_host) >= NI_MAXHOST)
|
||||
fatal("%.200s line %d: Bad forwarding specification.",
|
||||
filename, linenum);
|
||||
if (arg) {
|
||||
fwd.listen_port = a2port(arg);
|
||||
fwd.listen_host = cleanhostname(fwd.listen_host);
|
||||
} else {
|
||||
fwd.listen_port = a2port(fwd.listen_host);
|
||||
fwd.listen_host = "";
|
||||
}
|
||||
if (fwd.listen_port == 0)
|
||||
fatal("%.200s line %d: Badly formatted port number.",
|
||||
filename, linenum);
|
||||
if (*activep)
|
||||
add_local_forward(options, fwd_port, "socks", 0);
|
||||
add_local_forward(options, &fwd);
|
||||
break;
|
||||
|
||||
case oClearAllForwardings:
|
||||
|
@ -1045,3 +1061,68 @@ fill_default_options(Options * options)
|
|||
/* options->host_key_alias should not be set by default */
|
||||
/* options->preferred_authentications will be set in ssh */
|
||||
}
|
||||
|
||||
/*
|
||||
* parse_forward
|
||||
* parses a string containing a port forwarding specification of the form:
|
||||
* [listenhost:]listenport:connecthost:connectport
|
||||
* returns number of arguments parsed or zero on error
|
||||
*/
|
||||
int
|
||||
parse_forward(Forward *fwd, const char *fwdspec)
|
||||
{
|
||||
int i;
|
||||
char *p, *cp, *fwdarg[4];
|
||||
|
||||
memset(fwd, '\0', sizeof(*fwd));
|
||||
|
||||
cp = p = xstrdup(fwdspec);
|
||||
|
||||
/* skip leading spaces */
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
if ((fwdarg[i] = hpdelim(&cp)) == NULL)
|
||||
break;
|
||||
|
||||
/* Check for trailing garbage in 4-arg case*/
|
||||
if (cp != NULL)
|
||||
i = 0; /* failure */
|
||||
|
||||
switch (i) {
|
||||
case 3:
|
||||
fwd->listen_host = NULL;
|
||||
fwd->listen_port = a2port(fwdarg[0]);
|
||||
fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
|
||||
fwd->connect_port = a2port(fwdarg[2]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
|
||||
fwd->listen_port = a2port(fwdarg[1]);
|
||||
fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
|
||||
fwd->connect_port = a2port(fwdarg[3]);
|
||||
break;
|
||||
default:
|
||||
i = 0; /* failure */
|
||||
}
|
||||
|
||||
xfree(p);
|
||||
|
||||
if (fwd->listen_port == 0 && fwd->connect_port == 0)
|
||||
goto fail_free;
|
||||
|
||||
if (fwd->connect_host != NULL &&
|
||||
strlen(fwd->connect_host) >= NI_MAXHOST)
|
||||
goto fail_free;
|
||||
|
||||
return (i);
|
||||
|
||||
fail_free:
|
||||
if (fwd->connect_host != NULL)
|
||||
xfree(fwd->connect_host);
|
||||
if (fwd->listen_host != NULL)
|
||||
xfree(fwd->listen_host);
|
||||
return (0);
|
||||
}
|
||||
|
|
14
readconf.h
14
readconf.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: readconf.h,v 1.64 2004/07/11 17:48:47 deraadt Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.65 2005/03/01 10:09:52 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -21,9 +21,10 @@
|
|||
/* Data structure for representing a forwarding request. */
|
||||
|
||||
typedef struct {
|
||||
u_short port; /* Port to forward. */
|
||||
char *host; /* Host to connect. */
|
||||
u_short host_port; /* Port to connect on host. */
|
||||
char *listen_host; /* Host (address) to listen on. */
|
||||
u_short listen_port; /* Port to forward. */
|
||||
char *connect_host; /* Host to connect. */
|
||||
u_short connect_port; /* Port to connect on connect_host. */
|
||||
} Forward;
|
||||
/* Data structure for representing option data. */
|
||||
|
||||
|
@ -117,11 +118,12 @@ typedef struct {
|
|||
void initialize_options(Options *);
|
||||
void fill_default_options(Options *);
|
||||
int read_config_file(const char *, const char *, Options *, int);
|
||||
int parse_forward(Forward *, const char *);
|
||||
|
||||
int
|
||||
process_config_line(Options *, const char *, char *, const char *, int, int *);
|
||||
|
||||
void add_local_forward(Options *, u_short, const char *, u_short);
|
||||
void add_remote_forward(Options *, u_short, const char *, u_short);
|
||||
void add_local_forward(Options *, const Forward *);
|
||||
void add_remote_forward(Options *, const Forward *);
|
||||
|
||||
#endif /* READCONF_H */
|
||||
|
|
63
servconf.c
63
servconf.c
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: servconf.c,v 1.138 2004/12/23 23:11:00 djm Exp $");
|
||||
RCSID("$OpenBSD: servconf.c,v 1.139 2005/03/01 10:09:52 djm Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "log.h"
|
||||
|
@ -440,6 +440,7 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
char *cp, **charptr, *arg, *p;
|
||||
int *intptr, value, i, n;
|
||||
ServerOpCodes opcode;
|
||||
u_short port;
|
||||
|
||||
cp = line;
|
||||
arg = strdelim(&cp);
|
||||
|
@ -512,39 +513,21 @@ parse_time:
|
|||
|
||||
case sListenAddress:
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
|
||||
fatal("%s line %d: missing inet addr.",
|
||||
if (arg == NULL || *arg == '\0')
|
||||
fatal("%s line %d: missing address",
|
||||
filename, linenum);
|
||||
if (*arg == '[') {
|
||||
if ((p = strchr(arg, ']')) == NULL)
|
||||
fatal("%s line %d: bad ipv6 inet addr usage.",
|
||||
p = hpdelim(&arg);
|
||||
if (p == NULL)
|
||||
fatal("%s line %d: bad address:port usage",
|
||||
filename, linenum);
|
||||
arg++;
|
||||
memmove(p, p+1, strlen(p+1)+1);
|
||||
} else if (((p = strchr(arg, ':')) == NULL) ||
|
||||
(strchr(p+1, ':') != NULL)) {
|
||||
add_listen_addr(options, arg, 0);
|
||||
break;
|
||||
}
|
||||
if (*p == ':') {
|
||||
u_short port;
|
||||
p = cleanhostname(p);
|
||||
if (arg == NULL)
|
||||
port = 0;
|
||||
else if ((port = a2port(arg)) == 0)
|
||||
fatal("%s line %d: bad port number", filename, linenum);
|
||||
|
||||
add_listen_addr(options, p, port);
|
||||
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
fatal("%s line %d: bad inet addr:port usage.",
|
||||
filename, linenum);
|
||||
else {
|
||||
*(p-1) = '\0';
|
||||
if ((port = a2port(p)) == 0)
|
||||
fatal("%s line %d: bad port number.",
|
||||
filename, linenum);
|
||||
add_listen_addr(options, arg, port);
|
||||
}
|
||||
} else if (*p == '\0')
|
||||
add_listen_addr(options, arg, 0);
|
||||
else
|
||||
fatal("%s line %d: bad inet addr usage.",
|
||||
filename, linenum);
|
||||
break;
|
||||
|
||||
case sAddressFamily:
|
||||
|
@ -742,7 +725,23 @@ parse_flag:
|
|||
|
||||
case sGatewayPorts:
|
||||
intptr = &options->gateway_ports;
|
||||
goto parse_flag;
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing yes/no/clientspecified "
|
||||
"argument.", filename, linenum);
|
||||
value = 0; /* silence compiler */
|
||||
if (strcmp(arg, "clientspecified") == 0)
|
||||
value = 2;
|
||||
else if (strcmp(arg, "yes") == 0)
|
||||
value = 1;
|
||||
else if (strcmp(arg, "no") == 0)
|
||||
value = 0;
|
||||
else
|
||||
fatal("%s line %d: Bad yes/no/clientspecified "
|
||||
"argument: %s", filename, linenum, arg);
|
||||
if (*intptr == -1)
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case sUseDNS:
|
||||
intptr = &options->use_dns;
|
||||
|
|
59
ssh.1
59
ssh.1
|
@ -34,7 +34,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh.1,v 1.199 2004/11/07 17:42:36 jmc Exp $
|
||||
.\" $OpenBSD: ssh.1,v 1.200 2005/03/01 10:09:52 djm Exp $
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
|
@ -53,13 +53,13 @@
|
|||
.Op Fl i Ar identity_file
|
||||
.Oo Fl L Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address : Oc
|
||||
.Ar port :
|
||||
.Ar host :
|
||||
.Ar hostport
|
||||
.Sm on
|
||||
.Xc
|
||||
.Oc
|
||||
.Ek
|
||||
.Op Fl l Ar login_name
|
||||
.Op Fl m Ar mac_spec
|
||||
.Op Fl O Ar ctl_cmd
|
||||
|
@ -69,6 +69,7 @@
|
|||
.Ek
|
||||
.Oo Fl R Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address : Oc
|
||||
.Ar port :
|
||||
.Ar host :
|
||||
.Ar hostport
|
||||
|
@ -570,6 +571,7 @@ configuration files).
|
|||
Disables forwarding (delegation) of GSSAPI credentials to the server.
|
||||
.It Fl L Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address : Oc
|
||||
.Ar port : host : hostport
|
||||
.Sm on
|
||||
.Xc
|
||||
|
@ -577,7 +579,9 @@ Specifies that the given port on the local (client) host is to be
|
|||
forwarded to the given host and port on the remote side.
|
||||
This works by allocating a socket to listen to
|
||||
.Ar port
|
||||
on the local side, and whenever a connection is made to this port, the
|
||||
on the local side, optionally bound to the specified
|
||||
.Ar bind_address .
|
||||
Whenever a connection is made to this port, the
|
||||
connection is forwarded over the secure channel, and a connection is
|
||||
made to
|
||||
.Ar host
|
||||
|
@ -585,14 +589,30 @@ port
|
|||
.Ar hostport
|
||||
from the remote machine.
|
||||
Port forwardings can also be specified in the configuration file.
|
||||
Only root can forward privileged ports.
|
||||
IPv6 addresses can be specified with an alternative syntax:
|
||||
.Sm off
|
||||
.Xo
|
||||
.Oo Ar bind_address / Oc
|
||||
.Ar port No / Ar host No /
|
||||
.Ar hostport .
|
||||
.Ar hostport
|
||||
.Xc
|
||||
.Sm on
|
||||
or by enclosing the address in square brackets.
|
||||
Only the superuser can forward privileged ports.
|
||||
By default, the local port is bound in accordance with the
|
||||
.Cm GatewayPorts
|
||||
setting.
|
||||
However, an explicit
|
||||
.Ar bind_address
|
||||
may be used to bind the connection to a specific address.
|
||||
The
|
||||
.Ar bind_address
|
||||
of
|
||||
.Dq localhost
|
||||
indicates that the listening port be bound for local use only, while an
|
||||
empty address or
|
||||
.Dq *
|
||||
indicates that the port should be available from all interfaces.
|
||||
.It Fl l Ar login_name
|
||||
Specifies the user to log in as on the remote machine.
|
||||
This also may be specified on a per-host basis in the configuration file.
|
||||
|
@ -724,6 +744,7 @@ Quiet mode.
|
|||
Causes all warning and diagnostic messages to be suppressed.
|
||||
.It Fl R Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address : Oc
|
||||
.Ar port : host : hostport
|
||||
.Sm on
|
||||
.Xc
|
||||
|
@ -738,16 +759,34 @@ made to
|
|||
port
|
||||
.Ar hostport
|
||||
from the local machine.
|
||||
.Pp
|
||||
Port forwardings can also be specified in the configuration file.
|
||||
Privileged ports can be forwarded only when
|
||||
logging in as root on the remote machine.
|
||||
IPv6 addresses can be specified with an alternative syntax:
|
||||
.Sm off
|
||||
IPv6 addresses can be specified by enclosing the address in square braces or
|
||||
using an alternative syntax:
|
||||
.Xo
|
||||
.Ar port No / Ar host No /
|
||||
.Ar hostport .
|
||||
.Xc
|
||||
.Sm off
|
||||
.Oo Ar bind_address / Oc
|
||||
.Ar host/port/hostport
|
||||
.Sm on
|
||||
.Xc .
|
||||
.Pp
|
||||
By default, the listening socket on the server will be bound to the loopback
|
||||
interface only.
|
||||
This may be overriden by specifying a
|
||||
.Ar bind_address .
|
||||
An empty
|
||||
.Ar bind_address ,
|
||||
or the address
|
||||
.Ql *
|
||||
indicates that the remote socket should listen on all interfaces.
|
||||
Specifying a remote
|
||||
.Ar bind_address
|
||||
will only succeed if the server's
|
||||
.Cm GatewayPorts
|
||||
option is enabled (see
|
||||
.Xr sshd_config 5 ).
|
||||
.It Fl S Ar ctl_path
|
||||
Specifies the location of a control socket for connection sharing.
|
||||
Refer to the description of
|
||||
|
|
114
ssh.c
114
ssh.c
|
@ -40,7 +40,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh.c,v 1.231 2005/02/16 09:56:44 otto Exp $");
|
||||
RCSID("$OpenBSD: ssh.c,v 1.232 2005/03/01 10:09:52 djm Exp $");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
|
@ -158,9 +158,10 @@ usage(void)
|
|||
{
|
||||
fprintf(stderr,
|
||||
"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
|
||||
" [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n"
|
||||
" [-L port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd]\n"
|
||||
" [-o option] [-p port] [-R port:host:hostport] [-S ctl_path]\n"
|
||||
" [-D [listen-host:]port] [-e escape_char] [-F configfile]\n"
|
||||
" [-i identity_file] [-L [listen-host:]port:host:hostport]\n"
|
||||
" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
|
||||
" [-R [listen-host:]port:host:hostport] [-S ctl_path]\n"
|
||||
" [user@]hostname [command]\n"
|
||||
);
|
||||
exit(1);
|
||||
|
@ -178,14 +179,13 @@ int
|
|||
main(int ac, char **av)
|
||||
{
|
||||
int i, opt, exit_status;
|
||||
u_short fwd_port, fwd_host_port;
|
||||
char sfwd_port[6], sfwd_host_port[6];
|
||||
char *p, *cp, *line, buf[256];
|
||||
struct stat st;
|
||||
struct passwd *pw;
|
||||
int dummy;
|
||||
extern int optind, optreset;
|
||||
extern char *optarg;
|
||||
Forward fwd;
|
||||
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
init_rng();
|
||||
|
@ -401,39 +401,51 @@ again:
|
|||
break;
|
||||
|
||||
case 'L':
|
||||
case 'R':
|
||||
if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]",
|
||||
sfwd_port, buf, sfwd_host_port) != 3 &&
|
||||
sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]",
|
||||
sfwd_port, buf, sfwd_host_port) != 3) {
|
||||
if (parse_forward(&fwd, optarg))
|
||||
add_local_forward(&options, &fwd);
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Bad forwarding specification '%s'\n",
|
||||
"Bad local forwarding specification '%s'\n",
|
||||
optarg);
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if ((fwd_port = a2port(sfwd_port)) == 0 ||
|
||||
(fwd_host_port = a2port(sfwd_host_port)) == 0) {
|
||||
fprintf(stderr,
|
||||
"Bad forwarding port(s) '%s'\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
if (opt == 'L')
|
||||
add_local_forward(&options, fwd_port, buf,
|
||||
fwd_host_port);
|
||||
else if (opt == 'R')
|
||||
add_remote_forward(&options, fwd_port, buf,
|
||||
fwd_host_port);
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
if (parse_forward(&fwd, optarg)) {
|
||||
add_remote_forward(&options, &fwd);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Bad remote forwarding specification "
|
||||
"'%s'\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
fwd_port = a2port(optarg);
|
||||
if (fwd_port == 0) {
|
||||
cp = p = xstrdup(optarg);
|
||||
memset(&fwd, '\0', sizeof(fwd));
|
||||
fwd.connect_host = "socks";
|
||||
if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
|
||||
fprintf(stderr, "Bad dynamic forwarding "
|
||||
"specification '%.100s'\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
if (cp != NULL) {
|
||||
fwd.listen_port = a2port(cp);
|
||||
fwd.listen_host = cleanhostname(fwd.listen_host);
|
||||
} else {
|
||||
fwd.listen_port = a2port(fwd.listen_host);
|
||||
fwd.listen_host = "";
|
||||
}
|
||||
|
||||
if (fwd.listen_port == 0) {
|
||||
fprintf(stderr, "Bad dynamic port '%s'\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
add_local_forward(&options, fwd_port, "socks", 0);
|
||||
add_local_forward(&options, &fwd);
|
||||
xfree(p);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
|
@ -842,14 +854,19 @@ ssh_init_forwarding(void)
|
|||
|
||||
/* Initiate local TCP/IP port forwardings. */
|
||||
for (i = 0; i < options.num_local_forwards; i++) {
|
||||
debug("Connections to local port %d forwarded to remote address %.200s:%d",
|
||||
options.local_forwards[i].port,
|
||||
options.local_forwards[i].host,
|
||||
options.local_forwards[i].host_port);
|
||||
debug("Local connections to %.200s:%d forwarded to remote "
|
||||
"address %.200s:%d",
|
||||
(options.local_forwards[i].listen_host == NULL) ?
|
||||
(options.gateway_ports ? "*" : "LOCALHOST") :
|
||||
options.local_forwards[i].listen_host,
|
||||
options.local_forwards[i].listen_port,
|
||||
options.local_forwards[i].connect_host,
|
||||
options.local_forwards[i].connect_port);
|
||||
success += channel_setup_local_fwd_listener(
|
||||
options.local_forwards[i].port,
|
||||
options.local_forwards[i].host,
|
||||
options.local_forwards[i].host_port,
|
||||
options.local_forwards[i].listen_host,
|
||||
options.local_forwards[i].listen_port,
|
||||
options.local_forwards[i].connect_host,
|
||||
options.local_forwards[i].connect_port,
|
||||
options.gateway_ports);
|
||||
}
|
||||
if (i > 0 && success == 0)
|
||||
|
@ -857,14 +874,17 @@ ssh_init_forwarding(void)
|
|||
|
||||
/* Initiate remote TCP/IP port forwardings. */
|
||||
for (i = 0; i < options.num_remote_forwards; i++) {
|
||||
debug("Connections to remote port %d forwarded to local address %.200s:%d",
|
||||
options.remote_forwards[i].port,
|
||||
options.remote_forwards[i].host,
|
||||
options.remote_forwards[i].host_port);
|
||||
debug("Remote connections from %.200s:%d forwarded to "
|
||||
"local address %.200s:%d",
|
||||
options.remote_forwards[i].listen_host,
|
||||
options.remote_forwards[i].listen_port,
|
||||
options.remote_forwards[i].connect_host,
|
||||
options.remote_forwards[i].connect_port);
|
||||
channel_request_remote_forwarding(
|
||||
options.remote_forwards[i].port,
|
||||
options.remote_forwards[i].host,
|
||||
options.remote_forwards[i].host_port);
|
||||
options.remote_forwards[i].listen_host,
|
||||
options.remote_forwards[i].listen_port,
|
||||
options.remote_forwards[i].connect_host,
|
||||
options.remote_forwards[i].connect_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1040,12 +1060,12 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
|
|||
return;
|
||||
debug("remote forward %s for: listen %d, connect %s:%d",
|
||||
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
|
||||
options.remote_forwards[i].port,
|
||||
options.remote_forwards[i].host,
|
||||
options.remote_forwards[i].host_port);
|
||||
options.remote_forwards[i].listen_port,
|
||||
options.remote_forwards[i].connect_host,
|
||||
options.remote_forwards[i].connect_port);
|
||||
if (type == SSH2_MSG_REQUEST_FAILURE)
|
||||
logit("Warning: remote port forwarding failed for listen port %d",
|
||||
options.remote_forwards[i].port);
|
||||
logit("Warning: remote port forwarding failed for listen "
|
||||
"port %d", options.remote_forwards[i].listen_port);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
70
ssh_config.5
70
ssh_config.5
|
@ -34,7 +34,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh_config.5,v 1.42 2005/02/28 00:54:10 djm Exp $
|
||||
.\" $OpenBSD: ssh_config.5,v 1.43 2005/03/01 10:09:52 djm Exp $
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
|
@ -480,12 +480,37 @@ The default is to use the server specified list.
|
|||
Specifies that a TCP/IP port on the local machine be forwarded over
|
||||
the secure channel to the specified host and port from the remote machine.
|
||||
The first argument must be a port number, and the second must be
|
||||
.Ar host:port .
|
||||
IPv6 addresses can be specified with an alternative syntax:
|
||||
.Ar host/port .
|
||||
Multiple forwardings may be specified, and additional
|
||||
forwardings can be given on the command line.
|
||||
.Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address : Oc
|
||||
.Ar host:port
|
||||
.Sm on
|
||||
.Xc .
|
||||
IPv6 addresses can be specified by enclosing addresses in square brackets or
|
||||
by using an alternative syntax:
|
||||
.Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address / Oc
|
||||
.Ar host/port
|
||||
.Sm on
|
||||
.Xc .
|
||||
Multiple forwardings may be specified, and additional forwardings can be
|
||||
given on the command line.
|
||||
Only the superuser can forward privileged ports.
|
||||
By default, the local port is bound in accordance with the
|
||||
.Cm GatewayPorts
|
||||
setting.
|
||||
However, an explicit
|
||||
.Ar bind_address
|
||||
may be used to bind the connection to a specific address.
|
||||
The
|
||||
.Ar bind_address
|
||||
of
|
||||
.Dq localhost
|
||||
indicates that the listening port be bound for local use only, while an
|
||||
empty address or
|
||||
.Dq *
|
||||
indicates that the port should be available from all interfaces.
|
||||
.It Cm LogLevel
|
||||
Gives the verbosity level that is used when logging messages from
|
||||
.Nm ssh .
|
||||
|
@ -592,12 +617,39 @@ This option applies to protocol version 2 only.
|
|||
Specifies that a TCP/IP port on the remote machine be forwarded over
|
||||
the secure channel to the specified host and port from the local machine.
|
||||
The first argument must be a port number, and the second must be
|
||||
.Ar host:port .
|
||||
IPv6 addresses can be specified with an alternative syntax:
|
||||
.Ar host/port .
|
||||
.Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address : Oc
|
||||
.Ar host:port
|
||||
.Sm on
|
||||
.Xc .
|
||||
IPv6 addresses can be specified by enclosing any addresses in square brackets
|
||||
or by using the alternative syntax:
|
||||
.Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address / Oc
|
||||
.Ar host/port
|
||||
.Sm on
|
||||
.Xc .
|
||||
Multiple forwardings may be specified, and additional
|
||||
forwardings can be given on the command line.
|
||||
Only the superuser can forward privileged ports.
|
||||
.Pp
|
||||
If the
|
||||
.Ar bind_address
|
||||
is not specified, the default is to only bind to loopback addresses.
|
||||
If the
|
||||
.Ar bind_address
|
||||
is
|
||||
.Ql *
|
||||
or an empty string, then the forwarding is requested to listen on all
|
||||
interfaces.
|
||||
Specifying a remote
|
||||
.Ar bind_address
|
||||
will only succeed if the server's
|
||||
.Cm GatewayPorts
|
||||
option is enabled (see
|
||||
.Xr sshd_config 5 ).
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether to try rhosts based authentication with RSA host
|
||||
authentication.
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.38 2005/01/08 00:41:19 jmc Exp $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.39 2005/03/01 10:09:52 djm Exp $
|
||||
.Dd September 25, 1999
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
|
@ -256,12 +256,15 @@ This prevents other remote hosts from connecting to forwarded ports.
|
|||
.Cm GatewayPorts
|
||||
can be used to specify that
|
||||
.Nm sshd
|
||||
should bind remote port forwardings to the wildcard address,
|
||||
thus allowing remote hosts to connect to forwarded ports.
|
||||
The argument must be
|
||||
should allow remote port forwardings to bind to non-loopback addresses, thus
|
||||
allowing other hosts to connect.
|
||||
The argument may be
|
||||
.Dq no
|
||||
to force remote port forwardings to be available to the local host only,
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
to force remote port forwardings to bind to the wildcard address, or
|
||||
.Dq clientspecified
|
||||
to allow the client to select the address to which the forwarding is bound.
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm GSSAPIAuthentication
|
||||
|
|
Loading…
Reference in New Issue