Просмотр исходного кода

Merge pull request #725 from AndreasHuber-CH/contact_length

registrar: Fix check of contact length and make it configurable
Daniel-Constantin Mierla 9 лет назад
Родитель
Сommit
4af08be47d

+ 30 - 0
modules/registrar/doc/registrar_admin.xml

@@ -929,6 +929,36 @@ modparam("registrar", "flow_timer", 25)
 		</example>
 	</section>
 
+	<section id="registrar.p.contact_max_size">
+		<title><varname>contact_max_size</varname> (integer)</title>
+		<para>
+		Max size of URIs in <quote>Contact:</quote> header.
+		</para>
+		<para>
+		The size of URIs in <quote>Contact:</quote> headers are checked to be
+		lower or equal to this value.
+		A warning is logged and a 400 Bad Request is sent in response to REGISTER
+		requests with contact URIs that are longer than this value.
+		</para>
+		<para>
+		If a database is used then you must make sure that your database model supports
+		strings of the configured size in the column <quote>contact</quote> of the table
+		specified in <quote>save()</quote> function.
+		</para>
+		<para>
+		<emphasis>
+			Default value is 255.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>contact_max_size</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("registrar", "contact_max_size", 500)
+...
+		</programlisting>
+		</example>
+	</section>
 
 	</section>
 

+ 3 - 0
modules/registrar/registrar.c

@@ -106,6 +106,8 @@ int reg_outbound_mode = 0;
 int reg_regid_mode = 0;
 int reg_flow_timer = 0;
 
+int contact_max_size = 255; /* max size of contact URIs */
+
 str match_callid_name = str_init("match_callid");
 str match_received_name = str_init("match_received");
 str match_contact_name = str_init("match_contact");
@@ -225,6 +227,7 @@ static param_export_t params[] = {
 	{"outbound_mode",      INT_PARAM, &reg_outbound_mode					},
 	{"regid_mode",         INT_PARAM, &reg_regid_mode					},
 	{"flow_timer",         INT_PARAM, &reg_flow_timer					},
+	{"contact_max_size",   INT_PARAM, &contact_max_size					},
 	{0, 0, 0}
 };
 

+ 1 - 1
modules/registrar/registrar.h

@@ -39,7 +39,7 @@
 
 /* if DB support is used, this values must not exceed the
  * storage capacity of the DB columns! See db/schema/entities.xml */
-#define CONTACT_MAX_SIZE       255
+extern int contact_max_size; /* configurable using module parameter "contact_max_size" instead of compile time constant */
 #define RECEIVED_MAX_SIZE      255
 #define USERNAME_MAX_SIZE      64
 #define DOMAIN_MAX_SIZE        128

+ 14 - 5
modules/registrar/sip_msg.c

@@ -154,12 +154,14 @@ int check_contacts(struct sip_msg* _m, int* _s)
 		/* The first Contact HF is star */
 		/* Expires must be zero */
 		if (get_expires_hf(_m) != 0) {
+			LM_WARN("expires must be 0 for star contact\n");
 			rerrno = R_STAR_EXP;
 			return 1;
 		}
 
 		/* Message must contain no contacts */
 		if (((contact_body_t*)_m->contact->parsed)->contacts) {
+			LM_WARN("star contact cannot be mixed with other contacts\n");
 			rerrno = R_STAR_CONT;
 			return 1;
 		}
@@ -168,6 +170,7 @@ int check_contacts(struct sip_msg* _m, int* _s)
 		p = _m->contact->next;
 		while(p) {
 			if (p->type == HDR_CONTACT_T) {
+				LM_WARN("star contact cannot be mixed with other contacts\n");
 				rerrno = R_STAR_CONT;
 				return 1;
 			}
@@ -176,18 +179,24 @@ int check_contacts(struct sip_msg* _m, int* _s)
 
 		*_s = 1;
 	} else { /* The first Contact HF is not star */
-		/* Message must contain no star Contact HF */
-		p = _m->contact->next;
+		p = _m->contact;
 		while(p) {
 			if (p->type == HDR_CONTACT_T) {
+				/* Message must contain no star Contact HF */
 				if (((contact_body_t*)p->parsed)->star == 1) {
+					LM_WARN("star contact cannot be mixed with other contacts\n");
 					rerrno = R_STAR_CONT;
 					return 1;
 				}
-				/* check also the lenght of all contacts */
+				/* check also the length of all contacts */
 				for(c=((contact_body_t*)p->parsed)->contacts ; c ; c=c->next) {
-					if (c->uri.len > CONTACT_MAX_SIZE
-							|| (c->received && c->received->len>RECEIVED_MAX_SIZE) ) {
+					if (c->uri.len > contact_max_size) {
+						LM_WARN("contact uri is too long: [%.*s]\n", c->uri.len, c->uri.s);
+						rerrno = R_CONTACT_LEN;
+						return 1;
+					}
+					if (c->received && c->received->len>RECEIVED_MAX_SIZE) {
+						LM_WARN("received attribute of contact is too long\n");
 						rerrno = R_CONTACT_LEN;
 						return 1;
 					}