From fbbf7a989750930068826dc165b8567fc1ca9a76 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 31 Aug 2017 18:31:06 +0200 Subject: ssl: Add the role (server or client) to the alert message It is desirable to be as specific as possible in the info message, so there can be no mistake if the alert is form the peer or generated by us. This use to be an error message, but it is better to make it an info message as sending an ALERT ending the connection is an expected behaviour. --- lib/ssl/src/ssl_alert.erl | 24 ++++++++++++++++++++---- lib/ssl/src/ssl_connection.erl | 23 +++++++++++++++-------- 2 files changed, 35 insertions(+), 12 deletions(-) (limited to 'lib/ssl') diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl index 2749feb1eb..db415a3666 100644 --- a/lib/ssl/src/ssl_alert.erl +++ b/lib/ssl/src/ssl_alert.erl @@ -32,7 +32,7 @@ -include("ssl_record.hrl"). -include("ssl_internal.hrl"). --export([decode/1, alert_txt/1, reason_code/2]). +-export([decode/1, own_alert_txt/1, alert_txt/1, reason_code/2]). %%==================================================================== %% Internal application API @@ -59,13 +59,29 @@ reason_code(#alert{description = ?CLOSE_NOTIFY}, _) -> reason_code(#alert{description = Description}, _) -> {tls_alert, string:to_lower(description_txt(Description))}. +%%-------------------------------------------------------------------- +-spec own_alert_txt(#alert{}) -> string(). +%% +%% Description: Returns the error string for given alert generated +%% by the erlang implementation. +%%-------------------------------------------------------------------- +own_alert_txt(#alert{level = Level, description = Description, where = {Mod,Line}, reason = undefined, role = Role}) -> + "at " ++ Mod ++ ":" ++ integer_to_list(Line) ++ " generated " ++ string:to_upper(atom_to_list(Role)) ++ " ALERT: " ++ + level_txt(Level) ++ description_txt(Description); +own_alert_txt(#alert{reason = Reason} = Alert) -> + BaseTxt = own_alert_txt(Alert#alert{reason = undefined}), + FormatDepth = 9, % Some limit on printed representation of an error + ReasonTxt = lists:flatten(io_lib:format("~P", [Reason, FormatDepth])), + BaseTxt ++ " - " ++ ReasonTxt. + %%-------------------------------------------------------------------- -spec alert_txt(#alert{}) -> string(). %% -%% Description: Returns the error string for given alert. +%% Description: Returns the error string for given alert received from +%% the peer. %%-------------------------------------------------------------------- -alert_txt(#alert{level = Level, description = Description, where = {Mod,Line}, reason = undefined, role = Role}) -> - "at " ++ Mod ++ ":" ++ integer_to_list(Line) ++ " " ++ string:to_upper(atom_to_list(Role)) ++ " ALERT: " ++ +alert_txt(#alert{level = Level, description = Description, reason = undefined, role = Role}) -> + "received " ++ string:to_upper(atom_to_list(Role)) ++ " ALERT: " ++ level_txt(Level) ++ description_txt(Description); alert_txt(#alert{reason = Reason} = Alert) -> BaseTxt = alert_txt(Alert#alert{reason = undefined}), diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 5cd66387ae..b031d3d47b 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -1144,7 +1144,8 @@ handle_alert(#alert{level = ?FATAL} = Alert, StateName, port = Port, session = Session, user_application = {_Mon, Pid}, role = Role, socket_options = Opts, tracker = Tracker}) -> invalidate_session(Role, Host, Port, Session), - log_alert(SslOpts#ssl_options.log_alert, Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}), + log_alert(SslOpts#ssl_options.log_alert, Role, Connection:protocol_name(), + StateName, Alert#alert{role = opposite_role(Role)}), alert_user(Transport, Tracker, Socket, StateName, Opts, Pid, From, Alert, Role, Connection), {stop, normal}; @@ -1155,7 +1156,8 @@ handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert, handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName, #state{role = Role, ssl_options = SslOpts, protocol_cb = Connection, renegotiation = {true, internal}} = State) -> - log_alert(SslOpts#ssl_options.log_alert, Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}), + log_alert(SslOpts#ssl_options.log_alert, Role, + Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}), handle_normal_shutdown(Alert, StateName, State), {stop, {shutdown, peer_close}}; @@ -1163,7 +1165,8 @@ handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, #state{role = Role, ssl_options = SslOpts, renegotiation = {true, From}, protocol_cb = Connection} = State0) -> - log_alert(SslOpts#ssl_options.log_alert, Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}), + log_alert(SslOpts#ssl_options.log_alert, Role, + Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}), gen_statem:reply(From, {error, renegotiation_rejected}), {Record, State} = Connection:next_record(State0), %% Go back to connection! @@ -1172,7 +1175,8 @@ handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, %% Gracefully log and ignore all other warning alerts handle_alert(#alert{level = ?WARNING} = Alert, StateName, #state{ssl_options = SslOpts, protocol_cb = Connection, role = Role} = State0) -> - log_alert(SslOpts#ssl_options.log_alert, Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}), + log_alert(SslOpts#ssl_options.log_alert, Role, + Connection:protocol_name(), StateName, Alert#alert{role = opposite_role(Role)}), {Record, State} = Connection:next_record(State0), Connection:next_event(StateName, Record, State). @@ -2372,10 +2376,13 @@ alert_user(Transport, Tracker, Socket, Active, Pid, From, Alert, Role, Connectio Transport, Socket, Connection, Tracker), ReasonCode}) end. -log_alert(true, ProtocolName, StateName, Alert) -> +log_alert(true, Role, ProtocolName, StateName, #alert{role = Role} = Alert) -> + Txt = ssl_alert:own_alert_txt(Alert), + error_logger:info_report(io_lib:format("~s ~p: In state ~p ~s\n", [ProtocolName, Role, StateName, Txt])); +log_alert(true, Role, ProtocolName, StateName, Alert) -> Txt = ssl_alert:alert_txt(Alert), - error_logger:format("~s: In state ~p ~s\n", [ProtocolName, StateName, Txt]); -log_alert(false, _, _, _) -> + error_logger:info_report(io_lib:format("~s ~p: In state ~p ~s\n", [ProtocolName, Role, StateName, Txt])); +log_alert(false, _, _, _, _) -> ok. handle_own_alert(Alert, Version, StateName, @@ -2393,7 +2400,7 @@ handle_own_alert(Alert, Version, StateName, ignore end, try %% Try to tell the local user - log_alert(SslOpts#ssl_options.log_alert, Connection:protocol_name(), StateName, Alert#alert{role = Role}), + log_alert(SslOpts#ssl_options.log_alert, Role, Connection:protocol_name(), StateName, Alert#alert{role = Role}), handle_normal_shutdown(Alert,StateName, State) catch _:_ -> ok -- cgit v1.2.3