📄 digestauthenticator.cxx
字号:
#include "rutil/DnsUtil.hxx"#include "resip/stack/Message.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/stack/Auth.hxx"#include "resip/stack/Helper.hxx"#include "rutil/Logger.hxx"#include "repro/monkeys/DigestAuthenticator.hxx"#include "repro/RequestContext.hxx"#include "repro/Proxy.hxx"#include "repro/UserInfoMessage.hxx"#include "repro/UserStore.hxx"#include "repro/Dispatcher.hxx"#include "repro/UserAuthGrabber.hxx"#include "resip/stack/SipStack.hxx"#include "rutil/ParseBuffer.hxx"#include "rutil/WinLeakCheck.hxx"#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPROusing namespace resip;using namespace repro;using namespace std;DigestAuthenticator::DigestAuthenticator( UserStore& userStore, resip::SipStack* stack, bool noIdentityHeaders, int httpPort, bool useAuthInt, bool rejectBadNonces) : mNoIdentityHeaders(noIdentityHeaders), mHttpPort(httpPort), mUseAuthInt(useAuthInt), mRejectBadNonces(rejectBadNonces){ std::auto_ptr<Worker> grabber(new UserAuthGrabber(userStore)); mAuthRequestDispatcher= new Dispatcher(grabber,stack);}DigestAuthenticator::~DigestAuthenticator(){ delete mAuthRequestDispatcher;}repro::Processor::processor_action_tDigestAuthenticator::process(repro::RequestContext &rc){ DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << rc); Message *message = rc.getCurrentEvent(); SipMessage *sipMessage = dynamic_cast<SipMessage*>(message); UserInfoMessage *userInfo = dynamic_cast<UserInfoMessage*>(message); Proxy &proxy = rc.getProxy(); if (sipMessage) { if (sipMessage->method() == ACK || sipMessage->method() == BYE) { return Continue; } if (sipMessage->exists(h_ProxyAuthorizations)) { Auths &authHeaders = sipMessage->header(h_ProxyAuthorizations); // if we find a Proxy-Authorization header for a realm we handle, // asynchronously fetch the relevant userAuthInfo from the database for (Auths::iterator i = authHeaders.begin() ; i != authHeaders.end() ; ++i) { // !rwm! TODO sometime we need to have a separate isMyRealm() function if (proxy.isMyDomain(i->param(p_realm))) { return requestUserAuthInfo(rc, i->param(p_realm)); } } } // if there was no Proxy-Auth header already, and the request is purportedly From // one of our domains, send a challenge, unless this is from a trusted node in one // of "our" domains (ex: from a gateway). // // Note that other monkeys can still challenge the request later if needed // for other reasons (for example, the StaticRoute monkey) if(!sipMessage->header(h_From).isWellFormed() || sipMessage->header(h_From).isAllContacts() ) { InfoLog(<<"Malformed From header: cannot get realm to challenge with. Rejecting."); rc.sendResponse(*auto_ptr<SipMessage> (Helper::makeResponse(*sipMessage, 400, "Malformed From header"))); return SkipAllChains; } if (proxy.isMyDomain(sipMessage->header(h_From).uri().host())) { if (!rc.fromTrustedNode()) { challengeRequest(rc, false); return SkipAllChains; } } } else if (userInfo) { // Handle response from user authentication database sipMessage = &rc.getOriginalRequest(); const Data& a1 = userInfo->A1(); const Data& realm = userInfo->realm(); const Data& user = userInfo->user(); InfoLog (<< "Received user auth info for " << user << " at realm " << realm << " a1 is " << a1); pair<Helper::AuthResult,Data> result = Helper::advancedAuthenticateRequest(*sipMessage, realm, a1, 3000); // was 15// Auths &authHeaders = sipMessage->header(h_ProxyAuthorizations); switch (result.first) { case Helper::Failed: InfoLog (<< "Authentication failed for " << user << " at realm " << realm << ". Sending 403"); rc.sendResponse(*auto_ptr<SipMessage> (Helper::makeResponse(*sipMessage, 403, "Authentication Failed"))); return SkipAllChains; // !abr! Eventually, this should just append a counter to // the nonce, and increment it on each challenge. // If this count is smaller than some reasonable limit, // then we re-challenge; otherwise, we send a 403 instead. case Helper::Authenticated: InfoLog (<< "Authentication ok for " << user); // Delete the Proxy-Auth header for this realm. // other Proxy-Auth headers might be needed by a downsteram node/* Auths::iterator i = authHeaders.begin(); Auths::iterator j = authHeaders.begin(); while( i != authHeaders.end() ) { if (proxy.isMyDomain(i->param(p_realm))) { j = i++; authHeaders.erase(j); } else { ++i; } }*/ if(!sipMessage->header(h_From).isWellFormed() || sipMessage->header(h_From).isAllContacts()) { InfoLog(<<"From header is malformed in" " digest response."); rc.sendResponse(*auto_ptr<SipMessage> (Helper::makeResponse(*sipMessage, 400, "Malformed From header"))); return SkipAllChains; } if (authorizedForThisIdentity(user, realm, sipMessage->header(h_From).uri())) { rc.setDigestIdentity(user); // TODO Need a nerd knob to set PAI if (sipMessage->exists(h_PPreferredIdentities)) { // find the fist sip or sips P-Preferred-Identity header and the first tel // bool haveSip = false; // bool haveTel = false; // for (;;) // { // if ((i->uri().scheme() == Symbols::SIP) || (i->uri().scheme() == Symbols::SIPS)) // { // if (haveSip) // { // continue; // skip all but the first sip: or sips: URL // } // haveSip = true; // // if (knownSipIdentity( user, realm, i->uri() ) // should be NameAddr? // { // sipMessage->header(h_PAssertedIdentities).push_back( i->uri() ); // } // else // { // sipMessage->header(h_PAssertedIdentities).push_back(getDefaultIdentity(user, realm)); // } // } // else if ((i->uri().scheme() == Symbols::TEL)) // { // if (haveTel) // { // continue; // skip all but the first tel: URL // } // haveTel = true; // // if (knownTelIdentity( user, realm, i->uri() )) // { // sipMessage->header(h_PAssertedIdentities).push_back( i->uri() ); // } // } // } // sipMessage->header(h_PPreferredIdentities).erase(); } else { if (!sipMessage->exists(h_PAssertedIdentities)) { // sipMessage->header(h_PAssertedIdentities).push_back(getDefaultIdentity(user, realm)); } } #if defined(USE_SSL) if(!mNoIdentityHeaders) { static Data http("http://"); static Data post(":" + Data(mHttpPort) + "/cert?domain="); // .bwc. Leave pre-existing Identity headers alone. if(!sipMessage->exists(h_Identity)) { sipMessage->header(h_Identity).value() = Data::Empty; if(sipMessage->exists(h_IdentityInfo)) { InfoLog(<<"Somebody sent us a" " request with an Identity-Info, but no Identity" " header. Removing it."); if(!sipMessage->header(h_IdentityInfo).isWellFormed())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -