Module: sip-router
Branch: master
Commit: 5ec0e4222a31610ec0c4184dfdbe6d10dd00e0b5
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=5ec0e42…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Sun Dec 5 23:23:41 2010 +0100
auth: more return codes for auth API
- report more granular failure causes
- part of patch by Alex Hermann, FS#101
---
modules/auth/api.c | 9 +++++++--
modules/auth/api.h | 9 ++++++++-
modules/auth/auth_mod.c | 12 ++++++++++++
modules/auth/doc/functions.xml | 11 +++++++++++
modules/auth/nonce.c | 3 ++-
5 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/modules/auth/api.c b/modules/auth/api.c
index f73b75d..b7ce413 100644
--- a/modules/auth/api.c
+++ b/modules/auth/api.c
@@ -83,7 +83,7 @@ auth_result_t pre_auth(struct sip_msg* msg, str* realm, hdr_types_t
hftype,
} else if (ret > 0) {
DBG("auth:pre_auth: Credentials with realm '%.*s' not found\n",
realm->len, ZSW(realm->s));
- return NOT_AUTHENTICATED;
+ return NO_CREDENTIALS;
}
/* Pointer to the parsed credentials */
@@ -132,7 +132,12 @@ static int auth_check_hdr_md5(struct sip_msg* msg, auth_body_t*
auth,
if (ret==3 || ret==4){
/* failed auth_extra_checks or stale */
auth->stale=1; /* we mark the nonce as stale
- (hack that makes our life much easier) */
+ (hack that makes our life much easier) */
+ *auth_res = STALE_NONCE;
+ return 0;
+ } else if (ret==6) {
+ *auth_res = NONCE_REUSED;
+ return 0;
} else {
DBG("auth:pre_auth: Invalid nonce value received\n");
*auth_res = NOT_AUTHENTICATED;
diff --git a/modules/auth/api.h b/modules/auth/api.h
index 35807cd..976a547 100644
--- a/modules/auth/api.h
+++ b/modules/auth/api.h
@@ -44,6 +44,9 @@
* return codes to config by auth functions
*/
typedef enum auth_cfg_result {
+ AUTH_NONCE_REUSED = -6, /*!< Returned if nonce is used more than once */
+ AUTH_NO_CREDENTIALS = -5, /*!< Credentials missing */
+ AUTH_STALE_NONCE = -4, /*!< Stale nonce */
AUTH_USER_UNKNOWN = -3, /*!< User not found */
AUTH_INVALID_PASSWORD = -2, /*!< Invalid password */
AUTH_ERROR = -1, /*!< Error occurred */
@@ -56,7 +59,10 @@ typedef enum auth_cfg_result {
* return codes to auth API functions
*/
typedef enum auth_result {
- ERROR = -2 , /* Error occurred, a reply has been sent out -> return 0 to the
ser core */
+ NONCE_REUSED = -5, /* Returned if nonce is used more than once */
+ NO_CREDENTIALS, /* Credentials missing */
+ STALE_NONCE, /* Stale nonce */
+ ERROR, /* Error occurred, a reply has been sent out -> return 0 to the
ser core */
NOT_AUTHENTICATED, /* Don't perform authentication, credentials missing */
DO_AUTHENTICATION, /* Perform digest authentication */
AUTHENTICATED, /* Authenticated by default, no digest authentication necessary */
@@ -68,6 +74,7 @@ typedef enum auth_result {
* of sequnce numbers with mobile station. */
} auth_result_t;
+
typedef int (*check_auth_hdr_t)(struct sip_msg* msg, auth_body_t* auth_body,
auth_result_t* auth_res);
int check_auth_hdr(struct sip_msg* msg, auth_body_t* auth_body,
diff --git a/modules/auth/auth_mod.c b/modules/auth/auth_mod.c
index 87f4291..c44fb96 100644
--- a/modules/auth/auth_mod.c
+++ b/modules/auth/auth_mod.c
@@ -409,6 +409,18 @@ int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
ret = AUTH_ERROR;
switch(pre_auth(msg, realm, hftype, &h, NULL)) {
+ case NONCE_REUSED:
+ LM_DBG("nonce reused");
+ ret = AUTH_NONCE_REUSED;
+ goto end;
+ case STALE_NONCE:
+ LM_DBG("stale nonce\n");
+ ret = AUTH_STALE_NONCE;
+ goto end;
+ case NO_CREDENTIALS:
+ LM_DBG("no credentials\n");
+ ret = AUTH_NO_CREDENTIALS;
+ goto end;
case ERROR:
case BAD_CREDENTIALS:
LM_DBG("error or bad credentials\n");
diff --git a/modules/auth/doc/functions.xml b/modules/auth/doc/functions.xml
index 45eceb6..f452529 100644
--- a/modules/auth/doc/functions.xml
+++ b/modules/auth/doc/functions.xml
@@ -158,6 +158,17 @@ if (!proxy_authenticate("$fd", "subscriber)) {
<emphasis>-3 (invalid user)</emphasis> - authentication user does
not exist.
</para></listitem>
+ <listitem><para>
+ <emphasis>-4 (nonce expired)</emphasis> - the nonce has expired
+ </para></listitem>
+ <listitem><para>
+ <emphasis>-5 (no credentials)</emphasis> - request does not contain
+ an Authorization header with the correct realm.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>-6 (nonce reused)</emphasis> - the nonce has already been
+ used to authenticate a previous request
+ </para></listitem>
</itemizedlist>
<para>Meaning of the parameters is as follows:</para>
<itemizedlist>
diff --git a/modules/auth/nonce.c b/modules/auth/nonce.c
index 72c156a..1611876 100644
--- a/modules/auth/nonce.c
+++ b/modules/auth/nonce.c
@@ -302,6 +302,7 @@ int calc_nonce(char* nonce, int *nonce_len, int cfg, int since, int
expires,
* 3 - nonce expires ok, but the auth_extra checks failed
* 4 - stale
* 5 - invalid nc value (not an unsigned int)
+ * 6 - nonce reused
*/
int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
struct sip_msg* msg)
@@ -430,7 +431,7 @@ int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
case OTN_ID_OVERFLOW:
case OTN_INV_POOL:
case OTN_REPLAY:
- return 4; /* stale */
+ return 6; /* reused */
}
}
#endif