OsStatus SipRedirectorFallback::determineCallerLocationFromProvisionedUserLocation( const SipMessage& message, UtlString& callerLocation ) { OsStatus result = OS_FAILED; callerLocation.remove( 0 ); // First, determine the identity of the caller. This is done by looking for // a properly signed P-Asserted identity in the request message. // If the request contains a P-Asserted-Identity header and is not signed, // we will not trust it the returned location will be blank. UtlString matchedIdentityHeader; SipXauthIdentity sipxIdentity; Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRedirectorFallback:: unbound entities allowing: %s", mAllowUnbound ? "TRUE" : "FALSE"); if (!mAllowUnbound) { SipXauthIdentity sipxIdentity( message, matchedIdentityHeader, false ); } else { SipXauthIdentity sipxIdentity( message, matchedIdentityHeader, false, SipXauthIdentity::allowUnbound); } if( !matchedIdentityHeader.isNull() ) { UtlString authenticatedUserIdentity; bool bRequestIsAuthenticated; bRequestIsAuthenticated = sipxIdentity.getIdentity( authenticatedUserIdentity ); if( bRequestIsAuthenticated ) { // we now have the autheticated identity of the caller. Look up the user location // database to find out the location that is mapped to it. //ResultSet userLocationsResult; // Check in User Location database if user has locations //mpUserLocationDbInstance->getLocations( authenticatedUserIdentity, userLocationsResult ); // Get the caller's site location. Only the first returned location is used. // This is not a problem given that a user should only belong to one location. EntityRecord entity; EntityDB* entityDb = SipRegistrar::getInstance(NULL)->getEntityDB(); if (entityDb->findByIdentity(authenticatedUserIdentity.str(), entity)) { callerLocation = entity.location().c_str(); result = OS_SUCCESS; Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::determineCallerLocationFromProvisionedUserLocation mapped user '%s' taken from header '%s' to location '%s' based on its provisioned location", mLogName.data(), authenticatedUserIdentity.data(), authenticatedUserIdentity.data(), entity.location().c_str() ); } } } return result; }
// Get and add the credentials for sipXregistrar SipLineMgr* SipRedirectorJoin::addCredentials (UtlString domain, UtlString realm) { SipLine* line = NULL; SipLineMgr* lineMgr = NULL; UtlString user; Url identity; identity.setUserId(REGISTRAR_ID_TOKEN); identity.setHostAddress(domain); UtlString ha1_authenticator; UtlString authtype; bool bSuccess = false; EntityDB* entityDb = SipRegistrar::getInstance(NULL)->getEntityDB(); if (entityDb->getCredential(identity, realm, user, ha1_authenticator, authtype)) { if ((line = new SipLine( identity // user entered url ,identity // identity url ,user // user ,TRUE // visible ,SipLine::LINE_STATE_PROVISIONED ,TRUE // auto enable ,FALSE // use call handling ))) { if ((lineMgr = new SipLineMgr())) { if (lineMgr->addLine(*line)) { if (lineMgr->addCredentialForLine( identity, realm, user, ha1_authenticator ,HTTP_DIGEST_AUTHENTICATION ) ) { lineMgr->setDefaultOutboundLine(identity); bSuccess = true; Os::Logger::instance().log(FAC_SIP, PRI_INFO, "Added identity '%s': user='******' realm='%s'" ,identity.toString().data(), user.data(), realm.data() ); } else { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "Error adding identity '%s': user='******' realm='%s'\n" "Call Join feature will not work!", identity.toString().data(), user.data(), realm.data() ); } } else { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "addLine failed. Call Join feature will not work!" ); } } else { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "Constructing SipLineMgr failed. Call Join feature will not work!" ); } } else { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "Constructing SipLine failed. Call Join feature will not work!" ); } } else { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "No credential found for '%s' in realm '%s'. " "Call Join feature will not work!" ,identity.toString().data(), realm.data() ); } if( !bSuccess ) { delete line; line = NULL; delete lineMgr; lineMgr = NULL; } return lineMgr; }
RedirectPlugin::LookUpStatus SipRedirectorAliasDB::lookUp( const SipMessage& message, UtlString& requestString, Url& requestUri, const UtlString& method, ContactList& contactList, RequestSeqNo requestSeqNo, int redirectorNo, SipRedirectorPrivateStorage*& privateStorage, ErrorDescriptor& errorDescriptor) { // If url param sipx-userforward = false, do not redirect to user-forward // aliases. UtlString userforwardParam; requestUri.getUrlParameter("sipx-userforward", userforwardParam); bool disableForwarding = userforwardParam.compareTo("false", UtlString::ignoreCase) == 0; if (disableForwarding) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp user forwarding disabled by parameter", mLogName.data()); } if (_enableEarlyAliasResolution) { resolveAlias(message, requestString, requestUri); } UtlString requestIdentity; requestUri.getIdentity(requestIdentity); EntityDB::Aliases aliases; bool isUserIdentity = false; EntityDB* entityDb = SipRegistrar::getInstance(NULL)->getEntityDB(); entityDb->getAliasContacts(requestUri, aliases, isUserIdentity); int numAliasContacts = aliases.size(); if (numAliasContacts > 0) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp " "got %d AliasDB contacts", mLogName.data(), numAliasContacts); // Check if the request identity is a real user/extension UtlString realm; UtlString authType; SipXauthIdentity authIdentity; authIdentity.setIdentity(requestIdentity); for (EntityDB::Aliases::iterator iter = aliases.begin(); iter != aliases.end(); iter++) { // If disableForwarding and the relation value is "userforward", // do not record this contact. if (!(disableForwarding && iter->relation == ALIASDB_RELATION_USERFORWARD)) { UtlString contact = iter->contact.c_str(); Url contactUri(contact); // if the request identity is a real user if (isUserIdentity) { // Encode AuthIdentity into the URI authIdentity.encodeUri(contactUri, message); } contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, "AL"); contactList.add( contactUri, *this ); if (_enableDiversionHeader && contactList.getDiversionHeader().empty()) { // // Add a Diversion header for all deflections // UtlString stringUri; message.getRequestUri(&stringUri); // The requestUri is an addr-spec, not a name-addr. Url diversionUri(stringUri, TRUE); UtlString userId; diversionUri.getUserId(userId); UtlString host; diversionUri.getHostWithPort(host); std::ostringstream strm; strm << "<sip:"; if (!userId.isNull()) strm << userId.data() << "@"; strm << host.data(); strm << ">;reason=unconditional;sipxfwd=" << iter->relation; UtlString diversion = strm.str().c_str(); OS_LOG_INFO(FAC_SIP, "SipRedirectorAliasDB::lookUp inserting diversion from " << diversion.data()); contactList.setDiversionHeader(diversion.data()); } } } } return RedirectPlugin::SUCCESS; }
bool SipRedirectorAliasDB::resolveAlias( const SipMessage& message, UtlString& requestString, Url& requestUri ) { bool isDomainAlias = false; bool isUserAlias = false; UtlString domain; UtlString hostAlias; UtlString userAlias; requestUri.getHostAddress(domain); UtlBoolean isMyHostAlias = mpSipUserAgent->isMyHostAlias(requestUri); if (mpSipUserAgent && domain != _localDomain && isMyHostAlias) { isDomainAlias = true; hostAlias = domain; } UtlString requestIdentity; requestUri.getIdentity(requestIdentity); EntityDB::Aliases aliases; bool isUserIdentity = false; EntityDB* entityDb = SipRegistrar::getInstance(NULL)->getEntityDB(); entityDb->getAliasContacts(requestUri, aliases, isUserIdentity); int numAliasContacts = aliases.size(); EntityDB::Aliases::iterator iter = aliases.begin(); if (numAliasContacts == 1 && iter != aliases.end()) { // If disableForwarding and the relation value is "userforward", // do not record this contact. if (isUserIdentity && iter->relation != ALIASDB_RELATION_USERFORWARD && iter->relation != "callgroup") { UtlString contact = iter->contact.c_str(); Url contactUri(contact); isUserAlias = true; contactUri.getUserId(userAlias); } } if (isUserAlias) { requestUri.setUserId(userAlias.data()); requestUri.getUri(requestString); } if (isDomainAlias) { requestUri.setHostAddress(hostAlias); requestUri.getUri(requestString); } if (isUserAlias || isDomainAlias) { OS_LOG_NOTICE(FAC_SIP, "SipRedirectorAliasDB::lookUp normalized request-uri to " << requestString.data()); } return isUserAlias || isDomainAlias; }
RedirectPlugin::LookUpStatus SipRedirectorRegDB::lookUp( const SipMessage& message, UtlString& requestString, Url& requestUri, const UtlString& method, ContactList& contactList, RequestSeqNo requestSeqNo, int redirectorNo, SipRedirectorPrivateStorage*& privateStorage, ErrorDescriptor& errorDescriptor) { unsigned long timeNow = OsDateTime::getSecsSinceEpoch(); // Local copy of requestUri Url requestUriCopy = requestUri; // Look for any grid parameter and remove it. UtlString gridParameter; UtlBoolean gridPresent = requestUriCopy.getUrlParameter("grid", gridParameter, 0); if (gridPresent) { requestUriCopy.removeUrlParameter("grid"); } if (Os::Logger::instance().willLog(FAC_SIP, PRI_DEBUG)) { UtlString temp; requestUriCopy.getUri(temp); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp gridPresent = %d, gridParameter = '%s', " "requestUriCopy after removing grid = '%s'", mLogName.data(), gridPresent, gridParameter.data(), temp.data()); } RegDB::Bindings registrations; // Give the ~~in~ URIs separate processing. UtlString user; requestUriCopy.getUserId(user); RegDB* regDb = SipRegistrar::getInstance(NULL)->getRegDB(); if (user.index(URI_IN_PREFIX) == 0) { // This is a ~~in~ URI. // Check for an '&' separator. ssize_t s = user.last('&'); if (s != UTL_NOT_FOUND) { // This is a ~~in~[user]&[instrument] URI. const char* instrumentp = user.data() + s + 1; UtlString u; u.append(user, sizeof (URI_IN_PREFIX) - 1, s - (sizeof (URI_IN_PREFIX) - 1)); requestUriCopy.setUserId(u); //regDB-> // getUnexpiredContactsUserInstrument(requestUriCopy, instrumentp, timeNow, registrations); UtlString identity; requestUriCopy.getIdentity(identity); regDb->getUnexpiredContactsUserInstrument(identity.str(), instrumentp, timeNow, registrations); } else { // This is a ~~in~[instrument] URI. const char* instrumentp = user.data() + sizeof (URI_IN_PREFIX) - 1; regDb->getUnexpiredContactsInstrument(instrumentp, timeNow, registrations); } } else { // Note that getUnexpiredContactsUser will reduce the requestUri to its // identity (user/host/port) part before searching in the // database. The requestUri identity is matched against the // "identity" column of the database, which is the identity part of // the "uri" column which is stored in registration.xml. UtlString identity; requestUriCopy.getIdentity(identity); regDb->getUnexpiredContactsUser(identity.str(), timeNow, registrations); } int numUnexpiredContacts = registrations.size(); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp got %d unexpired contacts", mLogName.data(), numUnexpiredContacts); // Check for a per-user call forward timer. // Don't set timer if we're not going to forward to voicemail. std::ostringstream userCfwdTimer; bool foundUserCfwdTimer = false; if (method.compareTo(SIP_INVITE_METHOD) == 0) { UtlString noRoute; requestUriCopy.getUrlParameter("sipx-noroute", noRoute); if ((!noRoute.isNull()) && (noRoute.compareTo("Voicemail") == 0)) { // This is not a call scenerio controlled by this users "forward to voicemail" timer } else { UtlString identity; requestUriCopy.getIdentity(identity); EntityRecord entity; EntityDB* entityDb = SipRegistrar::getInstance(NULL)->getEntityDB(); foundUserCfwdTimer = entityDb->findByIdentity(identity.str(), entity); if (foundUserCfwdTimer) userCfwdTimer << entity.callForwardTime(); } } for (RegDB::Bindings::const_iterator iter = registrations.begin(); iter != registrations.end(); iter++) { // Query the Registration DB for the contact, expires and qvalue columns. Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp contact = '%s', qvalue = '%s', path = '%s'", mLogName.data(), iter->getContact().c_str(), iter->getQvalue().c_str(), iter->getPath().c_str() ); Url contactUri(iter->getContact().c_str()); // If available set the per-user call forward timer. if (foundUserCfwdTimer) { contactUri.setHeaderParameter("expires", userCfwdTimer.str().c_str()); } // If the contact URI is the same as the request URI, ignore it. if (!contactUri.isUserHostPortEqual(requestUriCopy)) { // Check if the q-value from the database is valid, and if so, // add it into contactUri. if (!iter->getQvalue().empty()) { // :TODO: (XPL-3) need a RegEx copy constructor here // Check if q value is numeric and between the range 0.0 and 1.0. static RegEx qValueValid("^(0(\\.\\d{0,3})?|1(\\.0{0,3})?)$"); if (qValueValid.Search(iter->getQvalue().c_str())) { contactUri.setFieldParameter(SIP_Q_FIELD, iter->getQvalue().c_str()); } } // Re-apply any grid parameter. if (gridPresent) { contactUri.setUrlParameter("grid", gridParameter); } contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, "INT"); // Check if database contained a Path value. If so, add a Route // header parameter to the contact with the Path vector taken from // the registration data. if (!iter->getPath().empty()) { UtlString existingRouteValue; std::string pathVector = iter->getPath(); if ( contactUri.getHeaderParameter(SIP_ROUTE_FIELD, existingRouteValue)) { // there is already a Route header parameter in the contact; append it to the // Route derived from the Path vector. pathVector += SIP_MULTIFIELD_SEPARATOR; pathVector += existingRouteValue.str(); } contactUri.setHeaderParameter(SIP_ROUTE_FIELD, pathVector.c_str()); } // Add the contact. contactList.add( contactUri, *this ); } } return RedirectPlugin::SUCCESS; }
RedirectPlugin::LookUpStatus SipRedirectorAliasDB::lookUp( const SipMessage& message, UtlString& requestString, Url& requestUri, const UtlString& method, ContactList& contactList, RequestSeqNo requestSeqNo, int redirectorNo, SipRedirectorPrivateStorage*& privateStorage, ErrorDescriptor& errorDescriptor) { // If url param sipx-userforward = false, do not redirect to user-forward // aliases. UtlString userforwardParam; requestUri.getUrlParameter("sipx-userforward", userforwardParam); bool disableForwarding = userforwardParam.compareTo("false", UtlString::ignoreCase) == 0; if (disableForwarding) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp user forwarding disabled by parameter", mLogName.data()); } bool isDomainAlias = false; UtlString domain; UtlString hostAlias; requestUri.getHostAddress(domain); UtlBoolean isMyHostAlias = mpSipUserAgent->isMyHostAlias(requestUri); if (mpSipUserAgent && domain != _localDomain && isMyHostAlias) { isDomainAlias = true; hostAlias = domain; requestUri.setHostAddress(_localDomain); } UtlString requestIdentity; requestUri.getIdentity(requestIdentity); OS_LOG_DEBUG(FAC_SIP, mLogName.data() << "::lookUp identity: " << requestIdentity.data() << " domain: " << domain.data() << " local-domain: " << _localDomain.data() << " isHostAlias: " << isMyHostAlias); //ResultSet aliases; //AliasDB::getInstance()->getContacts(requestUri, aliases); //int numAliasContacts = aliases.getSize(); EntityDB::Aliases aliases; bool isUserIdentity = false; EntityDB* entityDb = SipRegistrar::getInstance(NULL)->getEntityDB(); entityDb->getAliasContacts(requestUri, aliases, isUserIdentity); int numAliasContacts = aliases.size(); if (numAliasContacts > 0) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp " "got %d AliasDB contacts", mLogName.data(), numAliasContacts); // Check if the request identity is a real user/extension UtlString realm; UtlString authType; SipXauthIdentity authIdentity; authIdentity.setIdentity(requestIdentity); for (EntityDB::Aliases::iterator iter = aliases.begin(); iter != aliases.end(); iter++) { // If disableForwarding and the relation value is "userforward", // do not record this contact. if (!(disableForwarding && iter->relation == ALIASDB_RELATION_USERFORWARD)) { UtlString contact = iter->contact.c_str(); Url contactUri(contact); // if the request identity is a real user if (isUserIdentity) { // Encode AuthIdentity into the URI authIdentity.encodeUri(contactUri, message); } contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, "AL"); if (numAliasContacts == 1 && isDomainAlias && isUserIdentity) { UtlString userId; contactUri.getUserId(userId); requestUri.setUserId(userId.data()); requestUri.getUri(requestString); OS_LOG_NOTICE(FAC_SIP, "SipRedirectorAliasDB::lookUp normalized request-uri to " << requestString.data()); } else { // Add the contact. contactList.add( contactUri, *this ); } } } } else if (isDomainAlias) { // // No alias found. If this is was towards a domain alias, make sure to reset it back to // the old value prior to feeding it to the rest of the redirectors. // requestUri.setHostAddress(hostAlias); requestUri.getUri(requestString); } return RedirectPlugin::SUCCESS; }
UtlBoolean SubscribeServerThread::isAuthenticated (const SipMessage* message, SipMessage *responseMessage, UtlString& authenticatedUser, UtlString& authenticatedRealm ) { UtlBoolean retIsAuthenticated = FALSE; // if we are not using a database we must assume authenticated if ( !mIsCredentialDB ) { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthenticated() " ":: No Credential DB - request is always AUTHENTICATED"); retIsAuthenticated = TRUE; } else { // realm and auth type should be default for server // if URI not defined in DB, the user is not authorized to modify bindings - Os::Logger::instance().log( FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthenticated():TRUE realm=\"%s\" ", mRealm.data()); UtlString requestNonce; UtlString requestCnonce; UtlString requestNonceCount; UtlString requestQop; UtlString requestRealm; UtlString requestUser; UtlString requestUserBase; UtlString requestUriParam; int requestAuthIndex = 0; EntityDB* entityDb = StatusServer::getInstance()->getEntityDb(); // can have multiple authorization / authorization-proxy headers // headers search for a realm match while ( message->getDigestAuthorizationData ( &requestUser, &requestRealm, &requestNonce, NULL, // opaque NULL, // response &requestUriParam, &requestCnonce, &requestNonceCount, &requestQop, HttpMessage::SERVER, requestAuthIndex, &requestUserBase) ) { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthenticated() " "- Authorization header set in message, validate it.\n" "- reqRealm=\"%s\", reqUser=\"%s\", reqUserBase=\"%s\"", requestRealm.data(), requestUser.data(), requestUserBase.data()); UtlString qopType; UtlString callId; UtlString fromTag; long nonceExpires = (5*60); // five minutes Url fromUrl; message->getFromUrl(fromUrl); fromUrl.getFieldParameter("tag", fromTag); UtlString reqUri; message->getRequestUri(&reqUri); Url mailboxUrl(reqUri); message->getCallIdField(&callId); if (mRealm.compareTo(requestRealm) ) // case sensitive check that realm is correct { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthenticated() " "Realm does not match"); } // See if the nonce is valid - see net/SipNonceDb.cpp else if (!mNonceDb.isNonceValid(requestNonce, callId, fromTag, mRealm, nonceExpires)) { Os::Logger::instance().log(FAC_AUTH, PRI_INFO, "SubscribeServerThread::isAuthenticated() " "Invalid NONCE: '%s' found for mailboxUrl '%s' " "realm: '%s' user: '******' " "cnonce: '%s' nc: '%s' qop: '%s' " "expiration: %ld", requestNonce.data(), mailboxUrl.toString().data(), mRealm.data(), requestUser.data(), requestCnonce.data(), requestNonceCount.data(), requestQop.data(), nonceExpires); } // verify that qop,cnonce, nonceCount are compatible else if (message->verifyQopConsistency(requestCnonce.data(), requestNonceCount.data(), &requestQop, qopType) >= HttpMessage::AUTH_QOP_NOT_SUPPORTED) { Os::Logger::instance().log(FAC_AUTH, PRI_INFO, "SubscribeServerThread::isAuthenticated() " "Invalid combination of QOP('%s'), cnonce('%s') and nonceCount('%s')", requestQop.data(), requestCnonce.data(), requestNonceCount.data()); } else // realm, nonce and qop are all ok { UtlString authTypeDB; UtlString passTokenDB; // then get the credentials for this realm if (entityDb->getCredential(mailboxUrl, mRealm, requestUserBase, passTokenDB, authTypeDB)) { // the Digest Password is calculated from the request // user, passtoken, nonce and request URI retIsAuthenticated = message->verifyMd5Authorization(requestUser.data(), passTokenDB.data(), requestNonce.data(), requestRealm.data(), requestCnonce.data(), requestNonceCount.data(), requestQop.data(), requestUriParam.data()); if (retIsAuthenticated) { // can have multiple credentials for same realm so only break out // when we have a positive match Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthenticated() " "- request is AUTHENTICATED"); // copy the authenticated user/realm for subsequent authorization authenticatedUser = requestUserBase; authenticatedRealm = requestRealm; break; } else { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthenticated() " "- digest authorization failed " "nonce \"%s\", cnonce \"%s\" for " "mailboxUrl=\"%s\", reqRealm=\"%s\", reqUser=\"%s\"", requestNonce.data(), requestCnonce.data(), mailboxUrl.toString().data(), requestRealm.data(), requestUser.data()); } } else { Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthenticated() " "- No Credentials for mailboxUrl=\"%s\", reqRealm=\"%s\", reqUser=\"%s\"", mailboxUrl.toString().data(), requestRealm.data(), requestUser.data()); } // end check credentials } requestAuthIndex++; } //end while if ( !retIsAuthenticated ) { // Generate the 401 Unauthorized response to challenge for credentials // Use the SipNonceDB to generate a nonce UtlString newNonce; UtlString callId; UtlString fromTag; Url fromUrl; message->getFromUrl(fromUrl); fromUrl.getFieldParameter("tag", fromTag); message->getCallIdField(&callId); mNonceDb.createNewNonce(callId, fromTag, mRealm, newNonce); responseMessage->setRequestUnauthorized(message, HTTP_DIGEST_AUTHENTICATION, mRealm, newNonce); } } // end DB exists return retIsAuthenticated; }
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; }