mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-22 17:28:25 +01:00
Add tests for s2s code
This commit is contained in:
parent
ceda073766
commit
53209b9ab1
@ -158,7 +158,7 @@
|
||||
-record(stream_start, {from :: jid:jid(),
|
||||
to :: jid:jid(),
|
||||
id = <<>> :: binary(),
|
||||
version = <<>> :: binary(),
|
||||
version :: {non_neg_integer(),non_neg_integer()},
|
||||
xmlns = <<>> :: binary(),
|
||||
stream_xmlns = <<>> :: binary(),
|
||||
db_xmlns = <<>> :: binary(),
|
||||
|
@ -352,16 +352,16 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
||||
S -> S
|
||||
end,
|
||||
StreamVersion = case Version of
|
||||
<<"1.0">> -> <<"1.0">>;
|
||||
_ -> <<"">>
|
||||
{1,0} -> {1,0};
|
||||
_ -> undefined
|
||||
end,
|
||||
IsBlacklistedIP = is_ip_blacklisted(StateData#state.ip, Lang),
|
||||
case lists:member(Server, ?MYHOSTS) of
|
||||
true when IsBlacklistedIP == false ->
|
||||
change_shaper(StateData, jid:make(<<"">>, Server, <<"">>)),
|
||||
case StreamVersion of
|
||||
<<"1.0">> ->
|
||||
send_header(StateData, Server, <<"1.0">>, ?MYLANG),
|
||||
{1,0} ->
|
||||
send_header(StateData, Server, {1,0}, ?MYLANG),
|
||||
case StateData#state.authenticated of
|
||||
false ->
|
||||
TLS = StateData#state.tls,
|
||||
@ -490,10 +490,14 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
||||
send_header(StateData, ?MYNAME, StreamVersion, ?MYLANG),
|
||||
send_element(StateData, xmpp:serr_host_unknown()),
|
||||
{stop, normal, StateData}
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
send_header(StateData, ?MYNAME, {1,0}, ?MYLANG),
|
||||
send_element(StateData, xmpp:serr_invalid_xml()),
|
||||
{stop, normal, StateData}
|
||||
catch _:{xmpp_codec, Why} ->
|
||||
Txt = xmpp:format_error(Why),
|
||||
send_header(StateData, ?MYNAME, <<"1.0">>, ?MYLANG),
|
||||
send_header(StateData, ?MYNAME, {1,0}, ?MYLANG),
|
||||
send_element(StateData, xmpp:serr_invalid_xml(Txt, ?MYLANG)),
|
||||
{stop, normal, StateData}
|
||||
end;
|
||||
@ -506,7 +510,7 @@ wait_for_stream({xmlstreamend, _}, StateData) ->
|
||||
send_element(StateData, xmpp:serr_not_well_formed()),
|
||||
{stop, normal, StateData};
|
||||
wait_for_stream({xmlstreamerror, _}, StateData) ->
|
||||
send_header(StateData, ?MYNAME, <<"1.0">>, <<"">>),
|
||||
send_header(StateData, ?MYNAME, {1,0}, <<"">>),
|
||||
send_element(StateData, xmpp:serr_not_well_formed()),
|
||||
{stop, normal, StateData};
|
||||
wait_for_stream(closed, StateData) ->
|
||||
@ -1374,7 +1378,7 @@ handle_info({'DOWN', Monitor, _Type, _Object, _Info},
|
||||
handle_info(system_shutdown, StateName, StateData) ->
|
||||
case StateName of
|
||||
wait_for_stream ->
|
||||
send_header(StateData, ?MYNAME, <<"1.0">>, <<"en">>),
|
||||
send_header(StateData, ?MYNAME, {1,0}, <<"en">>),
|
||||
send_element(StateData, xmpp:serr_system_shutdown()),
|
||||
ok;
|
||||
_ ->
|
||||
@ -1597,39 +1601,20 @@ send_packet(StateData, Packet) ->
|
||||
end.
|
||||
|
||||
-spec send_header(state(), binary(), binary(), binary()) -> ok | {error, any()}.
|
||||
send_header(StateData, Server, Version, Lang)
|
||||
when StateData#state.xml_socket ->
|
||||
VersionAttr = case Version of
|
||||
<<"">> -> [];
|
||||
_ -> [{<<"version">>, Version}]
|
||||
end,
|
||||
LangAttr = case Lang of
|
||||
<<"">> -> [];
|
||||
_ -> [{<<"xml:lang">>, Lang}]
|
||||
end,
|
||||
Header = {xmlstreamstart, <<"stream:stream">>,
|
||||
VersionAttr ++
|
||||
LangAttr ++
|
||||
[{<<"xmlns">>, <<"jabber:client">>},
|
||||
{<<"xmlns:stream">>,
|
||||
<<"http://etherx.jabber.org/streams">>},
|
||||
{<<"id">>, StateData#state.streamid},
|
||||
{<<"from">>, Server}]},
|
||||
(StateData#state.sockmod):send_xml(StateData#state.socket,
|
||||
Header);
|
||||
send_header(StateData, Server, Version, Lang) ->
|
||||
VersionStr = case Version of
|
||||
<<"">> -> <<"">>;
|
||||
_ -> [<<" version='">>, Version, <<"'">>]
|
||||
end,
|
||||
LangStr = case Lang of
|
||||
<<"">> -> <<"">>;
|
||||
_ -> [<<" xml:lang='">>, Lang, <<"'">>]
|
||||
end,
|
||||
Header = io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.streamid, Server, VersionStr,
|
||||
LangStr]),
|
||||
send_text(StateData, iolist_to_binary(Header)).
|
||||
Header = #xmlel{name = Name, attrs = Attrs} =
|
||||
xmpp:encode(#stream_start{version = Version,
|
||||
lang = Lang,
|
||||
xmlns = ?NS_CLIENT,
|
||||
stream_xmlns = ?NS_STREAM,
|
||||
id = StateData#state.streamid,
|
||||
from = jid:make(Server)}),
|
||||
if StateData#state.xml_socket ->
|
||||
(StateData#state.sockmod):send_xml(StateData#state.socket,
|
||||
{xmlstreamstart, Name, Attrs});
|
||||
true ->
|
||||
send_text(StateData, fxml:element_to_header(Header))
|
||||
end.
|
||||
|
||||
-spec send_trailer(state()) -> ok | {error, any()}.
|
||||
send_trailer(StateData)
|
||||
|
@ -39,6 +39,7 @@
|
||||
remove_connection/2, find_connection/2,
|
||||
dirty_get_connections/0, allow_host/2,
|
||||
incoming_s2s_number/0, outgoing_s2s_number/0,
|
||||
stop_all_connections/0,
|
||||
clean_temporarily_blocked_table/0,
|
||||
list_temporarily_blocked_hosts/0,
|
||||
external_host_overloaded/1, is_temporarly_blocked/1,
|
||||
@ -480,7 +481,13 @@ get_commands_spec() ->
|
||||
"the node",
|
||||
policy = admin,
|
||||
module = ?MODULE, function = outgoing_s2s_number,
|
||||
args = [], result = {s2s_outgoing, integer}}].
|
||||
args = [], result = {s2s_outgoing, integer}},
|
||||
#ejabberd_commands{name = stop_all_connections,
|
||||
tags = [s2s],
|
||||
desc = "Stop all outgoing and incoming connections",
|
||||
policy = admin,
|
||||
module = ?MODULE, function = stop_all_connections,
|
||||
args = [], result = {res, rescode}}].
|
||||
|
||||
incoming_s2s_number() ->
|
||||
length(supervisor:which_children(ejabberd_s2s_in_sup)).
|
||||
@ -488,6 +495,15 @@ incoming_s2s_number() ->
|
||||
outgoing_s2s_number() ->
|
||||
length(supervisor:which_children(ejabberd_s2s_out_sup)).
|
||||
|
||||
stop_all_connections() ->
|
||||
lists:foreach(
|
||||
fun({_Id, Pid, _Type, _Module}) ->
|
||||
exit(Pid, kill)
|
||||
end,
|
||||
supervisor:which_children(ejabberd_s2s_in_sup) ++
|
||||
supervisor:which_children(ejabberd_s2s_out_sup)),
|
||||
mnesia:clear_table(s2s).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Update Mnesia tables
|
||||
|
||||
|
@ -168,21 +168,26 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
||||
try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of
|
||||
#stream_start{xmlns = NS_SERVER, stream_xmlns = NS_STREAM}
|
||||
when NS_SERVER /= ?NS_SERVER; NS_STREAM /= ?NS_STREAM ->
|
||||
send_header(StateData, <<" version='1.0'">>),
|
||||
send_header(StateData, {1,0}),
|
||||
send_element(StateData, xmpp:serr_invalid_namespace()),
|
||||
{stop, normal, StateData};
|
||||
#stream_start{to = #jid{lserver = Server},
|
||||
from = #jid{lserver = From},
|
||||
version = <<"1.0">>}
|
||||
from = From, version = {1,0}}
|
||||
when StateData#state.tls and not StateData#state.authenticated ->
|
||||
send_header(StateData, <<" version='1.0'">>),
|
||||
send_header(StateData, {1,0}),
|
||||
Auth = if StateData#state.tls_enabled ->
|
||||
{Result, Message} =
|
||||
ejabberd_s2s:check_peer_certificate(
|
||||
StateData#state.sockmod,
|
||||
StateData#state.socket,
|
||||
From),
|
||||
{Result, From, Message};
|
||||
case From of
|
||||
#jid{} ->
|
||||
{Result, Message} =
|
||||
ejabberd_s2s:check_peer_certificate(
|
||||
StateData#state.sockmod,
|
||||
StateData#state.socket,
|
||||
From#jid.lserver),
|
||||
{Result, From#jid.lserver, Message};
|
||||
undefined ->
|
||||
{error, <<"(unknown)">>,
|
||||
<<"Got no valid 'from' attribute">>}
|
||||
end;
|
||||
true ->
|
||||
{no_verify, <<"(unknown)">>, <<"TLS not (yet) enabled">>}
|
||||
end,
|
||||
@ -225,8 +230,8 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
||||
NewStateData#state{server = Server}}
|
||||
end;
|
||||
#stream_start{to = #jid{lserver = Server},
|
||||
version = <<"1.0">>} when StateData#state.authenticated ->
|
||||
send_header(StateData, <<" version='1.0'">>),
|
||||
version = {1,0}} when StateData#state.authenticated ->
|
||||
send_header(StateData, {1,0}),
|
||||
send_element(StateData,
|
||||
#stream_features{
|
||||
sub_els = ejabberd_hooks:run_fold(
|
||||
@ -236,24 +241,28 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
||||
#stream_start{db_xmlns = ?NS_SERVER_DIALBACK}
|
||||
when (StateData#state.tls_required and StateData#state.tls_enabled)
|
||||
or (not StateData#state.tls_required) ->
|
||||
send_header(StateData, <<"">>),
|
||||
send_header(StateData, undefined),
|
||||
{next_state, stream_established, StateData};
|
||||
#stream_start{} ->
|
||||
send_header(StateData, <<" version='1.0'">>),
|
||||
send_header(StateData, {1,0}),
|
||||
send_element(StateData, xmpp:serr_undefined_condition()),
|
||||
{stop, normal, StateData}
|
||||
{stop, normal, StateData};
|
||||
_ ->
|
||||
send_header(StateData, {1,0}),
|
||||
send_element(StateData, xmpp:serr_invalid_xml()),
|
||||
{stop, normal, StateData}
|
||||
catch _:{xmpp_codec, Why} ->
|
||||
Txt = xmpp:format_error(Why),
|
||||
send_header(StateData, <<" version='1.0'">>),
|
||||
send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)),
|
||||
send_header(StateData, {1,0}),
|
||||
send_element(StateData, xmpp:serr_invalid_xml(Txt, ?MYLANG)),
|
||||
{stop, normal, StateData}
|
||||
end;
|
||||
wait_for_stream({xmlstreamerror, _}, StateData) ->
|
||||
send_header(StateData, <<"">>),
|
||||
send_header(StateData, {1,0}),
|
||||
send_element(StateData, xmpp:serr_not_well_formed()),
|
||||
{stop, normal, StateData};
|
||||
wait_for_stream(timeout, StateData) ->
|
||||
send_header(StateData, <<"">>),
|
||||
send_header(StateData, {1,0}),
|
||||
send_element(StateData, xmpp:serr_connection_timeout()),
|
||||
{stop, normal, StateData};
|
||||
wait_for_stream(closed, StateData) ->
|
||||
@ -277,13 +286,21 @@ wait_for_feature_request(#starttls{},
|
||||
StateData#state.tls_options,
|
||||
{certfile, CertFile})
|
||||
end,
|
||||
TLSOpts2 = case ejabberd_config:get_option(
|
||||
{s2s_cafile, StateData#state.server},
|
||||
fun iolist_to_binary/1) of
|
||||
undefined -> TLSOpts1;
|
||||
CAFile ->
|
||||
lists:keystore(cafile, 1, TLSOpts1,
|
||||
{cafile, CAFile})
|
||||
end,
|
||||
TLSOpts = case ejabberd_config:get_option(
|
||||
{s2s_tls_compression, StateData#state.server},
|
||||
fun(true) -> true;
|
||||
(false) -> false
|
||||
end, false) of
|
||||
true -> lists:delete(compression_none, TLSOpts1);
|
||||
false -> [compression_none | TLSOpts1]
|
||||
true -> lists:delete(compression_none, TLSOpts2);
|
||||
false -> [compression_none | TLSOpts2]
|
||||
end,
|
||||
TLSSocket = (StateData#state.sockmod):starttls(
|
||||
Socket, TLSOpts,
|
||||
@ -293,8 +310,7 @@ wait_for_feature_request(#starttls{},
|
||||
StateData#state{socket = TLSSocket, streamid = new_id(),
|
||||
tls_enabled = true, tls_options = TLSOpts}};
|
||||
_ ->
|
||||
Txt = <<"Unsupported TLS transport">>,
|
||||
send_element(StateData, xmpp:serr_policy_violation(Txt, ?MYLANG)),
|
||||
send_element(StateData, #starttls_failure{}),
|
||||
{stop, normal, StateData}
|
||||
end;
|
||||
wait_for_feature_request(#sasl_auth{mechanism = Mech},
|
||||
@ -313,7 +329,10 @@ wait_for_feature_request(#sasl_auth{mechanism = Mech},
|
||||
StateData#state{streamid = new_id(),
|
||||
authenticated = true}};
|
||||
true ->
|
||||
send_element(StateData, #sasl_failure{}),
|
||||
Txt = xmpp:mk_text(<<"Denied by ACL">>, ?MYLANG),
|
||||
send_element(StateData,
|
||||
#sasl_failure{reason = 'not-authorized',
|
||||
text = Txt}),
|
||||
{stop, normal, StateData}
|
||||
end;
|
||||
_ ->
|
||||
@ -495,7 +514,7 @@ handle_info({send_text, Text}, StateName, StateData) ->
|
||||
handle_info({timeout, Timer, _}, StateName,
|
||||
#state{timer = Timer} = StateData) ->
|
||||
if StateName == wait_for_stream ->
|
||||
send_header(StateData, <<"">>);
|
||||
send_header(StateData, undefined);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
@ -555,15 +574,15 @@ send_error(StateData, Stanza, Error) ->
|
||||
send_trailer(StateData) ->
|
||||
send_text(StateData, <<"</stream:stream>">>).
|
||||
|
||||
-spec send_header(state(), binary()) -> ok.
|
||||
-spec send_header(state(), undefined | {integer(), integer()}) -> ok.
|
||||
send_header(StateData, Version) ->
|
||||
send_text(StateData,
|
||||
<<"<?xml version='1.0'?><stream:stream "
|
||||
"xmlns:stream='http://etherx.jabber.org/stream"
|
||||
"s' xmlns='jabber:server' xmlns:db='jabber:ser"
|
||||
"ver:dialback' id='",
|
||||
(StateData#state.streamid)/binary, "'", Version/binary,
|
||||
">">>).
|
||||
Header = xmpp:encode(
|
||||
#stream_start{xmlns = ?NS_SERVER,
|
||||
stream_xmlns = ?NS_STREAM,
|
||||
db_xmlns = ?NS_SERVER_DIALBACK,
|
||||
id = StateData#state.streamid,
|
||||
version = Version}),
|
||||
send_text(StateData, fxml:element_to_header(Header)).
|
||||
|
||||
-spec change_shaper(state(), binary(), jid()) -> ok.
|
||||
change_shaper(StateData, Host, JID) ->
|
||||
@ -606,9 +625,14 @@ fsm_limit_opts(Opts) ->
|
||||
end
|
||||
end.
|
||||
|
||||
-spec decode_element(xmlel(), state_name(), state()) -> fsm_transition().
|
||||
-spec decode_element(xmlel() | xmpp_element(), state_name(), state()) -> fsm_transition().
|
||||
decode_element(#xmlel{} = El, StateName, StateData) ->
|
||||
try xmpp:decode(El) of
|
||||
Opts = if StateName == stream_established ->
|
||||
[ignore_els];
|
||||
true ->
|
||||
[]
|
||||
end,
|
||||
try xmpp:decode(El, Opts) of
|
||||
Pkt -> ?MODULE:StateName(Pkt, StateData)
|
||||
catch error:{xmpp_codec, Why} ->
|
||||
case xmpp:is_stanza(El) of
|
||||
@ -620,12 +644,15 @@ decode_element(#xmlel{} = El, StateName, StateData) ->
|
||||
ok
|
||||
end,
|
||||
{next_state, StateName, StateData}
|
||||
end.
|
||||
end;
|
||||
decode_element(Pkt, StateName, StateData) ->
|
||||
?MODULE:StateName(Pkt, StateData).
|
||||
|
||||
opt_type(domain_certfile) -> fun iolist_to_binary/1;
|
||||
opt_type(max_fsm_queue) ->
|
||||
fun (I) when is_integer(I), I > 0 -> I end;
|
||||
opt_type(s2s_certfile) -> fun iolist_to_binary/1;
|
||||
opt_type(s2s_cafile) -> fun iolist_to_binary/1;
|
||||
opt_type(s2s_ciphers) -> fun iolist_to_binary/1;
|
||||
opt_type(s2s_dhfile) -> fun iolist_to_binary/1;
|
||||
opt_type(s2s_protocol_options) ->
|
||||
@ -647,6 +674,6 @@ opt_type(s2s_use_starttls) ->
|
||||
(required_trusted) -> required_trusted
|
||||
end;
|
||||
opt_type(_) ->
|
||||
[domain_certfile, max_fsm_queue, s2s_certfile,
|
||||
[domain_certfile, max_fsm_queue, s2s_certfile, s2s_cafile,
|
||||
s2s_ciphers, s2s_dhfile, s2s_protocol_options,
|
||||
s2s_tls_compression, s2s_use_starttls].
|
||||
|
@ -106,12 +106,6 @@
|
||||
%% Specified in miliseconds. Default value is 5 minutes.
|
||||
-define(MAX_RETRY_DELAY, 300000).
|
||||
|
||||
-define(STREAM_HEADER,
|
||||
<<"<?xml version='1.0'?><stream:stream "
|
||||
"xmlns:stream='http://etherx.jabber.org/stream"
|
||||
"s' xmlns='jabber:server' xmlns:db='jabber:ser"
|
||||
"ver:dialback' from='~s' to='~s'~s>">>).
|
||||
|
||||
-define(SOCKET_DEFAULT_RESULT, {error, badarg}).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@ -228,9 +222,8 @@ open_socket(init, StateData) ->
|
||||
?SOCKET_DEFAULT_RESULT, AddrList)
|
||||
of
|
||||
{ok, Socket} ->
|
||||
Version = if StateData#state.use_v10 ->
|
||||
<<" version='1.0'">>;
|
||||
true -> <<"">>
|
||||
Version = if StateData#state.use_v10 -> {1,0};
|
||||
true -> undefined
|
||||
end,
|
||||
NewStateData = StateData#state{socket = Socket,
|
||||
tls_enabled = false,
|
||||
@ -318,11 +311,10 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData0) ->
|
||||
{stop, normal, StateData};
|
||||
#stream_start{xmlns = NS_SERVER, stream_xmlns = NS_STREAM}
|
||||
when NS_SERVER /= ?NS_SERVER; NS_STREAM /= ?NS_STREAM ->
|
||||
send_header(StateData, <<" version='1.0'">>),
|
||||
send_element(StateData, xmpp:serr_invalid_namespace()),
|
||||
{stop, normal, StateData};
|
||||
#stream_start{db_xmlns = ?NS_SERVER_DIALBACK, id = ID,
|
||||
version = V} when V /= <<"1.0">> ->
|
||||
version = V} when V /= {1,0} ->
|
||||
send_db_request(StateData#state{remote_streamid = ID});
|
||||
#stream_start{db_xmlns = ?NS_SERVER_DIALBACK, id = ID}
|
||||
when StateData#state.use_v10 ->
|
||||
@ -337,13 +329,14 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData0) ->
|
||||
StateData#state{db_enabled = false, remote_streamid = ID},
|
||||
?FSMTIMEOUT};
|
||||
#stream_start{} ->
|
||||
send_header(StateData, <<"">>),
|
||||
send_element(StateData, xmpp:serr_invalid_namespace()),
|
||||
{stop, normal, StateData}
|
||||
{stop, normal, StateData};
|
||||
_ ->
|
||||
send_element(StateData, xmpp:serr_invalid_xml()),
|
||||
{stop, normal, StateData}
|
||||
catch _:{xmpp_codec, Why} ->
|
||||
Txt = xmpp:format_error(Why),
|
||||
send_header(StateData, <<" version='1.0'">>),
|
||||
send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)),
|
||||
send_element(StateData, xmpp:serr_invalid_xml(Txt, ?MYLANG)),
|
||||
{stop, normal, StateData}
|
||||
end;
|
||||
wait_for_stream(Event, StateData) ->
|
||||
@ -469,7 +462,7 @@ wait_for_auth_result({xmlstreamelement, El}, StateData) ->
|
||||
wait_for_auth_result(#sasl_success{}, StateData) ->
|
||||
?DEBUG("auth: ~p", [{StateData#state.myname, StateData#state.server}]),
|
||||
ejabberd_socket:reset_stream(StateData#state.socket),
|
||||
send_header(StateData, <<" version='1.0'">>),
|
||||
send_header(StateData, {1,0}),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{streamid = new_id(), authenticated = true},
|
||||
?FSMTIMEOUT};
|
||||
@ -500,7 +493,7 @@ wait_for_starttls_proceed(#starttls_proceed{}, StateData) ->
|
||||
streamid = new_id(),
|
||||
tls_enabled = true,
|
||||
tls_options = TLSOpts},
|
||||
send_header(NewStateData, <<" version='1.0'">>),
|
||||
send_header(NewStateData, {1,0}),
|
||||
{next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT};
|
||||
wait_for_starttls_proceed(Event, StateData) ->
|
||||
handle_unexpected_event(Event, wait_for_starttls_proceed, StateData).
|
||||
@ -567,7 +560,8 @@ handle_unexpected_event(Event, StateName, StateData) ->
|
||||
{xmlstreamend, _} ->
|
||||
?INFO_MSG("Closing s2s connection ~s -> ~s in state ~s: "
|
||||
"XML stream closed by peer",
|
||||
[StateData#state.myname, StateData#state.server]),
|
||||
[StateData#state.myname, StateData#state.server,
|
||||
StateName]),
|
||||
{stop, normal, StateData};
|
||||
timeout ->
|
||||
send_element(StateData, xmpp:serr_connection_timeout()),
|
||||
@ -741,6 +735,7 @@ print_state(State) -> State.
|
||||
|
||||
-spec send_text(state(), iodata()) -> ok.
|
||||
send_text(StateData, Text) ->
|
||||
?DEBUG("Send Text on stream = ~s", [Text]),
|
||||
ejabberd_socket:send(StateData#state.socket, Text).
|
||||
|
||||
-spec send_element(state(), xmpp_element()) -> ok.
|
||||
@ -748,15 +743,16 @@ send_element(StateData, El) ->
|
||||
El1 = fix_ns(xmpp:encode(El)),
|
||||
send_text(StateData, fxml:element_to_binary(El1)).
|
||||
|
||||
-spec send_header(state(), binary()) -> ok.
|
||||
-spec send_header(state(), undefined | {integer(), integer()}) -> ok.
|
||||
send_header(StateData, Version) ->
|
||||
Txt = io_lib:format(
|
||||
"<?xml version='1.0'?><stream:stream "
|
||||
"xmlns:stream='http://etherx.jabber.org/stream"
|
||||
"s' xmlns='jabber:server' xmlns:db='jabber:ser"
|
||||
"ver:dialback' from='~s' to='~s'~s>",
|
||||
[StateData#state.myname, StateData#state.server, Version]),
|
||||
send_text(StateData, Txt).
|
||||
Header = xmpp:encode(
|
||||
#stream_start{xmlns = ?NS_SERVER,
|
||||
stream_xmlns = ?NS_STREAM,
|
||||
db_xmlns = ?NS_SERVER_DIALBACK,
|
||||
from = jid:make(StateData#state.myname),
|
||||
to = jid:make(StateData#state.server),
|
||||
version = Version}),
|
||||
send_text(StateData, fxml:element_to_header(Header)).
|
||||
|
||||
-spec send_trailer(state()) -> ok.
|
||||
send_trailer(StateData) ->
|
||||
|
@ -149,6 +149,10 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
||||
#stream_start{} ->
|
||||
send_header(StateData, ?MYNAME),
|
||||
send_element(StateData, xmpp:serr_improper_addressing()),
|
||||
{stop, normal, StateData};
|
||||
_ ->
|
||||
send_header(StateData, ?MYNAME),
|
||||
send_element(StateData, xmpp:serr_invalid_xml()),
|
||||
{stop, normal, StateData}
|
||||
catch _:{xmpp_codec, Why} ->
|
||||
Txt = xmpp:format_error(Why),
|
||||
@ -319,13 +323,12 @@ send_error(StateData, Stanza, Error) ->
|
||||
|
||||
-spec send_header(state(), binary()) -> ok.
|
||||
send_header(StateData, Host) ->
|
||||
send_text(StateData,
|
||||
io_lib:format(
|
||||
<<"<?xml version='1.0'?><stream:stream "
|
||||
"xmlns:stream='http://etherx.jabber.org/stream"
|
||||
"s' xmlns='jabber:component:accept' id='~s' "
|
||||
"from='~s'>">>,
|
||||
[StateData#state.streamid, fxml:crypt(Host)])).
|
||||
Header = xmpp:encode(
|
||||
#stream_start{xmlns = ?NS_COMPONENT,
|
||||
stream_xmlns = ?NS_STREAM,
|
||||
from = jid:make(Host),
|
||||
id = StateData#state.streamid}),
|
||||
send_text(StateData, fxml:element_to_header(Header)).
|
||||
|
||||
-spec send_trailer(state()) -> ok.
|
||||
send_trailer(StateData) ->
|
||||
|
@ -3955,6 +3955,14 @@ pp(upload_slot, 3) -> [get, put, xmlns];
|
||||
pp(thumbnail, 4) -> [uri, 'media-type', width, height];
|
||||
pp(_, _) -> no.
|
||||
|
||||
enc_version({Maj, Min}) ->
|
||||
<<(integer_to_binary(Maj))/binary, $.,
|
||||
(integer_to_binary(Min))/binary>>.
|
||||
|
||||
dec_version(S) ->
|
||||
[Major, Minor] = binary:split(S, <<$.>>),
|
||||
{binary_to_integer(Major), binary_to_integer(Minor)}.
|
||||
|
||||
enc_host_port(Host) when is_binary(Host) -> Host;
|
||||
enc_host_port({{_, _, _, _, _, _, _, _} = IPv6,
|
||||
Port}) ->
|
||||
@ -5284,13 +5292,20 @@ encode_stream_start_attr_xmlns(_val, _acc) ->
|
||||
|
||||
decode_stream_start_attr_version(__TopXMLNS,
|
||||
undefined) ->
|
||||
<<>>;
|
||||
undefined;
|
||||
decode_stream_start_attr_version(__TopXMLNS, _val) ->
|
||||
_val.
|
||||
case catch dec_version(_val) of
|
||||
{'EXIT', _} ->
|
||||
erlang:error({xmpp_codec,
|
||||
{bad_attr_value, <<"version">>, <<"stream:stream">>,
|
||||
__TopXMLNS}});
|
||||
_res -> _res
|
||||
end.
|
||||
|
||||
encode_stream_start_attr_version(<<>>, _acc) -> _acc;
|
||||
encode_stream_start_attr_version(undefined, _acc) ->
|
||||
_acc;
|
||||
encode_stream_start_attr_version(_val, _acc) ->
|
||||
[{<<"version">>, _val} | _acc].
|
||||
[{<<"version">>, enc_version(_val)} | _acc].
|
||||
|
||||
decode_stream_start_attr_id(__TopXMLNS, undefined) ->
|
||||
<<>>;
|
||||
|
@ -20,13 +20,13 @@
|
||||
make_iq_result/1, start_event_relay/0,
|
||||
stop_event_relay/1, put_event/2, get_event/1,
|
||||
bind/1, auth/1, auth/2, open_session/1, open_session/2,
|
||||
zlib/1, starttls/1, close_socket/1, init_stream/1,
|
||||
auth_legacy/2, auth_legacy/3]).
|
||||
zlib/1, starttls/1, starttls/2, close_socket/1, init_stream/1,
|
||||
auth_legacy/2, auth_legacy/3, tcp_connect/1, send_text/2]).
|
||||
|
||||
-include("suite.hrl").
|
||||
|
||||
suite() ->
|
||||
[{timetrap, {seconds,10}}].
|
||||
[{timetrap, {seconds,30}}].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
NewConfig = init_config(Config),
|
||||
@ -36,6 +36,10 @@ init_per_suite(Config) ->
|
||||
LDIFFile = filename:join([DataDir, "ejabberd.ldif"]),
|
||||
{ok, _} = file:copy(ExtAuthScript, filename:join([CWD, "extauth.py"])),
|
||||
{ok, _} = ldap_srv:start(LDIFFile),
|
||||
inet_db:add_host({127,0,0,1}, [binary_to_list(?S2S_VHOST),
|
||||
binary_to_list(?MNESIA_VHOST)]),
|
||||
inet_db:set_domain(binary_to_list(randoms:get_string())),
|
||||
inet_db:set_lookup([file, native]),
|
||||
start_ejabberd(NewConfig),
|
||||
NewConfig.
|
||||
|
||||
@ -125,6 +129,16 @@ do_init_per_group(riak, Config) ->
|
||||
Err ->
|
||||
{skip, {riak_not_available, Err}}
|
||||
end;
|
||||
do_init_per_group(s2s, Config) ->
|
||||
ejabberd_config:add_option(s2s_use_starttls, required_trusted),
|
||||
ejabberd_config:add_option(domain_certfile, "cert.pem"),
|
||||
Port = ?config(s2s_port, Config),
|
||||
set_opt(server, ?COMMON_VHOST,
|
||||
set_opt(xmlns, ?NS_SERVER,
|
||||
set_opt(type, server,
|
||||
set_opt(server_port, Port,
|
||||
set_opt(stream_from, ?S2S_VHOST,
|
||||
set_opt(lang, <<"">>, Config))))));
|
||||
do_init_per_group(component, Config) ->
|
||||
Server = ?config(server, Config),
|
||||
Port = ?config(component_port, Config),
|
||||
@ -132,7 +146,7 @@ do_init_per_group(component, Config) ->
|
||||
set_opt(server, <<"component.", Server/binary>>,
|
||||
set_opt(type, component,
|
||||
set_opt(server_port, Port,
|
||||
set_opt(stream_version, <<"">>,
|
||||
set_opt(stream_version, undefined,
|
||||
set_opt(lang, <<"">>, Config))))));
|
||||
do_init_per_group(_GroupName, Config) ->
|
||||
Pid = start_event_relay(),
|
||||
@ -158,6 +172,8 @@ end_per_group(riak, _Config) ->
|
||||
ok;
|
||||
end_per_group(component, _Config) ->
|
||||
ok;
|
||||
end_per_group(s2s, _Config) ->
|
||||
ejabberd_config:add_option(s2s_use_starttls, false);
|
||||
end_per_group(_GroupName, Config) ->
|
||||
stop_event_relay(Config),
|
||||
ok.
|
||||
@ -215,7 +231,7 @@ init_per_testcase(TestCase, OrigConfig) ->
|
||||
"test_connect" ++ _ ->
|
||||
Config;
|
||||
"test_legacy_auth" ++ _ ->
|
||||
init_stream(set_opt(stream_version, <<"">>, Config));
|
||||
init_stream(set_opt(stream_version, undefined, Config));
|
||||
"test_auth" ++ _ ->
|
||||
connect(Config);
|
||||
"test_starttls" ++ _ ->
|
||||
@ -244,6 +260,8 @@ init_per_testcase(TestCase, OrigConfig) ->
|
||||
Password = ?config(password, Config),
|
||||
ejabberd_auth:try_register(User, Server, Password),
|
||||
open_session(bind(auth(connect(Config))));
|
||||
_ when TestGroup == s2s_tests ->
|
||||
auth(connect(starttls(connect(Config))));
|
||||
_ ->
|
||||
open_session(bind(auth(connect(Config))))
|
||||
end.
|
||||
@ -262,6 +280,7 @@ legacy_auth_tests() ->
|
||||
no_db_tests() ->
|
||||
[{generic, [parallel],
|
||||
[test_connect_bad_xml,
|
||||
test_connect_unexpected_xml,
|
||||
test_connect_unknown_ns,
|
||||
test_connect_bad_xmlns,
|
||||
test_connect_bad_ns_stream,
|
||||
@ -286,7 +305,12 @@ no_db_tests() ->
|
||||
time,
|
||||
stats,
|
||||
disco]},
|
||||
{presence, [sequence], [presence]},
|
||||
{presence_and_s2s, [sequence],
|
||||
[presence,
|
||||
s2s_dialback,
|
||||
s2s_optional,
|
||||
s2s_required,
|
||||
s2s_required_trusted]},
|
||||
{sm, [sequence],
|
||||
[sm,
|
||||
sm_resume,
|
||||
@ -433,18 +457,39 @@ extauth_tests() ->
|
||||
test_unregister]}].
|
||||
|
||||
component_tests() ->
|
||||
[{component_tests, [sequence],
|
||||
[{component_connect, [parallel],
|
||||
[test_connect_bad_xml,
|
||||
test_connect_unexpected_xml,
|
||||
test_connect_unknown_ns,
|
||||
test_connect_bad_xmlns,
|
||||
test_connect_bad_ns_stream,
|
||||
test_connect_missing_to,
|
||||
test_connect,
|
||||
test_auth,
|
||||
test_auth_fail,
|
||||
component_missing_address,
|
||||
component_invalid_from,
|
||||
component_send,
|
||||
test_auth_fail]},
|
||||
{component_tests, [sequence],
|
||||
[test_missing_address,
|
||||
test_invalid_from,
|
||||
test_component_send,
|
||||
bad_nonza,
|
||||
codec_failure]}].
|
||||
|
||||
s2s_tests() ->
|
||||
[{s2s_connect, [parallel],
|
||||
[test_connect_bad_xml,
|
||||
test_connect_unexpected_xml,
|
||||
test_connect_unknown_ns,
|
||||
test_connect_bad_xmlns,
|
||||
test_connect_bad_ns_stream,
|
||||
test_connect,
|
||||
test_connect_s2s_starttls_required,
|
||||
test_starttls,
|
||||
test_connect_missing_from,
|
||||
test_connect_s2s_unauthenticated_iq,
|
||||
test_auth_starttls]},
|
||||
{s2s_tests, [sequence],
|
||||
[test_missing_address,
|
||||
test_invalid_from,
|
||||
bad_nonza,
|
||||
codec_failure]}].
|
||||
|
||||
@ -453,6 +498,7 @@ groups() ->
|
||||
{extauth, [sequence], extauth_tests()},
|
||||
{no_db, [sequence], no_db_tests()},
|
||||
{component, [sequence], component_tests()},
|
||||
{s2s, [sequence], s2s_tests()},
|
||||
{mnesia, [sequence], db_tests(mnesia)},
|
||||
{redis, [sequence], db_tests(redis)},
|
||||
{mysql, [sequence], db_tests(mysql)},
|
||||
@ -461,16 +507,17 @@ groups() ->
|
||||
{riak, [sequence], db_tests(riak)}].
|
||||
|
||||
all() ->
|
||||
[{group, component},
|
||||
%%{group, ldap},
|
||||
[{group, ldap},
|
||||
{group, no_db},
|
||||
{group, mnesia},
|
||||
%%{group, redis},
|
||||
%%{group, mysql},
|
||||
%%{group, pgsql},
|
||||
%%{group, sqlite},
|
||||
%%{group, extauth},
|
||||
%%{group, riak},
|
||||
{group, redis},
|
||||
{group, mysql},
|
||||
{group, pgsql},
|
||||
{group, sqlite},
|
||||
{group, extauth},
|
||||
{group, riak},
|
||||
{group, component},
|
||||
{group, s2s},
|
||||
stop_ejabberd].
|
||||
|
||||
stop_ejabberd(Config) ->
|
||||
@ -480,11 +527,23 @@ stop_ejabberd(Config) ->
|
||||
Config.
|
||||
|
||||
test_connect_bad_xml(Config) ->
|
||||
Config0 = init_stream(set_opt(xmlns, <<"'">>, Config)),
|
||||
Config0 = tcp_connect(Config),
|
||||
send_text(Config0, <<"<'/>">>),
|
||||
Version = ?config(stream_version, Config0),
|
||||
?recv1(#stream_start{version = Version}),
|
||||
?recv1(#stream_error{reason = 'not-well-formed'}),
|
||||
?recv1({xmlstreamend, <<"stream:stream">>}),
|
||||
close_socket(Config0).
|
||||
|
||||
test_connect_unexpected_xml(Config) ->
|
||||
Config0 = tcp_connect(Config),
|
||||
send(Config0, #caps{}),
|
||||
Version = ?config(stream_version, Config0),
|
||||
?recv1(#stream_start{version = Version}),
|
||||
?recv1(#stream_error{reason = 'invalid-xml'}),
|
||||
?recv1({xmlstreamend, <<"stream:stream">>}),
|
||||
close_socket(Config0).
|
||||
|
||||
test_connect_unknown_ns(Config) ->
|
||||
Config0 = init_stream(set_opt(xmlns, <<"wrong">>, Config)),
|
||||
?recv1(#stream_error{reason = 'invalid-xml'}),
|
||||
@ -492,7 +551,11 @@ test_connect_unknown_ns(Config) ->
|
||||
close_socket(Config0).
|
||||
|
||||
test_connect_bad_xmlns(Config) ->
|
||||
Config0 = init_stream(set_opt(xmlns, ?NS_SERVER, Config)),
|
||||
NS = case ?config(type, Config) of
|
||||
client -> ?NS_SERVER;
|
||||
_ -> ?NS_CLIENT
|
||||
end,
|
||||
Config0 = init_stream(set_opt(xmlns, NS, Config)),
|
||||
?recv1(#stream_error{reason = 'invalid-namespace'}),
|
||||
?recv1({xmlstreamend, <<"stream:stream">>}),
|
||||
close_socket(Config0).
|
||||
@ -521,19 +584,32 @@ test_connect_missing_to(Config) ->
|
||||
?recv1({xmlstreamend, <<"stream:stream">>}),
|
||||
close_socket(Config0).
|
||||
|
||||
test_connect_missing_from(Config) ->
|
||||
Config1 = starttls(connect(Config)),
|
||||
Config2 = set_opt(stream_from, <<"">>, Config1),
|
||||
Config3 = init_stream(Config2),
|
||||
?recv1(#stream_error{reason = 'policy-violation'}),
|
||||
?recv1({xmlstreamend, <<"stream:stream">>}),
|
||||
close_socket(Config3).
|
||||
|
||||
test_connect(Config) ->
|
||||
disconnect(connect(Config)).
|
||||
|
||||
test_component_connect(Config) ->
|
||||
disconnect(component_connect(Config)).
|
||||
test_connect_s2s_starttls_required(Config) ->
|
||||
Config1 = connect(Config),
|
||||
send(Config1, #caps{}),
|
||||
?recv1(#stream_error{reason = 'policy-violation'}),
|
||||
?recv1({xmlstreamend, <<"stream:stream">>}),
|
||||
close_socket(Config1).
|
||||
|
||||
component_connect(Config) ->
|
||||
init_stream(Config).
|
||||
test_connect_s2s_unauthenticated_iq(Config) ->
|
||||
Config1 = connect(starttls(connect(Config))),
|
||||
unauthenticated_iq(Config1).
|
||||
|
||||
test_starttls(Config) ->
|
||||
case ?config(starttls, Config) of
|
||||
true ->
|
||||
disconnect(starttls(Config));
|
||||
disconnect(connect(starttls(Config)));
|
||||
_ ->
|
||||
{skipped, 'starttls_not_available'}
|
||||
end.
|
||||
@ -597,8 +673,11 @@ unauthenticated_stanza(Config) ->
|
||||
disconnect(Config).
|
||||
|
||||
unauthenticated_iq(Config) ->
|
||||
From = my_jid(Config),
|
||||
To = server_jid(Config),
|
||||
#iq{type = error} =
|
||||
send_recv(Config, #iq{type = get, sub_els = [#disco_info{}]}),
|
||||
send_recv(Config, #iq{type = get, from = From, to = To,
|
||||
sub_els = [#disco_info{}]}),
|
||||
disconnect(Config).
|
||||
|
||||
bad_nonza(Config) ->
|
||||
@ -613,23 +692,57 @@ invalid_from(Config) ->
|
||||
?recv1({xmlstreamend, <<"stream:stream">>}),
|
||||
close_socket(Config).
|
||||
|
||||
component_missing_address(Config) ->
|
||||
test_missing_address(Config) ->
|
||||
Server = server_jid(Config),
|
||||
#iq{type = error} = send_recv(Config, #iq{type = get, from = Server}),
|
||||
#iq{type = error} = send_recv(Config, #iq{type = get, to = Server}),
|
||||
disconnect(Config).
|
||||
|
||||
component_invalid_from(Config) ->
|
||||
test_invalid_from(Config) ->
|
||||
From = jid:make(randoms:get_string()),
|
||||
To = jid:make(randoms:get_string()),
|
||||
#iq{type = error} =
|
||||
send_recv(Config, #iq{type = get, from = From, to = To}),
|
||||
disconnect(Config).
|
||||
|
||||
component_send(Config) ->
|
||||
JID = my_jid(Config),
|
||||
send(Config, #message{from = JID, to = JID}),
|
||||
#message{from = JID, to = JID} = recv(),
|
||||
test_component_send(Config) ->
|
||||
To = jid:make(?COMMON_VHOST),
|
||||
From = server_jid(Config),
|
||||
#iq{type = result, from = To, to = From} =
|
||||
send_recv(Config, #iq{type = get, to = To, from = From,
|
||||
sub_els = [#ping{}]}),
|
||||
disconnect(Config).
|
||||
|
||||
s2s_dialback(Config) ->
|
||||
ejabberd_s2s:stop_all_connections(),
|
||||
ejabberd_config:add_option(s2s_use_starttls, false),
|
||||
ejabberd_config:add_option(domain_certfile, "self-signed-cert.pem"),
|
||||
s2s_ping(Config).
|
||||
|
||||
s2s_optional(Config) ->
|
||||
ejabberd_s2s:stop_all_connections(),
|
||||
ejabberd_config:add_option(s2s_use_starttls, optional),
|
||||
ejabberd_config:add_option(domain_certfile, "self-signed-cert.pem"),
|
||||
s2s_ping(Config).
|
||||
|
||||
s2s_required(Config) ->
|
||||
ejabberd_s2s:stop_all_connections(),
|
||||
ejabberd_config:add_option(s2s_use_starttls, required),
|
||||
ejabberd_config:add_option(domain_certfile, "self-signed-cert.pem"),
|
||||
s2s_ping(Config).
|
||||
|
||||
s2s_required_trusted(Config) ->
|
||||
ejabberd_s2s:stop_all_connections(),
|
||||
ejabberd_config:add_option(s2s_use_starttls, required),
|
||||
ejabberd_config:add_option(domain_certfile, "cert.pem"),
|
||||
s2s_ping(Config).
|
||||
|
||||
s2s_ping(Config) ->
|
||||
From = my_jid(Config),
|
||||
To = jid:make(?MNESIA_VHOST),
|
||||
ID = randoms:get_string(),
|
||||
ejabberd_s2s:route(From, To, #iq{id = ID, type = get, sub_els = [#ping{}]}),
|
||||
?recv1(#iq{type = result, id = ID, sub_els = []}),
|
||||
disconnect(Config).
|
||||
|
||||
auth_md5(Config) ->
|
||||
@ -674,6 +787,9 @@ test_legacy_auth_fail(Config0) ->
|
||||
test_auth(Config) ->
|
||||
disconnect(auth(Config)).
|
||||
|
||||
test_auth_starttls(Config) ->
|
||||
disconnect(auth(connect(starttls(Config)))).
|
||||
|
||||
test_auth_fail(Config0) ->
|
||||
Config = set_opt(user, <<"wrong">>,
|
||||
set_opt(password, <<"wrong">>, Config0)),
|
||||
@ -1895,7 +2011,6 @@ announce_slave(Config) ->
|
||||
|
||||
flex_offline_master(Config) ->
|
||||
Peer = ?config(slave, Config),
|
||||
ct:log("hooks = ~p", [ets:tab2list(hooks)]),
|
||||
LPeer = jid:remove_resource(Peer),
|
||||
lists:foreach(
|
||||
fun(I) ->
|
||||
|
27
test/ejabberd_SUITE_data/ca.key
Normal file
27
test/ejabberd_SUITE_data/ca.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAxGSSFSDTbBTk2GwkORLCXoBdYq5YxwPfen8bK+8WjxRb9Thp
|
||||
FsHYfImtDQV0qvcZyWnjUFxRh7Dyw7A2X690nplCdzZ9Gl+5yzzlRefHborMSnNY
|
||||
rnTqx3vs9qiac0A5bzdjMY7XN3VuVwz0XWY6rAiL/7OxunCNUnQz+oswDx7cj1W4
|
||||
bb9pFzBvW5TjaAiziyzS3IxvTc7kYQYJEa99vIlDZ+Ov9rHtiF/5CZ8kHc457B3s
|
||||
uc9hHxO2t0EzmBiqg7wpksJjoJeXaJvT9sKSgW6LXkjBCm/7jm1ElPq+7FCph0qp
|
||||
uIsxMtu15exLKQaSRLcc+tyNkWIZGQ371D2+7wIDAQABAoIBACzcNCozV1fm5ecx
|
||||
vIx05oUjmTFDVfAPyGp4wkIk2OhR5Dd9bTPPj53S7P5+coni67cAQvZGQDFYj/t3
|
||||
MtRkhaT8qRwGDEmL+CqefFidewabGdMfye//sOlkO1qUZMNStkvbQQM+95Ypcszb
|
||||
nq3+/gPx59i+uSg3MXDWLlFand217d8oU4JxmCxHc9ezhkpWsdReiAukWTud+q/5
|
||||
DzyPetaP09z8Ua/YNXuI6IdsvObYxOSCI1hPPuMSQGM4hQiqkHPqPNBIJDwfM9wk
|
||||
WzGom5M7nGitrKynJHdS2VRzsZwFL3Hg0yBXnSY1o8er5A6i5//dS2ISSEN9xHjz
|
||||
9PRRCbECgYEA+yVmv8i5uBLuz/Oeu/iOcX9ZNHfNowuIpInWVyfVhURIc1OwP1Sy
|
||||
uj5Qst2IY+Hm4IVq0sNg3cZdEk+K6RMyc/Qgd7GoYeJNKH1v0RbA6E1zEzqm8Xv+
|
||||
jA3dd7RLb5NTwFv11Qh0BDZfw2e8pCmN4oDp+n8fo7RE3NQGaLb77QsCgYEAyDBE
|
||||
FoYVwXhGaKnhDT1AqM3hkOGBqheJJIxkNUnyMhlU/AxmWtfvTtw7MCP+311bz4Ma
|
||||
h6yUfaEiHQJs2wkPyIaZ8CbbVyP7bXWMZzA/Rnk4dQWZ/VjRYvEzIvmz9di3w5j6
|
||||
P1fWX0QODqcY2CvHyMmPLIysbC0cjVDA4ZpDvC0CgYEAlqvrpuevtCV3rL7F3pPS
|
||||
MXlrdTTi5AyJX91qAEPfr+I1bSsqM/SGfYHhPE34A6SFtPGWEvgwZx0YvWGHPynL
|
||||
PRGbYPPuxzrTe5U1vkVeWoAMp96qRXpUToYK9kPudfP3bRI+vB4kLFrKvRrBa+Oa
|
||||
QeeBeE1IGBiQr8NsTOpq3d0CgYB9R+d0iRlYaKL3oUjcdjbe7Wl6uAXjorMLEmks
|
||||
CEjwHXZX/pKXy4dSPPU1nXFF7DEm3o9d1R1gudSVfw0MztD313TDHC4sjLIuwF/L
|
||||
vB/9RKOWaJkEOe9gEj7EZqy+8I+gcz45IglguUBq3xvnPQ7ck3dsk+TcFidGMQFk
|
||||
rpwxSQKBgQDbdzOJagPep0HVJPkOmF1X4idb1rnQUuMi59I3k6lFTXAaypy6nU69
|
||||
aAUgv7UY4i3XglEhbztk/o51W4/fJ1N8UzbXlBur/pJD8GN2h52ea77CbpOAmDSm
|
||||
Bjjoj92wmYGfBRf7DwJQDgqxvpa0s1cwtYjNf0RmbDPzBsfzrKLKbQ==
|
||||
-----END RSA PRIVATE KEY-----
|
22
test/ejabberd_SUITE_data/ca.pem
Normal file
22
test/ejabberd_SUITE_data/ca.pem
Normal file
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDtTCCAp2gAwIBAgIJAKI8WTrCnPXzMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTUwNDE1MTQxNTI0WhcNNDIwODMxMTQxNTI0WjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAxGSSFSDTbBTk2GwkORLCXoBdYq5YxwPfen8bK+8WjxRb9ThpFsHYfImt
|
||||
DQV0qvcZyWnjUFxRh7Dyw7A2X690nplCdzZ9Gl+5yzzlRefHborMSnNYrnTqx3vs
|
||||
9qiac0A5bzdjMY7XN3VuVwz0XWY6rAiL/7OxunCNUnQz+oswDx7cj1W4bb9pFzBv
|
||||
W5TjaAiziyzS3IxvTc7kYQYJEa99vIlDZ+Ov9rHtiF/5CZ8kHc457B3suc9hHxO2
|
||||
t0EzmBiqg7wpksJjoJeXaJvT9sKSgW6LXkjBCm/7jm1ElPq+7FCph0qpuIsxMtu1
|
||||
5exLKQaSRLcc+tyNkWIZGQ371D2+7wIDAQABo4GnMIGkMB0GA1UdDgQWBBTQ9mbL
|
||||
xyIyE3pDyrNMsC36DRHp+TB1BgNVHSMEbjBsgBTQ9mbLxyIyE3pDyrNMsC36DRHp
|
||||
+aFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
|
||||
BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAKI8WTrCnPXzMAwGA1UdEwQF
|
||||
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGyAi//UQaUhy8RLGc33T36Ni6TnRgpz
|
||||
1xu2aahMe0YfPUZsZwwCP6dK+6fSw7OsRqyXZNZJntlur30yMMDlvjXmV6UDzeS4
|
||||
/HGd/hr0LqruYpmvOKmvT/y8VkmBqsGlcaRNhSJGDzMHAVEQ0hzAJe3Emw5R753p
|
||||
iVRbxPqiOVt4U/gjwtrVumSt1v9O4buWo1lTp0jxK1L6K8YWmETLuxyS3IG+i9Ij
|
||||
DDNyU/UxyocP/mcscUAoV9MJX56exwPC93rPxOlwJT5e5ZMRGnwwUt017dPUrKbA
|
||||
u+24S8uJCKN2w0OzsrqzC6lvxOf0JRfNxxxGr1KZYyEGT7ps1jhTebA=
|
||||
-----END CERTIFICATE-----
|
@ -1,52 +1,54 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGbDCCBVSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET
|
||||
MIIEmTCCA4GgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET
|
||||
MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
|
||||
dHkgTHRkMB4XDTE2MDUyNDE3NDIyNVoXDTQzMTAxMDE3NDIyNVowVjELMAkGA1UE
|
||||
dHkgTHRkMB4XDTE2MDkyMzA3MDMyNFoXDTQ0MDIwOTA3MDMyNFowVjELMAkGA1UE
|
||||
BhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdp
|
||||
ZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAxMGYWN0aXZlMIGfMA0GCSqGSIb3DQEBAQUA
|
||||
A4GNADCBiQKBgQC+GTA1D1+yiXgLqUhJXkSj3hj5FiqlBAfJT/8OSXYifY4M4HYv
|
||||
VQrqER2Fs7jdCaeoGWDvwfK/UOV0b1ROnf+T/2bXFs8EOeqjOz4xG2oexNKVrYj9
|
||||
ICYAgmSh6Hf2cZJM/YCAISje93Xl2J2w/N7oFC1ZXasPoBIZv3Fgg7hTtQIDAQAB
|
||||
o4ID2DCCA9QwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l
|
||||
cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFEynWiCoZK4tLDk3KM1wMsbrz9Ug
|
||||
MB8GA1UdIwQYMBaAFND2ZsvHIjITekPKs0ywLfoNEen5MDMGA1UdHwQsMCowKKAm
|
||||
oCSGImh0dHA6Ly9sb2NhbGhvc3Q6NTI4MC9kYXRhL2NybC5kZXIwNgYIKwYBBQUH
|
||||
AQEEKjAoMCYGCCsGAQUFBzABhhpodHRwOi8vbG9jYWxob3N0OjUyODAvb2NzcDAL
|
||||
BgNVHQ8EBAMCBeAwEwYDVR0lBAwwCgYIKwYBBQUHAwkwggLIBgNVHREEggK/MIIC
|
||||
u6A4BggrBgEFBQcIBaAsDCp0ZXN0X3NpbmdsZSEjJCVeKigpYH4rLTtfPVtde318
|
||||
XEBsb2NhbGhvc3SgPwYIKwYBBQUHCAWgMwwxdGVzdF9zaW5nbGUhIyQlXiooKWB+
|
||||
Ky07Xz1bXXt9fFxAbW5lc2lhLmxvY2FsaG9zdKA+BggrBgEFBQcIBaAyDDB0ZXN0
|
||||
X3NpbmdsZSEjJCVeKigpYH4rLTtfPVtde318XEBteXNxbC5sb2NhbGhvc3SgPgYI
|
||||
KwYBBQUHCAWgMgwwdGVzdF9zaW5nbGUhIyQlXiooKWB+Ky07Xz1bXXt9fFxAcGdz
|
||||
cWwubG9jYWxob3N0oD8GCCsGAQUFBwgFoDMMMXRlc3Rfc2luZ2xlISMkJV4qKClg
|
||||
fistO189W117fXxcQHNxbGl0ZS5sb2NhbGhvc3SgQAYIKwYBBQUHCAWgNAwydGVz
|
||||
dF9zaW5nbGUhIyQlXiooKWB+Ky07Xz1bXXt9fFxAZXh0YXV0aC5sb2NhbGhvc3Sg
|
||||
PQYIKwYBBQUHCAWgMQwvdGVzdF9zaW5nbGUhIyQlXiooKWB+Ky07Xz1bXXt9fFxA
|
||||
bGRhcC5sb2NhbGhvc3SgPQYIKwYBBQUHCAWgMQwvdGVzdF9zaW5nbGUhIyQlXioo
|
||||
KWB+Ky07Xz1bXXt9fFxAcDFkYi5sb2NhbGhvc3SgPQYIKwYBBQUHCAWgMQwvdGVz
|
||||
dF9zaW5nbGUhIyQlXiooKWB+Ky07Xz1bXXt9fFxAcmlhay5sb2NhbGhvc3SgPgYI
|
||||
KwYBBQUHCAWgMgwwdGVzdF9zaW5nbGUhIyQlXiooKWB+Ky07Xz1bXXt9fFxAcmVk
|
||||
aXMubG9jYWxob3N0oD4GCCsGAQUFBwgFoDIMMHRlc3Rfc2luZ2xlISMkJV4qKClg
|
||||
fistO189W117fXxcQG1zc3FsLmxvY2FsaG9zdDANBgkqhkiG9w0BAQUFAAOCAQEA
|
||||
et4jpmpwlE+2bw+/iqCt7sfU/5nPmQ8YtgMB+32wf7DINNJgkwOdkYJpzhlMXKrh
|
||||
/bn8+Ybmq6MbK0r2R91Uu858xQf8VKExQm44qaGSyL5Ug3jsAWb3GLZSaWQo37e9
|
||||
QdDeP8XijCEyr3rum19tRIdiImsRAxJqwfaE4pUSgfCEQMkvb+6//8HSf9RRPToD
|
||||
o6eAg8QerEtTfxerEdW/0K1ozOrzSrQembWOu+JjvANRl+p59j+1YOWHzS/yQeZl
|
||||
K3sjFoCvXPvocRnUznvT+TSdy3ORJSjwfEcP5Crim70amZZ6NeMAxfby9wwmmX0x
|
||||
zkwPCSUXliXke6T88Olj7Q==
|
||||
ZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAxMGYWN0aXZlMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAselBnOh089g/VN7gH1m43Vo67kSqh8QRnXZxfjpzt3oP
|
||||
Dl5nd04eNey4ezoSBo7o1hKhj/m5KLxmy1kN+xssyutgzto1FZu8GC2jDyLvByNL
|
||||
h0Z3XLmzdzBzBjosCtllJtzHlVL08SPuuOId5hToiiT8h3ElgNI4L6w+eLzhZIk5
|
||||
Rj1WojGa+pnaTEgoOaZPcNrkOj81o1tgnbLXN7HY3hJKnRp78DmPySq82cRhvfNr
|
||||
ePCs6BJr3y7yYJk0nG+EOaj5BK95YSJondZ8fOZuCigJPMogEaSw0SGsSUiQrPsd
|
||||
+3vZQ+3ctOimnhW7cF3fAM79g+zDdv9N9E3D+inhyQIDAQABo4IBgTCCAX0wCQYD
|
||||
VR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlm
|
||||
aWNhdGUwHQYDVR0OBBYEFJgip1fThIyZu9J+YNz3XKDkOcMKMB8GA1UdIwQYMBaA
|
||||
FND2ZsvHIjITekPKs0ywLfoNEen5MDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9s
|
||||
b2NhbGhvc3Q6NTI4MC9kYXRhL2NybC5kZXIwNgYIKwYBBQUHAQEEKjAoMCYGCCsG
|
||||
AQUFBzABhhpodHRwOi8vbG9jYWxob3N0OjUyODAvb2NzcDALBgNVHQ8EBAMCBeAw
|
||||
JwYDVR0lBCAwHgYIKwYBBQUHAwkGCCsGAQUFBwMBBggrBgEFBQcDAjBfBgNVHREE
|
||||
WDBWoBcGCCsGAQUFBwgFoAsMCWxvY2FsaG9zdKAbBggrBgEFBQcIBaAPDA1zMnMu
|
||||
bG9jYWxob3N0oB4GCCsGAQUFBwgFoBIMEG1uZXNpYS5sb2NhbGhvc3QwDQYJKoZI
|
||||
hvcNAQEFBQADggEBAEwHeECqeEJIz0VFA0OZ0w9+3rfZPX9K59rbJNNnKVATPhk5
|
||||
g5NFpXy1mFTV/3MWjDS1QRbgoXzOYR64S87oez4l3jyDz3YxklyjbbiN3QKaUq5h
|
||||
284Ze6CiRqxIi6V2bhjjp3voMSP8BQ72bX9uAWjqQl7Z16wYuCzV4QzVZRD5p0c1
|
||||
y45WZ6J+sU1GTwEGh0vXZBlDMeTb+53smjEoCxET1ecJmStAvJi+UHiLn63Z3Yzz
|
||||
CTfdAZ/mj+ytaNLVsgrULXrmZAeo064HVqeyLWL8ZBoM0zLs6u14OQOeDCCB62cj
|
||||
UXb9npKmIdfsWvdii6emCVQqKBQmHnlUMCh56tE=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQC+GTA1D1+yiXgLqUhJXkSj3hj5FiqlBAfJT/8OSXYifY4M4HYv
|
||||
VQrqER2Fs7jdCaeoGWDvwfK/UOV0b1ROnf+T/2bXFs8EOeqjOz4xG2oexNKVrYj9
|
||||
ICYAgmSh6Hf2cZJM/YCAISje93Xl2J2w/N7oFC1ZXasPoBIZv3Fgg7hTtQIDAQAB
|
||||
AoGALddtJJ58eVVlOYqs/+RXsRyR8R9DUV/TcNx1qUBV2KNmafyHA4sCgsd10xQv
|
||||
9D2rzIGyOp8OpswfSSC/t+WqB9+ezSruzMuX6IURdHZbX6aWWX6maICtPKEEkCmI
|
||||
gaLxE/ojuOXnTEBTkVuVWtuFL9PsK/WGi/FIDzJbwqTWJ4ECQQDy9DrBAQM96B6u
|
||||
G4XpFzBsfgJZoS+NaMdCwK+/jgcEpI6oxobK8tuGB6drp5jNSuQ905W9n8XjA6Xq
|
||||
x8/GH9I5AkEAyE5g05HhMlxBWCq+P70pBDIamdHJcPQVL8+6NXkT+mTqqZxxkUy4
|
||||
nMfTh5zE6WfmqYNtrmNBDxXUyaoRSBydXQJACnFnCR7DBekxUGiMc/10LmWoMjQU
|
||||
eC6Vyg/APiqbsJ5mJ2kJKDYSK4uurZjxn3lloCa1HAZ/GgfxHMtj6e86OQJAetq3
|
||||
wIwE12KGIZF1xpo6gfxJHHbzWngaVozN5OYyPq2O0CDH9xpbUK2vK8oXbCDx9J5L
|
||||
s13lFV+Kd3X7y4LhcQJBAKSFg7ht33l8Sa0TdUkY6Tl1NBMCCLf+np+HYrAbQZux
|
||||
2NtR6nj2YqeOpEe1ibWZm8tj3dzlTm1FCOIpa+pm114=
|
||||
MIIEpAIBAAKCAQEAselBnOh089g/VN7gH1m43Vo67kSqh8QRnXZxfjpzt3oPDl5n
|
||||
d04eNey4ezoSBo7o1hKhj/m5KLxmy1kN+xssyutgzto1FZu8GC2jDyLvByNLh0Z3
|
||||
XLmzdzBzBjosCtllJtzHlVL08SPuuOId5hToiiT8h3ElgNI4L6w+eLzhZIk5Rj1W
|
||||
ojGa+pnaTEgoOaZPcNrkOj81o1tgnbLXN7HY3hJKnRp78DmPySq82cRhvfNrePCs
|
||||
6BJr3y7yYJk0nG+EOaj5BK95YSJondZ8fOZuCigJPMogEaSw0SGsSUiQrPsd+3vZ
|
||||
Q+3ctOimnhW7cF3fAM79g+zDdv9N9E3D+inhyQIDAQABAoIBAQCWIyxVx+36YgGA
|
||||
E927VzIkyqJ0tMncbOAYq/228oj4yy6th4l1Kx1fkHdWtnjDxBJFpc9l+u4ArI1r
|
||||
Cao8wIAadmxp48dshtJC7TBv86EXuvdgH11XiPcknGRVWv4T4cX099gN8cX3QcWR
|
||||
jHCC3B4phnD9s8RcZAs6X/cQWQU0mxiHodYJefSXDyRIx9wimXmmW83ZqcsFftXS
|
||||
MI0+jflmRTf07M4gALVL0LlaBkg2FMoNiaKYPTbubcrEMUgTDsoDsjX3Fi43qLdF
|
||||
QTq+lF7HrHQ1EQlngCJupka9JxwZc3Fae6XYlDQvSDPcRxzWJoOuVBPtheGeoU3c
|
||||
PAry9KihAoGBAN8HCb0k4bMN06WZjSzClKhb6eFw4GMbVpDAOwPDl2N+9+pwrGxE
|
||||
ztekrM+VdXVScIj23g6wKd6fPqK6EYuEEu3Hre82e9ApqjJ34p1UcOs9Vs4N3VDy
|
||||
HJnWhEytsc9c03O5nhsK1YAXoGHEPmCYGsg2UA171LDcarnO1WDmpKkNAoGBAMw2
|
||||
sTCC/LBwgsuPZL5fR10wQ1sr1fIheSL+VK10jSRDwNXT2Y4wdCpQXQ6XNi+n98n5
|
||||
VvKaE6PxFqjnKCrUUty8X5+fzVcTKpBYVICceEzpVY9FrKbeY1shMnOBRTCkaQwz
|
||||
8CoEbbQz6SH5s4qW7M8iJdUJ0RulaFDfpmangTStAoGBALMkMxVjZ4rsI0GT2grG
|
||||
7KNi2LTFducEUX8JeR2n4JUBql78S/LXPhGGa2x9z5ACPPQ23tyLccYowSXyMR+Q
|
||||
YafuyO4pJEBrBxNsqnDXH7BEX9I43rkjEAgdf70bk4RNOmdtA+sSw7UUxTVibPwn
|
||||
kPOadKiv+4JoOa2vzkL8X+yNAoGAbU85OUZkC+2tlViEDILjqDYVV8/3DUxtkxWg
|
||||
LdidVDQQHGTxpvK4u42Ywh6empPGRw54RBPFP5PlFTPmhEZytEUAymi3eUyBFBKz
|
||||
6MPYgRLFAZPB/vA7LqRuZPVlG8xljmqeu17zeenveIg4Wo6+44Dbz1UZ4TqAxAlz
|
||||
AK/YsWECgYAPuZnIo9fWJtUAIe5IA2LIqcN0rj3PsZ/tL6eaMXqKZgCYwTvVUGbT
|
||||
XD4O352t+yLM8v2hJGHrIPuHooN2dCadYuzoBvVFsRTZjGpBlAZ+EJ5WfDYFL0qf
|
||||
68O2KZNXaSS8ZARlp9g3C8AFiakm/uWhtSfwx09uSBHJgld1V3GAoA==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
@ -409,6 +409,7 @@ acl:
|
||||
user_regexp: ""
|
||||
define_macro:
|
||||
CERTFILE: "cert.pem"
|
||||
CAFILE: "ca.pem"
|
||||
language: "en"
|
||||
listen:
|
||||
-
|
||||
@ -450,6 +451,10 @@ Welcome to this XMPP server."
|
||||
mod_time: []
|
||||
mod_version: []
|
||||
registration_timeout: infinity
|
||||
route_subdomains: s2s
|
||||
domain_certfile: CERTFILE
|
||||
s2s_use_starttls: false
|
||||
s2s_cafile: CAFILE
|
||||
shaper:
|
||||
fast: 50000
|
||||
normal: 1000
|
||||
|
@ -7,7 +7,10 @@ def read():
|
||||
cmd = pkt[0]
|
||||
args_num = len(pkt) - 1
|
||||
if cmd == 'auth' and args_num >= 3:
|
||||
write(True)
|
||||
if pkt[1] == "wrong":
|
||||
write(False)
|
||||
else:
|
||||
write(True)
|
||||
elif cmd == 'isuser' and args_num == 2:
|
||||
write(True)
|
||||
elif cmd == 'setpass' and args_num >= 3:
|
||||
|
18
test/ejabberd_SUITE_data/gencerts.sh
Executable file
18
test/ejabberd_SUITE_data/gencerts.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
# Update openssl.cnf if needed (in particular section [alt_names])
|
||||
|
||||
rm -rf ssl
|
||||
mkdir -p ssl/newcerts
|
||||
touch ssl/index.txt
|
||||
echo 01 > ssl/serial
|
||||
echo 1000 > ssl/crlnumber
|
||||
openssl genrsa -out ssl/client.key
|
||||
openssl req -new -key ssl/client.key -out ssl/client.csr -config openssl.cnf -batch -subj /C=AU/ST=Some-State/O=Internet\ Widgits\ Pty\ Ltd/CN=active
|
||||
openssl ca -keyfile ca.key -cert ca.pem -in ssl/client.csr -out ssl/client.crt -config openssl.cnf -days 10000 -batch -notext
|
||||
openssl req -new -key ssl/client.key -out ssl/self-signed-client.csr -batch -subj /C=AU/ST=Some-State/O=Internet\ Widgits\ Pty\ Ltd/CN=active
|
||||
openssl x509 -req -in ssl/self-signed-client.csr -signkey ssl/client.key -out ssl/self-signed-client.crt -days 10000
|
||||
cat ssl/client.crt > cert.pem
|
||||
cat ssl/self-signed-client.crt > self-signed-cert.pem
|
||||
cat ssl/client.key >> cert.pem
|
||||
cat ssl/client.key >> self-signed-cert.pem
|
||||
rm -rf ssl
|
323
test/ejabberd_SUITE_data/openssl.cnf
Normal file
323
test/ejabberd_SUITE_data/openssl.cnf
Normal file
@ -0,0 +1,323 @@
|
||||
#
|
||||
# OpenSSL example configuration file.
|
||||
# This is mostly being used for generation of certificate requests.
|
||||
#
|
||||
|
||||
# This definition stops the following lines choking if HOME isn't
|
||||
# defined.
|
||||
HOME = .
|
||||
RANDFILE = $ENV::HOME/.rnd
|
||||
|
||||
# Extra OBJECT IDENTIFIER info:
|
||||
#oid_file = $ENV::HOME/.oid
|
||||
oid_section = new_oids
|
||||
|
||||
# To use this configuration file with the "-extfile" option of the
|
||||
# "openssl x509" utility, name here the section containing the
|
||||
# X.509v3 extensions to use:
|
||||
extensions = v3_req
|
||||
# (Alternatively, use a configuration file that has only
|
||||
# X.509v3 extensions in its main [= default] section.)
|
||||
|
||||
[ new_oids ]
|
||||
# We can add new OIDs in here for use by 'ca' and 'req'.
|
||||
# Add a simple OID like this:
|
||||
# testoid1=1.2.3.4
|
||||
# Or use config file substitution like this:
|
||||
# testoid2=${testoid1}.5.6
|
||||
|
||||
####################################################################
|
||||
[ ca ]
|
||||
default_ca = CA_default # The default ca section
|
||||
|
||||
####################################################################
|
||||
[ CA_default ]
|
||||
|
||||
#dir = ./demoCA # Where everything is kept
|
||||
dir = ssl
|
||||
certs = $dir/certs # Where the issued certs are kept
|
||||
crl_dir = $dir/crl # Where the issued crl are kept
|
||||
database = $dir/index.txt # database index file.
|
||||
#unique_subject = no # Set to 'no' to allow creation of
|
||||
# several ctificates with same subject.
|
||||
new_certs_dir = $dir/newcerts # default place for new certs.
|
||||
|
||||
certificate = $dir/cacert.pem # The CA certificate
|
||||
serial = $dir/serial # The current serial number
|
||||
crlnumber = $dir/crlnumber # the current crl number
|
||||
# must be commented out to leave a V1 CRL
|
||||
crl = $dir/crl.pem # The current CRL
|
||||
private_key = $dir/private/cakey.pem# The private key
|
||||
RANDFILE = $dir/private/.rand # private random number file
|
||||
|
||||
x509_extensions = usr_cert # The extentions to add to the cert
|
||||
|
||||
# Comment out the following two lines for the "traditional"
|
||||
# (and highly broken) format.
|
||||
name_opt = ca_default # Subject Name options
|
||||
cert_opt = ca_default # Certificate field options
|
||||
|
||||
# Extension copying option: use with caution.
|
||||
copy_extensions = copy
|
||||
|
||||
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
|
||||
# so this is commented out by default to leave a V1 CRL.
|
||||
# crlnumber must also be commented out to leave a V1 CRL.
|
||||
# crl_extensions = crl_ext
|
||||
|
||||
default_days = 365 # how long to certify for
|
||||
default_crl_days= 30 # how long before next CRL
|
||||
default_md = sha1 # which md to use.
|
||||
preserve = no # keep passed DN ordering
|
||||
|
||||
# A few difference way of specifying how similar the request should look
|
||||
# For type CA, the listed attributes must be the same, and the optional
|
||||
# and supplied fields are just that :-)
|
||||
policy = policy_match
|
||||
|
||||
# For the CA policy
|
||||
[ policy_match ]
|
||||
countryName = match
|
||||
stateOrProvinceName = match
|
||||
organizationName = match
|
||||
organizationalUnitName = optional
|
||||
commonName = optional
|
||||
emailAddress = optional
|
||||
|
||||
# For the 'anything' policy
|
||||
# At this point in time, you must list all acceptable 'object'
|
||||
# types.
|
||||
[ policy_anything ]
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
localityName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = optional
|
||||
emailAddress = optional
|
||||
|
||||
####################################################################
|
||||
[ req ]
|
||||
default_bits = 1024
|
||||
default_keyfile = privkey.pem
|
||||
distinguished_name = req_distinguished_name
|
||||
attributes = req_attributes
|
||||
x509_extensions = v3_ca # The extentions to add to the self signed cert
|
||||
|
||||
# Passwords for private keys if not present they will be prompted for
|
||||
# input_password = secret
|
||||
# output_password = secret
|
||||
|
||||
# This sets a mask for permitted string types. There are several options.
|
||||
# default: PrintableString, T61String, BMPString.
|
||||
# pkix : PrintableString, BMPString.
|
||||
# utf8only: only UTF8Strings.
|
||||
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
|
||||
# MASK:XXXX a literal mask value.
|
||||
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
|
||||
# so use this option with caution!
|
||||
string_mask = nombstr
|
||||
|
||||
req_extensions = v3_req # The extensions to add to a certificate request
|
||||
|
||||
[ req_distinguished_name ]
|
||||
countryName = Country Name (2 letter code)
|
||||
countryName_default = AU
|
||||
countryName_min = 2
|
||||
countryName_max = 2
|
||||
|
||||
stateOrProvinceName = State or Province Name (full name)
|
||||
stateOrProvinceName_default = Some-State
|
||||
|
||||
localityName = Locality Name (eg, city)
|
||||
|
||||
0.organizationName = Organization Name (eg, company)
|
||||
0.organizationName_default = Internet Widgits Pty Ltd
|
||||
|
||||
# we can do this but it is not needed normally :-)
|
||||
#1.organizationName = Second Organization Name (eg, company)
|
||||
#1.organizationName_default = World Wide Web Pty Ltd
|
||||
|
||||
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||
#organizationalUnitName_default =
|
||||
|
||||
commonName = Common Name (eg, YOUR name)
|
||||
commonName_max = 64
|
||||
|
||||
emailAddress = Email Address
|
||||
emailAddress_max = 64
|
||||
|
||||
# SET-ex3 = SET extension number 3
|
||||
|
||||
[ req_attributes ]
|
||||
challengePassword = A challenge password
|
||||
challengePassword_min = 4
|
||||
challengePassword_max = 20
|
||||
|
||||
unstructuredName = An optional company name
|
||||
|
||||
[ usr_cert ]
|
||||
|
||||
# These extensions are added when 'ca' signs a request.
|
||||
|
||||
# This goes against PKIX guidelines but some CAs do it and some software
|
||||
# requires this to avoid interpreting an end user certificate as a CA.
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
|
||||
# This stuff is for subjectAltName and issuerAltname.
|
||||
# Import the email address.
|
||||
# subjectAltName=email:copy
|
||||
# An alternative to produce certificates that aren't
|
||||
# deprecated according to PKIX.
|
||||
# subjectAltName=email:move
|
||||
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
crlDistributionPoints = URI:http://localhost:5280/data/crl.der
|
||||
authorityInfoAccess = OCSP;URI:http://localhost:5280/ocsp
|
||||
|
||||
[ v3_req ]
|
||||
|
||||
# Extensions to add to a certificate request
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = OCSPSigning,serverAuth,clientAuth
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
otherName.1 = 1.3.6.1.5.5.7.8.5;UTF8:"localhost"
|
||||
otherName.2 = 1.3.6.1.5.5.7.8.5;UTF8:"s2s.localhost"
|
||||
otherName.3 = 1.3.6.1.5.5.7.8.5;UTF8:"mnesia.localhost"
|
||||
|
||||
[ v3_ca ]
|
||||
crlDistributionPoints = URI:http://localhost:5280/data/crl.der
|
||||
|
||||
# Extensions for a typical CA
|
||||
|
||||
|
||||
# PKIX recommendation.
|
||||
|
||||
subjectKeyIdentifier=hash
|
||||
|
||||
authorityKeyIdentifier=keyid:always,issuer:always
|
||||
|
||||
# This is what PKIX recommends but some broken software chokes on critical
|
||||
# extensions.
|
||||
#basicConstraints = critical,CA:true
|
||||
# So we do this instead.
|
||||
basicConstraints = CA:true
|
||||
|
||||
# Key usage: this is typical for a CA certificate. However since it will
|
||||
# prevent it being used as an test self-signed certificate it is best
|
||||
# left out by default.
|
||||
# keyUsage = cRLSign, keyCertSign
|
||||
|
||||
# Some might want this also
|
||||
# nsCertType = sslCA, emailCA
|
||||
|
||||
# Include email address in subject alt name: another PKIX recommendation
|
||||
# subjectAltName=email:copy
|
||||
# Copy issuer details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
# DER hex encoding of an extension: beware experts only!
|
||||
# obj=DER:02:03
|
||||
# Where 'obj' is a standard or added object
|
||||
# You can even override a supported extension:
|
||||
# basicConstraints= critical, DER:30:03:01:01:FF
|
||||
|
||||
[ crl_ext ]
|
||||
|
||||
# CRL extensions.
|
||||
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
|
||||
|
||||
# issuerAltName=issuer:copy
|
||||
authorityKeyIdentifier=keyid:always,issuer:always
|
||||
|
||||
[ proxy_cert_ext ]
|
||||
# These extensions should be added when creating a proxy certificate
|
||||
|
||||
# This goes against PKIX guidelines but some CAs do it and some software
|
||||
# requires this to avoid interpreting an end user certificate as a CA.
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer:always
|
||||
|
||||
# This stuff is for subjectAltName and issuerAltname.
|
||||
# Import the email address.
|
||||
# subjectAltName=email:copy
|
||||
# An alternative to produce certificates that aren't
|
||||
# deprecated according to PKIX.
|
||||
# subjectAltName=email:move
|
||||
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
# This really needs to be in place for it to be a proxy certificate.
|
||||
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
|
46
test/ejabberd_SUITE_data/self-signed-cert.pem
Normal file
46
test/ejabberd_SUITE_data/self-signed-cert.pem
Normal file
@ -0,0 +1,46 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDKDCCAhACCQCsLYnJDV1wHDANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJB
|
||||
VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
|
||||
cyBQdHkgTHRkMQ8wDQYDVQQDEwZhY3RpdmUwHhcNMTYwOTIzMDcwMzI0WhcNNDQw
|
||||
MjA5MDcwMzI0WjBWMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEh
|
||||
MB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ8wDQYDVQQDEwZhY3Rp
|
||||
dmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx6UGc6HTz2D9U3uAf
|
||||
WbjdWjruRKqHxBGddnF+OnO3eg8OXmd3Th417Lh7OhIGjujWEqGP+bkovGbLWQ37
|
||||
GyzK62DO2jUVm7wYLaMPIu8HI0uHRndcubN3MHMGOiwK2WUm3MeVUvTxI+644h3m
|
||||
FOiKJPyHcSWA0jgvrD54vOFkiTlGPVaiMZr6mdpMSCg5pk9w2uQ6PzWjW2Cdstc3
|
||||
sdjeEkqdGnvwOY/JKrzZxGG982t48KzoEmvfLvJgmTScb4Q5qPkEr3lhImid1nx8
|
||||
5m4KKAk8yiARpLDRIaxJSJCs+x37e9lD7dy06KaeFbtwXd8Azv2D7MN2/030TcP6
|
||||
KeHJAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEAIFwHpNCVUiivAcfkxcUPKp0nn
|
||||
mhGqkMDRrPA7fOCm0ir1Puz4GQ/G4i+tWejzzFoS6kKQl+sUZAUYJdziftJFFoZ7
|
||||
br3q3Xafc2dWa8SHNcHH6lA1OEk8tXlhkNl+EgSLnRGMhIf0iZL2wGjE8Hlig6cu
|
||||
3h+OpbUijXUmq0XdH+ui3wNgXb7+Tosg/Od+lr0fNjkopsk3t1oiVXD4OQBZdUyq
|
||||
V5XValiZjMFDUUBdxBA+l6/Qj3bFmluz+FXI8UwfbinukqADTJzkMeUjEkvmKZWO
|
||||
tb+EU77NIuvg/k7b1yp4lEmATpdUfcGEuhWNtgeh5AqgMxOhAsJ7zUTA80I=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAselBnOh089g/VN7gH1m43Vo67kSqh8QRnXZxfjpzt3oPDl5n
|
||||
d04eNey4ezoSBo7o1hKhj/m5KLxmy1kN+xssyutgzto1FZu8GC2jDyLvByNLh0Z3
|
||||
XLmzdzBzBjosCtllJtzHlVL08SPuuOId5hToiiT8h3ElgNI4L6w+eLzhZIk5Rj1W
|
||||
ojGa+pnaTEgoOaZPcNrkOj81o1tgnbLXN7HY3hJKnRp78DmPySq82cRhvfNrePCs
|
||||
6BJr3y7yYJk0nG+EOaj5BK95YSJondZ8fOZuCigJPMogEaSw0SGsSUiQrPsd+3vZ
|
||||
Q+3ctOimnhW7cF3fAM79g+zDdv9N9E3D+inhyQIDAQABAoIBAQCWIyxVx+36YgGA
|
||||
E927VzIkyqJ0tMncbOAYq/228oj4yy6th4l1Kx1fkHdWtnjDxBJFpc9l+u4ArI1r
|
||||
Cao8wIAadmxp48dshtJC7TBv86EXuvdgH11XiPcknGRVWv4T4cX099gN8cX3QcWR
|
||||
jHCC3B4phnD9s8RcZAs6X/cQWQU0mxiHodYJefSXDyRIx9wimXmmW83ZqcsFftXS
|
||||
MI0+jflmRTf07M4gALVL0LlaBkg2FMoNiaKYPTbubcrEMUgTDsoDsjX3Fi43qLdF
|
||||
QTq+lF7HrHQ1EQlngCJupka9JxwZc3Fae6XYlDQvSDPcRxzWJoOuVBPtheGeoU3c
|
||||
PAry9KihAoGBAN8HCb0k4bMN06WZjSzClKhb6eFw4GMbVpDAOwPDl2N+9+pwrGxE
|
||||
ztekrM+VdXVScIj23g6wKd6fPqK6EYuEEu3Hre82e9ApqjJ34p1UcOs9Vs4N3VDy
|
||||
HJnWhEytsc9c03O5nhsK1YAXoGHEPmCYGsg2UA171LDcarnO1WDmpKkNAoGBAMw2
|
||||
sTCC/LBwgsuPZL5fR10wQ1sr1fIheSL+VK10jSRDwNXT2Y4wdCpQXQ6XNi+n98n5
|
||||
VvKaE6PxFqjnKCrUUty8X5+fzVcTKpBYVICceEzpVY9FrKbeY1shMnOBRTCkaQwz
|
||||
8CoEbbQz6SH5s4qW7M8iJdUJ0RulaFDfpmangTStAoGBALMkMxVjZ4rsI0GT2grG
|
||||
7KNi2LTFducEUX8JeR2n4JUBql78S/LXPhGGa2x9z5ACPPQ23tyLccYowSXyMR+Q
|
||||
YafuyO4pJEBrBxNsqnDXH7BEX9I43rkjEAgdf70bk4RNOmdtA+sSw7UUxTVibPwn
|
||||
kPOadKiv+4JoOa2vzkL8X+yNAoGAbU85OUZkC+2tlViEDILjqDYVV8/3DUxtkxWg
|
||||
LdidVDQQHGTxpvK4u42Ywh6empPGRw54RBPFP5PlFTPmhEZytEUAymi3eUyBFBKz
|
||||
6MPYgRLFAZPB/vA7LqRuZPVlG8xljmqeu17zeenveIg4Wo6+44Dbz1UZ4TqAxAlz
|
||||
AK/YsWECgYAPuZnIo9fWJtUAIe5IA2LIqcN0rj3PsZ/tL6eaMXqKZgCYwTvVUGbT
|
||||
XD4O352t+yLM8v2hJGHrIPuHooN2dCadYuzoBvVFsRTZjGpBlAZ+EJ5WfDYFL0qf
|
||||
68O2KZNXaSS8ZARlp9g3C8AFiakm/uWhtSfwx09uSBHJgld1V3GAoA==
|
||||
-----END RSA PRIVATE KEY-----
|
143
test/suite.erl
143
test/suite.erl
@ -27,13 +27,18 @@ init_config(Config) ->
|
||||
SASLPath = filename:join([PrivDir, "sasl.log"]),
|
||||
MnesiaDir = filename:join([PrivDir, "mnesia"]),
|
||||
CertFile = filename:join([DataDir, "cert.pem"]),
|
||||
SelfSignedCertFile = filename:join([DataDir, "self-signed-cert.pem"]),
|
||||
CAFile = filename:join([DataDir, "ca.pem"]),
|
||||
{ok, CWD} = file:get_cwd(),
|
||||
{ok, _} = file:copy(CertFile, filename:join([CWD, "cert.pem"])),
|
||||
{ok, _} = file:copy(SelfSignedCertFile,
|
||||
filename:join([CWD, "self-signed-cert.pem"])),
|
||||
{ok, _} = file:copy(CAFile, filename:join([CWD, "ca.pem"])),
|
||||
{ok, CfgContentTpl} = file:read_file(ConfigPathTpl),
|
||||
Password = <<"password!@#$%^&*()'\"`~<>+-/;:_=[]{}|\\">>,
|
||||
CfgContent = process_config_tpl(CfgContentTpl, [
|
||||
{c2s_port, 5222},
|
||||
{loglevel, 5},
|
||||
{loglevel, 4},
|
||||
{s2s_port, 5269},
|
||||
{component_port, 5270},
|
||||
{web_port, 5280},
|
||||
@ -62,6 +67,7 @@ init_config(Config) ->
|
||||
[{server_port, ct:get_config(c2s_port, 5222)},
|
||||
{server_host, "localhost"},
|
||||
{component_port, ct:get_config(component_port, 5270)},
|
||||
{s2s_port, ct:get_config(s2s_port, 5269)},
|
||||
{server, ?COMMON_VHOST},
|
||||
{user, <<"test_single!#$%^*()`~+-;_=[]{}|\\">>},
|
||||
{master_nick, <<"master_nick!@#$%^&*()'\"`~<>+-/;:_=[]{}|\\">>},
|
||||
@ -71,11 +77,14 @@ init_config(Config) ->
|
||||
{type, client},
|
||||
{xmlns, ?NS_CLIENT},
|
||||
{ns_stream, ?NS_STREAM},
|
||||
{stream_version, <<"1.0">>},
|
||||
{stream_version, {1, 0}},
|
||||
{stream_id, <<"">>},
|
||||
{stream_from, <<"">>},
|
||||
{db_xmlns, <<"">>},
|
||||
{mechs, []},
|
||||
{lang, <<"en">>},
|
||||
{base_dir, BaseDir},
|
||||
{socket, undefined},
|
||||
{resource, <<"resource!@#$%^&*()'\"`~<>+-/;:_=[]{}|\\">>},
|
||||
{master_resource, <<"master_resource!@#$%^&*()'\"`~<>+-/;:_=[]{}|\\">>},
|
||||
{slave_resource, <<"slave_resource!@#$%^&*()'\"`~<>+-/;:_=[]{}|\\">>},
|
||||
@ -130,42 +139,50 @@ process_config_tpl(Content, [{Name, DefaultValue} | Rest]) ->
|
||||
process_config_tpl(NewContent, Rest).
|
||||
|
||||
stream_header(Config) ->
|
||||
NSStream = ?config(ns_stream, Config),
|
||||
XMLNS = ?config(xmlns, Config),
|
||||
Lang = case ?config(lang, Config) of
|
||||
<<"">> -> <<"">>;
|
||||
L -> iolist_to_binary(["xml:lang='", L, "'"])
|
||||
end,
|
||||
To = case ?config(server, Config) of
|
||||
<<"">> -> <<"">>;
|
||||
Server -> <<"to='", Server/binary, "'">>
|
||||
<<"">> -> undefined;
|
||||
Server -> jid:make(Server)
|
||||
end,
|
||||
Version = case ?config(stream_version, Config) of
|
||||
<<"">> -> <<"">>;
|
||||
V -> <<"version='", V/binary, "'">>
|
||||
end,
|
||||
io_lib:format("<?xml version='1.0'?><stream:stream "
|
||||
"xmlns:stream='~s' xmlns='~s' ~s ~s ~s>",
|
||||
[NSStream, XMLNS, To, Version, Lang]).
|
||||
From = case ?config(stream_from, Config) of
|
||||
<<"">> -> undefined;
|
||||
Frm -> jid:make(Frm)
|
||||
end,
|
||||
#stream_start{to = To,
|
||||
from = From,
|
||||
lang = ?config(lang, Config),
|
||||
version = ?config(stream_version, Config),
|
||||
xmlns = ?config(xmlns, Config),
|
||||
db_xmlns = ?config(db_xmlns, Config),
|
||||
stream_xmlns = ?config(ns_stream, Config)}.
|
||||
|
||||
connect(Config) ->
|
||||
NewConfig = init_stream(Config),
|
||||
case ?config(type, NewConfig) of
|
||||
client -> process_stream_features(NewConfig);
|
||||
server -> process_stream_features(NewConfig);
|
||||
component -> NewConfig
|
||||
end.
|
||||
|
||||
tcp_connect(Config) ->
|
||||
case ?config(socket, Config) of
|
||||
undefined ->
|
||||
{ok, Sock} = ejabberd_socket:connect(
|
||||
?config(server_host, Config),
|
||||
?config(server_port, Config),
|
||||
[binary, {packet, 0}, {active, false}]),
|
||||
set_opt(socket, Sock, Config);
|
||||
_ ->
|
||||
Config
|
||||
end.
|
||||
|
||||
init_stream(Config) ->
|
||||
Version = ?config(stream_version, Config),
|
||||
{ok, Sock} = ejabberd_socket:connect(
|
||||
?config(server_host, Config),
|
||||
?config(server_port, Config),
|
||||
[binary, {packet, 0}, {active, false}]),
|
||||
NewConfig = set_opt(socket, Sock, Config),
|
||||
ok = send_text(NewConfig, stream_header(NewConfig)),
|
||||
NewConfig = tcp_connect(Config),
|
||||
send(NewConfig, stream_header(NewConfig)),
|
||||
XMLNS = case ?config(type, Config) of
|
||||
client -> ?NS_CLIENT;
|
||||
component -> ?NS_COMPONENT
|
||||
component -> ?NS_COMPONENT;
|
||||
server -> ?NS_SERVER
|
||||
end,
|
||||
#stream_start{id = ID, xmlns = XMLNS, version = Version} = recv(),
|
||||
set_opt(stream_id, ID, NewConfig).
|
||||
@ -206,13 +223,24 @@ close_socket(Config) ->
|
||||
Config.
|
||||
|
||||
starttls(Config) ->
|
||||
starttls(Config, false).
|
||||
|
||||
starttls(Config, ShouldFail) ->
|
||||
send(Config, #starttls{}),
|
||||
#starttls_proceed{} = recv(),
|
||||
TLSSocket = ejabberd_socket:starttls(
|
||||
?config(socket, Config),
|
||||
[{certfile, ?config(certfile, Config)},
|
||||
connect]),
|
||||
process_stream_features(init_stream(set_opt(socket, TLSSocket, Config))).
|
||||
case recv() of
|
||||
#starttls_proceed{} when ShouldFail ->
|
||||
ct:fail(starttls_should_have_failed);
|
||||
#starttls_failure{} when ShouldFail ->
|
||||
Config;
|
||||
#starttls_failure{} ->
|
||||
ct:fail(starttls_failed);
|
||||
#starttls_proceed{} ->
|
||||
TLSSocket = ejabberd_socket:starttls(
|
||||
?config(socket, Config),
|
||||
[{certfile, ?config(certfile, Config)},
|
||||
connect]),
|
||||
set_opt(socket, TLSSocket, Config)
|
||||
end.
|
||||
|
||||
zlib(Config) ->
|
||||
send(Config, #compress{methods = [<<"zlib">>]}),
|
||||
@ -228,14 +256,19 @@ auth(Config, ShouldFail) ->
|
||||
Mechs = ?config(mechs, Config),
|
||||
HaveMD5 = lists:member(<<"DIGEST-MD5">>, Mechs),
|
||||
HavePLAIN = lists:member(<<"PLAIN">>, Mechs),
|
||||
HaveExternal = lists:member(<<"EXTERNAL">>, Mechs),
|
||||
if HavePLAIN ->
|
||||
auth_SASL(<<"PLAIN">>, Config, ShouldFail);
|
||||
HaveMD5 ->
|
||||
auth_SASL(<<"DIGEST-MD5">>, Config, ShouldFail);
|
||||
HaveExternal andalso Type == server ->
|
||||
auth_SASL(<<"EXTERNAL">>, Config, ShouldFail);
|
||||
Type == client ->
|
||||
auth_legacy(Config, false, ShouldFail);
|
||||
Type == component ->
|
||||
auth_component(Config, ShouldFail)
|
||||
auth_component(Config, ShouldFail);
|
||||
true ->
|
||||
ct:fail(no_known_sasl_mechanism_available)
|
||||
end.
|
||||
|
||||
bind(Config) ->
|
||||
@ -341,10 +374,19 @@ wait_auth_SASL_result(Config, ShouldFail) ->
|
||||
ct:fail(sasl_auth_should_have_failed);
|
||||
#sasl_success{} ->
|
||||
ejabberd_socket:reset_stream(?config(socket, Config)),
|
||||
send_text(Config, stream_header(Config)),
|
||||
#stream_start{xmlns = ?NS_CLIENT, version = <<"1.0">>} = recv(),
|
||||
send(Config, stream_header(Config)),
|
||||
Type = ?config(type, Config),
|
||||
NS = if Type == client -> ?NS_CLIENT;
|
||||
Type == server -> ?NS_SERVER
|
||||
end,
|
||||
#stream_start{xmlns = NS, version = {1,0}} = recv(),
|
||||
#stream_features{sub_els = Fs} = recv(),
|
||||
#xmpp_session{optional = true} = lists:keyfind(xmpp_session, 1, Fs),
|
||||
if Type == client ->
|
||||
#xmpp_session{optional = true} =
|
||||
lists:keyfind(xmpp_session, 1, Fs);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
lists:foldl(
|
||||
fun(#feature_sm{}, ConfigAcc) ->
|
||||
set_opt(sm, true, ConfigAcc);
|
||||
@ -427,7 +469,11 @@ send(State, Pkt) ->
|
||||
end,
|
||||
El = xmpp_codec:encode(NewPkt),
|
||||
ct:pal("sent: ~p <-~n~s", [El, xmpp_codec:pp(NewPkt)]),
|
||||
ok = send_text(State, fxml:element_to_binary(El)),
|
||||
Data = case NewPkt of
|
||||
#stream_start{} -> fxml:element_to_header(El);
|
||||
_ -> fxml:element_to_binary(El)
|
||||
end,
|
||||
ok = send_text(State, Data),
|
||||
NewID.
|
||||
|
||||
send_recv(State, IQ) ->
|
||||
@ -437,6 +483,9 @@ send_recv(State, IQ) ->
|
||||
sasl_new(<<"PLAIN">>, User, Server, Password) ->
|
||||
{<<User/binary, $@, Server/binary, 0, User/binary, 0, Password/binary>>,
|
||||
fun (_) -> {error, <<"Invalid SASL challenge">>} end};
|
||||
sasl_new(<<"EXTERNAL">>, _User, _Server, _Password) ->
|
||||
{<<"">>,
|
||||
fun(_) -> ct:fail(sasl_challenge_is_not_expected) end};
|
||||
sasl_new(<<"DIGEST-MD5">>, User, Server, Password) ->
|
||||
{<<"">>,
|
||||
fun (ServerIn) ->
|
||||
@ -567,11 +616,21 @@ set_opt(Opt, Val, Config) ->
|
||||
|
||||
wait_for_master(Config) ->
|
||||
put_event(Config, slave_ready),
|
||||
master_ready = get_event(Config).
|
||||
case get_event(Config) of
|
||||
master_ready ->
|
||||
ok;
|
||||
Other ->
|
||||
suite:match_failure([Other], [master_ready])
|
||||
end.
|
||||
|
||||
wait_for_slave(Config) ->
|
||||
put_event(Config, master_ready),
|
||||
slave_ready = get_event(Config).
|
||||
case get_event(Config) of
|
||||
slave_ready ->
|
||||
ok;
|
||||
Other ->
|
||||
suite:match_failure([Other], [slave_ready])
|
||||
end.
|
||||
|
||||
make_iq_result(#iq{from = From} = IQ) ->
|
||||
IQ#iq{type = result, to = From, from = undefined, sub_els = []}.
|
||||
@ -592,6 +651,7 @@ event_relay() ->
|
||||
event_relay(Events, Subscribers) ->
|
||||
receive
|
||||
{subscribe, From} ->
|
||||
erlang:monitor(process, From),
|
||||
From ! {ok, self()},
|
||||
lists:foreach(
|
||||
fun(Event) -> From ! {event, Event, self()}
|
||||
@ -605,7 +665,14 @@ event_relay(Events, Subscribers) ->
|
||||
(_) ->
|
||||
ok
|
||||
end, Subscribers),
|
||||
event_relay([Event|Events], Subscribers)
|
||||
event_relay([Event|Events], Subscribers);
|
||||
{'DOWN', _MRef, process, Pid, _Info} ->
|
||||
NewSubscribers = lists:delete(Pid, Subscribers),
|
||||
lists:foreach(
|
||||
fun(Subscriber) ->
|
||||
Subscriber ! {event, peer_down, self()}
|
||||
end, NewSubscribers),
|
||||
event_relay(Events, NewSubscribers)
|
||||
end.
|
||||
|
||||
subscribe_to_events(Config) ->
|
||||
|
@ -75,6 +75,7 @@
|
||||
-define(LDAP_VHOST, <<"ldap.localhost">>).
|
||||
-define(EXTAUTH_VHOST, <<"extauth.localhost">>).
|
||||
-define(RIAK_VHOST, <<"riak.localhost">>).
|
||||
-define(S2S_VHOST, <<"s2s.localhost">>).
|
||||
|
||||
insert(Val, N, Tuple) ->
|
||||
L = tuple_to_list(Tuple),
|
||||
|
@ -3215,7 +3215,9 @@
|
||||
default = <<"">>},
|
||||
#attr{name = <<"xml:lang">>, label = '$lang',
|
||||
default = <<"">>},
|
||||
#attr{name = <<"version">>, default = <<"">>},
|
||||
#attr{name = <<"version">>,
|
||||
dec = {dec_version, []},
|
||||
enc = {enc_version, []}},
|
||||
#attr{name = <<"id">>, default = <<"">>}]}).
|
||||
|
||||
-xml(bob_data,
|
||||
@ -3479,6 +3481,14 @@ enc_host_port({Host, Port}) ->
|
||||
enc_host_port(Addr) ->
|
||||
enc_ip(Addr).
|
||||
|
||||
-spec dec_version(_) -> {non_neg_integer(), non_neg_integer()}.
|
||||
dec_version(S) ->
|
||||
[Major, Minor] = binary:split(S, <<$.>>),
|
||||
{binary_to_integer(Major), binary_to_integer(Minor)}.
|
||||
|
||||
enc_version({Maj, Min}) ->
|
||||
<<(integer_to_binary(Maj))/binary, $., (integer_to_binary(Min))/binary>>.
|
||||
|
||||
%% Local Variables:
|
||||
%% mode: erlang
|
||||
%% End:
|
||||
|
Loading…
Reference in New Issue
Block a user