Browse Source

modules_k/auth_radius: module is now using api from modules_s/auth

Juha Heinanen 15 năm trước cách đây
mục cha
commit
6f5bc8bed4

+ 182 - 142
modules_k/auth_radius/README

@@ -22,42 +22,41 @@ Jan Janak
 
 
    <[email protected]>
    <[email protected]>
 
 
-   Copyright © 2002, 2003 FhG FOKUS
+   Copyright © 2002, 2003 FhG FOKUS
 
 
-   Copyright © 2005 voice-system.ro
+   Copyright © 2005 voice-system.ro
 
 
-   Copyright © 2008 Juha Heinanen
+   Copyright © 2008 Juha Heinanen
    Revision History
    Revision History
-   Revision $Revision$ $Date: 2008-03-08 01:03:56 +0200
-                              (Sat, 08 Mar 2008) $
-     __________________________________________________________
+   Revision $Revision$ $Date$
+     __________________________________________________________________
 
 
    Table of Contents
    Table of Contents
 
 
    1. Admin Guide
    1. Admin Guide
 
 
-        1.1. Overview
-        1.2. Additional Credentials
-        1.3. Dependencies
+        1. Overview
+        2. Additional Credentials
+        3. Dependencies
 
 
-              1.3.1. Kamailio Modules
-              1.3.2. External Libraries or Applications
+              3.1. Modules
+              3.2. External Libraries or Applications
 
 
-        1.4. Exported Parameters
+        4. Exported Parameters
 
 
-              1.4.1. radius_config (string)
-              1.4.2. service_type (integer)
-              1.4.3. auth_extra (string)
-              1.4.4. use_ruri_flag (integer)
+              4.1. radius_config (string)
+              4.2. service_type (integer)
+              4.3. auth_extra (string)
+              4.4. use_ruri_flag (integer)
 
 
-        1.5. Exported Functions
+        5. Exported Functions
 
 
-              1.5.1. radius_www_authorize(realm)
-              1.5.2. radius_proxy_authorize(realm [, uri_user])
+              5.1. radius_www_authorize(realm)
+              5.2. radius_proxy_authorize(realm [, uri_user])
 
 
    List of Examples
    List of Examples
 
 
-   1.1. "SIP-AVP" RADIUS AVP exmaples
+   1.1. “SIP-AVP� RADIUS AVP exmaples
    1.2. radius_config parameter usage
    1.2. radius_config parameter usage
    1.3. service_type parameter usage
    1.3. service_type parameter usage
    1.4. auth_extra parameter usage
    1.4. auth_extra parameter usage
@@ -67,30 +66,50 @@ Jan Janak
 
 
 Chapter 1. Admin Guide
 Chapter 1. Admin Guide
 
 
-1.1. Overview
-
-   This module contains functions that are used to perform
-   authentication using a Radius server. Basically the proxy will
-   pass along the credentials to the radius server which will in
-   turn send a reply containing result of the authentication. So
-   basically the whole authentication is done in the Radius
-   server. Before sending the request to the radius server we
-   perform some sanity checks over the credentials to make sure
-   that only well formed credentials will get to the server. We
-   have implemented radius authentication according to
-   draft-sterman-aaa-sip-00. This module requires radiusclient-ng
-   library version 0.5.0 or higher which is available from
+   Table of Contents
+
+   1. Overview
+   2. Additional Credentials
+   3. Dependencies
+
+        3.1. Modules
+        3.2. External Libraries or Applications
+
+   4. Exported Parameters
+
+        4.1. radius_config (string)
+        4.2. service_type (integer)
+        4.3. auth_extra (string)
+        4.4. use_ruri_flag (integer)
+
+   5. Exported Functions
+
+        5.1. radius_www_authorize(realm)
+        5.2. radius_proxy_authorize(realm [, uri_user])
+
+1. Overview
+
+   This module contains functions that are used to perform authentication
+   using a Radius server. Basically the proxy will pass along the
+   credentials to the radius server which will in turn send a reply
+   containing result of the authentication. So basically the whole
+   authentication is done in the Radius server. Before sending the request
+   to the radius server we perform some sanity checks over the credentials
+   to make sure that only well formed credentials will get to the server.
+   We have implemented radius authentication according to
+   draft-sterman-aaa-sip-00. This module requires radiusclient-ng library
+   version 0.5.0 or higher which is available from
    http://developer.berlios.de/projects/radiusclient-ng/.
    http://developer.berlios.de/projects/radiusclient-ng/.
 
 
