pyVoIP
pyVoIP copied to clipboard
Setup code will not run for me. Issue with a key when hashing Auth request.
Not sure where to go from here. Tried to set up as a client of 3CX PBX (Self Hosted). pyVoIP installed from pip. Traceback is from the example quick start setup code. (KeyError: 'realm')?
The instance of VoIPPhone is set up as follows:
phone=VoIPPhone("10.0.50.100", 5060, "4004", "plOP1QNVuV", callCallback=answer, myIP="192.168.200.5")
All other code is copy and paste from readme file.
TODO: Add 500 Error on Receiving SIP Response
Traceback (most recent call last):
File "/home/grant/python/voip/main.py", line 12, in <module>
phone.start()
File "/home/grant/python/voip/venv/lib/python3.10/site-packages/pyVoIP/VoIP.py", line 423, in start
self.sip.start()
File "/home/grant/python/voip/venv/lib/python3.10/site-packages/pyVoIP/SIP.py", line 579, in start
register = self.register()
File "/home/grant/python/voip/venv/lib/python3.10/site-packages/pyVoIP/SIP.py", line 906, in register
regRequest = self.genRegister(response)
File "/home/grant/python/voip/venv/lib/python3.10/site-packages/pyVoIP/SIP.py", line 631, in genRegister
response = self.genAuthorization(request)
File "/home/grant/python/voip/venv/lib/python3.10/site-packages/pyVoIP/SIP.py", line 623, in genAuthorization
HA1 = hashlib.md5(self.username.encode('utf8')+b':'+request.authentication['realm'].encode('utf8')+b':'+self.password.encode('utf8')).hexdigest().encode('utf8')
KeyError: 'realm'
@Cabarnacus Were you able to get resolve the issue? I am currently stuck in the same spot @tayler6000 Any chance we could get your input?
@astrotrupti I'm afraid not. I shelved my VoIP project for just now. I will probably look for an alternative package to this.
@Cabarnacus Thanks! Could you please post here if you figure out how to solve it or if you find another package
@astrotrupti 👍 will do!
Hard to know for sure without a packet capture, but it looks like the PBX may not be following the authentication RFC properly. If I can get a packet capture I can make a patch for this case.
I somehow remember there was an issue with this in current master mostly caused by the fake request to non Asterisk. (I assume you are using Master) Think this was fixed with #10 in v1.6.0-dev branch. You could give it a try
I somehow remember there was an issue with this in current master mostly caused by the fake request to non Asterisk. (I assume you are using Master) Think this was fixed with #10 in v1.6.0-dev branch. You could give it a try
I will try another release this weekend if I get a moment. Thanks. 👍
@tayler6000 Here's a screenshot of the patch. It says it binds but I get the same exact error as @Cabarnacus.
@Input-BDF I tried using v1.6.0-dev. My line doesn't have a password so I enter '' in the password section. I get invalid username and password and it throws "400 Malformed Form, fix your code"
@astrotrupti This may actually be due to the fact that you don't have a password. I'll look into it.
@astrotrupti This may actually be due to the fact that you don't have a password. I'll look into it.
Could also be something with 3CX PBX, with which I personaly have no experience. @astrotrupti if you have a working line without password you could sniff up these packages and compare with pyVoips register requests.
Got my local vanilla Kamailio back working and tested latest 1.6.0-dev with the basic example and passwd='' Worked but (at least in my case) I had to specify myIP. Without I get 403: Not relaying.
@tayler6000 The original problem with the key error came somehow from the fake request in register()
before sending user auth which was replaced with genFirstRequest
/gen_first_response
in 1.6.0 . From there the SIP-server replied without a realm in the response under some conditions.
@Input-BDF Unfortunately I get the same error - Invalid username or Password for SIP server when I do what you did with 1.6.0-dev. Thanks for checking though
@tayler6000 @Input-BDF @Cabarnacus I got it to register successfully and it also says Busy when the callback is set to None. To do that I commented out both "realm" and "nonce" wherever they appeared. However, now, probably but I am not sure due to lack of knowledge, because I got rid of "realm" and "nonce" the algorithm doesn't enter def answer() function from the example or the call goes to unknown and never gets answered. Do you all have any suggestions here?
@astrotrupti do have a password for your phone setup?
@Cabarnacus Can you confirm if this is still an issue in v1.6.2?
I'm starting with this package (v1.6.2), trying to make a call with Yeaster tg100. But I can't register, I always have - Invalid username or Password for SIP server. I tested the device's config with zoiper client and everything works well.
@cfpena Can you please install pyVoIP from master and then add
import pyVoIP
pyVoIP.DEBUG = True
to the beginning of your code? Then reply with the debug output minus the packet that says "(DO NOT SHARE THIS PACKET)"? This will help us to debug the regex to fix the issue for your server.
@tayler6000
==================================================
Unauthorized, SIP Message Log:
SENT
REGISTER sip:192.168.10.210 SIP/2.0
Via: SIP/2.0/UDP 192.168.10.185:5060;branch=z9hG4bK4ccbf433c29e45b4b26853666;rport
From: "20001" <sip:[email protected]>;tag=9d84de77
To: "20001" <sip:[email protected]>
Call-ID: [email protected]:5060
CSeq: 1 REGISTER
Contact: <sip:[email protected]:5060;transport=UDP>;+sip.instance="<urn:uuid:7AB37954-1EC7-4C0D-AB4C-B0DD6C0876F4>"
Allow: INVITE, ACK, BYE, CANCEL
Max-Forwards: 70
Allow-Events: org.3gpp.nwinitdereg
User-Agent: pyVoIP 1.6.2
Expires: 120
Content-Length: 0
RECEIVED
Status: 401 Unauthorized
Headers:
Via: [{'type': 'SIP/2.0/UDP', 'address': ('192.168.10.185', '5060'), 'branch': 'z9hG4bK4ccbf433c29e45b4b26853666', 'received': '192.168.10.185', 'rport': '5060'}]
From: {'raw': '"20001" <sip:[email protected]>', 'tag': '9d84de77', 'address': '[email protected]', 'number': '20001', 'caller': '20001" ', 'host': '192.168.10.210'}
To: {'raw': '"20001" <sip:[email protected]>', 'tag': 'as226f9890', 'address': '[email protected]', 'number': '20001', 'caller': '20001" ', 'host': '192.168.10.210'}
Call-ID: [email protected]:5060
CSeq: {'check': '1', 'method': 'REGISTER'}
Server: TG100
Allow: ['INVITE', 'ACK', 'CANCEL', 'OPTIONS', 'BYE', 'REFER', 'SUBSCRIBE', 'NOTIFY', 'INFO']
Supported: ['replaces', 'timer']
WWW-Authenticate: {'algorithm': 'MD5', 'realm': 'asterisk', 'nonce': '03bbeb46'}
Content-Length: 0
Body:
Raw:
b'SIP/2.0 401 Unauthorized\r\nVia: SIP/2.0/UDP 192.168.10.185:5060;branch=z9hG4bK4ccbf433c29e45b4b26853666;received=192.168.10.185;rport=5060\r\nFrom: "20001" <sip:[email protected]>;tag=9d84de77\r\nTo: "20001" <sip:[email protected]>;tag=as226f9890\r\nCall-ID: [email protected]:5060\r\nCSeq: 1 REGISTER\r\nServer: TG100\r\nAllow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO\r\nSupported: replaces, timer\r\nWWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="03bbeb46"\r\nContent-Length: 0\r\n\r\n'
SENT (DO NOT SHARE THIS PACKET)
*********************
RECEIVED
Status: 401 Unauthorized
Headers:
Via: [{'type': 'SIP/2.0/UDP', 'address': ('192.168.10.185', '5060'), 'branch': 'z9hG4bKeddd669af1c44200aded2be25', 'received': '192.168.10.185', 'rport': '5060'}]
From: {'raw': '"20001" <sip:[email protected]>', 'tag': '9d84de77', 'address': '[email protected]', 'number': '20001', 'caller': '20001" ', 'host': '192.168.10.210'}
To: {'raw': '"20001" <sip:[email protected]>', 'tag': 'as00b6278f', 'address': '[email protected]', 'number': '20001', 'caller': '20001" ', 'host': '192.168.10.210'}
Call-ID: [email protected]:5060
CSeq: {'check': '2', 'method': 'REGISTER'}
Server: TG100
Allow: ['INVITE', 'ACK', 'CANCEL', 'OPTIONS', 'BYE', 'REFER', 'SUBSCRIBE', 'NOTIFY', 'INFO']
Supported: ['replaces', 'timer']
WWW-Authenticate: {'algorithm': 'MD5', 'realm': 'asterisk', 'nonce': '4256fa21'}
Content-Length: 0
Body:
Raw:
b'SIP/2.0 401 Unauthorized\r\nVia: SIP/2.0/UDP 192.168.10.185:5060;branch=z9hG4bKeddd669af1c44200aded2be25;received=192.168.10.185;rport=5060\r\nFrom: "20001" <sip:[email protected]>;tag=9d84de77\r\nTo: "20001" <sip:[email protected]>;tag=as00b6278f\r\nCall-ID: [email protected]:5060\r\nCSeq: 2 REGISTER\r\nServer: TG100\r\nAllow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO\r\nSupported: replaces, timer\r\nWWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="4256fa21"\r\nContent-Length: 0\r\n\r\n'
==================================================
Traceback (most recent call last):
File "/Users/cfpena/projects/test/pyVoIP/main.py", line 84, in <module>
phone.start()
File "/Users/cfpena/projects/test/pyVoIP/pyVoIP/VoIP.py", line 656, in start
self.sip.start()
File "/Users/cfpena/projects/test/pyVoIP/pyVoIP/SIP.py", line 949, in start
self.register()
File "/Users/cfpena/projects/test/pyVoIP/pyVoIP/SIP.py", line 1743, in register
raise InvalidAccountInfoError(
pyVoIP.SIP.InvalidAccountInfoError: Invalid Username or Password for SIP server 192.168.10.210:5060
I really appreciate your help. Thanks in advance
@tayler6000
================================================== Unauthorized, SIP Message Log: SENT REGISTER sip:192.168.10.210 SIP/2.0 Via: SIP/2.0/UDP 192.168.10.185:5060;branch=z9hG4bK4ccbf433c29e45b4b26853666;rport From: "20001" <sip:[email protected]>;tag=9d84de77 To: "20001" <sip:[email protected]> Call-ID: [email protected]:5060 CSeq: 1 REGISTER Contact: <sip:[email protected]:5060;transport=UDP>;+sip.instance="<urn:uuid:7AB37954-1EC7-4C0D-AB4C-B0DD6C0876F4>" Allow: INVITE, ACK, BYE, CANCEL Max-Forwards: 70 Allow-Events: org.3gpp.nwinitdereg User-Agent: pyVoIP 1.6.2 Expires: 120 Content-Length: 0 RECEIVED Status: 401 Unauthorized Headers: Via: [{'type': 'SIP/2.0/UDP', 'address': ('192.168.10.185', '5060'), 'branch': 'z9hG4bK4ccbf433c29e45b4b26853666', 'received': '192.168.10.185', 'rport': '5060'}] From: {'raw': '"20001" <sip:[email protected]>', 'tag': '9d84de77', 'address': '[email protected]', 'number': '20001', 'caller': '20001" ', 'host': '192.168.10.210'} To: {'raw': '"20001" <sip:[email protected]>', 'tag': 'as226f9890', 'address': '[email protected]', 'number': '20001', 'caller': '20001" ', 'host': '192.168.10.210'} Call-ID: [email protected]:5060 CSeq: {'check': '1', 'method': 'REGISTER'} Server: TG100 Allow: ['INVITE', 'ACK', 'CANCEL', 'OPTIONS', 'BYE', 'REFER', 'SUBSCRIBE', 'NOTIFY', 'INFO'] Supported: ['replaces', 'timer'] WWW-Authenticate: {'algorithm': 'MD5', 'realm': 'asterisk', 'nonce': '03bbeb46'} Content-Length: 0 Body: Raw: b'SIP/2.0 401 Unauthorized\r\nVia: SIP/2.0/UDP 192.168.10.185:5060;branch=z9hG4bK4ccbf433c29e45b4b26853666;received=192.168.10.185;rport=5060\r\nFrom: "20001" <sip:[email protected]>;tag=9d84de77\r\nTo: "20001" <sip:[email protected]>;tag=as226f9890\r\nCall-ID: [email protected]:5060\r\nCSeq: 1 REGISTER\r\nServer: TG100\r\nAllow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO\r\nSupported: replaces, timer\r\nWWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="03bbeb46"\r\nContent-Length: 0\r\n\r\n' SENT (DO NOT SHARE THIS PACKET) ********************* RECEIVED Status: 401 Unauthorized Headers: Via: [{'type': 'SIP/2.0/UDP', 'address': ('192.168.10.185', '5060'), 'branch': 'z9hG4bKeddd669af1c44200aded2be25', 'received': '192.168.10.185', 'rport': '5060'}] From: {'raw': '"20001" <sip:[email protected]>', 'tag': '9d84de77', 'address': '[email protected]', 'number': '20001', 'caller': '20001" ', 'host': '192.168.10.210'} To: {'raw': '"20001" <sip:[email protected]>', 'tag': 'as00b6278f', 'address': '[email protected]', 'number': '20001', 'caller': '20001" ', 'host': '192.168.10.210'} Call-ID: [email protected]:5060 CSeq: {'check': '2', 'method': 'REGISTER'} Server: TG100 Allow: ['INVITE', 'ACK', 'CANCEL', 'OPTIONS', 'BYE', 'REFER', 'SUBSCRIBE', 'NOTIFY', 'INFO'] Supported: ['replaces', 'timer'] WWW-Authenticate: {'algorithm': 'MD5', 'realm': 'asterisk', 'nonce': '4256fa21'} Content-Length: 0 Body: Raw: b'SIP/2.0 401 Unauthorized\r\nVia: SIP/2.0/UDP 192.168.10.185:5060;branch=z9hG4bKeddd669af1c44200aded2be25;received=192.168.10.185;rport=5060\r\nFrom: "20001" <sip:[email protected]>;tag=9d84de77\r\nTo: "20001" <sip:[email protected]>;tag=as00b6278f\r\nCall-ID: [email protected]:5060\r\nCSeq: 2 REGISTER\r\nServer: TG100\r\nAllow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO\r\nSupported: replaces, timer\r\nWWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="4256fa21"\r\nContent-Length: 0\r\n\r\n' ================================================== Traceback (most recent call last): File "/Users/cfpena/projects/test/pyVoIP/main.py", line 84, in <module> phone.start() File "/Users/cfpena/projects/test/pyVoIP/pyVoIP/VoIP.py", line 656, in start self.sip.start() File "/Users/cfpena/projects/test/pyVoIP/pyVoIP/SIP.py", line 949, in start self.register() File "/Users/cfpena/projects/test/pyVoIP/pyVoIP/SIP.py", line 1743, in register raise InvalidAccountInfoError( pyVoIP.SIP.InvalidAccountInfoError: Invalid Username or Password for SIP server 192.168.10.210:5060
I really appreciate your help. Thanks in advance
To be honest, I see nothing wrong with this... Does anyone else see an issue here?
@tayler6000
I was trying to check the problem with debugging and wireshark but couldn't find anything. But when I changed to pip version 1.5.6, everything worked fine.
For version 1.5.6 to work I had to disable the 'qualify' option. The reason is that the "option" method is not allowed. But in the current master branch and pip version 1.6 I couldn't find the problem.
@tayler6000
I was trying to check the problem with debugging and wireshark but couldn't find anything. But when I changed to pip version 1.5.6, everything worked fine.
For version 1.5.6 to work I had to disable the 'qualify' option. The reason is that the "option" method is not allowed. But in the current master branch and pip version 1.6 I couldn't find the problem.
This is very strange. If you're comfortable, could you send another debug log like you did before and the password you use for the sip account? My email is [email protected] this is really the only thing I can think of to debug this further.
@tayler6000 I was trying to check the problem with debugging and wireshark but couldn't find anything. But when I changed to pip version 1.5.6, everything worked fine. For version 1.5.6 to work I had to disable the 'qualify' option. The reason is that the "option" method is not allowed. But in the current master branch and pip version 1.6 I couldn't find the problem.
This is very strange. If you're comfortable, could you send another debug log like you did before and the password you use for the sip account? My email is [email protected] this is really the only thing I can think of to debug this further.
I've already made a separate script to compare the MD5 hash response and it's exactly the same. I will send you an email tomorrow with the requested information and some more data.
@cfpena Can you please install pyVoIP from master and then add
import pyVoIP pyVoIP.DEBUG = True
to the beginning of your code? Then reply with the debug output minus the packet that says "(DO NOT SHARE THIS PACKET)"? This will help us to debug the regex to fix the issue for your server.
As requested see below. There was no section titled "(DO NOT SHARE THIS PACKET)"?
I have tested this configuration out with a softphone (Grandstream wave) and it works fine. One thing to note is that GS Wave gives the options of the "SIP User ID" which is typically the extension number, and a "SIP Authentication ID" which is a randomly generated username (3CX endorse this for security reasons). Both have to be provided for registration to work.
For the purposes of this test I have configured the Authentication ID to the same as the User ID (server side). I have done this as the class VoIPPhone takes the argument "username". I am unsure if this is meant to be the extension (user id) or the authentication ID.
I have not used Asterisk based SIP servers before but i'm sure I read somewhere that there no distinction between a User ID and and Authentication ID. Maybe since the intended use of pyVoIP is to be paired with Asterisk then it is not compatible with 3CX at this time.
Proxy auth required
Status: 407 Proxy Authentication Required
Headers:
Via: [{'type': 'SIP/2.0/UDP', 'address': ('192.168.1.115', '5060'), 'branch': 'z9hG4bKa204b49c872e4536ad20ab0fe', 'rport': '5060'}]
Proxy-Authenticate: Digest nonce="414d53596337438754:e4245f22523b9adb224fe90d7c52e239",algorithm=MD5,realm="3CXPhoneSystem"
To: {'raw': '"4004"<sip:[email protected]>', 'tag': 'c61b1d0b', 'address': '[email protected]', 'number': '4004', 'caller': '4004', 'host': '10.0.50.100'}
From: {'raw': '"4004" <sip:[email protected]>', 'tag': 'a07c805b', 'address': '[email protected]', 'number': '4004', 'caller': '4004" ', 'host': '10.0.50.100'}
Call-ID: [email protected]:5060
CSeq: {'check': '1', 'method': 'REGISTER'}
Content-Length: 0
Body:
Raw:
b'SIP/2.0 407 Proxy Authentication Required\r\nVia: SIP/2.0/UDP 192.168.1.115:5060;branch=z9hG4bKa204b49c872e4536ad20ab0fe;rport=5060\r\nProxy-Authenticate: Digest nonce="414d53596337438754:e4245f22523b9adb224fe90d7c52e239",algorithm=MD5,realm="3CXPhoneSystem"\r\nTo: "4004"<sip:[email protected]>;tag=c61b1d0b\r\nFrom: "4004" <sip:[email protected]>;tag=a07c805b\r\nCall-ID: [email protected]:5060\r\nCSeq: 1 REGISTER\r\nContent-Length: 0\r\n\r\n'
b'SIP/2.0 407 Proxy Authentication Required\r\nVia: SIP/2.0/UDP 192.168.1.115:5060;branch=z9hG4bKa204b49c872e4536ad20ab0fe;rport=5060\r\nProxy-Authenticate: Digest nonce="414d53596337438754:e4245f22523b9adb224fe90d7c52e239",algorithm=MD5,realm="3CXPhoneSystem"\r\nTo: "4004"<sip:[email protected]>;tag=c61b1d0b\r\nFrom: "4004" <sip:[email protected]>;tag=a07c805b\r\nCall-ID: [email protected]:5060\r\nCSeq: 1 REGISTER\r\nContent-Length: 0\r\n\r\n'
Traceback (most recent call last):
File "/home/grant/python/voip/main.py", line 17, in <module>
phone.start()
File "/home/grant/python/voip/venv/lib/python3.10/site-packages/pyVoIP/VoIP.py", line 656, in start
self.sip.start()
File "/home/grant/python/voip/venv/lib/python3.10/site-packages/pyVoIP/SIP.py", line 949, in start
self.register()
File "/home/grant/python/voip/venv/lib/python3.10/site-packages/pyVoIP/SIP.py", line 1794, in register
raise InvalidAccountInfoError(
pyVoIP.SIP.InvalidAccountInfoError: Invalid Username or Password for SIP server 10.0.50.100:5060
@Cabarnacus You would have needed to install from source to get that extra level of debug, however this explains the issue. PyVoIP does not currently support proxies. Reference #69