فهرست منبع

modules/auth: Added an optional parameter for method to pv_www_authenticate()

Peter Dunkley 13 سال پیش
والد
کامیت
3f35106f79
4فایلهای تغییر یافته به همراه87 افزوده شده و 23 حذف شده
  1. 15 13
      modules/auth/README
  2. 2 2
      modules/auth/api.h
  3. 64 7
      modules/auth/auth_mod.c
  4. 6 1
      modules/auth/doc/functions.xml

+ 15 - 13
modules/auth/README

@@ -15,7 +15,7 @@ Daniel-Constantin Mierla
    asipto.com
    <[email protected]>
 
-   Copyright © 2002, 2003 FhG FOKUS
+   Copyright © 2002, 2003 FhG FOKUS
      __________________________________________________________________
 
    1.1. Overview
@@ -47,7 +47,7 @@ Daniel-Constantin Mierla
         1.4.3. www_challenge(realm, flags)
         1.4.4. proxy_challenge(realm, flags)
         1.4.5. auth_challenge(realm, flags)
-        1.4.6. pv_www_authenticate(realm, passwd, flags)
+        1.4.6. pv_www_authenticate(realm, passwd, flags [, method])
         1.4.7. pv_proxy_authenticate(realm, passwd, flags)
         1.4.8. pv_auth_check(realm, passwd, flags, checks)
         1.4.9. auth_get_www_authenticate(realm, flags, pvdst)
@@ -72,7 +72,7 @@ Daniel-Constantin Mierla
 
 1.3. Parameters
 
-1.3.1. auth_checks_register, auth_checks_no_dlg, and auth_checks_in_dlg
+1.3.1.  auth_checks_register, auth_checks_no_dlg, and auth_checks_in_dlg
 (flags)
 
    These three module parameters control which optional integrity checks
@@ -507,7 +507,7 @@ modparam("auth", "force_stateless_reply", 1)
    records (not all SIP clients support SRV lookup), a subdomain of the
    master domain can be defined for SIP purposes (like sip.mydomain.net
    pointing to same IP address as the SRV record for mydomain.net). By
-   ignoring the realm_prefix "sip.", at authentication, sip.mydomain.net
+   ignoring the realm_prefix “sip.�, at authentication, sip.mydomain.net
    will be equivalent to mydomain.net .
 
    Default value is empty string.
@@ -557,7 +557,7 @@ if (has_credentials("myrealm")) {
 }
 ...
 
-1.4.3. www_challenge(realm, flags)
+1.4.3.  www_challenge(realm, flags)
 
    The function challenges a user agent. It will generate a WWW-Authorize
    header field containing a digest challenge, it will put the header
