示例#1
0
/*-------------------------------------------------------------------------*/
int ProcessSrvRqst(struct sockaddr_in* peeraddr,
                   SLPMessage message,
                   SLPBuffer* sendbuf,
                   int errorcode)
/*-------------------------------------------------------------------------*/
{
    int                     i;
    int                     size        = 0;
    int                     count       = 0;
    int                     found       = 0;
    SLPDDatabaseSrvUrl*     srvarray    = 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,
                        23,
                        "service:directory-agent") == 0)
    {
        errorcode = ProcessDASrvRqst(peeraddr, message, sendbuf, errorcode);
        return errorcode;
    }
    if(SLPCompareString(message->body.srvrqst.srvtypelen,
                        message->body.srvrqst.srvtype,
                        21,
                        "service:service-agent") == 0)
    {
        errorcode = ProcessSASrvRqst(peeraddr, message, sendbuf, errorcode);
        return errorcode;
    }

    /* TODO: check the spi list of the message and return                  */
    /*       AUTHENTICATION_UNKNOWN since we do not do authentication yet  */

    /*------------------------------------*/
    /* 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 */
        /*-------------------------------*/
        while(found == count)
        {
            count += G_SlpdProperty.maxResults;

            if(srvarray) free(srvarray);
            srvarray = (SLPDDatabaseSrvUrl*)malloc(sizeof(SLPDDatabaseSrvUrl) * count);
            if(srvarray == 0)
            {
                found       = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }

            found = SLPDDatabaseFindSrv(&(message->body.srvrqst), srvarray, count);
            if(found < 0)
            {
                found = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }
        }

        /* remember the amount found if is really big for next time */
        if(found > G_SlpdProperty.maxResults)
        {
            G_SlpdProperty.maxResults = found;
        }
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }


    RESPOND:
    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if(found == 0 ||
       errorcode != 0)
    {
        if(message->header.flags & SLP_FLAG_MCAST ||
           ISMCAST(peeraddr->sin_addr))
        {
            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<found;i++)
        {
            size += srvarray[i].urllen + 6; /*  1 byte for reserved  */
            /*  2 bytes for lifetime */
            /*  2 bytes for urllen   */
            /*  1 byte for authcount */

            /* TODO: Fix this for authentication */
        } 
        result = SLPBufferRealloc(result,size);
        if(result == 0)
        {
            found = 0;
            errorcode = SLP_ERROR_INTERNAL_ERROR;
            goto FINISHED;
        }
    }

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 2;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVRPLY;
    /*length*/
    ToUINT24(result->start + 2, size);
    /*flags*/
    ToUINT16(result->start + 5,
             size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
    /*ext offset*/
    ToUINT24(result->start + 7,0);
    /*xid*/
    ToUINT16(result->start + 10,message->header.xid);
    /*lang tag len*/
    ToUINT16(result->start + 12,message->header.langtaglen);
    /*lang tag*/
    memcpy(result->start + 14,
           message->header.langtag,
           message->header.langtaglen);


    /*-------------------------*/
    /* Add rest of the SrvRply */
    /*-------------------------*/
    result->curpos = result->start + 14 + message->header.langtaglen;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2;
    /* urlentry count */
    ToUINT16(result->curpos, found);
    result->curpos = result->curpos + 2;
    for(i=0;i<found;i++)
    {
        /* url-entry reserved */
        *result->curpos = 0;        
        result->curpos = result->curpos + 1;
        /* url-entry lifetime */
        ToUINT16(result->curpos,srvarray[i].lifetime);
        result->curpos = result->curpos + 2;
        /* url-entry urllen */
        ToUINT16(result->curpos,srvarray[i].urllen);
        result->curpos = result->curpos + 2;
        /* url-entry url */
        memcpy(result->curpos,srvarray[i].url,srvarray[i].urllen);
        result->curpos = result->curpos + srvarray[i].urllen;
        /* url-entry authcount */
        *result->curpos = 0;        
        result->curpos = result->curpos + 1;

        /* TODO: put in authentication stuff too */
    }

    FINISHED:   
    if(srvarray) free(srvarray);

    *sendbuf = result;
    return errorcode;
}
示例#2
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;
}
示例#3
0
/*-------------------------------------------------------------------------*/
void ProcessSrvRqst(SLPDPeerInfo* peerinfo,
                    SLPMessage message,
                    SLPBuffer result)
