From: Shawn S. <kph...@at...> - 2005-06-19 21:12:39
|
This week I had some frustration with sipphone.com. Placing a call through them to the PSTN service ended "401 Unauthorized". Some digging into what was expected versus what was happening proved a little enlightening. The patch I'm attaching today adds 401 handling to the various handling*Response methods. With it, I'm properly able to 'dial' out through sipphone.com. Presumably, this would fix a couple of other "Unauthorized" issues I found in my net searches before digging in to fix it myself, but I don't know for sure. The patch was made against the CVS version. Feedback is welcomed warmly. I think next, I'm going to see what it would take to get my Internet Phone Wizard to act as something more than just a usbaudio device (Make it treat the phone more like a phone, ringing, detecting off-hook/on-hook and dialing presses). Yeah, a bit more ambitious. ---- diff -urw kphone/dissipate2/sipcall.cpp kphone.new/dissipate2/sipcall.cpp --- kphone/dissipate2/sipcall.cpp 2005-04-18 09:04:40.000000000 -0400 +++ kphone.new/dissipate2/sipcall.cpp 2005-06-18 12:18:29.072390176 -0400 @@ -62,15 +62,20 @@ authstate == authState_AuthenticationRequiredWithNewPassword ) ) { if( authtype == ProxyDigestAuthenticationRequired ) { proxyauthresponse = Sip::getDigestResponse( - username, password, "SUBSCRIBE", getContactUri().uri(), proxyauthstr ); + username, password, "SUBSCRIBE", getContactUri().uri(), authrequeststr ); } else if( authtype == ProxyBasicAuthenticationRequired ) { proxyauthresponse = Sip::getBasicResponse( username, password ); + } else if( authtype == DigestAuthenticationRequired ) { + authresponse = Sip::getDigestResponse( + username, password, "SUBSCRIBE", getContactUri().uri(), authrequeststr ); + } else if( authtype == BasicAuthenticationRequired ) { + authresponse = Sip::getBasicResponse( username, password ); } local = call->newRequest( this, Sip::SUBSCRIBE, localsessiondesc, localsessiontype, - SipUri::null, proxyauthresponse, localExpiresTime ); + SipUri::null, authresponse, proxyauthresponse, localExpiresTime ); } else { local = call->newRequest( this, Sip::SUBSCRIBE, localsessiondesc, localsessiontype, - SipUri::null, QString::null, localExpiresTime ); + SipUri::null, QString::null, QString::null, localExpiresTime ); } if( localExpiresTime > 0 ) { timer->start( localExpiresTime * 900, TRUE ); @@ -115,12 +120,12 @@ } authstate = authState_AuthenticationOK; } else if( local->getStatus().getCode() == 401) { - proxyauthstr = local->getFinalWWWAuthString(); - authstrtemp = proxyauthstr.lower(); + authrequeststr = local->getFinalWWWAuthString(); + authstrtemp = authrequeststr.lower(); if( authstrtemp.contains( "digest" ) ) { - authtype = ProxyDigestAuthenticationRequired; + authtype = DigestAuthenticationRequired; } else { - authtype = ProxyBasicAuthenticationRequired; + authtype = BasicAuthenticationRequired; } if( authstate == authState_AuthenticationTryingWithPassword ) { authstate = authState_AuthenticationRequiredWithNewPassword; @@ -132,8 +137,8 @@ return; } else if( local->getStatus().getCode() == 407) { - proxyauthstr = local->getFinalProxyAuthString(); - authstrtemp = proxyauthstr.lower(); + authrequeststr = local->getFinalProxyAuthString(); + authstrtemp = authrequeststr.lower(); if( authstrtemp.contains( "digest" ) ) { authtype = ProxyDigestAuthenticationRequired; } else { @@ -180,15 +185,20 @@ authstate == authState_AuthenticationRequiredWithNewPassword ) ) { if( authtype == ProxyDigestAuthenticationRequired ) { proxyauthresponse = Sip::getDigestResponse( - username, password, "NOTIFY", getContactUri().uri(), proxyauthstr ); + username, password, "NOTIFY", getContactUri().uri(), authrequeststr ); } else if( authtype == ProxyBasicAuthenticationRequired ) { proxyauthresponse = Sip::getBasicResponse( username, password ); + } else if ( authtype == DigestAuthenticationRequired ) { + authresponse = Sip::getDigestResponse( + username, password, "NOTIFY", getContactUri().uri(), authrequeststr ); + } else if ( authtype == BasicAuthenticationRequired ) { + authresponse = Sip::getBasicResponse( username, password ); } local = call->newRequest( this, Sip::NOTIFY, localsessiondesc, localsessiontype, - SipUri::null, proxyauthresponse, localExpiresTime ); + SipUri::null, authresponse, proxyauthresponse, localExpiresTime ); } else { local = call->newRequest( this, Sip::NOTIFY, localsessiondesc, localsessiontype, - SipUri::null, QString::null, localExpiresTime ); + SipUri::null, QString::null, QString::null, localExpiresTime ); } if( local ) { op = opRequest; @@ -229,8 +239,8 @@ local = 0; } else { if( local->getStatus().getCode() == 407) { - proxyauthstr = local->getFinalProxyAuthString(); - authstrtemp = proxyauthstr.lower(); + authrequeststr = local->getFinalProxyAuthString(); + authstrtemp = authrequeststr.lower(); if( authstrtemp.contains( "digest" ) ) { authtype = ProxyDigestAuthenticationRequired; } else { @@ -246,12 +256,12 @@ return; } else if( local->getStatus().getCode() == 401) { - proxyauthstr = local->getFinalWWWAuthString(); - authstrtemp = proxyauthstr.lower(); + authrequeststr = local->getFinalWWWAuthString(); + authstrtemp = authrequeststr.lower(); if( authstrtemp.contains( "digest" ) ) { - authtype = ProxyDigestAuthenticationRequired; + authtype = DigestAuthenticationRequired; } else { - authtype = ProxyBasicAuthenticationRequired; + authtype = BasicAuthenticationRequired; } if( authstate == authState_AuthenticationTryingWithPassword ) { authstate = authState_AuthenticationRequiredWithNewPassword; @@ -292,15 +302,20 @@ authstate == authState_AuthenticationRequiredWithNewPassword ) ) { if( authtype == ProxyDigestAuthenticationRequired ) { proxyauthresponse = Sip::getDigestResponse( - username, password, "MESSAGE", getContactUri().uri(), proxyauthstr ); + username, password, "MESSAGE", getContactUri().uri(), authrequeststr ); } else if( authtype == ProxyBasicAuthenticationRequired ) { proxyauthresponse = Sip::getBasicResponse( username, password ); + } else if( authtype == DigestAuthenticationRequired ) { + authresponse = Sip::getDigestResponse( + username, password, "MESSAGE", getContactUri().uri(), authrequeststr ); + } else if( authtype == BasicAuthenticationRequired ) { + authresponse = Sip::getBasicResponse( username, password ); } local = call->newRequest( this, Sip::MESSAGE, localsessiondesc, localsessiontype, - SipUri::null, proxyauthresponse, localExpiresTime ); + SipUri::null, authresponse, proxyauthresponse, localExpiresTime ); } else { local = call->newRequest( this, Sip::MESSAGE, localsessiondesc, localsessiontype, - SipUri::null, QString::null, localExpiresTime ); + SipUri::null, QString::null, QString::null, localExpiresTime ); } if( localExpiresTime > 0 ) { timer->start( localExpiresTime * 900, TRUE ); @@ -333,8 +348,8 @@ if( local->getStatus().getCode() < 300 ) { } else { if(local->getStatus().getCode() == 407){ - proxyauthstr = local->getFinalProxyAuthString(); - authstrtemp = proxyauthstr.lower(); + authrequeststr = local->getFinalProxyAuthString(); + authstrtemp = authrequeststr.lower(); if( authstrtemp.contains( "digest" ) ) { authtype = ProxyDigestAuthenticationRequired; } else { @@ -348,6 +363,21 @@ requestAuthMessage(); return; + } else if( local->getStatus().getCode() == 401) { + authrequeststr = local->getFinalWWWAuthString(); + authstrtemp = authrequeststr.lower(); + if( authstrtemp.contains( "digest" ) ) { + authtype = DigestAuthenticationRequired; + } else { + authtype = BasicAuthenticationRequired; + } + if( authstate == authState_AuthenticationTryingWithPassword ) { + authstate = authState_AuthenticationRequiredWithNewPassword; + } else { + authstate = authState_AuthenticationRequired; + } + requestAuthMessage(); + return; } else { state = state_Disconnected; @@ -378,15 +408,20 @@ authstate == authState_AuthenticationRequiredWithNewPassword ) ) { if( authtype == ProxyDigestAuthenticationRequired ) { proxyauthresponse = Sip::getDigestResponse( - username, password, "INVITE", getContactUri().uri(), proxyauthstr ); + username, password, "INVITE", getContactUri().uri(), authrequeststr ); } else if( authtype == ProxyBasicAuthenticationRequired ) { proxyauthresponse = Sip::getBasicResponse( username, password ); + } else if( authtype == DigestAuthenticationRequired ) { + authresponse = Sip::getDigestResponse( + username, password, "INVITE", getContactUri().uri(), authrequeststr ); + } else if( authtype == BasicAuthenticationRequired ) { + authresponse = Sip::getBasicResponse( username, password ); } local = call->newRequest( this, Sip::INVITE, localsessiondesc, localsessiontype, - SipUri::null, proxyauthresponse, localExpiresTime ); + SipUri::null, authresponse, proxyauthresponse, localExpiresTime ); } else { local = call->newRequest( this, Sip::INVITE, localsessiondesc, localsessiontype, - SipUri::null, QString::null, localExpiresTime ); + SipUri::null, QString::null, QString::null, localExpiresTime ); } if( localExpiresTime > 0 ) { timer->start( localExpiresTime * 900, TRUE ); @@ -418,8 +453,8 @@ statusdesc = tr("Response: ") + local->getStatus().getReasonPhrase(); statusUpdated( this ); } else if( local->getStatus().getCode() == 407 ) { - proxyauthstr = local->getFinalProxyAuthString(); - authstrtemp = proxyauthstr.lower(); + authrequeststr = local->getFinalProxyAuthString(); + authstrtemp = authrequeststr.lower(); if( authstrtemp.contains( "digest" ) ) { authtype = ProxyDigestAuthenticationRequired; } else { @@ -428,6 +463,17 @@ requestAuthInvite(); return; + } else if( local->getStatus().getCode() == 401) { + authrequeststr = local->getFinalWWWAuthString(); + authstrtemp = authrequeststr.lower(); + if( authstrtemp.contains( "digest" ) ) { + authtype = DigestAuthenticationRequired; + } else { + authtype = BasicAuthenticationRequired; + } + requestAuthInvite(); + return; + } else { state = state_Disconnected; statusdesc = tr("Response: ") + local->getStatus().getReasonPhrase(); @@ -438,8 +484,8 @@ } else if( state == state_Disconnecting ) { if( local->getStatus().getCode() >= 200 ) { if( local->getStatus().getCode() == 407 ) { - proxyauthstr = local->getFinalProxyAuthString(); - authstrtemp = proxyauthstr.lower(); + authrequeststr = local->getFinalProxyAuthString(); + authstrtemp = authrequeststr.lower(); if( authstrtemp.contains( "digest" ) ) { authtype = ProxyDigestAuthenticationRequired; } else { @@ -448,6 +494,17 @@ requestDisconnect(); return; + } else if( local->getStatus().getCode() == 401 ) { + authrequeststr = local->getFinalWWWAuthString(); + authstrtemp = authrequeststr.lower(); + if( authstrtemp.contains( "digest" ) ) { + authtype = DigestAuthenticationRequired; + } else { + authtype = BasicAuthenticationRequired; + } + requestDisconnect(); + + return; } else { state = state_Disconnected; @@ -481,8 +538,8 @@ redirectlist = local->getFinalContactList(); } else { if(local->getStatus().getCode() == 407){ - proxyauthstr = local->getFinalProxyAuthString(); - authstrtemp = proxyauthstr.lower(); + authrequeststr = local->getFinalProxyAuthString(); + authstrtemp = authrequeststr.lower(); if( authstrtemp.contains( "digest" ) ) { authtype = ProxyDigestAuthenticationRequired; } else { @@ -497,7 +554,23 @@ requestAuthInvite(); return; + } else if(local->getStatus().getCode() == 401) { + authrequeststr = local->getFinalWWWAuthString(); + authstrtemp = authrequeststr.lower(); + if( authstrtemp.contains( "digest" ) ) { + authtype = DigestAuthenticationRequired; + } else { + authtype = BasicAuthenticationRequired; + } + if( authstate == authState_AuthenticationTryingWithPassword || + authstate == authState_AuthenticationRequiredWithNewPassword ) { + authstate = authState_AuthenticationRequiredWithNewPassword; + } else { + authstate = authState_AuthenticationRequired; + } + requestAuthInvite(); + return; } else { state = state_Disconnected; statusdesc = "!!" + tr("Call Failed: ") + local->getStatus().getReasonPhrase(); @@ -765,10 +838,11 @@ SipTransaction *SipCall::newRequest( SipCallMember *member, Sip::Method meth, const QString &body, const MimeContentType &bodytype, const SipUri &transferto, + const QString &authentication, const QString &proxyauthentication, int expiresTime ) { SipTransaction *trans = new SipTransaction( lastseq++, member, this ); - if( trans->sendRequest( meth, body, bodytype, transferto, proxyauthentication, expiresTime ) ) { + if( trans->sendRequest( meth, body, bodytype, transferto, authentication, proxyauthentication, expiresTime ) ) { transactions.clear(); transactions.append( trans ); diff -urw kphone/dissipate2/sipcall.h kphone.new/dissipate2/sipcall.h --- kphone/dissipate2/sipcall.h 2005-04-18 09:04:40.000000000 -0400 +++ kphone.new/dissipate2/sipcall.h 2005-06-18 12:18:55.389389384 -0400 @@ -96,6 +96,8 @@ authState_AuthenticationRequiredWithNewPassword }; enum AuthType { + BasicAuthenticationRequired, + DigestAuthenticationRequired, ProxyBasicAuthenticationRequired, ProxyDigestAuthenticationRequired }; @@ -310,7 +312,8 @@ QString statusdesc; QString recentbody; MimeContentType recentbodytype; - QString proxyauthstr; + QString authrequeststr; + QString authresponse; QString proxyauthresponse; int localExpiresTime; QTimer *timer; @@ -418,6 +421,7 @@ const QString &body = QString::null, const MimeContentType &bodytype = MimeContentType::null, const SipUri &transferto = SipUri::null, + const QString &authentication = QString::null, const QString &proxyauthentication = QString::null, int expiresTime = -1 ); diff -urw kphone/dissipate2/siptransaction.cpp kphone.new/dissipate2/siptransaction.cpp --- kphone/dissipate2/siptransaction.cpp 2005-04-18 09:04:40.000000000 -0400 +++ kphone.new/dissipate2/siptransaction.cpp 2005-06-18 02:05:55.000000000 -0400 @@ -54,6 +54,7 @@ bool SipTransaction::sendRequest( Sip::Method meth, const QString &body, const MimeContentType &bodytype, const SipUri &transferto, + const QString &authentication, const QString &proxyauthentication, const int expiresTime ) { if( meth == Sip::INVITE ) { @@ -96,6 +97,9 @@ if( proxyauthentication != QString::null ) { requestmessage->insertHeader( SipHeader::Proxy_Authorization, proxyauthentication ); } + if ( authentication != QString::null ) { + requestmessage->insertHeader( SipHeader::Authorization, authentication ); + } if( expiresTime >= 0 ) { QString strExpiresTime; diff -urw kphone/dissipate2/siptransaction.h kphone.new/dissipate2/siptransaction.h --- kphone/dissipate2/siptransaction.h 2005-04-18 09:04:40.000000000 -0400 +++ kphone.new/dissipate2/siptransaction.h 2005-06-17 22:23:12.000000000 -0400 @@ -194,6 +194,7 @@ const QString &body = QString::null, const MimeContentType &bodytype = MimeContentType::null, const SipUri &transferto = SipUri::null, + const QString &authentication = QString::null, const QString &proxyauthentication = QString::null, const int expiresTime = -1 ); |