📄 serverauthmanager.cxx
字号:
#include <cassert>#include "resip/dum/ChallengeInfo.hxx"#include "resip/dum/DumFeature.hxx"#include "resip/dum/DumFeatureChain.hxx"#include "resip/dum/ServerAuthManager.hxx"#include "resip/dum/DialogUsageManager.hxx"#include "resip/dum/TargetCommand.hxx"#include "rutil/Logger.hxx"#include "resip/dum/UserAuthInfo.hxx"#include "resip/stack/Helper.hxx"#include "rutil/WinLeakCheck.hxx"#define RESIPROCATE_SUBSYSTEM Subsystem::DUMusing namespace resip;using namespace std;ServerAuthManager::ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target) : DumFeature(dum, target){}ServerAuthManager::~ServerAuthManager(){ InfoLog(<< "~ServerAuthManager: " << mMessages.size() << " messages in memory when destroying.");}// !bwc! We absolutely, positively, MUST NOT throw here. This is because in// DialogUsageManager::process(), we do not know if a DumFeature has taken// ownership of msg until we get a return. If we throw, the ownership of msg// is unknown. This is unacceptable.DumFeature::ProcessingResult ServerAuthManager::process(Message* msg){ SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg); if (sipMsg) { //!dcm! -- unecessary happens in handle switch ( handle(sipMsg) ) { case ServerAuthManager::Challenged: InfoLog(<< "ServerAuth challenged request " << sipMsg->brief()); return DumFeature::ChainDoneAndEventDone; case ServerAuthManager::RequestedInfo: InfoLog(<< "ServerAuth requested info (requiresChallenge) " << sipMsg->brief()); return DumFeature::EventTaken; case ServerAuthManager::RequestedCredentials: InfoLog(<< "ServerAuth requested credentials " << sipMsg->brief()); return DumFeature::EventTaken; case ServerAuthManager::Rejected: InfoLog(<< "ServerAuth rejected request " << sipMsg->brief()); return DumFeature::ChainDoneAndEventDone; default: // includes Skipped return DumFeature::FeatureDone; } } ChallengeInfo* challengeInfo = dynamic_cast<ChallengeInfo*>(msg); if(challengeInfo) { InfoLog(<< "ServerAuth got ChallengeInfo " << challengeInfo->brief()); MessageMap::iterator it = mMessages.find(challengeInfo->getTransactionId()); assert(it != mMessages.end()); std::auto_ptr<SipMessage> sipMsg(it->second); mMessages.erase(it); if(challengeInfo->isFailed()) { // some kind of failure occurred while checking whether a // challenge is required InfoLog(<< "ServerAuth requiresChallenge() async failed"); SharedPtr<SipMessage> response(new SipMessage); Helper::makeResponse(*response, *sipMsg, 500, "Server Internal Error"); mDum.send(response); return DumFeature::ChainDoneAndEventDone; } if(challengeInfo->isChallengeRequired()) { issueChallenge(sipMsg.get()); InfoLog(<< "ServerAuth challenged request (after async) " << sipMsg->brief()); return DumFeature::ChainDoneAndEventDone; } else { // challenge is not required, re-instate original message postCommand(auto_ptr<Message>(sipMsg)); return FeatureDoneAndEventDone; } } UserAuthInfo* userAuth = dynamic_cast<UserAuthInfo*>(msg); if (userAuth) { //InfoLog(<< "Got UserAuthInfo"); UserAuthInfo* userAuth = dynamic_cast<UserAuthInfo*>(msg); if (userAuth) { Message* result = handleUserAuthInfo(userAuth); if (result) { postCommand(auto_ptr<Message>(result)); return FeatureDoneAndEventDone; } else { InfoLog(<< "ServerAuth rejected request " << *userAuth); return ChainDoneAndEventDone; } } } return FeatureDone; }SipMessage*ServerAuthManager::handleUserAuthInfo(UserAuthInfo* userAuth){ assert(userAuth); MessageMap::iterator it = mMessages.find(userAuth->getTransactionId()); assert(it != mMessages.end()); SipMessage* requestWithAuth = it->second; mMessages.erase(it); InfoLog( << "Checking for auth result in realm=" << userAuth->getRealm() << " A1=" << userAuth->getA1()); if (userAuth->getMode() == UserAuthInfo::UserUnknown || (userAuth->getMode() == UserAuthInfo::RetrievedA1 && userAuth->getA1().empty())) { InfoLog (<< "User unknown " << userAuth->getUser() << " in " << userAuth->getRealm()); SharedPtr<SipMessage> response(new SipMessage); Helper::makeResponse(*response, *requestWithAuth, 404, "User unknown."); mDum.send(response); onAuthFailure(BadCredentials, *requestWithAuth); delete requestWithAuth; return 0; } if (userAuth->getMode() == UserAuthInfo::Error) { InfoLog (<< "Error in auth procedure for " << userAuth->getUser() << " in " << userAuth->getRealm()); SharedPtr<SipMessage> response(new SipMessage); Helper::makeResponse(*response, *requestWithAuth, 503, "Server Error."); mDum.send(response); onAuthFailure(Error, *requestWithAuth); delete requestWithAuth; return 0; } bool stale = false; bool digestAccepted = (userAuth->getMode() == UserAuthInfo::DigestAccepted); if(userAuth->getMode() == UserAuthInfo::RetrievedA1) { //!dcm! -- need to handle stale/unit test advancedAuthenticateRequest //!dcm! -- delta? deal with. std::pair<Helper::AuthResult,Data> resPair = Helper::advancedAuthenticateRequest(*requestWithAuth, userAuth->getRealm(), userAuth->getA1(), 3000, proxyAuthenticationMode()); switch (resPair.first) { case Helper::Authenticated: digestAccepted = true; break; case Helper::Failed: // digestAccepted = false; // already false by default break; case Helper::BadlyFormed: if(rejectBadNonces()) { InfoLog (<< "Authentication nonce badly formed for " << userAuth->getUser()); SharedPtr<SipMessage> response(new SipMessage); Helper::makeResponse(*response, *requestWithAuth, 403, "Invalid nonce"); mDum.send(response); onAuthFailure(InvalidRequest, *requestWithAuth); delete requestWithAuth; return 0; } else { stale=true; } break; case Helper::Expired: stale = true; break; default: break; } } if(stale || userAuth->getMode() == UserAuthInfo::Stale) { InfoLog (<< "Nonce expired for " << userAuth->getUser()); issueChallenge(requestWithAuth); delete requestWithAuth; return 0; } if(digestAccepted) { if (authorizedForThisIdentity(userAuth->getUser(), userAuth->getRealm(), requestWithAuth->header(h_From).uri())) { InfoLog (<< "Authorized request for " << userAuth->getRealm()); onAuthSuccess(*requestWithAuth); return requestWithAuth; } else { // !rwm! The user is trying to forge a request. Respond with a 403 InfoLog (<< "User: " << userAuth->getUser() << " at realm: " << userAuth->getRealm() << " trying to forge request from: " << requestWithAuth->header(h_From).uri()); SharedPtr<SipMessage> response(new SipMessage); Helper::makeResponse(*response, *requestWithAuth, 403, "Invalid user name provided"); mDum.send(response); onAuthFailure(InvalidRequest, *requestWithAuth); delete requestWithAuth; return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -