/* HTTP auth implementation. Only does basic authentication for now. */ /* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * Jeroen Domburg 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-auth.h" #include "httpd.h" #include "utils/base64.h" #include // 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; }