def _make_bad_extension(sip_message, validation_options, unsupported): try: SipMessage.parse( sip_message, [TO_HEADER, FROM_HEADER, CALLID_HEADER, CSEQ_HEADER]) to_tag = AUTO if validation_options.validate.to_tag is not None: to_tag = validation_options.validate.to_tag reply_opts = ReplyOptions(420, to_tag=to_tag) response = sip_message.reply(reply_opts) response.set(UNSUPPORTED_HEADER, unsupported) return response except Exception as e: raise e
def _make_reply(sip_msg, validation_options, code): try: sip_msg = SipMessage.parse( sip_msg, [TO_HEADER, FROM_HEADER, CALLID_HEADER, CSEQ_HEADER]) except SIPMessageParseError as e: raise e to_tag = AUTO if validation_options.validate.to_tag is not None: to_tag = validation_options.validate.to_tag reply_opts = ReplyOptions(status=code, reason=None, to_tag=to_tag) return sip_msg.reply(reply_opts)
def _validate_reasonable_syntax(raw_message, validation_options): try: return SipMessage.parse(raw_message, [ MAXFORWARDS_HEADER, PROXY_REQUIRE_HEADER, RECORD_ROUTE_HEADER, ROUTE_HEADER ]) except (SIPMessageParseError, SipHeaderError) as e: try: return CommonProxy._make_bad_request(raw_message, validation_options, e) except Exception as e: raise e
def process_response(previous_via, raw_message): try: sip_msg = SipMessage.parse(raw_message, []) if previous_via.branch is not None: if StatelessProxy.check_via_branch(previous_via.branch): topmostvia = sip_msg.topmost_via if isinstance(topmostvia, NotFound): return ProcessResponseDrop(reason=NO_MORE_VIA) return ProcessResponseForward(sip_msg=sip_msg) return ProcessResponseDrop(reason=VIA_NOT_MATCH) return ProcessResponseDrop(reason=VIA_NO_BRANCH) except Exception as e: raise StatelessProxyError(f'Cannot parse message: {e}')
def _make_bad_request(raw_message, validation_options, error): try: sip_msg = SipMessage.parse( raw_message, [TO_HEADER, FROM_HEADER, CALLID_HEADER, CSEQ_HEADER]) except SIPMessageParseError as e: raise e reason = bad_request_reason(error) to_tag = AUTO if validation_options.validate.to_tag is not None: to_tag = validation_options.validate.to_tag reply_options = ReplyOptions(status=400, reason=reason, to_tag=to_tag) return sip_msg.reply(reply_options)
def test_forward_request_invalid_maxforwars(): bob_uri = 'sip:[email protected]' msg = 'INVITE ' + bob_uri + ' SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: x' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' sip_msg = SipMessage.parse(raw_message(msg), []) with pytest.raises(SipHeaderError) as exc: CommonProxy.forward_request(Uri(bob_uri), sip_msg, ProxyOptionsDetails()) assert 'max-forwards' in str(exc.value).lower()
def test_request_validation_proxy_require(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nProxy-Require: gin' + \ '\r\n\r\n' unsupported = OptTagListHeader.from_list([OptionTag('gin')]) response = CommonProxy.validate_request(raw_message(msg), ValidationOptions()) assert response.status == 420 assert response.reason.lower() == 'bad extension' resp_raw_message = raw_message(response.serialize()) sip_response = SipMessage.parse(resp_raw_message, [UNSUPPORTED_HEADER]) assert sip_response.get(UNSUPPORTED_HEADER) == unsupported
def test_request_validation_maxforwards_is_zero_options_reply(): msg = 'OPTIONS sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 0' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 OPTIONS' + \ '\r\n\r\n' allow_methods = AllowHeader(MethodSet([INVITE, ACK, OPTIONS, CANCEL, BYE])) supported_list = OptTagListHeader.from_list([OptionTag('100rel'), OptionTag('timers')]) options = ValidationOptions(validate=ValidationOptionsDetails(reply_on_options=True), proxy=ProxyOptionsDetails(supported=supported_list, allow=allow_methods)) response = CommonProxy.validate_request(raw_message(msg), options) assert response.status == 200 assert response.reason == 'OK' resp_raw_message = raw_message(response.serialize()) sip_response = SipMessage.parse(resp_raw_message, [ALLOW_HEADER, SUPPORTED_HEADER]) assert allow_methods == sip_response.get(ALLOW_HEADER) assert sip_response.get(SUPPORTED_HEADER) == supported_list
def stateless_branch(string): return StatelessProxy.branch(SipMessage.parse(string, ALL))
def rebuild_sip_msg(sip_msg): sip_msg_str = sip_msg.serialize() p = Parser.new_dgram(sip_msg_str) msg, rest = Parser.parse(p) return SipMessage.parse(msg, ALL)