Commit ddd35c0c authored by Dmitry Frank's avatar Dmitry Frank Committed by Cesanta Bot

Fail if authn file is configured but doesn't exist

PUBLISHED_FROM=2c176091ffb6c7c5cfe8ea4f05b6109e00b33383
parent c97b6157
......@@ -4,8 +4,8 @@ decl_name: "mg_http_is_authorized"
symbol_kind: "func"
signature: |
int mg_http_is_authorized(struct http_message *hm, struct mg_str path,
int is_directory, const char *domain,
const char *passwords_file, int is_global_pass_file);
const char *domain, const char *passwords_file,
int flags);
---
Checks whether an http request is authorized. `domain` is the authentication
......
......@@ -7364,17 +7364,17 @@ int mg_check_digest_auth(struct mg_str method, struct mg_str uri,
}
int mg_http_is_authorized(struct http_message *hm, struct mg_str path,
int is_directory, const char *domain,
const char *passwords_file, int is_global_pass_file) {
const char *domain, const char *passwords_file,
int flags) {
char buf[MG_MAX_PATH];
const char *p;
FILE *fp;
int authorized = 1;
if (domain != NULL && passwords_file != NULL) {
if (is_global_pass_file) {
if (flags & MG_AUTH_FLAG_IS_GLOBAL_PASS_FILE) {
fp = mg_fopen(passwords_file, "r");
} else if (is_directory) {
} else if (flags & MG_AUTH_FLAG_IS_DIRECTORY) {
snprintf(buf, sizeof(buf), "%.*s%c%s", (int) path.len, path.p, DIRSEP,
passwords_file);
fp = mg_fopen(buf, "r");
......@@ -7389,24 +7389,24 @@ int mg_http_is_authorized(struct http_message *hm, struct mg_str path,
if (fp != NULL) {
authorized = mg_http_check_digest_auth(hm, domain, fp);
fclose(fp);
} else if (!(flags & MG_AUTH_FLAG_ALLOW_MISSING_FILE)) {
authorized = 0;
}
}
LOG(LL_DEBUG,
("%.*s %s %d %d", (int) path.len, path.p,
passwords_file ? passwords_file : "", is_global_pass_file, authorized));
LOG(LL_DEBUG, ("%.*s %s %x %d", (int) path.len, path.p,
passwords_file ? passwords_file : "", flags, authorized));
return authorized;
}
#else
int mg_http_is_authorized(struct http_message *hm, const struct mg_str path,
int is_directory, const char *domain,
const char *passwords_file, int is_global_pass_file) {
const char *domain, const char *passwords_file,
int flags) {
(void) hm;
(void) path;
(void) is_directory;
(void) domain;
(void) passwords_file;
(void) is_global_pass_file;
(void) flags;
return 1;
}
#endif
......@@ -8010,12 +8010,16 @@ MG_INTERNAL void mg_send_http_file(struct mg_connection *nc, char *path,
if (is_dav && opts->dav_document_root == NULL) {
mg_http_send_error(nc, 501, NULL);
} else if (!mg_http_is_authorized(hm, mg_mk_str(path), is_directory,
opts->auth_domain, opts->global_auth_file,
1) ||
!mg_http_is_authorized(hm, mg_mk_str(path), is_directory,
opts->auth_domain,
opts->per_directory_auth_file, 0)) {
} else if (!mg_http_is_authorized(
hm, mg_mk_str(path), opts->auth_domain, opts->global_auth_file,
((is_directory ? MG_AUTH_FLAG_IS_DIRECTORY : 0) |
MG_AUTH_FLAG_IS_GLOBAL_PASS_FILE |
MG_AUTH_FLAG_ALLOW_MISSING_FILE)) ||
!mg_http_is_authorized(
hm, mg_mk_str(path), opts->auth_domain,
opts->per_directory_auth_file,
((is_directory ? MG_AUTH_FLAG_IS_DIRECTORY : 0) |
MG_AUTH_FLAG_ALLOW_MISSING_FILE))) {
mg_http_send_digest_auth_request(nc, opts->auth_domain);
} else if (is_cgi) {
#if MG_ENABLE_HTTP_CGI
......@@ -8031,11 +8035,14 @@ MG_INTERNAL void mg_send_http_file(struct mg_connection *nc, char *path,
} else if (!mg_vcmp(&hm->method, "PROPFIND")) {
mg_handle_propfind(nc, path, &st, hm, opts);
#if !MG_DISABLE_DAV_AUTH
} else if (is_dav && (opts->dav_auth_file == NULL ||
(strcmp(opts->dav_auth_file, "-") != 0 &&
!mg_http_is_authorized(hm, mg_mk_str(path),
is_directory, opts->auth_domain,
opts->dav_auth_file, 1)))) {
} else if (is_dav &&
(opts->dav_auth_file == NULL ||
(strcmp(opts->dav_auth_file, "-") != 0 &&
!mg_http_is_authorized(
hm, mg_mk_str(path), opts->auth_domain, opts->dav_auth_file,
((is_directory ? MG_AUTH_FLAG_IS_DIRECTORY : 0) |
MG_AUTH_FLAG_IS_GLOBAL_PASS_FILE |
MG_AUTH_FLAG_ALLOW_MISSING_FILE))))) {
mg_http_send_digest_auth_request(nc, opts->auth_domain);
#endif
} else if (!mg_vcmp(&hm->method, "MKCOL")) {
......@@ -8444,9 +8451,8 @@ static void mg_http_call_endpoint_handler(struct mg_connection *nc, int ev,
mg_http_get_endpoint_handler(nc->listener, &hm->uri);
if (ep != NULL) {
#if MG_ENABLE_FILESYSTEM && !MG_DISABLE_HTTP_DIGEST_AUTH
if (!mg_http_is_authorized(hm, hm->uri, 0 /* is_directory */,
ep->auth_domain, ep->auth_file,
1 /* is_global_pass_file */)) {
if (!mg_http_is_authorized(hm, hm->uri, ep->auth_domain, ep->auth_file,
MG_AUTH_FLAG_IS_GLOBAL_PASS_FILE)) {
mg_http_send_digest_auth_request(nc, ep->auth_domain);
return;
}
......
......@@ -4541,6 +4541,13 @@ extern void mg_hash_md5_v(size_t num_msgs, const uint8_t *msgs[],
extern void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],
const size_t *msg_lens, uint8_t *digest);
/*
* Flags for `mg_http_is_authorized()`.
*/
#define MG_AUTH_FLAG_IS_DIRECTORY (1 << 0)
#define MG_AUTH_FLAG_IS_GLOBAL_PASS_FILE (1 << 1)
#define MG_AUTH_FLAG_ALLOW_MISSING_FILE (1 << 2)
/*
* Checks whether an http request is authorized. `domain` is the authentication
* realm, `passwords_file` is a htdigest file (can be created e.g. with
......@@ -4549,8 +4556,8 @@ extern void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],
* http request and returns 1 only if there is a match; 0 otherwise.
*/
int mg_http_is_authorized(struct http_message *hm, struct mg_str path,
int is_directory, const char *domain,
const char *passwords_file, int is_global_pass_file);
const char *domain, const char *passwords_file,
int flags);
/*
* Sends 401 Unauthorized response.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment