Diff for /embedaddon/miniupnpd/upnphttp.c between versions 1.1 and 1.1.1.2

version 1.1, 2012/02/21 23:16:02 version 1.1.1.2, 2012/05/29 12:55:57
Line 2 Line 2
 /* Project :  miniupnp  /* Project :  miniupnp
  * Website :  http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/   * Website :  http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
  * Author :   Thomas Bernard   * Author :   Thomas Bernard
 * Copyright (c) 2005-2008 Thomas Bernard * Copyright (c) 2005-2011 Thomas Bernard
  * This software is subject to the conditions detailed in the   * This software is subject to the conditions detailed in the
  * LICENCE file included in this distribution.   * LICENCE file included in this distribution.
  * */   * */
Line 13 Line 13
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/param.h>  #include <sys/param.h>
   #include <arpa/inet.h>
 #include <syslog.h>  #include <syslog.h>
 #include <ctype.h>  #include <ctype.h>
 #include "config.h"  #include "config.h"
Line 303  ProcessHTTPPOST_upnphttp(struct upnphttp * h) Line 304  ProcessHTTPPOST_upnphttp(struct upnphttp * h)
 }  }
   
 #ifdef ENABLE_EVENTS  #ifdef ENABLE_EVENTS
   /**
    * returns 0 if the callback header value is not valid
    * 1 if it is valid.
    */
   static int
   checkCallbackURL(struct upnphttp * h)
   {
           char addrstr[48];
           int ipv6;
           const char * p;
           int i;
   
           if(!h->req_Callback || h->req_CallbackLen < 8)
                   return 0;
           if(memcmp(h->req_Callback, "http://", 7) != 0)
                   return 0;
           ipv6 = 0;
           i = 0;
           p = h->req_Callback + 7;
           if(*p == '[') {
                   p++;
                   ipv6 = 1;
                   while(*p != ']' && i < (sizeof(addrstr)-1)
                         && p < (h->req_Callback + h->req_CallbackLen))
                           addrstr[i++] = *(p++);
           } else {
                   while(*p != '/' && *p != ':' && i < (sizeof(addrstr)-1)
                         && p < (h->req_Callback + h->req_CallbackLen))
                           addrstr[i++] = *(p++);
           }
           addrstr[i] = '\0';
           if(ipv6) {
                   struct in6_addr addr;
                   if(inet_pton(AF_INET6, addrstr, &addr) <= 0)
                           return 0;
   #ifdef ENABLE_IPV6
                   if(!h->ipv6
                     || (0!=memcmp(&addr, &(h->clientaddr_v6), sizeof(struct in6_addr))))
                           return 0;
   #else
                   return 0;
   #endif
           } else {
                   struct in_addr addr;
                   if(inet_pton(AF_INET, addrstr, &addr) <= 0)
                           return 0;
   #ifdef ENABLE_IPV6
                   if(h->ipv6) {
                           if(!IN6_IS_ADDR_V4MAPPED(&(h->clientaddr_v6)))
                                   return 0;
                           if(0!=memcmp(&addr, ((const char *)&(h->clientaddr_v6) + 12), 4))
                                   return 0;
                   } else {
                           if(0!=memcmp(&addr, &(h->clientaddr), sizeof(struct in_addr)))
                                   return 0;
                   }
   #else
                   if(0!=memcmp(&addr, &(h->clientaddr), sizeof(struct in_addr)))
                           return 0;
   #endif
           }
           return 1;
   }
   
 static void  static void
 ProcessHTTPSubscribe_upnphttp(struct upnphttp * h, const char * path)  ProcessHTTPSubscribe_upnphttp(struct upnphttp * h, const char * path)
 {  {
Line 323  ProcessHTTPSubscribe_upnphttp(struct upnphttp * h, con Line 388  ProcessHTTPSubscribe_upnphttp(struct upnphttp * h, con
          * - respond HTTP/x.x 200 OK            * - respond HTTP/x.x 200 OK 
          * - Send the initial event message */           * - Send the initial event message */
 /* Server:, SID:; Timeout: Second-(xx|infinite) */  /* Server:, SID:; Timeout: Second-(xx|infinite) */
           /* Check that the callback URL is on the same IP as
            * the request, and not on the internet, nor on ourself (DOS attack ?) */
                 if(h->req_Callback) {                  if(h->req_Callback) {
                        sid = upnpevents_addSubscriber(path, h->req_Callback,                        if(checkCallbackURL(h)) {
                                                       h->req_CallbackLen, h->req_Timeout);                                sid = upnpevents_addSubscriber(path, h->req_Callback,
                        h->respflags = FLAG_TIMEOUT;                                                               h->req_CallbackLen, h->req_Timeout);
                        if(sid) {                                h->respflags = FLAG_TIMEOUT;
                                syslog(LOG_DEBUG, "generated sid=%s", sid);                                if(sid) {
                                h->respflags |= FLAG_SID;                                        syslog(LOG_DEBUG, "generated sid=%s", sid);
                                h->req_SID = sid;                                        h->respflags |= FLAG_SID;
                                h->req_SIDLen = strlen(sid);                                        h->req_SID = sid;
                                         h->req_SIDLen = strlen(sid);
                                 }
                                 BuildResp_upnphttp(h, 0, 0);
                         } else {
                                 syslog(LOG_WARNING, "Invalid Callback in SUBSCRIBE %.*s",
                                h->req_CallbackLen, h->req_Callback);
                                 BuildResp2_upnphttp(h, 412, "Precondition Failed", 0, 0);
                         }                          }
                         BuildResp_upnphttp(h, 0, 0);  
                 } else {                  } else {
                         /* subscription renew */                          /* subscription renew */
                         /* Invalid SID                          /* Invalid SID
Line 343  with HTTP error 412 Precondition Failed. */ Line 416  with HTTP error 412 Precondition Failed. */
                         if(renewSubscription(h->req_SID, h->req_SIDLen, h->req_Timeout) < 0) {                          if(renewSubscription(h->req_SID, h->req_SIDLen, h->req_Timeout) < 0) {
                                 BuildResp2_upnphttp(h, 412, "Precondition Failed", 0, 0);                                  BuildResp2_upnphttp(h, 412, "Precondition Failed", 0, 0);
                         } else {                          } else {
                                   h->respflags = FLAG_TIMEOUT;
                                 BuildResp_upnphttp(h, 0, 0);                                  BuildResp_upnphttp(h, 0, 0);
                         }                          }
                 }                  }
Line 429  ProcessHttpQuery_upnphttp(struct upnphttp * h) Line 503  ProcessHttpQuery_upnphttp(struct upnphttp * h)
                         sendXMLdesc(h, genL3F);                          sendXMLdesc(h, genL3F);
                 }                  }
 #endif  #endif
   #ifdef ENABLE_6FC_SERVICE
                   else if(strcasecmp(WANIP6FC_PATH, HttpUrl) == 0)
                   {
                           sendXMLdesc(h, gen6FC);
                   }
   #endif
   #ifdef ENABLE_DP_SERVICE
                   else if(strcasecmp(DP_PATH, HttpUrl) == 0)
                   {
                           sendXMLdesc(h, genDP);
                   }
   #endif
                 else                  else
                 {                  {
                         syslog(LOG_NOTICE, "%s not found, responding ERROR 404", HttpUrl);                          syslog(LOG_NOTICE, "%s not found, responding ERROR 404", HttpUrl);
Line 535  static const char httpresphead[] = Line 621  static const char httpresphead[] =
         "Content-Type: %s\r\n"          "Content-Type: %s\r\n"
         "Connection: close\r\n"          "Connection: close\r\n"
         "Content-Length: %d\r\n"          "Content-Length: %d\r\n"
         /*"Server: miniupnpd/1.0 UPnP/1.0\r\n"*/  
         "Server: " MINIUPNPD_SERVER_STRING "\r\n"          "Server: " MINIUPNPD_SERVER_STRING "\r\n"
         ;       /*"\r\n";*/          ;       /*"\r\n";*/
 /*  /*
Line 560  BuildHeader_upnphttp(struct upnphttp * h, int respcode Line 645  BuildHeader_upnphttp(struct upnphttp * h, int respcode
         {          {
                 templen = sizeof(httpresphead) + 128 + bodylen;                  templen = sizeof(httpresphead) + 128 + bodylen;
                 h->res_buf = (char *)malloc(templen);                  h->res_buf = (char *)malloc(templen);
                   if(!h->res_buf)
                   {
                           syslog(LOG_ERR, "malloc error in BuildHeader_upnphttp()");
                           return;
                   }
                 h->res_buf_alloclen = templen;                  h->res_buf_alloclen = templen;
         }          }
         h->res_buflen = snprintf(h->res_buf, h->res_buf_alloclen,          h->res_buflen = snprintf(h->res_buf, h->res_buf_alloclen,
Line 593  BuildHeader_upnphttp(struct upnphttp * h, int respcode Line 683  BuildHeader_upnphttp(struct upnphttp * h, int respcode
         h->res_buf[h->res_buflen++] = '\n';          h->res_buf[h->res_buflen++] = '\n';
         if(h->res_buf_alloclen < (h->res_buflen + bodylen))          if(h->res_buf_alloclen < (h->res_buflen + bodylen))
         {          {
                h->res_buf = (char *)realloc(h->res_buf, (h->res_buflen + bodylen));                char * tmp;
                h->res_buf_alloclen = h->res_buflen + bodylen;                tmp = (char *)realloc(h->res_buf, (h->res_buflen + bodylen));
                 if(tmp)
                 {
                         h->res_buf = tmp;
                         h->res_buf_alloclen = h->res_buflen + bodylen;
                 }
                 else
                 {
                         syslog(LOG_ERR, "realloc error in BuildHeader_upnphttp()");
                 }
         }          }
 }  }
   
Line 620  BuildResp_upnphttp(struct upnphttp * h, Line 719  BuildResp_upnphttp(struct upnphttp * h,
 void  void
 SendResp_upnphttp(struct upnphttp * h)  SendResp_upnphttp(struct upnphttp * h)
 {  {
        int n;        char * p;
        n = send(h->socket, h->res_buf, h->res_buflen, 0);        ssize_t n;
        if(n<0)        size_t len;
         p = h->res_buf;
         len = h->res_buflen;
         while (len > 0)
         {          {
                syslog(LOG_ERR, "send(res_buf): %m");                n = send(h->socket, p, len, 0);
        }                if(n<0)
        else if(n < h->res_buflen)                {
        {                        syslog(LOG_ERR, "send(res_buf): %m");
                /* TODO : handle correctly this case */                }
                syslog(LOG_ERR, "send(res_buf): %d bytes sent (out of %d)",                else if(n == 0)
                                                n, h->res_buflen);                {
                         syslog(LOG_ERR, "send(res_buf): %zd bytes sent (out of %zu)",
                                                         n, len);
                         break;
                 }
                 else
                 {
                         p += n;
                         len -= n;
                 }
         }          }
 }  }
   

Removed from v.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>