-1.2. Additional Credentials
+2. Additional Credentials
 
 
-   When performing authentification, the RADIUS server may include
-   in the response additional credentials. This scheme is very
-   useful in fetching additional user information from the RADIUS
-   server without making extra queries.
+   When performing authentification, the RADIUS server may include in the
+   response additional credentials. This scheme is very useful in fetching
+   additional user information from the RADIUS server without making extra
+   queries.
 
 
-   The additional credentials are embedded in the RADIUS reply as
-   AVPs "SIP-AVP". The syntax of the value is:
+   The additional credentials are embedded in the RADIUS reply as AVPs
+   “SIP-AVP�. The syntax of the value is:
      * value = SIP_AVP_NAME SIP_AVP_VALUE
      * value = SIP_AVP_NAME SIP_AVP_VALUE
      * SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER
      * SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER
      * SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE
      * SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE
@@ -100,7 +119,7 @@ Chapter 1. Admin Guide
 
 
    The RPID value may be fetch via this mechanism.
    The RPID value may be fetch via this mechanism.
 
 
-   Example 1.1. "SIP-AVP" RADIUS AVP exmaples
+   Example 1.1. “SIP-AVP� RADIUS AVP exmaples
 ....
 ....
 "email:[email protected]"
 "email:[email protected]"
     - STRING NAME AVP (email) with STRING VALUE ([email protected])
     - STRING NAME AVP (email) with STRING VALUE ([email protected])
@@ -112,165 +131,186 @@ Chapter 1. Admin Guide
     - ID AVP (14) with INTEGER VALUE (28)
     - ID AVP (14) with INTEGER VALUE (28)
 ....
 ....
 
 
-1.3. Dependencies
+3. Dependencies
+
+   3.1. Modules
+   3.2. External Libraries or Applications
 
 
-1.3.1. Kamailio Modules
+3.1. Modules
 
 
-   The module depends on the following modules (in the other words
-   the listed modules must be loaded before this module):
-     * auth -- Generic authentication functions
+   The module depends on the following modules (in the other words the
+   listed modules must be loaded before this module):
+     * modules_s/auth -- Generic authentication functions
 
 
-1.3.2. External Libraries or Applications
+3.2. External Libraries or Applications
 
 
-   The following libraries or applications must be installed
-   before compilling Kamailio with this module loaded:
-     * radiusclient-ng 0.5.0 or higher -- library and development
-       files. See
-       http://developer.berlios.de/projects/radiusclient-ng/.
+   The following libraries or applications must be installed before
+   compilling Kamailio with this module loaded:
+     * radiusclient-ng 0.5.0 or higher -- library and development files.
+       See http://developer.berlios.de/projects/radiusclient-ng/.
 
 
-1.4. Exported Parameters
+4. Exported Parameters
 
 
-1.4.1. radius_config (string)
+   4.1. radius_config (string)
+   4.2. service_type (integer)
+   4.3. auth_extra (string)
+   4.4. use_ruri_flag (integer)
+
+4.1. radius_config (string)
 
 
    This is the location of the configuration file of radius client
    This is the location of the configuration file of radius client
    libraries.
    libraries.
 
 
-   Default value is
-   "/usr/local/etc/radiusclient-ng/radiusclient.conf".
+   Default value is “/usr/local/etc/radiusclient-ng/radiusclient.conf�.
 
 
    Example 1.2. radius_config parameter usage
    Example 1.2. radius_config parameter usage
 modparam("auth_radius", "radius_config", "/etc/radiusclient.conf")
 modparam("auth_radius", "radius_config", "/etc/radiusclient.conf")
 
 
-1.4.2. service_type (integer)
+4.2. service_type (integer)
 
 
-   This is the value of the Service-Type radius attribute to be
-   used. The default should be fine for most people. See your
-   radius client include files for numbers to be put in this
-   parameter if you need to change it.
+   This is the value of the Service-Type radius attribute to be used. The
+   default should be fine for most people. See your radius client include
+   files for numbers to be put in this parameter if you need to change it.
 
 
-   Default value is "15".
+   Default value is “15�.
 
 
    Example 1.3. service_type parameter usage
    Example 1.3. service_type parameter usage
 modparam("auth_radius", "service_type", 15)
 modparam("auth_radius", "service_type", 15)
 
 
-1.4.3. auth_extra (string)
+4.3. auth_extra (string)
 
 
    Semi-colon separated list of extra RADIUS attribute name=pseudo
    Semi-colon separated list of extra RADIUS attribute name=pseudo
-   variable pairs. When radius_www_authorize() or
-   radius_proxy_authorize() function is called, listed extra
-   attributes are included in RADIUS request with current values
-   of corresponding pseudo variables.
+   variable pairs. When radius_www_authorize() or radius_proxy_authorize()
+   function is called, listed extra attributes are included in RADIUS
+   request with current values of corresponding pseudo variables.
 
 
-   There is no default value, i.e., by default no extra attributes
-   are included.
+   There is no default value, i.e., by default no extra attributes are
+   included.
 
 
    Example 1.4. auth_extra parameter usage
    Example 1.4. auth_extra parameter usage
 modparam("auth_radius", "auth_extra", "Acct-Session-Id=$ci")
 modparam("auth_radius", "auth_extra", "Acct-Session-Id=$ci")
 
 
