Răsfoiți Sursa

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

Juha Heinanen 15 ani în urmă
părinte
comite
6f5bc8bed4

+ 182 - 142
modules_k/auth_radius/README

@@ -22,42 +22,41 @@ Jan Janak
 
    <[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 $Revision$ $Date: 2008-03-08 01:03:56 +0200
-                              (Sat, 08 Mar 2008) $
-     __________________________________________________________
+   Revision $Revision$ $Date$
+     __________________________________________________________________
 
    Table of Contents
 
    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
 
-   1.1. "SIP-AVP" RADIUS AVP exmaples
+   1.1. “SIP-AVP� RADIUS AVP exmaples
    1.2. radius_config parameter usage
    1.3. service_type parameter usage
    1.4. auth_extra parameter usage
@@ -67,30 +66,50 @@ Jan Janak
 
 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/.
 
-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
      * SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER
      * SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE
@@ -100,7 +119,7 @@ Chapter 1. Admin Guide
 
    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]"
     - STRING NAME AVP (email) with STRING VALUE ([email protected])
@@ -112,165 +131,186 @@ Chapter 1. Admin Guide
     - 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
    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
 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
 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
-   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
 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
 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
-   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:
-     * -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;
+     * -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:
-     * 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.
 
    This function can be used from REQUEST_ROUTE.
 
    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
-   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:
-     * 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.
-     * 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.
 
    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
  *
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2010 Juha Heinanen
  *
  * This file is part of Kamailio, a free SIP server.
  *
@@ -41,7 +42,7 @@
 #include "../../dprint.h"
 #include "../../ut.h"
 #include "../../pvar.h"
-#include "../../modules_k/auth/api.h"
+#include "../../modules_s/auth/api.h"
 #include "authorize.h"
 #include "sterman.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
  */
 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;
     auth_result_t ret;
@@ -87,22 +88,47 @@ static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
     str user, domain;
     pv_value_t pv_val;
 
+    cred = 0;
+    ret = -1;
+    user.s = 0;
+
     /* get pre_auth domain from _realm pvar (if exists) */
     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");
-	    return AUTH_ERROR;
+	    return -5;
 	}
     } else {
-	/* get pre_auth domain from To/From header */
 	domain.len = 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;
 
@@ -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_val.flags & PV_VAL_STR) {
 		res = radius_authorize_sterman(_msg, &cred->digest, 
-					       &_msg->first_line.u.request.method,
+					       &_msg->
+					       first_line.u.request.method,
 					       &pv_val.rs);
 	    } else {
 		LM_ERR("uri_user pvar value is not string\n");
-		return AUTH_ERROR;
+		ret = -5;
+		goto end;
 	    }
 	} else {
 	    LM_ERR("cannot get uri_user pvar value\n");
-	    return AUTH_ERROR;
+	    ret = -5;
+	    goto end;
 	}
     } else {
 	if (get_uri_user(_msg, &uri_user) < 0) {
 	    LM_ERR("To/From URI not found\n");
-	    return AUTH_ERROR;
+	    ret = -2;
+	    goto end;
 	}
 	user.s = (char *)pkg_malloc(uri_user->len);
 	if (user.s == NULL) {
 	    LM_ERR("no pkg memory left for user\n");
-	    return AUTH_ERROR;
+	    ret = -5;
+	    goto end;
 	}
 	un_escape(uri_user, &user);
 	res = radius_authorize_sterman(_msg, &cred->digest, 
 				       &_msg->first_line.u.request.method,
 				       &user);
-	pkg_free(user.s);
     }
 
     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];
 void *rh;
 
-auth_api_k_t auth_api;
+auth_api_s_t auth_api;
 
 static int mod_init(void);         /* Module initialization function */
 static int auth_fixup(void** param, int param_no); /* char* -> str* */
@@ -120,7 +120,7 @@ struct module_exports exports = {
 static int mod_init(void)
 {
 	DICT_VENDOR *vend;
-	bind_auth_k_t bind_auth;
+	bind_auth_s_t bind_auth;
 	int n;
 
 	if ((rh = rc_read_config(radius_config)) == NULL) {
@@ -133,7 +133,7 @@ static int mod_init(void)
 		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) {
 		LM_ERR("unable to find bind_auth function. Check if you load the auth module.\n");
 		return -1;

+ 2 - 2
modules_k/auth_radius/authrad_mod.h

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

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

@@ -78,14 +78,15 @@
 	<section>
 	<title>Dependencies</title>
 		<section>
-			<title>&kamailio; Modules</title>
+			<title>Modules</title>
 			<para>
 			The module depends on the following modules (in the other words 
 			the listed modules must be loaded before this module):
 			<itemizedlist>
 				<listitem>
-				<para><emphasis>auth</emphasis> -- Generic authentication 
-				functions</para>
+				<para><emphasis>modules_s/auth</emphasis>
+				-- Generic authentication functions
+				</para>
 				</listitem>
 			</itemizedlist>
 			</para>
@@ -198,45 +199,55 @@ modparam("auth_radius", "use_ruri_flag", 22)
 		<ulink url="http://www.ietf.org/rfc/rfc2617.txt">RFC2617</ulink>. 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
-		<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>Negative codes may be interpreted as follows:</para>
 		<itemizedlist>
 			<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>
 			<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>
 			<listitem><para>
 			<emphasis>-3 (stale nonce)</emphasis> - stale nonce;
 			</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>
 		<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.
 		</para>
 		<para>Meaning of the parameter is as follows:</para>
 		<itemizedlist>
 		<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>
 			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>
 		<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>
 		</example>
@@ -266,10 +290,15 @@ if (!radius_www_authorize("siphub.net")) {
 		<ulink url="http://www.ietf.org/rfc/rfc2617.txt">RFC2617</ulink>. 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 <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.
 		</para>
 		<para>
@@ -282,10 +311,9 @@ if (!radius_www_authorize("siphub.net")) {
 		<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.  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>
 			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>
 		<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>
 		</example>

+ 1 - 1
modules_k/auth_radius/sterman.c

@@ -35,7 +35,7 @@
 #include "../../usr_avp.h"
 #include "../../lib/kcore/radius.h"
 #include "../../ut.h"
-#include "../../modules_k/auth/api.h"
+#include "../../modules_s/auth/api.h"
 #include "sterman.h"
 #include "authrad_mod.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
  * 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 */