drachtio-server
drachtio-server copied to clipboard
Authorization header is removed from outgoing request
Hello! First, thank you guys for your super work 🚀
I was trying to register to a SIP trunk using drachtio (drachtio-server:latest, drachtio-srf: "4.5.17") with the following code:
const req = await this.srf.request(
`sip:${sipTrunk.realm}:5060`, {
method: 'REGISTER',
headers: {
'From': `sip:${this.publicIp}`,
'To': `sip:${sipTrunk.username}@${sipTrunk.realm}`,
'Contact': `<sip:${contactAddress}>;expires=180`,
'Expires': 180
},
auth: {
username: sipTrunk.username,
password: sipTrunk.password
}
});
When I run the code:
- drachtio client sends the request to drachtio server
- drachtio server sends the
REGISTER
request to my trunk - my trunk replies 401 and provides the challenge
- drachtio client sends the request again with the computed ´Authorization´ header.
- drachtio server sends the SIP request without the ´Authorization´ header. (double checked with Wireshark)
From the attached logs, it seems that drachtio-server
correctly receives the Authorization
header computed from the client but it's not appended in the sent message.
-- redacted: first register is sent --
drachtio:agent received sip response +0ms
drachtio:agent Agent#handle: got a response with status: 401 +0ms
drachtio:agent options: {"method":"REGISTER","headers":{"From":"<sip:192.168.1.1>;tag=F5DXvrDD68pyp","To":"sip:[email protected]","Contact":"<sip:sip:sip-username:192.168.1.1>;expires=180","Expires":180,"CSeq":"57290971 REGISTER","call-id":"f2ed4ba3-b39f-123b-2faa-0242ac270006","Authorization":"Digest username=\"sip-username\",realm=\"voip.provider.com\",nonce=\"6329e372ddc7a37f6c08c920d7984d6bb1902198\",uri=\"sip:voip.provider.com:5060\",response=\"fcee8283b3----REDACTED----c2d5ebe5bb\",algorithm=MD5,qop=auth,nc=00000001,cnonce=\"a829da65\""},"auth":{"username":"sip-username","password":"password"},"uri":"sip:voip.provider.com:5060","proxy":"sip:<provider-ip>:5060"} +1ms
drachtio:agent wp#send 172.39.0.6:9022 - 597#2f659bbc-4719-4c91-8cc4-b2d663ec51ca|sip|||sip:<provider-ip>:5060
drachtio:agent REGISTER sip:voip.provider.com:5060 SIP/2.0
drachtio:agent From: <sip:192.168.1.1>;tag=F5DXvrDD68pyp
drachtio:agent To: sip:[email protected]
drachtio:agent Contact: <sip:sip:sip-username:192.168.1.1>;expires=180
drachtio:agent Expires: 180
drachtio:agent CSeq: 57290971 REGISTER
drachtio:agent Call-ID: f2ed4ba3-b39f-123b-2faa-0242ac270006
drachtio:agent Authorization: Digest username="sip-username",realm="voip.provider.com",nonce="6329e372ddc7a37f6c08c920d7984d6bb1902198",uri="sip:voip.provider.com:5060",response="fcee8283b3----REDACTED----c2d5ebe5bb",algorithm=MD5,qop=auth,nc=00000001,cnonce="a829da65"
drachtio:agent Content-Length: 0
drachtio:agent
drachtio:agent +1ms
drachtio:agent <===485#d2d4582a-5fe6-47d0-a34e-0f592a8abb9d|response|2f659bbc-4719-4c91-8cc4-b2d663ec51ca|OK|application|298|udp|172.39.0.6|5060|15:58:45.920870|72b60e87-9e18-4094-88ae-750310f37853|Msg sent:|
drachtio:agent REGISTER sip:voip.provider.com:5060 SIP/2.0
drachtio:agent Via: SIP/2.0/UDP 172.39.0.6;rport;branch=z9hG4bK2Dm9XeapH3BBK
drachtio:agent Max-Forwards: 70
drachtio:agent From: <sip:192.168.1.1>;tag=F5DXvrDD68pyp
drachtio:agent To: <sip:[email protected]>
drachtio:agent Call-ID: f2f69174-b39f-123b-2faa-0242ac270006
drachtio:agent CSeq: 57290970 REGISTER
drachtio:agent Content-Length: 0
drachtio:agent
drachtio-server | 2022-09-20 15:58:45.915747 tport.c:1170 tport_unref() tport_unref(0x55b541926500): refcount is now 51
drachtio-server | 2022-09-20 15:58:45.916149 Client::write_handler - wrote 607 bytes: system:0
drachtio-server | 2022-09-20 15:58:45.917825 Client::read_handler read: 2f659bbc-4719-4c91-8cc4-b2d663ec51ca|sip|||sip:<provider-ip>:5060
drachtio-server | REGISTER sip:voip.provider.com:5060 SIP/2.0
drachtio-server | From: <sip:192.168.1.1>;tag=F5DXvrDD68pyp
drachtio-server | To: sip:[email protected]
drachtio-server | Contact: <sip:sip:sip-username:192.168.1.1>;expires=180
drachtio-server | Expires: 180
drachtio-server | CSeq: 57290971 REGISTER
drachtio-server | Call-ID: f2ed4ba3-b39f-123b-2faa-0242ac270006
drachtio-server | Authorization: Digest username="sip-username",realm="voip.provider.com",nonce="6329e372ddc7a37f6c08c920d7984d6bb1902198",uri="sip:voip.provider.com:5060",response="fcee8283b3----REDACTED----c2d5ebe5bb",algorithm=MD5,qop=auth,nc=00000001,cnonce="a829da65"
drachtio-server | Content-Length: 0
drachtio-server |
drachtio-server |
drachtio-server | 2022-09-20 15:58:45.917901 Client::processMessage - got request with 5 tokens
drachtio-server | 2022-09-20 15:58:45.917919 Client::processMessage - request id 2f659bbc-4719-4c91-8cc4-b2d663ec51ca, request type: sip transaction id: , dialog id:
drachtio-server | 2022-09-20 15:58:45.917942 Client::processMessage - sending a request outside of a dialog
drachtio-server | 2022-09-20 15:58:45.917961 ClientController::addAppTransaction: transactionId 72b60e87-9e18-4094-88ae-750310f37853; size: 1
drachtio-server | 2022-09-20 15:58:45.917971 ClientController::addApiRequest: clientMsgId 2f659bbc-4719-4c91-8cc4-b2d663ec51ca; size: 1
drachtio-server | 2022-09-20 15:58:45.918132 SipDialogController::doSendRequestOutsideDialog sending request to route url: sip:<provider-ip>:5060
drachtio-server | 2022-09-20 15:58:45.918957 SipTransport::findAppropriateTransport: searching for a transport to reach udp/sip:<provider-ip>:5060
drachtio-server | 2022-09-20 15:58:45.919018 SipTransport::findAppropriateTransport - after filtering for transport we have 2 candidates
drachtio-server | 2022-09-20 15:58:45.919033 SipTransport::findAppropriateTransport - after filtering for protocol we have 2 candidates
drachtio-server | 2022-09-20 15:58:45.919819 SipTransport::findAppropriateTransport: - returning the best match 0x55b541926500: udp/172.39.0.6:5060
drachtio-server | 2022-09-20 15:58:45.919877 SipTransport::getContactUri - created Contact header: sip:172.39.0.6:5060
drachtio-server | 2022-09-20 15:58:45.919891 SipDialogController::doSendRequestOutsideDialog selected transport 0x55b541926500udp/172.39.0.6:5060
drachtio-server | 2022-09-20 15:58:45.920009 makeTags - Adding well-known header 'From' with value '<sip:192.168.1.1>;tag=F5DXvrDD68pyp'
drachtio-server | 2022-09-20 15:58:45.920024 makeTags - Adding well-known header 'To' with value 'sip:[email protected]'
drachtio-server | 2022-09-20 15:58:45.920033 makeTags - Adding well-known header 'Contact' with value '<sip:sip:sip-username:192.168.1.1>;expires=180'
drachtio-server | 2022-09-20 15:58:45.920042 makeTags - Adding well-known header 'Expires' with value '180'
drachtio-server | 2022-09-20 15:58:45.920084 makeTags - Adding well-known header 'CSeq' with value '57290971 REGISTER'
drachtio-server | 2022-09-20 15:58:45.920097 makeTags - Adding well-known header 'Call-ID' with value 'f2ed4ba3-b39f-123b-2faa-0242ac270006'
drachtio-server | 2022-09-20 15:58:45.920107 makeTags - Adding well-known header 'Authorization' with value 'Digest username="sip-username",realm="voip.provider.com",nonce="6329e372ddc7a37f6c08c920d7984d6bb1902198",uri="sip:voip.provider.com:5060",response="fcee8283b3----REDACTED----c2d5ebe5bb",algorithm=MD5,qop=auth,nc=00000001,cnonce="a829da65"'
drachtio-server | 2022-09-20 15:58:45.920118 SipDialogController::doSendRequestOutsideDialog - from: <sip:192.168.1.1>;tag=F5DXvrDD68pyp
drachtio-server | 2022-09-20 15:58:45.920125 SipDialogController::doSendRequestOutsideDialog - to: sip:[email protected]
drachtio-server | 2022-09-20 15:58:45.920132 SipDialogController::doSendRequestOutsideDialog - contact: <sip:172.39.0.6:5060>
drachtio-server | 2022-09-20 15:58:45.920138 SipDialogController::doSendRequestOutsideDialog - using client-specified call-id: f2ed4ba3-b39f-123b-2faa-0242ac270006
drachtio-server | 2022-09-20 15:58:45.920148 isLocalSipUri: checking to see if this is one of mine: sip:voip.provider.com:5060
drachtio-server | 2022-09-20 15:58:45.920178 nta.c:7571 nta_outgoing_tcreate() nta_outgoing_tcreate(): bad tag ::tag_skip
drachtio-server | 2022-09-20 15:58:45.920203 nta.c:2834 nta_tpn_by_url() nta: selecting scheme sip
drachtio-server | 2022-09-20 15:58:45.920289 tport.c:1157 tport_ref() tport_ref(0x55b541926500): refcount is now 52
drachtio-server | 2022-09-20 15:58:45.920321 tport.c:3297 tport_tsend() tport_tsend(0x55b541926500) tpn = udp/<provider-ip>:5060
drachtio-server | 2022-09-20 15:58:45.920337 tport.c:4097 tport_resolve() tport_resolve addrinfo = <provider-ip>:5060
drachtio-server | 2022-09-20 15:58:45.920498 tport.c:4786 tport_by_addrinfo() tport_by_addrinfo(0x55b541926500): not found by name udp/<provider-ip>:5060
drachtio-server | 2022-09-20 15:58:45.920514 tport.c:4786 tport_by_addrinfo() tport_by_addrinfo(0x55b541926780): not found by name udp/<provider-ip>:5060
drachtio-server | 2022-09-20 15:58:45.920710 tport.c:3547 tport_send_msg() tport_vsend returned 298
drachtio-server | 2022-09-20 15:58:45.920799 send 298 bytes to udp/[<provider-ip>]:5060 at 15:58:45.920530:
drachtio-server | REGISTER sip:voip.provider.com:5060 SIP/2.0
drachtio-server | Via: SIP/2.0/UDP 172.39.0.6;rport;branch=z9hG4bK2Dm9XeapH3BBK
drachtio-server | Max-Forwards: 70
drachtio-server | From: <sip:192.168.1.1>;tag=F5DXvrDD68pyp
drachtio-server | To: <sip:[email protected]>
drachtio-server | Call-ID: f2f69174-b39f-123b-2faa-0242ac270006
drachtio-server | CSeq: 57290970 REGISTER
drachtio-server | Content-Length: 0
I'm trying to troubleshoot this but would be super to get some help from you. Thank you, Andrea
hmm, this seems to be related
bad tag ::tag_skip
I've seen this before -- it doesn't like the syntax of one of the headers you are adding, and then skips the rest. Not sure which one is causing the problem though....the key is, it is not the Authorization header most likely but one of the others (I think)
Oh its the Contact header, with the "sip:sip:"
Thats invalid
Hi Dave! Thank you for your prompt reply;
You are right, that was the problem! I was focused on the Authorization header and didn't notice the malformed header 😓
I attach the fixed and working code:
const contactAddress = `${sipTrunk.username}@${this.publicIp}`;
const req = await this.srf.request(
`sip:${sipTrunk.realm}:5060`, {
method: 'REGISTER',
headers: {
'From': `sip:${this.publicIp}`,
'Contact': `<sip:${contactAddress}>;expires=180`,
'Expires': 180
},
auth: {
username: sipTrunk.username,
password: sipTrunk.password
}
});
req.on('response', (response) => {
if (response.status === 200) {
console.log("Registration OK");
// ... start registration timeout
}else{
console.log("Registration KO");
// ...
}
});
Thank you!
Hello Dave,
I was thinking about a way to stop the REGISTER
s flooding: a recap of what's happening now in a header-malformed case is:
- drachtio-client tries to automatically reply to a 401.
- some header is malformed, drachtio-server logs a
bad tag ::tag_skip
and sends aREGISTER
without the passed headers but with a new Call-ID - The VoIP server answers with 401.
- drachtio-client tries to automatically reply to a 401.
- We are in an endless loop 😰
I had to either stop the client or the server to stop the 401 flooding.
I wanted to propose a fix I can implement here.
- We can check if the request received back from drachtio contains the header we added few lines above:
this.agent.request(options, (err, req)=> {
if (!req.headers[407 === this.res.statusCode ? 'Proxy-Authorization' : 'Authorization']) {
callback(new Error('unable to send authenticated request'));
}
callback(err, req);
});
- Or we can check if the Call-Id has changed
// ...
this.agent.request(options, (err, req)=>{
if (req.headers['call-id'] !== this.req.headers['call-id']) {
return callback(new Error('call-id mismatch on retransmitted request'));
}
callback(err, req);
});
and propagate the error here to the caller.
What do you think?