tayler6000 / pyVoIP

Pure python VoIP/SIP/RTP library. Currently supports PCMA, PCMU, and telephone-event
https://pypi.org/project/pyVoIP/
GNU General Public License v3.0
235 stars 109 forks source link

2.0.0a5 - Unable to answer SIP calls over TLS #280

Open YutangShi opened 1 month ago

YutangShi commented 1 month ago

I try to use SIP over TLS to register my PBX (TLS is required). The 2.0.0a5 version seems not work for me.

import ssl
from pyVoIP.credentials import CredentialsManager
from pyVoIP.VoIP.call import VoIPCall, CallState
from pyVoIP.VoIP.error import InvalidStateError
from pyVoIP.VoIP.phone import VoIPPhone, VoIPPhoneParameter
from pyVoIP.networking.transport import TransportMode
from pyVoIP.VoIP.status import PhoneStatus

import pyVoIP
pyVoIP.set_tls_security(ssl.CERT_NONE)
pyVoIP.DEBUG = True

import pyaudio

CHUNK = 160
FORMAT = pyaudio.paUInt8
CHANNELS = 1
RATE = 8000
p = pyaudio.PyAudio()
stream = p.open(format = FORMAT, channels = CHANNELS, rate = RATE,  input = True, output=True, frames_per_buffer = CHUNK)

class Call(VoIPCall):
    def ringing(self, invite_request):
        try:
            print('ringing')
            return self.answer()
        except InvalidStateError:
            pass

    def answered(self, request):
        try:
            print("Call answered")
            super().answered(request)
            while self.state == CallState.ANSWERED:
                audio_from_caller = super().read_audio()
                stream.write(audio_from_caller)
        except InvalidStateError as error:
            pass
        except Exception as error:
            print(f"Exception:{error}")
            self.hangup()

    def rejected(self, request):
        print("Call rejected")

    def hangup(self, request):
        print("Call ended")
        super().hangup()

if __name__ == "__main__":
    try:
        serverIP = "x.x.x.x"
        serverPort = 5068
        username = "xxxx"
        password = "xxxx"

        cm = CredentialsManager()
        cm.add(username, password)

        params = VoIPPhoneParameter(
            serverIP,
            serverPort,
            username,
            cm,
            call_class=Call,
            transport_mode=TransportMode.TLS
        )
        phone = VoIPPhone(params)

        phone.start()
        status = phone.get_status()
        print(f"Phone status: {status}")
        # phone.call("8121")

        input('Press enter to disable the phone')
        phone.stop()
    except Exception as e:
        print(f"error: {e}")

Register log

Although the phone status shows PhoneStatus.REGISTERED, I still can't receive the invite message from Wireshark or the debug log.

SENT:
REGISTER sip:220.130.164.1:5068 SIP/2.0

Headers:
Via: [{'type': 'SIP/2.0/TLS', 'address': ('0.0.0.0', 5060), 'branch': 'z9hG4bKeab01e2c94514657a77bece35'}]
From: {'raw': '<sips:8121@220.130.164.1:5068>;tag=4ef05147', 'tag': '4ef05147', 'uri': 'sips:8121@220.130.164.1:5068', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '220.130.164.1', 'port': 5068}
To: {'raw': '<sips:8121@220.130.164.1:5068>', 'tag': '', 'uri': 'sips:8121@220.130.164.1:5068', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '220.130.164.1', 'port': 5068}
Call-ID: 6b86b273ff34fce19d6b804eff5a3f57@0.0.0.0:5060
CSeq: {'check': 1, 'method': 'REGISTER'}
Contact: {'raw': '<sips:8121@0.0.0.0;transport=TLS>;+sip.instance="<urn:uuid:5949B2E0-4CAA-4CCC-8D39-74C072A00059>"', 'tag': '', 'uri': 'sips:8121@0.0.0.0', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '0.0.0.0', 'port': 5060}
Allow: ['INVITE', 'ACK', 'BYE', 'CANCEL', 'OPTIONS', 'NOTIFY', 'REGISTER', 'MESSAGE', 'SUBSCRIBE', 'REFER']
Max-Forwards: 70
Allow-Events: org.3gpp.nwinitdereg
User-Agent: pyVoIP 2.0.0a5
Expires: 120
Content-Length: 0

Body:
content: None

