Exemple #1
0
   void getOneRowByLocationCodeTest()
   {
      SipDbTestContext sipDbTestContext(TEST_DATA_DIR "/locationdata",
                                        TEST_WORK_DIR "/locationdata"
                                                 );
      sipDbTestContext.inputFile("dummy_loc_db.xml" );
      
      LocationDB* pLocDb = LocationDB::getInstance("dummy_loc_db");
      UtlHashMap hashmap;
      CPPUNIT_ASSERT( !pLocDb->getRowByLocationCode( "5144", hashmap ) );
      CPPUNIT_ASSERT( pLocDb->getRowByLocationCode( "514", hashmap ) );
      CPPUNIT_ASSERT( hashmap.entries() == 4 );

      UtlString* pTempString;
      UtlString key;
      key = "name";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Montreal", pTempString->data() );
      
      key = "description";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Go Habs Go!", pTempString->data() );
      
      key = "locationcode";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "514", pTempString->data() );

      key = "subnets";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "10.10.10.0/24,11.11.11.0/24,12.12.12.0/24", pTempString->data() );
   }
Exemple #2
0
UtlBoolean
ExtensionDB::insertRow (const UtlHashMap& nvPairs) 
{
    // Note we do not need the identity object here
    // as it is inferred from the uri
    return insertRow (
        Url( *((UtlString*)nvPairs.findValue(&gUriKey)) ),
        *((UtlString*)nvPairs.findValue(&gExtensionKey)) );
}
Exemple #3
0
UtlBoolean
AliasDB::insertRow (const UtlHashMap& nvPairs)
{
    // Note we do not need the identity object here
    // as it is inferred from the uri
    UtlString identity, contact;
    identity = *((UtlString*)nvPairs.findValue(&gIdentityKey));
    contact = *((UtlString*)nvPairs.findValue(&gContactKey));
    return insertRow ( Url( identity ), Url( contact ) );
}
Exemple #4
0
UtlBoolean
CredentialDB::insertRow (const UtlHashMap& nvPairs)
{
    // Note: identity inferred from the uri
    return insertRow (
        Url (*((UtlString*)nvPairs.findValue(&gUriKey))),
        *((UtlString*)nvPairs.findValue(&gRealmKey)),
        *((UtlString*)nvPairs.findValue(&gUseridKey)),
        *((UtlString*)nvPairs.findValue(&gPasstokenKey)),
        *((UtlString*)nvPairs.findValue(&gPintokenKey)),
        *((UtlString*)nvPairs.findValue(&gAuthtypeKey)));
}
Exemple #5
0
   void getOneRowByNameTest()
   {
      SipDbTestContext sipDbTestContext(TEST_DATA_DIR "/locationdata",
                                        TEST_WORK_DIR "/locationdata"
                                                 );
      sipDbTestContext.inputFile("dummy_loc_db.xml" );
      
      LocationDB* pLocDb = LocationDB::getInstance("dummy_loc_db");
      UtlHashMap hashmap;
      CPPUNIT_ASSERT( !pLocDb->getRowByName( "Washington", hashmap ) );
      CPPUNIT_ASSERT( pLocDb->getRowByName( "Ottawa", hashmap ) );
      CPPUNIT_ASSERT( hashmap.entries() == 4 );

      UtlString* pTempString;
      UtlString key;
      key = "name";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Ottawa", pTempString->data() );
      
      key = "description";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "One crazy location", pTempString->data() );
      
      key = "locationcode";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "613", pTempString->data() );

      key = "subnets";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "172.30.0.0/16,22.22.22.22/32", pTempString->data() );

      // get a second location row
      CPPUNIT_ASSERT( pLocDb->getRowByName( "Quebec", hashmap ) );
      CPPUNIT_ASSERT( hashmap.entries() == 4 );

      key = "name";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Quebec", pTempString->data() );
      
      key = "description";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Happy 400th anniversary", pTempString->data() );
      
      key = "locationcode";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "418", pTempString->data() );

      key = "subnets";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( SPECIAL_IMDB_NULL_VALUE, pTempString->data() );
   }
Exemple #6
0
UtlBoolean
DialByNameDB::insertRow ( const UtlHashMap& nvPairs ) const
{
    // Note we do not need the identity object here
    // as it is inferred from the uri
    return insertRow (
        Url( *((UtlString*)nvPairs.findValue(&gNp_contactKey)) ) );
}
Exemple #7
0
void
RegistrationDB::insertRow(const UtlHashMap& nvPairs)
{
    // For integer values, default to 0 if the datum is missing in the input.

    UtlString* expStr = (UtlString*) nvPairs.findValue(&gExpiresKey);
    UtlString* cseqStr = (UtlString*) nvPairs.findValue(&gCseqKey);

    // If the IMDB does not specify a Q-Value, "%" will be found here
    // (representing a null IMDB column).
    UtlString* qvalue = (UtlString*) nvPairs.findValue(&gQvalueKey);

    UtlString* updateNumberStr = (UtlString*) nvPairs.findValue(&gUpdateNumberKey);
    // Note that updateNumberStr is likely to start with 0x, so we
    // need the full functionality of strtoll here, not just a
    // decimal-to-binary conversion.  But strtoll is in C99, so it
    // should be OK.
    Int64 updateNumber = 
       updateNumberStr ? strtoll(updateNumberStr->data(), NULL, 0) : 0;

    // Get the remaining fields so that we can substitute the null string
    // if the fetched value is 0 (the null pointer) because the field
    // is not present in the disk file.
    UtlString* contact = (UtlString*) nvPairs.findValue(&gContactKey);
    UtlString* callId = (UtlString*) nvPairs.findValue(&gCallidKey);
    UtlString* instanceId = (UtlString*) nvPairs.findValue(&gInstanceIdKey);
    UtlString* gruu = (UtlString*) nvPairs.findValue(&gGruuKey);
    UtlString* path = (UtlString*) nvPairs.findValue(&gPathKey);
    UtlString* primary = (UtlString*) nvPairs.findValue(&gPrimaryKey);

    // Note: identity inferred from the uri
    updateBinding(
       Url(*((UtlString*)nvPairs.findValue(&gUriKey))),
       contact ? *contact : nullString,
       qvalue ? *qvalue : percent,
       callId ? *callId : nullString,
       cseqStr ? atoi(cseqStr->data()) : 0,
       expStr ? atoi(expStr->data()) : 0,
       instanceId ? *instanceId : nullString,
       gruu ? *gruu : nullString,
       path ? *path : nullString,
       primary ? *primary : nullString,
       updateNumber
       );
}
Exemple #8
0
UtlBoolean
UserForwardDB::insertRow (const UtlHashMap& nvPairs) 
{
    // Note we do not need the identity object here
    // as it is inferred from the uri
    UtlString identity, cfwdtime;
    identity = *(dynamic_cast <UtlString*> (nvPairs.findValue(&gIdentityKey)));
    cfwdtime = *(dynamic_cast <UtlString*> (nvPairs.findValue(&gCfwdtimeKey)));
    return insertRow ( Url( identity ), cfwdtime );
}
 void getResult( ResultSet& resultSet
                ,int         index
                ,const char* key
                ,UtlString&  result
                )
 {
    UtlHashMap hash;
    resultSet.getIndex( index, hash );
    UtlString theKey(key);
    result = *((UtlString*)hash.findValue(&theKey));
 }
Exemple #10
0
void requestGet(Url& url, UtlSList& names)
{
    XmlRpcRequest* request;
    XmlRpcResponse response;
    
    request = new XmlRpcRequest(url, "configurationParameter.get");
    request->addParam(&DataSet);        

    if (!names.isEmpty())
    {
        request->addParam(&names);
    }
      
    if (!request->execute(response/*, &pSocket*/))
    {
        exitFault(response);
    }
    else
    {
        UtlContainable* value;
        if (response.getResponse(value))
        {
            UtlHashMap* paramList = dynamic_cast<UtlHashMap*>(value);
            if (paramList)
            {
                UtlHashMapIterator params(*paramList);
                UtlString* name;
                while ((name = dynamic_cast<UtlString*>(params())))
                {
                    UtlString* value = dynamic_cast<UtlString*>(paramList->findValue(name));
                    printf("%s : %s\n", name->data(), value->data());
                }
            }
            else
            {
                fprintf(stderr, "Incorrect type returned.\n");
                exit(1);
            }
        }
        else
        {
            fprintf(stderr, "No value returned.\n");
            exit(1);
        }
    }    
    delete request;
    request = NULL;
}
Exemple #11
0
OsStatus
DialByNameDB::load() const
{
    // Critical Section here
    OsLock lock( sLockMutex );
    OsStatus result = OS_SUCCESS;

    if ( m_pFastDB != NULL ) 
    {
        // Clean out the existing DB rows before loading
        // a new set from persistent storage
        removeAllRows ();

        // Query all Identities with 'AutoAttendant' permission set
        PermissionDB * pPermissionDB = PermissionDB::getInstance();
        ResultSet permissionsResultSet;
        pPermissionDB->getIdentities ( "AutoAttendant", permissionsResultSet );

        CredentialDB * pCredentialDB = CredentialDB::getInstance();
        ResultSet credentialsResultSet;

        UtlString identity, permission;
        int numAutoAttendees = permissionsResultSet.getSize();
        for (int index = 0; index < numAutoAttendees; index++)
        {
            // get the next identity
            UtlString identityKey("identity");
            UtlHashMap record;
            permissionsResultSet.getIndex( index, record );
            UtlString identity = *((UtlString*)record.findValue(&identityKey));

            Url identityUrl (identity);
            pCredentialDB->
                getAllCredentials (
                    identityUrl,
                    credentialsResultSet );

            // we should only have one credential! we're 
            // only interested in the uri column's display name
            if ( credentialsResultSet.getSize() == 1)
            {
                UtlString uriKey("uri");
                UtlHashMap record;
                credentialsResultSet.getIndex( 0, record );
                UtlString uri = *((UtlString*)record.findValue(&uriKey));

                // must have a display name present before inserting a row
                // @TODO convert to url and get display name
                UtlHashMap nvPairs;
                if (!uri.isNull())
                {
                    // Null Element value create a special 
                    // char string we have key and value so insert
                    UtlString* contactValue = 
                        new UtlString( uri ); 

                    // Memory Leak fixes, make shallow copies of static keys
                    UtlString* contactKey = 
                        new UtlString( gNp_contactKey );

                    nvPairs.insertKeyAndValue ( 
                        contactKey, contactValue );
                }
                // Insert the item row into the IMDB
                insertRow ( nvPairs );
            }
        }

        // Reset the changed flags after a successful load
        SIPDBManager::getInstance()->
            setDatabaseChangedFlag("credential", FALSE);
        SIPDBManager::getInstance()->
            setDatabaseChangedFlag("permission", FALSE);
    } else
    {
        result = OS_FAILED;
    }
    return result;
}
OsStatus
ManageNotificationsWebCGI::getManageNotificationsUI(UtlString* out)
{
    // Construct the status message
    UtlString statusStr = "&nbsp";
    if( m_status == ADD_NOTIFICATION_SUCCESS )
        statusStr = "Email address added successfully" ;
    else if( m_status == EDIT_NOTIFICATION_SUCCESS )
        statusStr = "Email address modified successfully" ;
    else if( m_status == DELETE_NOTIFICATION_SUCCESS )
        statusStr = "Email address deleted successfully" ;
    else if( m_status == DELETE_NOTIFICATION_FAILED )
        statusStr = "Failed to delete the email address. Please try again." ;

    UtlString dynamicHtml =  HTML_BEGIN \
                            WEBPAGE_SNIPPET1 \
                            "Manage Notifications" \
                            WEBPAGE_SNIPPET2 \
                            "notify_by_email_page.htm" \
                            WEBPAGE_SNIPPET3 ;


    MailboxManager* pMailboxManager = MailboxManager::getInstance();

    if( TRUE ) // email notification is always enabled now
    {
        // Get the list of contacts
        UtlBoolean contactsFound = FALSE ;

        UtlHashMap contactsHashDictionary;
        pMailboxManager->getNotificationContactList (
            m_mailboxIdentity,
            &contactsHashDictionary );

        if( contactsHashDictionary.entries() > 0 )
        {
            // Get the sorted contacts list
            // Get the sorted list of contacts.
            UtlSortedList* contactList = (UtlSortedList*) contactsHashDictionary.
                    findValue( new UtlString("sortedcontacts") );

            if (contactList != NULL)
            {
                if( contactList->entries() > 0)
                {
                    contactsFound = TRUE ;

                    // Add code for displaying the status and
                    // the table header for listing the contacts.
                    dynamicHtml +=  statusStr +
                                WEBPAGE_SNIPPET4 +
                                "<tr> \n" \
                                  "<th>Email Address</th>\n" \
                                  "<th width=\"15%\">Edit</th>\n" \
                                  "<th width=\"15%\">Delete</th>\n" \
                                "</tr>\n" ;
                }

                while( contactList->entries() > 0 )
                {

                    UtlString* rwAddress =
                        (UtlString*) contactList->removeAt(0);
                    UtlString address = rwAddress->data();

                    if( contactsHashDictionary.findValue( rwAddress ) != NULL )
                    {
                        UtlHashMap* contactDetails = (UtlHashMap*) contactsHashDictionary.
                                                findValue( rwAddress );

                        // Construct the HTML code
                        UtlString htmlCode ;
                        getNotificationsUIHtmlCode( address, contactDetails, htmlCode ) ;
                        dynamicHtml += htmlCode ;
                    }

                }
                delete contactList ;
            }
        }

        if( !contactsFound )
        {
            statusStr += "<br><br>Notifications can be sent to your email when you receive a new voicemail.<br>Click on the button below to specify your email address";
            dynamicHtml += statusStr + "</td></tr>" ;
        }

        dynamicHtml +=  "</table>\n" \
                        "</td></tr>\n" \
                        "<tr>\n" \
                            "<td colspan=\"2\"> \n" \
                               "<form action=\"" + m_cgiUrl + "\" method=\"post\">\n" \
                               "<input type=\"hidden\" name=\"action\" value=\"getaddnotificationui\">\n" \
                               "<input type=\"hidden\" name=\"fromweb\" value=\"yes\">\n" \
                               "<input type=\"submit\" value=\"Add Notification\">\n" \
                               "</form>\n" \
                            "</td> \n" \
                        "</tr> \n" ;
    }
    else
    {
        dynamicHtml +=  "<br><br>Email notification feature has not been enabled. Please contact your SIPxchange administrator." \
                        "</table>\n" \
                        "</td></tr>\n" ;
    }

    dynamicHtml +=  "</table>\n" \
                    "</td>\n" \
                    "</tr>\n" \
                    "</table>\n" \
                    HTML_END ;

    if( out )
    {
        out->remove(0);
        out->append( dynamicHtml.data() );
    }

    return OS_SUCCESS ;
}
OsStatus SipRedirectorPresenceRouting::pingOpenfire( void )
{
    OsStatus rc = OS_FAILED;
    UtlString presenceMonitorUrlAsString = mLocalPresenceMonitorServerUrl.toString();
    XmlRpcRequest pingRequest( mOpenFirePresenceServerUrl, PING_METHOD );
    pingRequest.addParam( &mLogName );
    XmlRpcResponse pingResponse;
    if( pingRequest.execute( pingResponse ) == true )
    {
       UtlContainable* pValue = NULL;
       if ( !pingResponse.getResponse( pValue ) || !pValue )
       {
          OsSysLog::add(FAC_NAT, PRI_CRIT, "SipRedirectorPresenceRouting::pingOpenfire response had no result.");
       }
       else
       {
          UtlString keyName;
          UtlHashMap* pMap = dynamic_cast<UtlHashMap*>( pValue );
          if ( !pMap )
          {
             OsSysLog::add(FAC_NAT, PRI_ERR,
                           "SipRedirectorPresenceRouting::pingOpenfire response result had unexpected type: %s",
                           pValue->getContainableType() );
          }
          else
          {
             // extract status code and check it.
             keyName = STATUS_CODE;
             UtlString* pStatusCode = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) );
             if( pStatusCode->compareTo( STATUS_CODE_VALUE_OK, UtlString::ignoreCase ) == 0 )
             {
                keyName = INSTANCE_HANDLE;
                UtlString* pInstanceHandle = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) );
                if( pInstanceHandle )
                {
                   if( mOpenfireInstanceHandle.compareTo( NIL_INSTANCE_HANDLE_VALUE ) == 0 )
                   {
                      // This is the first instance handle we get from openfire, save it
                      mOpenfireInstanceHandle = *pInstanceHandle;
                      rc = OS_SUCCESS;
                   }
                   else
                   {
                      // check if the openfire handle we received matches the one we have on record
                      if( mOpenfireInstanceHandle.compareTo( *pInstanceHandle ) == 0 )
                      {
                         // there is a match; everything is fine.
                         rc = OS_SUCCESS;
                      }
                      else
                      {
                         // mistmatch - likely caused by openfire resetting behind our back.
                         // fail the ping to cause a re-register with openfire
                         mOpenfireInstanceHandle = *pInstanceHandle;
                         rc = OS_FAILED; // rc already set to OS_FAILED; added for readability
                      }
                   }
                }
             }
          }
       }
    }
    return rc;
}
UtlBoolean SipPublishContentMgr::getContent(const char* resourceId,
                                            const char* eventTypeKey,
                                            const char* eventType,
                                            UtlBoolean fullState,
                                            const UtlString& acceptHeaderValue,
                                            HttpBody*& content,
                                            UtlBoolean& isDefaultContent,
                                            UtlString* availableMediaTypes)
{
    UtlBoolean foundContent = FALSE;
    PublishContentContainer* container = NULL;
    isDefaultContent = FALSE;

    UtlString key;
    key.append(resourceId);
    key.append(CONTENT_KEY_SEPARATOR);
    key.append(eventTypeKey);

    lock();

    UtlHashBag* pContent;
    if (fullState)
    {
       // Full content (this is the usual case)
       pContent = &mContentEntries;
    }
    else
    {
       // Partial content (used for partial dialog events)
       pContent = &mPartialContentEntries;
    }

    // See if resource-specific content exists
    container =
        dynamic_cast <PublishContentContainer*> (pContent->find(&key));

    // There is no resource-specific content.  Check if the default
    // constructor exists.
    if (container == NULL)
    {
       // Construct the key for the default data.
       UtlString default_key;
       default_key.append(CONTENT_KEY_SEPARATOR);
       default_key.append(eventTypeKey);

       // Look up the constructor.

       UtlHashMap* pDefaultConstructors;
       if (fullState)
       {
          // Full content (this is the usual case)
          pDefaultConstructors = &mDefaultContentConstructors;
       }
       else
       {
          // Partial content (used for partial dialog events)
          pDefaultConstructors = &mDefaultPartialContentConstructors;
       }
       SipPublishContentMgrDefaultConstructor* constructor =
          dynamic_cast <SipPublishContentMgrDefaultConstructor*>
          (pDefaultConstructors->findValue(&default_key));
       // If it exists, call it to publish content for this resource/event.
       if (constructor)
       {
          constructor->generateDefaultContent(this, resourceId,
                                              eventTypeKey, eventType);
       }

       // See if resource-specific content exists now.
       container =
          dynamic_cast <PublishContentContainer*> (pContent->find(&key));

       // If content was found, still mark it as default content.
       if (container)
       {
               isDefaultContent = TRUE;
       }
       // If still no content was found, check if (fixed) default content exists.
       else
       {
           container =
              dynamic_cast <PublishContentContainer*>
              (mDefaultContentEntries.find(&default_key));
           if(container)
           {
               isDefaultContent = TRUE;
           }
       }
    }

    // Within the container, choose the correct content.
    if (container)
    {
        if (acceptHeaderValue.compareTo(acceptAllTypes) != 0)
        {
           // Search for the first content in the container whose
           // MIME type is in the acceptable list.
           UtlSListIterator contentIterator(container->mEventContent);
           HttpBody* bodyPtr;
           while (!foundContent &&
                  (bodyPtr = dynamic_cast <HttpBody*> (contentIterator())))
           {
              // Trim any parameters off the body content type.
              UtlString* content_type = bodyPtr;
              UtlString base_content_type(*content_type);
              ssize_t i = base_content_type.index(';');
              if (i != UTL_NOT_FOUND)
              {
                 base_content_type.remove(i);
              }
              
              // See if base_content_type is in acceptHeaderValue.
              if (acceptHeaderValue.findToken(base_content_type.data(), ",", ";"))
              {
                 // If base_content_type is "multipart/related", extract
                 // the 'type' parameter value, which is the type of the
                 // root component, and check whether it is in acceptHeaderValue.
                 ssize_t j;
                 if (base_content_type.compareTo("multipart/related",
                                                 UtlString::ignoreCase) == 0)
                 {
                    // Search for the 'type' parameter.
                    i = content_type->index(";type=", UtlString::ignoreCase);
                    if (i != UTL_NOT_FOUND)
                    {
                       // Advance i to point to the value.
                       i += sizeof (";type=") - 1;
                       if ((*content_type)(i) == '\"')
                       {
                          // Value is quoted.
                          // Advance i to point to the value proper.
                          i++;
                          // Find the closing double-quote.
                          j = content_type->index('\"', i);
                          if (j == UTL_NOT_FOUND)
                          {
                             // This shouldn't happen.
                             Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                                           "SipPublishContentMgr::getContent "
                                           "No closing double-quote found for 'type' parameter in body MIME type '%s'",
                                           content_type->data());
                             // j == UTL_NOT_FOUND indicates failure.
                          }
                       }
                       else
                       {
                          // Value is not quoted.
                          // Find the end of the parameter.
                          j = content_type->index(';', i);
                          if (j == UTL_NOT_FOUND)
                          {
                             j = content_type->length();
                          }
                       }
                       if (j != UTL_NOT_FOUND)
                       {
                          // Characters from i to j are the type parameter value.
                          UtlString base_root_type;
                          base_root_type.append(*content_type, i, j - i);
                          // Remove parameters from base_root_type.
                          ssize_t k = base_content_type.index(';');
                          if (k != UTL_NOT_FOUND)
                          {
                             base_content_type.remove(k);
                          }
                          // See if base_root_type is in acceptHeaderValue.
                          if (acceptHeaderValue.findToken(base_root_type.data(), ",", ";"))
                          {
                             // Having passed all the tests, this content is OK.
                             foundContent = true;
                          }
                       }              
                    }
                    else
                    {
                       Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                                     "SipPublishContentMgr::getContent "
                                     "No 'type' parameter in body MIME type '%s'",
                                     content_type->data());
                    }
                 }
                 else
                 {
                    // If base_content_type is not multipart/related,
                    // we can accept the content with no further tests.
                    foundContent = true;
                 }

                 // If this content is acceptable, copy it into 'content'.
                 // Because foundContent is true, the loop will exit.
                 if (foundContent)
                 {
                    content = bodyPtr->copy();
                 }
              }
           }
           if (!foundContent)
           {
              // No content was found that matched the allowed MIME types.
              Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                            "SipPublishContentMgr::getContent no acceptable content found for key '%s', acceptHeaderValue '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s'",
                            key.data(),
                            acceptHeaderValue.data(),
                            resourceId ? resourceId : "[none]",
                            eventTypeKey, eventType);
              if (availableMediaTypes)
              {
                 // Construct the list of available MIME types.
                 availableMediaTypes->remove(0);
                 contentIterator.reset();
                 while ((bodyPtr = dynamic_cast <HttpBody*> (contentIterator())))
                 {
                    if (!availableMediaTypes->isNull())
                    {
                       availableMediaTypes->append(',');
                    }
                    availableMediaTypes->append(static_cast <UtlString&> (*bodyPtr));
                 }
              }
           }
        }
        else
        {
           // No MIME types were specified, take the first content in the list.
           // (which should exist)
           HttpBody* bodyPtr =
              dynamic_cast <HttpBody*> (container->mEventContent.first());
           if (bodyPtr)
           {
              content = bodyPtr->copy();
              foundContent = TRUE;
           }
           else
           {
              // No content was found (at all).
              // Set *availableMediaTypes.
              if (availableMediaTypes)
              {
                 availableMediaTypes->remove(0);
              }
              Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                            "SipPublishContentMgr::getContent no content found for key '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s' - publish() must have been called with numContentTypes==0",
                            key.data(),
                            resourceId ? resourceId : "[none]",
                            eventTypeKey, eventType);
           }
        }
    }
    else
    {
       // No container found for this resource and event.
       // Set *availableMediaTypes.
       if (availableMediaTypes)
       {
          availableMediaTypes->remove(0);
       }
       Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                     "SipPublishContentMgr::getContent no container found for key '%s', acceptHeaderValue '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s', fullState = %d",
                     key.data(),
                     acceptHeaderValue.data(),
                     resourceId ? resourceId : "[none]",
                     eventTypeKey, eventType,
                     fullState);
    }

    unlock();

    return foundContent;
}
int MpTopologyGraph::linkTopologyResources(MpResourceTopology& resourceTopology,
                                           UtlHashBag& newResources,
                                           UtlBoolean replaceNumInName,
                                           int resourceNum)
{
    // Link the resources
    int connectionIndex = 0;
    UtlString outputResourceName;
    UtlString inputResourceName;
    int outputResourcePortIndex;
    int inputResourcePortIndex;
    MpResource* outputResource = NULL;
    MpResource* inputResource = NULL;
    OsStatus result;
    UtlHashMap newConnectionIds;

#ifdef TEST_PRINT
    osPrintf("%d new resources in the list\n", newResources.entries());
    UtlHashBagIterator iterator(newResources);
    MpResource* containerResource = NULL;
    while(containerResource = (MpResource*) iterator())
    {
        osPrintf("found list resource: \"%s\" value: \"%s\"\n",
                 containerResource->getName().data(), containerResource->data());
    }
#endif

    while(resourceTopology.getConnection(connectionIndex,
                                         outputResourceName,
                                         outputResourcePortIndex,
                                         inputResourceName,
                                         inputResourcePortIndex) == OS_SUCCESS)
    {
        if(replaceNumInName)
        {
            resourceTopology.replaceNumInName(outputResourceName, resourceNum);
            resourceTopology.replaceNumInName(inputResourceName, resourceNum);
        }

        // Look in the container of new resources first as this is more 
        // efficient and new resources are not added immediately to a running
        // flowgraph
        outputResource = (MpResource*) newResources.find(&outputResourceName);
        if(outputResource == NULL)
        {
            result = lookupResource(outputResourceName, outputResource);
            if(result != OS_SUCCESS)
            {
                int virtPortIdx = outputResourcePortIndex>=0?outputResourcePortIndex:-1;
                int realPortIdx;
                result = lookupVirtualOutput(outputResourceName, virtPortIdx,
                                             outputResource, realPortIdx);
                if (result == OS_SUCCESS && outputResourcePortIndex>=0)
                {
                   outputResourcePortIndex = realPortIdx;
                }
            }
            assert(result == OS_SUCCESS);
        }
        inputResource = (MpResource*) newResources.find(&inputResourceName);
        if(inputResource == NULL)
        {
            result = lookupResource(inputResourceName, inputResource);
            if(result != OS_SUCCESS)
            {
                int virtPortIdx = inputResourcePortIndex>=0?inputResourcePortIndex:-1;
                int realPortIdx;
                result = lookupVirtualInput(inputResourceName, virtPortIdx,
                                            inputResource, realPortIdx);
                if (result == OS_SUCCESS && inputResourcePortIndex>=0)
                {
                   inputResourcePortIndex = realPortIdx;
                }
            }
            assert(result == OS_SUCCESS);
        }
        assert(outputResource);
        assert(inputResource);

        if(outputResource && inputResource)
        {
            if(outputResourcePortIndex == MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                outputResourcePortIndex = outputResource->reserveFirstUnconnectedOutput();
                assert(outputResourcePortIndex >= 0);
            }
            else if(outputResourcePortIndex < MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                // First see if a real port is already in the dictionary
                UtlInt searchKey(outputResourcePortIndex);
                UtlInt* foundValue = NULL;
                if((foundValue = (UtlInt*) newConnectionIds.findValue(&searchKey)))
                {
                    // Use the mapped index
                    outputResourcePortIndex = foundValue->getValue();
                }
                else
                {
                    // Find an available port and add it to the map
                    int realPortNum = outputResource->reserveFirstUnconnectedOutput();
                    assert(realPortNum >= 0);
                    UtlInt* portKey = new UtlInt(outputResourcePortIndex);
                    UtlInt* portValue = new UtlInt(realPortNum);
                    newConnectionIds.insertKeyAndValue(portKey, portValue);
                    outputResourcePortIndex = realPortNum;
                }
            }

            if(inputResourcePortIndex == MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                inputResourcePortIndex = inputResource->reserveFirstUnconnectedInput();
                assert(inputResourcePortIndex >= 0);
            }
            else if(inputResourcePortIndex < MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                // First see if a real port is already in the dictionary
                UtlInt searchKey(inputResourcePortIndex);
                UtlInt* foundValue = NULL;
                if((foundValue = (UtlInt*) newConnectionIds.findValue(&searchKey)))
                {
                    // Use the mapped index
                    inputResourcePortIndex = foundValue->getValue();
                }
                else
                {
                    // Find an available port and add it to the map
                    int realPortNum = inputResource->reserveFirstUnconnectedInput();
                    assert(realPortNum >= 0);
                    UtlInt* portKey = new UtlInt(inputResourcePortIndex);
                    UtlInt* portValue = new UtlInt(realPortNum);
                    newConnectionIds.insertKeyAndValue(portKey, portValue);
                    inputResourcePortIndex = realPortNum;
                }
            }


            result = addLink(*outputResource, outputResourcePortIndex, *inputResource, inputResourcePortIndex);
            assert(result == OS_SUCCESS);
        }
        connectionIndex++;
    }

    newConnectionIds.destroyAll();
    return(connectionIndex);
}
OsStatus SipRedirectorPresenceRouting::registerPresenceMonitorServerWithOpenfire( void )
{
    OsStatus rc = OS_FAILED;
    UtlString presenceMonitorUrlAsString = mLocalPresenceMonitorServerUrl.toString();

    XmlRpcRequest registerPresenceMonitorRequest( mOpenFirePresenceServerUrl, REGISTER_PRESENCE_MONITOR_METHOD );
    UtlString protocol = XML_RPC_PROTOCOL;
    registerPresenceMonitorRequest.addParam( &protocol );
    registerPresenceMonitorRequest.addParam( &presenceMonitorUrlAsString );
    XmlRpcResponse registerPresenceMonitorResponse;
    if( registerPresenceMonitorRequest.execute( registerPresenceMonitorResponse ) == true )
    {
       UtlContainable* pValue = NULL;
       if ( !registerPresenceMonitorResponse.getResponse( pValue ) || !pValue )
       {
          OsSysLog::add(FAC_NAT, PRI_ERR, "SipRedirectorPresenceRouting::registerPresenceMonitorRequestWithOpenfire response had no result.");
       }
       else
       {
          UtlString keyName;
          UtlHashMap* pMap = dynamic_cast<UtlHashMap*>( pValue );
          if ( !pMap )
          {
             OsSysLog::add(FAC_NAT, PRI_ERR,
                           "SipRedirectorPresenceRouting::registerPresenceMonitorRequestWithOpenfire response result had unexpected type: %s",
                           pValue->getContainableType() );
          }
          else
          {
             // extract status code and check it.
             keyName = STATUS_CODE;
             UtlString* pStatusCode = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) );
             if( pStatusCode->compareTo( STATUS_CODE_VALUE_OK, UtlString::ignoreCase ) != 0 )
             {
                // status-code is not "OK", some error happened - extract error information.
                keyName = ERROR_CODE;
                UtlString* pErrorCode = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) );
                keyName = ERROR_INFO;
                UtlString* pErrorInfo = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) );
                if( pErrorCode && pErrorInfo )
                {
                   OsSysLog::add(FAC_NAT, PRI_ERR, "SipRedirectorPresenceRouting::registerPresenceMonitorRequestWithOpenfire request failed: %s:'%s'", pErrorCode->data(), pErrorInfo->data() );
                }
             }
             else
             {
                keyName = INSTANCE_HANDLE;
                UtlString* pInstanceHandle = dynamic_cast<UtlString*>( pMap->findValue( &keyName ) );
                if( pInstanceHandle )
                {
                   // set openfire instance value 
                   mOpenfireInstanceHandle = *pInstanceHandle;
                }
                rc = OS_SUCCESS;
             }
          }
       }
    }
    else
    {
       // Check if the request failed because of a failed connection.
       // That error can sometimes happen when the server closed the TCP
       // connection we were using to communicate to it and can usually

        // be recovered by sending the request again.  Try to send the
        // request once more to see if it will fly this time.
        int faultCode;
        UtlString faultString;
        registerPresenceMonitorResponse.getFault( &faultCode, faultString );
        OsSysLog::add( FAC_NAT, PRI_ERR,
                       "SipRedirectorPresenceRouting::registerPresenceMonitorRequestWithOpenfire failed to execute() request: %d : %s",
                       faultCode, faultString.data() );
    }
    return rc;
}
RedirectPlugin::LookUpStatus
SipRedirectorFallback::lookUp(
   const SipMessage& message,
   UtlString& requestString,
   Url& requestUri,
   const UtlString& method,
   ContactList& contactList,
   RequestSeqNo requestSeqNo,
   int redirectorNo,
   SipRedirectorPrivateStorage*& privateStorage,
   ErrorDescriptor& errorDescriptor)
{
   ResultSet urlMappingRegistrations;

   UtlString callTag = "UNK";

   if (mMappingRulesLoaded == OS_SUCCESS)
   {      
      UtlString callerLocation;
      determineCallerLocation( message, callerLocation );
    
#ifndef __USE_OLD_FALLBACKRULES_SCHEMA__      
      mMap.getContactList(
         requestUri,
         callerLocation,
         urlMappingRegistrations,
         callTag );
#else
      ResultSet dummyMappingPermissions;
      mMap.getContactList(
         requestUri,
         urlMappingRegistrations, 
         dummyMappingPermissions );
#endif      
      
      int numUrlMappingRegistrations = urlMappingRegistrations.getSize();
      Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                    "%s::lookUp got %d UrlMapping Contacts for %s @ location '%s'",
                    mLogName.data(), numUrlMappingRegistrations, requestString.data(), callerLocation.data() );

      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)));
            UtlString callTagKey("callTag");
            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());

            contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, callTag.data());

            // Add the contact.
            contactList.add( contactUri, *this );
         }
      }
   }
   return RedirectPlugin::SUCCESS;
}
void
SipRedirectorGateway::processForm(const HttpRequestContext& requestContext,
                              const HttpMessage& request,
                              HttpMessage*& response)
{
   UtlString string_get("get");
   UtlString string_set("set");
   UtlString string_prefix("prefix");
   UtlString string_destination("destination");

   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "%s::processForm entered", mLogName.data());
   UtlString* user;

   // Process the request.

   // Get the body of the request.
   const HttpBody* request_body = request.getBody();

   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "%s::processForm A *** request body is '%s'",
                 mLogName.data(), request_body->getBytes());

   // Get the values from the form.
   if (request_body->isMultipart())
   {
      // Extract the values from the form data.
      UtlHashMap values;
      int c = request_body->getMultipartCount();
      for (int i = 0; i < c; i++)
      {
         UtlString* name = new UtlString;
         if (request_body->getMultipart(i)->getPartHeaderValue("name", *name))
         {
            const char* v;
            int l;
            request_body->getMultipartBytes(i, &v, &l);
            // Strip leading and trailing whitespace from values.
            UtlString* value = new UtlString(v, l);
            value->strip(UtlString::both);
            OsSysLog::add(FAC_SIP, PRI_CRIT,
                          "%s::processForm "
                          "form value '%s' = '%s'",
                          mLogName.data(), name->data(), value->data());
            // 'name' and 'value' are now owned by 'values'.
            values.insertKeyAndValue(name, value);
         }
         else
         {
            // 'name' is not owned by 'values' and we have to delete it.
            delete name;
         }
      }

      if (values.findValue(&string_get))
      {
         // This is a "get gateway" request.

         // Insert the HTML into the response.
         HttpBody* response_body = new HttpBody(form, -1, CONTENT_TYPE_TEXT_HTML);
         response->setBody(response_body);
      }
      else if (values.findValue(&string_set))
      {
         // This is a "set gateway" request.

         // Validate the routing prefix.
         UtlString* prefix =
            dynamic_cast <UtlString*> (values.findValue(&string_prefix));
         if (prefixIsValid(*prefix))
         {
            // Validate the destination.
            UtlString* destination =
               dynamic_cast <UtlString*>
                   (values.findValue(&string_destination));
            if (destination_is_valid(destination))
            {
               OsSysLog::add(FAC_SIP, PRI_CRIT,
                             "%s::processForm "
                             "add mapping '%s' -> '%s'",
                             mLogName.data(), prefix->data(), destination->data());

               mMapLock.acquire();
               // Insert the mapping.
               mMapUserToContacts.insertKeyAndValue(prefix, destination);
               mMapContactsToUser.insertKeyAndValue(destination, prefix);
               mMapLock.release();

               writeMappings();
            }
         }
         // Insert the HTML into the response.
         HttpBody* response_body = new HttpBody(form, -1, CONTENT_TYPE_TEXT_HTML);
         response->setBody(response_body);
      }
      else
      {
         // Incomprehensible request.

         // Insert the HTML into the response.
         HttpBody* response_body = new HttpBody(form, -1, CONTENT_TYPE_TEXT_HTML);
         response->setBody(response_body);
      }
   }
   else
   {
      // Incomprehensible request.

      // Insert the default HTML into the response.
      HttpBody* response_body = new HttpBody(form, -1, CONTENT_TYPE_TEXT_HTML);
      response->setBody(response_body);
   }
   
