// Test that permissions of authIdentity are taken into consideration void testAuthIdentity() { UtlString identity("*****@*****.**"); // has only 'fishing' permission Url okRequestUri("sip:user@boat"); UtlSList noRemovedRoutes; UtlString rejectReason; const char* okMessage = "INVITE sip:user@boat SIP/2.0\r\n" // 'lodge' requires 'hunting' permission "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n" "To: sip:user@boat\r\n" "From: Caller <sip:[email protected]>; tag=30543f3483e1cb11ecb40866edd3295b\r\n" "Call-Id: exception-1\r\n" "Cseq: 2 INVITE\r\n" "Max-Forwards: 20\r\n" "Contact: [email protected]\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage okMsg(okMessage, strlen(okMessage)); UtlString routeName("example.com"); RouteState okRouteState( okMsg, noRemovedRoutes, routeName ); UtlString method("INVITE"); const bool bSpiralingRequest = false; AuthPlugin::AuthResult priorResult = AuthPlugin::CONTINUE; // confirm that supercaster can call boat CPPUNIT_ASSERT(AuthPlugin::ALLOW == enforcer->authorizeAndModify(identity, okRequestUri, okRouteState, method, priorResult, okMsg, bSpiralingRequest, rejectReason )); CPPUNIT_ASSERT(rejectReason.isNull()); okRouteState.update(&okMsg); UtlString recordRoute; CPPUNIT_ASSERT(okMsg.getRecordRouteField(0, &recordRoute)); ASSERT_STR_EQUAL( "<sip:example.com;lr;sipXecs-rs=enforce%2Aauth%7E%210083f7f42bdf4998911a18d41fb3aa01>", recordRoute ); // now try the same request, but mightyhunter as authIdentity // so this time it should NOT work // Modify the identity to mightyhunter and verify that he can't call boat const char* notOkMessage = "INVITE sip:user@boat SIP/2.0\r\n" // 'lodge' requires 'hunting' permission "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n" "To: sip:user@boat\r\n" "From: Caller <sip:[email protected]>; tag=30543f3483e1cb11ecb40866edd3295b\r\n" "Call-Id: exception-1\r\n" "Cseq: 2 INVITE\r\n" "Max-Forwards: 20\r\n" "Contact: [email protected]\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage notOkMsg( notOkMessage, strlen(notOkMessage)); SipXauthIdentity authIdentity; authIdentity.setIdentity("*****@*****.**"); authIdentity.insert(notOkMsg, SipXauthIdentity::AuthIdentityHeaderName); rejectReason.remove(0); // confirm that mightyhunter can't call boat CPPUNIT_ASSERT(AuthPlugin::DENY == enforcer->authorizeAndModify(identity, okRequestUri, okRouteState, method, priorResult, notOkMsg, bSpiralingRequest, rejectReason )); CPPUNIT_ASSERT(!rejectReason.compareTo("Requires fishing")); // check that the authidentity is still present SipXauthIdentity testIdentity(notOkMsg, SipXauthIdentity::AuthIdentityHeaderName); UtlString testIdentityString; CPPUNIT_ASSERT(testIdentity.getIdentity(testIdentityString)); ASSERT_STR_EQUAL(testIdentityString, "*****@*****.**"); const char* noprivMessage = "INVITE sip:user@lodge SIP/2.0\r\n" // 'lodge' requires 'hunting' permission "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n" "To: sip:user@lodge\r\n" "From: Caller <sip:[email protected]>; tag=30543f3483e1cb11ecb40866edd3295b\r\n" "Call-Id: exception-2\r\n" "Cseq: 2 INVITE\r\n" "Max-Forwards: 20\r\n" "Contact: [email protected]\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage noprivMsg(noprivMessage, strlen(noprivMessage)); RouteState noprivRouteState( noprivMsg, noRemovedRoutes, routeName ); Url noprivRequestUri("sip:user@lodge"); rejectReason.remove(0); // confirm that supercaster cannot call lodge CPPUNIT_ASSERT(AuthPlugin::DENY == enforcer->authorizeAndModify(identity, noprivRequestUri, noprivRouteState, method, priorResult, noprivMsg, bSpiralingRequest, rejectReason )); ASSERT_STR_EQUAL("Requires hunting", rejectReason.data()); // now try the same request, but mightyhunter as authIdentity // so this time it should work const char* allowedMessage = "INVITE sip:allowed@lodge SIP/2.0\r\n" // 'lodge' requires 'hunting' permission "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n" "To: sip:allowed@lodge\r\n" "From: Caller <sip:[email protected]>; tag=30543f3483e1cb11ecb40866edd3295b\r\n" "Call-Id: exception-3\r\n" "Cseq: 2 INVITE\r\n" "Max-Forwards: 20\r\n" "Contact: [email protected]\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage allowedMsg(allowedMessage, strlen(allowedMessage)); RouteState allowedRouteState( allowedMsg, noRemovedRoutes, routeName ); rejectReason.remove(0); authIdentity.insert(allowedMsg, SipXauthIdentity::AuthIdentityHeaderName); CPPUNIT_ASSERT(AuthPlugin::ALLOW == enforcer->authorizeAndModify(identity, noprivRequestUri, allowedRouteState, method, priorResult, allowedMsg, bSpiralingRequest, rejectReason )); CPPUNIT_ASSERT(rejectReason.isNull()); // check that the authidentity is still present SipXauthIdentity testIdentity1(notOkMsg, SipXauthIdentity::AuthIdentityHeaderName); CPPUNIT_ASSERT(testIdentity1.getIdentity(testIdentityString)); ASSERT_STR_EQUAL(testIdentityString, "*****@*****.**"); allowedRouteState.update(&allowedMsg); CPPUNIT_ASSERT(allowedMsg.getRecordRouteField(0, &recordRoute)); ASSERT_STR_EQUAL( "<sip:example.com;lr;sipXecs-rs=enforce%2Aauth%7E%2175da650843a06eee569f3c93b0f94ee5>", recordRoute ); // check that invalid authidentity can not help bypass permissions rejectReason.remove(0); // invalid authidentity - Call-ID does not match allowedMsg.addHeaderField("X-Sipx-Authidentity", "<sip:[email protected];signature=46A66059%3Ab1b86dffc2e38191cdfad0500bf9a209>"); CPPUNIT_ASSERT(AuthPlugin::DENY == enforcer->authorizeAndModify(identity, noprivRequestUri, allowedRouteState, method, priorResult, allowedMsg, bSpiralingRequest, rejectReason )); ASSERT_STR_EQUAL("Requires hunting", rejectReason.data()); }