-1.4.4. use_ruri_flag (integer)
+4.4. use_ruri_flag (integer)
 
 
-   When this parameter is set to the value other than "-1" and the
-   request being authenticated has flag with matching number set
-   via setflag() function, use Request URI instead of uri
-   parameter value from the Authorization / Proxy-Authorization
-   header field to perform RADIUS authentication. This is intended
-   to provide workaround for misbehaving NAT / routers / ALGs that
-   alter request in the transit, breaking authentication. At the
-   time of this writing, certain versions of Linksys WRT54GL are
-   known to do that.
+   When this parameter is set to the value other than "-1" and the request
+   being authenticated has flag with matching number set via setflag()
+   function, use Request URI instead of uri parameter value from the
+   Authorization / Proxy-Authorization header field to perform RADIUS
+   authentication. This is intended to provide workaround for misbehaving
+   NAT / routers / ALGs that alter request in the transit, breaking
+   authentication. At the time of this writing, certain versions of
+   Linksys WRT54GL are known to do that.
 
 
-   Default value is "-1".
+   Default value is “-1�.
 
 
    Example 1.5. use_ruri_flag parameter usage
    Example 1.5. use_ruri_flag parameter usage
 modparam("auth_radius", "use_ruri_flag", 22)
 modparam("auth_radius", "use_ruri_flag", 22)
 
 
-1.5. Exported Functions
+5. Exported Functions
+
+   5.1. radius_www_authorize(realm)
+   5.2. radius_proxy_authorize(realm [, uri_user])
 
 
-1.5.1. radius_www_authorize(realm)
+5.1. radius_www_authorize(realm)
 
 
    The function verifies credentials according to RFC2617. If the
    The function verifies credentials according to RFC2617. If the
-   credentials are verified successfully then the function will
-   succeed and mark the credentials as authorized (marked
-   credentials can be later used by some other functions). If the
-   function was unable to verify the credentials for some reason
-   then it will fail and the script should call www_challenge
-   which will challenge the user again.
+   credentials are verified successfully then the function will succeed
+   and mark the credentials as authorized (marked credentials can be later
+   used by some other functions).
+
+   If the function was unable to verify the credentials for some reason,
+   it fails and assigns a WWW-Authorize header containing a new challenge
+   to digest_challenge AVP (see modules_s/auth). The script should then
+   respond with 401 that includes this header, which will challenge the
+   user again.
 
 
    Negative codes may be interpreted as follows:
    Negative codes may be interpreted as follows:
-     * -5 (generic error) - some generic error occurred and no
-       reply was sent out;
-     * -4 (no credentials) - credentials were not found in
-       request;
+     * -5 (internal error) - some internal error occurred;
+     * -4 (no credentials) - credentials were not found in request;
      * -3 (stale nonce) - stale nonce;
      * -3 (stale nonce) - stale nonce;
+     * -2 (bad request) - something wrong in request, for example,
+       credentials were not filled properly;
+     * -1 (authorization failed) - RADIUS responded with Access Reject
 
 
-   This function will, in fact, perform sanity checks over the
-   received credentials and then pass them along to the radius
-   server which will verify the credentials and return whether
-   they are valid or not.
+   This function will, in fact, perform sanity checks over the received
+   credentials and then pass them along to the radius server which will
+   verify the credentials and return whether they are valid or not.
 
 
    Meaning of the parameter is as follows:
    Meaning of the parameter is as follows:
-     * realm - Realm is a opaque string that the user agent should
-       present to the user so he can decide what username and
-       password to use. Usually this is domain of the host the
-       server is running on.
-       If an empty string "" is used then the server will generate
-       it from the request. In case of REGISTER requests To header
-       field domain will be used (because this header field
-       represents a user being registered), for all other messages
-       From header field domain will be used.
+     * realm - Realm is a opaque string that the user agent should present
+       to the user so he can decide what username and password to use. In
+       case of REGISTER requests it is usually hostpart of To URI.
        The string may contain pseudo variables.
        The string may contain pseudo variables.
 
 
    This function can be used from REQUEST_ROUTE.
    This function can be used from REQUEST_ROUTE.
 
 
    Example 1.6. radius_www_authorize usage
    Example 1.6. radius_www_authorize usage
 ...
 ...