#if 0

#if 0
   // This is quite a chore, because getMultipartBytes gets the entire
   // multipart section, including the trailing delimiter, rather than just
   // the body, which is what we need.
   const char* value;
   int length;
   request_body->getMultipartBytes(0, &value, &length);
#if 0
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "%s::processForm A *** seeing '%.*s'", mLogName.data(), length, value);
#endif
   // Advance 'value' over the first \r\n\r\n, which ends the headers.
   const char* s = strstr(value, "\r\n\r\n");
   if (s)
   {
      s += 4;                   // Allow for length of \r\n\r\n.
      length -= s - value;
      value = s;
   }
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "%s::processForm B *** seeing '%.*s'", mLogName.data(), length, value);
#if 0
   // Search backward for the last \r, excepting the one in the second-to-last
   // position, which marks the end of the contents.
   if (length >= 3)
   {
      for (s = value + length - 3;
           !(s == value || *s == '\r');
           s--)
      {
         /* empty */
      }
      length = s - value;
   }
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "%s::processForm seeing '%.*s'", mLogName.data(), length, value);
#endif

   // Add the mappings.
   const char* error_msg;
   int error_location;
   UtlBoolean success =
      addMappings(value, length, user, error_msg, error_location);

   // Construct the response.

   response = new HttpMessage();

   // Send 200 OK reply.
   response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION,
                                        HTTP_OK_CODE,
                                        HTTP_OK_TEXT);
   // Construct the HTML.
   char buffer1[100];
