Browse Source

Allow listening with only SNI options

Cert/certfile is no longer required if SNI options are provided.
Loïc Hoguin 8 years ago
parent
commit
da68b2009f
2 changed files with 33 additions and 2 deletions
  1. 3 1
      src/ranch_ssl.erl
  2. 30 1
      test/acceptor_SUITE.erl

+ 3 - 1
src/ranch_ssl.erl

@@ -90,7 +90,9 @@ messages() -> {ssl, ssl_closed, ssl_error}.
 -spec listen(opts()) -> {ok, ssl:sslsocket()} | {error, atom()}.
 -spec listen(opts()) -> {ok, ssl:sslsocket()} | {error, atom()}.
 listen(Opts) ->
 listen(Opts) ->
 	true = lists:keymember(cert, 1, Opts)
 	true = lists:keymember(cert, 1, Opts)
-		orelse lists:keymember(certfile, 1, Opts),
+		orelse lists:keymember(certfile, 1, Opts)
+		orelse lists:keymember(sni_fun, 1, Opts)
+		orelse lists:keymember(sni_hosts, 1, Opts),
 	Opts2 = ranch:set_option_default(Opts, backlog, 1024),
 	Opts2 = ranch:set_option_default(Opts, backlog, 1024),
 	Opts3 = ranch:set_option_default(Opts2, ciphers, unbroken_cipher_suites()),
 	Opts3 = ranch:set_option_default(Opts2, ciphers, unbroken_cipher_suites()),
 	Opts4 = ranch:set_option_default(Opts3, nodelay, true),
 	Opts4 = ranch:set_option_default(Opts3, nodelay, true),

+ 30 - 1
test/acceptor_SUITE.erl

@@ -39,7 +39,9 @@ groups() ->
 		ssl_accept_error,
 		ssl_accept_error,
 		ssl_accept_socket,
 		ssl_accept_socket,
 		ssl_active_echo,
 		ssl_active_echo,
-		ssl_echo
+		ssl_echo,
+		ssl_sni_echo,
+		ssl_sni_fail
 	]}, {misc, [
 	]}, {misc, [
 		misc_bad_transport,
 		misc_bad_transport,
 		misc_bad_transport_options
 		misc_bad_transport_options
@@ -132,6 +134,33 @@ ssl_echo(_) ->
 	{'EXIT', _} = begin catch ranch:get_port(Name) end,
 	{'EXIT', _} = begin catch ranch:get_port(Name) end,
 	ok.
 	ok.
 
 
+ssl_sni_echo(_) ->
+	doc("Ensure that SNI works with SSL transport."),
+	Name = name(),
+	Opts = ct_helper:get_certs_from_ets(),
+	{ok, _} = ranch:start_listener(Name, 1, ranch_ssl, [{sni_hosts, [{"localhost", Opts}]}], echo_protocol, []),
+	Port = ranch:get_port(Name),
+	{ok, Socket} = ssl:connect("localhost", Port, [binary, {active, false}, {packet, raw}]),
+	ok = ssl:send(Socket, <<"SSL Ranch is working!">>),
+	{ok, <<"SSL Ranch is working!">>} = ssl:recv(Socket, 21, 1000),
+	ok = ranch:stop_listener(Name),
+	{error, closed} = ssl:recv(Socket, 0, 1000),
+	%% Make sure the listener stopped.
+	{'EXIT', _} = begin catch ranch:get_port(Name) end,
+	ok.
+
+ssl_sni_fail(_) ->
+	doc("Ensure that connection fails when host is not in SNI list."),
+	Name = name(),
+	Opts = ct_helper:get_certs_from_ets(),
+	{ok, _} = ranch:start_listener(Name, 1, ranch_ssl, [{sni_hosts, [{"pouet", Opts}]}], echo_protocol, []),
+	Port = ranch:get_port(Name),
+	{error, _} = ssl:connect("localhost", Port, [binary, {active, false}, {packet, raw}]),
+	ok = ranch:stop_listener(Name),
+	%% Make sure the listener stopped.
+	{'EXIT', _} = begin catch ranch:get_port(Name) end,
+	ok.
+
 %% tcp.
 %% tcp.
 
 
 tcp_accept_socket(_) ->
 tcp_accept_socket(_) ->