HTTP: fix stack overwrite due to format string error.
[silc.git] / lib / silchttp / silchttpserver.c
index d2700ff20749dfb42d1fd2730ff2f7f20d489111..e83d2f379b274f1106774bbc754ecb98ecf8482d 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2006 Pekka Riikonen
+  Copyright (C) 2006 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@ struct SilcHttpServerStruct {
 /* HTTP connection context */
 struct SilcHttpConnectionStruct {
   struct SilcHttpConnectionStruct *next;
+  struct SilcHttpConnectionStruct *next2;
   SilcHttpServer httpd;                    /* Server */
   SilcStream stream;               /* Connection stream */
   SilcBuffer inbuf;                /* Read data buffer */
@@ -81,6 +82,7 @@ static void silc_http_server_close_connection(SilcHttpConnection conn)
   silc_schedule_task_del_by_context(conn->httpd->schedule, conn);
   silc_stream_set_notifier(conn->stream, conn->httpd->schedule, NULL, NULL);
   silc_stream_destroy(conn->stream);
+  conn->stream = NULL;
 
   /* Add to free list */
   silc_list_add(conn->httpd->conns, conn);
@@ -144,7 +146,7 @@ static SilcBool silc_http_server_parse(SilcHttpServer httpd,
     SILC_LOG_DEBUG(("URI: '%s'", conn->uri));
 
     /* Protocol version compatibility */
-    tmp = memchr(tmp, '\0', data_len - (tmp - data)) + 1;
+    tmp = ((unsigned char *)memchr(tmp, '\0', data_len - (tmp - data))) + 1;
     SILC_LOG_DEBUG(("Protocol: %s", tmp));
     if (strstr(tmp, "HTTP/1.0"))
       conn->keepalive = FALSE;
@@ -192,7 +194,7 @@ static SilcBool silc_http_server_parse(SilcHttpServer httpd,
 
     /* Check we have received all data */
     cl = silc_mime_get_field(conn->curheaders, "Content-Length");
-    if (cl && sscanf(cl, "%lu", (unsigned long *)&cll) == 1) {
+    if (cl && sscanf(cl, "%u", &cll) == 1) {
       if (data_len < cll) {
        /* More data to come */
        silc_mime_free(conn->curheaders);
@@ -476,6 +478,9 @@ SilcHttpServer silc_http_server_alloc(const char *ip, SilcUInt16 port,
   httpd->callback = callback;
   httpd->context = context;
 
+  silc_list_init(httpd->conns, struct SilcHttpConnectionStruct, next);
+  silc_list_init(httpd->allconns, struct SilcHttpConnectionStruct, next2);
+
   /* Allocate connections list */
   for (i = 0; i < SILC_HTTP_SERVER_CONNS; i++) {
     conn = silc_http_server_alloc_connection();
@@ -483,6 +488,7 @@ SilcHttpServer silc_http_server_alloc(const char *ip, SilcUInt16 port,
       break;
     silc_list_add(httpd->conns, conn);
     silc_list_add(httpd->allconns, conn);
+    conn->httpd = httpd;
   }
 
   SILC_LOG_DEBUG(("HTTP Server started"));
@@ -499,7 +505,8 @@ void silc_http_server_free(SilcHttpServer httpd)
   silc_list_start(httpd->allconns);
   while ((conn = silc_list_get(httpd->allconns))) {
     conn->keepalive = FALSE;
-    silc_http_server_close_connection(conn);
+    if (conn->httpd && conn->stream)
+      silc_http_server_close_connection(conn);
     silc_buffer_free(conn->inbuf);
     silc_buffer_free(conn->outbuf);
     silc_free(conn);
@@ -547,11 +554,11 @@ SilcBool silc_http_server_send(SilcHttpServer httpd,
 
   silc_mime_add_field(conn->headers, "Last-Modified",
                      silc_time_string(conn->touched));
-  snprintf(tmp, sizeof(tmp), "%d", (int)silc_buffer_len(data));
+  silc_snprintf(tmp, sizeof(tmp), "%d", (int)silc_buffer_len(data));
   silc_mime_add_field(conn->headers, "Content-Length", tmp);
   if (conn->keepalive) {
     silc_mime_add_field(conn->headers, "Connection", "keep-alive");
-    snprintf(tmp, sizeof(tmp), "%d", (int)SILC_HTTP_SERVER_TIMEOUT);
+    silc_snprintf(tmp, sizeof(tmp), "%d", (int)SILC_HTTP_SERVER_TIMEOUT);
     silc_mime_add_field(conn->headers, "Keep-alive", tmp);
   }