diff --git a/test/emqttd_SUITE.erl b/test/emqttd_SUITE.erl index 4ae7884e3..2df2ccfd8 100644 --- a/test/emqttd_SUITE.erl +++ b/test/emqttd_SUITE.erl @@ -26,6 +26,15 @@ -define(CONTENT_TYPE, "application/x-www-form-urlencoded"). +-define(MQTT_SSL_MUTWAY, [{cacertfile, "certs/cacert.pem"}, + {verify, verify_peer}, + {fail_if_no_peer_cert, true}]). + +-define(MQTT_SSL_CLIENT, [{keyfile, "certs/client-key.pem"}, + {cacertfile, "certs/cacert.pem"}, + {certfile, "certs/client-cert.pem"}]). + + all() -> [{group, protocol}, {group, pubsub}, @@ -43,7 +52,8 @@ all() -> groups() -> [{protocol, [sequence], [mqtt_connect, - mqtt_ssl_oneway]}, + mqtt_ssl_oneway, + mqtt_ssl_mutway]}, {pubsub, [sequence], [subscribe_unsubscribe, publish, pubsub, @@ -98,8 +108,11 @@ groups() -> init_per_suite(Config) -> application:start(lager), DataDir = proplists:get_value(data_dir, Config), - start_apps(emqttd, DataDir), - Config. + NewConfig = emqttd_config(DataDir), + Vals = change_opts(ssl_oneway, DataDir, proplists:get_value(emqttd, NewConfig)), + [application:set_env(emqttd, Par, Value) || {Par, Value} <- Vals], + application:ensure_all_started(emqttd), + [{config, NewConfig} | Config]. end_per_suite(_Config) -> application:stop(emqttd), @@ -134,9 +147,6 @@ mqtt_ssl_oneway(_) -> {ok, Pub} = emqttc:start_link([{host, "localhost"}, {client_id, <<"pub">>}]), - timer:sleep(10), - emqttc:publish(Pub, <<"topic">>, <<"SSL oneWay test">>, [{qos, 1}]), - timer:sleep(10), receive {publish, _Topic, RM} -> ?assertEqual(<<"SSL oneWay test">>, RM) after 1000 -> false @@ -144,6 +154,32 @@ mqtt_ssl_oneway(_) -> emqttc:disconnect(SslOneWay), emqttc:disconnect(Pub). +mqtt_ssl_mutway(Config) -> + emqttd_cluster:prepare(), + DataDir = proplists:get_value(data_dir, Config), + EmqConfig = proplists:get_value(config, Config), + Vals = change_opts(ssl_mut, DataDir, proplists:get_value(emqttd, EmqConfig)), + [application:set_env(emqttd, Par, Value) || {Par, Value} <- Vals], + emqttd_cluster:reboot(), + + ClientSSl = [{Key, filename:join([DataDir, File])} || + {Key, File} <- ?MQTT_SSL_CLIENT ], + {ok, SslMutWay} = emqttc:start_link([{host, "localhost"}, + {port, 8883}, + {client_id, <<"sslmut">>}, + {ssl, ClientSSl}]), + {ok, Sub} = emqttc:start_link([{host, "localhost"}, + {client_id, <<"sub">>}]), + emqttc:subscribe(Sub, <<"topic">>, qos1), + emqttc:publish(SslMutWay, <<"topic">>, <<"ssl client pub message">>, [{qos, 1}]), + timer:sleep(10), + receive {publish, _Topic, RM} -> + ?assertEqual(<<"ssl client pub message">>, RM) + after 1000 -> false + end, + emqttc:disconnect(SslMutWay), + emqttc:disconnect(Sub). + %%-------------------------------------------------------------------- %% PubSub Test %%-------------------------------------------------------------------- @@ -607,16 +643,12 @@ slave(emqttd, Node) -> slave(node, Node) -> {ok, N} = slave:start(host(), Node, "-pa ../../ebin -pa ../../deps/*/ebin"), N. +emqttd_config(DataDir) -> + Schema = cuttlefish_schema:files([filename:join([DataDir, "emqttd.schema"])]), + Conf = conf_parse:file(filename:join([DataDir, "emqttd.conf"])), + cuttlefish_generator:map(Schema, Conf). -start_apps(App, DataDir) -> - Schema = cuttlefish_schema:files([filename:join([DataDir, atom_to_list(App) ++ ".schema"])]), - Conf = conf_parse:file(filename:join([DataDir, atom_to_list(App) ++ ".conf"])), - NewConfig = cuttlefish_generator:map(Schema, Conf), - Vals = merge_opts(App, DataDir, proplists:get_value(App, NewConfig)), - [application:set_env(App, Par, Value) || {Par, Value} <- Vals], - application:ensure_all_started(App). - -merge_opts(emqttd, DataDir, Vals) -> +change_opts(SslType, DataDir, Vals) -> Listeners = proplists:get_value(listeners, Vals), NewListeners = lists:foldl(fun({Protocol, Port, Opts} = Listener, Acc) -> case Protocol of @@ -624,15 +656,21 @@ merge_opts(emqttd, DataDir, Vals) -> SslOpts = proplists:get_value(ssl, Opts), Keyfile = filename:join([DataDir, proplists:get_value(keyfile, SslOpts)]), Certfile = filename:join([DataDir, proplists:get_value(certfile, SslOpts)]), - TupleList2 = lists:keyreplace(keyfile, 1, SslOpts, {keyfile, Keyfile}), - TupleList3 = lists:keyreplace(certfile, 1, TupleList2, {certfile, Certfile}), + TupleList1 = lists:keyreplace(keyfile, 1, SslOpts, {keyfile, Keyfile}), + TupleList2 = lists:keyreplace(certfile, 1, TupleList1, {certfile, Certfile}), + TupleList3 = + case SslType of + ssl_mut -> + CAfile = filename:join([DataDir, proplists:get_value(cacertfile, ?MQTT_SSL_MUTWAY)]), + MutSslList = lists:keyreplace(cacertfile, 1, ?MQTT_SSL_MUTWAY, {cacertfile, CAfile}), + lists:merge(TupleList2, MutSslList); + _ -> + TupleList2 + end, [{Protocol, Port, [{ssl, TupleList3}]} | Acc]; _ -> [Listener | Acc] end end, [], Listeners), - lists:keyreplace(listeners, 1, Vals, {listeners, NewListeners}); - -merge_opts(_, _, Vals) -> - Vals. + lists:keyreplace(listeners, 1, Vals, {listeners, NewListeners}).