reSIProcate/DialogUsageManager  9694
RADIUSServerAuthManager.cxx
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include "config.h"
00003 #endif
00004 
00005 
00006 #include <sstream>
00007 
00008 #include "resip/dum/ChallengeInfo.hxx"
00009 #include "resip/dum/ClientInviteSession.hxx"
00010 #include "resip/dum/DialogUsageManager.hxx"
00011 #include "resip/dum/UserAuthInfo.hxx"
00012 #include "resip/dum/RADIUSServerAuthManager.hxx"
00013 #include "resip/stack/ExtensionHeader.hxx"
00014 #include "rutil/Data.hxx"
00015 #include "rutil/Logger.hxx"
00016 #include "rutil/MD5Stream.hxx"
00017 
00018 #ifdef USE_RADIUS_CLIENT
00019 
00020 using namespace resip;
00021 using namespace std;
00022 
00023 #define RESIPROCATE_SUBSYSTEM Subsystem::DUM
00024 
00025 RADIUSServerAuthManager::RADIUSServerAuthManager(resip::DialogUsageManager& dum) : ServerAuthManager(dum, dum.dumIncomingTarget()), dum(dum) {
00026 
00027   RADIUSDigestAuthenticator::init(NULL);
00028 }
00029 
00030 RADIUSServerAuthManager::~RADIUSServerAuthManager() {
00031 }
00032 
00033 ServerAuthManager::AsyncBool RADIUSServerAuthManager::requiresChallenge(const SipMessage& msg) {
00034 
00035   ostringstream s;
00036   s << msg.header(h_RequestLine).uri(); 
00037   DebugLog(<<"RADIUSServerAuthManager::requiresChallenge, uri = " << s.str().c_str());
00038 
00039   // default behaviour is to challenge
00040   ChallengeInfo *cmsg = new ChallengeInfo(false, true, msg.getTransactionId());
00041   dum.post(cmsg);
00042   return Async;
00043 }
00044 
00045 void RADIUSServerAuthManager::requestCredential(const resip::Data& user, const resip::Data& realm, const resip::SipMessage& msg, const resip::Auth& auth, const resip::Data& transactionId) {
00046 
00047   ostringstream s;
00048   s << msg.header(h_RequestLine).uri();
00049   DebugLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s << " authUser = " << user);
00050 
00051   MyRADIUSDigestAuthListener *radiusListener = NULL;
00052   try {
00053 
00054     radiusListener = new MyRADIUSDigestAuthListener(user, realm, dum, transactionId);
00055     Data radiusUser(user + "@" + realm);
00056     DebugLog(<< "radiusUser = " << radiusUser.c_str() << ", " << "user = " << user.c_str());
00057     Data reqUri("");
00058     Data reqMethod("");
00059     if(msg.isRequest()) {
00060       //reqUri = Data(msg.header(h_RequestLine).uri());
00061   //    ostringstream s;
00062   //    s << msg.header(h_RequestLine).uri();
00063       //reqUri = Data(s.str());
00064       reqUri = auth.param(p_uri);
00065       reqMethod = Data(resip::getMethodName(msg.header(h_RequestLine).getMethod()));
00066     }
00067     RADIUSDigestAuthenticator *radius = NULL;
00068     if(auth.exists(p_qop)) {
00069       if(auth.param(p_qop) == Symbols::auth) {
00070         Data myQop("auth");
00071         radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, myQop, auth.param(p_nc), auth.param(p_cnonce), auth.param(p_response), radiusListener);     
00072       } else if(auth.param(p_qop) == Symbols::authInt) {
00073         Data myQop("auth-int");
00074         radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, myQop, auth.param(p_nc), auth.param(p_cnonce), auth.param(p_opaque), auth.param(p_response), radiusListener); 
00075       }
00076     }
00077     if(radius == NULL) {
00078       radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, auth.param(p_response), radiusListener);
00079     }
00080     int result = radius->doRADIUSCheck(); 
00081     if(result < 0) {
00082       ErrLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s <<" failed to start thread, error = " << result);
00083     }
00084   } catch(...) {
00085     WarningLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s <<" exception");
00086     delete radiusListener;
00087   }
00088 }
00089 
00090 bool RADIUSServerAuthManager::useAuthInt() const {
00091   return true;
00092 }
00093 
00094 bool RADIUSServerAuthManager::authorizedForThisIdentity(const resip::Data &user, const resip::Data &realm, resip::Uri &fromUri) {
00095   // Always returns true: in other words, any user can send any from URI
00096   // or forge any CLI
00097   return true;
00098 }
00099 
00100 void
00101 RADIUSServerAuthManager::onAuthSuccess(const resip::SipMessage& msg) {
00102 }
00103 
00104 void 
00105 RADIUSServerAuthManager::onAuthFailure(resip::ServerAuthManager::AuthFailureReason reason, const resip::SipMessage& msg) {
00106   Data failureMsg("unknown failure");
00107   switch(reason) {
00108   case InvalidRequest: 
00109     failureMsg = Data("InvalidRequest");
00110     break;
00111   case BadCredentials:
00112     failureMsg = Data("BadCredentials");
00113     break;
00114   case Error:
00115     failureMsg = Data("Error");
00116     break;
00117   }
00118   Tuple sourceTuple = msg.getSource();
00119   Data sourceIp = Data(inet_ntoa(sourceTuple.toGenericIPAddress().v4Address.sin_addr));
00120   WarningLog(<<"auth failure: " << failureMsg << ": src IP=" << sourceIp << ", uri=" << msg.header(h_RequestLine).uri().user() << ", from=" <<msg.header(h_From).uri().user() << ", to=" << msg.header(h_To).uri().user());
00121 }
00122 
00123 MyRADIUSDigestAuthListener::MyRADIUSDigestAuthListener(const resip::Data& user, const resip::Data& realm, resip::TransactionUser& tu, const resip::Data& transactionId) : user(user), realm(realm), tu(tu), transactionId(transactionId) {
00124 }
00125 
00126 MyRADIUSDigestAuthListener::~MyRADIUSDigestAuthListener() {
00127 }
00128 
00129 void MyRADIUSDigestAuthListener::onSuccess(const resip::Data& rpid) {
00130   DebugLog(<<"MyRADIUSDigestAuthListener::onSuccess");
00131   if(!rpid.empty())
00132     DebugLog(<<"MyRADIUSDigestAuthListener::onSuccess rpid = " << rpid.c_str());
00133   else
00134     DebugLog(<<"MyRADIUSDigestAuthListener::onSuccess, no rpid");
00135   UserAuthInfo *uai = new UserAuthInfo(user, realm, UserAuthInfo::DigestAccepted, transactionId);
00136   tu.post(uai);
00137 }
00138 
00139 void MyRADIUSDigestAuthListener::onAccessDenied() {
00140   DebugLog(<<"MyRADIUSDigestAuthListener::onAccessDenied");
00141   UserAuthInfo *uai = new UserAuthInfo(user, realm, UserAuthInfo::DigestNotAccepted, transactionId);
00142   tu.post(uai);
00143 }
00144 
00145 void MyRADIUSDigestAuthListener::onError() {
00146   WarningLog(<<"MyRADIUSDigestAuthListener::onError");
00147   UserAuthInfo *uai = new UserAuthInfo(user, realm, UserAuthInfo::Error, transactionId);
00148   tu.post(uai);
00149 }
00150 
00151 #endif
00152