Raw:
b'REGISTER sip:220.130.164.1:5068 SIP/2.0\r\nVia: SIP/2.0/TLS 0.0.0.0:5060;branch=z9hG4bKeab01e2c94514657a77bece35\r\nFrom: <sips:8121@220.130.164.1:5068>;tag=4ef05147\r\nTo: <sips:8121@220.130.164.1:5068>\r\nCall-ID: 6b86b273ff34fce19d6b804eff5a3f57@0.0.0.0:5060\r\nCSeq: 1 REGISTER\r\nContact: <sips:8121@0.0.0.0;transport=TLS>;+sip.instance="<urn:uuid:5949B2E0-4CAA-4CCC-8D39-74C072A00059>"\r\nAllow: INVITE, ACK, BYE, CANCEL, OPTIONS, NOTIFY, REGISTER, MESSAGE, SUBSCRIBE, REFER\r\nMax-Forwards: 70\r\nAllow-Events: org.3gpp.nwinitdereg\r\nUser-Agent: pyVoIP 2.0.0a5\r\nExpires: 120\r\nContent-Length: 0\r\n\r\n'
RECEIVED:
SIP/2.0 401 Unauthorized

Headers:
Via: [{'type': 'SIP/2.0/TLS', 'address': ('0.0.0.0', 5060), 'rport': 64168, 'received': '36.228.154.39', 'branch': 'z9hG4bKeab01e2c94514657a77bece35'}]
Call-ID: 6b86b273ff34fce19d6b804eff5a3f57@0.0.0.0:5060
From: {'raw': '<sips:8121@220.130.164.1>;tag=4ef05147', 'tag': '4ef05147', 'uri': 'sips:8121@220.130.164.1', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '220.130.164.1', 'port': 5060}
To: {'raw': '<sips:8121@220.130.164.1>;tag=z9hG4bKeab01e2c94514657a77bece35', 'tag': 'z9hG4bKeab01e2c94514657a77bece35', 'uri': 'sips:8121@220.130.164.1', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '220.130.164.1', 'port': 5060}
CSeq: {'check': 1, 'method': 'REGISTER'}
WWW-Authenticate: {'header': 'WWW-Authenticate', 'method': 'Digest', 'realm': 'Acer_UC', 'nonce': '1727873144/5a31dcf95a560decf71e8d55349cd6d7', 'opaque': '6a7a4b1f2276c1ee', 'algorithm': 'md5', 'qop': ['auth']}
Server: Acer UC v3.08.2002
Content-Length: 0

Body:
content: None

Raw:
b'SIP/2.0 401 Unauthorized\r\nVia: SIP/2.0/TLS 0.0.0.0:5060;rport=64168;received=36.228.154.39;branch=z9hG4bKeab01e2c94514657a77bece35\r\nCall-ID: 6b86b273ff34fce19d6b804eff5a3f57@0.0.0.0:5060\r\nFrom: <sips:8121@220.130.164.1>;tag=4ef05147\r\nTo: <sips:8121@220.130.164.1>;tag=z9hG4bKeab01e2c94514657a77bece35\r\nCSeq: 1 REGISTER\r\nWWW-Authenticate: Digest realm="Acer_UC",nonce="1727873144/5a31dcf95a560decf71e8d55349cd6d7",opaque="6a7a4b1f2276c1ee",algorithm=md5,qop="auth"\r\nServer: Acer UC v3.08.2002\r\nContent-Length:  0\r\n\r\n'
SENT:
REGISTER sip:220.130.164.1:5068 SIP/2.0

Headers:
Via: [{'type': 'SIP/2.0/TLS', 'address': ('0.0.0.0', 5060), 'branch': 'z9hG4bK89016a7566824a8fac524dc22'}]
From: {'raw': '<sips:8121@220.130.164.1:5068>;tag=4ef05147', 'tag': '4ef05147', 'uri': 'sips:8121@220.130.164.1:5068', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '220.130.164.1', 'port': 5068}
To: {'raw': '<sips:8121@220.130.164.1:5068>', 'tag': '', 'uri': 'sips:8121@220.130.164.1:5068', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '220.130.164.1', 'port': 5068}
Call-ID: 6b86b273ff34fce19d6b804eff5a3f57@0.0.0.0:5060
CSeq: {'check': 2, 'method': 'REGISTER'}
Contact: {'raw': '<sips:8121@0.0.0.0;transport=TLS>;+sip.instance="<urn:uuid:5949B2E0-4CAA-4CCC-8D39-74C072A00059>"', 'tag': '', 'uri': 'sips:8121@0.0.0.0', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '0.0.0.0', 'port': 5060}
Allow: ['INVITE', 'ACK', 'BYE', 'CANCEL', 'OPTIONS', 'NOTIFY', 'REGISTER', 'MESSAGE', 'SUBSCRIBE', 'REFER']
Max-Forwards: 70
Allow-Events: org.3gpp.nwinitdereg
User-Agent: pyVoIP 2.0.0a5
Expires: 120
Authorization: {'header': 'Authorization', 'method': 'Digest', 'username': '8121', 'realm': 'Acer_UC', 'nonce': '1727873144/5a31dcf95a560decf71e8d55349cd6d7', 'uri': 'sip:220.130.164.1;transport=TLS', 'response': 'b557955364ab56f5d383329a3e30ea22', 'algorithm': 'md5', 'qop': ['auth'], 'cnonce': '020f66e4734643ed8d86205885bff870', 'nc': '00000001', 'userhash': False, 'opaque': '6a7a4b1f2276c1ee'}
Content-Length: 0

