aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src/ssh_message.erl
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2017-04-10 16:25:06 +0200
committerHans Nilsson <[email protected]>2017-04-26 12:13:01 +0200
commit29d7533c715f972ee996382c2c45cc0c055e10d2 (patch)
treeb370920e82c28335cb601d997920d41ea6cd76cd /lib/ssh/src/ssh_message.erl
parentc0d2e134f90ddd3fd2f5b0f9a94a5b0d55c93416 (diff)
downloadotp-29d7533c715f972ee996382c2c45cc0c055e10d2.tar.gz
otp-29d7533c715f972ee996382c2c45cc0c055e10d2.tar.bz2
otp-29d7533c715f972ee996382c2c45cc0c055e10d2.zip
ssh: Implement ext-info extension. draft-ietf-curdle-ssh-ext-info
This is only a draft extension, but it is quite stable and already supported by some implementations. OpenSSH has had it for some year now.
Diffstat (limited to 'lib/ssh/src/ssh_message.erl')
-rw-r--r--lib/ssh/src/ssh_message.erl33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index 562f040477..56f678876c 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -215,6 +215,16 @@ encode(#ssh_msg_service_accept{
}) ->
<<?Ebyte(?SSH_MSG_SERVICE_ACCEPT), ?Estring_utf8(Service)>>;
+encode(#ssh_msg_ext_info{
+ nr_extensions = N,
+ data = Data
+ }) ->
+ lists:foldl(fun({ExtName,ExtVal}, Acc) ->
+ <<Acc/binary, ?Estring(ExtName), ?Estring(ExtVal)>>
+ end,
+ <<?Ebyte(?SSH_MSG_EXT_INFO), ?Euint32(N)>>,
+ Data);
+
encode(#ssh_msg_newkeys{}) ->
<<?Ebyte(?SSH_MSG_NEWKEYS)>>;
@@ -435,6 +445,18 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_RESPONSE), ?UINT32(Num), Data/binary>>) ->
num_responses = Num,
data = Data};
+decode(<<?BYTE(?SSH_MSG_EXT_INFO), ?UINT32(N), BinData/binary>>) ->
+ Data = bin_foldr(
+ fun(Bin,Acc) when length(Acc) == N ->
+ {Bin,Acc};
+ (<<?DEC_BIN(V0,__0), ?DEC_BIN(V1,__1), Rest/binary>>, Acc) ->
+ {Rest,[{binary_to_list(V0),binary_to_list(V1)}|Acc]}
+ end, [], BinData),
+ #ssh_msg_ext_info{
+ nr_extensions = N,
+ data = Data
+ };
+
%%% Keyexchange messages
decode(<<?BYTE(?SSH_MSG_KEXINIT), Cookie:128, Data/binary>>) ->
decode_kex_init(Data, [Cookie, ssh_msg_kexinit], 10);
@@ -537,17 +559,28 @@ decode(<<?BYTE(?SSH_MSG_DEBUG), ?BYTE(Bool), ?DEC_BIN(Msg,__0), ?DEC_BIN(Lang,__
%%% Helper functions
%%%
+bin_foldr(Fun, Acc, Bin) ->
+ lists:reverse(bin_foldl(Fun, Acc, Bin)).
+
+bin_foldl(_, Acc, <<>>) -> Acc;
+bin_foldl(Fun, Acc0, Bin0) ->
+ {Bin,Acc} = Fun(Bin0,Acc0),
+ bin_foldl(Fun, Acc, Bin).
+
+%%%----------------------------------------------------------------
decode_keyboard_interactive_prompts(<<>>, Acc) ->
lists:reverse(Acc);
decode_keyboard_interactive_prompts(<<?DEC_BIN(Prompt,__0), ?BYTE(Bool), Bin/binary>>,
Acc) ->
decode_keyboard_interactive_prompts(Bin, [{Prompt, erl_boolean(Bool)} | Acc]).
+%%%----------------------------------------------------------------
erl_boolean(0) ->
false;
erl_boolean(1) ->
true.
+%%%----------------------------------------------------------------
decode_kex_init(<<?BYTE(Bool), ?UINT32(X)>>, Acc, 0) ->
list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc]));
decode_kex_init(<<?BYTE(Bool)>>, Acc, 0) ->