| 1586 | #define METHOD_WITH_CONTACT_HDR (METHOD_INVITE | METHOD_REGISTER | METHOD_UPDATE | METHOD_SUBSCRIBE | METHOD_REFER) |
| 1587 | |
| 1588 | static enum sip_validation_failures validate_contact_header(struct sip_msg *msg, enum request_method method, char reason[static MAX_REASON]) |
| 1589 | { |
| 1590 | struct hdr_field *ptr = NULL; |
| 1591 | contact_t * contacts = NULL; |
| 1592 | exp_body_t *expires_body = NULL; |
| 1593 | struct sip_uri test_contacts; |
| 1594 | |
| 1595 | if (method & METHOD_WITH_CONTACT_HDR) { |
| 1596 | if (!msg->contact) { |
| 1597 | strcpy(reason, "SIP message doesn't have 'Contact' header"); |
| 1598 | return SV_NO_CONTACT; |
| 1599 | } |
| 1600 | |
| 1601 | /* iterate through Contact headers */ |
| 1602 | for(ptr = msg->contact; ptr; ptr = ptr->sibling) { |
| 1603 | /* parse Contact header */ |
| 1604 | if (!ptr->parsed && (parse_contact(ptr) < 0 |
| 1605 | || !ptr->parsed)) { |
| 1606 | strcpy(reason, "failed to parse 'Contact' header"); |
| 1607 | return SV_CONTACT_PARSE_ERROR; |
| 1608 | } |
| 1609 | contacts = ((contact_body_t*)ptr->parsed)->contacts; |
| 1610 | |
| 1611 | if (contacts != NULL) { |
| 1612 | /* iterate through URIs and check validty */ |
| 1613 | for (; contacts; contacts = contacts->next) { |
| 1614 | if(parse_uri(contacts->uri.s, contacts->uri.len, |
| 1615 | &test_contacts) < 0 |
| 1616 | || test_contacts.host.len < 0) { |
| 1617 | strcpy(reason, "failed to parse 'Contact' header"); |
| 1618 | return SV_CONTACT_PARSE_ERROR; |
| 1619 | } |
| 1620 | } |
| 1621 | } else { |
| 1622 | /* This is a star Contact header, valid only for REGISTER requests */ |
| 1623 | if (method == METHOD_REGISTER) { |
| 1624 | if (msg->first_line.type == SIP_REPLY) { |
| 1625 | strcpy(reason, "'Contact' header for REGISTER reply contains '*' only valid for REGISTER request"); |
| 1626 | return SV_BAD_STAR_CONTACT; |
| 1627 | } |
| 1628 | |
| 1629 | if (!msg->expires || (parse_expires(msg->expires) < 0 || !msg->expires->parsed)) { |
| 1630 | strcpy(reason, "failed to parse 'Expires' header"); |
| 1631 | return SV_BAD_STAR_CONTACT; |
| 1632 | } |
| 1633 | |
| 1634 | expires_body = (exp_body_t*) msg->expires->parsed; |
| 1635 | |
| 1636 | if (!expires_body || expires_body->val != 0) { |
| 1637 | strcpy(reason, "'Expires' header greater than 0 for REGISTER 'Contact' header with '*' value"); |
| 1638 | return SV_BAD_STAR_CONTACT; |
| 1639 | } |
| 1640 | } else { |
| 1641 | strcpy(reason, "'Contact' header for SIP message contains '*' only valid for REGISTER request"); |
| 1642 | return SV_BAD_STAR_CONTACT; |
| 1643 | } |
| 1644 | } |
| 1645 | } |
no test coverage detected