Experimental -R support patch for openssh client
Jarno Huuskonen
jhuuskon at messi.uku.fi
Wed Aug 16 02:55:11 EST 2000
Hi !
Here's an experimental patch for openssh-2.1.1p4 to add support
(to openssh client) for -R (protocol 2).
So if you have access to a commercial ssh2 server (that allows port
forwardings) could you test this patch.
(Note the openssh server doesn't have support for -R with protocol 2 so
testing with openssh server won't do much good).
To test remember to use -o "Protocol 2".
This is my first go at implementing -R support so expect a few glitches.
Thanks,
-Jarno
--
Jarno Huuskonen - System Administrator | Jarno.Huuskonen at uku.fi
University of Kuopio - Computer Center | Work: +358 17 162822
PO BOX 1627, 70211 Kuopio, Finland | Mobile: +358 40 5388169
-------------- next part --------------
diff -u -r openssh-2.1.1p4/channels.c openssh-2.1.1p4-jhchanges/channels.c
--- openssh-2.1.1p4/channels.c Mon Jun 26 03:22:53 2000
+++ openssh-2.1.1p4-jhchanges/channels.c Tue Aug 15 19:10:49 2000
@@ -1506,38 +1509,139 @@
u_short port_to_connect)
{
int payload_len;
+ int type;
+ int success = 0;
+
/* Record locally that connection to this host/port is permitted. */
if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
fatal("channel_request_remote_forwarding: too many forwards");
- permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
- permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
- permitted_opens[num_permitted_opens].listen_port = listen_port;
- num_permitted_opens++;
-
/* Send the forward request to the remote side. */
if (compat20) {
const char *address_to_bind = "0.0.0.0";
packet_start(SSH2_MSG_GLOBAL_REQUEST);
packet_put_cstring("tcpip-forward");
- packet_put_char(0); /* boolean: want reply */
+ /* Ask for reply so we know to expect 'forwarded-tcpip' messages */
+ packet_put_char(1); /* Boolean 1 asks for reply */
packet_put_cstring(address_to_bind);
packet_put_int(listen_port);
- } else {
+ packet_send();
+ packet_write_wait();
+
+ type = packet_read(&payload_len); /* Expect reply from server */
+ switch (type) {
+ case SSH2_MSG_REQUEST_SUCCESS:
+ success = 1;
+ break;
+ case SSH2_MSG_REQUEST_FAILURE:
+ log("Warning: Server doesn't do port forwarding.");
+ break;
+ default:
+ /* Unknown packet */
+ packet_disconnect("Protocol error for port forward request: received packet type %d.", type);
+ }
+
+ }
+ else {
+ /* Protocol 1 */
packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
packet_put_int(listen_port);
packet_put_cstring(host_to_connect);
packet_put_int(port_to_connect);
packet_send();
packet_write_wait();
- /*
- * Wait for response from the remote side. It will send a disconnect
- * message on failure, and we will never see it here.
+
+ /* Jarno: Server can send SSH_SMSG_FAILURE if it won't do port
+ * forwardings. Read the server reply.
*/
- packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
+ type = packet_read(&payload_len); /* Expect reply from server */
+ switch (type) {
+ case SSH_SMSG_SUCCESS:
+ success = 1;
+ break;
+ case SSH_SMSG_FAILURE:
+ log("Warning: Server doesn't do port forwarding.");
+ break;
+ default:
+ /* Unknown packet */
+ packet_disconnect("Protocol error for port forward request: received packet type %d.", type);
+ }
+ }
+
+ if ( success ) {
+ debug("Server acknowledged our remote port forward request");
+ permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
+ permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
+ permitted_opens[num_permitted_opens].listen_port = listen_port;
+ num_permitted_opens++;
}
}
+/* Jarno Huuskonen:
+ * ssh2
+ * This called after client has received SSH2_MSG_GLOBAL_REQUEST/
+ * "forwarded-tcpip".
+ * Checks if creating the channel is ok. And connects to required host.
+ * returns new channel if OK or NULL for failure.
+ */
+Channel*
+client_forwarded_tcpip_request(const char *request_type, int rchan,
+ int rwindow, int rmaxpack)
+{
+ Channel* c = NULL;
+ int sock;
+ char *connected_address; /* Remote address that is listening for the
+ connection */
+ int connected_port; /* Remote port connected */
+
+ char* client_address; /* Client that connected to connected_address */
+ int client_port; /* Client port */
+
+ unsigned int client_len, connected_len;
+
+ int newch;
+ int i;
+
+ debug("ssh2 server tries to open forwarded-tcpip channel.");
+
+ /* Get rest of the packet */
+ connected_address = packet_get_string(&connected_len);
+ connected_port = packet_get_int();
+ client_address = packet_get_string(&client_len);
+ client_port = packet_get_int();
+ packet_done();
+
+ /* Check if we have requested this remote forwarding */
+ for (i = 0; i<num_permitted_opens; i++) {
+ if ( permitted_opens[i].listen_port == connected_port ) {
+ break;
+ }
+ }
+
+ /* We haven't requested the connection to be forwarded ! */
+ if ( i >= num_permitted_opens ) {
+ log("Received request to open remote forwarded channel (%d) but the request was denied", rchan);
+ return NULL;
+ }
+
+ /* TODO: call somekind of forward allowed function to check if connection
+ * is allowed.
+ */
+ /* int allowed = allow_forwarded_tcpip( .... ); */
+
+ /* Open socket */
+ sock = channel_connect_to(permitted_opens[i].host_to_connect,
+ permitted_opens[i].port_to_connect);
+
+ if ( sock >= 0 ) {
+ newch = channel_new("forwarded-tcpip", SSH_CHANNEL_OPEN,
+ sock, sock, -1, 4*1024, 32*1024, 0,
+ xstrdup(client_address));
+ c = channel_lookup( newch );
+ }
+ return c;
+}
+
/*
* This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
* listening for the port, and sends back a success reply (or disconnect
diff -u -r openssh-2.1.1p4/channels.h openssh-2.1.1p4-jhchanges/channels.h
--- openssh-2.1.1p4/channels.h Thu Jun 22 14:32:31 2000
+++ openssh-2.1.1p4-jhchanges/channels.h Tue Aug 15 19:03:17 2000
@@ -163,6 +163,12 @@
channel_request_remote_forwarding(u_short port, const char *host,
u_short remote_port);
+/* Jarno: Copy comment from source
+ */
+Channel *
+client_forwarded_tcpip_request(const char *request_type, int rchan,
+ int rwindow, int rmaxpack);
+
/*
* Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually
* called by the server, because the user could connect to any port anyway,
diff -u -r openssh-2.1.1p4/clientloop.c openssh-2.1.1p4-jhchanges/clientloop.c
--- openssh-2.1.1p4/clientloop.c Sat Jul 15 07:14:17 2000
+++ openssh-2.1.1p4-jhchanges/clientloop.c Tue Aug 15 19:16:15 2000
@@ -974,6 +974,16 @@
debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
ctype, rchan, rwindow, rmaxpack);
+ /* Jarno: Check if ssh2 server tries to open remote forward channel */
+ if (strcmp(ctype, "forwarded-tcpip") == 0) {
+ c = client_forwarded_tcpip_request( ctype, rchan, rwindow, rmaxpack );
+ }
+
+ /* if (strcmp(ctype, "x11") == 0) {
+ c = client_forwarded_x11_request( ctype, rchan, rwindow, rmaxpack );
+ }
+ */
+
if (strcmp(ctype, "x11") == 0) {
int sock;
char *originator;
@@ -1015,7 +1025,7 @@
packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(rchan);
packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
- packet_put_cstring("bla bla");
+ packet_put_cstring("bla bla"); /* TODO: Shouldn't we send a reason ?*/
packet_put_cstring("");
packet_send();
}
diff -u -r openssh-2.1.1p4/ssh.c openssh-2.1.1p4-jhchanges/ssh.c
--- openssh-2.1.1p4/ssh.c Sat Jul 15 07:14:17 2000
+++ openssh-2.1.1p4-jhchanges/ssh.c Mon Aug 14 20:04:53 2000
@@ -891,6 +891,22 @@
}
}
+/* Jarno: ssh2_session calls this */
+void
+init_remote_fwd(void)
+{
+ int i;
+ 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);
+ }
+}
+
extern void client_set_session_ident(int id);
void
@@ -963,7 +979,9 @@
/* should be pre-session */
init_local_fwd();
-
+ /* Jarno */
+ init_remote_fwd();
+
window = 32*1024;
if (tty_flag) {
packetmax = window/8;
More information about the openssh-unix-dev
mailing list