summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorjp161948 <none@none>2007-10-26 07:29:16 -0700
committerjp161948 <none@none>2007-10-26 07:29:16 -0700
commit9b03ea0f916d36e6ec001b90683afcaee8e29a40 (patch)
treec15358939ef4c4b1318e3f463c0482391fbfb094 /usr/src
parent6f1fe22336d824f58bda6680410a6b1c2a72ea2d (diff)
downloadillumos-gate-9b03ea0f916d36e6ec001b90683afcaee8e29a40.tar.gz
PSARC/2007/610 ssh(1) binding address for port forwarding
6506674 allow specific binding address to be used with -LRD options for ssh(1) 6619347 SunSSH is not fully compatible with RFC4254 with regard to port forwarding
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/ssh/Makefile.ssh-common2
-rw-r--r--usr/src/cmd/ssh/include/channels.h39
-rw-r--r--usr/src/cmd/ssh/include/compat.h29
-rw-r--r--usr/src/cmd/ssh/include/misc.h1
-rw-r--r--usr/src/cmd/ssh/include/readconf.h14
-rw-r--r--usr/src/cmd/ssh/libssh/common/channels.c161
-rw-r--r--usr/src/cmd/ssh/libssh/common/compat.c34
-rw-r--r--usr/src/cmd/ssh/libssh/common/misc.c42
-rw-r--r--usr/src/cmd/ssh/libssh/common/readconf.c165
-rw-r--r--usr/src/cmd/ssh/ssh.po451
-rw-r--r--usr/src/cmd/ssh/ssh/clientloop.c100
-rw-r--r--usr/src/cmd/ssh/ssh/ssh.c103
-rw-r--r--usr/src/cmd/ssh/sshd/servconf.c15
-rw-r--r--usr/src/cmd/ssh/sshd/serverloop.c16
14 files changed, 773 insertions, 399 deletions
diff --git a/usr/src/cmd/ssh/Makefile.ssh-common b/usr/src/cmd/ssh/Makefile.ssh-common
index d3d27a8068..566d923ad5 100644
--- a/usr/src/cmd/ssh/Makefile.ssh-common
+++ b/usr/src/cmd/ssh/Makefile.ssh-common
@@ -33,7 +33,7 @@ TEXT_DOMAIN=SUNW_OST_OSCMD
CFLAGS += $(CCVERBOSE)
LDFLAGS += $(MAPFILE.NGB:%=-M%)
-SSH_VERSION=\"Sun_SSH_1.1\"
+SSH_VERSION=\"Sun_SSH_1.2\"
C99MODE= $(C99_ENABLE)
diff --git a/usr/src/cmd/ssh/include/channels.h b/usr/src/cmd/ssh/include/channels.h
index 449f7a6640..408f819d7f 100644
--- a/usr/src/cmd/ssh/include/channels.h
+++ b/usr/src/cmd/ssh/include/channels.h
@@ -1,20 +1,4 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/* $OpenBSD: channels.h,v 1.70 2002/06/24 14:33:27 markus Exp $ */
-
-#ifndef _CHANNELS_H
-#define _CHANNELS_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -48,6 +32,21 @@ extern "C" {
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/* $OpenBSD: channels.h,v 1.70 2002/06/24 14:33:27 markus Exp $ */
+
+
+#ifndef _CHANNELS_H
+#define _CHANNELS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
#include "buffer.h"
@@ -216,9 +215,13 @@ 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);
-int channel_setup_local_fwd_listener(u_short, const char *, u_short, int);
+int 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);
/* x11 forwarding */
diff --git a/usr/src/cmd/ssh/include/compat.h b/usr/src/cmd/ssh/include/compat.h
index 930bb08956..cd5d056f94 100644
--- a/usr/src/cmd/ssh/include/compat.h
+++ b/usr/src/cmd/ssh/include/compat.h
@@ -1,15 +1,3 @@
-/* $OpenBSD: compat.h,v 1.33 2002/09/27 10:42:09 mickey Exp $ */
-
-#ifndef _COMPAT_H
-#define _COMPAT_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -38,6 +26,18 @@ extern "C" {
* Use is subject to license terms.
*/
+#ifndef _COMPAT_H
+#define _COMPAT_H
+
+/* $OpenBSD: compat.h,v 1.33 2002/09/27 10:42:09 mickey Exp $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define SSH_PROTO_UNKNOWN 0x00
#define SSH_PROTO_1 0x01
#define SSH_PROTO_1_PREFERRED 0x02
@@ -62,6 +62,7 @@ extern "C" {
#define SSH_BUG_HBSERVICE 0x00010000
#define SSH_BUG_OPENFAILURE 0x00020000
#define SSH_BUG_DERIVEKEY 0x00040000
+/*#define this is free slot 0x00080000 */
#define SSH_BUG_DUMMYCHAN 0x00100000
#define SSH_BUG_EXTEOF 0x00200000
#define SSH_BUG_K5USER 0x00400000
@@ -70,8 +71,10 @@ extern "C" {
#define SSH_OLD_GSSAPI 0x02000000
#define SSH_BUG_GSSAPI_BER 0x04000000
#define SSH_BUG_FIRSTKEX 0x08000000
-
+#define SSH_BUG_RFWD_ADDR 0x10000000
#define SSH_BUG_GSSKEX_HOSTKEY 0x20000000
+/* SSH_OLD_FORWARD_ADDR flag bumped up the SunSSH version to 1.2 */
+#define SSH_OLD_FORWARD_ADDR 0x40000000
void enable_compat13(void);
void enable_compat20(void);
diff --git a/usr/src/cmd/ssh/include/misc.h b/usr/src/cmd/ssh/include/misc.h
index 205e88f697..16f2210291 100644
--- a/usr/src/cmd/ssh/include/misc.h
+++ b/usr/src/cmd/ssh/include/misc.h
@@ -32,6 +32,7 @@ void unset_nonblock(int);
void set_nodelay(int);
int a2port(const char *);
char *cleanhostname(char *);
+char *hpdelim(char **);
char *colon(char *);
long convtime(const char *);
char *tohex(const void *, size_t);
diff --git a/usr/src/cmd/ssh/include/readconf.h b/usr/src/cmd/ssh/include/readconf.h
index c5257a2922..3d1fe7b211 100644
--- a/usr/src/cmd/ssh/include/readconf.h
+++ b/usr/src/cmd/ssh/include/readconf.h
@@ -38,9 +38,10 @@ extern "C" {
/* 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. */
@@ -160,14 +161,15 @@ typedef struct {
void initialize_options(Options *);
void fill_default_options(Options *);
int read_config_file(const char *, const char *, Options *);
+int parse_forward(int, 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 *);
-void process_unknown_options(Options *options);
+void process_unknown_options(Options *);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/ssh/libssh/common/channels.c b/usr/src/cmd/ssh/libssh/common/channels.c
index 78c5a72f1f..03720994e3 100644
--- a/usr/src/cmd/ssh/libssh/common/channels.c
+++ b/usr/src/cmd/ssh/libssh/common/channels.c
@@ -1,8 +1,4 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -41,6 +37,10 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include "includes.h"
RCSID("$OpenBSD: channels.c,v 1.183 2002/09/17 07:47:02 itojun Exp $");
@@ -2165,35 +2165,77 @@ 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, is_client, on = 1, wildcard = 0, success = 0;
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.");
- return success;
+ return 0;
}
if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
error("Forward host name too long.");
- return success;
+ return 0;
}
/*
+ * 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 && is_client == 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 {
+ error("channel_setup_fwd_listener: "
+ "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
+ }
+ return 0;
+ }
for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
@@ -2204,7 +2246,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
continue;
}
/* Create a port to listen for the host. */
- sock = socket(ai->ai_family, SOCK_STREAM, 0);
+ sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock < 0) {
/* this is no error since kernel may not support ipv6 */
verbose("socket: %.100s", strerror(errno));
@@ -2253,13 +2295,35 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
return success;
}
+int
+channel_cancel_rport_listener(const char *host, u_short port)
+{
+ u_int i;
+ int found = 0;
+
+ for (i = 0; i < channels_alloc; i++) {
+ Channel *c = channels[i];
+
+ if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
+ strncmp(c->path, host, sizeof(c->path)) == 0 &&
+ c->listening_port == port) {
+ debug2("%s: close channel %d", __func__, i);
+ channel_free(c);
+ found = 1;
+ }
+ }
+
+ return (found);
+}
+
/* 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 */
@@ -2276,8 +2340,8 @@ channel_setup_remote_fwd_listener(const char *listen_address,
* the secure channel to host:port from local side.
*/
-void
-channel_request_remote_forwarding(u_short listen_port,
+int
+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;
@@ -2286,9 +2350,29 @@ channel_request_remote_forwarding(u_short listen_port,
if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
fatal("channel_request_remote_forwarding: too many forwards");
+ if (listen_host != NULL &&
+ strlen(listen_host) > SSH_CHANNEL_PATH_LEN - 1) {
+ error("Binding address too long.");
+ return -1;
+ }
+
/* 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) {
+ if (datafellows & SSH_BUG_RFWD_ADDR)
+ address_to_bind = "127.0.0.1";
+ else
+ address_to_bind = "localhost";
+ } else if (*listen_host == '\0' ||
+ strcmp(listen_host, "*") == 0) {
+ if (datafellows & SSH_BUG_RFWD_ADDR)
+ address_to_bind = "0.0.0.0";
+ else
+ 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 */
@@ -2327,6 +2411,41 @@ channel_request_remote_forwarding(u_short listen_port,
permitted_opens[num_permitted_opens].listen_port = listen_port;
num_permitted_opens++;
}
+ return (success ? 0 : -1);
+}
+
+/*
+ * Request cancellation of remote forwarding of connection host:port from
+ * local side.
+ */
+void
+channel_request_rforward_cancel(const char *host, u_short port)
+{
+ int i;
+
+ if (!compat20)
+ return;
+
+ for (i = 0; i < num_permitted_opens; i++) {
+ if (permitted_opens[i].host_to_connect != NULL &&
+ permitted_opens[i].listen_port == port)
+ break;
+ }
+ if (i >= num_permitted_opens) {
+ debug("%s: requested forward not found", __func__);
+ return;
+ }
+ packet_start(SSH2_MSG_GLOBAL_REQUEST);
+ packet_put_cstring("cancel-tcpip-forward");
+ packet_put_char(0);
+ packet_put_cstring(host == NULL ? "" : host);
+ packet_put_int(port);
+ packet_send();
+
+ permitted_opens[i].listen_port = 0;
+ permitted_opens[i].port_to_connect = 0;
+ xfree(permitted_opens[i].host_to_connect);
+ permitted_opens[i].host_to_connect = NULL;
}
/*
@@ -2356,7 +2475,8 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
port);
#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);
@@ -2378,7 +2498,7 @@ void
channel_add_permitted_opens(char *host, int port)
{
if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
- fatal("channel_request_remote_forwarding: too many forwards");
+ fatal("channel_add_permitted_opens: too many forwards");
debug("allow port forwarding to host %s port %d", host, port);
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
@@ -2396,7 +2516,6 @@ channel_clear_permitted_opens(void)
for (i = 0; i < num_permitted_opens; i++)
xfree(permitted_opens[i].host_to_connect);
num_permitted_opens = 0;
-
}
diff --git a/usr/src/cmd/ssh/libssh/common/compat.c b/usr/src/cmd/ssh/libssh/common/compat.c
index f63c6c0139..a6d6ef8ad3 100644
--- a/usr/src/cmd/ssh/libssh/common/compat.c
+++ b/usr/src/cmd/ssh/libssh/common/compat.c
@@ -68,42 +68,47 @@ 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_OLD_GSSAPI},
+ SSH_OLD_GSSAPI|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.9p*", SSH_BUG_EXTEOF|SSH_OLD_GSSAPI|
- SSH_BUG_GSSKEX_HOSTKEY},
+ SSH_BUG_GSSKEX_HOSTKEY|SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_2.*,"
"OpenSSH_3.0*,"
- "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_GSSAPI|
- SSH_BUG_GSSAPI_BER|
+ "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR|
+ SSH_OLD_GSSAPI|SSH_BUG_GSSAPI_BER|
SSH_BUG_GSSKEX_HOSTKEY},
{ "OpenSSH_3.2*,"
"OpenSSH_3.3*,"
"OpenSSH_3.4*,"
"OpenSSH_3.5*", SSH_BUG_GSSAPI_BER|SSH_OLD_GSSAPI|
- SSH_BUG_GSSKEX_HOSTKEY},
+ SSH_BUG_GSSKEX_HOSTKEY|SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_3.6*,"
"OpenSSH_3.7*,"
- "OpenSSH_3.8*", SSH_BUG_GSSKEX_HOSTKEY},
+ "OpenSSH_3.8*", SSH_BUG_GSSKEX_HOSTKEY|SSH_OLD_FORWARD_ADDR},
+ { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR},
{ "OpenSSH*", 0 },
{ "Sun_SSH_1.0.*", SSH_BUG_NOREKEY|
- SSH_BUG_LOCALES_NOT_LANGTAGS},
+ SSH_BUG_LOCALES_NOT_LANGTAGS|SSH_OLD_FORWARD_ADDR},
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
- SSH_BUG_LOCALES_NOT_LANGTAGS},
+ SSH_BUG_LOCALES_NOT_LANGTAGS|SSH_OLD_FORWARD_ADDR},
+ { "Sun_SSH_1.1*", SSH_OLD_FORWARD_ADDR},
+ { "Sun_SSH_1.2*", 0 },
{ "*MindTerm*", 0 },
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
@@ -145,7 +150,8 @@ compat_datafellows(const char *version)
{ "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5|
SSH_BUG_FIRSTKEX },
{ "2.4", SSH_OLD_SESSIONID }, /* Van Dyke */
- { "2.*", SSH_BUG_DEBUG|SSH_BUG_FIRSTKEX },
+ { "2.*", SSH_BUG_DEBUG|SSH_BUG_FIRSTKEX|
+ SSH_BUG_RFWD_ADDR},
{ "3.0.*", SSH_BUG_DEBUG },
{ "3.0 SecureCRT*", SSH_OLD_SESSIONID },
{ "1.7 SecureFX*", SSH_OLD_SESSIONID },
diff --git a/usr/src/cmd/ssh/libssh/common/misc.c b/usr/src/cmd/ssh/libssh/common/misc.c
index 6431255004..dcd7902021 100644
--- a/usr/src/cmd/ssh/libssh/common/misc.c
+++ b/usr/src/cmd/ssh/libssh/common/misc.c
@@ -306,6 +306,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)
{
diff --git a/usr/src/cmd/ssh/libssh/common/readconf.c b/usr/src/cmd/ssh/libssh/common/readconf.c
index e0d1ac2e71..86caa54913 100644
--- a/usr/src/cmd/ssh/libssh/common/readconf.c
+++ b/usr/src/cmd/ssh/libssh/common/readconf.c
@@ -230,21 +230,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;
}
/*
@@ -253,17 +255,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
@@ -271,11 +275,17 @@ 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++) {
+ if (options->local_forwards[i].listen_host != NULL)
+ 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++) {
+ if (options->remote_forwards[i].listen_host != NULL)
+ xfree(options->remote_forwards[i].listen_host);
+ xfree(options->remote_forwards[i].connect_host);
+ }
options->num_remote_forwards = 0;
}
@@ -307,11 +317,10 @@ process_config_line(Options *options, const char *host,
char *line, const char *filename, int linenum,
int *activep)
{
- char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
+ char *s, *string, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
int opcode, *intptr, value, i;
- u_short fwd_port, fwd_host_port;
- char sfwd_host_port[6];
StoredOption *so;
+ Forward fwd;
s = line;
/* Get the keyword. (Each line is supposed to begin with a keyword). */
@@ -694,30 +703,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.",
- filename, linenum);
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing second argument.",
+ arg2 = strdelim(&s);
+ if (arg2 == NULL || *arg2 == '\0')
+ fatal("%.200s line %d: Missing target 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(1, &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;
@@ -726,12 +731,16 @@ parse_int:
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing port argument.",
filename, linenum);
- fwd_port = a2port(arg);
- if (fwd_port == 0)
- fatal("%.200s line %d: Badly formatted port number.",
+
+ if (parse_forward(0, &fwd, arg) == 0) {
+ fatal("%.200s line %d: Bad dynamic forwarding specification.",
filename, linenum);
- if (*activep)
- add_local_forward(options, fwd_port, "socks4", 0);
+ }
+
+ if (*activep) {
+ fwd.connect_host = "socks";
+ add_local_forward(options, &fwd);
+ }
break;
case oClearAllForwardings:
@@ -1091,6 +1100,84 @@ fill_default_options(Options * options)
}
/*
+ * Parses a string containing a port forwarding specification of one of the
+ * two forms, short or long:
+ *
+ * [listenhost:]listenport
+ * [listenhost:]listenport:connecthost:connectport
+ *
+ * short forwarding specification is used for dynamic port forwarding and for
+ * port forwarding cancelation in process_cmdline(). The function returns number
+ * of arguments parsed or zero on any error.
+ */
+int
+parse_forward(int long_form, Forward *fwd, const char *fwdspec)
+{
+ int i;
+ char *p, *cp, *fwdarg[5];
+
+ memset(fwd, '\0', sizeof(*fwd));
+
+ cp = p = xstrdup(fwdspec);
+
+ /* skip leading spaces */
+ while (isspace(*cp))
+ cp++;
+
+ for (i = 0; i < 5; ++i)
+ if ((fwdarg[i] = hpdelim(&cp)) == NULL)
+ break;
+
+ if ((long_form == 0 && i > 2) || (long_form == 1 && i < 3) || (i == 5))
+ goto fail_free;
+
+ switch (i) {
+ case 0:
+ goto fail_free;
+
+ case 1:
+ fwd->listen_host = NULL;
+ fwd->listen_port = a2port(fwdarg[0]);
+ break;
+
+ case 2:
+ fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
+ fwd->listen_port = a2port(fwdarg[1]);
+ break;
+
+ 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;
+ }
+
+ xfree(p);
+
+ if (fwd->listen_port == 0 || (fwd->connect_port == 0 && i > 2))
+ goto fail_free;
+
+ return (i);
+
+ fail_free:
+ if (p != NULL)
+ xfree(p);
+ if (fwd->connect_host != NULL)
+ xfree(fwd->connect_host);
+ if (fwd->listen_host != NULL)
+ xfree(fwd->listen_host);
+ return (0);
+}
+
+/*
* Process previously stored unknown options. When this function is called we
* already have IgnoreIfUnknown set so finally we can decide whether each
* unknown option is to be ignored or not.
diff --git a/usr/src/cmd/ssh/ssh.po b/usr/src/cmd/ssh/ssh.po
index 7c7b4f1a15..1c7de1550e 100644
--- a/usr/src/cmd/ssh/ssh.po
+++ b/usr/src/cmd/ssh/ssh.po
@@ -405,8 +405,8 @@ msgstr ""
# File: ../common/channels.c, line: 2103
# File: ../common/channels.c, line: 2128
# File: ../common/channels.c, line: 2150
-# File: ../common/channels.c, line: 2756
-# File: ../common/channels.c, line: 2895
+# File: ../common/channels.c, line: 2877
+# File: ../common/channels.c, line: 3016
# File: ../common/kex.c, line: 175
# File: ../common/kex.c, line: 248
# File: ../common/kexdhc.c, line: 88
@@ -439,12 +439,12 @@ msgstr ""
# File: auth2-pubkey.c, line: 130
# File: auth2-pubkey.c, line: 163
# File: auth2.c, line: 139
-# File: clientloop.c, line: 1292
-# File: clientloop.c, line: 1302
-# File: clientloop.c, line: 1311
+# File: clientloop.c, line: 1328
# File: clientloop.c, line: 1338
-# File: clientloop.c, line: 1378
-# File: clientloop.c, line: 1493
+# File: clientloop.c, line: 1347
+# File: clientloop.c, line: 1374
+# File: clientloop.c, line: 1414
+# File: clientloop.c, line: 1529
# File: serverloop.c, line: 1024
# File: serverloop.c, line: 1040
# File: serverloop.c, line: 1053
@@ -460,8 +460,8 @@ msgstr ""
# File: session.c, line: 1717
# File: session.c, line: 1727
# File: session.c, line: 1737
-# File: ssh.c, line: 929
-# File: ssh.c, line: 977
+# File: ssh.c, line: 926
+# File: ssh.c, line: 974
# File: sshconnect1.c, line: 122
# File: sshconnect1.c, line: 260
# File: sshconnect1.c, line: 377
@@ -532,18 +532,24 @@ msgstr ""
msgid "Forward host name too long."
msgstr ""
#
-# File: ../common/channels.c, line: 2209
-msgid "getaddrinfo: fatal error"
+# File: ../common/channels.c, line: 2245
+#, c-format
+msgid "getaddrinfo: fatal error: %s"
msgstr ""
#
-# File: ../common/channels.c, line: 2216
+# File: ../common/channels.c, line: 2248
+#, c-format
+msgid "channel_setup_fwd_listener: getaddrinfo(%.64s): %s"
+msgstr ""
+#
+# File: ../common/channels.c, line: 2259
msgid "channel_setup_fwd_listener: getnameinfo failed"
msgstr ""
#
-# File: ../common/channels.c, line: 2223
-# File: ../common/channels.c, line: 2449
-# File: ../common/channels.c, line: 2549
-# File: ../common/channels.c, line: 2624
+# File: ../common/channels.c, line: 2266
+# File: ../common/channels.c, line: 2570
+# File: ../common/channels.c, line: 2670
+# File: ../common/channels.c, line: 2745
# File: session.c, line: 203
# File: sshconnect.c, line: 206
# File: sshd.c, line: 1343
@@ -551,143 +557,150 @@ msgstr ""
msgid "socket: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2233
+# File: ../common/channels.c, line: 2276
# File: sshd.c, line: 1358
#, c-format
msgid "setsockopt SO_REUSEADDR: %s"
msgstr ""
#
-# File: ../common/channels.c, line: 2241
-# File: ../common/channels.c, line: 2243
+# File: ../common/channels.c, line: 2284
+# File: ../common/channels.c, line: 2286
# File: session.c, line: 211
#, c-format
msgid "bind: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2250
-# File: ../common/channels.c, line: 2595
+# File: ../common/channels.c, line: 2293
+# File: ../common/channels.c, line: 2716
# File: session.c, line: 218
# File: sshd.c, line: 1376
#, c-format
msgid "listen: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2264
+# File: ../common/channels.c, line: 2307
#, c-format
msgid "channel_setup_fwd_listener: cannot listen to port: %d"
msgstr ""
#
-# File: ../common/channels.c, line: 2302
-# File: ../common/channels.c, line: 2399
+# File: ../common/channels.c, line: 2367
msgid "channel_request_remote_forwarding: too many forwards"
msgstr ""
#
-# File: ../common/channels.c, line: 2335
+# File: ../common/channels.c, line: 2371
+msgid "Binding address too long."
+msgstr ""
+#
+# File: ../common/channels.c, line: 2420
#, c-format
msgid "Protocol error for port forward request:received packet type %d."
msgstr ""
#
-# File: ../common/channels.c, line: 2372
+# File: ../common/channels.c, line: 2493
#, c-format
msgid "Requested forwarding of port %d but user is not root."
msgstr ""
#
-# File: ../common/channels.c, line: 2435
+# File: ../common/channels.c, line: 2521
+msgid "channel_add_permitted_opens: too many forwards"
+msgstr ""
+#
+# File: ../common/channels.c, line: 2556
#, c-format
msgid "connect_to %.100s: unknown host (%s)"
msgstr ""
#
-# File: ../common/channels.c, line: 2444
+# File: ../common/channels.c, line: 2565
msgid "connect_to: getnameinfo failed"
msgstr ""
#
-# File: ../common/channels.c, line: 2453
+# File: ../common/channels.c, line: 2574
#, c-format
msgid "connect_to: F_SETFL: %s"
msgstr ""
#
-# File: ../common/channels.c, line: 2456
+# File: ../common/channels.c, line: 2577
#, c-format
msgid "connect_to %.100s port %s: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2466
+# File: ../common/channels.c, line: 2587
#, c-format
msgid "connect_to %.100s port %d: failed."
msgstr ""
#
-# File: ../common/channels.c, line: 2484
+# File: ../common/channels.c, line: 2605
#, c-format
msgid "WARNING: Server requests forwarding for unknown listen_port %d"
msgstr ""
#
-# File: ../common/channels.c, line: 2540
+# File: ../common/channels.c, line: 2661
#, c-format
msgid "getaddrinfo: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2561
+# File: ../common/channels.c, line: 2682
#, c-format
msgid "setsockopt IPV6_V6ONLY: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2588
+# File: ../common/channels.c, line: 2709
msgid "Failed to allocate internet-domain X11 display socket."
msgstr ""
#
-# File: ../common/channels.c, line: 2631
+# File: ../common/channels.c, line: 2752
#, c-format
msgid "connect %.100s: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2648
+# File: ../common/channels.c, line: 2769
msgid "DISPLAY not set."
msgstr ""
#
-# File: ../common/channels.c, line: 2666
-# File: ../common/channels.c, line: 2692
+# File: ../common/channels.c, line: 2787
+# File: ../common/channels.c, line: 2813
#, c-format
msgid "Could not parse display number from DISPLAY: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2686
+# File: ../common/channels.c, line: 2807
#, c-format
msgid "Could not find ':' in DISPLAY: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2703
+# File: ../common/channels.c, line: 2824
#, c-format
msgid "%.100s: unknown host. (%s)"
msgstr ""
#
-# File: ../common/channels.c, line: 2725
+# File: ../common/channels.c, line: 2846
#, c-format
msgid "connect %.100s port %d: %.100s"
msgstr ""
#
-# File: ../common/channels.c, line: 2789
-# File: clientloop.c, line: 1401
+# File: ../common/channels.c, line: 2910
+# File: clientloop.c, line: 1437
msgid "Warning: ssh server tried agent forwarding."
msgstr ""
#
-# File: ../common/channels.c, line: 2792
-# File: clientloop.c, line: 1367
+# File: ../common/channels.c, line: 2913
+# File: clientloop.c, line: 1403
msgid "Warning: ssh server tried X11 forwarding."
msgstr ""
#
-# File: ../common/channels.c, line: 2795
+# File: ../common/channels.c, line: 2916
#, c-format
msgid "deny_input_open: type %d"
msgstr ""
#
-# File: ../common/channels.c, line: 2798
-# File: clientloop.c, line: 1368
-# File: clientloop.c, line: 1402
+# File: ../common/channels.c, line: 2919
+# File: clientloop.c, line: 1404
+# File: clientloop.c, line: 1438
msgid ""
"Warning: this is probably a break in attempt by a malicious server."
msgstr ""
#
-# File: ../common/channels.c, line: 2843
+# File: ../common/channels.c, line: 2964
#, c-format
msgid "x11_request_forwarding: bad authentication data: %.100s"
msgstr ""
@@ -766,7 +779,7 @@ msgstr ""
msgid "ssh_aes_ctr_iv: no context"
msgstr ""
#
-# File: ../common/compat.c, line: 247
+# File: ../common/compat.c, line: 253
msgid "No available ciphers found."
msgstr ""
#
@@ -1373,25 +1386,25 @@ msgstr ""
msgid "setsockopt TCP_NODELAY: %.100s"
msgstr ""
#
-# File: ../common/misc.c, line: 365
+# File: ../common/misc.c, line: 408
msgid "replacearg: argument too long"
msgstr ""
#
-# File: ../common/misc.c, line: 368
+# File: ../common/misc.c, line: 411
#, c-format
msgid "replacearg: tried to replace invalid arg %d >= %d"
msgstr ""
#
-# File: ../common/misc.c, line: 549
-# File: ../common/readconf.c, line: 467
-# File: ../common/readconf.c, line: 488
-# File: ../common/readconf.c, line: 548
-# File: ../common/readconf.c, line: 568
-# File: ../common/readconf.c, line: 580
-# File: ../common/readconf.c, line: 591
-# File: ../common/readconf.c, line: 602
-# File: ../common/readconf.c, line: 614
-# File: ../common/readconf.c, line: 696
+# File: ../common/misc.c, line: 592
+# File: ../common/readconf.c, line: 497
+# File: ../common/readconf.c, line: 518
+# File: ../common/readconf.c, line: 578
+# File: ../common/readconf.c, line: 598
+# File: ../common/readconf.c, line: 610
+# File: ../common/readconf.c, line: 621
+# File: ../common/readconf.c, line: 632
+# File: ../common/readconf.c, line: 644
+# File: ../common/readconf.c, line: 726
#, c-format
msgid "%.200s line %d: Missing argument."
msgstr ""
@@ -2019,146 +2032,148 @@ msgstr ""
msgid "Too many local forwards (max %d)."
msgstr ""
#
-# File: ../common/readconf.c, line: 237
+# File: ../common/readconf.c, line: 239
#, c-format
msgid "Too many remote forwards (max %d)."
msgstr ""
#
-# File: ../common/readconf.c, line: 272
-# File: servconf.c, line: 482
+# File: ../common/readconf.c, line: 318
#, c-format
-msgid "%s: line %d: Bad configuration option: %s"
+msgid "we can't have more than %d unknown options:"
+msgstr ""
+#
+# File: ../common/readconf.c, line: 322
+#, c-format
+msgid "%s:%d:%s"
msgstr ""
#
-# File: ../common/readconf.c, line: 314
+# File: ../common/readconf.c, line: 327
+msgid "too many unknown options found, can't continue"
+msgstr ""
+#
+# File: ../common/readconf.c, line: 344
# File: servconf.c, line: 587
#, c-format
msgid "%s line %d: missing time value."
msgstr ""
#
-# File: ../common/readconf.c, line: 317
+# File: ../common/readconf.c, line: 347
# File: servconf.c, line: 590
#, c-format
msgid "%s line %d: invalid time value."
msgstr ""
#
-# File: ../common/readconf.c, line: 328
+# File: ../common/readconf.c, line: 358
#, c-format
msgid "%.200s line %d: Missing yes/no argument."
msgstr ""
#
-# File: ../common/readconf.c, line: 335
+# File: ../common/readconf.c, line: 365
#, c-format
msgid "%.200s line %d: Bad yes/no argument."
msgstr ""
#
-# File: ../common/readconf.c, line: 429
+# File: ../common/readconf.c, line: 459
#, c-format
msgid "%.200s line %d: Missing yes/no/ask argument."
msgstr ""
#
-# File: ../common/readconf.c, line: 439
+# File: ../common/readconf.c, line: 469
#, c-format
msgid "%.200s line %d: Bad yes/no/ask argument."
msgstr ""
#
-# File: ../common/readconf.c, line: 471
+# File: ../common/readconf.c, line: 501
#, c-format
msgid "%.200s line %d: Too many identity files specified (max %d)."
msgstr ""
#
-# File: ../common/readconf.c, line: 550
-# File: ../common/readconf.c, line: 555
+# File: ../common/readconf.c, line: 580
+# File: ../common/readconf.c, line: 585
#, c-format
msgid "%.200s line %d: Bad number."
msgstr ""
#
-# File: ../common/readconf.c, line: 571
+# File: ../common/readconf.c, line: 601
#, c-format
msgid "%.200s line %d: Bad cipher '%s'."
msgstr ""
#
-# File: ../common/readconf.c, line: 582
+# File: ../common/readconf.c, line: 612
#, c-format
msgid "%.200s line %d: Bad SSH2 cipher spec '%s'."
msgstr ""
#
-# File: ../common/readconf.c, line: 593
+# File: ../common/readconf.c, line: 623
#, c-format
msgid "%.200s line %d: Bad SSH2 Mac spec '%s'."
msgstr ""
#
-# File: ../common/readconf.c, line: 604
+# File: ../common/readconf.c, line: 634
#, c-format
msgid "%.200s line %d: Bad protocol 2 host key algorithms '%s'."
msgstr ""
#
-# File: ../common/readconf.c, line: 617
+# File: ../common/readconf.c, line: 647
#, c-format
msgid "%.200s line %d: Bad protocol spec '%s'."
msgstr ""
#
-# File: ../common/readconf.c, line: 628
-# File: servconf.c, line: 826
+# File: ../common/readconf.c, line: 658
+# File: servconf.c, line: 835
#, c-format
msgid "%.200s line %d: unsupported log level '%s'"
msgstr ""
#
-# File: ../common/readconf.c, line: 638
-# File: ../common/readconf.c, line: 667
+# File: ../common/readconf.c, line: 668
+# File: ../common/readconf.c, line: 693
#, c-format
msgid "%.200s line %d: Missing port argument."
msgstr ""
#
-# File: ../common/readconf.c, line: 641
+# File: ../common/readconf.c, line: 672
#, c-format
-msgid "%.200s line %d: Bad listen port."
+msgid "%.200s line %d: Missing target argument."
msgstr ""
#
-# File: ../common/readconf.c, line: 645
-#, c-format
-msgid "%.200s line %d: Missing second argument."
-msgstr ""
-#
-# File: ../common/readconf.c, line: 649
+# File: ../common/readconf.c, line: 679
#, c-format
msgid "%.200s line %d: Bad forwarding specification."
msgstr ""
#
-# File: ../common/readconf.c, line: 652
-#, c-format
-msgid "%.200s line %d: Bad forwarding port."
-msgstr ""
-#
-# File: ../common/readconf.c, line: 671
+# File: ../common/readconf.c, line: 697
#, c-format
-msgid "%.200s line %d: Badly formatted port number."
+msgid "%.200s line %d: Bad dynamic forwarding specification."
msgstr ""
#
-# File: ../common/readconf.c, line: 705
+# File: ../common/readconf.c, line: 735
#, c-format
msgid "%.200s line %d: Bad escape character."
msgstr ""
#
-# File: ../common/readconf.c, line: 735
+# File: ../common/readconf.c, line: 765
#, c-format
msgid "%.200s line %d: Bad yes/no/in-exec-mode argument."
msgstr ""
#
-# File: ../common/readconf.c, line: 745
+# File: ../common/readconf.c, line: 779
#, c-format
msgid "process_config_line: Unimplemented opcode %d"
msgstr ""
#
-# File: ../common/readconf.c, line: 750
+# File: ../common/readconf.c, line: 784
#, c-format
msgid "%.200s line %d: garbage at end of line; \"%.200s\"."
msgstr ""
#
-# File: ../common/readconf.c, line: 794
-# File: servconf.c, line: 1035
+# File: ../common/readconf.c, line: 1155
#, c-format
-msgid "%s: terminating, %d bad configuration options"
+msgid "%s: line %d: unknown configuration option: %s"
+msgstr ""
+#
+# File: ../common/readconf.c, line: 1165
+#, c-format
+msgid "terminating, %d bad configuration option(s)"
msgstr ""
#
# File: ../common/sftp-common.c, line: 164
@@ -2247,143 +2262,147 @@ msgid ""
" -b addr Local IP address.\n"
msgstr ""
#
-# File: ssh.c, line: 269
+# File: ssh.c, line: 268
#, c-format
msgid "setrlimit failed: %.100s"
msgstr ""
#
-# File: ssh.c, line: 275
+# File: ssh.c, line: 274
msgid "You don't exist, go away!"
msgstr ""
#
-# File: ssh.c, line: 329
+# File: ssh.c, line: 328
msgid "Warning: Option -P has been deprecated\n"
msgstr ""
#
-# File: ssh.c, line: 343
+# File: ssh.c, line: 342
#, c-format
msgid "Warning: Identity file %s does not exist.\n"
msgstr ""
#
-# File: ssh.c, line: 349
+# File: ssh.c, line: 348
#, c-format
msgid "Too many identity files specified (max %d)"
msgstr ""
#
# File: ssh-keyscan.c, line: 725
-# File: ssh.c, line: 372
+# File: ssh.c, line: 371
msgid "Too high debugging level."
msgstr ""
#
-# File: ssh.c, line: 376
+# File: ssh.c, line: 375
#, c-format
msgid "%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n"
msgstr ""
#
-# File: ssh.c, line: 399
+# File: ssh.c, line: 398
#, c-format
msgid "Bad escape character '%s'.\n"
msgstr ""
#
-# File: ssh.c, line: 414
+# File: ssh.c, line: 413
#, c-format
msgid "Unknown cipher type '%s'\n"
msgstr ""
#
-# File: ssh.c, line: 432
+# File: ssh.c, line: 431
#, c-format
msgid "Unknown mac type '%s'\n"
msgstr ""
#
# File: ssh-keyscan.c, line: 704
-# File: ssh.c, line: 440
+# File: ssh.c, line: 439
#, c-format
msgid "Bad port '%s'\n"
msgstr ""
#
-# File: ssh.c, line: 456
+# File: ssh.c, line: 452
#, c-format
-msgid "Bad forwarding specification '%s'\n"
+msgid "Bad local forwarding specification '%s'\n"
msgstr ""
#
-# File: ssh.c, line: 465
+# File: ssh.c, line: 460
#, c-format
-msgid "Bad forwarding port(s) '%s'\n"
+msgid "Bad remote forwarding specification '%s'\n"
msgstr ""
#
-# File: ssh.c, line: 481
+# File: ssh.c, line: 466
#, c-format
-msgid "Bad dynamic port '%s'\n"
+msgid "Bad dynamic forwarding specification '%s'\n"
msgstr ""
#
-# File: ssh.c, line: 562
+# File: ssh.c, line: 546
msgid "You must specify a subsystem to invoke.\n"
msgstr ""
#
-# File: ssh.c, line: 577
+# File: ssh.c, line: 561
msgid "Cannot fork into background without a command to execute."
msgstr ""
#
-# File: ssh.c, line: 589
+# File: ssh.c, line: 573
msgid ""
"Pseudo-terminal will not be allocated because stdin is not a terminal."
msgstr ""
#
-# File: ssh.c, line: 608
+# File: ssh.c, line: 592
#, c-format
msgid "Can't open user config file %.100s: %.100s"
msgstr ""
#
+# File: ssh.c, line: 634
# File: ssh.c, line: 648
-# File: ssh.c, line: 662
msgid "rsh_connect returned"
msgstr ""
#
-# File: ssh.c, line: 724
+# File: ssh.c, line: 710
#, c-format
msgid "Could not create directory '%.200s'."
msgstr ""
#
-# File: ssh.c, line: 801
+# File: ssh.c, line: 792
msgid "Could not request local forwarding."
msgstr ""
#
-# File: ssh.c, line: 841
+# File: ssh.c, line: 808
+msgid "Warning: Could not request remote forwarding."
+msgstr ""
+#
+# File: ssh.c, line: 838
msgid "Compression level must be from 1 (fast) to 9 (slow, best)."
msgstr ""
#
-# File: ssh.c, line: 852
+# File: ssh.c, line: 849
msgid "Warning: Remote host refused compression."
msgstr ""
#
-# File: ssh.c, line: 854
+# File: ssh.c, line: 851
msgid "Protocol error waiting for compression response."
msgstr ""
#
-# File: ssh.c, line: 892
+# File: ssh.c, line: 889
msgid "Warning: Remote host failed or refused to allocate a pseudo tty."
msgstr ""
#
-# File: ssh.c, line: 894
+# File: ssh.c, line: 891
msgid "Protocol error waiting for pty request response."
msgstr ""
#
-# File: ssh.c, line: 912
+# File: ssh.c, line: 909
msgid "Warning: Remote host denied X11 forwarding."
msgstr ""
#
-# File: ssh.c, line: 914
+# File: ssh.c, line: 911
msgid "Protocol error waiting for X11 forwarding"
msgstr ""
#
-# File: clientloop.c, line: 1292
-# File: clientloop.c, line: 1302
-# File: clientloop.c, line: 1311
+# File: clientloop.c, line: 1328
# File: clientloop.c, line: 1338
-# File: clientloop.c, line: 1378
-# File: clientloop.c, line: 1493
-# File: ssh.c, line: 929
-# File: ssh.c, line: 977
+# File: clientloop.c, line: 1347
+# File: clientloop.c, line: 1374
+# File: clientloop.c, line: 1414
+# File: clientloop.c, line: 1529
+# File: ssh.c, line: 926
+# File: ssh.c, line: 974
# File: sshconnect1.c, line: 122
# File: sshconnect1.c, line: 260
# File: sshconnect1.c, line: 377
@@ -2401,32 +2420,32 @@ msgstr ""
msgid "Packet integrity error (%d bytes remaining) at %s:%d"
msgstr ""
#
-# File: ssh.c, line: 931
+# File: ssh.c, line: 928
msgid "Warning: Remote host denied authentication agent forwarding."
msgstr ""
#
-# File: ssh.c, line: 940
-# File: ssh.c, line: 1162
+# File: ssh.c, line: 937
+# File: ssh.c, line: 1159
# File: sshd.c, line: 1284
#, c-format
msgid "daemon() failed: %.200s"
msgstr ""
#
-# File: ssh.c, line: 979
+# File: ssh.c, line: 976
#, c-format
msgid "Request for subsystem '%.*s' failed on channel %d"
msgstr ""
#
-# File: ssh.c, line: 997
+# File: ssh.c, line: 994
#, c-format
msgid "Warning: remote port forwarding failed for listen port %d"
msgstr ""
#
-# File: ssh.c, line: 1118
+# File: ssh.c, line: 1115
msgid "dup() in/out/err failed"
msgstr ""
#
-# File: ssh.c, line: 1198
+# File: ssh.c, line: 1195
msgid "Using rsh. WARNING: Connection will not be encrypted."
msgstr ""
#
@@ -3000,57 +3019,81 @@ msgstr ""
msgid "Read from remote host %.300s: %.100s\r\n"
msgstr ""
#
-# File: clientloop.c, line: 667
+# File: clientloop.c, line: 672
+msgid "Commands:"
+msgstr ""
+#
+# File: clientloop.c, line: 673
+msgid ""
+" -L[bind_address:]port:host:hostport Request local forward"
+msgstr ""
+#
+# File: clientloop.c, line: 675
+msgid ""
+" -R[bind_address:]port:host:hostport Request remote forward"
+msgstr ""
+#
+# File: clientloop.c, line: 677
+msgid ""
+" -KR[bind_address:]port Cancel remote forward"
+msgstr ""
+#
+# File: clientloop.c, line: 687
# File: sftp.c, line: 894
msgid "Invalid command."
msgstr ""
#
-# File: clientloop.c, line: 673
+# File: clientloop.c, line: 693
+msgid "Not supported."
+msgstr ""
+#
+# File: clientloop.c, line: 697
msgid "Not supported for SSH protocol version 1."
msgstr ""
#
-# File: clientloop.c, line: 684
-msgid "Bad forwarding specification."
+# File: clientloop.c, line: 706
+msgid "Bad forwarding close port"
msgstr ""
#
-# File: clientloop.c, line: 689
-msgid "Bad forwarding port(s)."
+# File: clientloop.c, line: 712
+msgid "Bad forwarding specification."
msgstr ""
#
-# File: clientloop.c, line: 695
+# File: clientloop.c, line: 719
+# File: clientloop.c, line: 726
msgid "Port forwarding failed."
msgstr ""
#
-# File: clientloop.c, line: 701
+# File: clientloop.c, line: 731
msgid "Forwarding port."
msgstr ""
#
-# File: clientloop.c, line: 743
+# File: clientloop.c, line: 779
#, c-format
msgid "%c^Z [suspend ssh]\r\n"
msgstr ""
#
-# File: clientloop.c, line: 756
+# File: clientloop.c, line: 792
#, c-format
msgid "%cB [sent break]\r\n"
msgstr ""
#
-# File: clientloop.c, line: 770
+# File: clientloop.c, line: 806
msgid "Server does not support re-keying"
msgstr ""
#
-# File: clientloop.c, line: 789
+# File: clientloop.c, line: 825
#, c-format
msgid "%c& [backgrounded]\n"
msgstr ""
#
-# File: clientloop.c, line: 796
+# File: clientloop.c, line: 832
# File: sshd.c, line: 1580
#, c-format
msgid "fork: %.100s"
msgstr ""
#
-# File: clientloop.c, line: 829
+# File: clientloop.c, line: 865
#, c-format
msgid ""
"%c?\r\n"
@@ -3067,40 +3110,40 @@ msgid ""
"(Note that escapes are only recognized immediately after newline.)\r\n"
msgstr ""
#
-# File: clientloop.c, line: 1021
+# File: clientloop.c, line: 1057
#, c-format
msgid "client_channel_closed: id %d != session_ident %d"
msgstr ""
#
-# File: clientloop.c, line: 1226
+# File: clientloop.c, line: 1262
#, c-format
msgid "Killed by signal %d."
msgstr ""
#
-# File: clientloop.c, line: 1236
+# File: clientloop.c, line: 1272
#, c-format
msgid "Connection to %.64s closed.\r\n"
msgstr ""
#
-# File: clientloop.c, line: 1246
+# File: clientloop.c, line: 1282
msgid "Write failed flushing stdout buffer."
msgstr ""
#
-# File: clientloop.c, line: 1258
+# File: clientloop.c, line: 1294
msgid "Write failed flushing stderr buffer."
msgstr ""
#
-# File: clientloop.c, line: 1482
+# File: clientloop.c, line: 1518
#, c-format
msgid "client_input_channel_req: no channel %d"
msgstr ""
#
-# File: clientloop.c, line: 1484
+# File: clientloop.c, line: 1520
#, c-format
msgid "client_input_channel_req: channel %d: wrong channel: %d"
msgstr ""
#
-# File: clientloop.c, line: 1489
+# File: clientloop.c, line: 1525
#, c-format
msgid "client_input_channel_req: channel %d: unknown channel"
msgstr ""
@@ -3894,6 +3937,11 @@ msgstr ""
msgid "mm_memvalid: address too large: %p"
msgstr ""
#
+# File: servconf.c, line: 482
+#, c-format
+msgid "%s: line %d: Bad configuration option: %s"
+msgstr ""
+#
# File: servconf.c, line: 514
#, c-format
msgid "bad addr or host: %s (%s)"
@@ -3983,94 +4031,104 @@ msgstr ""
msgid "%s line %d: Bad yes/no argument: %s"
msgstr ""
#
-# File: servconf.c, line: 815
+# File: servconf.c, line: 811
+#, c-format
+msgid "%.200s line %d: Bad yes/no/clientspecified argument."
+msgstr ""
+#
+# File: servconf.c, line: 824
#, c-format
msgid "%.200s line %d: unsupported log facility '%s'"
msgstr ""
#
-# File: servconf.c, line: 843
+# File: servconf.c, line: 852
#, c-format
msgid "%s line %d: too many allow users."
msgstr ""
#
-# File: servconf.c, line: 853
+# File: servconf.c, line: 862
#, c-format
msgid "%s line %d: too many deny users."
msgstr ""
#
-# File: servconf.c, line: 863
+# File: servconf.c, line: 872
#, c-format
msgid "%s line %d: too many allow groups."
msgstr ""
#
-# File: servconf.c, line: 873
+# File: servconf.c, line: 882
#, c-format
msgid "%s line %d: too many deny groups."
msgstr ""
#
-# File: servconf.c, line: 882
-# File: servconf.c, line: 893
-# File: servconf.c, line: 905
+# File: servconf.c, line: 891
+# File: servconf.c, line: 902
+# File: servconf.c, line: 914
#, c-format
msgid "%s line %d: Missing argument."
msgstr ""
#
-# File: servconf.c, line: 884
+# File: servconf.c, line: 893
#, c-format
msgid "%s line %d: Bad SSH2 cipher spec '%s'."
msgstr ""
#
-# File: servconf.c, line: 895
+# File: servconf.c, line: 904
#, c-format
msgid "%s line %d: Bad SSH2 mac spec '%s'."
msgstr ""
#
-# File: servconf.c, line: 908
+# File: servconf.c, line: 917
#, c-format
msgid "%s line %d: Bad protocol spec '%s'."
msgstr ""
#
-# File: servconf.c, line: 916
+# File: servconf.c, line: 925
#, c-format
msgid "%s line %d: too many subsystems defined."
msgstr ""
#
-# File: servconf.c, line: 921
+# File: servconf.c, line: 930
#, c-format
msgid "%s line %d: Missing subsystem name."
msgstr ""
#
-# File: servconf.c, line: 925
+# File: servconf.c, line: 934
#, c-format
msgid "%s line %d: Subsystem '%s' already defined."
msgstr ""
#
-# File: servconf.c, line: 930
+# File: servconf.c, line: 939
#, c-format
msgid "%s line %d: Missing subsystem command."
msgstr ""
#
-# File: servconf.c, line: 939
+# File: servconf.c, line: 948
#, c-format
msgid "%s line %d: Missing MaxStartups spec."
msgstr ""
#
-# File: servconf.c, line: 949
-# File: servconf.c, line: 952
+# File: servconf.c, line: 958
+# File: servconf.c, line: 961
#, c-format
msgid "%s line %d: Illegal MaxStartups spec."
msgstr ""
#
-# File: servconf.c, line: 1003
+# File: servconf.c, line: 1012
#, c-format
msgid "%s line %d: Missing handler for opcode %s (%d)"
msgstr ""
#
-# File: servconf.c, line: 1007
+# File: servconf.c, line: 1016
#, c-format
msgid "%s line %d: garbage at end of line; \"%.200s\"."
msgstr ""
#
+# File: servconf.c, line: 1044
+#, c-format
+msgid "%s: terminating, %d bad configuration options"
+msgstr ""
+#
# File: serverloop.c, line: 118
#, c-format
msgid "pipe(notify_pipe) failed %s"
@@ -4128,7 +4186,7 @@ msgstr ""
msgid "Server has disabled port forwarding."
msgstr ""
#
-# File: serverloop.c, line: 1227
+# File: serverloop.c, line: 1239
#, c-format
msgid "server_input_channel_req: unknown channel %d"
msgstr ""
@@ -4833,6 +4891,7 @@ msgstr ""
msgid "line %d: invalid hashed name: %.64s..."
msgstr ""
#
+# File: ssh-keygen.c, line: 645
# File: ssh-keygen.c, line: 659
#, c-format
msgid "# Host %s found: line %d type %s\n"
diff --git a/usr/src/cmd/ssh/ssh/clientloop.c b/usr/src/cmd/ssh/ssh/clientloop.c
index 5979b6bac6..6485414a57 100644
--- a/usr/src/cmd/ssh/ssh/clientloop.c
+++ b/usr/src/cmd/ssh/ssh/clientloop.c
@@ -111,7 +111,7 @@ extern char *host;
static volatile sig_atomic_t received_window_change_signal = 0;
static volatile sig_atomic_t received_signal = 0;
-/* Flag indicating whether the user\'s terminal is in non-blocking mode. */
+/* Flag indicating whether the user's terminal is in non-blocking mode. */
static int in_non_blocking_mode = 0;
/* Common data for the client loop code. */
@@ -630,60 +630,96 @@ 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];
+ int delete = 0;
int local = 0;
+ Forward fwd;
+
+ memset(&fwd, 0, sizeof(fwd));
leave_raw_mode();
handler = signal(SIGINT, SIG_IGN);
cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
if (s == NULL)
goto out;
- while (*s && isspace(*s))
+ while (isspace(*s))
s++;
- if (*s == 0)
+ if (*s == '-')
+ s++; /* Skip cmdline '-', if any */
+ if (*s == '\0')
goto out;
- if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
- log("Invalid command.");
+
+ if (*s == 'h' || *s == 'H' || *s == '?') {
+ log("Commands:");
+ log(" -L[bind_address:]port:host:hostport "
+ "Request local forward");
+ log(" -R[bind_address:]port:host:hostport "
+ "Request remote forward");
+ log(" -KR[bind_address:]port "
+ "Cancel remote forward");
goto out;
}
- if (s[1] == 'L')
- local = 1;
- if (!local && !compat20) {
- log("Not supported for SSH protocol version 1.");
+
+ if (*s == 'K') {
+ delete = 1;
+ s++;
+ }
+ if (*s != 'L' && *s != 'R') {
+ log("Invalid command.");
goto out;
}
- s += 2;
- while (*s && isspace(*s))
- s++;
-
- 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) {
- log("Bad forwarding specification.");
+ if (*s == 'L')
+ local = 1;
+ if (local && delete) {
+ log("Not supported.");
goto out;
}
- if ((fwd_port = a2port(sfwd_port)) == 0 ||
- (fwd_host_port = a2port(sfwd_host_port)) == 0) {
- log("Bad forwarding port(s).");
+ if ((!local || delete) && !compat20) {
+ log("Not supported for SSH protocol version 1.");
goto out;
}
- if (local) {
- if (channel_setup_local_fwd_listener(fwd_port, buf,
- fwd_host_port, options.gateway_ports) < 0) {
- log("Port forwarding failed.");
+
+ while (isspace(*++s))
+ ;
+
+ if (delete) {
+ if (parse_forward(0, &fwd, s) == 0) {
+ log("Bad forwarding close port");
+ goto out;
+ }
+ channel_request_rforward_cancel(fwd.listen_host, fwd.listen_port);
+ } else {
+ if (parse_forward(1, &fwd, s) == 0) {
+ log("Bad forwarding specification.");
goto out;
}
- } else
- channel_request_remote_forwarding(fwd_port, buf,
- fwd_host_port);
- log("Forwarding port.");
+ if (local) {
+ if (channel_setup_local_fwd_listener(fwd.listen_host,
+ fwd.listen_port, fwd.connect_host,
+ fwd.connect_port, options.gateway_ports) < 0) {
+ log("Port forwarding failed.");
+ goto out;
+ }
+ } else {
+ if (channel_request_remote_forwarding(fwd.listen_host,
+ fwd.listen_port, fwd.connect_host,
+ fwd.connect_port) < 0) {
+ log("Port forwarding failed.");
+ goto out;
+ }
+ }
+
+ log("Forwarding port.");
+ }
+
out:
signal(SIGINT, handler);
enter_raw_mode();
- if (cmd)
+ if (cmd != NULL)
xfree(cmd);
+ if (fwd.listen_host != NULL)
+ xfree(fwd.listen_host);
+ if (fwd.connect_host != NULL)
+ xfree(fwd.connect_host);
}
/* process the characters one by one */
diff --git a/usr/src/cmd/ssh/ssh/ssh.c b/usr/src/cmd/ssh/ssh/ssh.c
index fe1623fa00..e88bbb9941 100644
--- a/usr/src/cmd/ssh/ssh/ssh.c
+++ b/usr/src/cmd/ssh/ssh/ssh.c
@@ -233,14 +233,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, buf[256];
struct stat st;
struct passwd *pw;
int dummy;
extern int optind, optreset;
extern char *optarg;
+ Forward fwd;
__progname = get_progname(av[0]);
@@ -457,42 +456,27 @@ again:
break;
case 'L':
+ if (parse_forward(1, &fwd, optarg))
+ add_local_forward(&options, &fwd);
+ else
+ fatal("Bad local forwarding specification "
+ "'%s'\n", optarg);
+ break;
+
case 'R':
- if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]",
- sfwd_port, buf, sfwd_host_port) != 3 &&
- sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]",
- sfwd_port, buf, sfwd_host_port) != 3) {
- fprintf(stderr,
- gettext("Bad forwarding "
- "specification '%s'\n"),
- optarg);
- usage();
- /* NOTREACHED */
- }
- if ((fwd_port = a2port(sfwd_port)) == 0 ||
- (fwd_host_port = a2port(sfwd_host_port)) == 0) {
- fprintf(stderr,
- gettext("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);
+ if (parse_forward(1, &fwd, optarg))
+ add_remote_forward(&options, &fwd);
+ else
+ fatal("Bad remote forwarding specification "
+ "'%s'\n", optarg);
break;
case 'D':
- fwd_port = a2port(optarg);
- if (fwd_port == 0) {
- fprintf(stderr,
- gettext("Bad dynamic port '%s'\n"),
- optarg);
- exit(1);
- }
- add_local_forward(&options, fwd_port, "socks4", 0);
+ if (parse_forward(0, &fwd, optarg) == 0)
+ fatal("Bad dynamic forwarding specification "
+ "'%s'\n", optarg);
+ fwd.connect_host = "socks";
+ add_local_forward(&options, &fwd);
break;
case 'C':
@@ -797,14 +781,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)
@@ -812,14 +801,20 @@ 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);
- channel_request_remote_forwarding(
- 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 == NULL) ?
+ "LOCALHOST" : options.remote_forwards[i].listen_host,
+ options.remote_forwards[i].listen_port,
+ options.remote_forwards[i].connect_host,
+ options.remote_forwards[i].connect_port);
+ if (channel_request_remote_forwarding(
+ options.remote_forwards[i].listen_host,
+ options.remote_forwards[i].listen_port,
+ options.remote_forwards[i].connect_host,
+ options.remote_forwards[i].connect_port) < 0) {
+ log("Warning: Could not request remote forwarding.");
+ }
}
}
@@ -827,7 +822,7 @@ static void
check_agent_present(void)
{
if (options.forward_agent) {
- /* Clear agent forwarding if we don\'t have an agent. */
+ /* Clear agent forwarding if we don't have an agent. */
if (!ssh_agent_present())
options.forward_agent = 0;
}
@@ -998,12 +993,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)
log("Warning: remote port forwarding failed for listen port %d",
- options.remote_forwards[i].port);
+ options.remote_forwards[i].listen_port);
}
static
diff --git a/usr/src/cmd/ssh/sshd/servconf.c b/usr/src/cmd/ssh/sshd/servconf.c
index 346940e22d..863a75af74 100644
--- a/usr/src/cmd/ssh/sshd/servconf.c
+++ b/usr/src/cmd/ssh/sshd/servconf.c
@@ -9,7 +9,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -896,8 +896,17 @@ parse_flag:
goto parse_flag;
case sGatewayPorts:
- intptr = &options->gateway_ports;
- goto parse_flag;
+ arg = strdelim(&cp);
+ if (get_yes_no_flag(&options->gateway_ports, arg, filename,
+ linenum, 1) == 1)
+ break;
+
+ if (strcmp(arg, "clientspecified") == 0)
+ options->gateway_ports = 2;
+ else
+ fatal("%.200s line %d: Bad yes/no/clientspecified "
+ "argument.", filename, linenum);
+ break;
case sVerifyReverseMapping:
intptr = &options->verify_reverse_mapping;
diff --git a/usr/src/cmd/ssh/sshd/serverloop.c b/usr/src/cmd/ssh/sshd/serverloop.c
index 1d081caa76..a720fae405 100644
--- a/usr/src/cmd/ssh/sshd/serverloop.c
+++ b/usr/src/cmd/ssh/sshd/serverloop.c
@@ -34,7 +34,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1179,8 +1179,19 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
listen_address, listen_port, options.gateway_ports);
}
xfree(listen_address);
+ } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
+ char *cancel_address;
+ u_short cancel_port;
+
+ cancel_address = packet_get_string(NULL);
+ cancel_port = (u_short)packet_get_int();
+ debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
+ cancel_address, cancel_port);
+
+ success = channel_cancel_rport_listener(cancel_address,
+ cancel_port);
+ xfree(cancel_address);
}
-
if (want_reply) {
packet_start(success ?
SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
@@ -1189,6 +1200,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
}
xfree(rtype);
}
+
static void
server_input_channel_req(int type, u_int32_t seq, void *ctxt)
{