Example #1
0
   void testSupportedAndRequiredFields()
   {
      SipUserAgent sipUA( 5090, 5090, 5091, 
                          NULL, NULL,   // default publicAddress and defaultUser
                         "127.0.0.1" ); 

      // Supported
      CPPUNIT_ASSERT( ! sipUA.isExtensionAllowed( "nope" ) );

      UtlString supported( "supported-1" );
      sipUA.allowExtension( supported );

      UtlString tmp;
      sipUA.getSupportedExtensions( tmp );
      CPPUNIT_ASSERT( supported == tmp );
      supported.toUpper();
      CPPUNIT_ASSERT( sipUA.isExtensionAllowed( supported ) );
      CPPUNIT_ASSERT( ! sipUA.isExtensionAllowed( "nope" ) );


      // Required
      CPPUNIT_ASSERT( ! sipUA.isExtensionRequired( "nope" ) );

      UtlString required( "required-1, required-2, required-3" );
      UtlString copy_required( required );
      copy_required += ',';
      ssize_t prev = 0;
      ssize_t index = copy_required.index( ',', prev );
      while( UTL_NOT_FOUND != index )
      {
         UtlString field = copy_required( prev, index - prev );
         field.strip( UtlString::both );
         sipUA.requireExtension( field );
         prev = index + 1;
         index = copy_required.index( ',', prev );
      }

      sipUA.getRequiredExtensions( tmp );
      CPPUNIT_ASSERT( required == tmp );
      index = copy_required.index( ',', prev );
      while( UTL_NOT_FOUND != index )
      {
         UtlString field = copy_required( prev, index - prev );
         field.strip( UtlString::both );
         field.toUpper();
         CPPUNIT_ASSERT( sipUA.isExtensionRequired( field ) );
         prev = index + 1;
         index = copy_required.index( ',', prev );
      }
      CPPUNIT_ASSERT( ! sipUA.isExtensionRequired( "nope" ) );
   }
