From ddd35c0cba9869a19ce846b1f14567cdcb1fbdeb Mon Sep 17 00:00:00 2001 From: Dmitry Frank Date: Tue, 28 Nov 2017 13:48:57 +0200 Subject: [PATCH] Fail if authn file is configured but doesn't exist PUBLISHED_FROM=2c176091ffb6c7c5cfe8ea4f05b6109e00b33383 --- docs/c-api/http.h/mg_http_is_authorized.md | 4 +- mongoose.c | 56 ++++++++++++---------- mongoose.h | 11 ++++- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/docs/c-api/http.h/mg_http_is_authorized.md b/docs/c-api/http.h/mg_http_is_authorized.md index 92e05e2a..97f029ab 100644 --- a/docs/c-api/http.h/mg_http_is_authorized.md +++ b/docs/c-api/http.h/mg_http_is_authorized.md @@ -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 diff --git a/mongoose.c b/mongoose.c index d9fff80d..83d86e64 100644 --- a/mongoose.c +++ b/mongoose.c @@ -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; } diff --git a/mongoose.h b/mongoose.h index e112a940..2e9324eb 100644 --- a/mongoose.h +++ b/mongoose.h @@ -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.