#if 0
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "%s::processForm *** domain '%s'",
                 mLogName.data(), Gatewayredirector->mDomainName.data());
#endif
   if (success)
   {
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "%s::processForm success user '%s'",
                    mLogName.data(), user->data());
      sprintf(buffer1, "<code>sip:<font size=\"+1\">%s</font>@%s:65070</code> redirects to:<br />",
              user->data(), Gatewayredirector->mDomainName.data());
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "%s::processForm failure error_msg '%s', error_location %d",
                    mLogName.data(), error_msg, error_location);
      strcpy(buffer1, "<i>Error:</i>");
   }
   // Transcribe the input value into buffer2.
   char buffer2[FORM_SIZE];
   char* p;
   int i;
   if (success)
   {
      // An impossible location.
      error_location = -1;
   }
   for (p = buffer2, i = 0;
        ;
        i++)
   {
      // If this is the error location, insert the error message.
      if (i == error_location)
      {
         *p++ = '!';
         *p++ = '-';
         *p++ = '-';
         strcpy(p, error_msg);
         p += strlen(error_msg);
         *p++ = '-';
         *p++ = '-';
         *p++ = '!';
      }
      // Test for ending the loop after testing to insert the error message,
      // because the error message may be after the last character.
      if (i >= length)
      {
         break;
      }
      switch (value[i])
      {
      case '<':
         *p++ = '&';
         *p++ = 'l';
         *p++ = 't';
         *p++ = ';';
         break;
      case '>':
         *p++ = '&';
         *p++ = 'g';
         *p++ = 't';
         *p++ = ';';
         break;
      case '&':
         *p++ = '&';
         *p++ = 'a';
         *p++ = 'm';
         *p++ = 'p';
         *p++ = ';';
         break;
      default:
         *p++ = value[i];
         break;
      }
   }
   *p++ = '\0';
