I see a few people have found the following issue with SIPp: 'nc' counter not
incremented when authorization reused.
Background:
According to SIP-Connect:
"...
2. In order to avoid unnecessary challenges, the SIP-PBX SHOULD include its
authorization credentials using the current nonce in each subsequent request
that allows authentication credentials to be sent to the SP-SSE..."
So an endpoint should be able to (and SHOULD) re-send it's existing
authorization credentials with each INVITE, REFER,. etc it sends. It MAY be
challenged for new authorization (401 / 407 Unauthorised). but the previous
credentials MAY be accepted, thus reducing mwessage load on the system.
According to RFC2617, the 'nc' counter in the authorization header MUST be
incremented for successive new messages which re-use an existing authorization,
(but not incremented for retransmissions of old messages).
"nonce-count
This MUST be specified if a qop directive is sent (see above), and
MUST NOT be specified if the server did not send a qop directive in
the WWW-Authenticate header field. The nc-value is the hexadecimal
count of the number of requests (including the current request)
that the client has sent with the nonce value in this request. For
example, in the first request sent in response to a given nonce
value, the client sends "nc=00000001". The purpose of this
directive is to allow the server to detect request replays by
maintaining its own copy of this count - if the same nc-value is
seen twice, then the request is a replay. See the description
below of the construction of the request-digest value."
The problem: SIPP has 'nc' hard-coded to '1'
The patch below sets nc to '1' for each new authorization, then increments it
each time a new message is generated which reuses the same authorization. The
counter is not incremented for retransmissions. This probably counts as a
hack, so apollogies for that - but it does the job.
diff -bruN of affected files: Diff is aghainst SIPP v 3.2
--- ../sipp.svn/auth.c 2011-12-17 09:28:00.062500000 +1300
+++ auth.c 2012-09-07 11:20:58.328125000 +1200
@@ -79,13 +79,14 @@
int createAuthHeaderMD5(char * user, char * password, int password_len, char *
method,
char * uri, char * msgbody, char * auth,
- char * algo, char * result);
+ char * algo, char * result, unsigned int mync);
int createAuthHeaderAKAv1MD5(char * user, char * OP,
char * AMF,
char * K,
char * method,
char * uri, char * msgbody, char * auth, char
*algo,
- char * result);
+ char * result,
+ unsigned int mync);
/* This function is from RFC 2617 Section 5 */
@@ -143,7 +144,8 @@
char * aka_OP,
char * aka_AMF,
char * aka_K,
- char * result) {
+ char * result,
+ unsigned int mync) {
char algo[32]="MD5";
char *start, *end;
@@ -163,12 +165,12 @@
}
if (strncasecmp(algo, "MD5", 3)==0) {
- return
createAuthHeaderMD5(user,password,strlen(password),method,uri,msgbody,auth,algo,result);
+ return
createAuthHeaderMD5(user,password,strlen(password),method,uri,msgbody,auth,algo,result,mync);
} else if (strncasecmp(algo, "AKAv1-MD5", 9)==0) {
return createAuthHeaderAKAv1MD5(user, aka_OP,
aka_AMF,
aka_K,
-
method,uri,msgbody,auth,algo,result);
+
method,uri,msgbody,auth,algo,result,mync);
}else{
sprintf(result, "createAuthHeader: authentication must use MD5 or
AKAv1-MD5");
return 0;
@@ -213,14 +215,13 @@
int createAuthHeaderMD5(char * user, char * password, int password_len, char *
method,
char * uri, char * msgbody, char * auth,
- char * algo, char * result) {
+ char * algo, char * result, unsigned int mync) {
unsigned char ha1[MD5_HASH_SIZE], ha2[MD5_HASH_SIZE];
unsigned char resp[MD5_HASH_SIZE], body[MD5_HASH_SIZE];
unsigned char ha1_hex[HASH_HEX_SIZE+1], ha2_hex[HASH_HEX_SIZE+1];
unsigned char resp_hex[HASH_HEX_SIZE+1], body_hex[HASH_HEX_SIZE+1];
char tmp[MAX_HEADER_LEN], authtype[16], cnonce[32], nc[32], opaque[64];
- static unsigned int mync = 1;
int has_opaque = 0;
MD5_CTX Md5Ctx;
@@ -584,7 +585,8 @@
char * aka_K,
char * method,
char * uri, char * msgbody, char * auth, char *algo,
- char * result) {
+ char * result,
+ unsigned int mync) {
char tmp[MAX_HEADER_LEN];
char *start, *end;
@@ -657,7 +659,7 @@
sqn_he[5] = sqn[5];
has_auts = 0;
/* RES has to be used as password to compute response */
- resuf = createAuthHeaderMD5(user, (char *) res, RESLEN, method, uri,
msgbody, auth, algo, result);
+ resuf = createAuthHeaderMD5(user, (char *) res, RESLEN, method, uri,
msgbody, auth, algo, result, mync);
} else {
sqn_ms[5] = sqn_he[5] + 1;
f5star(k, rnd, ak, op);
@@ -667,7 +669,7 @@
has_auts = 1;
/* When re-synchronisation occurs an empty password has to be used */
/* to compute MD5 response (Cf. rfc 3310 section 3.2) */
- resuf=createAuthHeaderMD5(user,"",0,method,uri,msgbody,auth,algo,result);
+
resuf=createAuthHeaderMD5(user,"",0,method,uri,msgbody,auth,algo,result,mync);
}
if (has_auts) {
/* Format data for output in the SIP message */
--- ../sipp.svn/call.cpp 2012-01-30 11:44:23.734375000 +1300
+++ call.cpp 2012-09-07 11:46:32.421875000 +1200
@@ -409,6 +409,7 @@
#ifdef _USE_OPENSSL
dialog_authentication = NULL;
dialog_challenge_type = 0;
+ lastnc = 1;
m_ctx_ssl = NULL ;
m_bio = NULL ;
@@ -2492,7 +2493,7 @@
createSendingMessage(auth_comp->comp_param.auth_param.aka_OP, -2,
my_aka_OP, sizeof(my_aka_OP));
if (createAuthHeader(my_auth_user, my_auth_pass, method, uri, auth_body,
dialog_authentication,
- my_aka_OP, my_aka_AMF, my_aka_K, result + authlen) == 0) {
+ my_aka_OP, my_aka_AMF, my_aka_K, result + authlen, lastnc++) == 0) {
ERROR("%s", result + authlen);
}
authlen = strlen(result);
@@ -3302,6 +3303,7 @@
}
dialog_authentication = (char *) realloc(dialog_authentication,
strlen(auth) + 2);
+ lastnc = 1;
sprintf(dialog_authentication, "%s", auth);
/* Store the code of the challenge for building the proper header */
--- ../sipp.svn/call.hpp 2011-12-17 15:02:12.593750000 +1300
+++ call.hpp 2012-09-07 11:40:15.000000000 +1200
@@ -52,9 +52,9 @@
#define RTCHECK_LOOSE 2
#ifdef __HPUX
- extern int createAuthHeader(char * user, char * password, char * method,
char * uri, char * msgbody, char * auth, char * aka_OP, char * aka_AMF, char *
aka_K, char * result);
+ extern int createAuthHeader(char * user, char * password, char * method,
char * uri, char * msgbody, char * auth, char * aka_OP, char * aka_AMF, char *
aka_K, char * result, unsigned int mync);
#else
- extern "C" { extern int createAuthHeader(char * user, char * password, char
* method, char * uri, char * msgbody, char * auth, char * aka_OP, char *
aka_AMF, char * aka_K, char * result); }
+ extern "C" { extern int createAuthHeader(char * user, char * password, char
* method, char * uri, char * msgbody, char * auth, char * aka_OP, char *
aka_AMF, char * aka_K, char * result, unsigned int mync); }
extern "C" { int verifyAuthHeader(char * user, char * password, char *
method, char * auth); }
#endif
@@ -174,6 +174,8 @@
#ifdef _USE_OPENSSL
/* holds the auth header and if the challenge was 401 or 407 */
char * dialog_authentication;
+ unsigned int lastnc;
+
int dialog_challenge_type;
#endif
===================================
Matt Briggs
Test Engineer
Mobile: +64 27 ####
www.telecom.co.nz
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Sipp-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sipp-users