Jelajahi Sumber

sanity: add check to ignore non-"digest" schemes

resolves #892
Camille Oudot 8 tahun lalu
induk
melakukan
9b6824da31

+ 9 - 0
src/modules/sanity/doc/sanity_admin.xml

@@ -101,6 +101,15 @@
 			digest credentials (2048) - Check all instances of digest credentials in a
 			digest credentials (2048) - Check all instances of digest credentials in a
 			message. The test checks whether there are all required
 			message. The test checks whether there are all required
 			digest parameters and that they have meaningful values.
 			digest parameters and that they have meaningful values.
+			<emphasis>NOTE:</emphasis> the message will be considered invalid
+			if the authorization scheme differs from "digest",
+			</para>
+		</listitem>
+		<listitem>
+			<para>
+			authorization header (8192) - checks if the Authorization is valid
+			if the scheme is "digest" (see "digest credentials" above), always
+			returns success for other schemes.
 			</para>
 			</para>
 		</listitem>
 		</listitem>
 		</itemizedlist>
 		</itemizedlist>

+ 4 - 0
src/modules/sanity/mod_sanity.c

@@ -209,6 +209,10 @@ int sanity_check(struct sip_msg* _msg, int msg_checks, int uri_checks)
 			(ret = check_digest(_msg, uri_checks)) != SANITY_CHECK_PASSED) {
 			(ret = check_digest(_msg, uri_checks)) != SANITY_CHECK_PASSED) {
 		goto done;
 		goto done;
 	}
 	}
+	if (SANITY_CHECK_AUTHORIZATION & msg_checks &&
+			(ret = check_authorization(_msg, uri_checks)) != SANITY_CHECK_PASSED) {
+		goto done;
+	}
 	if (SANITY_CHECK_DUPTAGS & msg_checks &&
 	if (SANITY_CHECK_DUPTAGS & msg_checks &&
 			(ret = check_duptags(_msg)) != SANITY_CHECK_PASSED) {
 			(ret = check_duptags(_msg)) != SANITY_CHECK_PASSED) {
 		goto done;
 		goto done;

+ 3 - 1
src/modules/sanity/mod_sanity.h

@@ -41,7 +41,8 @@
 #define SANITY_PARSE_URIS              (1<<10)
 #define SANITY_PARSE_URIS              (1<<10)
 #define SANITY_CHECK_DIGEST            (1<<11)
 #define SANITY_CHECK_DIGEST            (1<<11)
 #define SANITY_CHECK_DUPTAGS           (1<<12)
 #define SANITY_CHECK_DUPTAGS           (1<<12)
-#define SANITY_MAX_CHECKS              (1<<13)  /* Make sure this is the highest value */
+#define SANITY_CHECK_AUTHORIZATION     (1<<13)
+#define SANITY_MAX_CHECKS              (1<<14)  /* Make sure this is the highest value */
 
 
 /* VIA_SIP_VERSION and VIA_PROTOCOL do not work yet
 /* VIA_SIP_VERSION and VIA_PROTOCOL do not work yet
  * and PARSE_URIS is very expensive */
  * and PARSE_URIS is very expensive */
@@ -69,6 +70,7 @@
 #define SANITY_CHECK_PASSED 1
 #define SANITY_CHECK_PASSED 1
 #define SANITY_CHECK_FAILED 0
 #define SANITY_CHECK_FAILED 0
 #define SANITY_CHECK_ERROR -1
 #define SANITY_CHECK_ERROR -1
+#define SANITY_CHECK_NOT_APPLICABLE -2
 
 
 struct _strlist {
 struct _strlist {
 	str string;            /* the string */
 	str string;            /* the string */

+ 26 - 4
src/modules/sanity/sanity.c

@@ -937,11 +937,10 @@ int check_parse_uris(struct sip_msg* _msg, int checks) {
 	return SANITY_CHECK_PASSED;
 	return SANITY_CHECK_PASSED;
 }
 }
 
 
-
 /* Make sure that username attribute in all digest credentials
 /* Make sure that username attribute in all digest credentials
  * instances has a meaningful value
  * instances has a meaningful value
  */
  */
-int check_digest(struct sip_msg* msg, int checks)
+static int check_digest_only(struct sip_msg* msg, int checks)
 {
 {
 	struct hdr_field* ptr;
 	struct hdr_field* ptr;
 	dig_cred_t* cred;
 	dig_cred_t* cred;
@@ -970,9 +969,14 @@ int check_digest(struct sip_msg* msg, int checks)
 	}
 	}
 	while(ptr) {
 	while(ptr) {
 		if ((ret = parse_credentials(ptr)) != 0) {
 		if ((ret = parse_credentials(ptr)) != 0) {
-			DBG("sanity_check(): check_digest: Cannot parse credentials: %d\n",
+			if (ret == 1) {
+				DBG("sanity_check(): check_digest: Not a \"digest\" authorization\n");
+				return SANITY_CHECK_NOT_APPLICABLE;
+			} else {
+				DBG("sanity_check(): check_digest: Cannot parse credentials: %d\n",
 					ret);
 					ret);
-			return SANITY_CHECK_FAILED;
+				return SANITY_CHECK_FAILED;
+			}
 		}
 		}
 
 
 		cred = &((auth_body_t*)ptr->parsed)->digest;
 		cred = &((auth_body_t*)ptr->parsed)->digest;
@@ -1018,6 +1022,24 @@ int check_digest(struct sip_msg* msg, int checks)
 	return SANITY_CHECK_PASSED;
 	return SANITY_CHECK_PASSED;
 }
 }
 
 
+int check_authorization(struct sip_msg* msg, int checks) {
+	int ret;
+
+	ret = check_digest_only(msg, checks);
+	if (ret == SANITY_CHECK_PASSED || ret == SANITY_CHECK_NOT_APPLICABLE) {
+		return SANITY_CHECK_PASSED;
+	} else {
+		return SANITY_CHECK_FAILED;
+	}
+}
+
+int check_digest(struct sip_msg* msg, int checks) {
+	if (check_digest_only(msg, checks) == SANITY_CHECK_PASSED) {
+		return SANITY_CHECK_PASSED;
+	} else {
+		return SANITY_CHECK_FAILED;
+	}
+}
 
 
 /* check for the presence of duplicate tag prameters in To/From headers */
 /* check for the presence of duplicate tag prameters in To/From headers */
 int check_duptags(sip_msg_t* _msg)
 int check_duptags(sip_msg_t* _msg)

+ 2 - 0
src/modules/sanity/sanity.h

@@ -74,6 +74,8 @@ int check_parse_uris(struct sip_msg* _msg, int checks);
  */
  */
 int check_digest(struct sip_msg* _msg, int checks);
 int check_digest(struct sip_msg* _msg, int checks);
 
 
+int check_authorization(struct sip_msg* msg, int checks);
+
 /* check if there are duplicate tag params in From/To headers */
 /* check if there are duplicate tag params in From/To headers */
 int check_duptags(sip_msg_t* _msg);
 int check_duptags(sip_msg_t* _msg);