@@ -571,7 +571,7 @@ if (has_credentials("myrealm")) {
      * 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.
-       It must not be empty string "". In case of REGISTER requests To
+       It must not be empty string “�. In case of REGISTER requests To
        header field domain (e.g., variable $td) can be used (because this
        header field represents the user being registered), for all other
        messages From header field domain can be used (e.g., variable $fd).
@@ -593,7 +593,7 @@ if (!www_authenticate("$td", "subscriber")) {
 }
 ...
 
-1.4.4. proxy_challenge(realm, flags)
+1.4.4.  proxy_challenge(realm, flags)
 
    The function challenges a user agent. It will generate a
    Proxy-Authorize header field containing a digest challenge, it will put
@@ -615,7 +615,7 @@ if (!proxy_authenticate("$fd", "subscriber")) {
 };
 ...
 
-1.4.5. auth_challenge(realm, flags)
+1.4.5.  auth_challenge(realm, flags)
 
    The function challenges a user agent for authentication. It combines
    the functions www_challenge() and proxy_challenge(), by calling
@@ -634,7 +634,7 @@ if (!auth_check("$fd", "subscriber", "1")) {
 };
 ...
 
-1.4.6. pv_www_authenticate(realm, passwd, flags)
+1.4.6.  pv_www_authenticate(realm, passwd, flags [, method])
 
    The function verifies credentials according to RFC2617. If the
    credentials are verified successfully then the function will succeed
@@ -658,7 +658,7 @@ if (!auth_check("$fd", "subscriber", "1")) {
      * 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.
-       It must not be empty string "". In case of REGISTER requests To
+       It must not be empty string “�. In case of REGISTER requests To
        header field domain (e.g., varibale $td) can be used (because this
        header field represents a user being registered), for all other
        messages From header field domain can be used (e.g., varibale $fd).
@@ -671,6 +671,8 @@ if (!auth_check("$fd", "subscriber", "1")) {
           + 4 - build challenge header with qop=auth and add it to avp
           + 8 - build challenge header with qop=auth-int and add it to avp
           + 16 - build challenge header with stale=true
+     * method - the method to be used for authentication. This parameter
+       is optional and if not set is the first "word" on the request-line.
 
    When challenge header is built and stored in avp, append_to_reply() and
    sl reply functions can be used to send appropriate SIP reply to
@@ -685,7 +687,7 @@ if (!pv_www_authenticate("$td", "123abc", "0")) {
 };
 ...
 
-1.4.7. pv_proxy_authenticate(realm, passwd, flags)
+1.4.7.  pv_proxy_authenticate(realm, passwd, flags)
 
    The function verifies credentials according to RFC2617. If the
    credentials are verified successfully then the function will succeed
@@ -708,7 +710,7 @@ if (!pv_proxy_authenticate("$fd", "$avp(password)", "0")) {
 };
 ...
 
-1.4.8. pv_auth_check(realm, passwd, flags, checks)
+1.4.8.  pv_auth_check(realm, passwd, flags, checks)
 
    The function combines the functionalities of pv_www_authenticate and
    pv_proxy_authenticate, first being exectuted if the SIP request is a
@@ -733,7 +735,7 @@ if (!pv_auth_check("$fd", "$avp(password)", "0", "1")) {
 };
 ...
 
-1.4.9. auth_get_www_authenticate(realm, flags, pvdst)
+1.4.9.  auth_get_www_authenticate(realm, flags, pvdst)
 
    Build WWW-Authentication header and set the resulting value in 'pvdest'
    parameter.

+ 2 - 2
modules/auth/api.h

@@ -116,9 +116,9 @@ int auth_challenge(struct sip_msg *msg, str *realm, int flags,
 		int hftype);
 
 typedef int (*pv_authenticate_f)(struct sip_msg *msg, str *realm, str *passwd,
-		int flags, int hftype);
+		int flags, int hftype, str *method);
 int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
-		int flags, int hftype);
+		int flags, int hftype, str *method);
 
 typedef int (*consume_credentials_f)(struct sip_msg* msg);
 int consume_credentials(struct sip_msg* msg);

+ 64 - 7
modules/auth/auth_mod.c

@@ -93,6 +93,8 @@ static int pv_proxy_authenticate(struct sip_msg* msg, char* realm,
 		char *passwd, char *flags);
 static int pv_www_authenticate(struct sip_msg* msg, char* realm,
 		char *passwd, char *flags);
+static int pv_www_authenticate2(struct sip_msg* msg, char* realm,
+		char *passwd, char *flags, char *method);
 static int fixup_pv_auth(void **param, int param_no);
 static int pv_auth_check(sip_msg_t *msg, char *realm,
 		char *passwd, char *flags, char *checks);
@@ -166,6 +168,8 @@ static cmd_export_t cmds[] = {
 			fixup_pv_auth, REQUEST_ROUTE},
     {"pv_www_authenticate",    (cmd_function)pv_www_authenticate,    3,
 			fixup_pv_auth, REQUEST_ROUTE},
+    {"pv_www_authenticate",    (cmd_function)pv_www_authenticate2,   4,
+			fixup_pv_auth, REQUEST_ROUTE},
     {"pv_proxy_authorize",     (cmd_function)pv_proxy_authenticate,  3,
 			fixup_pv_auth, REQUEST_ROUTE},
     {"pv_proxy_authenticate",  (cmd_function)pv_proxy_authenticate,  3,
@@ -458,7 +462,7 @@ int w_has_credentials(sip_msg_t *msg, char* realm, char* s2)
  * @brief do WWW-Digest authentication with password taken from cfg var
  */
 int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
-		int flags, int hftype)
+		int flags, int hftype, str *method)
 {
 	struct hdr_field* h;
 	auth_body_t* cred;
@@ -522,8 +526,7 @@ int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
 	}
 
 	/* Recalculate response, it must be same to authorize successfully */