Example #2
0
OsStatus ForwardRules::getRouteTo(UtlString& RouteToString,
                                 bool& authRequired,
                                  TiXmlNode* nodeWithRouteToChild)
{
   
   OsStatus currentStatus = OS_FAILED;
   nodeWithRouteToChild->ToElement();
   TiXmlNode* routeToNode = NULL;
   TiXmlNode* routeToText = NULL;


   //get the user text value from it
   routeToNode = nodeWithRouteToChild->FirstChild(XML_TAG_ROUTETO);
   if(routeToNode)
   {
      if(routeToNode && routeToNode->Type() != TiXmlNode::ELEMENT)
      {
         return currentStatus;
      }

      TiXmlElement* routeToElement = routeToNode->ToElement();

      const char* authRequiredPtr = 
         routeToElement->Attribute(XML_ATT_AUTHREQUIRED);

      //set the authRequired attribute
      authRequired=getYN(authRequiredPtr, false) ; //defaults to false

      RouteToString.remove(0);
      routeToText = routeToElement->FirstChild();
      if(routeToText && routeToText->Type() == TiXmlNode::TEXT)
      {
         TiXmlText* routeTo = routeToText->ToText();
         if (routeTo)
         {
            RouteToString.append(routeTo->Value());
         }
      }
      // TinyXML compresses white space, so an all white space element becomes
      // zero length, but just in case, let's strip it ourselves.
      RouteToString.strip(UtlString::both);
      if (RouteToString.length() > 0)
      {
         // The route is not empty.  Declare success
         currentStatus = OS_SUCCESS;
      }
      else if (authRequired)
      {
         // The Route can be empty, as long as authRequired is set.
         // This means just route to the authProxy.
         currentStatus = OS_SUCCESS;
      }
      else
      {
         // Empty or missing route, and no authRequired...that's not allowed.
         currentStatus = OS_FAILED;
      }
   }
   return currentStatus;
}
Example #3
0
void Url::getDisplayName(UtlString& displayName) const
{
    displayName = mDisplayName;
    if (isDigitString(mDisplayName.data()))
    {
       displayName.strip(UtlString::both, '\"');
    }
}
Example #4
0
void writeBranchId(int outputFileDescriptor,
                   UtlString& branchId)
{
    branchId.strip(UtlString::both);
    UtlString node("\t\t\t<branchId>");
    node.append(branchId);
    node.append("</branchId>\n");

    write(outputFileDescriptor, node.data(), node.length());
}
DirectoryResource*
DirectoryResourceManager::findFilename(const char* fullName ///< full path to a file
                                       )
{
   OsPath fullFileName(fullName);
   UtlString dirName  = fullFileName.getDirName();
   UtlString fileName;

   fileName.append(fullName, dirName.length(), UtlString::UTLSTRING_TO_END);
   dirName.strip(UtlString::trailing, OsPath::separator[0]);

   DirectoryResource* found = NULL;
   
   Os::Logger::instance().log(FAC_SUPERVISOR, PRI_DEBUG,
                 "DirectoryResourceManager::findFilename: path '%s' file '%s'",
                 dirName.data(), fileName.data());

   {
      OsLock tableMutex(mDirectoryResourceTableLock);
      UtlSListIterator directories(mDirectoryResourceTable);
      DirectoryResource* dir;
   
      while (!found
             && (dir = dynamic_cast<DirectoryResource*>(directories.findNext(&dirName))))
      {
         if ( dir->matches(fileName) )
         {
            found = dir;
         }
      }
   }

   if (found)
   {
      UtlString matched;
      found->appendDescription(matched);
      Os::Logger::instance().log(FAC_SUPERVISOR, PRI_DEBUG,
                    "DirectoryResourceManager::findFilename: '%s' matches %s",
                    fullName, matched.data());
   }
   else
   {
      Os::Logger::instance().log(FAC_SUPERVISOR, PRI_WARNING,
                    "DirectoryResourceManager::findFilename: no match found for '%s'",
                    fullName);
   }
   
   return found;
}
Example #6
0
UtlBoolean SipRegistrar::handleMessage( OsMsg& eventMessage )
{
    UtlBoolean handled = FALSE;

    int msgType = eventMessage.getMsgType();
    int msgSubType = eventMessage.getMsgSubType();

    if (   (msgType == OsMsg::PHONE_APP)
        && (msgSubType == SipMessage::NET_SIP_MESSAGE)
        )
    {
        Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage()"
                      " Start processing SIP message") ;

        const SipMessage* message =
           ((SipMessageEvent&)eventMessage).getMessage();
        UtlString callId;
        if ( message )
        {
            message->getCallIdField(&callId);
            UtlString method;
            message->getRequestMethod(&method);

            if ( !message->isResponse() ) // is a request ?
            {
                if ( method.compareTo(SIP_REGISTER_METHOD) == 0 )
                {
                    //send to Register Thread
                    sendToRegistrarServer(eventMessage);
                }
                else if ( method.compareTo(SIP_OPTIONS_METHOD) == 0 )
                {
                    UtlString requestUri;
                    message->getRequestUri(&requestUri);

                    // Check if the OPTIONS request URI is addressed to a user or
                    // to the domain.
                    if (!requestUri.contains("@"))
                    {
                        UtlString contentEncoding;
                        message->getContentEncodingField(&contentEncoding);

                        UtlString disallowedExtensions;

                        int extensionIndex = 0;
                        UtlString extension;

                        disallowedExtensions.remove(0);
                        while(message->getRequireExtension(extensionIndex, &extension))
                        {
                            if(!(mSipUserAgent->isExtensionAllowed(extension.data())) )
                            {
                                if(!disallowedExtensions.isNull())
                                {
                                    disallowedExtensions.append(SIP_MULTIFIELD_SEPARATOR);
                                    disallowedExtensions.append(SIP_SINGLE_SPACE);
                                }
                                disallowedExtensions.append(extension.data());
                            }
                            extensionIndex++;
                        }

                        //delete leading and trailing white spaces
                        disallowedExtensions = disallowedExtensions.strip(UtlString::both);

                        SipMessage response;

                        // Check if the extensions are supported
                        if(!disallowedExtensions.isNull() )
                        {
                           // error response - bad extension
                           response.setRequestBadExtension(message,
                                                           disallowedExtensions);
                        }
                        // Check if the encoding is supported
                        // i.e. no encoding
                        else if(!contentEncoding.isNull())
                        {
                           // error response - content encoding
                           response.setRequestBadContentEncoding(message,"");
                        }
                        else
                        {
                            // Send an OK, the allowed field will get added to all final responses.
                            // Options 200 response
                            response.setResponseData(message,
                                                     SIP_OK_CODE,
                                                     SIP_OK_TEXT);
                        }

                        mSipUserAgent->send(response);
                    }
                    else
                    {
                        //OPTIONS is addressed to a user, send to redirect thread
                        sendToRedirectServer(eventMessage);
                    }
                }
                else
                {
                    //send to redirect thread
                    sendToRedirectServer(eventMessage);
                }
            }
            else
            {
               // responses are ignored.
            }
        }
        else
        {
           Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                         "SipRegistrar::handleMessage no message."
                         ) ;
        }

        handled = TRUE;
    }
    else if ( OsMsg::OS_SHUTDOWN == msgType )
    {
       Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                     "SipRegistrar::handleMessage shutting down all tasks");

       // Do an orderly shutdown of all the various threads.


       if ( mSipUserAgent )
       {
          Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                        "SipRegistrar::handleMessage shutting down SipUserAgent");
          mSipUserAgent->shutdown();
          delete mSipUserAgent ;
          mSipUserAgent = NULL ;
       }


       if ( mRegistrarPersist )
       {
          Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                        "SipRegistrar::handleMessage shutting down RegistrarPersist");
          mRegistrarPersist->requestShutdown();
          delete mRegistrarPersist;
          mRegistrarPersist = NULL;
       }

       if ( mRedirectServer )
       {
          Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                        "SipRegistrar::handleMessage shutting down RedirectServer");
          mRedirectServer->requestShutdown();
          delete mRedirectServer;
          mRedirectServer = NULL;
          mRedirectMsgQ = NULL;
       }

       if ( mRegistrarServer )
       {
          Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                        "SipRegistrar::handleMessage shutting down RegistrarServer");
          mRegistrarServer->requestShutdown();
          delete mRegistrarServer;
          mRegistrarServer = NULL;
          mRegistrarMsgQ = NULL;
       }

       if ( mRegisterEventServer )
       {
          Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                        "SipRegistrar::handleMessage shutting down RegisterEventServer");
          delete mRegisterEventServer;
          mRegisterEventServer = NULL;
       }

       OsTask::requestShutdown(); // tell OsServerTask::run to exit
       handled = TRUE;
    }
    else
    {
       Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                     "SipRegistrar::handleMessage unhandled type %d/%d",
                     msgType, msgSubType
                     ) ;
    }

    return handled;
}
Example #7
0
UtlBoolean 
DialByNameDB::getDigitStrings (
    const UtlString& displayName, 
    UtlSList& rDTMFStrings ) const
{
    UtlString lowerString = displayName;
    lowerString.toLower();
    lowerString = lowerString.strip(UtlString::both, '"');
    UtlTokenizer next( lowerString );
    UtlString token;
    UtlSList names;

    // Parse the Display name into a list of names
    // The algorithm for breaking up the string is as follows
    // if the string has > 2 tokens (forget about , separators)
    // create multiple entries in the IMDB for the all combinations
    // so for example
    // John Peter Smith Jr would result in DTMF entries for
    // PeterSmithJrJohn, SmithJrJohnPeter and JrJohnPeterSmith
    // @JC Added - separator for MIT's Avery-Smith example
   
    while (next.next(token, "\t\n,- ")) 
    {
        names.insert ( new UtlString ( token ) );
    }

    size_t numNames = names.entries();

    if ( numNames > 0 ) 
    {
        UtlString reorderedString;
        unsigned int splitPosition = 1;
        do 
        {
            unsigned int i;
            UtlString firstNames;
            for ( i=0; i<splitPosition; i++ ) 
            {
                firstNames += *(UtlString*)names.at(i);
            }

            UtlString lastNames;
            for ( i = splitPosition; i<numNames; i++) 
            {
                lastNames += *(UtlString*)names.at(i);
            }

            // add the new string
            reorderedString = lastNames + firstNames;

            unsigned int len = reorderedString.length();
            
            // calculate thd DTMF digits for the display name
            // firstly strip all , 's and spaces
            UtlString digitString;
            for ( i = 0; i<len; i++ )
            {
                int offset = (int) ( reorderedString(i) - 'a' );
                // filter out white space and comma separators
                if ( (offset >= 0) && (offset < 26) )
                    digitString += digitmap[ offset ];
            }

            rDTMFStrings.insert ( new UtlString (digitString) );

            splitPosition++;
        } while ( splitPosition<numNames );
    }

    // call the desctuctors on all the temp strings
    names.destroyAll();
    return TRUE;
}
Example #8
0
void writeBranchNodeData(int outputFileDescriptor,
                      UtlString& time,
                      UtlString& source,
                      UtlString& destination,
                      UtlString& sourceAddress,
                      UtlString& destinationAddress,
                      UtlString& transactionId,
                      UtlString& frameId,
                      UtlString& method,
                      UtlString& responseCode,
                      UtlString& responseText,
                      UtlString& message)
{
    time.strip(UtlString::both);
    source.strip(UtlString::both);
    destination.strip(UtlString::both);
    sourceAddress.strip(UtlString::both);
    destinationAddress.strip(UtlString::both);
    transactionId.strip(UtlString::both);
    frameId.strip(UtlString::both);
    method.strip(UtlString::both);
    responseCode.strip(UtlString::both);
    responseText.strip(UtlString::both);
    //message.strip(UtlString::both);

    UtlString node("\t\t<time>");
    node.append(time);
    node.append("</time>\n");

    if(!source.isNull())
    {
        node.append("\t\t<source>");
        node.append(source);
        node.append("</source>\n");
    }

    if(!destination.isNull())
    {
        node.append("\t\t<destination>");
        node.append(destination);
        node.append("</destination>\n");
    }

    node.append("\t\t<sourceAddress>");
    node.append(sourceAddress);
    node.append("</sourceAddress>\n");

    node.append("\t\t<destinationAddress>");
    node.append(destinationAddress);
    node.append("</destinationAddress>\n");

    node.append("\t\t<transactionId>");
    node.append(transactionId);
    node.append("</transactionId>\n");

    if(!method.isNull())
    {
        node.append("\t\t<method>");
        node.append(method);
        node.append("</method>\n");
    }
    else
    {
        node.append("\t\t<responseCode>");
        node.append(responseCode);
        node.append("</responseCode>\n");

        node.append("\t\t<responseText>");
        node.append(responseText);
        node.append("</responseText>\n");
    }

    node.append("\t\t<frameId>");
    node.append(frameId);
    node.append("</frameId>\n");

    node.append("\t\t<message><![CDATA[");
    node.append(message);
    node.append("]]></message>\n");

    write(outputFileDescriptor, node.data(), node.length());
}
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

}