diff options
author | Hans Nilsson <hans@erlang.org> | 2019-08-15 12:51:54 +0200 |
---|---|---|
committer | Hans Nilsson <hans@erlang.org> | 2019-09-20 10:31:47 +0200 |
commit | 33b9ea4ca66f63adae4679ae6351c121a588d4dd (patch) | |
tree | 6aa8e775a6b3f8e74680e52622b0c71aa4065e82 | |
parent | 0bb391db6e31d5c2672a865cfae4b7051e1cc88c (diff) | |
download | erlang-33b9ea4ca66f63adae4679ae6351c121a588d4dd.tar.gz |
ssh: direct-tcpip, server part
Added handling of SSH_MSG_CHANNEL_OPEN(diret-tcpip) and a new
boolean option tcpip_tunnel_in with default false.
-rw-r--r-- | lib/ssh/doc/src/ssh.xml | 10 | ||||
-rw-r--r-- | lib/ssh/src/ssh.hrl | 2 | ||||
-rw-r--r-- | lib/ssh/src/ssh_connection.erl | 61 | ||||
-rw-r--r-- | lib/ssh/src/ssh_options.erl | 6 |
4 files changed, 79 insertions, 0 deletions
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml index 7f5be7b17d..2314474c36 100644 --- a/lib/ssh/doc/src/ssh.xml +++ b/lib/ssh/doc/src/ssh.xml @@ -694,6 +694,16 @@ </datatype> <datatype> + <name name="tcpip_tunnel_in_daemon_option"/> + <desc> + <p>Enables (<c>true</c>) or disables (<c>false</c>) the possibility to tunnel a TCP/IP connection in to a + <seealso marker="ssh:ssh#daemon-2">server</seealso>. + Disabled per default. + </p> + </desc> + </datatype> + + <datatype> <name name="tcpip_tunnel_out_daemon_option"/> <desc> <p>Enables (<c>true</c>) or disables (<c>false</c>) the possibility to tunnel a TCP/IP connection out of a diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl index 301e0d91e5..7afa6fcd16 100644 --- a/lib/ssh/src/ssh.hrl +++ b/lib/ssh/src/ssh.hrl @@ -303,6 +303,7 @@ | exec_daemon_option() | ssh_cli_daemon_option() | tcpip_tunnel_out_daemon_option() + | tcpip_tunnel_in_daemon_option() | authentication_daemon_options() | diffie_hellman_group_exchange_daemon_option() | negotiation_timeout_daemon_option() @@ -331,6 +332,7 @@ -type ssh_cli_daemon_option() :: {ssh_cli, mod_args() | no_cli }. -type tcpip_tunnel_out_daemon_option() :: {tcpip_tunnel_out, boolean()} . +-type tcpip_tunnel_in_daemon_option() :: {tcpip_tunnel_in, boolean()} . -type send_ext_info_daemon_option() :: {send_ext_info, boolean()} . diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index 0caf5cd819..318e0ca35d 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -583,6 +583,67 @@ handle_msg(#ssh_msg_channel_open{channel_type = "session" = Type, {[{connection_reply, FailMsg}], Connection0} end; +handle_msg(#ssh_msg_channel_open{channel_type = "direct-tcpip", + sender_channel = RemoteId, + initial_window_size = WindowSize, + maximum_packet_size = PacketSize, + data = <<?DEC_BIN(HostToConnect,_L1), ?UINT32(PortToConnect), + ?DEC_BIN(_OriginatorIPaddress,_L2), ?UINT32(_OrignatorPort) + >> + }, + #connection{channel_cache = Cache, + channel_id_seed = ChId, + options = Options, + sub_system_supervisor = SubSysSup + } = C, + server) -> + + {ReplyMsg, NextChId} = + case ?GET_OPT(tcpip_tunnel_in, Options) of + %% May add more to the option, like allowed ip/port pairs to connect to + false -> + {channel_open_failure_msg(RemoteId, + ?SSH_OPEN_CONNECT_FAILED, + "Forwarding disabled", "en"), + ChId}; + + true -> + case gen_tcp:connect(binary_to_list(HostToConnect), PortToConnect, + [{active,false}, binary]) of + {ok,Sock} -> + {ok,Pid} = ssh_subsystem_sup:start_channel(server, SubSysSup, self(), + ssh_tcpip_forward_srv, ChId, + [Sock], undefined, Options), + ssh_client_channel:cache_update(Cache, + #channel{type = "direct-tcpip", + sys = "none", + local_id = ChId, + remote_id = RemoteId, + user = Pid, + recv_window_size = ?DEFAULT_WINDOW_SIZE, + recv_packet_size = ?DEFAULT_PACKET_SIZE, + send_window_size = WindowSize, + send_packet_size = PacketSize, + send_buf = queue:new() + }), + gen_tcp:controlling_process(Sock, Pid), + ssh_tcpip_forward_srv:use_socket(Pid, Sock), + + {channel_open_confirmation_msg(RemoteId, ChId, + ?DEFAULT_WINDOW_SIZE, + ?DEFAULT_PACKET_SIZE), + ChId + 1}; + + {error,Error} -> + {channel_open_failure_msg(RemoteId, + ?SSH_OPEN_CONNECT_FAILED, + io_lib:format("Forwarded connection refused: ~p",[Error]), + "en"), + ChId} + end + end, + {[{connection_reply, ReplyMsg}], C#connection{channel_id_seed = NextChId}}; + handle_msg(#ssh_msg_channel_open{channel_type = "session", sender_channel = RemoteId}, Connection, diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl index 7a2bb95298..505f248720 100644 --- a/lib/ssh/src/ssh_options.erl +++ b/lib/ssh/src/ssh_options.erl @@ -335,6 +335,12 @@ default(server) -> class => user_option }, + tcpip_tunnel_in => + #{default => false, + chk => fun erlang:is_boolean/1, + class => user_option + }, + system_dir => #{default => "/etc/ssh", chk => fun(V) -> check_string(V) andalso check_dir(V) end, |