Ejemplo n.º 1
0
/*-------------------------------------------------------------------------*/ 
SLPError ProcessSrvReg(PSLPHandleInfo handle)
/*-------------------------------------------------------------------------*/
{
    int                 sock;
    struct sockaddr_in  peeraddr;
    int                 bufsize     = 0;
    char*               buf         = 0;
    char*               curpos      = 0;
    SLPError            result      = 0;

#ifdef ENABLE_SECURITY
    int                 urlauthlen  = 0;
    unsigned char*      urlauth     = 0;
    int                 attrauthlen = 0;
    unsigned char*      attrauth    = 0;

    if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled")))
    {
        result = SLPAuthSignUrl(handle->hspi,
                                0,
                                0,
                                handle->params.reg.urllen,
                                handle->params.reg.url,
                                &urlauthlen,
                                &urlauth);
        if(result == 0)
        {
            result = SLPAuthSignString(handle->hspi,
                                       0,
                                       0,
                                       handle->params.reg.attrlistlen,
                                       handle->params.reg.attrlist,
                                       &attrauthlen,
                                       &attrauth);
        }
        bufsize += urlauthlen;
        bufsize += attrauthlen;
    }
#endif


    /*-------------------------------------------------------------------*/
    /* determine the size of the fixed portion of the SRVREG             */
    /*-------------------------------------------------------------------*/
    bufsize += handle->params.reg.urllen + 6;       /*  1 byte for reserved  */
                                                    /*  2 bytes for lifetime */
                                                    /*  2 bytes for urllen   */
                                                    /*  1 byte for authcount */
    bufsize += handle->params.reg.srvtypelen + 2;   /*  2 bytes for len field */
    bufsize += handle->params.reg.scopelistlen + 2; /*  2 bytes for len field */
    bufsize += handle->params.reg.attrlistlen + 2;  /*  2 bytes for len field */
    bufsize += 1;                                   /*  1 byte for authcount */

    buf = curpos = (char*)xmalloc(bufsize);
    if(buf == 0)
    {
        result = SLP_MEMORY_ALLOC_FAILED;
        goto FINISHED;
    }

    /*------------------------------------------------------------*/
    /* Build a buffer containing the fixed portion of the SRVREG  */
    /*------------------------------------------------------------*/
    /* url-entry reserved */
    *curpos= 0;        
    curpos = curpos + 1;
    /* url-entry lifetime */
    ToUINT16(curpos,handle->params.reg.lifetime);
    curpos = curpos + 2;
    /* url-entry urllen */
    ToUINT16(curpos,handle->params.reg.urllen);
    curpos = curpos + 2;
    /* url-entry url */
    memcpy(curpos,
           handle->params.reg.url,
           handle->params.reg.urllen);
    curpos = curpos + handle->params.reg.urllen;
    /* url-entry authblock */
#ifdef ENABLE_SECURITY
    if(urlauth)
    {
        /* authcount */
        *curpos = 1;
        curpos = curpos + 1;
        /* authblock */
        memcpy(curpos,urlauth,urlauthlen);
        curpos = curpos + urlauthlen;
    }
    else
#endif
    {
        /* authcount */
        *curpos = 0;
        curpos = curpos + 1;
    } 
    /* service type */
    ToUINT16(curpos,handle->params.reg.srvtypelen);
    curpos = curpos + 2;
    memcpy(curpos,
           handle->params.reg.srvtype,
           handle->params.reg.srvtypelen);
    curpos = curpos + handle->params.reg.srvtypelen;
    /* scope list */
    ToUINT16(curpos,handle->params.reg.scopelistlen);
    curpos = curpos + 2;
    memcpy(curpos,
           handle->params.reg.scopelist,
           handle->params.reg.scopelistlen);
    curpos = curpos + handle->params.reg.scopelistlen;
    /* attr list */
    ToUINT16(curpos,handle->params.reg.attrlistlen);
    curpos = curpos + 2;
    memcpy(curpos,
           handle->params.reg.attrlist,
           handle->params.reg.attrlistlen);
    curpos = curpos + handle->params.reg.attrlistlen;
    /* attribute auth block */
#ifdef ENABLE_SECURITY
    if(attrauth)
    {
        /* authcount */
        *curpos = 1;
        curpos = curpos + 1;
        /* authblock */
        memcpy(curpos,attrauth,attrauthlen);
        curpos = curpos + attrauthlen;
    }
    else
#endif
    {
        /* authcount */
        *curpos = 0;
        curpos = curpos + 1;
    }

    /*--------------------------*/
    /* Call the RqstRply engine */
    /*--------------------------*/
    do
    {
        sock = NetworkConnectToSA(handle,
                                  handle->params.reg.scopelist,
                                  handle->params.reg.scopelistlen,
                                  &peeraddr);
        if(sock == -1)
        {
            result = SLP_NETWORK_INIT_FAILED;
            break;
        }

        result = NetworkRqstRply(sock,
                                 &peeraddr,
                                 handle->langtag,
                                 buf,
                                 SLP_FUNCT_SRVREG,
                                 bufsize,
                                 CallbackSrvReg,
                                 handle);
        if(result)
        {
            NetworkDisconnectSA(handle);
        }

    }while(result == SLP_NETWORK_ERROR);


    FINISHED:
    if(buf) xfree(buf);
    
#ifdef ENABLE_SECURITY
    if(urlauth) xfree(urlauth);
    if(attrauth) xfree(attrauth);
#endif 

    return result;
}
Ejemplo n.º 2
0
/** Read service registrations from a text file.
 *
 * A really big and nasty function that reads service registrations from
 * from a file. Don't look at this too hard or you'll be sick. This is by
 * far the most horrible code in OpenSLP. Please volunteer to rewrite it!
 *
 * "THANK GOODNESS this function is only called at startup" -- Matt
 *
 * @param[in] fd - The file to read from.
 * @param[out] msg - A message describing the SrvReg in buf.
 * @param[out] buf - The buffer used to hold @p message data.
 *
 * @return Zero on success. A value greater than zero on error. A value
 *    less than zero on EOF.
 *
 * @note Eventually the caller needs to call SLPBufferFree and
 *    SLPMessageFree to free memory.
 */
