diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 82 |
1 files changed, 46 insertions, 36 deletions
diff --git a/clientloop.c b/clientloop.c index 4bc5b57d2..0180774bb 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.258 2014/02/02 03:44:31 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.261 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -100,13 +100,13 @@ | |||
100 | #include "cipher.h" | 100 | #include "cipher.h" |
101 | #include "kex.h" | 101 | #include "kex.h" |
102 | #include "log.h" | 102 | #include "log.h" |
103 | #include "misc.h" | ||
103 | #include "readconf.h" | 104 | #include "readconf.h" |
104 | #include "clientloop.h" | 105 | #include "clientloop.h" |
105 | #include "sshconnect.h" | 106 | #include "sshconnect.h" |
106 | #include "authfd.h" | 107 | #include "authfd.h" |
107 | #include "atomicio.h" | 108 | #include "atomicio.h" |
108 | #include "sshpty.h" | 109 | #include "sshpty.h" |
109 | #include "misc.h" | ||
110 | #include "match.h" | 110 | #include "match.h" |
111 | #include "msg.h" | 111 | #include "msg.h" |
112 | #include "roaming.h" | 112 | #include "roaming.h" |
@@ -880,13 +880,11 @@ static void | |||
880 | process_cmdline(void) | 880 | process_cmdline(void) |
881 | { | 881 | { |
882 | void (*handler)(int); | 882 | void (*handler)(int); |
883 | char *s, *cmd, *cancel_host; | 883 | char *s, *cmd; |
884 | int delete = 0, local = 0, remote = 0, dynamic = 0; | 884 | int ok, delete = 0, local = 0, remote = 0, dynamic = 0; |
885 | int cancel_port, ok; | 885 | struct Forward fwd; |
886 | Forward fwd; | ||
887 | 886 | ||
888 | memset(&fwd, 0, sizeof(fwd)); | 887 | memset(&fwd, 0, sizeof(fwd)); |
889 | fwd.listen_host = fwd.connect_host = NULL; | ||
890 | 888 | ||
891 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 889 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
892 | handler = signal(SIGINT, SIG_IGN); | 890 | handler = signal(SIGINT, SIG_IGN); |
@@ -952,29 +950,20 @@ process_cmdline(void) | |||
952 | 950 | ||
953 | /* XXX update list of forwards in options */ | 951 | /* XXX update list of forwards in options */ |
954 | if (delete) { | 952 | if (delete) { |
955 | cancel_port = 0; | 953 | /* We pass 1 for dynamicfwd to restrict to 1 or 2 fields. */ |
956 | cancel_host = hpdelim(&s); /* may be NULL */ | 954 | if (!parse_forward(&fwd, s, 1, 0)) { |
957 | if (s != NULL) { | 955 | logit("Bad forwarding close specification."); |
958 | cancel_port = a2port(s); | ||
959 | cancel_host = cleanhostname(cancel_host); | ||
960 | } else { | ||
961 | cancel_port = a2port(cancel_host); | ||
962 | cancel_host = NULL; | ||
963 | } | ||
964 | if (cancel_port <= 0) { | ||
965 | logit("Bad forwarding close port"); | ||
966 | goto out; | 956 | goto out; |
967 | } | 957 | } |
968 | if (remote) | 958 | if (remote) |
969 | ok = channel_request_rforward_cancel(cancel_host, | 959 | ok = channel_request_rforward_cancel(&fwd) == 0; |
970 | cancel_port) == 0; | ||
971 | else if (dynamic) | 960 | else if (dynamic) |
972 | ok = channel_cancel_lport_listener(cancel_host, | 961 | ok = channel_cancel_lport_listener(&fwd, |
973 | cancel_port, 0, options.gateway_ports) > 0; | 962 | 0, &options.fwd_opts) > 0; |
974 | else | 963 | else |
975 | ok = channel_cancel_lport_listener(cancel_host, | 964 | ok = channel_cancel_lport_listener(&fwd, |
976 | cancel_port, CHANNEL_CANCEL_PORT_STATIC, | 965 | CHANNEL_CANCEL_PORT_STATIC, |
977 | options.gateway_ports) > 0; | 966 | &options.fwd_opts) > 0; |
978 | if (!ok) { | 967 | if (!ok) { |
979 | logit("Unkown port forwarding."); | 968 | logit("Unkown port forwarding."); |
980 | goto out; | 969 | goto out; |
@@ -986,16 +975,13 @@ process_cmdline(void) | |||
986 | goto out; | 975 | goto out; |
987 | } | 976 | } |
988 | if (local || dynamic) { | 977 | if (local || dynamic) { |
989 | if (!channel_setup_local_fwd_listener(fwd.listen_host, | 978 | if (!channel_setup_local_fwd_listener(&fwd, |
990 | fwd.listen_port, fwd.connect_host, | 979 | &options.fwd_opts)) { |
991 | fwd.connect_port, options.gateway_ports)) { | ||
992 | logit("Port forwarding failed."); | 980 | logit("Port forwarding failed."); |
993 | goto out; | 981 | goto out; |
994 | } | 982 | } |
995 | } else { | 983 | } else { |
996 | if (channel_request_remote_forwarding(fwd.listen_host, | 984 | if (channel_request_remote_forwarding(&fwd) < 0) { |
997 | fwd.listen_port, fwd.connect_host, | ||
998 | fwd.connect_port) < 0) { | ||
999 | logit("Port forwarding failed."); | 985 | logit("Port forwarding failed."); |
1000 | goto out; | 986 | goto out; |
1001 | } | 987 | } |
@@ -1008,7 +994,9 @@ out: | |||
1008 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 994 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
1009 | free(cmd); | 995 | free(cmd); |
1010 | free(fwd.listen_host); | 996 | free(fwd.listen_host); |
997 | free(fwd.listen_path); | ||
1011 | free(fwd.connect_host); | 998 | free(fwd.connect_host); |
999 | free(fwd.connect_path); | ||
1012 | } | 1000 | } |
1013 | 1001 | ||
1014 | /* reasons to suppress output of an escape command in help output */ | 1002 | /* reasons to suppress output of an escape command in help output */ |
@@ -1865,11 +1853,10 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) | |||
1865 | originator_port = packet_get_int(); | 1853 | originator_port = packet_get_int(); |
1866 | packet_check_eom(); | 1854 | packet_check_eom(); |
1867 | 1855 | ||
1868 | debug("client_request_forwarded_tcpip: listen %s port %d, " | 1856 | debug("%s: listen %s port %d, originator %s port %d", __func__, |
1869 | "originator %s port %d", listen_address, listen_port, | 1857 | listen_address, listen_port, originator_address, originator_port); |
1870 | originator_address, originator_port); | ||
1871 | 1858 | ||
1872 | c = channel_connect_by_listen_address(listen_port, | 1859 | c = channel_connect_by_listen_address(listen_address, listen_port, |
1873 | "forwarded-tcpip", originator_address); | 1860 | "forwarded-tcpip", originator_address); |
1874 | 1861 | ||
1875 | free(originator_address); | 1862 | free(originator_address); |
@@ -1878,6 +1865,27 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) | |||
1878 | } | 1865 | } |
1879 | 1866 | ||
1880 | static Channel * | 1867 | static Channel * |
1868 | client_request_forwarded_streamlocal(const char *request_type, int rchan) | ||
1869 | { | ||
1870 | Channel *c = NULL; | ||
1871 | char *listen_path; | ||
1872 | |||
1873 | /* Get the remote path. */ | ||
1874 | listen_path = packet_get_string(NULL); | ||
1875 | /* XXX: Skip reserved field for now. */ | ||
1876 | if (packet_get_string_ptr(NULL) == NULL) | ||
1877 | fatal("%s: packet_get_string_ptr failed", __func__); | ||
1878 | packet_check_eom(); | ||
1879 | |||
1880 | debug("%s: %s", __func__, listen_path); | ||
1881 | |||
1882 | c = channel_connect_by_listen_path(listen_path, | ||
1883 | "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); | ||
1884 | free(listen_path); | ||
1885 | return c; | ||
1886 | } | ||
1887 | |||
1888 | static Channel * | ||
1881 | client_request_x11(const char *request_type, int rchan) | 1889 | client_request_x11(const char *request_type, int rchan) |
1882 | { | 1890 | { |
1883 | Channel *c = NULL; | 1891 | Channel *c = NULL; |
@@ -2004,6 +2012,8 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt) | |||
2004 | 2012 | ||
2005 | if (strcmp(ctype, "forwarded-tcpip") == 0) { | 2013 | if (strcmp(ctype, "forwarded-tcpip") == 0) { |
2006 | c = client_request_forwarded_tcpip(ctype, rchan); | 2014 | c = client_request_forwarded_tcpip(ctype, rchan); |
2015 | } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { | ||
2016 | c = client_request_forwarded_streamlocal(ctype, rchan); | ||
2007 | } else if (strcmp(ctype, "x11") == 0) { | 2017 | } else if (strcmp(ctype, "x11") == 0) { |
2008 | c = client_request_x11(ctype, rchan); | 2018 | c = client_request_x11(ctype, rchan); |
2009 | } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { | 2019 | } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { |
@@ -2074,7 +2084,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) | |||
2074 | } | 2084 | } |
2075 | packet_check_eom(); | 2085 | packet_check_eom(); |
2076 | } | 2086 | } |
2077 | if (reply && c != NULL) { | 2087 | if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) { |
2078 | packet_start(success ? | 2088 | packet_start(success ? |
2079 | SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); | 2089 | SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); |
2080 | packet_put_int(c->remote_id); | 2090 | packet_put_int(c->remote_id); |