aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2015-08-20 14:40:39 +0200
committerHans Nilsson <[email protected]>2015-08-25 15:40:13 +0200
commit2564e317e34fe7f928bf6e234998b295848a5c91 (patch)
tree84238b065c7e993633b6383561d3ffd602d49242
parenta93087eafd98bf60b9611c807d0074d304e93383 (diff)
downloadotp-2564e317e34fe7f928bf6e234998b295848a5c91.tar.gz
otp-2564e317e34fe7f928bf6e234998b295848a5c91.tar.bz2
otp-2564e317e34fe7f928bf6e234998b295848a5c91.zip
ssh: add extra random length padding in packets
A new experimental option 'max_random_length_padding', not documented so it might change...
-rw-r--r--lib/ssh/src/ssh.erl5
-rw-r--r--lib/ssh/src/ssh.hrl1
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl10
-rw-r--r--lib/ssh/src/ssh_transport.erl15
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl2
5 files changed, 27 insertions, 6 deletions
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 5b2e0a988c..132de71aed 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -397,6 +397,8 @@ handle_option([{id_string, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{profile, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{max_random_length_padding, _Bool} = Opt|Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions).
@@ -515,6 +517,9 @@ handle_ssh_option({id_string, random}) ->
{id_string, {random,2,5}}; %% 2 - 5 random characters
handle_ssh_option({id_string, ID} = Opt) when is_list(ID) ->
Opt;
+handle_ssh_option({max_random_length_padding, Value} = Opt) when is_integer(Value),
+ Value =< 255 ->
+ Opt;
handle_ssh_option({profile, Value} = Opt) when is_atom(Value) ->
Opt;
handle_ssh_option(Opt) ->
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index 8df5ee820c..462c98f503 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -124,6 +124,7 @@
recv_sequence = 0,
keyex_key,
keyex_info,
+ random_length_padding = 255, % From RFC 4253 section 6.
%% User auth
user,
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index c059834b27..180698d741 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1187,7 +1187,10 @@ init_ssh(client = Role, Vsn, Version, Options, Socket) ->
opts = Options,
userauth_supported_methods = AuthMethods,
peer = {PeerName, PeerAddr},
- available_host_keys = supported_host_keys(Role, KeyCb, Options)
+ available_host_keys = supported_host_keys(Role, KeyCb, Options),
+ random_length_padding = proplists:get_value(max_random_length_padding,
+ Options,
+ (#ssh{})#ssh.random_length_padding)
};
init_ssh(server = Role, Vsn, Version, Options, Socket) ->
@@ -1207,7 +1210,10 @@ init_ssh(server = Role, Vsn, Version, Options, Socket) ->
userauth_methods = AuthMethodsAsList,
kb_tries_left = 3,
peer = {undefined, PeerAddr},
- available_host_keys = supported_host_keys(Role, KeyCb, Options)
+ available_host_keys = supported_host_keys(Role, KeyCb, Options),
+ random_length_padding = proplists:get_value(max_random_length_padding,
+ Options,
+ (#ssh{})#ssh.random_length_padding)
}.
supported_host_keys(client, _, Options) ->
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 38a0b7ec7c..9ed6c85ff7 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -745,13 +745,20 @@ ssh_packet(Msg, Ssh) ->
pack(Data0, #ssh{encrypt_block_size = BlockSize,
send_sequence = SeqNum, send_mac = MacAlg,
- send_mac_key = MacKey}
+ send_mac_key = MacKey,
+ random_length_padding = RandomLengthPadding}
= Ssh0) when is_binary(Data0) ->
{Ssh1, Data} = compress(Ssh0, Data0),
PL = (BlockSize - ((4 + 1 + size(Data)) rem BlockSize)) rem BlockSize,
- PaddingLen = if PL < 4 -> PL + BlockSize;
- true -> PL
- end,
+ MinPaddingLen = if PL < 4 -> PL + BlockSize;
+ true -> PL
+ end,
+ PadBlockSize = max(BlockSize,4),
+ MaxExtraBlocks = (max(RandomLengthPadding,MinPaddingLen) - MinPaddingLen) div PadBlockSize,
+ ExtraPaddingLen = try crypto:rand_uniform(0,MaxExtraBlocks)*PadBlockSize
+ catch _:_ -> 0
+ end,
+ PaddingLen = MinPaddingLen + ExtraPaddingLen,
Padding = ssh_bits:random(PaddingLen),
PacketLen = 1 + PaddingLen + size(Data),
PacketData = <<?UINT32(PacketLen),?BYTE(PaddingLen),
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index f30e86f193..6dfff945ac 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -466,6 +466,7 @@ rekey_limit(Config) ->
DataFile = filename:join(UserDir, "rekey.data"),
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {max_random_length_padding, 0},
{user_dir, UserDir},
{user_passwords,
[{"simon", "says"}]}]),
@@ -475,6 +476,7 @@ rekey_limit(Config) ->
{user, "simon"},
{password, "says"},
{rekey_limit, 2500},
+ {max_random_length_padding, 0},
{user_interaction, false},
{silently_accept_hosts, true}]),