int SLPDRegFileReadSrvReg(FILE * fd, SLPMessage ** msg, SLPBuffer * buf)
{
   char * slider1;
   char * slider2;
   char line[4096];

   struct sockaddr_storage peer;
   int result = 0;
   size_t bufsize = 0;
   size_t langtaglen = 0;
   char * langtag = 0;
   size_t scopelistlen = 0;
   char * scopelist = 0;
   size_t urllen = 0;
   char * url = 0;
   int lifetime = 0;
   size_t srvtypelen = 0;
   char * srvtype = 0;
   size_t attrlistlen = 0;
   char * attrlist = 0;
   SLPBuffer tmp;

#ifdef ENABLE_SLPv2_SECURITY
   unsigned char * urlauth = 0;
   int urlauthlen = 0;
   unsigned char * attrauth = 0;
   int attrauthlen = 0;
#endif

   /* give the out params an initial NULL value */
   *buf = 0;
   *msg = 0;

   /* read the next non-white non-comment line from the stream */
   do
   {
      slider1 = RegFileReadLine(fd, line, 4096);
      if (slider1 == 0)
         return -1;

   } while (*slider1 == 0x0d ||  *slider1 == 0x0a);

   /* Parse the url-props */
   slider2 = strchr(slider1, ',');
   if (slider2)
   {
      /* srvurl */
      *slider2 = 0; /* squash comma to null terminate srvurl */
      url = xstrdup(TrimWhitespace(slider1));
      if (url == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      urllen = strlen(url);

      /* derive srvtype from srvurl */
      srvtype = strstr(slider1, "://");
      if (srvtype == 0)
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }
      *srvtype = 0;
      srvtype=xstrdup(TrimWhitespace(slider1));
      if (srvtype == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      srvtypelen = strlen(srvtype);
      slider1 = slider2 + 1;

      /*lang*/
      slider2 = strchr(slider1, ',');
      if (slider2)
      {
         *slider2 = 0; /* squash comma to null terminate lang */
         langtag = xstrdup(TrimWhitespace(slider1));
         if (langtag == 0)
         {
            result = SLP_ERROR_INVALID_REGISTRATION;
            goto CLEANUP;
         }
         langtaglen = strlen(langtag);
         slider1 = slider2 + 1;
      }
      else
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }

      /* ltime */
      slider2 = strchr(slider1,',');
      if (slider2)
      {
         *slider2 = 0; /* squash comma to null terminate ltime */
         lifetime = atoi(slider1);
         slider1 = slider2 + 1;
      }
      else
      {
         lifetime = atoi(slider1);
         slider1 = slider2;
      }
      if (lifetime < 1 || lifetime > SLP_LIFETIME_MAXIMUM)
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }

      /* get the srvtype if one was not derived by the srvurl */
      if (srvtype == 0)
      {
         srvtype = xstrdup(TrimWhitespace(slider1));
         if (srvtype == 0)
         {
            result = SLP_ERROR_INTERNAL_ERROR;
            goto CLEANUP;
         }
         srvtypelen = strlen(srvtype);
         if (srvtypelen == 0)
         {
            result = SLP_ERROR_INVALID_REGISTRATION;
            goto CLEANUP;
         }
      }
   }
   else
   {
      result = SLP_ERROR_INVALID_REGISTRATION;
      goto CLEANUP;
   }

   /* read all the attributes including the scopelist */
   *line=0;
   while (1)
   {
      slider1 = RegFileReadLine(fd,line,4096);
      if (slider1 == 0)
      {
         result = -1;
         break;
      }
      if (*slider1 == 0x0d || *slider1 == 0x0a)
         break;

      /* Check to see if it is the scopes line */
      /* FIXME We can collapse the scope stuff into the value getting and
         just make it a special case (do strcmp on the tag as opposed to the
         line) of attribute getting. */
      if (strncasecmp(slider1,"scopes", 6) == 0)
      {
         /* found scopes line */
         slider2 = strchr(slider1,'=');
         if (slider2)
         {
            slider2++;
            if (*slider2)
            {
               /* just in case some idiot puts multiple scopes lines */
               if (scopelist)
               {
                  result = SLP_ERROR_SCOPE_NOT_SUPPORTED;
                  goto CLEANUP;
               }

               /* make sure there are no spaces in the scope list
      NOTE: There's nothing in the spec that indicates that
      scopes can't contain spaces. Commenting out for now. --jmc
               if (strchr(slider2, ' '))
               {
                  result = SLP_ERROR_SCOPE_NOT_SUPPORTED;
                  goto CLEANUP;
               } */

               scopelist = xstrdup(TrimWhitespace(slider2));
               if (scopelist == 0)
               {
                  result = SLP_ERROR_INTERNAL_ERROR;
                  goto CLEANUP;
               }
               scopelistlen = strlen(scopelist);
            }
         }
      }
      else
      {
         /* line contains an attribute (slow but it works)*/
         /* TODO Fix this so we do not have to realloc memory each time! */
         TrimWhitespace(slider1);

         if (attrlist == 0)
         {
            attrlistlen += strlen(slider1) + 2;
            attrlist = xmalloc(attrlistlen + 1);
            if (attrlist == 0)
            {
               result = SLP_ERROR_INTERNAL_ERROR;
               goto CLEANUP;
            }
            *attrlist = 0;
         }
         else
         {
            char * tmp_attrlist;
            attrlistlen += strlen(slider1) + 3;
            if ((tmp_attrlist = xrealloc(attrlist, attrlistlen + 1)) == 0)
            {
               xfree(attrlist);
               result = SLP_ERROR_INTERNAL_ERROR;
               goto CLEANUP;
            }
            attrlist = tmp_attrlist;
            strcat(attrlist, ",");
         }

         if (attrlist == 0)
         {
            result = SLP_ERROR_INTERNAL_ERROR;
            goto CLEANUP;
         }

         /* we need special case for keywords (why do we need these)
            they seem like a waste of code.  Why not just use booleans */
         if (strchr(slider1, '='))
         {
            /* normal attribute (with '=') */
            strcat(attrlist, "(");
            strcat(attrlist, slider1);
            strcat(attrlist, ")");
         }
         else
         {
            /* keyword (no '=') */
            attrlistlen -= 2; /* subtract 2 bytes for no '(' or ')' */
            strcat(attrlist, slider1);
         }
      }
   }

   /* Set the scope set in properties if not is set */
   if (scopelist == 0)
   {
      scopelist = xstrdup(G_SlpdProperty.useScopes);
      if (scopelist == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      scopelistlen = G_SlpdProperty.useScopesLen;
   }

#ifdef ENABLE_SLPv2_SECURITY
   /* generate authentication blocks */
   if (G_SlpdProperty.securityEnabled)
   {
      SLPAuthSignUrl(G_SlpdSpiHandle, 0, 0, urllen, url,
            &urlauthlen, &urlauth);
      SLPAuthSignString(G_SlpdSpiHandle, 0, 0, attrlistlen, attrlist,
            &attrauthlen, &attrauth);
   }
#endif

   /* allocate buffer for the SrvReg Message */
   bufsize = 14 + langtaglen;    /* 14 bytes for header    */
   bufsize += urllen + 6;        /*  1 byte for reserved   */
                                 /*  2 bytes for lifetime  */
                                 /*  2 bytes for urllen    */
                                 /*  1 byte for authcount  */
   bufsize += srvtypelen + 2;    /*  2 bytes for len field */
   bufsize += scopelistlen + 2;  /*  2 bytes for len field */
   bufsize += attrlistlen + 2;   /*  2 bytes for len field */
   bufsize += 1;                 /*  1 byte for authcount  */

#ifdef ENABLE_SLPv2_SECURITY
   bufsize += urlauthlen;
   bufsize += attrauthlen;
#endif

   tmp = *buf = SLPBufferAlloc(bufsize);
   if (tmp == 0)
   {
      result = SLP_ERROR_INTERNAL_ERROR;
      goto CLEANUP;
   }

   /* now build the SrvReg Message */

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

   /* function id */
   *tmp->curpos++ = SLP_FUNCT_SRVREG;

   /* length */
   PutUINT24(&tmp->curpos, bufsize);

   /* flags */
   PutUINT16(&tmp->curpos, 0);

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

   /* xid */
   PutUINT16(&tmp->curpos, 0);

   /* lang tag len */
   PutUINT16(&tmp->curpos, langtaglen);

   /* lang tag */
   memcpy(tmp->curpos, langtag, langtaglen);
   tmp->curpos += langtaglen;

   /* url-entry reserved */
   *tmp->curpos++ = 0;

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

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

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

   /* url-entry authblock */
#ifdef ENABLE_SLPv2_SECURITY
   if (urlauth)
   {
      /* authcount */
      *tmp->curpos++ = 1;

      /* authblock */
      memcpy(tmp->curpos, urlauth, urlauthlen);
      tmp->curpos += urlauthlen;
   }
   else
#endif
      *tmp->curpos++ = 0;

   /* service type */
   PutUINT16(&tmp->curpos, srvtypelen);
   memcpy(tmp->curpos, srvtype, srvtypelen);
   tmp->curpos += srvtypelen;

   /* scope list */
   PutUINT16(&tmp->curpos, scopelistlen);
   memcpy(tmp->curpos, scopelist, scopelistlen);
   tmp->curpos += scopelistlen;

   /* attr list */
   PutUINT16(&tmp->curpos, attrlistlen);
   memcpy(tmp->curpos, attrlist, attrlistlen);
   tmp->curpos += attrlistlen;

   /* attribute auth block */
#ifdef ENABLE_SLPv2_SECURITY
   if (attrauth)
   {
      /* authcount */
      *tmp->curpos++ = 1;

      /* authblock */
      memcpy(tmp->curpos, attrauth, attrauthlen);
      tmp->curpos += attrauthlen;
   }
   else
#endif
      *tmp->curpos++ = 0;

   /* okay, now comes the really stupid (and lazy part) */
   *msg = SLPMessageAlloc();
   if (*msg == 0)
   {
      SLPBufferFree(*buf);
      *buf = 0;
      result = SLP_ERROR_INTERNAL_ERROR;
      goto CLEANUP;
   }

   /* this should be ok even if we are not supporting IPv4,
    * since it's a static service
    */
   memset(&peer, 0, sizeof(struct sockaddr_in));
   peer.ss_family = AF_UNSPEC;
   ((struct sockaddr_in *)&peer)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   result = SLPMessageParseBuffer(&peer, &peer, *buf, *msg);
   (*msg)->body.srvreg.source = SLP_REG_SOURCE_STATIC;

CLEANUP:

   /* check for errors and free memory */
   switch(result)
   {
      case SLP_ERROR_INTERNAL_ERROR:
         SLPDLog("\nERROR: Out of memory one reg file line:\n   %s\n", line);
         break;

      case SLP_ERROR_INVALID_REGISTRATION:
         SLPDLog("\nERROR: Invalid reg file format near:\n   %s\n", line);
         break;

      case SLP_ERROR_SCOPE_NOT_SUPPORTED:
         SLPDLog("\nERROR: Duplicate scopes or scope list with "
               "embedded spaces near:\n   %s\n", line);
         break;

      default:
         break;
   }

   xfree(langtag);
   xfree(scopelist);
   xfree(url);
   xfree(srvtype);
   xfree(attrlist);

#ifdef ENABLE_SLPv2_SECURITY
   xfree(urlauth);
   xfree(attrauth);
#endif

   return result;
}
Ejemplo n.º 3
0
/** Formats and sends an SLPReg wire buffer request.
 *
 * @param handle - The OpenSLP session handle, containing request 
 *    parameters. See docs for SLPReg.
 *
 * @return Zero on success, or an SLP API error code.
 * 
 * @internal
 */
