From e7aa2ccad03ddf92b3410a407c5bf6cc571514c9 Mon Sep 17 00:00:00 2001 From: Sebastian Cohnen Date: Fri, 1 Feb 2019 19:11:42 +0100 Subject: [PATCH 1/3] add cert and key element under certificate to accept inline data --- src/tsung/ts_client.erl | 9 +++++++-- src/tsung_controller/ts_config.erl | 17 +++++++++++++++-- tsung-1.0.dtd | 4 +++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/tsung/ts_client.erl b/src/tsung/ts_client.erl index 6ab139238..2c0f1fbac 100644 --- a/src/tsung/ts_client.erl +++ b/src/tsung/ts_client.erl @@ -496,8 +496,8 @@ handle_next_action(State=#state_rcv{dynvars = DynVars}) -> RateConf=#token_bucket{rate=Rate,burst=Burst,last_packet_date=?NOW}, Thresh=lists:min([Burst,State#state_rcv.size_mon_thresh]), handle_next_action(State#state_rcv{size_mon=Thresh,size_mon_thresh=Thresh,rate_limit=RateConf,count=Count}); - {set_option, undefined, certificate, {Cacert, KeyFile, KeyPass, CertFile}} -> - ?LOGF("Set client certificate: ~p ~p ~p ~p~n",[Cacert, KeyFile, KeyPass, CertFile],?DEB), + {set_option, undefined, certificate, {Cacert, KeyFile, TLSKey, KeyPass, CertFile, TLSCert}} -> + ?LOGF("Set client certificate: ~p ~p ~p ~p ~p ~p ~n",[Cacert, KeyFile, TLSKey, KeyPass, CertFile, TLSCert],?DEB), Opts = ts_utils:filtermap(fun({N,V}) -> case V of undefined -> @@ -509,7 +509,9 @@ handle_next_action(State=#state_rcv{dynvars = DynVars}) -> end end , [{certfile, CertFile}, + {cert,TLSCert}, {keyfile,KeyFile}, + {key,TLSKey}, {password,KeyPass}, {cacertfile,Cacert}]), ?LOGF("SSL options for certificate: ~p~n",[Opts],?DEB), @@ -1050,6 +1052,9 @@ reconnect(none, ServerName, Port, {Protocol, Proto_opts}, {IP,CPort, Try}) when end, ?LOGF("Connect failed with client port ~p, retry with ~p~n",[CPort, NewCPort],?INFO), reconnect(none, ServerName, Port, {Protocol, Proto_opts}, {IP,NewCPort, undefined}); + {{options, {Option, _}}, _, _} -> + CountName="error_connect_option_"++atom_to_list(Option), + ts_mon_cache:add({ count, list_to_atom(CountName) }); _ -> CountName="error_connect_"++atom_to_list(Reason), ts_mon_cache:add({ count, list_to_atom(CountName) }) diff --git a/src/tsung_controller/ts_config.erl b/src/tsung_controller/ts_config.erl index e15419a4b..bf0e250b8 100644 --- a/src/tsung_controller/ts_config.erl +++ b/src/tsung_controller/ts_config.erl @@ -720,14 +720,27 @@ parse( Element = #xmlElement{name=set_option, attributes=Attrs}, Max = getAttr(integer, Attrs, max, Rate), {undefined, rate_limit, {1024*Rate div 1000, 1024 * Max}}; "certificate" -> - {value, #xmlElement{attributes=AttrCert}} = lists:keysearch(certificate, + {value, CertificateElement = #xmlElement{attributes=AttrCert}} = lists:keysearch(certificate, #xmlElement.name, Element#xmlElement.content), Cacert = getAttr(string, AttrCert, cacertfile, undefined), KeyFile = getAttr(string, AttrCert, keyfile, undefined), KeyPass = getAttr(string, AttrCert, keypass, undefined), CertFile = getAttr(string, AttrCert, certfile, undefined), - {undefined, certificate, {Cacert, KeyFile,KeyPass,CertFile}}; + + TLSCert = case lists:keysearch(cert, #xmlElement.name, CertificateElement#xmlElement.content) of + {value, #xmlElement{content=CertRaw}} -> + ts_utils:clean_str(getText(CertRaw)); + _ -> undefined + end, + + TLSKey = case lists:keysearch(key, #xmlElement.name, CertificateElement#xmlElement.content) of + {value, #xmlElement{content=KeyRaw}} -> + ts_utils:clean_str(getText(KeyRaw)); + _ -> undefined + end, + + {undefined, certificate, {Cacert, KeyFile, TLSKey, KeyPass, CertFile, TLSCert}}; "connect_timeout" -> ConnectTimeout = getAttr(integer, Attrs, value), {undefined, connect_timeout, {ConnectTimeout}} diff --git a/tsung-1.0.dtd b/tsung-1.0.dtd index a8ffb1e0e..acf39bd11 100644 --- a/tsung-1.0.dtd +++ b/tsung-1.0.dtd @@ -124,13 +124,15 @@ type (ts_http | ts_jabber | ts_pgsql) #IMPLIED value CDATA #IMPLIED> - + + + Date: Sat, 2 Feb 2019 17:23:23 +0100 Subject: [PATCH 2/3] decode key and certificate --- src/tsung/ts_client.erl | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/tsung/ts_client.erl b/src/tsung/ts_client.erl index 2c0f1fbac..3bec438a4 100644 --- a/src/tsung/ts_client.erl +++ b/src/tsung/ts_client.erl @@ -507,16 +507,33 @@ handle_next_action(State=#state_rcv{dynvars = DynVars}) -> Val -> {true, {N,ts_search:subst(Val, DynVars)}} end - end , + end, [{certfile, CertFile}, {cert,TLSCert}, {keyfile,KeyFile}, {key,TLSKey}, {password,KeyPass}, {cacertfile,Cacert}]), - ?LOGF("SSL options for certificate: ~p~n",[Opts],?DEB), + + Opts2 = ts_utils:filtermap( + fun({N,V}) -> + case {N,V} of + {_, undefined} -> false; + {key, _} -> + [{KeyType, KeyData, _} | _] = public_key:pem_decode(list_to_binary(V)), + {true, {key, {KeyType, KeyData}}}; + {cert, _} -> + [{'Certificate', CertData, _} | _] = public_key:pem_decode(list_to_binary(V)), + {true, {cert, CertData}}; + {_, V} -> {true, {N,V}} + end + end, + Opts + ), + + ?LOGF("SSL options for certificate: ~p~n",[Opts2],?DEB), OldOpts = State#state_rcv.proto_opts, - NewOpts = OldOpts#proto_opts{certificate = Opts}, + NewOpts = OldOpts#proto_opts{certificate = Opts2}, %% close connection if necessary (State#state_rcv.protocol):close(State#state_rcv.socket), set_connected_status(false), From ab2a0cf7ed28514125048b08b320cb22f8ca7db7 Mon Sep 17 00:00:00 2001 From: Sebastian Cohnen Date: Mon, 4 Feb 2019 10:26:03 +0100 Subject: [PATCH 3/3] handle tls_alert --- src/tsung/ts_client.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tsung/ts_client.erl b/src/tsung/ts_client.erl index 3bec438a4..f2f0f9efa 100644 --- a/src/tsung/ts_client.erl +++ b/src/tsung/ts_client.erl @@ -1072,6 +1072,8 @@ reconnect(none, ServerName, Port, {Protocol, Proto_opts}, {IP,CPort, Try}) when {{options, {Option, _}}, _, _} -> CountName="error_connect_option_"++atom_to_list(Option), ts_mon_cache:add({ count, list_to_atom(CountName) }); + {tls_alert, "bad certificate"} -> + ts_mon_cache:add({ count, list_to_atom("error_connect_tls_bad_certificate") }); _ -> CountName="error_connect_"++atom_to_list(Reason), ts_mon_cache:add({ count, list_to_atom(CountName) })