Bladeren bron

Server should check the nonce - see http://en.wikipedia.org/wiki/Digest_access_authentication#Advantages

bel 11 jaren geleden
bovenliggende
commit
903287ff0a
1 gewijzigde bestanden met toevoegingen van 23 en 1 verwijderingen
  1. 23 1
      src/civetweb.c

+ 23 - 1
src/civetweb.c

@@ -617,6 +617,9 @@ struct mg_context {
     int workerthreadcount;     /* The amount of worker threads. */
     pthread_t *workerthreadids;/* The worker thread IDs. */
 
+    unsigned long start_time;  /* Server start time, used for authentication */
+    unsigned long nonce_count; /* Used nonces, used for authentication */
+
     /* linked list of uri handlers */
     struct mg_request_handler_info *request_handlers;
 };
@@ -2760,6 +2763,14 @@ static int parse_auth_header(struct mg_connection *conn, char *buf,
     if ((s == NULL) || (*s != 0)) {
         return 0;
     }
+    nonce ^= (unsigned long)(conn->ctx);
+    if (nonce<conn->ctx->start_time) {
+        /* nonce is from a previous start of the server and no longer valid (replay attack?) */
+        return 0;
+    }
+    if (nonce>=conn->ctx->start_time+conn->ctx->nonce_count) {
+        return 0;
+    }
 
     /* CGI needs it as REMOTE_USER */
     if (ah->user != NULL) {
@@ -2862,8 +2873,14 @@ static void send_authorization_request(struct mg_connection *conn)
 {
     char date[64];
     time_t curtime = time(NULL);
-    unsigned long nonce = (unsigned long)curtime ^ (unsigned long)conn;
+    unsigned long nonce = (unsigned long)(conn->ctx->start_time);
+
+    (void)pthread_mutex_lock(&conn->ctx->mutex);
+    nonce += conn->ctx->nonce_count;
+    ++conn->ctx->nonce_count;
+    (void)pthread_mutex_unlock(&conn->ctx->mutex);
 
+    nonce ^= (unsigned long)(conn->ctx);
     conn->status_code = 401;
     conn->must_close = 1;
 
@@ -6197,12 +6214,17 @@ static void master_thread_run(void *thread_func_param)
     }
 #endif
 
+    /* Initialize thread local storage */
 #if defined(_WIN32) && !defined(__SYMBIAN32__)
     tls.pthread_cond_helper_mutex = CreateEvent(NULL, FALSE, FALSE, NULL);
 #endif
     tls.is_master = 1;
     pthread_setspecific(sTlsKey, &tls);
 
+    /* Server starts *now* */
+    ctx->start_time = (unsigned long)time(NULL);
+
+    /* Allocate memory for the listening sockets, and start the server */
     pfd = (struct pollfd *) calloc(ctx->num_listening_sockets, sizeof(pfd[0]));
     while (pfd != NULL && ctx->stop_flag == 0) {
         for (i = 0; i < ctx->num_listening_sockets; i++) {