SSL in Erlang/OTP
Peter H|gfeldt
peter@REDACTED
Wed Nov 26 21:10:11 CET 2003
Yes, I agree that ssl:recv/x and ssl:send/x should behave as
gen_tcp:recv/x and gen_tcp:send/x do.
I will add that request to the todo-list for the next release.
I also agree that there should be some kind of "pre_accept" that
returns a "raw" non-SSL socket, to be closed on reasons you have
mentioned (although I think a firewall is the proper agent for
denying attacks).
I will add that request to the todo-list.
With a "pre_accept" and a "post_accept" that does SSL handshaking, it is
natural to add also a "pre_connect" and a corresponding "post_connect".
That will achieve your request for a "STARTTTLS" command (there must of
course be a well-defined protocol on top for this).
I will add that to the todo-list.
/Peter
> Hello, Peter!
>
> On Wed, 19 Nov 2003 20:37:35 +0100 (MET), you said:
>
> >> Can anyone help with following issues with SSL application?
> >>
> >> * ssl:accept locks when when one TCP connection is established, but SSL
> >> handshake is not finished. E.g. if Yaws is listen for SSL connections on
> >> port 443 and someone runs "telnet this.server 443" (note that this is not
> >> SSL-enabled telnet), then noone will be able to retreive web pages via this
> >> port until this connection will be closed. As temporary solution I use
> >> ssl:accept with small timeout value, but this is just workaround. IMHO
> >> ssl:accept should not have such behaviour.
>
> PH> In Erlang/OTP SSL you can have several processes, each waiting for an
> PH> ssl:accept/N on one and the the same port. That is needed to obtain
> PH> acceptable (no pun intended) parallellism.
>
> I.e. I need to run several such processess?:
>
> accept(ListenSocket, Opts) ->
> case ssl:accept(ListenSocket) of
> {ok, Socket} ->
> % Start new process for Socket
> accept(ListenSocket, Opts);
> {error, Reason} -> ...
> end.
>
> But even if I run e.g. 1000 such parallell accepts, malicious user still can
> open 1000 connections with the way I describe above (with ssl:accept locking),
> which will make service unaccessible for other users.
>
> So IMHO ssl:accept should return immediately after TCP connection to listened
> port will be established with new socket in "handshaking" state. In this state
> must be possible to know sockname (e.g. to prevent many conections from one
> host), and data sended with ssl:send will be writed to queue, which will be
> sended after handshaking.
>
> PH> That it not practically possible with gen_tcp:accept/N (if you try it you
> PH> will get an error return). I think gen_tcp should accept multiple accepts
> PH> as well.
>
> >> * ssl:send locks if another process runs ssl:recv on the same port. And I
> >> can't use "{active, true}" option, because I need flow control. Again, as
> >> a temporary solution I use timeout value in ssl:recv/3, so ssl:send can
> >> work several times in second. But this makes notable increase of CPU load:
> >> e.g. with ejabberd on jabber.ru (~440 connected users, ~100 using SSL) with
> >> 20ms timeout -- CPU load is ~40%, with 200ms -- 9-12%, with SSL switched
> >> off -- 3-4%.
>
> PH> When an SSL-connection has been established all data flow through gen_tcp
> PH> to/from the SSL portprogram, which is then just a multiplexer of data
> PH> (slow connections will not impair fast connections).
>
> PH> Seems as if your problem is really a gen_tcp problem?
>
> I think this is ssl_broker problem, look:
>
> %% recv - passive mode
> %%
> handle_call({recv, Client, Length, Timeout}, From, St)
> when St#st.status =/= closed, St#st.active == false ->
> debug(St, "recv: client = ~w~n", [Client]),
> Reply = gen_tcp:recv(St#st.proxysock, Length, Timeout),
> {reply, Reply, St};
>
> (This is part of ssl_broker.erl from R8B, but R9C do almost the same)
>
> After ssl:recv call, appropriate ssl_broker process hangs inside gen_tcp:recv,
> and can't process other requests (including ssl:send). It seems this can be
> solved by moving gen_tcp:recv call to another process... What about something
> like this:
>
> recv(Socket, Length, Timeout) when record(Socket, sslsocket) ->
> Req = {recv, self()},
> ProxySock = gen_server:call(Socket#sslsocket.pid, Req, infinity),
> case gen_tcp:recv(St#st.proxysock, Length, Timeout) of
> {ok, _} = Result -> Result;
> {error, timeout} -> {error, timeout};
> {error, Reason} = Error ->
> gen_server:call(Socket#sslsocket.pid, {switch to closing state}, infinity),
> Error
> end.
>
> handle_call({recv, Client}, From, St)
> when St#st.status =/= closed, St#st.active == false ->
> debug(St, "recv: client = ~w~n", [Client]),
> Reply = St#st.proxysock,
> {reply, Reply, St};
>
> I.e. gen_tcp:recv will be executed in process that calls ssl:recv.
>
> >> * (Feature Request) Many protocols have some kinds of STARTTLS command
> >> (e.g. IMAP, POP3 (RFC2595), Jabber/XMPP). So this would be great to have
> >> ability to convert gen_tcp sockets to ssl ones.
>
> PH> Ok, I am not familiar with STARTTLS or similar, but I will investigate it.
>
> Thanks!
>
More information about the erlang-questions
mailing list