24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-06-10 21:47:01 +02:00

* src/tls/tls.erl: Added recv_data/2 function

* src/jlib.erl: Added NS_TLS macro

* src/ejabberd_receiver.erl: Support for STARTTLS
* src/ejabberd_c2s.erl: Likewise

SVN Revision: 252
This commit is contained in:
Alexey Shchepin 2004-08-01 20:12:20 +00:00
parent 6cd02b9714
commit 73d7e1161e
5 changed files with 104 additions and 33 deletions

View File

@ -1,3 +1,12 @@
2004-08-01 Alexey Shchepin <alexey@sevcom.net>
* src/tls/tls.erl: Added recv_data/2 function
* src/jlib.erl: Added NS_TLS macro
* src/ejabberd_receiver.erl: Support for STARTTLS
* src/ejabberd_c2s.erl: Likewise
2004-07-30 Alexey Shchepin <alexey@sevcom.net> 2004-07-30 Alexey Shchepin <alexey@sevcom.net>
* examples/extauth/check_pass_null.pl: A reference "null" * examples/extauth/check_pass_null.pl: A reference "null"

View File

@ -23,7 +23,7 @@
-export([init/1, -export([init/1,
wait_for_stream/2, wait_for_stream/2,
wait_for_auth/2, wait_for_auth/2,
wait_for_sasl_auth/2, wait_for_feature_request/2,
wait_for_bind/2, wait_for_bind/2,
wait_for_session/2, wait_for_session/2,
wait_for_sasl_response/2, wait_for_sasl_response/2,
@ -178,12 +178,26 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
{xmlelement, "mechanism", [], {xmlelement, "mechanism", [],
[{xmlcdata, S}]} [{xmlcdata, S}]}
end, cyrsasl:listmech()), end, cyrsasl:listmech()),
TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled,
SockMod = StateData#state.sockmod,
TLSFeature =
case (TLS == true) andalso
(TLSEnabled == false) andalso
(SockMod == gen_tcp) of
true ->
[{xmlelement, "starttls",
[{"xmlns", ?NS_TLS}], []}];
false ->
[]
end,
send_element(StateData, send_element(StateData,
{xmlelement, "stream:features", [], {xmlelement, "stream:features", [],
TLSFeature ++
[{xmlelement, "mechanisms", [{xmlelement, "mechanisms",
[{"xmlns", ?NS_SASL}], [{"xmlns", ?NS_SASL}],
Mechs}]}), Mechs}]}),
{next_state, wait_for_sasl_auth, {next_state, wait_for_feature_request,
StateData#state{sasl_state = SASLState, StateData#state{sasl_state = SASLState,
lang = Lang}}; lang = Lang}};
_ -> _ ->
@ -357,8 +371,11 @@ wait_for_auth(closed, StateData) ->
{stop, normal, StateData}. {stop, normal, StateData}.
wait_for_sasl_auth({xmlstreamelement, El}, StateData) -> wait_for_feature_request({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El, {xmlelement, Name, Attrs, Els} = El,
TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled,
SockMod = StateData#state.sockmod,
case {xml:get_attr_s("xmlns", Attrs), Name} of case {xml:get_attr_s("xmlns", Attrs), Name} of
{?NS_SASL, "auth"} -> {?NS_SASL, "auth"} ->
Mech = xml:get_attr_s("mechanism", Attrs), Mech = xml:get_attr_s("mechanism", Attrs),
@ -391,8 +408,22 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
{xmlelement, "failure", {xmlelement, "failure",
[{"xmlns", ?NS_SASL}], [{"xmlns", ?NS_SASL}],
[{xmlelement, Error, [], []}]}), [{xmlelement, Error, [], []}]}),
{next_state, wait_for_sasl_auth, StateData} {next_state, wait_for_feature_request, StateData}
end; end;
{?NS_TLS, "starttls"} when TLS == true,
TLSEnabled == false,
SockMod == gen_tcp ->
Socket = StateData#state.socket,
TLSOpts = StateData#state.tls_options,
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
ejabberd_receiver:starttls(StateData#state.receiver, TLSSocket),
send_element(StateData,
{xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
{next_state, wait_for_stream,
StateData#state{sockmod = tls,
socket = TLSSocket,
tls_enabled = true
}};
_ -> _ ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
#iq{xmlns = ?NS_REGISTER} = IQ -> #iq{xmlns = ?NS_REGISTER} = IQ ->
@ -403,21 +434,21 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1), Res = jlib:remove_attr("to", Res1),
send_element(StateData, Res), send_element(StateData, Res),
{next_state, wait_for_sasl_auth, StateData}; {next_state, wait_for_feature_request, StateData};
_ -> _ ->
{next_state, wait_for_sasl_auth, StateData} {next_state, wait_for_feature_request, StateData}
end end
end; end;
wait_for_sasl_auth({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};
wait_for_sasl_auth({xmlstreamerror, _}, StateData) -> wait_for_feature_request({xmlstreamerror, _}, StateData) ->
send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
wait_for_sasl_auth(closed, StateData) -> wait_for_feature_request(closed, StateData) ->
{stop, normal, StateData}. {stop, normal, StateData}.
@ -453,7 +484,7 @@ 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_sasl_auth, StateData} {next_state, wait_for_feature_request, StateData}
end; end;
_ -> _ ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
@ -465,9 +496,9 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1), Res = jlib:remove_attr("to", Res1),
send_element(StateData, Res), send_element(StateData, Res),
{next_state, wait_for_sasl_auth, StateData}; {next_state, wait_for_feature_request, StateData};
_ -> _ ->
{next_state, wait_for_sasl_auth, StateData} {next_state, wait_for_feature_request, StateData}
end end
end; end;