static SLPError ProcessSrvReg(SLPHandleInfo * handle)
{
   sockfd_t sock;
   uint8_t * buf;
   uint8_t * curpos;
   SLPError serr;
   size_t extoffset = 0;
   int urlauthlen = 0;
   uint8_t * urlauth = 0;
   int attrauthlen = 0;
   uint8_t * attrauth = 0;
   SLPBoolean watchRegPID;
   struct sockaddr_storage saaddr;

#ifdef ENABLE_SLPv2_SECURITY
   if (SLPPropertyAsBoolean("net.slp.securityEnabled"))
   {
      int err = SLPAuthSignUrl(handle->hspi, 0, 0, handle->params.reg.urllen,
            handle->params.reg.url, &urlauthlen, &urlauth);
      if (err == 0)
         err = SLPAuthSignString(handle->hspi, 0, 0,
               handle->params.reg.attrlistlen, handle->params.reg.attrlist,
               &attrauthlen, &attrauth);
      if (err != 0)
         return SLP_AUTHENTICATION_ABSENT;
   }
#endif

   /* Should we send the "Watch Registration PID" extension? */
   watchRegPID = SLPPropertyAsBoolean("net.slp.watchRegistrationPID");

/*  0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                          <URL-Entry>                          \
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | length of service type string |        <service-type>         \
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     length of <scope-list>    |         <scope-list>          \
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  length of attr-list string   |          <attr-list>          \
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |# of AttrAuths |(if present) Attribute Authentication Blocks...\
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
   |    WATCH-PID extension ID     |    next extension offset      \
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
   |  nxo (cont)   |     process identifier to be monitored        \
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
   |  PID (cont)   |
   +-+-+-+-+-+-+-+-+ */

   buf = curpos = xmalloc(
         + SizeofURLEntry(handle->params.reg.urllen, urlauthlen)
         + 2 + handle->params.reg.srvtypelen
         + 2 + handle->params.reg.scopelistlen
         + 2 + handle->params.reg.attrlistlen
         + 1 + attrauthlen 
         + (watchRegPID? (2 + 3 + 4): 0));
   if (buf == 0)
   {
      xfree(urlauth);
      xfree(attrauth);
      return SLP_MEMORY_ALLOC_FAILED;
   }

   /* URL entry */
   PutURLEntry(&curpos, handle->params.reg.lifetime, handle->params.reg.url, 
         handle->params.reg.urllen, urlauth, urlauthlen);

   /* <service-type> */
   PutL16String(&curpos, handle->params.reg.srvtype, 
         handle->params.reg.srvtypelen);

   /* <scope-list> */
   PutL16String(&curpos, handle->params.reg.scopelist,
         handle->params.reg.scopelistlen);

   /* <attr-list> */
   PutL16String(&curpos, handle->params.reg.attrlist, 
         handle->params.reg.attrlistlen);

   /** @todo Handle multiple attribute authentication blocks. */

   /* Attribute Authentication Blocks */
   *curpos++ = attrauth? 1: 0;
   memcpy(curpos, attrauth, attrauthlen);
   curpos += attrauthlen;

   /* SLP_EXTENSION_ID_REG_PID */
   if (watchRegPID)
   {
      extoffset = curpos - buf;

      /** @todo In some future code base, this should be changed to use the 
       * non-deprecated official version, SLP_EXTENSION_ID_REG_PID. For now
       * we need to use the EXPerimental version in order to interoperate
       * properly with OpenSLP 1.x SA's.
       */

      PutUINT16(&curpos, SLP_EXTENSION_ID_REG_PID_EXP);
      PutUINT24(&curpos, 0);
      PutUINT32(&curpos, SLPPidGet());
   }

   /* Call the Request-Reply engine. */
   sock = NetworkConnectToSA(handle, handle->params.reg.scopelist,
         handle->params.reg.scopelistlen, &saaddr);
   if (sock != SLP_INVALID_SOCKET)
   {
      serr = NetworkRqstRply(sock, &saaddr, handle->langtag, extoffset,
            buf, SLP_FUNCT_SRVREG, curpos - buf, CallbackSrvReg, handle);
      if (serr)
         NetworkDisconnectSA(handle);
   }
   else
      serr = SLP_NETWORK_INIT_FAILED;    

   xfree(buf);
   xfree(urlauth);
   xfree(attrauth);

   return serr;
}
Ejemplo n.º 4
0
/*-------------------------------------------------------------------------*/ 
SLPError ProcessSrvDeReg(PSLPHandleInfo handle)
/*-------------------------------------------------------------------------*/
{
    int						sock;
    struct sockaddr_storage peeraddr;
    int						bufsize     = 0;
    char*					buf         = 0;
    char*					curpos      = 0;
    SLPError				result      = 0;

#ifdef ENABLE_SLPv2_SECURITY
    int                 urlauthlen  = 0;
    unsigned char*      urlauth     = 0;
    if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled")))
    {
        result = SLPAuthSignUrl(handle->hspi,
                                0,
                                0,
                                handle->params.dereg.urllen,
                                handle->params.dereg.url,
                                &urlauthlen,
                                &urlauth);
        bufsize += urlauthlen;
    }
#endif

    /*-------------------------------------------------------------------*/
    /* determine the size of the fixed portion of the SRVDEREG           */
    /*-------------------------------------------------------------------*/
    bufsize += handle->params.dereg.scopelistlen + 2; /*  2 bytes for len field*/
    bufsize += handle->params.dereg.urllen + 6;       /*  1 byte for reserved  */
                                                      /*  2 bytes for lifetime */
                                                      /*  2 bytes for urllen   */
                                                      /*  1 byte for authcount */
    bufsize += 2;                                     /*  2 bytes for taglistlen*/
    
    /*--------------------------------------------*/
    /* Allocate a buffer for the SRVDEREG message */
    /*--------------------------------------------*/
    buf = curpos = (char*)xmalloc(bufsize);
    if(buf == 0)
    {
        result = SLP_MEMORY_ALLOC_FAILED;
        goto FINISHED;
    }

    /*------------------------------------------------------------*/
    /* Build a buffer containing the fixed portion of the SRVDEREG*/
    /*------------------------------------------------------------*/
    /* scope list */
    ToUINT16(curpos,handle->params.dereg.scopelistlen);
    curpos = curpos + 2;
    memcpy(curpos,
           handle->params.dereg.scopelist,
           handle->params.dereg.scopelistlen);
    curpos = curpos + handle->params.dereg.scopelistlen;
    /* url-entry reserved */
    *curpos = 0;        
    curpos = curpos + 1;
    /* url-entry lifetime */
    ToUINT16(curpos, 0);
    curpos = curpos + 2;
    /* url-entry urllen */
    ToUINT16(curpos,handle->params.dereg.urllen);
    curpos = curpos + 2;
    /* url-entry url */
    memcpy(curpos,
           handle->params.dereg.url,
           handle->params.dereg.urllen);
    curpos = curpos + handle->params.dereg.urllen;
    /* url-entry authcount */
#ifdef ENABLE_SLPv2_SECURITY
    if(urlauth)
    {
        /* authcount */
        *(curpos) = 1;
        curpos = curpos + 1;
        /* authblock */
        memcpy(curpos,urlauth,urlauthlen);
        curpos = curpos + urlauthlen;
    }
    else
#endif
    {
        /* authcount */
        *(curpos) = 0;
        curpos = curpos + 1;
    } 
    /* tag list */
    /* TODO: No tag list for now put in taglist stuff */
    ToUINT16(curpos,0);

   
    /*--------------------------*/
    /* Call the RqstRply engine */
    /*--------------------------*/
    sock = NetworkConnectToSA(handle,
                              handle->params.reg.scopelist,
                              handle->params.reg.scopelistlen,
                              &peeraddr);
    if(sock >= 0)
    {
        result = NetworkRqstRply(sock,
				 &peeraddr,
				 handle->langtag,
				 0,
				 buf,
				 SLP_FUNCT_SRVDEREG,
				 bufsize,
				 CallbackSrvDeReg,
				 handle);
        if (result)
        {
            NetworkDisconnectSA(handle);
        }           
    }
    else
    {
        result = SLP_NETWORK_INIT_FAILED;
        goto FINISHED;
    }
    
    
    FINISHED:
    if(buf) xfree(buf);
#ifdef ENABLE_SLPv2_SECURITY
    if(urlauth) xfree(urlauth);
#endif

    return result;
}