Exemplo n.º 1
0
/** Process a general service request message.
 *
 * @param[in] message - The message to process.
 * @param[out] sendbuf - The response buffer to fill.
 * @param[in] errorcode - The error code from the client request.
 *
 * @return Zero on success, or a non-zero SLP error on failure.
 *
 * @internal
 */
static int ProcessSrvRqst(SLPMessage * message, SLPBuffer * sendbuf, 
      int errorcode)
{
   int i;
   SLPUrlEntry * urlentry;
   SLPDDatabaseSrvRqstResult * db = 0;
   size_t size = 0;
   SLPBuffer result = *sendbuf;

#ifdef ENABLE_SLPv2_SECURITY
   SLPAuthBlock * authblock = 0;
   int j;
#endif

   /* If errorcode is set, we can not be sure that message is good
      Go directly to send response code 
    */
   if (errorcode)
      goto RESPOND;

   /* Check for one of our IP addresses in the prlist */
   if (SLPIntersectStringList(message->body.srvrqst.prlistlen, 
         message->body.srvrqst.prlist, G_SlpdProperty.interfacesLen,
         G_SlpdProperty.interfaces))
   {
      /* silently ignore */
      result->end = result->start;
      goto FINISHED;
   }

   /* Make sure that we handle at least verify registrations made with
      the requested SPI.  If we can't then have to return an error
      because there is no way we can return URL entries that are
      signed in a way the requester can understand
    */
#ifdef ENABLE_SLPv2_SECURITY
   if (G_SlpdProperty.securityEnabled)
   {
      if (SLPSpiCanVerify(G_SlpdSpiHandle, message->body.srvrqst.spistrlen,
            message->body.srvrqst.spistr) == 0)
      {
         errorcode = SLP_ERROR_AUTHENTICATION_UNKNOWN;
         goto RESPOND;
      }
   }
   else if (message->body.srvrqst.spistrlen)
   {
      errorcode = SLP_ERROR_AUTHENTICATION_UNKNOWN;
      goto RESPOND;
   }
#else
   if (message->body.srvrqst.spistrlen)
   {
      errorcode = SLP_ERROR_AUTHENTICATION_UNKNOWN;
      goto RESPOND;
   }
#endif

   /* check to to see if a this is a special SrvRqst */
   if (SLPCompareString(message->body.srvrqst.srvtypelen, 
         message->body.srvrqst.srvtype, 23, SLP_DA_SERVICE_TYPE) == 0)
   {
      errorcode = ProcessDASrvRqst(message, sendbuf, errorcode);
      if (errorcode == 0)
      {
         /* Since we have an errorcode of 0, we were successful,
            and have already formed a response packet; return now.
          */
         return errorcode;
      }
      goto RESPOND;
   }
   if (SLPCompareString(message->body.srvrqst.srvtypelen, 
         message->body.srvrqst.srvtype, 21, SLP_SA_SERVICE_TYPE) == 0)
   {
      errorcode = ProcessSASrvRqst(message, sendbuf, errorcode);
      if (errorcode == 0)
      {
         /* Since we have an errorcode of 0, we were successful,
            and have already formed a response packet; return now.
          */
         return errorcode;
      }
      goto RESPOND;
   }

   /* make sure that we handle the scope */
   if (SLPIntersectStringList(message->body.srvrqst.scopelistlen, 
         message->body.srvrqst.scopelist, G_SlpdProperty.useScopesLen,
         G_SlpdProperty.useScopes) != 0)
      errorcode = SLPDDatabaseSrvRqstStart(message, &db);
   else
      errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;

RESPOND:

   /* do not send error codes or empty replies to multicast requests */
   if (errorcode != 0 || db->urlcount == 0)
   {
      if (message->header.flags & SLP_FLAG_MCAST 
            || SLPNetIsMCast(&(message->peer)))
      {
         result->end = result->start;
         goto FINISHED;  
      }
   }

   /* ensure the buffer is big enough to handle the whole srvrply */
   size = message->header.langtaglen + 18;/* 14 bytes for header     */
                                          /*  2 bytes for error code */
                                          /*  2 bytes for url count  */
   if (errorcode == 0)
   {
      for (i = 0; i < db->urlcount; i++)
      {
         /* urlentry is the url from the db result */
         urlentry = db->urlarray[i];

         size += urlentry->urllen + 6; /*  1 byte for reserved  */
                                       /*  2 bytes for lifetime */
                                       /*  2 bytes for urllen   */
                                       /*  1 byte for authcount */
#ifdef ENABLE_SLPv2_SECURITY
         /* make room to include the authblock that was asked for */
         if (G_SlpdProperty.securityEnabled 
               && message->body.srvrqst.spistrlen)
         {
            for (j = 0; j < urlentry->authcount; j++)
            {
               if (SLPCompareString(urlentry->autharray[j].spistrlen,
                     urlentry->autharray[j].spistr,
                     message->body.srvrqst.spistrlen,
                     message->body.srvrqst.spistr) == 0)
               {
                  authblock = &(urlentry->autharray[j]);
                  size += authblock->length;
                  break;
               }
            }
         }
#endif 
      }
   }

   /* reallocate the result buffer */
   result = SLPBufferRealloc(result, size);
   if (result == 0)
   {
      errorcode = SLP_ERROR_INTERNAL_ERROR;
      goto FINISHED;
   }

   /* add the header */

   /* version */
   *result->curpos++ = 2;

   /* function id */
   *result->curpos++ = SLP_FUNCT_SRVRPLY;

   /* length */
   PutUINT24(&result->curpos, size);

   /* flags */
   PutUINT16(&result->curpos, (size > (size_t)G_SlpdProperty.MTU? 
         SLP_FLAG_OVERFLOW: 0));

   /* ext offset */
   PutUINT24(&result->curpos, 0);

   /* xid */
   PutUINT16(&result->curpos, message->header.xid);

   /* lang tag len */
   PutUINT16(&result->curpos, message->header.langtaglen);

   /* lang tag */
   memcpy(result->curpos, message->header.langtag,
         message->header.langtaglen);
   result->curpos += message->header.langtaglen;

   /* add rest of the SrvRply */

   /* error code*/
   PutUINT16(&result->curpos, errorcode);
   if (errorcode == 0)
   {
      /* urlentry count */
      PutUINT16(&result->curpos, db->urlcount);
      for (i = 0; i < db->urlcount; i++)
      {
         /* urlentry is the url from the db result */
         urlentry = db->urlarray[i]; 

#ifdef ENABLE_SLPv1
         if (urlentry->opaque == 0)
         {
            /* url-entry reserved */
            *result->curpos++ = 0;        

            /* url-entry lifetime */
            PutUINT16(&result->curpos, urlentry->lifetime);

            /* url-entry urllen */
            PutUINT16(&result->curpos, urlentry->urllen);

            /* url-entry url */
            memcpy(result->curpos, urlentry->url, urlentry->urllen);
            result->curpos += urlentry->urllen;

            /* url-entry auths */
            *result->curpos++ = 0;
         }
         else
#endif
         {
            /* Use an opaque copy if available (and authentication is 
             * not being used).
             */

            /* TRICKY: Fix up the lifetime. */
            TO_UINT16(urlentry->opaque + 1, urlentry->lifetime);
            memcpy(result->curpos, urlentry->opaque, urlentry->opaquelen);
            result->curpos += urlentry->opaquelen;
         }
      }
   }
   else
      PutUINT16(&result->curpos, 0); /* set urlentry count to 0*/

FINISHED:   

   if (db) 
      SLPDDatabaseSrvRqstEnd(db);

   *sendbuf = result;

   return errorcode;
}
Exemplo n.º 2
0
/*-------------------------------------------------------------------------*/
int v1ProcessSrvRqst(struct sockaddr_in* peeraddr,
                     SLPMessage message,
                     SLPBuffer* sendbuf,
                     int errorcode)
