basic_auth.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "basic_auth.h"
  2. #include "read_network_config.h"
  3. #include <esp_tls_crypto.h>
  4. #include <esp_log.h>
  5. #define HTTPD_401 "401 UNAUTHORIZED"
  6. static const char *TAG = "HTTPAUTH";
  7. typedef struct
  8. {
  9. const char *username;
  10. const char *password;
  11. } basic_auth_info_t;
  12. basic_auth_info_t basic_auth_info = {NULL, NULL};
  13. void init_basic_auth()
  14. {
  15. if (!network_config.http_username.empty() && !network_config.http_password.empty())
  16. {
  17. basic_auth_info.username = network_config.http_username.c_str();
  18. basic_auth_info.password = network_config.http_password.c_str();
  19. }
  20. }
  21. static char *http_auth_basic(const char *username, const char *password)
  22. {
  23. int out;
  24. char *user_info = NULL;
  25. char *digest = NULL;
  26. size_t n = 0;
  27. asprintf(&user_info, "%s:%s", username, password);
  28. if (!user_info)
  29. {
  30. ESP_LOGE(TAG, "No enough memory for user information");
  31. return NULL;
  32. }
  33. esp_crypto_base64_encode(NULL, 0, &n, (const unsigned char *)user_info, strlen(user_info));
  34. /* 6: The length of the "Basic " string
  35. * n: Number of bytes for a base64 encode format
  36. * 1: Number of bytes for a reserved which be used to fill zero
  37. */
  38. digest = static_cast<char *>(calloc(1, 6 + n + 1));
  39. if (digest)
  40. {
  41. strcpy(digest, "Basic ");
  42. esp_crypto_base64_encode((unsigned char *)digest + 6, n, (size_t *)&out, (const unsigned char *)user_info, strlen(user_info));
  43. }
  44. free(user_info);
  45. return digest;
  46. }
  47. esp_err_t basic_auth_request_filter(httpd_req_t *req, esp_err_t original_handler(httpd_req_t *))
  48. {
  49. char *buf = NULL;
  50. size_t buf_len = 0;
  51. esp_err_t ret = ESP_OK;
  52. char unauthorized[] = "You are not authorized to use this website!";
  53. if (basic_auth_info.username == NULL || basic_auth_info.password == NULL)
  54. {
  55. ret = original_handler(req);
  56. }
  57. else
  58. {
  59. buf_len = httpd_req_get_hdr_value_len(req, "Authorization") + 1;
  60. if (buf_len > 1)
  61. {
  62. buf = static_cast<char *>(calloc(1, buf_len));
  63. if (!buf)
  64. {
  65. ESP_LOGE(TAG, "No enough memory for basic authorization");
  66. return ESP_ERR_NO_MEM;
  67. }
  68. if (httpd_req_get_hdr_value_str(req, "Authorization", buf, buf_len) == ESP_OK)
  69. {
  70. ESP_LOGI(TAG, "Found header => Authorization: %s", buf);
  71. }
  72. else
  73. {
  74. ESP_LOGE(TAG, "No auth value received");
  75. }
  76. char *auth_credentials = http_auth_basic(basic_auth_info.username, basic_auth_info.password);
  77. if (!auth_credentials)
  78. {
  79. ESP_LOGE(TAG, "No enough memory for basic authorization credentials");
  80. free(buf);
  81. return ESP_ERR_NO_MEM;
  82. }
  83. if (strncmp(auth_credentials, buf, buf_len))
  84. {
  85. ESP_LOGE(TAG, "Not authenticated");
  86. httpd_resp_set_status(req, HTTPD_401);
  87. httpd_resp_set_type(req, HTTPD_TYPE_TEXT);
  88. httpd_resp_set_hdr(req, "Connection", "keep-alive");
  89. httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic realm=\"AIOTED\"");
  90. httpd_resp_send(req, unauthorized, strlen(unauthorized));
  91. }
  92. else
  93. {
  94. ESP_LOGI(TAG, "Authenticated calling http handler now!");
  95. ret = original_handler(req);
  96. }
  97. free(auth_credentials);
  98. free(buf);
  99. }
  100. else
  101. {
  102. ESP_LOGE(TAG, "No auth header received");
  103. httpd_resp_set_status(req, HTTPD_401);
  104. httpd_resp_set_type(req, HTTPD_TYPE_TEXT);
  105. httpd_resp_set_hdr(req, "Connection", "keep-alive");
  106. httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic realm=\"AIOTED\"");
  107. httpd_resp_send(req, unauthorized, strlen(unauthorized));
  108. }
  109. }
  110. return ret;
  111. }