#endif

#endif

}
// Constructor
SipPersistentSubscriptionMgr::SipPersistentSubscriptionMgr(
   const UtlString& component,
   const UtlString& domain,
   const UtlString& fileName) :
   mComponent(component),
   mDomain(domain),
   mSubscriptionDBInstance(SubscriptionDB::getInstance(fileName)),
   mPersistenceTimer(mPersistTask.getMessageQueue(), 0),
   mPersistTask(mSubscriptionDBInstance)
{
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "SipPersistentSubscriptionMgr:: "
                 "mComponent = '%s', mDomain = '%s', fileName = '%s'",
                 mComponent.data(), mDomain.data(), fileName.data());

   // Start the persist task.
   mPersistTask.start();

   // Read the subscription table and initialize the SipSubscriptionMgr.

   unsigned long now = OsDateTime::getSecsSinceEpoch();
   ResultSet rs;
   mSubscriptionDBInstance->getAllRows(rs);
   UtlSListIterator itor(rs);
   UtlHashMap* rowp;
   while ((rowp = dynamic_cast <UtlHashMap*> (itor())))
   {
      if (OsSysLog::willLog(FAC_SIP, PRI_DEBUG))
      {
         UtlString out;
         UtlHashMapIterator itor(*rowp);
         UtlString* key;
         UtlContainable* value;
         while ((key = dynamic_cast <UtlString*> (itor())))
         {
            value = itor.value();
            if (!out.isNull())
            {
               out.append(", ");
            }
            out.append(*key);
            out.append(" = ");
            if (value->getContainableType() == UtlString::TYPE)
            {
               out.append("'");
               out.append(*(dynamic_cast <UtlString*> (value)));
               out.append("'");
            }
            else if (value->getContainableType() == UtlInt::TYPE)
            {
               out.appendNumber((int) (*(dynamic_cast <UtlInt*> (value))));
            }
            else
            {
               out.append(value->getContainableType());
            }
         }
         OsSysLog::add(FAC_SIP, PRI_DEBUG,
                       "SipPersistentSubscriptionMgr:: "
                       "table row: %s",
                       out.data());
      }

      // First, filter for rows that have the right component and have
      // not yet expired.
      UtlString* componentp =
         dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gComponentKey));
      assert(componentp);
      int expires =
         *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gExpiresKey)));
      if (componentp->compareTo(mComponent) == 0 &&
          expires - now >= 0)
      {
         OsSysLog::add(FAC_SIP, PRI_DEBUG,
                       "SipPersistentSubscriptionMgr:: "
                       "loading row");

         // Extract the values from the row.
         const UtlString* top =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gToKey));
         const UtlString* fromp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gFromKey));
         const UtlString* callidp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gCallidKey));
         const UtlString* eventtypep =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gEventtypeKey));
         const UtlString* eventidp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gIdKey));
         // Correct the null string if it is returned as
         // SPECIAL_IMDB_NULL_VALUE.
         if (eventidp->compareTo(special_imdb_null_value) == 0)
         {
            eventidp = &null_string;
         }
         int subcseq =
            *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gSubscribecseqKey)));
         const UtlString* urip =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gUriKey));
         const UtlString* contactp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gContactKey));
         const UtlString* routep =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gRecordrouteKey));
         // Correct the null string if it is returned as
         // SPECIAL_IMDB_NULL_VALUE.
         if (routep->compareTo(special_imdb_null_value) == 0)
         {
            routep = &null_string;
         }
         int notifycseq =
            *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gNotifycseqKey)));
         const UtlString* acceptp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gAcceptKey));
         int version =
            *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gVersionKey)));

         // Use SipSubscriptionMgr to update the in-memory data.

         // Construct a fake SUBSCRIBE request to carry most of the data
         // that updateDialogInfo needs.
         SipMessage subscribeRequest;
         subscribeRequest.setSubscribeData(urip->data(),
                                           fromp->data(),
                                           top->data(),
                                           callidp->data(),
                                           subcseq,
                                           eventtypep->data(),
                                           acceptp->data(),
                                           eventidp->data(),
                                           contactp->data(),
                                           routep->data(),
                                           expires - now);

         // Variables to hold the output of insertDialogInfo.
         UtlString subscribeDialogHandle;
         UtlBoolean isNew, isSubscriptionExpired;
         SipMessage subscribeResponse;
         UtlBoolean ret =
            SipSubscriptionMgr::insertDialogInfo(subscribeRequest,
                                                 // *urip is the request-URI of
                                                 // of the SUBSCRIBE.
                                                 *urip,
                                                 *eventtypep,
                                                 subscribeDialogHandle,
                                                 isNew,
                                                 isSubscriptionExpired,
                                                 subscribeResponse);
         if (!ret)
         {
            OsSysLog::add(FAC_SIP, PRI_ERR,
                          "SipPersistentSubscriptionMgr:: "
                          "insertDialogInfo failed urip = '%s', subscribeDialogHandle = '%s'",
                          urip->data(), subscribeDialogHandle.data());
         }
         else
         {
            // Set the next NOTIFY CSeq value.
            // (The data in IMDB has already been set.)
            SipSubscriptionMgr::setNextNotifyCSeq(subscribeDialogHandle,
                                                  notifycseq,
                                                  version);
         }
      }
   }
}
UtlBoolean
SubscribeServerThread::isAuthorized (
    const SipMessage* message,
    SipMessage *responseMessage,
    StatusPluginReference* pluginContainer)
{
    UtlBoolean isAuthorized = FALSE;
    UtlString  requestUser;
    Url       identityUrl;
    message->getUri(NULL, NULL, NULL, &requestUser);
    identityUrl.setUserId(requestUser);
    identityUrl.setHostAddress(mDefaultDomain);

    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
            ResultSet dbPermissions;

            PermissionDB::getInstance()->getPermissions( identityUrl, dbPermissions );

            int numDBPermissions = dbPermissions.getSize();

            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 ( int dbIndex = 0; dbIndex < numDBPermissions; dbIndex++ )
                    {

                        UtlHashMap record;
                        dbPermissions.getIndex( dbIndex, record );
                        // note not interested in identity here
                        UtlString permissionKey ("permission");
                        UtlString permission = *((UtlString*)record.findValue(&permissionKey));
                        if( permission.compareTo( *pluginPermission, UtlString::ignoreCase ) == 0)
                        {
                            nextPermissionMatched = TRUE;
                            break;
                        }
                    }
                }
                delete pluginPermissionIterator;

                // after going thru all permissions find out if all matched or not
                if( nextPermissionMatched )
                {
                   OsSysLog::add(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthorized() -"
                        " All permissions matched - request is AUTHORIZED");
                    isAuthorized = TRUE;
                }
                else
                {
                    OsSysLog::add(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthorized() -"
                        " One or more Permissions did not match - request is UNAUTHORIZED");
                    isAuthorized = FALSE;
                }
            }
            else
            {
                // one or more permissions needed by plugin and none in IMDB => UNAUTHORIZED
                OsSysLog::add(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthorized() -"
                    " No Permissions in IMDB - request is UNAUTHORIZED");
                isAuthorized = FALSE;
            }
        }
        else
        {
            OsSysLog::add(FAC_AUTH, PRI_DEBUG, "SubscribeServerThread::isAuthorized() -"
                " No Permissions required - request is always AUTHORIZED");
            isAuthorized = TRUE;
        }
    }
    //set the error response message id unauthorized
    if(!isAuthorized)
    {
        responseMessage->setResponseData(message,SIP_FORBIDDEN_CODE, SIP_FORBIDDEN_TEXT);
    }
    return isAuthorized;
}
   void stateSetting()
   {
      FileTestContext testContext(TEST_DATA_DIR "processState",
            TEST_WORK_DIR "processState");

      // copy test files into testContext structure
      testContext.inputFile("newprocess.xml");
      testContext.inputFile("another-process.xml");
      testContext.inputFile("notherprocess.sh");

      UtlString exePath;
      testContext.workingFilePath("notherprocess.sh", exePath);
      chmod(exePath.data(), S_IREAD | S_IWRITE | S_IEXEC);

      testContext.setSipxDir(SipXecsService::VarDirType, "var");
      testContext.setSipxDir(SipXecsService::LogDirType);

      UtlHashMap status;
      SipxProcessManager::getInstance()->getProcessStateAll(status);

      size_t existingProcesses = status.entries();

      UtlString path;
      SipxProcess* process1;
      SipxProcess* process2;

      testContext.inputFilePath("newprocess.xml", path);
      CPPUNIT_ASSERT((process1 = SipxProcess::createFromDefinition(path)));
      testContext.inputFilePath("another-process.xml", path);
      CPPUNIT_ASSERT((process2 = SipxProcess::createFromDefinition(path)));
      OsTask::delay(1 * OsTime::MSECS_PER_SEC); // give task some time to get up and running

      ASSERT_STR_EQUAL("New", process1->data());
      ASSERT_STR_EQUAL("1.0.0", process1->mVersion.data());

      CPPUNIT_ASSERT_EQUAL(SipxProcess::pDisabled->name(), process1->GetCurrentState()->name());
      CPPUNIT_ASSERT_EQUAL(SipxProcess::pDisabled->name(), process1->mpDesiredState->name());
      CPPUNIT_ASSERT(!process1->isEnabled());

      ASSERT_STR_EQUAL("Nother", process2->data());
      ASSERT_STR_EQUAL("1.0.0", process2->mVersion.data());

      ASSERT_STR_EQUAL(SipxProcess::pDisabled->name(), process2->GetCurrentState()->name());
      ASSERT_STR_EQUAL(SipxProcess::pDisabled->name(), process2->mpDesiredState->name());

      // set the expected version ourselves, since no-one else can in unit test!
      UtlString newCfgVersion("1.0.0");
      process1->setConfigurationVersion(newCfgVersion);
      UtlString currCfgVersion;
      process2->getConfigurationVersion(currCfgVersion);
      OsSysLog::add(FAC_SUPERVISOR, PRI_DEBUG,
                    "process2 config version = %s", currCfgVersion.data());

      process1->enable();
      process2->enable();

      int retries = 5;
      while ( retries-- &&
            !(process1->GetCurrentState()->name()==SipxProcess::pRunning->name() &&
              process2->GetCurrentState()->name()==SipxProcess::pConfigurationMismatch->name()) )
      {
         OsTask::delay(1 * OsTime::MSECS_PER_SEC);
      }

      OsSysLog::add(FAC_SUPERVISOR, PRI_DEBUG,
                    "test that process2 does not start until config version is set");
      ASSERT_STR_EQUAL(SipxProcess::pConfigurationMismatch->name(), process2->GetCurrentState()->name());

      process2->setConfigurationVersion(newCfgVersion);
      retries = 5;
      while ( retries-- && strcmp(process2->GetCurrentState()->name(),SipxProcess::pRunning->name()) )
      {
         OsTask::delay(1 * OsTime::MSECS_PER_SEC);
      }

      CPPUNIT_ASSERT(process1->isEnabled());
      CPPUNIT_ASSERT(process2->isEnabled());
      ASSERT_STR_EQUAL(SipxProcess::pRunning->name(), process1->mpDesiredState->name());

      ASSERT_STR_EQUAL(SipxProcess::pRunning->name(), process1->GetCurrentState()->name());
      ASSERT_STR_EQUAL(SipxProcess::pRunning->name(), process2->GetCurrentState()->name());

      SipxProcessManager::getInstance()->getProcessStateAll(status);

      CPPUNIT_ASSERT_EQUAL(existingProcesses + 2U, status.entries());
      UtlString* statusValue;

      UtlString process1name("New");
      CPPUNIT_ASSERT(statusValue = dynamic_cast<UtlString*>(status.findValue(&process1name)));
      ASSERT_STR_EQUAL("Running", statusValue->data());

      UtlString process2name("Nother");
      CPPUNIT_ASSERT(statusValue = dynamic_cast<UtlString*>(status.findValue(&process2name)));
      ASSERT_STR_EQUAL("Running", statusValue->data());

      process2->shutdown();
      CPPUNIT_ASSERT(process2->isEnabled());

      ASSERT_STR_EQUAL(SipxProcess::pRunning->name(), process2->mpDesiredState->name());

      retries = 5;
      while ( retries-- && strcmp(process2->GetCurrentState()->name(),SipxProcess::pShutDown->name()) )
      {
         OsTask::delay(1 * OsTime::MSECS_PER_SEC); // give task some time to shutdown
      }
      ASSERT_STR_EQUAL(SipxProcess::pShutDown->name(), process2->GetCurrentState()->name());

   }