-if (!radius_www_authorize("siphub.net")) {
-        www_challenge("siphub.net", "1");
-};
+    if (!radius_www_authorize("$td")) {
+    switch ($rc) {
+    case -5:
+        send_reply("500", "Server Internal Error");
+        exit;
+    case -2:
+        send_reply("400", "Bad Request");
+        exit;
+    default:
+    };
+    if (defined($avp(digest_challenge)) &&
+            ($avp(digest_challenge) != "")) {
+        append_to_reply("$avp(digest_challenge)");
+    };
+    send_reply("401", "Unauthorized");
+    exit;
 ...
 ...
 
 
-1.5.2. radius_proxy_authorize(realm [, uri_user])
+5.2. radius_proxy_authorize(realm [, uri_user])
 
 
    The function verifies credentials according to RFC2617. If the
    The function verifies credentials according to RFC2617. If the
-   credentials are verified successfully then the function will
-   succeed and mark the credentials as authorized (marked
-   credentials can be later used by some other functions). If the
-   function was unable to verify the credentials for some reason
-   then it will fail and the script should call proxy_challenge
-   which will challenge the user again. For more about the
-   negative return codes, see the above function.
-
-   This function will, in fact, perform sanity checks over the
-   received credentials and then pass them along to the radius
-   server which will verify the credentials and return whether
-   they are valid or not.
+   credentials are verified successfully then the function will succeed
+   and mark the credentials as authorized (marked credentials can be later
+   used by some other functions).
+
+   If the function was unable to verify the credentials for some reason,
+   it fails and assigns a WWW-Authorize header containing a new challenge
+   to digest_challenge AVP. The script should then respond with 407 that
+   includes this header, which will challenge the user again. For more
+   about the negative return codes, see the above function.
+
+   This function will, in fact, perform sanity checks over the received
+   credentials and then pass them along to the radius server which will
+   verify the credentials and return whether they are valid or not.
 
 
    Meaning of the parameters is as follows:
    Meaning of the parameters is as follows:
-     * realm - Realm is a opaque string that the user agent should
-       present to the user so he can decide what username and
-       password to use. This is usually one of the domains the
-       proxy is responsible for. If an empty string "" is used
-       then the server will generate realm from host part of From
-       header field URI.
+     * realm - Realm is a opaque string that the user agent should present
+       to the user so he can decide what username and password to use. In
+       case of non-REGISTER requests it is usually hostpart of From or
+       P-Preferred-Identity URI.
        The string may contain pseudo variables.
        The string may contain pseudo variables.
-     * uri_user - Uri_user is an optional pseudo variable
-       parameter whose value, if present, will be given to Radius
-       server as value of SIP-URI-User check item. If uri_user
-       pseudo variable parameter is not present, the server will
-       generate SIP-URI-User check item value from user part of
-       To/From URI.
+     * uri_user - Uri_user is an optional pseudo variable parameter whose
+       value, if present, will be given to Radius server as value of
+       SIP-URI-User check item. If uri_user pseudo variable parameter is
+       not present, the server will generate SIP-URI-User check item value
+       from user part of To/From URI.
 
 
    This function can be used from REQUEST_ROUTE.
    This function can be used from REQUEST_ROUTE.
 
 
    Example 1.7. proxy_authorize usage
    Example 1.7. proxy_authorize usage
 ...
 ...
-if (!radius_proxy_authorize("")) {   # Realm and URI user will be autoge
-nerated
-        proxy_challenge("", "1");
-};
-...
-if (!radius_proxy_authorize("$pd", "$pU")) { # Realm and URI user are ta
-ken
-        proxy_challenge("$pd", "1");         # from P-Preferred-Identity
-};                                           # header field
+    if (!radius_proxy_authorize("$pd", "$pU")) { # Realm and URI user are taken
+    switch ($rc) {                               # from P-Preferred-Identity
+    case -5:                                     # header field
+        send_reply("500", "Server Internal Error");
+        exit;
+    case -2:
+        send_reply("400", "Bad Request");
+        exit;
+    default:
+    };
+    if (defined($avp(digest_challenge)) &&
+            ($avp(digest_challenge) != "")) {
+        append_to_reply("$avp(digest_challenge)");
+    };
+    send_reply("407", "Proxy Authentication Required");
+    exit;
 ...
 ...

+ 76 - 18
modules_k/auth_radius/authorize.c

@@ -4,6 +4,7 @@
  * Digest Authentication - Radius support
  * Digest Authentication - Radius support
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2010 Juha Heinanen
  *
  *
  * This file is part of Kamailio, a free SIP server.
  * This file is part of Kamailio, a free SIP server.
  *
  *
@@ -41,7 +42,7 @@
 #include "../../dprint.h"
 #include "../../dprint.h"
 #include "../../ut.h"
 #include "../../ut.h"
 #include "../../pvar.h"
 #include "../../pvar.h"
-#include "../../modules_k/auth/api.h"
+#include "../../modules_s/auth/api.h"
 #include "authorize.h"
 #include "authorize.h"
 #include "sterman.h"
 #include "sterman.h"
 #include "authrad_mod.h"
 #include "authrad_mod.h"
@@ -77,7 +78,7 @@ static inline int get_uri_user(struct sip_msg* _m, str** _uri_user)
  * Authorize digest credentials
  * Authorize digest credentials
  */
  */
 static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
 static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
-			    pv_spec_t * _uri_user, int _hftype)
+			    pv_spec_t * _uri_user, hdr_types_t _hftype)
 {
 {
     int res;
     int res;
     auth_result_t ret;
     auth_result_t ret;
@@ -87,22 +88,47 @@ static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
     str user, domain;
     str user, domain;
     pv_value_t pv_val;
     pv_value_t pv_val;
 
 
+    cred = 0;
+    ret = -1;
+    user.s = 0;
+
     /* get pre_auth domain from _realm pvar (if exists) */
     /* get pre_auth domain from _realm pvar (if exists) */
     if (_realm) {
     if (_realm) {
-	if (pv_printf_s(_msg, _realm, &domain)!=0) {
+	if (pv_printf_s(_msg, _realm, &domain) != 0) {
 	    LM_ERR("pv_printf_s failed\n");
 	    LM_ERR("pv_printf_s failed\n");
-	    return AUTH_ERROR;
+	    return -5;
 	}
 	}
     } else {
     } else {
-	/* get pre_auth domain from To/From header */
 	domain.len = 0;
 	domain.len = 0;
 	domain.s = 0;
 	domain.s = 0;
     }
     }
 
 
-    ret = auth_api.pre_auth(_msg, &domain, _hftype, &h);
-
-    if (ret != DO_AUTHORIZATION)
-	return ret;
+    switch(auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)) {
+    default:
+	BUG("unexpected reply '%d'.\n",
+	    auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL));
+#ifdef EXTRA_DEBUG
+	abort();
+#endif
+	ret = -5;
+	goto end;
+
+    case ERROR:
+    case BAD_CREDENTIALS:
+	ret = -2;
+	goto end;
+	
+    case NOT_AUTHENTICATED:
+	ret = -4;
+	goto end;
+	
+    case DO_AUTHENTICATION:
+	break;
+	
+    case AUTHENTICATED:
+	ret = 1;
+	goto end;
+    }
 
 
     cred = (auth_body_t*)h->parsed;
     cred = (auth_body_t*)h->parsed;
 
 
