소스 검색

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
    asipto.com
    <[email protected]>
    <[email protected]>
 
 
-   Copyright © 2002, 2003 FhG FOKUS
+   Copyright © 2002, 2003 FhG FOKUS
      __________________________________________________________________
      __________________________________________________________________
 
 
    1.1. Overview
    1.1. Overview
@@ -47,7 +47,7 @@ Daniel-Constantin Mierla
         1.4.3. www_challenge(realm, flags)
         1.4.3. www_challenge(realm, flags)
         1.4.4. proxy_challenge(realm, flags)
         1.4.4. proxy_challenge(realm, flags)
         1.4.5. auth_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.7. pv_proxy_authenticate(realm, passwd, flags)
         1.4.8. pv_auth_check(realm, passwd, flags, checks)
         1.4.8. pv_auth_check(realm, passwd, flags, checks)
         1.4.9. auth_get_www_authenticate(realm, flags, pvdst)
         1.4.9. auth_get_www_authenticate(realm, flags, pvdst)
@@ -72,7 +72,7 @@ Daniel-Constantin Mierla
 
 
 1.3. Parameters
 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)
 (flags)
 
 
    These three module parameters control which optional integrity checks
    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
    records (not all SIP clients support SRV lookup), a subdomain of the
    master domain can be defined for SIP purposes (like sip.mydomain.net
    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
    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 .
    will be equivalent to mydomain.net .
 
 
    Default value is empty string.
    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
    The function challenges a user agent. It will generate a WWW-Authorize
    header field containing a digest challenge, it will put the header
    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
      * 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.
        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.
        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 domain (e.g., variable $td) can be used (because this
        header field represents the user being registered), for all other
        header field represents the user being registered), for all other
        messages From header field domain can be used (e.g., variable $fd).
        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
    The function challenges a user agent. It will generate a
    Proxy-Authorize header field containing a digest challenge, it will put
    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 function challenges a user agent for authentication. It combines
    the functions www_challenge() and proxy_challenge(), by calling
    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
    The function verifies credentials according to RFC2617. If the
    credentials are verified successfully then the function will succeed
    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
      * 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.
        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.
        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 domain (e.g., varibale $td) can be used (because this
        header field represents a user being registered), for all other
        header field represents a user being registered), for all other
        messages From header field domain can be used (e.g., varibale $fd).
        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
           + 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
           + 8 - build challenge header with qop=auth-int and add it to avp
           + 16 - build challenge header with stale=true
           + 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
    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
    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
    The function verifies credentials according to RFC2617. If the
    credentials are verified successfully then the function will succeed
    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
    The function combines the functionalities of pv_www_authenticate and
    pv_proxy_authenticate, first being exectuted if the SIP request is a
    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'
    Build WWW-Authentication header and set the resulting value in 'pvdest'
    parameter.
    parameter.

+ 2 - 2
modules/auth/api.h

@@ -116,9 +116,9 @@ int auth_challenge(struct sip_msg *msg, str *realm, int flags,
 		int hftype);
 		int hftype);
 
 
 typedef int (*pv_authenticate_f)(struct sip_msg *msg, str *realm, str *passwd,
 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 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);
 typedef int (*consume_credentials_f)(struct sip_msg* msg);
 int consume_credentials(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);
 		char *passwd, char *flags);
 static int pv_www_authenticate(struct sip_msg* msg, char* realm,
 static int pv_www_authenticate(struct sip_msg* msg, char* realm,
 		char *passwd, char *flags);
 		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 fixup_pv_auth(void **param, int param_no);
 static int pv_auth_check(sip_msg_t *msg, char *realm,
 static int pv_auth_check(sip_msg_t *msg, char *realm,
 		char *passwd, char *flags, char *checks);
 		char *passwd, char *flags, char *checks);
@@ -166,6 +168,8 @@ static cmd_export_t cmds[] = {
 			fixup_pv_auth, REQUEST_ROUTE},
 			fixup_pv_auth, REQUEST_ROUTE},
     {"pv_www_authenticate",    (cmd_function)pv_www_authenticate,    3,
     {"pv_www_authenticate",    (cmd_function)pv_www_authenticate,    3,
 			fixup_pv_auth, REQUEST_ROUTE},
 			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,
     {"pv_proxy_authorize",     (cmd_function)pv_proxy_authenticate,  3,
 			fixup_pv_auth, REQUEST_ROUTE},
 			fixup_pv_auth, REQUEST_ROUTE},
     {"pv_proxy_authenticate",  (cmd_function)pv_proxy_authenticate,  3,
     {"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
  * @brief do WWW-Digest authentication with password taken from cfg var
  */
  */
 int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
 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;
 	struct hdr_field* h;
 	auth_body_t* cred;
 	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 */
 	/* 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) {
 	if(ret==AUTHENTICATED) {
 		ret = AUTH_OK;
 		ret = AUTH_OK;
 		switch(post_auth(msg, h)) {
 		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");
 		LM_ERR("invalid flags value\n");
 		goto error;
 		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:
 error:
 	return AUTH_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");
 		LM_ERR("invalid flags value\n");
 		goto error;
 		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:
 error:
 	return AUTH_ERROR;
 	return AUTH_ERROR;
@@ -711,9 +766,11 @@ static int pv_auth_check(sip_msg_t *msg, char *realm,
 			vflags, vchecks);
 			vflags, vchecks);
 
 
 	if(msg->REQ_METHOD==METHOD_REGISTER)
 	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
 	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)) {
 	if(ret==AUTH_OK && (vflags&AUTH_CHECK_ID_F)) {
 		hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth;
 		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">
 	<section id="pv_www_authenticate">
 		<title>
 		<title>
-		<function moreinfo="none">pv_www_authenticate(realm, passwd, flags)</function>
+		<function moreinfo="none">pv_www_authenticate(realm, passwd, flags [, method])</function>
 		</title>
 		</title>
 		<para>
 		<para>
 		The function verifies credentials according to
 		The function verifies credentials according to
@@ -270,6 +270,11 @@ if (!auth_check("$fd", "subscriber", "1")) {
 
 
 			</itemizedlist>
 			</itemizedlist>
 		</listitem>
 		</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>
 		</itemizedlist>
 		<para>
 		<para>
 			When challenge header is built and stored in avp,
 			When challenge header is built and stored in avp,