Exemple #22
0
   void getRowByIpAddressTest()
   {
      SipDbTestContext sipDbTestContext(TEST_DATA_DIR "/locationdata",
                                        TEST_WORK_DIR "/locationdata"
                                                 );
      sipDbTestContext.inputFile("dummy_loc_db.xml" );
      
      LocationDB* pLocDb = LocationDB::getInstance("dummy_loc_db");
      UtlHashMap hashmap;
      UtlString key;
      UtlString* pTempString;
      key = "name";
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "172.29.255.255", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "172.31.0.0", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "22.22.22.21", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "22.22.22.23", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "10.10.9.255", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "10.10.11.0", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "11.11.10.255", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "11.11.12.0", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "12.12.11.255", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "12.12.13.0", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "46.255.255.255", hashmap ) );
      CPPUNIT_ASSERT( !pLocDb->getRowByIpAddress( "48.0.0.0", hashmap ) );

      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "172.30.0.0", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Ottawa", pTempString->data() );

      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "172.30.255.255", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Ottawa", pTempString->data() );
/*
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "22.22.22.22", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Ottawa", pTempString->data() );
*/
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "10.10.10.0", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Montreal", pTempString->data() );
      
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "10.10.10.255", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Montreal", pTempString->data() );
      
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "11.11.11.0", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Montreal", pTempString->data() );
      
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "11.11.11.255", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Montreal", pTempString->data() );
      
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "12.12.12.0", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Montreal", pTempString->data() );
      
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "12.12.12.255", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Montreal", pTempString->data() );
      
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "47.0.0.0", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Springfield", pTempString->data() );
      
      CPPUNIT_ASSERT( pLocDb->getRowByIpAddress( "47.255.255.255", hashmap ) );
      pTempString = dynamic_cast<UtlString*>( hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "Springfield", pTempString->data() );
      
      key = "description";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "It's a hell of a town", pTempString->data() );
      
      key = "locationcode";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "KL5", pTempString->data() );

      key = "subnets";
      pTempString = dynamic_cast<UtlString*>(hashmap.findValue( &key ) );
      CPPUNIT_ASSERT( pTempString );
      ASSERT_STR_EQUAL( "47.0.0.0/8", pTempString->data() );      
   }
