Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

merge sip-digest patch (Jason Tucker)

SVN Revision: 652
  • Loading branch information...
commit 29482d40c3ba60b0a21fab81649b099ec9058b84 1 parent 5046cec
@nniclausse nniclausse authored
View
3  CONTRIBUTORS
@@ -13,6 +13,8 @@ o Micka
various patches for HTTP; configure support; SOAP support; initial
dynamic substitution implementation.
+o Jason Tucker: Solaris testing and fixes, jabber patches (sip_digest, ...).
+
o Jonathan Bresler: Jabber testing and bug reporting
o Gordon Guthrie: tips for ssh setup on Suse
o Romain Lenglet: Suggestions for ts_os_mon
@@ -20,5 +22,4 @@ o Johann Messner: Bug reports
o Anders Nygren: Documentation updates/suggestions, fix for recorder
o Adam Spotton: Bug reports and tests (status, HTTP proxy load testing)
o Matthew Schulkind: small fix to freemem computation
-o Jason Tucker: Solaris testing and fixes, jabber patches.
o Jesper Wilhelmsson: testing
View
6 include/ts_jabber.hrl
@@ -33,9 +33,11 @@
jud_param,
cle,
id = 0,
- domain, %% jabber domain
+ domain, %% jabber domain
username, %% first chars of username (will append id dynamically)
- passwd %% first chars of passwd (will append id dynamically)
+ passwd, %% first chars of passwd (will append id dynamically)
+ nonce, %% used to generate sip-digest passwd
+ sid %% used to generate digest passwd
}).
-define(setroster_intensity, 1/(ts_utils:get_val(setroster)*1000)).
View
79 src/tsung/ts_digest.erl
@@ -0,0 +1,79 @@
+%%%
+%%% Created: Apr 2006 by Jason Tucker <jasonwtucker@gmail.com>
+%%%
+%%% Modified by Nicolas Niclausse
+%%%
+%%% This program is free software; you can redistribute it and/or modify
+%%% it under the terms of the GNU General Public License as published by
+%%% the Free Software Foundation; either version 2 of the License, or
+%%% (at your option) any later version.
+%%%
+%%% This program is distributed in the hope that it will be useful,
+%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%%% GNU General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+%%% In addition, as a special exception, you have the permission to
+%%% link the code of this program with any library released under
+%%% the EPL license and distribute linked combinations including
+%%% the two.
+
+-module(ts_digest).
+-author('jasonwtucker@gmail.com').
+
+-export([ digest/2, sip_digest/4,
+ md5hex/1, shahex/1, tohex/1
+ ]).
+
+%%%----------------------------------------------------------------------
+%%% Func: sip_digest/4
+%%%----------------------------------------------------------------------
+sip_digest(Nonce, Jid, Realm, Passwd) ->
+ HA1 = md5hex(Jid ++ ":" ++ Realm ++ ":" ++ Passwd),
+ HA2 = md5hex("REGISTER:" ++ Jid),
+ INTEGRITY = md5hex(Nonce ++ ":" ++ HA2),
+ HA3 = md5hex(HA1 ++ ":" ++ INTEGRITY),
+ {HA3,INTEGRITY}.
+
+%%%----------------------------------------------------------------------
+%%% Func: digest/2
+%%% Computes XMPP digest password described in JEP-0078
+%%%----------------------------------------------------------------------
+digest(Sid, Passwd) ->
+ HA1 = shahex(Sid ++ Passwd),
+ {HA1}.
+
+%%%----------------------------------------------------------------------
+%%% Func: md5hex/1
+%%%----------------------------------------------------------------------
+md5hex(Clear) ->
+ tohex(binary_to_list(erlang:md5(Clear))).
+
+%%%----------------------------------------------------------------------
+%%% Func: shahex/1
+%%%----------------------------------------------------------------------
+shahex(Clear) ->
+ tohex(binary_to_list(crypto:sha(Clear))).
+
+%%%----------------------------------------------------------------------
+%%% Func: tohex/1
+%%% Purpose: convert list of integers to hexadecimal string
+%%%----------------------------------------------------------------------
+tohex(A)->
+ Fun = fun(X)->
+ httpd_util:to_lower(padhex(httpd_util:integer_to_hexlist(X)))
+ end,
+ lists:flatten( lists:map(Fun, A) ).
+
+%%%----------------------------------------------------------------------
+%%% Func: padhex/1
+%%% Purpose: needed because httpd_util:integer_to_hexlist returns hex
+%%% values <10 as only 1 character, ie. "0F" is simply returned as
+%%% "F". For our digest, we need these leading zeros to be present.
+%%% ----------------------------------------------------------------------
+padhex(S=[Char]) -> "0" ++ S;
+padhex(String) -> String.
View
20 src/tsung/ts_jabber.erl
@@ -92,8 +92,8 @@ add_dynparams(false,#dyndata{proto=DynData}, Param, _Host) ->
Param#jabber{id=DynData#jabber_dyndata.id};
add_dynparams(true,#dyndata{proto=JabDynData, dynvars=DynVars}, Param, _Host) ->
?DebugF("Subst in jabber msg (~p) with dyn vars ~p~n",[Param,DynVars]),
- NewParam = subst(Param, DynVars),
- NewParam#jabber{id=JabDynData#jabber_dyndata.id}.
+ NewParam = subst(Param, DynVars),
+ updatejab(DynVars, NewParam#jabber{id = JabDynData#jabber_dyndata.id}).
init_dynparams() ->
#dyndata{proto=#jabber_dyndata{id=ts_user_server:get_idle()}}.
@@ -105,3 +105,19 @@ init_dynparams() ->
%%----------------------------------------------------------------------
subst(Req=#jabber{data=Data}, DynData) ->
Req#jabber{data=ts_search:subst(Data,DynData)}.
+
+
+%%----------------------------------------------------------------------
+%% Func: updatejab/2
+%% takes dyn vars and adds them to jabber record
+%% 'nonce' used for sip-digest auth
+%% 'sid' session-id used for digest auth
+%%----------------------------------------------------------------------
+updatejab([],Param) -> Param;
+updatejab([{nonce, Val}|Rest], Param)->
+ updatejab(Rest, Param#jabber{nonce = Val});
+updatejab([{sid, Val}|Rest], Param)->
+ updatejab(Rest, Param#jabber{sid = Val});
+updatejab([_|Rest], Param)->
+ updatejab(Rest, Param).
+
View
100 src/tsung/ts_jabber_common.erl
@@ -116,7 +116,6 @@ get_message(#jabber{type = 'iq:roster:get', id = Id,username=User,domain=Domain}
get_message(Jabber=#jabber{type = 'raw'}) ->
raw(Jabber);
-
get_message(Jabber=#jabber{username = Name, passwd= Passwd, id=Id}) ->
FullName = Name ++ Id,
FullPasswd = Passwd ++ Id,
@@ -128,8 +127,14 @@ get_message(Jabber=#jabber{username = Name, passwd= Passwd, id=Id}) ->
%%----------------------------------------------------------------------
get_message2(Jabber=#jabber{type = 'register'}) ->
registration(Jabber);
-get_message2(Jabber=#jabber{type = 'authenticate'}) ->
- auth(Jabber).
+get_message2(Jabber=#jabber{type = 'auth_get'}) ->
+ auth_get(Jabber);
+get_message2(Jabber=#jabber{type = 'auth_set_plain'}) ->
+ auth_set_plain(Jabber);
+get_message2(Jabber=#jabber{type = 'auth_set_digest', sid=Sid}) ->
+ auth_set_digest(Jabber,Sid);
+get_message2(Jabber=#jabber{type = 'auth_set_sip', domain=Realm, nonce=Nonce}) ->
+ auth_set_sip(Jabber,Nonce,Realm).
@@ -152,26 +157,99 @@ connect(#jabber{domain=Domain}) ->
close () -> list_to_binary("</stream:stream>").
%%----------------------------------------------------------------------
-%% generic Authentication message (auth or register)
+%% Func: auth_get/1
+%%----------------------------------------------------------------------
+auth_get(#jabber{username=Name,passwd=Passwd})->
+ auth_get(Name, Passwd, "auth").
+
+%%----------------------------------------------------------------------
+%% Func: auth_get/3
+%%----------------------------------------------------------------------
+auth_get(Username, Passwd, Type) ->
+ list_to_binary([
+ "<iq id='", ts_msg_server:get_id(list),
+ "' type='get' >",
+ "<query xmlns='jabber:iq:", Type, "'>",
+ "<username>", Username, "</username></query></iq>"]).
+
+%%----------------------------------------------------------------------
+%% Func: auth_set_plain/1
%%----------------------------------------------------------------------
-auth(#jabber{username=Name,passwd=Passwd})->
- auth(Name, Passwd, "auth").
+auth_set_plain(#jabber{username=Name,passwd=Passwd})->
+ auth_set_plain(Name, Passwd, "auth").
-auth(Username, Passwd, Type) ->
+
+%%----------------------------------------------------------------------
+%% Func: auth_set_plain/3
+%%----------------------------------------------------------------------
+auth_set_plain(Username, Passwd, Type) ->
list_to_binary([
"<iq id='", ts_msg_server:get_id(list),
"' type='set' >",
"<query xmlns='jabber:iq:", Type, "'>",
- "<username>", Username, "</username>",
- "<resource>Tsung</resource>",
+ "<username>", Username, "</username>",
+ "<resource>tsunami</resource>",
"<password>", Passwd, "</password></query></iq>"]).
+
+%%----------------------------------------------------------------------
+%% Func: auth_set_digest/2
+%%----------------------------------------------------------------------
+auth_set_digest(#jabber{username=Name,passwd=Passwd}, Sid)->
+ auth_set_digest(Name, Passwd, "auth", Sid).
+
+
+%%----------------------------------------------------------------------
+%% Func: auth_set_digest/4
+%%----------------------------------------------------------------------
+auth_set_digest(Username, Passwd, Type, Sid) ->
+ {Digest} = ts_digest:digest(Sid, Passwd),
+ list_to_binary([
+ "<iq id='", ts_msg_server:get_id(list),
+ "' type='set' >",
+ "<query xmlns='jabber:iq:", Type, "'>",
+ "<username>", Username, "</username>",
+ "<resource>tsunami</resource>",
+ "<digest>", Digest, "</digest></query></iq>"]).
+
+
+%%----------------------------------------------------------------------
+%% Func: auth_set_sip/3
+%%----------------------------------------------------------------------
+auth_set_sip(#jabber{username=Name,passwd=Passwd,domain=Domain}, Nonce, Realm)->
+ auth_set_sip(Name, Passwd, Domain, "auth", Nonce, Realm).
+
+%%----------------------------------------------------------------------
+%% Func: auth_set_sip/6
+%%----------------------------------------------------------------------
+auth_set_sip(Username, Passwd, Domain, Type, Nonce, Realm) ->
+ Jid = Username ++ "@" ++ Realm,
+ {SipDigest,Integrity} = ts_digest:sip_digest(Nonce, Jid, Realm, Passwd),
+ list_to_binary([
+ "<iq id='", ts_msg_server:get_id(list),
+ "' type='set' >",
+ "<query xmlns='jabber:iq:", Type, "'>",
+ "<username>", Jid, "</username>",
+ "<resource>tsunami</resource>",
+ "<x xmlns='xmpp:assert' version='1.0'>",
+ "<ContextInfo><ServiceValue><Realm>", Domain,
+ "</Realm></ServiceValue></ContextInfo>",
+ "<TokenInfo><SubjectValue>",
+ "<Username>", Jid, "</Username>",
+ "<Password type='sip-digest' encoding='hex'>", SipDigest,
+ "</Password>",
+ "<Nonce encoding='hex'>", Nonce, "</Nonce>",
+ "<Integrity encoding='hex'>", Integrity, "</Integrity>",
+ "</SubjectValue></TokenInfo></x></query></iq>"]).
+
+
+
%%----------------------------------------------------------------------
%% Func: registration/1
%% Purpose: register message
%%----------------------------------------------------------------------
registration(#jabber{username=Name,passwd=Passwd})->
- auth(Name, Passwd, "register").
+ auth_set_plain(Name, Passwd, "register").
%%----------------------------------------------------------------------
%% Func: message/3
@@ -280,5 +358,3 @@ raw(#jabber{data=undefined}) ->
raw(#jabber{data=Data}) when is_list(Data) ->
list_to_binary(Data).
-
-
View
1  src/tsung/ts_launcher.erl
@@ -95,6 +95,7 @@ launch({Node, Host, Arrivals}) ->
%%----------------------------------------------------------------------
init([]) ->
ts_utils:init_seed(),
+ crypto:start(),
{ok, MyHostName} = ts_utils:node_to_hostname(node()),
{ok, wait, #state{myhostname=MyHostName}}.
Please sign in to comment.
Something went wrong with that request. Please try again.