From c945a703ef65e3595d4b2e4576f4fe0c7255cfc9 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Thu, 23 Jun 2016 12:46:09 +0200 Subject: Reset data when changing node or no schedulers change Caused a crash in 19, see ERL-171. Data was never reset so the number of schedulers didn't match the previous collected data. --- lib/observer/src/observer_perf_wx.erl | 40 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/observer/src/observer_perf_wx.erl b/lib/observer/src/observer_perf_wx.erl index 1010a6af4c..6a1aac92c7 100644 --- a/lib/observer/src/observer_perf_wx.erl +++ b/lib/observer/src/observer_perf_wx.erl @@ -235,12 +235,14 @@ terminate(_Event, #state{appmon=Pid}) -> code_change(_, _, State) -> State. -restart_fetcher(Node, #state{appmon=Old, panel=Panel, time=#ti{fetch=Freq}=Ti}=State) -> +restart_fetcher(Node, #state{appmon=Old, panel=Panel, time=#ti{fetch=Freq}=Ti, wins=Wins0}=State) -> catch Old ! exit, Me = self(), Pid = spawn_link(Node, observer_backend, fetch_stats, [Me, round(1000/Freq)]), wxWindow:refresh(Panel), - precalc(State#state{active=true, appmon=Pid, samples=reset_data(), time=Ti#ti{tick=0}}). + Wins = [W#win{state=undefined} || W <- Wins0], + precalc(State#state{active=true, appmon=Pid, samples=reset_data(), + wins=Wins, time=Ti#ti{tick=0}}). reset_data() -> {0, queue:new()}. @@ -253,18 +255,25 @@ add_data(Stats, {N, Q}, Wins, _, Active) -> add_data_1([#win{state={_,St}}|_]=Wins0, Last, N, {Drop, Q}, Active) when St /= undefined -> - {Wins, Stat} = - lists:mapfoldl(fun(Win0, Entry) -> - {Win1,Stat} = add_data_2(Win0, Last, Entry), - case Active of - true -> - Win = add_data_3(Win1, N, Drop, Stat, Q), - {Win, Stat}; - false -> - {Win1, Stat} - end - end, #{}, Wins0), - {Wins, {N,queue:in(Stat#{}, Q)}}; + try + {Wins, Stat} = + lists:mapfoldl(fun(Win0, Entry) -> + {Win1,Stat} = add_data_2(Win0, Last, Entry), + case Active of + true -> + Win = add_data_3(Win1, N, Drop, Stat, Q), + {Win, Stat}; + false -> + {Win1, Stat} + end + end, #{}, Wins0), + {Wins, {N,queue:in(Stat#{}, Q)}} + catch no_scheduler_change -> + {[Win#win{state=init_data(Id, Last), + info = info(Id, Last)} + || #win{name=Id}=Win <- Wins0], {0,queue:new()}} + end; + add_data_1(Wins, Stats, 1, {_, Q}, _) -> {[Win#win{state=init_data(Id, Stats), info = info(Id, Stats)} @@ -409,7 +418,8 @@ collect_data(utilz, MemInfo, Max) -> calc_delta([{Id, WN, TN}|Ss], [{Id, WP, TP}|Ps]) -> [100*(WN-WP) div (TN-TP)|calc_delta(Ss, Ps)]; -calc_delta([], []) -> []. +calc_delta([], []) -> []; +calc_delta(_, _) -> throw(no_scheduler_change). precalc(#state{samples=Data0, paint=Paint, time=Ti, wins=Wins0}=State) -> Wins = [precalc(Ti, Data0, Paint, Win) || Win <- Wins0], -- cgit v1.2.3 From 3f2ed5864b94edb6709c7942f5fdc50448744e3d Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 15 Jun 2016 12:04:28 +0200 Subject: ssh: test cases for no repetition of bad passwords --- lib/ssh/test/ssh_basic_SUITE.erl | 84 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl index 733414e23a..d52d453007 100644 --- a/lib/ssh/test/ssh_basic_SUITE.erl +++ b/lib/ssh/test/ssh_basic_SUITE.erl @@ -50,7 +50,12 @@ inet6_option/1, inet_option/1, internal_error/1, - known_hosts/1, + known_hosts/1, + login_bad_pwd_no_retry1/1, + login_bad_pwd_no_retry2/1, + login_bad_pwd_no_retry3/1, + login_bad_pwd_no_retry4/1, + login_bad_pwd_no_retry5/1, misc_ssh_options/1, openssh_zlib_basic_test/1, packet_size_zero/1, @@ -100,7 +105,8 @@ all() -> daemon_opt_fd, multi_daemon_opt_fd, packet_size_zero, - ssh_info_print + ssh_info_print, + {group, login_bad_pwd_no_retry} ]. groups() -> @@ -116,7 +122,13 @@ groups() -> {dsa_pass_key, [], [pass_phrase]}, {rsa_pass_key, [], [pass_phrase]}, {key_cb, [], [key_callback, key_callback_options]}, - {internal_error, [], [internal_error]} + {internal_error, [], [internal_error]}, + {login_bad_pwd_no_retry, [], [login_bad_pwd_no_retry1, + login_bad_pwd_no_retry2, + login_bad_pwd_no_retry3, + login_bad_pwd_no_retry4, + login_bad_pwd_no_retry5 + ]} ]. @@ -1089,6 +1101,72 @@ ssh_info_print(Config) -> end. +%%-------------------------------------------------------------------- +%% Check that a basd pwd is not tried more times. Could cause lock-out +%% on server + +login_bad_pwd_no_retry1(Config) -> + login_bad_pwd_no_retry(Config, "keyboard-interactive,password"). + +login_bad_pwd_no_retry2(Config) -> + login_bad_pwd_no_retry(Config, "password,keyboard-interactive"). + +login_bad_pwd_no_retry3(Config) -> + login_bad_pwd_no_retry(Config, "password,publickey,keyboard-interactive"). + +login_bad_pwd_no_retry4(Config) -> + login_bad_pwd_no_retry(Config, "password,other,keyboard-interactive"). + +login_bad_pwd_no_retry5(Config) -> + login_bad_pwd_no_retry(Config, "password,other,keyboard-interactive,password,password"). + + + + + +login_bad_pwd_no_retry(Config, AuthMethods) -> + PrivDir = proplists:get_value(priv_dir, Config), + UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth + file:make_dir(UserDir), + SysDir = proplists:get_value(data_dir, Config), + + Parent = self(), + PwdFun = fun(_, _, _, undefined) -> {false, 1}; + (_, _, _, _) -> Parent ! retry_bad_pwd, + false + end, + + {DaemonRef, _Host, Port} = + ssh_test_lib:daemon([{system_dir, SysDir}, + {user_dir, UserDir}, + {auth_methods, AuthMethods}, + {user_passwords, [{"foo","somepwd"}]}, + {pwdfun, PwdFun} + ]), + + ConnRes = ssh:connect("localhost", Port, + [{silently_accept_hosts, true}, + {user, "foo"}, + {password, "badpwd"}, + {user_dir, UserDir}, + {user_interaction, false}]), + + receive + retry_bad_pwd -> + ssh:stop_daemon(DaemonRef), + {fail, "Retry bad password"} + after 0 -> + case ConnRes of + {error,"Unable to connect using the available authentication methods"} -> + ssh:stop_daemon(DaemonRef), + ok; + {ok,Conn} -> + ssh:close(Conn), + ssh:stop_daemon(DaemonRef), + {fail, "Connect erroneosly succeded"} + end + end. + %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- -- cgit v1.2.3 From 53b5d8cf604222c970a298e98c6937e268011b54 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 15 Jun 2016 13:03:40 +0200 Subject: ssh: Make client send a faulty pwd only once, ssh_auth part Conflicts: lib/ssh/src/ssh_connection_handler.erl --- lib/ssh/src/ssh_auth.erl | 214 ++++++++++++++++++++++++++++------------------- 1 file changed, 126 insertions(+), 88 deletions(-) diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index 49eec8072f..1c6f656913 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -31,12 +31,107 @@ -export([publickey_msg/1, password_msg/1, keyboard_interactive_msg/1, service_request_msg/1, init_userauth_request_msg/1, userauth_request_msg/1, handle_userauth_request/3, - handle_userauth_info_request/3, handle_userauth_info_response/2 + handle_userauth_info_request/2, handle_userauth_info_response/2 ]). %%-------------------------------------------------------------------- %%% Internal application API %%-------------------------------------------------------------------- +%%%---------------------------------------------------------------- +userauth_request_msg(#ssh{userauth_methods = ServerMethods, + userauth_supported_methods = UserPrefMethods, % Note: this is not documented as supported for clients + userauth_preference = ClientMethods0 + } = Ssh0) -> + case sort_select_mthds(ClientMethods0, UserPrefMethods, ServerMethods) of + [] -> + Msg = #ssh_msg_disconnect{code = ?SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE, + description = "Unable to connect using the available authentication methods", + language = "en"}, + {disconnect, Msg, ssh_transport:ssh_packet(Msg, Ssh0)}; + + [{Pref,Module,Function,Args} | Prefs] -> + Ssh = case Pref of + "keyboard-interactive" -> Ssh0; + _ -> Ssh0#ssh{userauth_preference = Prefs} + end, + case Module:Function(Args ++ [Ssh]) of + {not_ok, Ssh1} -> + userauth_request_msg(Ssh1#ssh{userauth_preference = Prefs}); + Result -> + {Pref,Result} + end + end. + + + +sort_select_mthds(Clients, undefined, Servers) -> + %% User has not expressed an opinion via option "auth_methods", use the server's prefs + sort_select_mthds(Clients, Servers, Servers); + +sort_select_mthds(Clients, Users0, Servers0) -> + %% The User has an opinion, use the intersection of that and the Servers whishes but + %% in the Users order + Servers = unique(Servers0), + Users = unique(Users0), + [C || Key <- Users, + lists:member(Key, Servers), + C <- Clients, + element(1,C) == Key]. + +unique(L) -> + lists:reverse( + lists:foldl(fun(E,Acc) -> + case lists:member(E,Acc) of + true -> Acc; + false -> [E|Acc] + end + end, [], L)). + + +%%%---- userauth_request_msg "callbacks" +password_msg([#ssh{opts = Opts, io_cb = IoCb, + user = User, service = Service} = Ssh0]) -> + {Password,Ssh} = + case proplists:get_value(password, Opts) of + undefined when IoCb == ssh_no_io -> + {not_ok, Ssh0}; + undefined -> + {IoCb:read_password("ssh password: ",Ssh0), Ssh0}; + PW -> + %% If "password" option is given it should not be tried again + {PW, Ssh0#ssh{opts = lists:keyreplace(password,1,Opts,{password,not_ok})}} + end, + case Password of + not_ok -> + {not_ok, Ssh}; + _ -> + ssh_transport:ssh_packet( + #ssh_msg_userauth_request{user = User, + service = Service, + method = "password", + data = + <>}, + Ssh) + end. + +%% See RFC 4256 for info on keyboard-interactive +keyboard_interactive_msg([#ssh{user = User, + opts = Opts, + service = Service} = Ssh]) -> + case proplists:get_value(password, Opts) of + not_ok -> + {not_ok,Ssh}; % No need to use a failed pwd once more + _ -> + ssh_transport:ssh_packet( + #ssh_msg_userauth_request{user = User, + service = Service, + method = "keyboard-interactive", + data = << ?STRING(<<"">>), + ?STRING(<<>>) >> }, + Ssh) + end. + publickey_msg([Alg, #ssh{user = User, session_id = SessionId, service = Service, @@ -48,7 +143,7 @@ publickey_msg([Alg, #ssh{user = User, StrAlgo = atom_to_list(Alg), case encode_public_key(StrAlgo, ssh_transport:extract_public_key(PrivKey)) of not_ok -> - not_ok; + {not_ok, Ssh}; PubKeyBlob -> SigData = build_sig_data(SessionId, User, Service, PubKeyBlob, StrAlgo), @@ -65,52 +160,15 @@ publickey_msg([Alg, #ssh{user = User, Ssh) end; _Error -> - not_ok + {not_ok, Ssh} end. -password_msg([#ssh{opts = Opts, io_cb = IoCb, - user = User, service = Service} = Ssh]) -> - Password = case proplists:get_value(password, Opts) of - undefined -> - user_interaction(IoCb, Ssh); - PW -> - PW - end, - case Password of - not_ok -> - not_ok; - _ -> - ssh_transport:ssh_packet( - #ssh_msg_userauth_request{user = User, - service = Service, - method = "password", - data = - <>}, - Ssh) - end. - -user_interaction(ssh_no_io, _) -> - not_ok; -user_interaction(IoCb, Ssh) -> - IoCb:read_password("ssh password: ", Ssh). - - -%% See RFC 4256 for info on keyboard-interactive -keyboard_interactive_msg([#ssh{user = User, - service = Service} = Ssh]) -> - ssh_transport:ssh_packet( - #ssh_msg_userauth_request{user = User, - service = Service, - method = "keyboard-interactive", - data = << ?STRING(<<"">>), - ?STRING(<<>>) >> }, - Ssh). - +%%%---------------------------------------------------------------- service_request_msg(Ssh) -> ssh_transport:ssh_packet(#ssh_msg_service_request{name = "ssh-userauth"}, Ssh#ssh{service = "ssh-userauth"}). +%%%---------------------------------------------------------------- init_userauth_request_msg(#ssh{opts = Opts} = Ssh) -> case user_name(Opts) of {ok, User} -> @@ -140,34 +198,9 @@ init_userauth_request_msg(#ssh{opts = Opts} = Ssh) -> description = ErrStr}) end. -userauth_request_msg(#ssh{userauth_preference = []} = Ssh) -> - Msg = #ssh_msg_disconnect{code = - ?SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE, - description = "Unable to connect using the available" - " authentication methods", - language = "en"}, - {disconnect, Msg, ssh_transport:ssh_packet(Msg, Ssh)}; - -userauth_request_msg(#ssh{userauth_methods = Methods, - userauth_preference = [{Pref, Module, - Function, Args} | Prefs]} - = Ssh0) -> - Ssh = Ssh0#ssh{userauth_preference = Prefs}, - case lists:member(Pref, Methods) of - true -> - case Module:Function(Args ++ [Ssh]) of - not_ok -> - userauth_request_msg(Ssh); - Result -> - {Pref,Result} - end; - false -> - userauth_request_msg(Ssh) - end. - - -handle_userauth_request(#ssh_msg_service_request{name = - Name = "ssh-userauth"}, +%%%---------------------------------------------------------------- +%%% called by server +handle_userauth_request(#ssh_msg_service_request{name = Name = "ssh-userauth"}, _, Ssh) -> {ok, ssh_transport:ssh_packet(#ssh_msg_service_accept{name = Name}, Ssh#ssh{service = "ssh-connection"})}; @@ -319,21 +352,28 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User, partial_success = false}, Ssh)}. - -handle_userauth_info_request( - #ssh_msg_userauth_info_request{name = Name, - instruction = Instr, - num_prompts = NumPrompts, - data = Data}, IoCb, - #ssh{opts = Opts} = Ssh) -> +%%%---------------------------------------------------------------- +%%% keyboard-interactive client +handle_userauth_info_request(#ssh_msg_userauth_info_request{name = Name, + instruction = Instr, + num_prompts = NumPrompts, + data = Data}, + #ssh{opts = Opts, + io_cb = IoCb + } = Ssh) -> PromptInfos = decode_keyboard_interactive_prompts(NumPrompts,Data), - Responses = keyboard_interact_get_responses(IoCb, Opts, - Name, Instr, PromptInfos), - {ok, - ssh_transport:ssh_packet( - #ssh_msg_userauth_info_response{num_responses = NumPrompts, - data = Responses}, Ssh)}. + case keyboard_interact_get_responses(IoCb, Opts, Name, Instr, PromptInfos) of + not_ok -> + not_ok; + Responses -> + {ok, + ssh_transport:ssh_packet( + #ssh_msg_userauth_info_response{num_responses = NumPrompts, + data = Responses}, Ssh)} + end. +%%%---------------------------------------------------------------- +%%% keyboard-interactive server handle_userauth_info_response(#ssh_msg_userauth_info_response{num_responses = 1, data = <>}, #ssh{opts = Opts, @@ -369,11 +409,6 @@ method_preference(Algs) -> [{"publickey", ?MODULE, publickey_msg, [A]} | Acc] end, [{"password", ?MODULE, password_msg, []}, - {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}, - {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}, - {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}, - {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}, - {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}, {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []} ], Algs). @@ -473,6 +508,9 @@ keyboard_interact_get_responses(IoCb, Opts, Name, Instr, PromptInfos) -> proplists:get_value(password, Opts, undefined), IoCb, Name, Instr, PromptInfos, Opts, NumPrompts). + +keyboard_interact_get_responses(_, _, not_ok, _, _, _, _, _, _) -> + not_ok; keyboard_interact_get_responses(_, undefined, Password, _, _, _, _, _, 1) when Password =/= undefined -> [Password]; %% Password auth implemented with keyboard-interaction and passwd is known -- cgit v1.2.3 From 4f24fd3f8943d8c7ebd56336d15f699dde9bcc61 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 15 Jun 2016 13:03:40 +0200 Subject: ssh: Make client send a faulty pwd only once, ssh_connection_handler part --- lib/ssh/src/ssh_connection_handler.erl | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index e952a333ff..27c205a932 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -428,7 +428,12 @@ init_connection(server, C = #connection{}, Opts) -> init_ssh_record(Role, Socket, Opts) -> {ok, PeerAddr} = inet:peername(Socket), KeyCb = proplists:get_value(key_cb, Opts, ssh_file), - AuthMethods = proplists:get_value(auth_methods, Opts, ?SUPPORTED_AUTH_METHODS), + AuthMethods = proplists:get_value(auth_methods, + Opts, + case Role of + server -> ?SUPPORTED_AUTH_METHODS; + client -> undefined + end), S0 = #ssh{role = Role, key_cb = KeyCb, opts = Opts, @@ -794,9 +799,13 @@ handle_event(_, #ssh_msg_userauth_banner{message = Msg}, {userauth,client}, D) - handle_event(_, #ssh_msg_userauth_info_request{} = Msg, {userauth_keyboard_interactive, client}, #data{ssh_params = Ssh0} = D) -> - {ok, {Reply, Ssh}} = ssh_auth:handle_userauth_info_request(Msg, Ssh0#ssh.io_cb, Ssh0), - send_bytes(Reply, D), - {next_state, {userauth_keyboard_interactive_info_response,client}, D#data{ssh_params = Ssh}}; + case ssh_auth:handle_userauth_info_request(Msg, Ssh0) of + {ok, {Reply, Ssh}} -> + send_bytes(Reply, D), + {next_state, {userauth_keyboard_interactive_info_response,client}, D#data{ssh_params = Ssh}}; + not_ok -> + {next_state, {userauth,client}, D, [{next_event, internal, Msg}]} + end; handle_event(_, #ssh_msg_userauth_info_response{} = Msg, {userauth_keyboard_interactive, server}, D) -> case ssh_auth:handle_userauth_info_response(Msg, D#data.ssh_params) of @@ -819,7 +828,18 @@ handle_event(_, Msg = #ssh_msg_userauth_failure{}, {userauth_keyboard_interactiv D = D0#data{ssh_params = Ssh0#ssh{userauth_preference=Prefs}}, {next_state, {userauth,client}, D, [{next_event, internal, Msg}]}; -handle_event(_, Msg=#ssh_msg_userauth_failure{}, {userauth_keyboard_interactive_info_response, client}, D) -> +handle_event(_, Msg=#ssh_msg_userauth_failure{}, {userauth_keyboard_interactive_info_response, client}, + #data{ssh_params = Ssh0} = D0) -> + Opts = Ssh0#ssh.opts, + D = case proplists:get_value(password, Opts) of + undefined -> + D0; + _ -> + D0#data{ssh_params = + Ssh0#ssh{opts = + lists:keyreplace(password,1,Opts, + {password,not_ok})}} % FIXME:intermodule dependency + end, {next_state, {userauth,client}, D, [{next_event, internal, Msg}]}; handle_event(_, Msg=#ssh_msg_userauth_success{}, {userauth_keyboard_interactive_info_response, client}, D) -> -- cgit v1.2.3 From 2219cdc9dfa500625527510a4e179cd9c068407a Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 17 Jun 2016 13:34:47 +0200 Subject: ssh: Fix type error in args of ssh_auth:sort_selected_mthds --- lib/ssh/src/ssh_auth.erl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index 1c6f656913..c8f66c9d61 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -66,11 +66,15 @@ userauth_request_msg(#ssh{userauth_methods = ServerMethods, sort_select_mthds(Clients, undefined, Servers) -> %% User has not expressed an opinion via option "auth_methods", use the server's prefs - sort_select_mthds(Clients, Servers, Servers); + sort_select_mthds1(Clients, Servers, string:tokens(?SUPPORTED_AUTH_METHODS,",")); sort_select_mthds(Clients, Users0, Servers0) -> %% The User has an opinion, use the intersection of that and the Servers whishes but %% in the Users order + sort_select_mthds1(Clients, string:tokens(Users0,","), Servers0). + + +sort_select_mthds1(Clients, Users0, Servers0) -> Servers = unique(Servers0), Users = unique(Users0), [C || Key <- Users, -- cgit v1.2.3 From 51f0950b714505a036df7e1c3030b1c16828fd3c Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 17 Jun 2016 14:41:22 +0200 Subject: ssh: Some code cuddling in ssh_io --- lib/ssh/src/ssh_io.erl | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/lib/ssh/src/ssh_io.erl b/lib/ssh/src/ssh_io.erl index 026d0f6151..759ee71877 100644 --- a/lib/ssh/src/ssh_io.erl +++ b/lib/ssh/src/ssh_io.erl @@ -36,47 +36,42 @@ read_line(Prompt, Ssh) -> end. yes_no(Prompt, Ssh) -> - io:format("~s [y/n]?", [Prompt]), + format("~s [y/n]?", [Prompt]), proplists:get_value(user_pid, Ssh#ssh.opts) ! {self(), question}, receive + %% I can't see that the atoms y and n are ever received, but it must + %% be investigated before removing + y -> yes; + n -> no; + Answer -> case trim(Answer) of "y" -> yes; "n" -> no; "Y" -> yes; "N" -> no; - y -> yes; - n -> no; _ -> - io:format("please answer y or n\n"), + format("please answer y or n\n",[]), yes_no(Prompt, Ssh) end end. -read_password(Prompt, Ssh) -> +read_password(Prompt, #ssh{opts=Opts}) -> read_password(Prompt, Opts); +read_password(Prompt, Opts) when is_list(Opts) -> format("~s", [listify(Prompt)]), - case is_list(Ssh) of - false -> - proplists:get_value(user_pid, Ssh#ssh.opts) ! {self(), user_password}; - _ -> - proplists:get_value(user_pid, Ssh) ! {self(), user_password} - end, + proplists:get_value(user_pid, Opts) ! {self(), user_password}, receive + "" -> + read_password(Prompt, Opts); Answer -> - case Answer of - "" -> - read_password(Prompt, Ssh); - Pass -> Pass - end + Answer end. -listify(A) when is_atom(A) -> - atom_to_list(A); -listify(L) when is_list(L) -> - L; -listify(B) when is_binary(B) -> - binary_to_list(B). + +listify(A) when is_atom(A) -> atom_to_list(A); +listify(L) when is_list(L) -> L; +listify(B) when is_binary(B) -> binary_to_list(B). format(Fmt, Args) -> io:format(Fmt, Args). @@ -93,6 +88,3 @@ trim1([$\r|Cs]) -> trim(Cs); trim1([$\n|Cs]) -> trim(Cs); trim1([$\t|Cs]) -> trim(Cs); trim1(Cs) -> Cs. - - - -- cgit v1.2.3 From 4586fd6fa3447a1c4191620fe5b8f4412d5af0ad Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 17 Jun 2016 14:49:04 +0200 Subject: ssh: Fix a hazard bug in ssh_auth --- lib/ssh/src/ssh_io.erl | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/ssh/src/ssh_io.erl b/lib/ssh/src/ssh_io.erl index 759ee71877..1d8f370884 100644 --- a/lib/ssh/src/ssh_io.erl +++ b/lib/ssh/src/ssh_io.erl @@ -31,7 +31,7 @@ read_line(Prompt, Ssh) -> format("~s", [listify(Prompt)]), proplists:get_value(user_pid, Ssh) ! {self(), question}, receive - Answer -> + Answer when is_list(Answer) -> Answer end. @@ -44,7 +44,7 @@ yes_no(Prompt, Ssh) -> y -> yes; n -> no; - Answer -> + Answer when is_list(Answer) -> case trim(Answer) of "y" -> yes; "n" -> no; @@ -62,20 +62,24 @@ read_password(Prompt, Opts) when is_list(Opts) -> format("~s", [listify(Prompt)]), proplists:get_value(user_pid, Opts) ! {self(), user_password}, receive - "" -> - read_password(Prompt, Opts); - Answer -> - Answer + Answer when is_list(Answer) -> + case trim(Answer) of + "" -> + read_password(Prompt, Opts); + Pwd -> + Pwd + end end. +format(Fmt, Args) -> + io:format(Fmt, Args). + +%%%================================================================ listify(A) when is_atom(A) -> atom_to_list(A); listify(L) when is_list(L) -> L; listify(B) when is_binary(B) -> binary_to_list(B). -format(Fmt, Args) -> - io:format(Fmt, Args). - trim(Line) when is_list(Line) -> lists:reverse(trim1(lists:reverse(trim1(Line)))); -- cgit v1.2.3 From 12cdbfec9d19378057e92200564198f359ea3c43 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 17 Jun 2016 16:01:38 +0200 Subject: ssh: polishing of password prompt's linefeed --- lib/ssh/src/ssh_auth.erl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index c8f66c9d61..fb5e086656 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -528,17 +528,18 @@ keyboard_interact_get_responses(true, Fun, _Pwd, _IoCb, Name, Instr, PromptInfos keyboard_interact_fun(Fun, Name, Instr, PromptInfos, NumPrompts). keyboard_interact(IoCb, Name, Instr, Prompts, Opts) -> - if Name /= "" -> IoCb:format("~s~n", [Name]); - true -> ok - end, - if Instr /= "" -> IoCb:format("~s~n", [Instr]); - true -> ok - end, + write_if_nonempty(IoCb, Name), + write_if_nonempty(IoCb, Instr), lists:map(fun({Prompt, true}) -> IoCb:read_line(Prompt, Opts); ({Prompt, false}) -> IoCb:read_password(Prompt, Opts) end, Prompts). +write_if_nonempty(_, "") -> ok; +write_if_nonempty(_, <<>>) -> ok; +write_if_nonempty(IoCb, Text) -> IoCb:format("~s~n",[Text]). + + keyboard_interact_fun(KbdInteractFun, Name, Instr, PromptInfos, NumPrompts) -> Prompts = lists:map(fun({Prompt, _Echo}) -> Prompt end, PromptInfos), -- cgit v1.2.3 From e6e8b9bd005910ba3840b5ff154e37d5e1366a8b Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 27 Jun 2016 13:49:44 +0200 Subject: ssh: update vsn.mk --- lib/ssh/vsn.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index b165928877..575c1af3a9 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,5 +1,5 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 4.3 +SSH_VSN = 4.3.1 APP_VSN = "ssh-$(SSH_VSN)" -- cgit v1.2.3 From a296fc4d7f6f52c78da4596b9b08f39147089d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20L=C3=A5ng?= Date: Tue, 28 Jun 2016 11:23:49 +0200 Subject: erl_types: Normalise X:=none() pairs in t_map/3 t_map/3 previously required callers to perform this normalisation, but as t_from_form/5 would sometimes fail to do so, this requirement is relaxed. Bug (ERL-177) reported and shrunk by Luke Imhoff. --- .../test/map_SUITE_data/src/mand_remote_val/a.erl | 9 +++++++++ .../test/map_SUITE_data/src/mand_remote_val/b.erl | 3 +++ lib/hipe/cerl/erl_types.erl | 20 ++++++++++---------- 3 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/a.erl create mode 100644 lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/b.erl diff --git a/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/a.erl b/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/a.erl new file mode 100644 index 0000000000..827984b20b --- /dev/null +++ b/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/a.erl @@ -0,0 +1,9 @@ +-module(a). +-export([to_map/1, to_map/2]). +-type t() :: #{type := b:t()}. + +-spec to_map(t()) -> map(). +to_map(Resource) -> to_map(Resource, #{}). + +-spec to_map(t(), map()) -> map(). +to_map(_, Map) when is_map(Map) -> #{}. diff --git a/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/b.erl b/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/b.erl new file mode 100644 index 0000000000..31f9bb6b3e --- /dev/null +++ b/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/b.erl @@ -0,0 +1,3 @@ +-module(b). +-export_type([t/0]). +-type t() :: binary(). diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index 7826dada9d..243bb6e25d 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -1664,10 +1664,12 @@ t_map(Pairs0, DefK0, DefV0) -> %% define(DEBUG, true). try validate_map_elements(Pairs) - catch error:badarg -> error(badarg, [Pairs0,DefK0,DefV0]); - error:{badarg, E} -> error({badarg, E}, [Pairs0,DefK0,DefV0]) + catch error:badarg -> error(badarg, [Pairs0,DefK0,DefV0]) end, - ?map(Pairs, DefK, DefV). + case map_pairs_are_none(Pairs) of + true -> ?none; + false -> ?map(Pairs, DefK, DefV) + end. normalise_map_optionals([], _, _) -> []; normalise_map_optionals([E={K,?opt,?none}|T], DefK, DefV) -> @@ -1684,7 +1686,6 @@ normalise_map_optionals([E={K,?opt,V}|T], DefK, DefV) -> normalise_map_optionals([E|T], DefK, DefV) -> [E|normalise_map_optionals(T, DefK, DefV)]. -validate_map_elements([{_,?mand,?none}|_]) -> error({badarg, none_in_mand}); validate_map_elements([{K1,_,_}|Rest=[{K2,_,_}|_]]) -> case is_singleton_type(K1) andalso K1 < K2 of false -> error(badarg); @@ -1697,6 +1698,10 @@ validate_map_elements([{K,_,_}]) -> end; validate_map_elements([]) -> true. +map_pairs_are_none([]) -> false; +map_pairs_are_none([{_,?mand,?none}|_]) -> true; +map_pairs_are_none([_|Ps]) -> map_pairs_are_none(Ps). + -spec t_is_map(erl_type()) -> boolean(). t_is_map(Type) -> @@ -2833,12 +2838,7 @@ t_inf(?map(_, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B, _Opaques) -> %% becomes mandatory in the infinumum (K, _, V1, _, V2) -> {K, ?mand, t_inf(V1, V2)} end, A, B), - %% If the infinimum of any mandatory values is ?none, the entire map infinimum - %% is ?none. - case lists:any(fun({_,?mand,?none})->true; ({_,_,_}) -> false end, Pairs) of - true -> t_none(); - false -> t_map(Pairs, t_inf(ADefK, BDefK), t_inf(ADefV, BDefV)) - end; + t_map(Pairs, t_inf(ADefK, BDefK), t_inf(ADefV, BDefV)); t_inf(?matchstate(Pres1, Slots1), ?matchstate(Pres2, Slots2), _Opaques) -> ?matchstate(t_inf(Pres1, Pres2), t_inf(Slots1, Slots2)); t_inf(?nil, ?nil, _Opaques) -> ?nil; -- cgit v1.2.3 From 44fb5e8c080a682cd47b791ae641c196b1c0ec74 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Tue, 28 Jun 2016 14:02:14 +0200 Subject: tools: Fix a bug adding multiple modules to an Xref server The bug when introduced in OTP-19.0. Optimize adding multiple modules to an Xref server --- lib/tools/src/xref_base.erl | 4 +++- lib/tools/test/xref_SUITE.erl | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/tools/src/xref_base.erl b/lib/tools/src/xref_base.erl index bb9815f9b0..f298a1ce81 100644 --- a/lib/tools/src/xref_base.erl +++ b/lib/tools/src/xref_base.erl @@ -746,7 +746,7 @@ read_a_module({Dir, BaseName}, AppName, Builtins, Verbose, Warnings, Mode) -> message(Warnings, no_debug_info, [File]), no; {ok, M, Data, UnresCalls0} -> - message(Verbose, done, [File]), + message(Verbose, done_file, [File]), %% Remove duplicates. Identical unresolved calls on the %% same line are counted as _one_ unresolved call. UnresCalls = usort(UnresCalls0), @@ -1842,6 +1842,8 @@ message(true, What, Arg) -> set_up -> io:format("Setting up...", Arg); done -> + io:format("done~n", Arg); + done_file -> io:format("done reading ~ts~n", Arg); error -> io:format("error~n", Arg); diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl index ce30fb711a..01dbac6ecb 100644 --- a/lib/tools/test/xref_SUITE.erl +++ b/lib/tools/test/xref_SUITE.erl @@ -50,7 +50,7 @@ -export([analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]). --export([format_error/1, otp_7423/1, otp_7831/1, otp_10192/1]). +-export([format_error/1, otp_7423/1, otp_7831/1, otp_10192/1, otp_13708/1]). -import(lists, [append/2, flatten/1, keysearch/3, member/2, sort/1, usort/1]). @@ -82,7 +82,7 @@ groups() -> fun_mfa_r14, fun_mfa_vars, qlc]}, {analyses, [], [analyze, basic, md, q, variables, unused_locals]}, - {misc, [], [format_error, otp_7423, otp_7831, otp_10192]}]. + {misc, [], [format_error, otp_7423, otp_7831, otp_10192, otp_13708]}]. init_per_suite(Conf) when is_list(Conf) -> @@ -2393,6 +2393,19 @@ otp_10192(Conf) when is_list(Conf) -> xref:stop(s), ok. +%% OTP-10192. Allow filenames with character codes greater than 126. +otp_13708(Conf) when is_list(Conf) -> + {ok, _} = start(s), + ok = xref:set_default(s, [{verbose, true}]), + {ok, []} = xref:q(s,"E"), + xref:stop(s), + + CopyDir = ?copydir, + Dir = fname(CopyDir,"lib_test"), + {ok, _} = start(s), + ok = xref:set_library_path(s, [Dir], [{verbose, true}]), + xref:stop(s). + %%% %%% Utilities %%% -- cgit v1.2.3 From c7478ca8549817bb6b20bc0000edb1f00f6fdf6f Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Jun 2016 19:44:51 +0200 Subject: inets: ftp debug printout removed --- lib/inets/src/ftp/ftp.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index bbf25f8e90..a57c47e00f 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -106,8 +106,8 @@ -type common_reason() :: 'econn' | 'eclosed' | term(). -type file_write_error_reason() :: term(). % See file:write for more info -%%-define(DBG(F,A), 'n/a'). --define(DBG(F,A), io:format(F,A)). +-define(DBG(F,A), 'n/a'). +%%-define(DBG(F,A), io:format(F,A)). %%%========================================================================= %%% API - CLIENT FUNCTIONS -- cgit v1.2.3 From e0b3bd1c394c2ccf8190cb1c3768c8314d265e5a Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Jun 2016 19:45:56 +0200 Subject: inets: unused var in ftp.erl anonymized --- lib/inets/src/ftp/ftp.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index a57c47e00f..8bad91bf98 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -2099,7 +2099,7 @@ handle_ctrl_result({pos_prel, _}, #state{caller = {transfer_data, Bin}} %%-------------------------------------------------------------------------- %% Default -handle_ctrl_result({Status, Lines}, #state{client = From} = State) +handle_ctrl_result({Status, _Lines}, #state{client = From} = State) when From =/= undefined -> ctrl_result_response(Status, State, {error, Status}). -- cgit v1.2.3 From 594ce0721b872e93cd8b7522224902e66af8dfa6 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 29 Jun 2016 12:26:18 +0200 Subject: inets: updated version --- lib/inets/vsn.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 543e0d44fd..3408c3b128 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 6.3 +INETS_VSN = 6.3.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" -- cgit v1.2.3 From 4fb1bf9584cd2a9efb5dd0b527961087a3871387 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 22 Jun 2016 12:06:37 +0200 Subject: ssh: remove 'sync sleeps' --- lib/ssh/src/ssh_connection_handler.erl | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index e952a333ff..a62af9e1ce 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -1315,12 +1315,10 @@ terminate(shutdown, StateName, State0) -> State = send_msg(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION, description = "Application shutdown"}, State0), -timer:sleep(400), %% FIXME!!! gen_tcp:shutdown instead finalize_termination(StateName, State); %% terminate({shutdown,Msg}, StateName, State0) when is_record(Msg,ssh_msg_disconnect)-> %% State = send_msg(Msg, State0), -%% timer:sleep(400), %% FIXME!!! gen_tcp:shutdown instead %% finalize_termination(StateName, Msg, State); terminate({shutdown,_R}, StateName, State) -> @@ -1635,7 +1633,6 @@ new_channel_id(#data{connection_state = #connection{channel_id_seed = Id} = disconnect(Msg=#ssh_msg_disconnect{description=Description}, _StateName, State0) -> State = send_msg(Msg, State0), disconnect_fun(Description, State), -timer:sleep(400), {stop, {shutdown,Description}, State}. %%%---------------------------------------------------------------- -- cgit v1.2.3 From 4b8ac323044db286123c3f9734681b53e824b6ac Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 22 Jun 2016 12:07:35 +0200 Subject: ssh: Extend experimental ssh_dbg.erl 1) extend ssh_dbg:message with second arg, a fun/1 that is intended to replace pids in the trace printouts with better descriptions. 2) printout improvments --- lib/ssh/src/ssh_dbg.erl | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl index 480795cfc7..bd6bc0335b 100644 --- a/lib/ssh/src/ssh_dbg.erl +++ b/lib/ssh/src/ssh_dbg.erl @@ -24,6 +24,7 @@ -export([messages/0, messages/1, + messages/2, stop/0 ]). @@ -36,12 +37,16 @@ writer, acc = []}). %%%================================================================ -messages() -> messages(fun(String,_D) -> io:format(String) end). -%% messages() -> messages(fun(String,Acc) -> [String|Acc] end) +messages() -> + messages(fun(String,_D) -> io:format(String) end). messages(Write) when is_function(Write,2) -> + messages(Write, fun(X) -> X end). + +messages(Write, MangleArg) when is_function(Write,2), + is_function(MangleArg,1) -> catch dbg:start(), - setup_tracer(Write), + setup_tracer(Write, MangleArg), dbg:p(new,c), dbg_ssh_messages(). @@ -63,18 +68,30 @@ msg_formater({trace,_Pid,return_from,{ssh_message,encode,1},_Res}, D) -> msg_formater({trace,_Pid,call,{ssh_message,decode,_}}, D) -> D; msg_formater({trace,Pid,return_from,{ssh_message,decode,1},Msg}, D) -> - fmt("~nRECV ~p ~s~n", [Pid,wr_record(shrink_bin(Msg))], D); + fmt("~n~p RECV ~s~n", [Pid,wr_record(shrink_bin(Msg))], D); msg_formater({trace,_Pid,call,{ssh_transport,select_algorithm,_}}, D) -> D; msg_formater({trace,Pid,return_from,{ssh_transport,select_algorithm,3},{ok,Alg}}, D) -> - fmt("~nALGORITHMS ~p~n~s~n", [Pid, wr_record(Alg)], D); + fmt("~n~p ALGORITHMS~n~s~n", [Pid, wr_record(Alg)], D); + + +msg_formater({trace,Pid,send,{tcp,Sock,Bytes},Pid}, D) -> + fmt("~n~p TCP SEND on ~p~n ~p~n", [Pid,Sock, shrink_bin(Bytes)], D); + +msg_formater({trace,Pid,send,{tcp,Sock,Bytes},Dest}, D) -> + fmt("~n~p TCP SEND from ~p TO ~p~n ~p~n", [Pid,Sock,Dest, shrink_bin(Bytes)], D); msg_formater({trace,Pid,send,ErlangMsg,Dest}, D) -> - fmt("~nERL MSG ~p SEND TO ~p~n ~p~n", [Pid,Dest, shrink_bin(ErlangMsg)], D); + fmt("~n~p ERL MSG SEND TO ~p~n ~p~n", [Pid,Dest, shrink_bin(ErlangMsg)], D); + + +msg_formater({trace,Pid,'receive',{tcp,Sock,Bytes}}, D) -> + fmt("~n~p TCP RECEIVE on ~p~n ~p~n", [Pid,Sock,shrink_bin(Bytes)], D); msg_formater({trace,Pid,'receive',ErlangMsg}, D) -> - fmt("~nERL MSG ~p RECIEVE~n ~p~n", [Pid,shrink_bin(ErlangMsg)], D); + fmt("~n~p ERL MSG RECEIVE~n ~p~n", [Pid,shrink_bin(ErlangMsg)], D); + msg_formater(M, D) -> fmt("~nDBG ~n~p~n", [shrink_bin(M)], D). @@ -87,8 +104,10 @@ fmt(Fmt, Args, D=#data{writer=Write,acc=Acc}) -> D#data{acc = Write(io_lib:format(Fmt, Args), Acc)}. %%%---------------------------------------------------------------- -setup_tracer(Write) -> - Handler = fun msg_formater/2, +setup_tracer(Write, MangleArg) -> + Handler = fun(Arg, D) -> + msg_formater(MangleArg(Arg), D) + end, InitialData = #data{writer = Write}, {ok,_} = dbg:tracer(process, {Handler, InitialData}), ok. -- cgit v1.2.3 From 698b11ec4a4f9944ea66ace7bacb17535f6cb9ee Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 23 Jun 2016 15:47:48 +0200 Subject: ssh: added dbg keys to ssh:connection_info/2 and ssh:channel_info/3 --- lib/ssh/src/ssh_connection_handler.erl | 73 +++++++++++++++++----------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index a62af9e1ce..f825f0fae2 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -1006,13 +1006,13 @@ handle_event({call,From}, get_print_info, StateName, D) -> {keep_state_and_data, [{reply,From,Reply}]}; handle_event({call,From}, {connection_info, Options}, _, D) -> - Info = ssh_info(Options, D, []), + Info = fold_keys(Options, fun conn_info/2, D), {keep_state_and_data, [{reply,From,Info}]}; handle_event({call,From}, {channel_info,ChannelId,Options}, _, D) -> case ssh_channel:cache_lookup(cache(D), ChannelId) of #channel{} = Channel -> - Info = ssh_channel_info(Options, Channel, []), + Info = fold_keys(Options, fun chann_info/2, Channel), {keep_state_and_data, [{reply,From,Info}]}; undefined -> {keep_state_and_data, [{reply,From,[]}]} @@ -1641,43 +1641,43 @@ counterpart_versions(NumVsn, StrVsn, #ssh{role = server} = Ssh) -> counterpart_versions(NumVsn, StrVsn, #ssh{role = client} = Ssh) -> Ssh#ssh{s_vsn = NumVsn , s_version = StrVsn}. -ssh_info([], _State, Acc) -> - Acc; -ssh_info([client_version | Rest], #data{ssh_params = #ssh{c_vsn = IntVsn, - c_version = StringVsn}} = State, Acc) -> - ssh_info(Rest, State, [{client_version, {IntVsn, StringVsn}} | Acc]); - -ssh_info([server_version | Rest], #data{ssh_params =#ssh{s_vsn = IntVsn, - s_version = StringVsn}} = State, Acc) -> - ssh_info(Rest, State, [{server_version, {IntVsn, StringVsn}} | Acc]); -ssh_info([peer | Rest], #data{ssh_params = #ssh{peer = Peer}} = State, Acc) -> - ssh_info(Rest, State, [{peer, Peer} | Acc]); -ssh_info([sockname | Rest], #data{socket = Socket} = State, Acc) -> - {ok, SockName} = inet:sockname(Socket), - ssh_info(Rest, State, [{sockname, SockName}|Acc]); -ssh_info([user | Rest], #data{auth_user = User} = State, Acc) -> - ssh_info(Rest, State, [{user, User}|Acc]); -ssh_info([ _ | Rest], State, Acc) -> - ssh_info(Rest, State, Acc). - - -ssh_channel_info([], _, Acc) -> - Acc; +%%%---------------------------------------------------------------- +conn_info(client_version, #data{ssh_params=S}) -> {S#ssh.c_vsn, S#ssh.c_version}; +conn_info(server_version, #data{ssh_params=S}) -> {S#ssh.s_vsn, S#ssh.s_version}; +conn_info(peer, #data{ssh_params=S}) -> S#ssh.peer; +conn_info(user, D) -> D#data.auth_user; +conn_info(sockname, D) -> {ok, SockName} = inet:sockname(D#data.socket), + SockName; +%% dbg options ( = not documented): +conn_info(socket, D) -> D#data.socket; +conn_info(chan_ids, D) -> + ssh_channel:cache_foldl(fun(#channel{local_id=Id}, Acc) -> + [Id | Acc] + end, [], cache(D)). -ssh_channel_info([recv_window | Rest], #channel{recv_window_size = WinSize, - recv_packet_size = Packsize - } = Channel, Acc) -> - ssh_channel_info(Rest, Channel, [{recv_window, {{win_size, WinSize}, - {packet_size, Packsize}}} | Acc]); -ssh_channel_info([send_window | Rest], #channel{send_window_size = WinSize, - send_packet_size = Packsize - } = Channel, Acc) -> - ssh_channel_info(Rest, Channel, [{send_window, {{win_size, WinSize}, - {packet_size, Packsize}}} | Acc]); -ssh_channel_info([ _ | Rest], Channel, Acc) -> - ssh_channel_info(Rest, Channel, Acc). +%%%---------------------------------------------------------------- +chann_info(recv_window, C) -> + {{win_size, C#channel.recv_window_size}, + {packet_size, C#channel.recv_packet_size}}; +chann_info(send_window, C) -> + {{win_size, C#channel.send_window_size}, + {packet_size, C#channel.send_packet_size}}; +%% dbg options ( = not documented): +chann_info(pid, C) -> + C#channel.user. +%%%---------------------------------------------------------------- +%% Assisting meta function for the *_info functions +fold_keys(Keys, Fun, Extra) -> + lists:foldr(fun(Key, Acc) -> + try Fun(Key, Extra) of + Value -> [{Key,Value}|Acc] + catch + _:_ -> Acc + end + end, [], Keys). +%%%---------------------------------------------------------------- log_error(Reason) -> Report = io_lib:format("Erlang ssh connection handler failed with reason:~n" " ~p~n" @@ -1686,7 +1686,6 @@ log_error(Reason) -> [Reason, erlang:get_stacktrace()]), error_logger:error_report(Report). - %%%---------------------------------------------------------------- not_connected_filter({connection_reply, _Data}) -> true; not_connected_filter(_) -> false. -- cgit v1.2.3 From 50aa639c4c3398c40fdce514e45ce687aa189189 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Jun 2016 16:57:51 +0200 Subject: ssh: Remove possible hanging in TCs when server and client is on the same node --- lib/ssh/src/ssh_connection_handler.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index f825f0fae2..5e05188e7f 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -1206,8 +1206,9 @@ handle_event(internal, prepare_next_packet, _, D) -> Sz when Sz >= Enough -> self() ! {D#data.transport_protocol, D#data.socket, <<>>}; _ -> - inet:setopts(D#data.socket, [{active, once}]) + ok end, + inet:setopts(D#data.socket, [{active, once}]), keep_state_and_data; handle_event(info, {CloseTag,Socket}, StateName, -- cgit v1.2.3 From 3dca3e5732b8fe02531f17a6fb25ca513f75ed4c Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 29 Jun 2016 13:36:01 +0200 Subject: ssh: Update ssh version --- lib/ssh/vsn.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index b165928877..575c1af3a9 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,5 +1,5 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 4.3 +SSH_VSN = 4.3.1 APP_VSN = "ssh-$(SSH_VSN)" -- cgit v1.2.3 From 6e9af06b17476cb680fbc33ae47dff173ea24204 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Wed, 29 Jun 2016 17:14:18 +0200 Subject: Fix group_leader/2 --- erts/emulator/beam/bif.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index fc14061a44..d9048065c8 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -4305,8 +4305,9 @@ BIF_RETTYPE group_leader_2(BIF_ALIST_2) else { locks &= ~ERTS_PROC_LOCK_STATUS; erts_smp_proc_unlock(new_member, ERTS_PROC_LOCK_STATUS); - if (erts_smp_atomic32_read_nob(&new_member->state) - & !(ERTS_PSFLG_DIRTY_RUNNING|ERTS_PSFLG_DIRTY_RUNNING_SYS)) { + if (new_member == BIF_P + || !(erts_smp_atomic32_read_nob(&new_member->state) + & (ERTS_PSFLG_DIRTY_RUNNING|ERTS_PSFLG_DIRTY_RUNNING_SYS))) { new_member->group_leader = STORE_NC_IN_PROC(new_member, BIF_ARG_1); } @@ -4326,6 +4327,7 @@ BIF_RETTYPE group_leader_2(BIF_ALIST_2) BIF_ARG_1); bp->next = new_member->mbuf; new_member->mbuf = bp; + new_member->mbuf_sz += bp->used_size; } } } -- cgit v1.2.3 From e0995e0b54de40edd87b4ed48ce8595d5b561c66 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Wed, 29 Jun 2016 17:42:55 +0200 Subject: Update version numbers --- erts/vsn.mk | 2 +- lib/dialyzer/vsn.mk | 2 +- lib/observer/vsn.mk | 2 +- lib/tools/vsn.mk | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/erts/vsn.mk b/erts/vsn.mk index 6ad3680213..924558dab1 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 8.0 +VSN = 8.0.1 # Port number 4365 in 4.2 # Port number 4366 in 4.3 diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk index 077fe01e85..b9a28afdd9 100644 --- a/lib/dialyzer/vsn.mk +++ b/lib/dialyzer/vsn.mk @@ -1 +1 @@ -DIALYZER_VSN = 3.0 +DIALYZER_VSN = 3.0.1 diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk index f214810199..9a7c6a546f 100644 --- a/lib/observer/vsn.mk +++ b/lib/observer/vsn.mk @@ -1 +1 @@ -OBSERVER_VSN = 2.2 +OBSERVER_VSN = 2.2.1 diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index 8c889cbe4e..e6287b0430 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 2.8.4 +TOOLS_VSN = 2.8.5 -- cgit v1.2.3 From 9517c37a8c2319be620d304db0d5b11d398057be Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Wed, 29 Jun 2016 17:43:27 +0200 Subject: Update release notes --- erts/doc/src/notes.xml | 18 ++++++++++++++++++ lib/dialyzer/doc/src/notes.xml | 14 ++++++++++++++ lib/inets/doc/src/notes.xml | 18 +++++++++++++++++- lib/observer/doc/src/notes.xml | 17 +++++++++++++++++ lib/ssh/doc/src/notes.xml | 24 ++++++++++++++++++++++++ lib/tools/doc/src/notes.xml | 15 +++++++++++++++ 6 files changed, 105 insertions(+), 1 deletion(-) diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 3c3129d543..4b5b01d2b1 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -32,6 +32,24 @@

This document describes the changes made to the ERTS application.

+
Erts 8.0.1 + +
Fixed Bugs and Malfunctions + + +

+ A memory allocation bug in group_leader/2 could + cause an emulator crash when garbage collecting a process + that had been assigned a remote group leader. This bug + was introduced in ERTS version 8.0.

+

+ Own Id: OTP-13716

+
+
+
+ +
+
Erts 8.0
Fixed Bugs and Malfunctions diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml index a5a52fee61..6400072b1f 100644 --- a/lib/dialyzer/doc/src/notes.xml +++ b/lib/dialyzer/doc/src/notes.xml @@ -32,6 +32,20 @@

This document describes the changes made to the Dialyzer application.

+
Dialyzer 3.0.1 + +
Fixed Bugs and Malfunctions + + +

Fix a map related bug.

+

+ Own Id: OTP-13709 Aux Id: ERL-177, PR-1115

+
+
+
+ +
+
Dialyzer 3.0
Fixed Bugs and Malfunctions diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 5321203511..2f071f049f 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,7 +33,23 @@ notes.xml -
Inets 6.3 +
Inets 6.3.1 + +
Fixed Bugs and Malfunctions + + +

+ A debug message was accidently left enabled in the ftp + client.

+

+ Own Id: OTP-13712 Aux Id: seq13143

+
+
+
+ +
+ +
Inets 6.3
Fixed Bugs and Malfunctions diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml index 505d0dcc89..f79f75fead 100644 --- a/lib/observer/doc/src/notes.xml +++ b/lib/observer/doc/src/notes.xml @@ -32,6 +32,23 @@

This document describes the changes made to the Observer application.

+
Observer 2.2.1 + +
Fixed Bugs and Malfunctions + + +

+ Fixed a crash happening when observing another node, who + have a different number of schedulers than the current + one.

+

+ Own Id: OTP-13702 Aux Id: ERL-171

+
+
+
+ +
+
Observer 2.2
Improvements and New Features diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index fd15c334a3..ef6ee79654 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -30,6 +30,30 @@ notes.xml +
Ssh 4.3.1 + +
Fixed Bugs and Malfunctions + + +

+ SSH client does not any longer retry a bad password given + as option to ssh:connect et al.

+

+ Own Id: OTP-13674 Aux Id: TR-HU92273

+
+ +

+ Removed possible hanging risk for a certain timing + sequence when communicating client and server executes on + the same node.

+

+ Own Id: OTP-13715

+
+
+
+ +
+
Ssh 4.3
Improvements and New Features diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index 0b8a2be715..a0a817c0f2 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -31,6 +31,21 @@

This document describes the changes made to the Tools application.

+
Tools 2.8.5 + +
Fixed Bugs and Malfunctions + + +

Correct a bug when adding multiple modules to an Xref + server. The bug was introduced in OTP-19.0.

+

+ Own Id: OTP-13708 Aux Id: ERL-173

+
+
+
+ +
+
Tools 2.8.4
Fixed Bugs and Malfunctions -- cgit v1.2.3 From 0573efbc18fc20f8646cf3ff64d2affd06e03cb8 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Wed, 29 Jun 2016 17:43:28 +0200 Subject: Updated OTP version --- OTP_VERSION | 2 +- otp_versions.table | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/OTP_VERSION b/OTP_VERSION index 6ea9a3bd47..1870facefc 100644 --- a/OTP_VERSION +++ b/OTP_VERSION @@ -1 +1 @@ -19.0 +19.0.1 diff --git a/otp_versions.table b/otp_versions.table index bfaa17a394..21c12505c1 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,3 +1,4 @@ +OTP-19.0.1 : dialyzer-3.0.1 erts-8.0.1 inets-6.3.1 observer-2.2.1 ssh-4.3.1 tools-2.8.5 # asn1-4.0.3 common_test-1.12.2 compiler-7.0 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7 debugger-4.2 diameter-1.12 edoc-0.7.19 eldap-1.2.2 erl_docgen-0.5 erl_interface-3.9 et-1.6 eunit-2.3 gs-1.6.1 hipe-3.15.1 ic-4.4.1 jinterface-1.7 kernel-5.0 megaco-3.18.1 mnesia-4.14 odbc-2.11.2 orber-3.8.2 os_mon-2.4.1 otp_mibs-1.1.1 parsetools-2.1.2 percept-0.9 public_key-1.2 reltool-0.7.1 runtime_tools-1.10 sasl-3.0 snmp-5.2.3 ssl-8.0 stdlib-3.0 syntax_tools-2.0 typer-0.9.11 wx-1.7 xmerl-1.3.11 : OTP-19.0 : asn1-4.0.3 common_test-1.12.2 compiler-7.0 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7 debugger-4.2 dialyzer-3.0 diameter-1.12 edoc-0.7.19 eldap-1.2.2 erl_docgen-0.5 erl_interface-3.9 erts-8.0 et-1.6 eunit-2.3 gs-1.6.1 hipe-3.15.1 ic-4.4.1 inets-6.3 jinterface-1.7 kernel-5.0 megaco-3.18.1 mnesia-4.14 observer-2.2 odbc-2.11.2 orber-3.8.2 os_mon-2.4.1 otp_mibs-1.1.1 parsetools-2.1.2 percept-0.9 public_key-1.2 reltool-0.7.1 runtime_tools-1.10 sasl-3.0 snmp-5.2.3 ssh-4.3 ssl-8.0 stdlib-3.0 syntax_tools-2.0 tools-2.8.4 typer-0.9.11 wx-1.7 xmerl-1.3.11 # : OTP-18.3.4 : inets-6.2.4 ssl-7.3.3 # asn1-4.0.2 common_test-1.12.1 compiler-6.0.3 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2.1 cosProperty-1.2 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 erts-7.3.1 et-1.5.1 eunit-2.2.13 gs-1.6 hipe-3.15 ic-4.4 jinterface-1.6.1 kernel-4.2 megaco-3.18 mnesia-4.13.4 observer-2.1.2 odbc-2.11.1 orber-3.8.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1.1 reltool-0.7 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 stdlib-2.8 syntax_tools-1.7 test_server-3.10 tools-2.8.3 typer-0.9.10 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 : OTP-18.3.3 : common_test-1.12.1 inets-6.2.3 ssl-7.3.2 # asn1-4.0.2 compiler-6.0.3 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2.1 cosProperty-1.2 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 erts-7.3.1 et-1.5.1 eunit-2.2.13 gs-1.6 hipe-3.15 ic-4.4 jinterface-1.6.1 kernel-4.2 megaco-3.18 mnesia-4.13.4 observer-2.1.2 odbc-2.11.1 orber-3.8.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1.1 reltool-0.7 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 stdlib-2.8 syntax_tools-1.7 test_server-3.10 tools-2.8.3 typer-0.9.10 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 : -- cgit v1.2.3