@@ -112,39 +138,71 @@ static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
 	if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) {
 	if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) {
 	    if (pv_val.flags & PV_VAL_STR) {
 	    if (pv_val.flags & PV_VAL_STR) {
 		res = radius_authorize_sterman(_msg, &cred->digest, 
 		res = radius_authorize_sterman(_msg, &cred->digest, 
-					       &_msg->first_line.u.request.method,
+					       &_msg->
+					       first_line.u.request.method,
 					       &pv_val.rs);
 					       &pv_val.rs);
 	    } else {
 	    } else {
 		LM_ERR("uri_user pvar value is not string\n");
 		LM_ERR("uri_user pvar value is not string\n");
-		return AUTH_ERROR;
+		ret = -5;
+		goto end;
 	    }
 	    }
 	} else {
 	} else {
 	    LM_ERR("cannot get uri_user pvar value\n");
 	    LM_ERR("cannot get uri_user pvar value\n");
-	    return AUTH_ERROR;
+	    ret = -5;
+	    goto end;
 	}
 	}
     } else {
     } else {
 	if (get_uri_user(_msg, &uri_user) < 0) {
 	if (get_uri_user(_msg, &uri_user) < 0) {
 	    LM_ERR("To/From URI not found\n");
 	    LM_ERR("To/From URI not found\n");
-	    return AUTH_ERROR;
+	    ret = -2;
+	    goto end;
 	}
 	}
 	user.s = (char *)pkg_malloc(uri_user->len);
 	user.s = (char *)pkg_malloc(uri_user->len);
 	if (user.s == NULL) {
 	if (user.s == NULL) {
 	    LM_ERR("no pkg memory left for user\n");
 	    LM_ERR("no pkg memory left for user\n");
-	    return AUTH_ERROR;
+	    ret = -5;
+	    goto end;
 	}
 	}
 	un_escape(uri_user, &user);
 	un_escape(uri_user, &user);
 	res = radius_authorize_sterman(_msg, &cred->digest, 
 	res = radius_authorize_sterman(_msg, &cred->digest, 
 				       &_msg->first_line.u.request.method,
 				       &_msg->first_line.u.request.method,
 				       &user);
 				       &user);
-	pkg_free(user.s);
     }
     }
 
 
     if (res == 1) {
     if (res == 1) {
-	ret = auth_api.post_auth(_msg, h);
-	return ret;
+	switch(auth_api.post_auth(_msg, h)) {
+	default:
+	    BUG("unexpected reply '%d'.\n",
+		auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL));
+#ifdef EXTRA_DEBUG
+	    abort();
+#endif
+	    ret = -5;
+	    break;
+	case ERROR:             
+	    ret = -2;
+	    break;
+	case NOT_AUTHENTICATED:
+	    ret = -3;
+	    break;
+	case AUTHENTICATED:
+	    ret = 1;
+	    break;
+	}
+    } else {
+	ret = -1;
     }
     }
 
 
