You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.2 KiB
101 lines
3.2 KiB
/*
|
|
HTTP auth implementation. Only does basic authentication for now.
|
|
*/
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
|
|
* this notice you can do whatever you want with this stuff. If we meet some day,
|
|
* and you think this stuff is worth it, you can buy me a beer in return.
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "httpd.h"
|
|
#include "httpd-auth.h"
|
|
#include "utils/base64.h"
|
|
#include <ctype.h>
|
|
|
|
// base64 increases length by about 33%
|
|
#define BA_HDRBUFLEN ((AUTH_MAX_USER_LEN + AUTH_MAX_PASS_LEN + 2) * 2)
|
|
|
|
httpd_cgi_state cgiAuthBasic(HttpdConnData *connData)
|
|
{
|
|
int r;
|
|
char hdr[BA_HDRBUFLEN]; // +2 because of the terminator + colon ?
|
|
|
|
if (connData->conn == NULL) {
|
|
//Connection aborted. Clean up.
|
|
return HTTPD_CGI_DONE;
|
|
}
|
|
|
|
r = httpdGetHeader(connData, "Authorization", hdr, sizeof(hdr));
|
|
if (r && strncmp(hdr, "Basic", 5) == 0) {
|
|
const char *token = hdr + 5;
|
|
// discard leading whitepsace
|
|
while (isspace(*token)) {
|
|
token++;
|
|
}
|
|
|
|
r = httpd_base64_decode(strlen(token), token, BA_HDRBUFLEN, (uint8_t *) hdr); // Decoding in-place
|
|
if (r < 0) { r = 0; } //just clean out string on decode error
|
|
hdr[r] = 0; //zero-terminate user:pass string
|
|
|
|
char * colon_ptr = strchr(hdr, ':');
|
|
if (colon_ptr) {
|
|
*colon_ptr = 0; // null-terminate username
|
|
colon_ptr++;
|
|
if (((HttpdBasicAuthCb) (connData->cgiArg))(connData, hdr, colon_ptr)) {
|
|
return HTTPD_CGI_AUTHENTICATED;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Not authenticated. Go bug user with login screen.
|
|
httpdStartResponse(connData, 401);
|
|
httpdHeader(connData, "Content-Type", "text/plain");
|
|
httpdHeader(connData, "WWW-Authenticate", "Basic realm=\""HTTP_AUTH_REALM"\"");
|
|
httpdEndHeaders(connData);
|
|
httpdSendStr(connData, "401 Unauthorized.");
|
|
//Okay, all done.
|
|
return HTTPD_CGI_DONE;
|
|
}
|
|
|
|
|
|
httpd_cgi_state cgiAuthBearer(HttpdConnData *connData)
|
|
{
|
|
int r;
|
|
char hdr[AUTH_MAX_TOKEN_LEN + 1];
|
|
|
|
if (connData->conn == NULL) {
|
|
//Connection aborted. Clean up.
|
|
return HTTPD_CGI_DONE;
|
|
}
|
|
|
|
r = httpdGetHeader(connData, "Authorization", hdr, sizeof(hdr));
|
|
if (r && strncmp(hdr, "Bearer", 6) == 0) {
|
|
// Don't base64-decode, token may not be encoded!
|
|
hdr[AUTH_MAX_TOKEN_LEN] = 0; //zero-terminate
|
|
|
|
char *token = hdr + 6;
|
|
|
|
// discard leading whitepsace
|
|
while (isspace(*token)) {
|
|
token++;
|
|
}
|
|
|
|
if (((HttpdBearerAuthCb) (connData->cgiArg))(connData, token)) {
|
|
return HTTPD_CGI_AUTHENTICATED;
|
|
}
|
|
}
|
|
|
|
//Not authenticated. Go bug user with login screen.
|
|
httpdStartResponse(connData, 401);
|
|
httpdHeader(connData, "Content-Type", "text/plain");
|
|
httpdHeader(connData, "WWW-Authenticate", "Basic realm=\""HTTP_AUTH_REALM"\"");
|
|
httpdEndHeaders(connData);
|
|
httpdSendStr(connData, "401 Unauthorized.");
|
|
//Okay, all done.
|
|
return HTTPD_CGI_DONE;
|
|
}
|
|
|
|
|