Exemplo n.º 1
0
/** Process a general attribute 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 ProcessAttrRqst(SLPMessage * message, SLPBuffer * sendbuf, 
      int errorcode)
{
   SLPDDatabaseAttrRqstResult * db = 0;
   size_t size = 0;
   SLPBuffer result = *sendbuf;

#ifdef ENABLE_SLPv2_SECURITY
   int i;
   uint8_t * generatedauth = 0;
   int generatedauthlen = 0;
   uint8_t * opaqueauth = 0;
   int opaqueauthlen = 0;
#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.attrrqst.prlistlen, 
         message->body.attrrqst.prlist, G_SlpdProperty.interfacesLen,
         G_SlpdProperty.interfaces))
   {
      /* Silently ignore */
      result->end = result->start;
      goto FINISHED;
   }

   /* make sure that we handle the scope */
   if (SLPIntersectStringList(message->body.attrrqst.scopelistlen, 
         message->body.attrrqst.scopelist, G_SlpdProperty.useScopesLen,
         G_SlpdProperty.useScopes))
   {
      /* 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 ares
         signed in a way the requester can understand
       */
#ifdef ENABLE_SLPv2_SECURITY
      if (G_SlpdProperty.securityEnabled)
      {
         if (message->body.attrrqst.taglistlen == 0)
         {
            /* We can send back entire attribute strings without
               generating a new attribute authentication block
               we just use the one sent by the registering agent
               which we have to have been able to verify
             */
            if (SLPSpiCanVerify(G_SlpdSpiHandle, 
                  message->body.attrrqst.spistrlen,
                  message->body.attrrqst.spistr) == 0)
            {
               errorcode = SLP_ERROR_AUTHENTICATION_UNKNOWN;
               goto RESPOND;
            }
         }
         else
         {
            /* We have to be able to *generate* (sign) authentication
               blocks for attrrqst with taglists since it is possible
               that the returned attributes are a subset of what the
               original registering agent sent
             */
            if (SLPSpiCanSign(G_SlpdSpiHandle, 
                  message->body.attrrqst.spistrlen,
                  message->body.attrrqst.spistr) == 0)
            {
               errorcode = SLP_ERROR_AUTHENTICATION_UNKNOWN;
               goto RESPOND;
            }
         }
      }
      else
      {
         if (message->body.attrrqst.spistrlen)
         {
            errorcode = SLP_ERROR_AUTHENTICATION_UNKNOWN;
            goto RESPOND;
         }
      }
#else
      if (message->body.attrrqst.spistrlen)
      {
         errorcode = SLP_ERROR_AUTHENTICATION_UNKNOWN;
         goto RESPOND;
      }
#endif
      /* Find attributes in the database */
      errorcode = SLPDDatabaseAttrRqstStart(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->attrlistlen == 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 attrrply */
   size = message->header.langtaglen + 19; /* 14 bytes for header     */
   /*  2 bytes for error code */
   /*  2 bytes for attr-list len */
   /*  1 byte for the authcount */ 
   if (errorcode == 0)
   {
      size += db->attrlistlen;

#ifdef ENABLE_SLPv2_SECURITY
      /* Generate authblock if necessary or just use the one was included
         by registering agent.  Reserve sufficent space for either case.
       */
      if (G_SlpdProperty.securityEnabled 
            && message->body.attrrqst.spistrlen)
      {
         if (message->body.attrrqst.taglistlen == 0)
         {
            for (i = 0; i < db->authcount; i++)
            {
               if (SLPCompareString(db->autharray[i].spistrlen, 
                     db->autharray[i].spistr, message->body.attrrqst.spistrlen,
                     message->body.attrrqst.spistr) == 0)
               {
                  opaqueauth = db->autharray[i].opaque;
                  opaqueauthlen = db->autharray[i].opaquelen;
                  break;
               }
            }
         }
         else
         {
            errorcode = SLPAuthSignString(G_SlpdSpiHandle, 
                  message->body.attrrqst.spistrlen,
                  message->body.attrrqst.spistr,
                  db->attrlistlen, db->attrlist,
                  &generatedauthlen, &generatedauth);
            opaqueauthlen = generatedauthlen;
            opaqueauth = generatedauth;
         }
         size += opaqueauthlen;
      }
#endif

   }

   /* alloc the  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_ATTRRPLY;

   /* 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 AttrRqst */

   /* error code*/
   PutUINT16(&result->curpos, errorcode);
   if (errorcode == 0)
   {
      /* attr-list len */
      PutUINT16(&result->curpos, db->attrlistlen);
      if (db->attrlistlen)
         memcpy(result->curpos, db->attrlist, db->attrlistlen);
      result->curpos += db->attrlistlen;

      /* authentication block */
#ifdef ENABLE_SLPv2_SECURITY
      if (opaqueauth)
      {
         /* authcount */
         *result->curpos++ = 1;
         memcpy(result->curpos, opaqueauth, opaqueauthlen);
         result->curpos += opaqueauthlen;
      }
      else
#endif
         *result->curpos++ = 0; /* authcount */
   }

FINISHED:

#ifdef ENABLE_SLPv2_SECURITY    
   /* free the generated authblock if any */
   xfree(generatedauth);
#endif

   if (db) 
      SLPDDatabaseAttrRqstEnd(db);

   *sendbuf = result;

   return errorcode;
}        
Exemplo n.º 2
0
/*-------------------------------------------------------------------------*/
int v1ProcessAttrRqst(struct sockaddr_in* peeraddr,
                      SLPMessage message,
                      SLPBuffer* sendbuf,
                      int errorcode)
/*-------------------------------------------------------------------------*/
{
    SLPDDatabaseAttrRqstResult* db              = 0;
    int                         attrlen     = 0;
    int                         size        = 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.attrrqst.prlistlen,
                               message->body.attrrqst.prlist,
                               G_SlpdProperty.interfacesLen,
                               G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if (SLPIntersectStringList(message->body.attrrqst.scopelistlen,
                               message->body.attrrqst.scopelist,
                               G_SlpdProperty.useScopesLen,
                               G_SlpdProperty.useScopes))
    {
        /*---------------------------------*/
        /* Find attributes in the database */
        /*---------------------------------*/
        errorcode = SLPDDatabaseAttrRqstStart(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->attrlistlen == 0)
        {
            result->end = result->start;
            goto FINISHED;  
        }
    }

    /*--------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole attrrply */
    /*--------------------------------------------------------------*/
    size = 16; /* 12 bytes for header, 2 bytes for error code, 2 bytes
                for attr-list len */
    if (errorcode == 0)
    {

        attrlen = INT_MAX;
        errorcode = SLPv1ToEncoding(0, &attrlen,
                                    message->header.encoding,  
                                    db->attrlist,
                                    db->attrlistlen);
        size += attrlen;
    }

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

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 1;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_ATTRRPLY;
    /*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 AttrRply */
    /*--------------------------*/
    result->curpos = result->start + 12;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2; 
    if (errorcode == 0)
    {
        /* attr-list len */
        ToUINT16(result->curpos, attrlen);
        result->curpos = result->curpos + 2;
        attrlen = size;
        SLPv1ToEncoding(result->curpos, &attrlen,
                        message->header.encoding,
                        db->attrlist,
                        db->attrlistlen);
        result->curpos = result->curpos + attrlen; 
    }

    FINISHED:
    *sendbuf = result;
    if (db) SLPDDatabaseAttrRqstEnd(db);

    return errorcode;
}