@@ -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
16191619static 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-
16831687failed :
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