mirror of
https://github.com/processone/ejabberd.git
synced 2024-10-31 15:21:38 +01: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:
parent
6cd02b9714
commit
73d7e1161e
@ -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"
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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}.
|
||||||
|
|
||||||
|
|
||||||
|
@ -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").
|
||||||
|
@ -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) ->
|
||||||
|
Loading…
Reference in New Issue
Block a user