RedirectPlugin::LookUpStatus
SipRedirectorAliasDB::lookUp(
    const SipMessage& message,
    const UtlString& requestString,
    const 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 its aliases
    UtlString disableForwarding;
    requestUri.getUrlParameter("sipx-userforward", disableForwarding);
    if (disableForwarding.compareTo("false", UtlString::ignoreCase) == 0)
    {
        OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::lookUp user forwarding disabled by parameter",
                      mLogName.data());
    }
    else
    {
        UtlString requestIdentity;
        requestUri.getIdentity(requestIdentity);

        OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::lookUp identity '%s'",
                      mLogName.data(), requestIdentity.data());

        ResultSet aliases;
        AliasDB::getInstance()->getContacts(requestUri, aliases);
        int numAliasContacts = aliases.getSize();
        if (numAliasContacts > 0)
        {
            OsSysLog::add(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;
            bool isUserIdentity =
                CredentialDB::getInstance()->isUriDefined(requestUri, realm, authType);
            SipXauthIdentity authIdentity;
            authIdentity.setIdentity(requestIdentity);

            for (int i = 0; i < numAliasContacts; i++)
            {
                static UtlString contactKey("contact");

                UtlHashMap record;
                if (aliases.getIndex(i, record))
                {
                    UtlString contact = *((UtlString*)record.findValue(&contactKey));
                    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");
                    // Add the contact.
                    contactList.add( contactUri, *this );
                }
            }
        }
    }

    return RedirectPlugin::SUCCESS;
}
Exemple #24
0
OsStatus
CredentialDB::load()
{
    // Critical Section here
    OsLock lock( sLockMutex );
    OsStatus result = OS_SUCCESS;

    if ( m_pFastDB != NULL ) 
    {
        // Clean out the existing DB rows before loading
        // a new set from persistent storage
        removeAllRows ();

        UtlString fileName = OsPath::separator + mDatabaseName + ".xml";
        UtlString pathName = SipXecsService::Path(SipXecsService::DatabaseDirType,
                                                  fileName.data());

        OsSysLog::add(FAC_DB, PRI_DEBUG, "CredentialDB::load loading \"%s\"",
                    pathName.data());

        TiXmlDocument doc ( pathName );

        // Verify that we can load the file (i.e it must exist)
        if( doc.LoadFile() )
        {
            // the checksum is used to determine if the db changed between reloads
            int loadChecksum = 0;
            TiXmlNode * rootNode = doc.FirstChild ("items");
            if (rootNode != NULL)
            {
                // the folder node contains at least the name/displayname/
                // and autodelete elements, it may contain others
                for( TiXmlNode *itemNode = rootNode->FirstChild( "item" );
                     itemNode;
                     itemNode = itemNode->NextSibling( "item" ) )
                {
                    // Create a hash dictionary for element attributes
                    UtlHashMap nvPairs;

                    for( TiXmlNode *elementNode = itemNode->FirstChild();
                         elementNode;
                         elementNode = elementNode->NextSibling() )
                    {
                        // Bypass comments and other element types only interested
                        // in parsing element attributes
                        if ( elementNode->Type() == TiXmlNode::ELEMENT )
                        {
                            UtlString elementName = elementNode->Value();
                            UtlString elementValue;

                            result = SIPDBManager::getAttributeValue (
                                *itemNode, elementName, elementValue);

                            // update the load checksum
                            loadChecksum += ( elementName.hash() + elementValue.hash() );
                            if (result == OS_SUCCESS)
                            {
                                UtlString* collectableKey =
                                    new UtlString( elementName );
                                UtlString* collectableValue =
                                    new UtlString( elementValue );
                                nvPairs.insertKeyAndValue (
                                    collectableKey, collectableValue );
                            } else if ( elementNode->FirstChild() == NULL )
                            {
                                // Null Element value creaete a special
                                // char string we have key and value so insert
                                UtlString* collectableKey =
                                    new UtlString( elementName );
                                UtlString* collectableValue =
                                    new UtlString( SPECIAL_IMDB_NULL_VALUE );
                                nvPairs.insertKeyAndValue (
                                    collectableKey, collectableValue );
                            }
                        }
                    }

                    // If this is an old credentials file, it may not contain
                    //    the pintoken element - if not, duplicate the passtoken
                    //    to create it.
                    if (!nvPairs.contains(&gPintokenKey))
                    {
                       UtlString* pintokenKey = new UtlString(gPintokenKey);
                       UtlString* pintokenValue
                          = new UtlString(*((UtlString*)nvPairs.findValue(&gPasstokenKey)));
                       nvPairs.insertKeyAndValue(pintokenKey, pintokenValue);
                    }

                    // Insert the item row into the IMDB
                    insertRow ( nvPairs );
                }
            }
            // Update the tableInfo table and determine if the db has 
            // changed as a result of the reload (setting the 
            // changed tableInfo field
            SIPDBManager::getInstance()->
                updateDatabaseInfo(
                    mDatabaseName, loadChecksum);
        } else 
        {
            OsSysLog::add(FAC_DB, PRI_WARNING, "CredentialDB::load failed to load \"%s\"",
                    pathName.data());
            result = OS_FAILED;
        }
    } else 
    {
        OsSysLog::add(FAC_DB, PRI_ERR, "CredentialDB::load failed - no DB");
        result = OS_FAILED;
    }
    return result;
}
Exemple #25
0
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;
}
SubscribeServerThread::SubscribeStatus SubscribeServerThread::addSubscription(
    const int timeNow,
    const SipMessage* subscribeMessage,
    const char* domain,
    const UtlString& eventType,
    const UtlString& eventId,
    const UtlHashMap& eventParams,
    UtlString& newToTag,
    int& grantedExpiration)
{
    SubscribeStatus returnStatus = STATUS_INTERNAL_ERROR;
    int subscribeCseqInt = 0;
    UtlString callId;
    UtlString contactEntry;
    UtlString to;
    UtlString from;
    UtlString route;
    UtlString key;
    UtlString method;
    Url identity;

    //  Construct the identity
    UtlString uriUser, requestUri;
    subscribeMessage->getUri( NULL, NULL, NULL, &uriUser );
    subscribeMessage->getRequestUri( &requestUri );
    identity.setUserId( uriUser );
    identity.setUrlType( "sip" );
    identity.setHostAddress( domain );

    subscribeMessage->getToField(&to);
    subscribeMessage->getFromField(&from);
    subscribeMessage->getCallIdField(&callId);
    subscribeMessage->getCSeqField(&subscribeCseqInt, &method);
    subscribeMessage->getContactEntry(0, &contactEntry);

    subscribeMessage->buildRouteField(&route);
    Url toUrl;
    subscribeMessage->getToUrl(toUrl);
    int commonExpires = -1;
    if ( subscribeMessage->getExpiresField( &commonExpires ) )
    {
       if( commonExpires > 0 ) // came from request
       {
          if (commonExpires < mMinExpiresTimeint)
          {
             returnStatus = STATUS_LESS_THAN_MINEXPIRES;
             OsSysLog::add( FAC_SIP, PRI_ERR, "addSubscription: "
                            "Expires (%d) less than Minimum (%d)",
                           commonExpires, mMinExpiresTimeint);
             return returnStatus;
          }
          else if (commonExpires > mDefaultSubscribePeriod)
          {
             commonExpires = mDefaultSubscribePeriod;
          }
          else
          {
             // commonExpires is in the allowed range - use the requested value
          }
        }
        else if( commonExpires == 0 )
        {
            // remove subscription binding
            // remove all bindings  because one contact value is *
            OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription -"
                " subscription for url %s and event %s to be removed after sending NOTIFY",
                toUrl.toString().data(), eventType.data());

            returnStatus = STATUS_TO_BE_REMOVED;
            return returnStatus;
        }
        else if( commonExpires == -1) // no expires value in request
        {
            // Assume the default value
            commonExpires = mDefaultSubscribePeriod;
            OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription -"
                " No Expires Value, assigning default value (%d)", commonExpires);
        }
    }

    UtlString sipxImpliedParameter(SIPX_IMPLIED_SUB);
    UtlString* sipxImpliedDuration = NULL;

    int grantedExpirationTime;
    if ((  sipxImpliedDuration
         = dynamic_cast<UtlString*>(eventParams.findValue(&sipxImpliedParameter))))
    {
       /*
        * This request was generated by the registrar as an implied subscription;
        * its duration must therefore match that of the registration, which has
        * already been randomized.
        */
       grantedExpirationTime = atoi(sipxImpliedDuration->data());
    }
    else
    {
       /*
        * The request is for a new or refreshed subscription (other cases were handled above);
        * commonExpires is now the requested duration in the range:
        *    mMinExpiresTimeint <= commonExpires <= mDefaultSubscribePeriod
        * In order to distribute expirations smoothly, we actually grant a randomized duration
        */
       int spreadFloor = mMinExpiresTimeint*2;

       if ( commonExpires > spreadFloor )
       {
          // a normal (long) registration
          // - spread it between twice the min and the longest they asked for
          grantedExpirationTime = (  (rand() % (commonExpires - spreadFloor))
                                   + spreadFloor);
       }
       else if ( commonExpires > mMinExpiresTimeint )
       {
          // a short but not minimum registration
          // - spread it between the min and the longest they asked for
          grantedExpirationTime = (  (rand()
                                      % (commonExpires - mMinExpiresTimeint)
                                      )
                                   + mMinExpiresTimeint
                                   );
       }
       else // longestExpiration == mMinExpiresTimeint
       {
          // minimum - can't randomize because we can't shorten or lengthen it
          grantedExpirationTime = mMinExpiresTimeint;
       }
    }

    // Handle the to-tag:
    // If no to-tag, this is a new subscription, for which we must create
    // a to-tag.
    // If there is a to-tag, this is a renewal of a subscription, and we
    // must first check that the subscription exists.  (This is because if
    // the UA thinks there is a subscription, but we do not know of it, we
    // cannot reconstitute the subscription, as we do not know the NOTIFY CSeq
    // that the UA expects.  See XECS-406 for the ill consequences of
    // this problem.)

    // Clear the returned new to-tag.
    newToTag.remove(0);
    {
       UtlString x;
       bool r = toUrl.getFieldParameter("tag", x);
       OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription getting to-tag, return %d, value '%s'",
                     (int) r, x.data());
    }
    UtlString toTag;
    if (toUrl.getFieldParameter("tag", toTag))
    {
       // Check to see if this subscription exists.
       // Critical Section here
       OsLock mutex(mLock);

       bool exists = SubscriptionDB::getInstance()->subscriptionExists(
          SUBSCRIPTION_COMPONENT_STATUS,
          to, from, callId, OsDateTime::getSecsSinceEpoch());

       OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription subscriptionExists(..., '%s', '%s', '%s', %d) = %d",
                     to.data(), from.data(),
                     callId.data(), (int) OsDateTime::getSecsSinceEpoch(),
                     exists);

       if (!exists)
       {
          returnStatus = STATUS_BAD_SUBSCRIPTION;
          return returnStatus;
       }
    }
    else
    {
       // Generate a random to-tag.
       CallId::getNewTag(newToTag);
       // Add it to the remembered To header value.
       to.append(";tag=");
       to.append(newToTag);
       OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription generated to-tag '%s'",
                     newToTag.data());
    }

    OsSysLog::add(FAC_SIP, PRI_DEBUG,
                  "SubscribeServerThread::addSubscription -"
                  " Adding/updating subscription for URI '%s' event %s duration %d to '%s'",
                  toUrl.toString().data(), eventType.data(), grantedExpirationTime, contactEntry.data());

    // trim the contact to just the uri
    Url contactUrl(contactEntry);
    contactUrl.getUri(contactEntry);

    // add bindings
    identity.getIdentity( key );

    // Insert or update the information for this subscription.
    // (Note that the "notify CSeq" parameter is ignored if there is
    // an existing SubscriptionDB row for this subscription.)
    if (insertRow(requestUri, // identity,
                  callId,
                  contactEntry,
                  grantedExpirationTime + timeNow,
                  subscribeCseqInt,
                  eventType,
                  eventId,
                  to,
                  from,
                  key,                 // this will be searched for later
                  route,
                  1))                  // initial notify cseq (sent to phone)
    {
       grantedExpiration = grantedExpirationTime;
       returnStatus = STATUS_SUCCESS;
    }
    else
    {
       // log the error and send error indication to subscriber
       OsSysLog::add(FAC_SIP, PRI_ERR,
                     "SubscribeServerThread::addSubscription -"
                     " Could not insert record in Database");

       returnStatus = STATUS_INTERNAL_ERROR;
    }

    return returnStatus;
}
Exemple #27
0
UtlBoolean HttpServer::mapUri(UtlHashMap& uriMaps, const char* uri, UtlString& mappedUri)
{
    UtlBoolean mapFound = FALSE;
    mappedUri.remove(0);

    if(uri)
    {
        UtlString originalUri(uri);
        UtlString mapFromUri(uri);
        UtlString* mapToUri;
        ssize_t dirSeparatorIndex;

        do
        {
            mapToUri = dynamic_cast<UtlString*>(uriMaps.findValue(&mapFromUri));
            if(mapToUri)
            {
                mappedUri.append(mapToUri->data());
                if (mapFromUri.length() < originalUri.length())
                {
                   if(mappedUri.length() == 1)
                   {
                      // this is a mapping from some path to "/", so remove what we just added
                      mappedUri.remove(0);
                   }
                   else if(   mappedUri.data()[mappedUri.length() - 1] != '/'
                           && uri[mapFromUri.length()] != '/'
                           )
                   {
                      // Need a directory separator
                      mappedUri.append('/');
                   }
                   mappedUri.append(originalUri, mapFromUri.length(),
                                    UtlString::UTLSTRING_TO_END);
                }
                else
                {
                   mappedUri.append(originalUri, mapFromUri.length(),
                                    UtlString::UTLSTRING_TO_END);
                }
                mapFound = TRUE;
            }
            else
            {
               dirSeparatorIndex = mapFromUri.last('/');
               if(dirSeparatorIndex == 0 && mapFromUri.length() > 1)
               {
                  // we're down to "/string" - remove the "string"
                  mapFromUri.remove(1);
               }
               else if(dirSeparatorIndex >= 0)
               {
                  // remove the topmost path and the separator
                  mapFromUri.remove(dirSeparatorIndex);
               }
               else
               {
                  // no separator found - empty the from string to exit the loop
                  mapFromUri.remove(0);
               }
            }
        } while(!mapFound && !mapFromUri.isNull());

        if (!mapFound)
        {
           mappedUri.append(uri);
        }
    }

    OsSysLog::add(FAC_SIP,
                  mapFound ? PRI_INFO : PRI_DEBUG,
                  "HttpServer::mapUri %s '%s' -> '%s'",
                  mapFound ? "mapped" : "no mapping",
                  uri, mappedUri.data());

    return(mapFound);
}