diff options
author | Henrik Nord <[email protected]> | 2015-06-02 09:00:04 +0200 |
---|---|---|
committer | Henrik Nord <[email protected]> | 2015-06-02 09:00:04 +0200 |
commit | 21b8941d83516e381000387c47758bc7f040ae8b (patch) | |
tree | 2499b8b04c15a5ba2777a54921af7e4f9916676d /lib/ssh/src/ssh_auth.erl | |
parent | f3fefbae24a2569a13b538d80d0e99129963ebef (diff) | |
parent | c1df511623b9a2a98d4d3862ae612c1ca9837da7 (diff) | |
download | otp-21b8941d83516e381000387c47758bc7f040ae8b.tar.gz otp-21b8941d83516e381000387c47758bc7f040ae8b.tar.bz2 otp-21b8941d83516e381000387c47758bc7f040ae8b.zip |
Merge tag 'OTP-17.5.6' into maint
=== OTP-17.5.6 ===
Changed Applications:
- inets-5.10.9
- ssh-3.2.4
- ssl-6.0.1
Unchanged Applications:
- asn1-3.0.4
- common_test-1.10.1
- compiler-5.0.4
- cosEvent-2.1.15
- cosEventDomain-1.1.14
- cosFileTransfer-1.1.16
- cosNotification-1.1.21
- cosProperty-1.1.17
- cosTime-1.1.14
- cosTransactions-1.2.14
- crypto-3.5
- debugger-4.0.3
- dialyzer-2.7.4
- diameter-1.9.2
- edoc-0.7.16
- eldap-1.1.1
- erl_docgen-0.3.7
- erl_interface-3.7.20
- erts-6.4.1
- et-1.5
- eunit-2.2.9
- gs-1.5.16
- hipe-3.11.3
- ic-4.3.6
- jinterface-1.5.12
- kernel-3.2
- megaco-3.17.3
- mnesia-4.12.5
- observer-2.0.4
- odbc-2.10.22
- orber-3.7.1
- os_mon-2.3.1
- ose-1.0.2
- otp_mibs-1.0.10
- parsetools-2.0.12
- percept-0.8.10
- public_key-0.23
- reltool-0.6.6
- runtime_tools-1.8.16
- sasl-2.4.1
- snmp-5.1.2
- stdlib-2.4
- syntax_tools-1.6.18
- test_server-3.8.1
- tools-2.7.2
- typer-0.9.8
- webtool-0.8.10
- wx-1.3.3
- xmerl-1.3.7
Diffstat (limited to 'lib/ssh/src/ssh_auth.erl')
-rw-r--r-- | lib/ssh/src/ssh_auth.erl | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index 45c4d52d7e..9d1ab14ce9 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -259,6 +259,54 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User, handle_userauth_request(#ssh_msg_userauth_request{user = User, service = "ssh-connection", + method = "keyboard-interactive", + data = _}, + _, #ssh{opts = Opts} = Ssh) -> + %% RFC4256 + %% The data field contains: + %% - language tag (deprecated). If =/=[] SHOULD use it however. We skip + %% it for simplicity. + %% - submethods. "... the user can give a hint of which actual methods + %% he wants to use. ...". It's a "MAY use" so we skip + %% it. It also needs an understanding between the client + %% and the server. + %% + %% "The server MUST reply with an SSH_MSG_USERAUTH_SUCCESS, + %% SSH_MSG_USERAUTH_FAILURE, or SSH_MSG_USERAUTH_INFO_REQUEST message." + Default = {"SSH server", + "Enter password for \""++User++"\"", + "pwd: ", + false}, + + {Name, Instruction, Prompt, Echo} = + case proplists:get_value(auth_method_kb_interactive_data, Opts) of + undefined -> + Default; + {_,_,_,_}=V -> + V; + F when is_function(F) -> + {_,PeerName} = Ssh#ssh.peer, + F(PeerName, User, "ssh-connection") + end, + EchoEnc = case Echo of + true -> <<?TRUE>>; + false -> <<?FALSE>> + end, + Msg = #ssh_msg_userauth_info_request{name = unicode:characters_to_list(Name), + instruction = unicode:characters_to_list(Instruction), + language_tag = "", + num_prompts = 1, + data = <<?STRING(unicode:characters_to_binary(Prompt)), + EchoEnc/binary + >> + }, + {not_authorized, {User, undefined}, + ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User, + opts = [{max_kb_tries,3},{kb_userauth_info_msg,Msg}|Opts] + })}; + +handle_userauth_request(#ssh_msg_userauth_request{user = User, + service = "ssh-connection", method = Other}, _, #ssh{userauth_supported_methods = Methods} = Ssh) -> {not_authorized, {User, {authmethod, Other}}, @@ -280,6 +328,38 @@ handle_userauth_info_request( #ssh_msg_userauth_info_response{num_responses = NumPrompts, data = Responses}, Ssh)}. +handle_userauth_info_response(#ssh_msg_userauth_info_response{num_responses = 1, + data = <<?UINT32(Sz), Password:Sz/binary>>}, + #ssh{opts = Opts0, + user = User} = Ssh) -> + NumTriesLeft = proplists:get_value(max_kb_tries, Opts0, 0) - 1, + Opts = lists:keydelete(max_kb_tries,1,Opts0), + case check_password(User, unicode:characters_to_list(Password), Opts) of + true -> + {authorized, User, + ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)}; + false when NumTriesLeft > 0 -> + UserAuthInfoMsg = + (proplists:get_value(kb_userauth_info_msg,Opts)) + #ssh_msg_userauth_info_request{name = "", + instruction = + lists:concat( + ["Bad user or password, try again. ", + integer_to_list(NumTriesLeft), + " tries left."])}, + {not_authorized, {User, undefined}, + ssh_transport:ssh_packet(UserAuthInfoMsg, + Ssh#ssh{opts = [{max_kb_tries,NumTriesLeft}|Opts]})}; + + false -> + {not_authorized, {User, {error,"Bad user or password"}}, + ssh_transport:ssh_packet(#ssh_msg_userauth_failure{ + authentications = "", + partial_success = false}, + Ssh#ssh{opts = lists:keydelete(kb_userauth_info_msg,1,Opts)} + )} + end; + handle_userauth_info_response(#ssh_msg_userauth_info_response{}, _Auth) -> throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_SERVICE_NOT_AVAILABLE, |