Skip to content

Commit 1714b3d

Browse files
davidtrihy-genesysbenceszigeti
authored andcommitted
Updated docs and added explicit return code for * Contact when it fails
1 parent 9be7fa9 commit 1714b3d

File tree

2 files changed

+38
-22
lines changed

2 files changed

+38
-22
lines changed

modules/sipmsgops/doc/sipmsgops_admin.xml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,8 @@ add_body_part("Hello World!", "text/plain");
964964
<listitem><para><emphasis>'t'</emphasis> - checks the URI of the 'To' field
965965
and whether the domain contains valid characters.
966966
</para></listitem>
967-
<listitem><para><emphasis>'c'</emphasis> - checks the URI of the 'Contact' field.
967+
<listitem><para><emphasis>'c'</emphasis> - checks the value of the 'Contact' field
968+
and whether it is a Uri, Star - for REGISTER requests with Expires header set to 0.
968969
</para></listitem>
969970
</itemizedlist>
970971
</para>
@@ -1035,6 +1036,8 @@ add_body_part("Hello World!", "text/plain");
10351036
</para></listitem>
10361037
<listitem><para><emphasis>-29</emphasis> - Bad To URI username
10371038
</para></listitem>
1039+
<listitem><para><emphasis>-30</emphasis> - Contact header contains * for non-Register request
1040+
</para></listitem>
10381041
<listitem><para><emphasis>-255</emphasis> - undefined errors.
10391042
</para></listitem>
10401043
</itemizedlist>
@@ -1062,6 +1065,15 @@ if(!sipmsg_validate("sh", $var(err_reason)))
10621065
exit;
10631066
}
10641067
...
1068+
1069+
...
1070+
# checks Contact header for a 200 Ok reply and logs when it's *
1071+
if(!sipmsg_validate("c"))
1072+
{
1073+
if ($rc == -30)
1074+
xlog("Invalid * Contact header found\n");
1075+
}
1076+
...
10651077
</programlisting>
10661078
</example>
10671079
</section>

modules/sipmsgops/sipmsgops.c

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,29 +1610,31 @@ enum sip_validation_failures {
16101610
SV_BAD_USERNAME=-27,
16111611
SV_FROM_USERNAME_ERROR=-28,
16121612
SV_TO_USERNAME_ERROR=-29,
1613-
SV_BAD_EXPIRES=-30,
1613+
SV_BAD_STAR_CONTACT=-30,
16141614
SV_GENERIC_FAILURE=-255
16151615
};
16161616

16171617
#define METHOD_WITH_CONTACT_HDR (METHOD_INVITE | METHOD_REGISTER | METHOD_UPDATE | METHOD_SUBSCRIBE | METHOD_REFER)
16181618

16191619
static enum sip_validation_failures validate_contact_header(struct sip_msg *msg, enum request_method method, char reason[static MAX_REASON])
16201620
{
1621-
struct hdr_field *ptr = NULL, *expires = NULL;
1621+
struct hdr_field *ptr = NULL;
16221622
contact_t * contacts = NULL;
1623-
contact_body_t *contact_body = NULL;
16241623
exp_body_t *expires_body = NULL;
16251624
struct sip_uri test_contacts;
1626-
enum sip_validation_failures ret;
1625+
enum sip_validation_failures ret = SV_NO_ERROR;
16271626

16281627
if (method & METHOD_WITH_CONTACT_HDR) {
1629-
ret = SV_NO_CONTACT;
1630-
CHECK_HEADER("", contact);
1628+
if (!msg->contact) {
1629+
strcpy(reason, "SIP message doesn't have 'Contact' header");
1630+
ret = SV_NO_CONTACT;
1631+
goto failed;
1632+
}
16311633

16321634
/* iterate through Contact headers */
16331635
for(ptr = msg->contact; ptr; ptr = ptr->sibling) {
16341636
/* parse Contact header */
1635-
if(!ptr->parsed && (parse_contact(ptr) < 0
1637+
if (!ptr->parsed && (parse_contact(ptr) < 0
16361638
|| !ptr->parsed)) {
16371639
strcpy(reason, "failed to parse 'Contact' header");
16381640
ret = SV_CONTACT_PARSE_ERROR;
@@ -1652,34 +1654,36 @@ static enum sip_validation_failures validate_contact_header(struct sip_msg *msg,
16521654
}
16531655
}
16541656
} else {
1655-
/* empty contacts header - this can be a * Contact header, valid only for REGISTER requests */
1656-
contact_body = (contact_body_t *) msg->contact->parsed;
1657+
/* This is a star Contact header, valid only for REGISTER requests */
1658+
if (method == METHOD_REGISTER) {
1659+
if (msg->first_line.type == SIP_REPLY) {
1660+
strcpy(reason, "'Contact' header for REGISTER reply contains '*' only valid for REGISTER request");
1661+
ret = SV_BAD_STAR_CONTACT;
1662+
goto failed;
1663+
}
16571664

1658-
if (method != METHOD_REGISTER || msg->first_line.type == SIP_REPLY) {
1659-
strcpy(reason, "empty body for 'Contact' header");
1660-
ret = SV_CONTACT_PARSE_ERROR;
1661-
goto failed;
1662-
} else {
16631665
if (!msg->expires || (parse_expires(msg->expires) < 0 || !msg->expires->parsed)) {
16641666
strcpy(reason, "failed to parse 'Expires' header");
1665-
ret = SV_BAD_EXPIRES;
1667+
ret = SV_BAD_STAR_CONTACT;
16661668
goto failed;
16671669
}
16681670

16691671
expires_body = (exp_body_t*) msg->expires->parsed;
16701672

1671-
if (!expires_body || !(expires_body->val == 0 && contact_body->star == 1)) {
1672-
strcpy(reason, "Expires header greater than 0 for REGISTER 'Contact' header with '*' value");
1673-
ret = SV_CONTACT_PARSE_ERROR;
1673+
if (!expires_body || expires_body->val != 0) {
1674+
strcpy(reason, "'Expires' header greater than 0 for REGISTER 'Contact' header with '*' value");
1675+
ret = SV_BAD_STAR_CONTACT;
16741676
goto failed;
16751677
}
1678+
} else {
1679+
strcpy(reason, "'Contact' header for SIP message contains '*' only valid for REGISTER request");
1680+
ret = SV_BAD_STAR_CONTACT;
1681+
goto failed;
16761682
}
16771683
}
16781684
}
16791685
}
16801686

1681-
ret = SV_NO_ERROR;
1682-
16831687
failed:
16841688
return ret;
16851689
}
@@ -1912,7 +1916,7 @@ static int w_sip_validate(struct sip_msg *msg, void *_flags, pv_spec_t* err_txt)
19121916
}
19131917
}
19141918

1915-
if (flags & SIP_PARSE_CONTACT && (status_code > 199 || status_code < 400)) {
1919+
if (flags & SIP_PARSE_CONTACT && (status_code > 199 && status_code < 400)) {
19161920
ret = validate_contact_header(msg, method, reason);
19171921

19181922
if (ret != 0) {

0 commit comments

Comments
 (0)