/*-------------------------------------------------------------------------*/
{
    int                     i;
    int                     size        = 0;
    int                     count       = 0;
    int                     found       = 0;
    SLPDDatabaseSrvUrl*     srvarray    = 0;
    int                     errorcode   = 0;
    

    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if(SLPStringListIntersect(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(SLPStringCompare(message->body.srvrqst.srvtypelen,
			message->body.srvrqst.srvtype,
			23,
			"service:directory-agent") == 0)
    {
        ProcessDASrvRqst(peerinfo,
			 message,
			 result);
        goto FINISHED;
    }
    if(SLPStringCompare(message->body.srvrqst.srvtypelen,
			message->body.srvrqst.srvtype,
			21,
			"service:service-agent") == 0)
    {
        ProcessSASrvRqst(peerinfo,
			 message,
			 result);
        goto FINISHED;
    }
   
    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if(SLPStringListIntersect(message->body.srvrqst.scopelistlen,
                              message->body.srvrqst.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes) != 0)
    {
        /*-------------------------------*/
        /* Find services in the database */
        /*-------------------------------*/
        while(found == count)
        {
            count += SLPDPROCESS_RESULT_COUNT;
        
            if(srvarray) free(srvarray);
            srvarray = (SLPDDatabaseSrvUrl*)malloc(sizeof(SLPDDatabaseSrvUrl) * count);
            if(srvarray == 0)
            {
                found       = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }
        
            found = SLPDDatabaseFindSrv(&(message->body.srvrqst), srvarray, count);
            if(found < 0)
            {
                found = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }
        }
    }
    else
    { 
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }
   
    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if(found <= 0 && (message->header.flags & SLP_FLAG_MCAST))
    {
        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  */ 
    for(i=0;i<found;i++)
    {
        size += srvarray[i].urllen + 6; /*  1 byte for reserved  */
                                                /*  2 bytes for lifetime */
                                                /*  2 bytes for urllen   */
                                                /*  1 byte for authcount */
        
        /* TODO: Fix this for authentication */
    } 
    result = SLPBufferRealloc(result,size);
    if(result == 0)
    {
        found = 0;
        errorcode = SLP_ERROR_INTERNAL_ERROR;
    }

    
    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 2;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVRPLY;
    /*length*/
    ToUINT24(result->start + 2, size);
    /*flags*/
    ToUINT16(result->start + 5,
             size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
    /*ext offset*/
    ToUINT24(result->start + 7,0);
    /*xid*/
    ToUINT16(result->start + 10,message->header.xid);
    /*lang tag len*/
    ToUINT16(result->start + 12,message->header.langtaglen);
    /*lang tag*/
    memcpy(result->start + 14,
           message->header.langtag,
           message->header.langtaglen);
    
    
    /*-------------------------*/
    /* Add rest of the SrvRply */
    /*-------------------------*/
    result->curpos = result->start + 14 + message->header.langtaglen;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2;
    /* urlentry count */
    ToUINT16(result->curpos, found);
    result->curpos = result->curpos + 2;
    for(i=0;i<found;i++)
    {
        /* url-entry reserved */
        *result->curpos = 0;        
        result->curpos = result->curpos + 1;
        /* url-entry lifetime */
        ToUINT16(result->curpos,srvarray[i].lifetime);
        result->curpos = result->curpos + 2;
        /* url-entry urllen */
        ToUINT16(result->curpos,srvarray[i].urllen);
        result->curpos = result->curpos + 2;
        /* url-entry url */
        memcpy(result->curpos,srvarray[i].url,srvarray[i].urllen);
        result->curpos = result->curpos + srvarray[i].urllen;
        /* url-entry authcount */
        *result->curpos = 0;        
        result->curpos = result->curpos + 1;

        /* TODO: put in authentication stuff too */
    }
    
    FINISHED:   
    if(srvarray) free(srvarray);
}