RedirectPlugin::LookUpStatus SipRedirectorMapping::lookUp( const SipMessage& message, const UtlString& requestString, const Url& requestUri, const UtlString& method, ContactList& contactList, RequestSeqNo requestSeqNo, int redirectorNo, SipRedirectorPrivateStorage*& privateStorage, ErrorDescriptor& errorDescriptor) { UtlString callTag = "UNK"; UtlString permissionName; ResultSet urlMappingRegistrations; ResultSet urlMappingPermissions; // @JC This variable is strangely overloaded // If we have no permissions then add any encountered // contacts. If we do have permissions then the // permission must match UtlBoolean permissionFound = TRUE; if (mMappingRulesLoaded == OS_SUCCESS) { mMap.getContactList( requestUri, urlMappingRegistrations, urlMappingPermissions, callTag); } int numUrlMappingPermissions = urlMappingPermissions.getSize(); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp " "got %d UrlMapping Permission requirements for %d contacts", mLogName.data(), numUrlMappingPermissions, urlMappingRegistrations.getSize()); if (numUrlMappingPermissions > 0) { // check if we have field parameter that indicates that some permissions should be ignored UtlString ignorePermissionStr; // :KLUDGE: remove const_cast and uri declaration after XSL-88 gets fixed Url& uri = const_cast<Url&>(requestUri); uri.getUrlParameter("sipx-noroute", ignorePermissionStr); EntityRecord entity; std::set<std::string> permissions; if (_dataStore.entityDB().findByIdentityOrAlias(requestUri, entity)) permissions = entity.permissions(); size_t numDBPermissions = permissions.size(); for (int i = 0; i<numUrlMappingPermissions; i++) { UtlHashMap record; urlMappingPermissions.getIndex(i, record); UtlString permissionKey("permission"); UtlString urlMappingPermissionStr = *((UtlString*) record.findValue(&permissionKey)); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp checking permissions DB for " "urlMappingPermissions[%d] = '%s'", mLogName.data(), i, urlMappingPermissionStr.data()); // Try to match the permission // so assume it cannot be found unless we // see a match in the IMDB permissionFound = FALSE; // if the permission we are looking for is the one the we are supposed to ignore, // than assume that permission is not found if (urlMappingPermissionStr.compareTo(ignorePermissionStr, UtlString::ignoreCase) == 0) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp ignoring permission '%s'", mLogName.data(), ignorePermissionStr.data()); continue; } UtlString permissionsFound; for (std::set<std::string>::const_iterator iter = permissions.begin(); iter != permissions.end(); iter++) { UtlString dbPermissionStr = iter->c_str(); bool equal = dbPermissionStr.compareTo(urlMappingPermissionStr, UtlString::ignoreCase) == 0; if (Os::Logger::instance().willLog(FAC_SIP, PRI_DEBUG)) { permissionsFound.append(" "); permissionsFound.append(dbPermissionStr); if (equal) { permissionsFound.append("[matches]"); } } if (equal) { // matching permission found in IMDB permissionFound = TRUE; break; } dbPermissionStr.remove(0); } Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp %d permissions configured for request URI '%s'. Checking: %s", mLogName.data(), numDBPermissions, requestUri.toString().data(), permissionsFound.data()); if (permissionFound) { break; } urlMappingPermissionStr.remove(0); } } // either there were no requirements to match against voicemail // or there were and we found a match in the IMDB for the URI // so now add the contacts to the SIP message if (permissionFound) { int numUrlMappingRegistrations = urlMappingRegistrations.getSize(); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp got %d UrlMapping Contacts", mLogName.data(), numUrlMappingRegistrations); if (numUrlMappingRegistrations > 0) { for (int i = 0; i < numUrlMappingRegistrations; i++) { UtlHashMap record; urlMappingRegistrations.getIndex(i, record); UtlString contactKey("contact"); UtlString contact= *(dynamic_cast <UtlString*> (record.findValue(&contactKey))); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp contact = '%s'", mLogName.data(), contact.data()); Url contactUri(contact); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp contactUri = '%s'", mLogName.data(), contactUri.toString().data()); // We no longer check for recursive loops here because we // have comprehensive loop detection in the proxy. UtlString recordRoute; UtlString curCallDest; if (message.getRecordRouteField(0,&recordRoute)) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp RecordRouteField = '%s'", mLogName.data(), recordRoute.data()); } contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, callTag.data()); // Add the contact. contactList.add( contactUri, *this ); } } } return RedirectPlugin::SUCCESS; }
UtlBoolean SubscribeServerThread::isAuthorized ( const SipMessage* message, SipMessage *responseMessage, StatusPluginReference* pluginContainer) { UtlBoolean retIsAuthorized = FALSE; UtlString requestUser; Url identityUrl; message->getUri(NULL, NULL, NULL, &requestUser); identityUrl.setUserId(requestUser); identityUrl.setHostAddress(mDefaultDomain); EntityDB* entityDb = StatusServer::getInstance()->getEntityDb(); if( pluginContainer ) { // if the plugin has permissions, we must match all these against the IMDB if( pluginContainer->hasPermissions() ) { // permission required. Check for required permission in permission IMDB // All required permissions should match EntityRecord entity; entityDb->findByIdentity(identityUrl, entity); std::set<std::string> permissions = entity.permissions(); int numDBPermissions = permissions.size(); if( numDBPermissions > 0 ) { UtlBoolean nextPermissionMatched = TRUE; UtlSListIterator* pluginPermissionIterator = pluginContainer->permissionsIterator(); UtlString* pluginPermission; // Iterated through the plugin permissions matching // them one by one against the IMDB while( (pluginPermission = (UtlString*)(*pluginPermissionIterator)()) && nextPermissionMatched ) { //check againt all permissions in IMDB nextPermissionMatched = FALSE; UtlString identity, permission; for ( std::set<std::string>::iterator iter = permissions.begin(); iter != permissions.end(); iter++ ) { permission = iter->c_str(); if (pluginPermission->compareTo(permission, UtlString::ignoreCase ) == 0) { nextPermissionMatched = TRUE; break; } } } delete pluginPermissionIterator; // after going thru all permissions find out if all matched or not if( nextPermissionMatched ) { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthorized() -" " All permissions matched - request is AUTHORIZED"); retIsAuthorized = TRUE; } else { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthorized() -" " One or more Permissions did not match - request is UNAUTHORIZED"); retIsAuthorized = FALSE; } } else { // one or more permissions needed by plugin and none in IMDB => UNAUTHORIZED Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthorized() -" " No Permissions in IMDB - request is UNAUTHORIZED"); retIsAuthorized = FALSE; } } else { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthorized() -" " No Permissions required - request is always AUTHORIZED"); retIsAuthorized = TRUE; } } //set the error response message id unauthorized if(!retIsAuthorized) { responseMessage->setResponseData(message,SIP_FORBIDDEN_CODE, SIP_FORBIDDEN_TEXT); } return retIsAuthorized; }