[erlang-questions] Listen to SSL and normal TCP connections on the same port

Tony Rogvall tony@REDACTED
Wed Apr 17 10:15:26 CEST 2013


Hi!

In general it is not possible to detect and upgrade a socket to ssl, BUT if the client initiate with some 
known message data that can be distinguished from the SSL hello message, like HTTP requests then 
you can do something like (I have, and it works :-):

The socket should already be in {packet,0} packet mode, set {active,false}, {packet,0} in the options to listen.
Then either read in passive mode:

	{ok,Header} = gen_tcp:recv(Socket, MinHeaderBlockSize),		%% say 8 bytes ?

Or something like this in active once mode
	inet:setopts(Socket, [{active, once}]),	%% not easy to control the number of bytes received here yet (there is an EEP!)
	Header = 
	receive
		{tcp, Socket, Header} -> ok
	end
		
Then do a match on the data that the client normally send with some known SSL intro messages:

	Type = detect(Header),

detect(<<"GET", _/binary>>) ->    plain;
detect(<<"POST", _/binary>>) ->    plain;
detect(<<"OPTIONS", _/binary>>) ->  plain;
detect(<<"TRACE", _/binary>>) ->    plain;
...
detect(<<1:1,_Len:15,1:8,_Version:16, _/binary>>) ->  ssl;
detect(<<ContentType:8, _Version:16, _Length:16, _/binary>>) ->
    if ContentType == 22 ->  %% HANDSHAKE
            ssl;
       true ->
            undefined
    end;
detect(_) ->
    undefined.

Then switch to ssl if that was detected:

	if Type =:= ssl ->
		%% Socket MUST be in passive mode at this point
		gen_tcp:unrecv(Socket, Header),		%% push back SSL data 
		{ok, SSLSocket} = ssl:ssl_accept(Socket, SSLOptions, SSLAcceptTimeout),
		do_ssl_request(SSLSocket);
	    true ->
		do_plain_request(Socket)
	end

/Tony

On 17 apr 2013, at 09:41, Ingela Andin <ingela.andin@REDACTED> wrote:

> Hi!
> 
> 2013/4/17 pablo platt <pablo.platt@REDACTED>
> Hi,
> 
> Is it possible to accept SSL connections and normal TCP connections on the same port?
> Maybe accept normal TCP connections. If the connection is SSL connection pass it to the ssl module  and if it is a normal TCP connection just handle the socket.
> 
> It is possible to upgrade a tcp socket to an ssl socket.
> 
> If it is possible, how can I distinct SSL from non SSL connections?
> 
> That is the hard part. You must have some scheme to negotiate the upgrade with the client over plain tcp. (Like STARTTLS, HTTP Connect etc)
>  
> How can I pass the socket to the ssl module?
> 
> ssl:ssl_accept(TcpSocket, SslOptions)  or ssl:connect(TcpSocket, SslOptions) 
> make sure the socket is passive ({active, false}) before you make the call.
> 
> Regards Ingela Erlang/OTP team Ericsson AB
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

"Installing applications can lead to corruption over time. Applications gradually write over each other's libraries, partial upgrades occur, user and system errors happen, and minute changes may be unnoticeable and difficult to fix"



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130417/29d3f35e/attachment.htm>


More information about the erlang-questions mailing list