-    return AUTH_ERROR;
+ end:
+    if (user.s) pkg_free(user.s);
+    if (ret < 0) {
+	if (auth_api.build_challenge(_msg, (cred ? cred->stale : 0), &domain,
+				     NULL, NULL, _hftype) < 0) {
+	    LM_ERR("while creating challenge\n");
+	    ret = -5;
+	}
+    }
+    return ret;
 }
 }
 
 
 
 

+ 3 - 3
modules_k/auth_radius/authrad_mod.c

@@ -52,7 +52,7 @@ struct attr attrs[A_MAX+MAX_EXTRA];
 struct val vals[V_MAX+MAX_EXTRA];
 struct val vals[V_MAX+MAX_EXTRA];
 void *rh;
 void *rh;
 
 
-auth_api_k_t auth_api;
+auth_api_s_t auth_api;
 
 
 static int mod_init(void);         /* Module initialization function */
 static int mod_init(void);         /* Module initialization function */
 static int auth_fixup(void** param, int param_no); /* char* -> str* */
 static int auth_fixup(void** param, int param_no); /* char* -> str* */
@@ -120,7 +120,7 @@ struct module_exports exports = {
 static int mod_init(void)
 static int mod_init(void)
 {
 {
 	DICT_VENDOR *vend;
 	DICT_VENDOR *vend;
-	bind_auth_k_t bind_auth;
+	bind_auth_s_t bind_auth;
 	int n;
 	int n;
 
 
 	if ((rh = rc_read_config(radius_config)) == NULL) {
 	if ((rh = rc_read_config(radius_config)) == NULL) {
@@ -133,7 +133,7 @@ static int mod_init(void)
 		return -2;
 		return -2;
 	}
 	}
 
 
-	bind_auth = (bind_auth_k_t)find_export("bind_auth_k", 0, 0);
+	bind_auth = (bind_auth_s_t)find_export("bind_auth_s", 0, 0);
 	if (!bind_auth) {
 	if (!bind_auth) {
 		LM_ERR("unable to find bind_auth function. Check if you load the auth module.\n");
 		LM_ERR("unable to find bind_auth function. Check if you load the auth module.\n");
 		return -1;
 		return -1;

+ 2 - 2
modules_k/auth_radius/authrad_mod.h

@@ -30,7 +30,7 @@
 #ifndef AUTHRAD_MOD_H
 #ifndef AUTHRAD_MOD_H
 #define AUTHRAD_MOD_H
 #define AUTHRAD_MOD_H
 
 
-#include "../../modules_k/auth/api.h"
+#include "../../modules_s/auth/api.h"
 #include "../../lib/kcore/radius.h"
 #include "../../lib/kcore/radius.h"
 
 
 extern struct attr attrs[];
 extern struct attr attrs[];
@@ -41,6 +41,6 @@ extern struct extra_attr *auth_extra;
 
 
 extern int use_ruri_flag;
 extern int use_ruri_flag;
 
 
-extern auth_api_k_t auth_api;
+extern auth_api_s_t auth_api;
 
 
 #endif /* AUTHRAD_MOD_H */
 #endif /* AUTHRAD_MOD_H */

+ 80 - 43
modules_k/auth_radius/doc/auth_radius_admin.xml

@@ -78,14 +78,15 @@
 	<section>
 	<section>
 	<title>Dependencies</title>
 	<title>Dependencies</title>
 		<section>
 		<section>
-			<title>&kamailio; Modules</title>
+			<title>Modules</title>
 			<para>
 			<para>
 			The module depends on the following modules (in the other words 
 			The module depends on the following modules (in the other words 
 			the listed modules must be loaded before this module):
 			the listed modules must be loaded before this module):
 			<itemizedlist>
 			<itemizedlist>
 				<listitem>
 				<listitem>
-				<para><emphasis>auth</emphasis> -- Generic authentication 
-				functions</para>
+				<para><emphasis>modules_s/auth</emphasis>
+				-- Generic authentication functions
+				</para>
 				</listitem>
 				</listitem>
 			</itemizedlist>
 			</itemizedlist>
 			</para>
 			</para>
@@ -198,45 +199,55 @@ modparam("auth_radius", "use_ruri_flag", 22)
 		<ulink url="http://www.ietf.org/rfc/rfc2617.txt">RFC2617</ulink>. If 
 		<ulink url="http://www.ietf.org/rfc/rfc2617.txt">RFC2617</ulink>. If 
 		the credentials are verified successfully then the function will 
 		the credentials are verified successfully then the function will 
 		succeed and mark the credentials as authorized (marked credentials can 
 		succeed and mark the credentials as authorized (marked credentials can 
-		be later used by some other functions). If the function was unable to 
-		verify the credentials for some reason then it will fail and
-		the script should call
-		<function moreinfo="none">www_challenge</function>
-		which will challenge the user again.
+		be later used by some other functions).
+		</para>
+		<para>
+		If the function	was unable to  
+		verify the credentials for some reason, it fails and
+		assigns a WWW-Authorize header containing a new
+	challenge to digest_challenge AVP (see modules_s/auth).
+	The script should
+	then respond with 401 that includes this header, which will
+	challenge the user again.
 		</para>
 		</para>
 		<para>Negative codes may be interpreted as follows:</para>
 		<para>Negative codes may be interpreted as follows:</para>
 		<itemizedlist>
 		<itemizedlist>
 			<listitem><para>
 			<listitem><para>
-			<emphasis>-5 (generic error)</emphasis> - some generic error
-			occurred and no reply was sent out;
+			<emphasis>-5 (internal error)</emphasis> - some
+			internal error occurred;
 			</para></listitem>
 			</para></listitem>
 			<listitem><para>
 			<listitem><para>
-			<emphasis>-4 (no credentials)</emphasis> - credentials were not
-			found in request;
+			<emphasis>-4 (no credentials)</emphasis> -
+			credentials were not found in request;
 			</para></listitem>
 			</para></listitem>
 			<listitem><para>
 			<listitem><para>
 			<emphasis>-3 (stale nonce)</emphasis> - stale nonce;
 			<emphasis>-3 (stale nonce)</emphasis> - stale nonce;
 			</para></listitem>
 			</para></listitem>
+			<listitem><para>
+			<emphasis>-2 (bad request)</emphasis> -
+			something wrong in request, for example, credentials were not filled properly;
+			</para></listitem>
+			<listitem><para>
+			<emphasis>-1 (authorization failed)</emphasis> -
+			RADIUS responded with Access Reject
+			</para></listitem>
 		</itemizedlist>
 		</itemizedlist>
 		<para>
 		<para>
-		This function will, in fact, perform sanity checks over the received 
-		credentials and then pass them along to the radius server which will 
+		This function will, in fact, perform sanity checks over
+	the received  
+		credentials and then pass them along to the radius
+	server which will  
 		verify the credentials and return whether they are valid or not.
 		verify the credentials and return whether they are valid or not.
 		</para>
 		</para>
 		<para>Meaning of the parameter is as follows:</para>
 		<para>Meaning of the parameter is as follows:</para>
 		<itemizedlist>
 		<itemizedlist>
 		<listitem>
 		<listitem>
-			<para><emphasis>realm</emphasis> - Realm is a opaque string that 
-			the user agent should present to the user so he can decide what 
-			username and password to use. Usually this is domain of the host 
-			the server is running on.
-			</para>
-			<para>
-			If an empty string <quote></quote> is used then the server will 
-			generate it from the request. In case of REGISTER requests To 
-			header field domain will be used (because this header field 
-			represents a user being registered), for all other messages From 
-			header field domain will be used.
+			<para><emphasis>realm</emphasis> - Realm is a
+	opaque string that  
+			the user agent should present to the user so he
+	can decide what  
+			username and password to use.  In case of
+	REGISTER requests it is usually hostpart of To URI.
 			</para>
 			</para>
 			<para>
 			<para>
 			The string may contain pseudo variables.
 			The string may contain pseudo variables.
@@ -250,9 +261,22 @@ modparam("auth_radius", "use_ruri_flag", 22)
 		<title><function moreinfo="none">radius_www_authorize</function> usage</title>
 		<title><function moreinfo="none">radius_www_authorize</function> usage</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
 ...
 ...
-if (!radius_www_authorize("siphub.net")) {
-	www_challenge("siphub.net", "1");
-};
+    if (!radius_www_authorize("$td")) {
+    switch ($rc) {
+    case -5:
+	send_reply("500", "Server Internal Error");
+	exit;
+    case -2:
+        send_reply("400", "Bad Request");
+        exit;
+    default:
+    };
+    if (defined($avp(digest_challenge)) &amp;&amp;
+            ($avp(digest_challenge) != "")) {
+        append_to_reply("$avp(digest_challenge)");
+    };
+    send_reply("401", "Unauthorized");
+    exit;
 ...
 ...
 </programlisting>
 </programlisting>
 		</example>
 		</example>
@@ -266,10 +290,15 @@ if (!radius_www_authorize("siphub.net")) {
 		<ulink url="http://www.ietf.org/rfc/rfc2617.txt">RFC2617</ulink>. If 
 		<ulink url="http://www.ietf.org/rfc/rfc2617.txt">RFC2617</ulink>. If 
 		the credentials are verified successfully then the function will 
 		the credentials are verified successfully then the function will 
 		succeed and mark the credentials as authorized (marked credentials can 
 		succeed and mark the credentials as authorized (marked credentials can 
-		be later used by some other functions). If the function was unable to 
-		verify the credentials for some reason then it will fail and the script 
-		should call <function moreinfo="none">proxy_challenge</function> which 
-		will challenge the user again. For more about the negative return 
+		be later used by some other functions).  
+		</para>
+		<para>If the function was unable to  
+		verify the credentials for some reason, it fails and
+		assigns a WWW-Authorize header containing a new
+	challenge to digest_challenge AVP.  The script should
+	then respond with 407 that includes this header, which will
+	challenge the user again.
+		For more about the negative return 
 		codes, see the above function.
 		codes, see the above function.
 		</para>
 		</para>
 		<para>
 		<para>
@@ -282,10 +311,9 @@ if (!radius_www_authorize("siphub.net")) {
 		<listitem>
 		<listitem>
 			<para><emphasis>realm</emphasis> - Realm is a opaque string that 
 			<para><emphasis>realm</emphasis> - Realm is a opaque string that 
 			the user agent should present to the user so he can decide what 
 			the user agent should present to the user so he can decide what 
-			username and password to use.  This is usually
-			one of the domains the proxy is responsible for.
-			If an empty string <quote></quote> is used then the server will 
-			generate realm from host part of From header field URI.
+			username and password to use.  In case of
+	non-REGISTER requests it is usually hostpart of From or
+		P-Preferred-Identity URI.
 			</para>
 			</para>
 			<para>
 			<para>
 			The string may contain pseudo variables.
 			The string may contain pseudo variables.
@@ -310,13 +338,22 @@ if (!radius_www_authorize("siphub.net")) {
 		<title><function moreinfo="none">proxy_authorize</function> usage</title>
 		<title><function moreinfo="none">proxy_authorize</function> usage</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
 ...
 ...
-if (!radius_proxy_authorize("")) {   # Realm and URI user will be autogenerated
-	proxy_challenge("", "1");
-};
-...
-if (!radius_proxy_authorize("$pd", "$pU")) { # Realm and URI user are taken
-	proxy_challenge("$pd", "1");         # from P-Preferred-Identity
-};                                           # header field
+    if (!radius_proxy_authorize("$pd", "$pU")) { # Realm and URI user are taken
+    switch ($rc) {                               # from P-Preferred-Identity
+    case -5:                                     # header field
+	send_reply("500", "Server Internal Error");
+	exit;
+    case -2:
+        send_reply("400", "Bad Request");
+        exit;
+    default:
+    };
+    if (defined($avp(digest_challenge)) &amp;&amp;
+            ($avp(digest_challenge) != "")) {
+        append_to_reply("$avp(digest_challenge)");
+    };
+    send_reply("407", "Proxy Authentication Required");
+    exit;
 ...
 ...
 </programlisting>
 </programlisting>
 		</example>
 		</example>

+ 1 - 1
modules_k/auth_radius/sterman.c

@@ -35,7 +35,7 @@
 #include "../../usr_avp.h"
 #include "../../usr_avp.h"
 #include "../../lib/kcore/radius.h"
 #include "../../lib/kcore/radius.h"
 #include "../../ut.h"
 #include "../../ut.h"
-#include "../../modules_k/auth/api.h"
+#include "../../modules_s/auth/api.h"
 #include "sterman.h"
 #include "sterman.h"
 #include "authrad_mod.h"
 #include "authrad_mod.h"
 #include "extra.h"
 #include "extra.h"

+ 2 - 1
modules_k/auth_radius/sterman.h

@@ -40,6 +40,7 @@
  * which can be be used as a check item in the request.  Service type of
  * which can be be used as a check item in the request.  Service type of
  * the request is Authenticate-Only.
  * the request is Authenticate-Only.
  */
  */
-int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _method, str* _user); 
+int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred,
+			     str* _method, str* _user); 
 
 
 #endif /* STERMAN_H */
 #endif /* STERMAN_H */