Here's my patch.
It does not handle the case of having some pages in a protected area and
some others not.
Also I'm doubt if the correct writing is HTTP/1.0 401 Unauthorized
or HTTP/1.1 401 Unauthorized
(Don't know the difference between 1.0 and 1.1)

Il giorno gio 23 apr 2020 alle ore 12:10 Marco Lazzaroni <motum...@gmail.com>
ha scritto:

> Il giorno gio 23 apr 2020 alle ore 11:17 Ben Stuyts <b...@altus-escon.com>
> ha scritto:
>
>> Hi Marco,
>>
>> Sounds good! I’m interested in this. Would it be possible for you to post
>> a complete patch?
>>
>> Sure I'll do it! Anyway I must say that it's not fully tested and I think
> it works only if you enable  LWIP_HTTPD_SUPPORT_EXTSTATUS. Instead, it
> should work also without enabling LWIP_HTTP_DYNAMIC_HEADERS like I did.
>
diff -u a/httpd.c b/httpd.c
--- a/httpd.c	2020-04-23 12:22:52.163327518 +0200
+++ b/httpd.c	2020-04-23 16:15:53.854185917 +0200
@@ -311,6 +311,12 @@
 static err_t http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, u8_t tag_check, char *params);
 static err_t http_poll(void *arg, struct altcp_pcb *pcb);
 static u8_t http_check_eof(struct altcp_pcb *pcb, struct http_state *hs);
+
+#if LWIP_HTTPD_BASIC_AUTH == 1
+/* must be provided externally */
+char http_basic_credentials_ok(char* credentials, int len); 
+#endif /* LWIP_HTTPD_BASIC_AUTH */
+
 #if LWIP_HTTPD_FS_ASYNC_READ
 static void http_continue(void *connection);
 #endif /* LWIP_HTTPD_FS_ASYNC_READ */
@@ -874,12 +880,18 @@
      special case.  We assume that any filename with "404" in it must be
      indicative of a 404 server error whereas all other files require
      the 200 OK header. */
-  if (strstr(uri, "404.") == uri) {
+  if (strstr(uri, "/404.") == uri) { /* see https://savannah.nongnu.org/bugs/?58223 */
     hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND];
-  } else if (strstr(uri, "400.") == uri) {
+  } else if (strstr(uri, "/400.") == uri) {
     hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_BAD_REQUEST];
-  } else if (strstr(uri, "501.") == uri) {
+  } else if (strstr(uri, "/501.") == uri) {
     hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_IMPL];
+#if LWIP_HTTPD_BASIC_AUTH == 1	 
+  } else if (strstr(uri, "/401.") == uri) {
+    hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = "HTTP/1.0 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"Access to site\"\r\n";  /* 1.0 or 1.1? */
+  } else if (strstr(uri, "/403.") == uri) {
+    hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = "HTTP/1.0 403 Forbidden\r\n";  /* 1.0 or 1.1? */	  
+#endif /* LWIP_HTTPD_BASIC_AUTH */
   } else {
     hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_OK];
   }
@@ -1655,12 +1667,27 @@
     uri1 = "/501.html";
     uri2 = "/501.htm";
     uri3 = "/501.shtml";
+#if LWIP_HTTPD_BASIC_AUTH == 1	  
+  } else if (error_nr == 401) { 
+    uri1 = "/401.html";
+    uri2 = "/401.htm";
+    uri3 = "/401.shtml";
+  } else if (error_nr == 403) { 
+    uri1 = "/403.html";
+    uri2 = "/403.htm";
+    uri3 = "/403.shtml";  
+  } else if (error_nr == 404) { 
+    uri1 = "/404.html";
+    uri2 = "/404.htm";
+    uri3 = "/404.shtml";
+#endif	/* LWIP_HTTPD_BASIC_AUTH */
   } else {
     /* 400 (bad request is the default) */
     uri1 = "/400.html";
     uri2 = "/400.htm";
     uri3 = "/400.shtml";
   }
+
   if (fs_open(&hs->file_handle, uri1) == ERR_OK) {
     uri = uri1;
   } else if (fs_open(&hs->file_handle, uri2) == ERR_OK) {
@@ -2084,7 +2111,25 @@
           } else {
             hs->keepalive = 0;
           }
-#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */
+#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ 
+#if LWIP_HTTPD_BASIC_AUTH == 1				
+          char* authorization_header = lwip_strnstr(data, CRLF "Authorization: Basic ", data_len);
+          if(authorization_header == NULL)    
+          {
+            /* Header is missing -> HTTP status code 401 */
+            return http_find_error_file(hs, 401);
+          }
+          /* skips CRLF */
+          authorization_header+=2;		
+          char* credentials = &authorization_header[strlen("Authorization: Basic ")];
+          int credentials_left_len = (u16_t)(data_len - ((credentials + 1) - data));
+          char* credentials_end = lwip_strnstr(credentials + 1, CRLF, credentials_left_len);
+          if(!http_basic_credentials_ok(credentials,credentials_end-credentials))
+          {	
+            /* wrong credentials, returns 401 in order to give another chance */
+            return http_find_error_file(hs, 401);
+          }
+#endif /* LWIP_HTTPD_BASIC_AUTH */
           /* null-terminate the METHOD (pbuf is freed anyway wen returning) */
           *sp1 = 0;
           uri[uri_len] = 0;
_______________________________________________
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to