-	ret = auth_check_response(&(cred->digest),
-				&msg->first_line.u.request.method, ha1);
+	ret = auth_check_response(&(cred->digest), method, ha1);
 	if(ret==AUTHENTICATED) {
 		ret = AUTH_OK;
 		switch(post_auth(msg, h)) {
@@ -602,7 +605,8 @@ static int pv_proxy_authenticate(struct sip_msg *msg, char* realm,
 		LM_ERR("invalid flags value\n");
 		goto error;
 	}
-	return pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T);
+	return pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T,
+				&msg->first_line.u.request.method);
 
 error:
 	return AUTH_ERROR;
@@ -642,7 +646,58 @@ static int pv_www_authenticate(struct sip_msg *msg, char* realm,
 		LM_ERR("invalid flags value\n");
 		goto error;
 	}
-	return pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T);
+	return pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T,
+				&msg->first_line.u.request.method);
+
+error:
+	return AUTH_ERROR;
+}
+
+static int pv_www_authenticate2(struct sip_msg *msg, char* realm,
+		char *passwd, char *flags, char *method)
+{
+    int vflags = 0;
+    str srealm  = {0, 0};
+    str spasswd = {0, 0};
+    str smethod = {0, 0};
+
+	if (get_str_fparam(&srealm, msg, (fparam_t*)realm) < 0) {
+		LM_ERR("failed to get realm value\n");
+		goto error;
+	}
+
+	if(srealm.len==0) {
+		LM_ERR("invalid realm value - empty content\n");
+		goto error;
+	}
+
+	if (get_str_fparam(&spasswd, msg, (fparam_t*)passwd) < 0) {
+		LM_ERR("failed to get passwd value\n");
+		goto error;
+	}
+
+	if(spasswd.len==0) {
+		LM_ERR("invalid password value - empty content\n");
+		goto error;
+	}
+
+	if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) {
+		LM_ERR("invalid flags value\n");
+		goto error;
+	}
+
+	if (get_str_fparam(&smethod, msg, (fparam_t*)method) < 0) {
+		LM_ERR("failed to get method value\n");
+		goto error;
+	}
+
+	if(smethod.len==0) {
+		LM_ERR("invalid method value - empty content\n");
+		goto error;
+	}
+
+	return pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T,
+				&smethod);
 
 error:
 	return AUTH_ERROR;
@@ -711,9 +766,11 @@ static int pv_auth_check(sip_msg_t *msg, char *realm,
 			vflags, vchecks);
 
 	if(msg->REQ_METHOD==METHOD_REGISTER)
-		ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T);
+		ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T,
+					&msg->first_line.u.request.method);
 	else
-		ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T);
+		ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T,
+					&msg->first_line.u.request.method);
 
 	if(ret==AUTH_OK && (vflags&AUTH_CHECK_ID_F)) {
 		hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth;

+ 6 - 1
modules/auth/doc/functions.xml

@@ -181,7 +181,7 @@ if (!auth_check("$fd", "subscriber", "1")) {
 
 	<section id="pv_www_authenticate">
 		<title>
-		<function moreinfo="none">pv_www_authenticate(realm, passwd, flags)</function>
+		<function moreinfo="none">pv_www_authenticate(realm, passwd, flags [, method])</function>
 		</title>
 		<para>
 		The function verifies credentials according to
@@ -270,6 +270,11 @@ if (!auth_check("$fd", "subscriber", "1")) {
 
 			</itemizedlist>
 		</listitem>
+		<listitem>
+			<para><emphasis>method</emphasis> - the method to be used for
+			authentication. This parameter is optional and if not set
+			is the first "word" on the request-line.</para>
+		</listitem>
 		</itemizedlist>
 		<para>
 			When challenge header is built and stored in avp,