View File

@ -13,7 +13,8 @@
-export([start/3, -export([start/3,
receiver/4, receiver/4,
change_shaper/2, change_shaper/2,
reset_stream/1]). reset_stream/1,
starttls/2]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
@ -34,7 +35,30 @@ receiver(Socket, SockMod, Shaper, C2SPid) ->
receiver(Socket, SockMod, ShaperState, C2SPid, XMLStreamPid, Timeout). receiver(Socket, SockMod, ShaperState, C2SPid, XMLStreamPid, Timeout).
receiver(Socket, SockMod, ShaperState, C2SPid, XMLStreamPid, Timeout) -> receiver(Socket, SockMod, ShaperState, C2SPid, XMLStreamPid, Timeout) ->
case catch SockMod:recv(Socket, 0, Timeout) of Res = (catch SockMod:recv(Socket, 0, Timeout)),
case Res of
{ok, Data} ->
receive
{starttls, TLSSocket} ->
exit(XMLStreamPid, closed),
XMLStreamPid1 = xml_stream:start(self(), C2SPid),
TLSRes = tls:recv_data(TLSSocket, Data),
receiver1(TLSSocket, tls,
ShaperState, C2SPid, XMLStreamPid1, Timeout,
TLSRes)
after 0 ->
receiver1(Socket, SockMod,
ShaperState, C2SPid, XMLStreamPid, Timeout,
Res)
end;
_ ->
receiver1(Socket, SockMod,
ShaperState, C2SPid, XMLStreamPid, Timeout, Res)
end.
receiver1(Socket, SockMod, ShaperState, C2SPid, XMLStreamPid, Timeout, Res) ->
case Res of
{ok, Text} -> {ok, Text} ->
ShaperSt1 = receive ShaperSt1 = receive
{change_shaper, Shaper} -> {change_shaper, Shaper} ->
@ -75,4 +99,7 @@ change_shaper(Pid, Shaper) ->
reset_stream(Pid) -> reset_stream(Pid) ->
Pid ! reset_stream. Pid ! reset_stream.
starttls(Pid, TLSSocket) ->
Pid ! {starttls, TLSSocket}.

View File

@ -40,6 +40,7 @@
-define(NS_STANZAS, "urn:ietf:params:xml:ns:xmpp-stanzas"). -define(NS_STANZAS, "urn:ietf:params:xml:ns:xmpp-stanzas").
-define(NS_STREAMS, "urn:ietf:params:xml:ns:xmpp-streams"). -define(NS_STREAMS, "urn:ietf:params:xml:ns:xmpp-streams").
-define(NS_TLS, "urn:ietf:params:xml:ns:xmpp-tls").
-define(NS_SASL, "urn:ietf:params:xml:ns:xmpp-sasl"). -define(NS_SASL, "urn:ietf:params:xml:ns:xmpp-sasl").
-define(NS_SESSION, "urn:ietf:params:xml:ns:xmpp-session"). -define(NS_SESSION, "urn:ietf:params:xml:ns:xmpp-session").
-define(NS_BIND, "urn:ietf:params:xml:ns:xmpp-bind"). -define(NS_BIND, "urn:ietf:params:xml:ns:xmpp-bind").

View File

@ -15,7 +15,7 @@
-export([start/0, start_link/0, -export([start/0, start_link/0,
tcp_to_tls/2, tls_to_tcp/1, tcp_to_tls/2, tls_to_tcp/1,
send/2, send/2,
recv/2, recv/3, recv/2, recv/3, recv_data/2,
close/1, close/1,
test/0]). test/0]).
@ -86,7 +86,6 @@ tcp_to_tls(TCPSocket, Options) ->
{value, {certfile, CertFile}} -> {value, {certfile, CertFile}} ->
ok = erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv), ok = erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv),
Port = open_port({spawn, tls_drv}, [binary]), Port = open_port({spawn, tls_drv}, [binary]),
io:format("open_port: ~p~n", [Port]),
case port_control(Port, ?SET_CERTIFICATE_FILE, case port_control(Port, ?SET_CERTIFICATE_FILE,
CertFile ++ [0]) of CertFile ++ [0]) of
<<0>> -> <<0>> ->
@ -104,23 +103,27 @@ tls_to_tcp(#tlssock{tcpsock = TCPSocket, tlsport = Port}) ->
recv(Socket, Length) -> recv(Socket, Length) ->
recv(Socket, Length, infinity). recv(Socket, Length, infinity).
recv(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Length, Timeout) -> recv(#tlssock{tcpsock = TCPSocket, tlsport = Port} = TLSSock,
Length, Timeout) ->
case gen_tcp:recv(TCPSocket, Length, Timeout) of case gen_tcp:recv(TCPSocket, Length, Timeout) of
{ok, Packet} -> {ok, Packet} ->
case port_control(Port, ?SET_ENCRYPTED_INPUT, Packet) of recv_data(TLSSock, Packet);
<<0>> -> {error, _Reason} = Error ->
case port_control(Port, ?GET_DECRYPTED_INPUT, []) of Error
<<0, In/binary>> -> end.
case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of
<<0, Out/binary>> -> recv_data(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet) ->
case gen_tcp:send(TCPSocket, Out) of case port_control(Port, ?SET_ENCRYPTED_INPUT, Packet) of
ok -> <<0>> ->
{ok, In}; case port_control(Port, ?GET_DECRYPTED_INPUT, []) of
Error -> <<0, In/binary>> ->
Error case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of
end; <<0, Out/binary>> ->
<<1, Error/binary>> -> case gen_tcp:send(TCPSocket, Out) of
{error, binary_to_list(Error)} ok ->
{ok, In};
Error ->
Error
end; end;
<<1, Error/binary>> -> <<1, Error/binary>> ->
{error, binary_to_list(Error)} {error, binary_to_list(Error)}
@ -128,8 +131,8 @@ recv(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Length, Timeout) ->
<<1, Error/binary>> -> <<1, Error/binary>> ->
{error, binary_to_list(Error)} {error, binary_to_list(Error)}
end; end;
{error, _Reason} = Error -> <<1, Error/binary>> ->
Error {error, binary_to_list(Error)}
end. end.
send(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet) -> send(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet) ->