Bugzilla – Attachment 1372 Details for
Bug 993
adding and removing forwardings via the control connection
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Support for adding port-forwards from slaves
clientpf.patch2 (text/plain), 9.74 KB, created by
Martin Forssen
on 2007-10-31 09:01:27 AEDT
(
hide
)
Description:
Support for adding port-forwards from slaves
Filename:
MIME Type:
Creator:
Martin Forssen
Created:
2007-10-31 09:01:27 AEDT
Size:
9.74 KB
patch
obsolete
>Index: clientloop.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/clientloop.c,v >retrieving revision 1.182 >diff -u -r1.182 clientloop.c >--- clientloop.c 4 Sep 2007 03:21:03 -0000 1.182 >+++ clientloop.c 30 Oct 2007 08:22:12 -0000 >@@ -169,6 +169,7 @@ > extern Kex *xxx_kex; > > void ssh_process_session2_setup(int, int, int, Buffer *); >+static void client_process_control_forward(int client_fd, Buffer m); > > /* Restores stdin to blocking mode. */ > >@@ -765,8 +766,6 @@ > command = buffer_get_int(&m); > flags = buffer_get_int(&m); > >- buffer_clear(&m); >- > switch (command) { > case SSHMUX_COMMAND_OPEN: > if (options.control_master == SSHCTL_MASTER_ASK || >@@ -797,6 +796,11 @@ > buffer_free(&m); > close(client_fd); > return; >+ case SSHMUX_COMMAND_FORWARD: >+ client_process_control_forward(client_fd, m); >+ buffer_free(&m); >+ close(client_fd); >+ return; > default: > error("Unsupported command %d", command); > buffer_free(&m); >@@ -933,6 +937,65 @@ > > channel_send_open(c->self); > channel_register_confirm(c->self, client_extra_session2_setup, cctx); >+} >+ >+static void >+client_process_control_forward(int client_fd, Buffer m) >+{ >+ int local, gateway_ports, success; >+ char *listen_host, *connect_host; >+ u_short listen_port, connect_port; >+ >+ local = buffer_get_char(&m); >+ listen_host = buffer_get_string(&m, NULL); >+ listen_port = buffer_get_short(&m); >+ connect_host = buffer_get_string(&m, NULL); >+ connect_port = buffer_get_short(&m); >+ gateway_ports = buffer_get_char(&m); >+ >+ if ((options.control_master == SSHCTL_MASTER_ASK || >+ options.control_master == SSHCTL_MASTER_AUTO_ASK) >+ && !ask_permission("Allow %s forward %s:%d -> %s:%d", >+ (local ? "local" : "remote"), >+ (gateway_ports ? "*" : >+ (listen_host ? listen_host : "LOCALHOST")), >+ listen_port, connect_host, connect_port)) { >+ success = 0; >+ goto send_reply; >+ } >+ >+ if (local) { >+ success = channel_setup_local_fwd_listener(listen_host, >+ listen_port, connect_host, connect_port, gateway_ports); >+ debug("Local connections to %.200s:%d forwarded to remote " >+ "address %.200s:%d", >+ (*listen_host == '\0') ? >+ (gateway_ports ? "*" : "LOCALHOST") : listen_host, >+ listen_port, connect_host, connect_port); >+ } else { >+ if (channel_request_remote_forwarding(listen_host, listen_port, >+ connect_host, connect_port) < 0) { >+ success = 0; >+ } else { >+ success = 1; >+ } >+ debug("Remote connections from %.200s:%d forwarded to " >+ "local address %.200s:%d", >+ (*listen_host == '\0') ? "LOCALHOST" : listen_host, >+ listen_port, connect_host, connect_port); >+ } >+ >+ if (!success) { >+ error("Could not request %s forwarding.", >+ (local ? "local" : "remote")); >+ } >+ >+send_reply: >+ buffer_clear(&m); >+ buffer_put_int(&m, 1); >+ buffer_put_int(&m, success); >+ if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) >+ error("%s: client msg_send failed", __func__); > } > > static void >Index: clientloop.h >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/clientloop.h,v >retrieving revision 1.17 >diff -u -r1.17 clientloop.h >--- clientloop.h 7 Aug 2007 07:32:53 -0000 1.17 >+++ clientloop.h 30 Oct 2007 08:22:12 -0000 >@@ -47,12 +47,13 @@ > int client_request_tun_fwd(int, int, int); > > /* Multiplexing protocol version */ >-#define SSHMUX_VER 1 >+#define SSHMUX_VER 2 > > /* Multiplexing control protocol flags */ > #define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ > #define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ > #define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */ >+#define SSHMUX_COMMAND_FORWARD 4 /* Open port forward */ > > #define SSHMUX_FLAG_TTY (1) /* Request tty on open */ > #define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ >Index: ssh.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/ssh.c,v >retrieving revision 1.305 >diff -u -r1.305 ssh.c >--- ssh.c 29 Oct 2007 06:54:50 -0000 1.305 >+++ ssh.c 30 Oct 2007 08:22:13 -0000 >@@ -191,6 +191,13 @@ > static int ssh_session2(void); > static void load_public_identity_files(void); > static void control_client(const char *path); >+static int control_client_connect(const char *path); >+static int control_client_get_reply(int sock); >+static int control_client_request_forward(const char *path, int local, >+ const char *listen_host, >+ u_short listen_port, >+ const char *connect_host, >+ u_short connect_port); > > /* > * Main program for the ssh client. >@@ -1293,14 +1300,16 @@ > static void > control_client(const char *path) > { >- struct sockaddr_un addr; > int i, r, fd, sock, exitval[2], num_env; > Buffer m; > char *term; > extern char **environ; > u_int flags; > >- if (mux_command == 0) >+ if (mux_command == 0 && no_shell_flag && >+ (options.num_local_forwards || options.num_remote_forwards)) { >+ mux_command = SSHMUX_COMMAND_FORWARD; >+ } else if (mux_command == 0) > mux_command = SSHMUX_COMMAND_OPEN; > > switch (options.control_master) { >@@ -1314,33 +1323,32 @@ > return; > } > >- memset(&addr, '\0', sizeof(addr)); >- addr.sun_family = AF_UNIX; >- addr.sun_len = offsetof(struct sockaddr_un, sun_path) + >- strlen(path) + 1; >- >- if (strlcpy(addr.sun_path, path, >- sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) >- fatal("ControlPath too long"); >- >- if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) >- fatal("%s socket(): %s", __func__, strerror(errno)); >- >- if (connect(sock, (struct sockaddr *)&addr, addr.sun_len) == -1) { >- if (mux_command != SSHMUX_COMMAND_OPEN) { >- fatal("Control socket connect(%.100s): %s", path, >- strerror(errno)); >+ /* Open requested forwards */ >+ if (options.num_local_forwards || options.num_remote_forwards) { >+ for (i=0; i<options.num_local_forwards; i++) { >+ if (control_client_request_forward(path, 1, >+ options.local_forwards[i].listen_host, >+ options.local_forwards[i].listen_port, >+ options.local_forwards[i].connect_host, >+ options.local_forwards[i].connect_port)) >+ goto fail; > } >- if (errno == ENOENT) >- debug("Control socket \"%.100s\" does not exist", path); >- else { >- error("Control socket connect(%.100s): %s", path, >- strerror(errno)); >+ for (i=0; i<options.num_remote_forwards; i++) { >+ if (control_client_request_forward(path, 0, >+ options.remote_forwards[i].listen_host, >+ options.remote_forwards[i].listen_port, >+ options.remote_forwards[i].connect_host, >+ options.remote_forwards[i].connect_port)) >+ goto fail; > } >- close(sock); >- return; > } > >+ if (mux_command == SSHMUX_COMMAND_FORWARD) >+ exit(0); >+ >+ if ((sock = control_client_connect(path)) == -1) >+ goto fail; >+ > if (stdin_null_flag) { > if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) > fatal("open(/dev/null): %s", strerror(errno)); >@@ -1372,15 +1380,7 @@ > buffer_clear(&m); > > /* Get authorisation status and PID of controlee */ >- if (ssh_msg_recv(sock, &m) == -1) >- fatal("%s: msg_recv", __func__); >- if (buffer_get_char(&m) != SSHMUX_VER) >- fatal("%s: wrong version", __func__); >- if (buffer_get_int(&m) != 1) >- fatal("Connection to master denied"); >- control_server_pid = buffer_get_int(&m); >- >- buffer_clear(&m); >+ control_server_pid = control_client_get_reply(sock); > > switch (mux_command) { > case SSHMUX_COMMAND_ALIVE_CHECK: >@@ -1484,4 +1484,98 @@ > fprintf(stderr, "Shared connection to %s closed.\r\n", host); > > exit(exitval[0]); >+ >+ fail: >+ if (mux_command != SSHMUX_COMMAND_OPEN) { >+ fatal("Control socket connect(%.100s): %s", path, >+ strerror(errno)); >+ } >+ if (errno == ENOENT) >+ debug("Control socket \"%.100s\" does not exist", path); >+ else { >+ error("Control socket connect(%.100s): %s", path, >+ strerror(errno)); >+ } >+} >+ >+static int >+control_client_connect(const char *path) >+{ >+ struct sockaddr_un addr; >+ int sock; >+ >+ debug3("Connect to master"); >+ memset(&addr, '\0', sizeof(addr)); >+ addr.sun_family = AF_UNIX; >+ addr.sun_len = offsetof(struct sockaddr_un, sun_path) + >+ strlen(path) + 1; >+ >+ if (strlcpy(addr.sun_path, path, sizeof(addr.sun_path)) >+ >= sizeof(addr.sun_path)) >+ fatal("ControlPath too long"); >+ >+ if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) >+ fatal("%s socket(): %s", __func__, strerror(errno)); >+ >+ if (connect(sock, (struct sockaddr *)&addr, addr.sun_len) == -1) { >+ close(sock); >+ return -1; >+ } >+ return sock; >+} >+ >+static int >+control_client_get_reply(int sock) >+{ >+ Buffer m; >+ int r; >+ >+ buffer_init(&m); >+ if (ssh_msg_recv(sock, &m) == -1) >+ fatal("%s: msg_recv", __func__); >+ if (buffer_get_char(&m) != SSHMUX_VER) >+ fatal("%s: wrong version", __func__); >+ if (buffer_get_int(&m) != 1) >+ fatal("Connection to master denied"); >+ r = buffer_get_int(&m); >+ buffer_clear(&m); >+ return r; >+} >+ >+static int >+control_client_request_forward(const char *path, int local, >+ const char *listen_host, u_short listen_port, >+ const char *connect_host, u_short connect_port) >+{ >+ Buffer m; >+ int sock; >+ >+ if ((sock = control_client_connect(path)) == -1) >+ return 1; >+ >+ /* Send our command to server */ >+ buffer_init(&m); >+ buffer_put_int(&m, SSHMUX_COMMAND_FORWARD); >+ buffer_put_int(&m, 0); >+ buffer_put_char(&m, local); >+ buffer_put_cstring(&m, listen_host ? listen_host : ""); >+ buffer_put_short(&m, listen_port); >+ buffer_put_cstring(&m, connect_host); >+ buffer_put_short(&m, connect_port); >+ buffer_put_char(&m, options.gateway_ports); >+ if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) >+ fatal("%s: msg_send", __func__); >+ buffer_clear(&m); >+ >+ if (!control_client_get_reply(sock)) >+ fatal("Master denied our forward request to %s:%d", >+ connect_host, connect_port); >+ close(sock); >+ >+ debug("Local connections to %.200s:%d forwarded to remote " >+ "address %.200s:%d", >+ (listen_host == NULL) ? >+ (options.gateway_ports ? "*" : "LOCALHOST") : >+ listen_host, listen_port, connect_host, connect_port); >+ return 0; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 993
:
847
| 1372