1+ #include " src/httpd_basic_auth.h"
2+ #include " mbedtls/base64.h"
3+
4+ #include < esp_log.h>
5+
6+ static const char *TAG = " httpd_basic_auth" ;
7+
8+ esp_err_t httpd_basic_auth_resp_send_401 (httpd_req_t * req) {
9+ esp_err_t ret = httpd_resp_set_status (req, HTTPD_401);
10+
11+ ESP_LOGD (TAG, " httpd_basic_auth_resp_send_401" );
12+ if (ret == ESP_OK) {
13+ ret = httpd_resp_set_hdr (req, " WWW-Authenticate" , " Basic realm=\" User Visible Realm\" " );
14+ }
15+
16+ return ret;
17+ }
18+
19+ esp_err_t httpd_basic_auth (httpd_req_t * req, const char * username, const char * password) {
20+ size_t auth_head_len = 1 + httpd_req_get_hdr_value_len (req, " Authorization" );
21+ size_t n = 0 ;
22+ size_t out;
23+
24+ ESP_LOGD (TAG, " httpd_basic_auth" );
25+
26+ if (auth_head_len <= 1 + 7 ) {
27+
28+ ESP_LOGE (TAG, " ESP_ERR_HTTPD_BASIC_AUTH_HEADER_NOT_FOUND" );
29+ return ESP_ERR_HTTPD_BASIC_AUTH_HEADER_NOT_FOUND;
30+ }
31+
32+ char * auth_head = (char *)malloc (auth_head_len);
33+
34+ if (auth_head == NULL ) {
35+ return ESP_ERR_NO_MEM;
36+ }
37+
38+ if (httpd_req_get_hdr_value_str (req, " Authorization" , auth_head, auth_head_len) != ESP_OK) {
39+ free (auth_head);
40+ return ESP_ERR_HTTPD_BASIC_AUTH_FAIL_TO_GET_HEADER;
41+ }
42+
43+ ESP_LOGD (TAG, " Header: '%s'" , auth_head);
44+
45+ if (strncmp (" Basic" , auth_head, 5 ) != 0 ) {
46+ free (auth_head);
47+ return ESP_ERR_HTTPD_BASIC_AUTH_HEADER_INVALID;
48+ }
49+
50+ mbedtls_base64_decode (NULL , 0 , &n, (const unsigned char *)(auth_head + 6 ), auth_head_len - 6 - 1 );
51+
52+ unsigned char * decoded = (unsigned char *) calloc (1 , 6 + n + 1 );
53+
54+ if (decoded) {
55+ strcpy ((char *)decoded, " Basic " );
56+ int err = mbedtls_base64_decode (decoded, n, &out, (const unsigned char *)(auth_head + 6 ), auth_head_len - 6 - 1 );
57+ if (err != 0 ) {
58+ free (auth_head);
59+ free (decoded);
60+ ESP_LOGE (TAG, " ESP_ERR_HTTPD_BASIC_AUTH_HEADER_INVALID" );
61+ return ESP_ERR_HTTPD_BASIC_AUTH_HEADER_INVALID;
62+ }
63+ }
64+
65+ free (auth_head);
66+
67+ char * colonDelimiter = strchr ((const char *) decoded, ' :' );
68+
69+ if (colonDelimiter == NULL ) {
70+ free (decoded);
71+ ESP_LOGE (TAG, " ESP_ERR_HTTPD_BASIC_AUTH_HEADER_INVALID2" );
72+
73+ return ESP_ERR_HTTPD_BASIC_AUTH_HEADER_INVALID;
74+ }
75+
76+ size_t head_username_len = colonDelimiter - (const char *) decoded;
77+ size_t head_password_len = strlen (colonDelimiter + 1 );
78+
79+ if (strlen (username) != head_username_len
80+ || strlen (password) != head_password_len
81+ || strncmp (username, (const char *) decoded, head_username_len) != 0
82+ || strncmp (password, colonDelimiter + 1 , head_password_len) != 0 ) {
83+ free (decoded);
84+ ESP_LOGD (TAG, " ESP_ERR_HTTPD_BASIC_AUTH_NOT_AUTHORIZED" );
85+ return ESP_ERR_HTTPD_BASIC_AUTH_NOT_AUTHORIZED;
86+ }
87+
88+ free (decoded);
89+
90+ return ESP_OK;
91+ }
0 commit comments