From b22a68377d3026572e7859f712674b319767eb7e Mon Sep 17 00:00:00 2001 From: Louis-Philippe Gauthier Date: Thu, 20 Jun 2013 01:48:31 -0400 Subject: Add openssh_zlib compression type to ssh_transport http://www.openssh.org/txt/draft-miller-secsh-compression-delayed-00.txt --- lib/ssh/src/ssh.hrl | 3 ++- lib/ssh/src/ssh_connection_handler.erl | 4 ++-- lib/ssh/src/ssh_transport.erl | 37 ++++++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl index da5750b6c3..4fd347ba8f 100644 --- a/lib/ssh/src/ssh.hrl +++ b/lib/ssh/src/ssh.hrl @@ -127,7 +127,8 @@ userauth_supported_methods , % userauth_methods, userauth_preference, - available_host_keys + available_host_keys, + authenticated = false }). -record(alg, diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index 1c4477aeb3..d2792727db 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -426,10 +426,10 @@ userauth(#ssh_msg_userauth_info_response{} = Msg, language = "en"}, State) end; -userauth(#ssh_msg_userauth_success{}, #state{ssh_params = #ssh{role = client}, +userauth(#ssh_msg_userauth_success{}, #state{ssh_params = #ssh{role = client} = Ssh, manager = Pid} = State) -> Pid ! ssh_connected, - {next_state, connected, next_packet(State)}; + {next_state, connected, next_packet(State#state{ssh_params = Ssh#ssh{authenticated = true}})}; userauth(#ssh_msg_userauth_failure{}, #state{ssh_params = #ssh{role = client, diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl index beaffdc025..682d766d99 100644 --- a/lib/ssh/src/ssh_transport.erl +++ b/lib/ssh/src/ssh_transport.erl @@ -206,6 +206,7 @@ key_exchange_init_msg(Ssh0) -> kex_init(#ssh{role = Role, opts = Opts, available_host_keys = HostKeyAlgs}) -> Random = ssh_bits:random(16), Compression = case proplists:get_value(compression, Opts, none) of + openssh_zlib -> ["zlib@openssh.com", "none"]; zlib -> ["zlib", "none"]; none -> ["none", "zlib"] end, @@ -855,33 +856,47 @@ decrypt(#ssh{decrypt = 'aes128-cbc', decrypt_keys = Key, IV = crypto:next_iv(aes_cbc, Data), {Ssh#ssh{decrypt_ctx = IV}, Dec}. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Compression %% -%% none REQUIRED no compression -%% zlib OPTIONAL ZLIB (LZ77) compression +%% none REQUIRED no compression +%% zlib OPTIONAL ZLIB (LZ77) compression +%% openssh_zlib OPTIONAL ZLIB (LZ77) compression %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + compress_init(SSH) -> compress_init(SSH, 1). compress_init(#ssh{compress = none} = Ssh, _) -> {ok, Ssh}; compress_init(#ssh{compress = zlib} = Ssh, Level) -> + Zlib = zlib:open(), + ok = zlib:deflateInit(Zlib, Level), + {ok, Ssh#ssh{compress_ctx = Zlib}}; +compress_init(#ssh{compress = 'zlib@openssh.com'} = Ssh, Level) -> Zlib = zlib:open(), ok = zlib:deflateInit(Zlib, Level), {ok, Ssh#ssh{compress_ctx = Zlib}}. - compress_final(#ssh{compress = none} = Ssh) -> {ok, Ssh}; compress_final(#ssh{compress = zlib, compress_ctx = Context} = Ssh) -> + zlib:close(Context), + {ok, Ssh#ssh{compress = none, compress_ctx = undefined}}; +compress_final(#ssh{compress = 'zlib@openssh.com', authenticated = false} = Ssh) -> + {ok, Ssh}; +compress_final(#ssh{compress = 'zlib@openssh.com', compress_ctx = Context, authenticated = true} = Ssh) -> zlib:close(Context), {ok, Ssh#ssh{compress = none, compress_ctx = undefined}}. compress(#ssh{compress = none} = Ssh, Data) -> {Ssh, Data}; compress(#ssh{compress = zlib, compress_ctx = Context} = Ssh, Data) -> + Compressed = zlib:deflate(Context, Data, sync), + {Ssh, list_to_binary(Compressed)}; +compress(#ssh{compress = 'zlib@openssh.com', authenticated = false} = Ssh, Data) -> + {Ssh, Data}; +compress(#ssh{compress = 'zlib@openssh.com', compress_ctx = Context, authenticated = true} = Ssh, Data) -> Compressed = zlib:deflate(Context, Data, sync), {Ssh, list_to_binary(Compressed)}. @@ -892,6 +907,10 @@ compress(#ssh{compress = zlib, compress_ctx = Context} = Ssh, Data) -> decompress_init(#ssh{decompress = none} = Ssh) -> {ok, Ssh}; decompress_init(#ssh{decompress = zlib} = Ssh) -> + Zlib = zlib:open(), + ok = zlib:inflateInit(Zlib), + {ok, Ssh#ssh{decompress_ctx = Zlib}}; +decompress_init(#ssh{decompress = 'zlib@openssh.com'} = Ssh) -> Zlib = zlib:open(), ok = zlib:inflateInit(Zlib), {ok, Ssh#ssh{decompress_ctx = Zlib}}. @@ -899,12 +918,22 @@ decompress_init(#ssh{decompress = zlib} = Ssh) -> decompress_final(#ssh{decompress = none} = Ssh) -> {ok, Ssh}; decompress_final(#ssh{decompress = zlib, decompress_ctx = Context} = Ssh) -> + zlib:close(Context), + {ok, Ssh#ssh{decompress = none, decompress_ctx = undefined}}; +decompress_final(#ssh{decompress = 'zlib@openssh.com', authenticated = false} = Ssh) -> + {ok, Ssh}; +decompress_final(#ssh{decompress = 'zlib@openssh.com', decompress_ctx = Context, authenticated = true} = Ssh) -> zlib:close(Context), {ok, Ssh#ssh{decompress = none, decompress_ctx = undefined}}. decompress(#ssh{decompress = none} = Ssh, Data) -> {Ssh, Data}; decompress(#ssh{decompress = zlib, decompress_ctx = Context} = Ssh, Data) -> + Decompressed = zlib:inflate(Context, Data), + {Ssh, list_to_binary(Decompressed)}; +decompress(#ssh{decompress = 'zlib@openssh.com', authenticated = false} = Ssh, Data) -> + {Ssh, Data}; +decompress(#ssh{decompress = 'zlib@openssh.com', decompress_ctx = Context, authenticated = true} = Ssh, Data) -> Decompressed = zlib:inflate(Context, Data), {Ssh, list_to_binary(Decompressed)}. -- cgit v1.2.1