Skip to content

Commit 1fce718

Browse files
committed
add basic_auth
1 parent bbdb29b commit 1fce718

File tree

3 files changed

+133
-1
lines changed

3 files changed

+133
-1
lines changed

esp32-cam-webserver.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ extern esp_err_t SendPictureHttp();
7676
unsigned long previousMillis;
7777

7878
// Every 5 Minutes
79-
const unsigned long interval = (5 * 1000);
79+
const unsigned long interval = (5 * 60 * 1000);
8080

8181
// Names for the Camera. (set these in myconfig.h)
8282
#if defined(CAM_NAME)

src/httpd_basic_auth.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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+
}

src/httpd_basic_auth.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @file httpd_basic_auth.h
3+
* @brief Basic Authorization Wrapper around Htppd
4+
*/
5+
6+
#include <esp_http_server.h>
7+
8+
#define ESP_ERR_HTTPD_BASIC_AUTH_BASE (ESP_ERR_HTTPD_BASE + 200) /*!< Starting number of HTTPD_BASIC_AUTH error codes */
9+
#define ESP_ERR_HTTPD_BASIC_AUTH_HEADER_NOT_FOUND (ESP_ERR_HTTPD_BASIC_AUTH_BASE + 1) /*!< Authorization header has not found in request */
10+
#define ESP_ERR_HTTPD_BASIC_AUTH_FAIL_TO_GET_HEADER (ESP_ERR_HTTPD_BASIC_AUTH_BASE + 2) /*!< Fail to read authorization header */
11+
#define ESP_ERR_HTTPD_BASIC_AUTH_HEADER_INVALID (ESP_ERR_HTTPD_BASIC_AUTH_BASE + 3) /*!< Invalid format of authorization header */
12+
#define ESP_ERR_HTTPD_BASIC_AUTH_NOT_AUTHORIZED (ESP_ERR_HTTPD_BASIC_AUTH_BASE + 4) /*!< Not authorized */
13+
14+
#ifndef HTTPD_401
15+
#define HTTPD_401 "401 Unauthorized"
16+
#endif
17+
18+
/**
19+
* @brief Send error code 401 and set "WWW-Authenticate" header
20+
* @param[in] req The request being responded to
21+
*
22+
* @return
23+
* - ESP_OK on success
24+
*/
25+
esp_err_t httpd_basic_auth_resp_send_401(httpd_req_t* req);
26+
27+
/**
28+
* @brief Read authorization token from request and compare with provided username and password
29+
* @param[in] req The request being responded to
30+
* @param[in] username Username
31+
* @param[in] password Password
32+
*
33+
* @return
34+
* - ESP_OK user is authorized
35+
* - ESP_ERR_NO_MEM no memory
36+
* - ESP_ERR_HTTPD_BASIC_AUTH_HEADER_NOT_FOUND authorization header is not provided in request
37+
* - ESP_ERR_HTTPD_BASIC_AUTH_FAIL_TO_GET_HEADER fail to read authorization header
38+
* - ESP_ERR_HTTPD_BASIC_AUTH_HEADER_INVALID invalid format of authorization header
39+
* - ESP_ERR_HTTPD_BASIC_AUTH_NOT_AUTHORIZED not authorized
40+
*/
41+
esp_err_t httpd_basic_auth(httpd_req_t* req, const char* username, const char* password);

0 commit comments

Comments
 (0)