mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-22 17:28:25 +01:00
* src/ejabberd_c2s.erl: Implements timeouts during session opening negociation (EJAB-355).
SVN Revision: 933
This commit is contained in:
parent
7146a52a84
commit
f787a3ed71
@ -84,6 +84,10 @@
|
|||||||
[SockData, Opts])).
|
[SockData, Opts])).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
%% This is the timeout to apply between event when starting a new
|
||||||
|
%% session:
|
||||||
|
-define(C2S_OPEN_TIMEOUT, 5000).
|
||||||
|
|
||||||
-define(STREAM_HEADER,
|
-define(STREAM_HEADER,
|
||||||
"<?xml version='1.0'?>"
|
"<?xml version='1.0'?>"
|
||||||
"<stream:stream xmlns='jabber:client' "
|
"<stream:stream xmlns='jabber:client' "
|
||||||
@ -166,7 +170,7 @@ init([{SockMod, Socket}, Opts]) ->
|
|||||||
streamid = new_id(),
|
streamid = new_id(),
|
||||||
access = Access,
|
access = Access,
|
||||||
shaper = Shaper,
|
shaper = Shaper,
|
||||||
ip = IP}}.
|
ip = IP}, ?C2S_OPEN_TIMEOUT}.
|
||||||
|
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
@ -265,7 +269,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
|||||||
{next_state, wait_for_feature_request,
|
{next_state, wait_for_feature_request,
|
||||||
StateData#state{server = Server,
|
StateData#state{server = Server,
|
||||||
sasl_state = SASLState,
|
sasl_state = SASLState,
|
||||||
lang = Lang}};
|
lang = Lang},
|
||||||
|
?C2S_OPEN_TIMEOUT};
|
||||||
_ ->
|
_ ->
|
||||||
case StateData#state.resource of
|
case StateData#state.resource of
|
||||||
"" ->
|
"" ->
|
||||||
@ -278,7 +283,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
|||||||
[{"xmlns", ?NS_SESSION}], []}]}),
|
[{"xmlns", ?NS_SESSION}], []}]}),
|
||||||
{next_state, wait_for_bind,
|
{next_state, wait_for_bind,
|
||||||
StateData#state{server = Server,
|
StateData#state{server = Server,
|
||||||
lang = Lang}};
|
lang = Lang},
|
||||||
|
?C2S_OPEN_TIMEOUT};
|
||||||
_ ->
|
_ ->
|
||||||
send_element(
|
send_element(
|
||||||
StateData,
|
StateData,
|
||||||
@ -328,6 +334,9 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
|||||||
{stop, normal, StateData}
|
{stop, normal, StateData}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
wait_for_stream(timeout, StateData) ->
|
||||||
|
{stop, normal, StateData};
|
||||||
|
|
||||||
wait_for_stream({xmlstreamelement, _}, StateData) ->
|
wait_for_stream({xmlstreamelement, _}, StateData) ->
|
||||||
send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
|
send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
|
||||||
{stop, normal, StateData};
|
{stop, normal, StateData};
|
||||||
@ -376,13 +385,13 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
]}]}
|
]}]}
|
||||||
end,
|
end,
|
||||||
send_element(StateData, Res),
|
send_element(StateData, Res),
|
||||||
{next_state, wait_for_auth, StateData};
|
{next_state, wait_for_auth, StateData, ?C2S_OPEN_TIMEOUT};
|
||||||
{auth, _ID, set, {_U, _P, _D, ""}} ->
|
{auth, _ID, set, {_U, _P, _D, ""}} ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
El,
|
El,
|
||||||
?ERR_AUTH_NO_RESOURCE_PROVIDED(StateData#state.lang)),
|
?ERR_AUTH_NO_RESOURCE_PROVIDED(StateData#state.lang)),
|
||||||
send_element(StateData, Err),
|
send_element(StateData, Err),
|
||||||
{next_state, wait_for_auth, StateData};
|
{next_state, wait_for_auth, StateData, ?C2S_OPEN_TIMEOUT};
|
||||||
{auth, _ID, set, {U, P, D, R}} ->
|
{auth, _ID, set, {U, P, D, R}} ->
|
||||||
JID = jlib:make_jid(U, StateData#state.server, R),
|
JID = jlib:make_jid(U, StateData#state.server, R),
|
||||||
case (JID /= error) andalso
|
case (JID /= error) andalso
|
||||||
@ -435,7 +444,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
El, ?ERR_NOT_AUTHORIZED),
|
El, ?ERR_NOT_AUTHORIZED),
|
||||||
send_element(StateData, Err),
|
send_element(StateData, Err),
|
||||||
{next_state, wait_for_auth, StateData}
|
{next_state, wait_for_auth, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
if
|
if
|
||||||
@ -446,7 +456,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
[StateData#state.socket, U, R]),
|
[StateData#state.socket, U, R]),
|
||||||
Err = jlib:make_error_reply(El, ?ERR_JID_MALFORMED),
|
Err = jlib:make_error_reply(El, ?ERR_JID_MALFORMED),
|
||||||
send_element(StateData, Err),
|
send_element(StateData, Err),
|
||||||
{next_state, wait_for_auth, StateData};
|
{next_state, wait_for_auth, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT};
|
||||||
true ->
|
true ->
|
||||||
?INFO_MSG(
|
?INFO_MSG(
|
||||||
"(~w) Forbidden legacy authentication for ~s",
|
"(~w) Forbidden legacy authentication for ~s",
|
||||||
@ -454,14 +465,18 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
jlib:jid_to_string(JID)]),
|
jlib:jid_to_string(JID)]),
|
||||||
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
||||||
send_element(StateData, Err),
|
send_element(StateData, Err),
|
||||||
{next_state, wait_for_auth, StateData}
|
{next_state, wait_for_auth, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
process_unauthenticated_stanza(StateData, El),
|
process_unauthenticated_stanza(StateData, El),
|
||||||
{next_state, wait_for_auth, StateData}
|
{next_state, wait_for_auth, StateData, ?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
wait_for_auth(timeout, StateData) ->
|
||||||
|
{stop, normal, StateData};
|
||||||
|
|
||||||
wait_for_auth({xmlstreamend, _Name}, StateData) ->
|
wait_for_auth({xmlstreamend, _Name}, StateData) ->
|
||||||
send_text(StateData, ?STREAM_TRAILER),
|
send_text(StateData, ?STREAM_TRAILER),
|
||||||
{stop, normal, StateData};
|
{stop, normal, StateData};
|
||||||
@ -501,7 +516,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
|||||||
StateData#state{streamid = new_id(),
|
StateData#state{streamid = new_id(),
|
||||||
authenticated = true,
|
authenticated = true,
|
||||||
user = U
|
user = U
|
||||||
}};
|
}, ?C2S_OPEN_TIMEOUT};
|
||||||
{continue, ServerOut, NewSASLState} ->
|
{continue, ServerOut, NewSASLState} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
{xmlelement, "challenge",
|
{xmlelement, "challenge",
|
||||||
@ -509,7 +524,8 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
|||||||
[{xmlcdata,
|
[{xmlcdata,
|
||||||
jlib:encode_base64(ServerOut)}]}),
|
jlib:encode_base64(ServerOut)}]}),
|
||||||
{next_state, wait_for_sasl_response,
|
{next_state, wait_for_sasl_response,
|
||||||
StateData#state{sasl_state = NewSASLState}};
|
StateData#state{sasl_state = NewSASLState},
|
||||||
|
?C2S_OPEN_TIMEOUT};
|
||||||
{error, Error, Username} ->
|
{error, Error, Username} ->
|
||||||
?INFO_MSG(
|
?INFO_MSG(
|
||||||
"(~w) Failed authentication for ~s@~s",
|
"(~w) Failed authentication for ~s@~s",
|
||||||
@ -519,13 +535,15 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
|||||||
{xmlelement, "failure",
|
{xmlelement, "failure",
|
||||||
[{"xmlns", ?NS_SASL}],
|
[{"xmlns", ?NS_SASL}],
|
||||||
[{xmlelement, Error, [], []}]}),
|
[{xmlelement, Error, [], []}]}),
|
||||||
{next_state, wait_for_feature_request, StateData};
|
{next_state, wait_for_feature_request, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT};
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
{xmlelement, "failure",
|
{xmlelement, "failure",
|
||||||
[{"xmlns", ?NS_SASL}],
|
[{"xmlns", ?NS_SASL}],
|
||||||
[{xmlelement, Error, [], []}]}),
|
[{xmlelement, Error, [], []}]}),
|
||||||
{next_state, wait_for_feature_request, StateData}
|
{next_state, wait_for_feature_request, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
{?NS_TLS, "starttls"} when TLS == true,
|
{?NS_TLS, "starttls"} when TLS == true,
|
||||||
TLSEnabled == false,
|
TLSEnabled == false,
|
||||||
@ -548,7 +566,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
|||||||
StateData#state{socket = TLSSocket,
|
StateData#state{socket = TLSSocket,
|
||||||
streamid = new_id(),
|
streamid = new_id(),
|
||||||
tls_enabled = true
|
tls_enabled = true
|
||||||
}};
|
}, ?C2S_OPEN_TIMEOUT};
|
||||||
{?NS_COMPRESS, "compress"} when Zlib == true,
|
{?NS_COMPRESS, "compress"} when Zlib == true,
|
||||||
SockMod == gen_tcp ->
|
SockMod == gen_tcp ->
|
||||||
case xml:get_subtag(El, "method") of
|
case xml:get_subtag(El, "method") of
|
||||||
@ -557,7 +575,8 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
|||||||
{xmlelement, "failure",
|
{xmlelement, "failure",
|
||||||
[{"xmlns", ?NS_COMPRESS}],
|
[{"xmlns", ?NS_COMPRESS}],
|
||||||
[{xmlelement, "setup-failed", [], []}]}),
|
[{xmlelement, "setup-failed", [], []}]}),
|
||||||
{next_state, wait_for_feature_request, StateData};
|
{next_state, wait_for_feature_request, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT};
|
||||||
Method ->
|
Method ->
|
||||||
case xml:get_tag_cdata(Method) of
|
case xml:get_tag_cdata(Method) of
|
||||||
"zlib" ->
|
"zlib" ->
|
||||||
@ -570,14 +589,15 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
|||||||
{next_state, wait_for_stream,
|
{next_state, wait_for_stream,
|
||||||
StateData#state{socket = ZlibSocket,
|
StateData#state{socket = ZlibSocket,
|
||||||
streamid = new_id()
|
streamid = new_id()
|
||||||
}};
|
}, ?C2S_OPEN_TIMEOUT};
|
||||||
_ ->
|
_ ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
{xmlelement, "failure",
|
{xmlelement, "failure",
|
||||||
[{"xmlns", ?NS_COMPRESS}],
|
[{"xmlns", ?NS_COMPRESS}],
|
||||||
[{xmlelement, "unsupported-method",
|
[{xmlelement, "unsupported-method",
|
||||||
[], []}]}),
|
[], []}]}),
|
||||||
{next_state, wait_for_feature_request, StateData}
|
{next_state, wait_for_feature_request, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
@ -591,10 +611,14 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
|||||||
{stop, normal, StateData};
|
{stop, normal, StateData};
|
||||||
true ->
|
true ->
|
||||||
process_unauthenticated_stanza(StateData, El),
|
process_unauthenticated_stanza(StateData, El),
|
||||||
{next_state, wait_for_feature_request, StateData}
|
{next_state, wait_for_feature_request, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
wait_for_feature_request(timeout, StateData) ->
|
||||||
|
{stop, normal, StateData};
|
||||||
|
|
||||||
wait_for_feature_request({xmlstreamend, _Name}, StateData) ->
|
wait_for_feature_request({xmlstreamend, _Name}, StateData) ->
|
||||||
send_text(StateData, ?STREAM_TRAILER),
|
send_text(StateData, ?STREAM_TRAILER),
|
||||||
{stop, normal, StateData};
|
{stop, normal, StateData};
|
||||||
@ -627,7 +651,7 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
|||||||
StateData#state{streamid = new_id(),
|
StateData#state{streamid = new_id(),
|
||||||
authenticated = true,
|
authenticated = true,
|
||||||
user = U
|
user = U
|
||||||
}};
|
}, ?C2S_OPEN_TIMEOUT};
|
||||||
{continue, ServerOut, NewSASLState} ->
|
{continue, ServerOut, NewSASLState} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
{xmlelement, "challenge",
|
{xmlelement, "challenge",
|
||||||
@ -645,19 +669,25 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
|||||||
{xmlelement, "failure",
|
{xmlelement, "failure",
|
||||||
[{"xmlns", ?NS_SASL}],
|
[{"xmlns", ?NS_SASL}],
|
||||||
[{xmlelement, Error, [], []}]}),
|
[{xmlelement, Error, [], []}]}),
|
||||||
{next_state, wait_for_feature_request, StateData};
|
{next_state, wait_for_feature_request, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT};
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
{xmlelement, "failure",
|
{xmlelement, "failure",
|
||||||
[{"xmlns", ?NS_SASL}],
|
[{"xmlns", ?NS_SASL}],
|
||||||
[{xmlelement, Error, [], []}]}),
|
[{xmlelement, Error, [], []}]}),
|
||||||
{next_state, wait_for_feature_request, StateData}
|
{next_state, wait_for_feature_request, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
process_unauthenticated_stanza(StateData, El),
|
process_unauthenticated_stanza(StateData, El),
|
||||||
{next_state, wait_for_feature_request, StateData}
|
{next_state, wait_for_feature_request, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
wait_for_sasl_response(timeout, StateData) ->
|
||||||
|
{stop, normal, StateData};
|
||||||
|
|
||||||
wait_for_sasl_response({xmlstreamend, _Name}, StateData) ->
|
wait_for_sasl_response({xmlstreamend, _Name}, StateData) ->
|
||||||
send_text(StateData, ?STREAM_TRAILER),
|
send_text(StateData, ?STREAM_TRAILER),
|
||||||
{stop, normal, StateData};
|
{stop, normal, StateData};
|
||||||
@ -687,7 +717,7 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
|
|||||||
error ->
|
error ->
|
||||||
Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST),
|
Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST),
|
||||||
send_element(StateData, Err),
|
send_element(StateData, Err),
|
||||||
{next_state, wait_for_bind, StateData};
|
{next_state, wait_for_bind, StateData, ?C2S_OPEN_TIMEOUT};
|
||||||
_ ->
|
_ ->
|
||||||
JID = jlib:make_jid(U, StateData#state.server, R),
|
JID = jlib:make_jid(U, StateData#state.server, R),
|
||||||
Res = IQ#iq{type = result,
|
Res = IQ#iq{type = result,
|
||||||
@ -698,12 +728,16 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
|
|||||||
jlib:jid_to_string(JID)}]}]}]},
|
jlib:jid_to_string(JID)}]}]}]},
|
||||||
send_element(StateData, jlib:iq_to_xml(Res)),
|
send_element(StateData, jlib:iq_to_xml(Res)),
|
||||||
{next_state, wait_for_session,
|
{next_state, wait_for_session,
|
||||||
StateData#state{resource = R, jid = JID}}
|
StateData#state{resource = R, jid = JID},
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{next_state, wait_for_bind, StateData}
|
{next_state, wait_for_bind, StateData, ?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
wait_for_bind(timeout, StateData) ->
|
||||||
|
{stop, normal, StateData};
|
||||||
|
|
||||||
wait_for_bind({xmlstreamend, _Name}, StateData) ->
|
wait_for_bind({xmlstreamend, _Name}, StateData) ->
|
||||||
send_text(StateData, ?STREAM_TRAILER),
|
send_text(StateData, ?STREAM_TRAILER),
|
||||||
{stop, normal, StateData};
|
{stop, normal, StateData};
|
||||||
@ -760,12 +794,16 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
|||||||
jlib:jid_to_string(JID)]),
|
jlib:jid_to_string(JID)]),
|
||||||
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
||||||
send_element(StateData, Err),
|
send_element(StateData, Err),
|
||||||
{next_state, wait_for_session, StateData}
|
{next_state, wait_for_session, StateData,
|
||||||
|
?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{next_state, wait_for_session, StateData}
|
{next_state, wait_for_session, StateData, ?C2S_OPEN_TIMEOUT}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
wait_for_session(timeout, StateData) ->
|
||||||
|
{stop, normal, StateData};
|
||||||
|
|
||||||
wait_for_session({xmlstreamend, _Name}, StateData) ->
|
wait_for_session({xmlstreamend, _Name}, StateData) ->
|
||||||
send_text(StateData, ?STREAM_TRAILER),
|
send_text(StateData, ?STREAM_TRAILER),
|
||||||
{stop, normal, StateData};
|
{stop, normal, StateData};
|
||||||
|
Loading…
Reference in New Issue
Block a user