Body:
content: None

Raw:
b'REGISTER sip:220.130.164.1:5068 SIP/2.0\r\nVia: SIP/2.0/TLS 0.0.0.0:5060;branch=z9hG4bK89016a7566824a8fac524dc22\r\nFrom: <sips:8121@220.130.164.1:5068>;tag=4ef05147\r\nTo: <sips:8121@220.130.164.1:5068>\r\nCall-ID: 6b86b273ff34fce19d6b804eff5a3f57@0.0.0.0:5060\r\nCSeq: 2 REGISTER\r\nContact: <sips:8121@0.0.0.0;transport=TLS>;+sip.instance="<urn:uuid:5949B2E0-4CAA-4CCC-8D39-74C072A00059>"\r\nAllow: INVITE, ACK, BYE, CANCEL, OPTIONS, NOTIFY, REGISTER, MESSAGE, SUBSCRIBE, REFER\r\nMax-Forwards: 70\r\nAllow-Events: org.3gpp.nwinitdereg\r\nUser-Agent: pyVoIP 2.0.0a5\r\nExpires: 120\r\nAuthorization: Digest username="8121",realm="Acer_UC",nonce="1727873144/5a31dcf95a560decf71e8d55349cd6d7",uri="sip:220.130.164.1;transport=TLS",response="b557955364ab56f5d383329a3e30ea22",algorithm=md5,qop=auth,cnonce="020f66e4734643ed8d86205885bff870",nc=00000001,userhash=false,opaque="6a7a4b1f2276c1ee"\r\nContent-Length: 0\r\n\r\n'
RECEIVED:
SIP/2.0 200 OK

Headers:
Via: [{'type': 'SIP/2.0/TLS', 'address': ('0.0.0.0', 5060), 'rport': 64169, 'received': '36.228.154.39', 'branch': 'z9hG4bK89016a7566824a8fac524dc22'}]
Call-ID: 6b86b273ff34fce19d6b804eff5a3f57@0.0.0.0:5060
From: {'raw': '<sips:8121@220.130.164.1>;tag=4ef05147', 'tag': '4ef05147', 'uri': 'sips:8121@220.130.164.1', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '220.130.164.1', 'port': 5060}
To: {'raw': '<sips:8121@220.130.164.1>;tag=z9hG4bK89016a7566824a8fac524dc22', 'tag': 'z9hG4bK89016a7566824a8fac524dc22', 'uri': 'sips:8121@220.130.164.1', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '220.130.164.1', 'port': 5060}
CSeq: {'check': 2, 'method': 'REGISTER'}
Date: Wed, 02 Oct 2024 12:45:44 GMT
Contact: {'raw': '<sips:8121@0.0.0.0;transport=TLS>;expires=119', 'tag': '', 'uri': 'sips:8121@0.0.0.0', 'uri-type': 'sips', 'user': '8121', 'password': '', 'display-name': '', 'host': '0.0.0.0', 'port': 5060}
Expires: 120
Server: Acer UC v3.08.2002
Content-Length: 0

Body:
content: None

Raw:
b'SIP/2.0 200 OK\r\nVia: SIP/2.0/TLS 0.0.0.0:5060;rport=64169;received=36.228.154.39;branch=z9hG4bK89016a7566824a8fac524dc22\r\nCall-ID: 6b86b273ff34fce19d6b804eff5a3f57@0.0.0.0:5060\r\nFrom: <sips:8121@220.130.164.1>;tag=4ef05147\r\nTo: <sips:8121@220.130.164.1>;tag=z9hG4bK89016a7566824a8fac524dc22\r\nCSeq: 2 REGISTER\r\nDate: Wed, 02 Oct 2024 12:45:44 GMT\r\nContact: <sips:8121@0.0.0.0;transport=TLS>;expires=119\r\nExpires: 120\r\nServer: Acer UC v3.08.2002\r\nContent-Length:  0\r\n\r\n'
New register thread
Phone status: PhoneStatus.REGISTERED
Press enter to disable the phone

I didn't know why SIP client trigger RST package to PBX.

SCR-20241002-t2o

Other tools

pjsua cli or MicroSIP register over TLS is work