/*-------------------------------------------------------------------------*/
{
    int                         i;
    int                         urllen;
    int                         size        = 0;
    SLPDDatabaseSrvRqstResult*  db          = 0;
    SLPBuffer                   result      = *sendbuf;

    /*--------------------------------------------------------------*/
    /* If errorcode is set, we can not be sure that message is good */
    /* Go directly to send response code                            */
    /*--------------------------------------------------------------*/
    if (errorcode)
    {
        goto RESPOND;
    }

    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if (SLPIntersectStringList(message->body.srvrqst.prlistlen,
                               message->body.srvrqst.prlist,
                               G_SlpdProperty.interfacesLen,
                               G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------------------*/
    /* Check to to see if a this is a special SrvRqst */
    /*------------------------------------------------*/
    if (SLPCompareString(message->body.srvrqst.srvtypelen,
                         message->body.srvrqst.srvtype,
                         15,
                         "directory-agent") == 0)
    {
        errorcode = v1ProcessDASrvRqst(peeraddr, message, sendbuf, errorcode);
        return errorcode;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if (SLPIntersectStringList(message->body.srvrqst.scopelistlen,
                               message->body.srvrqst.scopelist,
                               G_SlpdProperty.useScopesLen,
                               G_SlpdProperty.useScopes) != 0)
    {
        /*-------------------------------*/
        /* Find services in the database */
        /*-------------------------------*/
        errorcode = SLPDDatabaseSrvRqstStart(message, &db);
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }


    RESPOND:
    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if (message->header.flags & SLP_FLAG_MCAST)
    {
        if (errorcode != 0 || db->urlcount == 0)
        {
            result->end = result->start;
            goto FINISHED;  
        }
    }

    /*-------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvrply */
    /*-------------------------------------------------------------*/
    size = 16; /* 12 bytes for header, 2 bytes for error code, 2 bytes
          for url count */
    if (errorcode == 0)
    {
        for (i = 0; i < db->urlcount; i++)
        {
            urllen = INT_MAX;
            errorcode = SLPv1ToEncoding(0, 
                                        &urllen,
                                        message->header.encoding,  
                                        db->urlarray[i]->url,
                                        db->urlarray[i]->urllen);
            if (errorcode)
                break;
            size += urllen + 4; /* 2 bytes for lifetime, 2 bytes for urllen */
        } 
        result = SLPBufferRealloc(result,size);
        if (result == 0)
        {
            errorcode = SLP_ERROR_INTERNAL_ERROR;
        }
    }

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 1;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVRPLY;
    /*length*/
    ToUINT16(result->start + 2, size);
    /*flags - TODO set the flags correctly */
    *(result->start + 4) = message->header.flags |
                           (size > SLP_MAX_DATAGRAM_SIZE ? SLPv1_FLAG_OVERFLOW : 0);  
    /*dialect*/
    *(result->start + 5) = 0;
    /*language code*/
    memcpy(result->start + 6, message->header.langtag, 2);
    ToUINT16(result->start + 8, message->header.encoding);
    /*xid*/
    ToUINT16(result->start + 10, message->header.xid);

    /*-------------------------*/
    /* Add rest of the SrvRply */
    /*-------------------------*/
    result->curpos = result->start + 12;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2;
    if (errorcode == 0)
    {
        /* urlentry count */
        ToUINT16(result->curpos, db->urlcount);
        result->curpos = result->curpos + 2;
        for (i = 0; i < db->urlcount; i++)
        {
            /* url-entry lifetime */
            ToUINT16(result->curpos, db->urlarray[i]->lifetime);
            result->curpos = result->curpos + 2;
            /* url-entry url and urllen */
            urllen = size;      
            errorcode = SLPv1ToEncoding(result->curpos + 2, 
                                        &urllen,
                                        message->header.encoding,  
                                        db->urlarray[i]->url,
                                        db->urlarray[i]->urllen);
            ToUINT16(result->curpos, urllen);
            result->curpos = result->curpos + 2 + urllen;
        }
    }
    else
    {
        /* urlentry count */
        ToUINT16(result->curpos, 0);
        result->curpos = result->curpos + 2;
    }

    FINISHED:   

    SLPDDatabaseSrvRqstEnd(db);

    *sendbuf = result;

    return errorcode;
}