summaryrefslogtreecommitdiff
path: root/src/mod_authn_file.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2019-03-05 22:31:41 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2019-03-07 00:32:17 -0500
commitb9e2be50c9772d6c886c2213933da2a6e9bdea6b (patch)
tree0386ce37c500dee23a28770d47e58f039f882266 /src/mod_authn_file.c
parent1fb0d7e295669d59b56679868df8f8724d4dc5af (diff)
downloadlighttpd-git-b9e2be50c9772d6c886c2213933da2a6e9bdea6b.tar.gz
[mod_auth] HTTP Auth Digest algorithm=SHA-256
(also support Digest algorithm=SHA-512-256 if library support present) enable additional algorithms by configuring lighttpd.conf auth.require with new optional keyword "algorithm" => "MD5|SHA-256" default algorithm remains MD5 if "algorithm" not specified Tested with: curl --digest -u "user:pass" ... (which supports SHA-256) x-ref: "HTTP Digest Access Authentication" https://tools.ietf.org/html/rfc7616
Diffstat (limited to 'src/mod_authn_file.c')
-rw-r--r--src/mod_authn_file.c109
1 files changed, 75 insertions, 34 deletions
diff --git a/src/mod_authn_file.c b/src/mod_authn_file.c
index e3a38cb2..6264d62c 100644
--- a/src/mod_authn_file.c
+++ b/src/mod_authn_file.c
@@ -197,6 +197,64 @@ static int mod_authn_file_patch_connection(server *srv, connection *con, plugin_
#undef PATCH
+
+
+#ifdef USE_OPENSSL_CRYPTO
+
+static void mod_authn_file_digest_sha256(http_auth_info_t *ai, const char *pw, size_t pwlen) {
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, (const unsigned char *)ai->username, ai->ulen);
+ SHA256_Update(&ctx, CONST_STR_LEN(":"));
+ SHA256_Update(&ctx, (const unsigned char *)ai->realm, ai->rlen);
+ SHA256_Update(&ctx, CONST_STR_LEN(":"));
+ SHA256_Update(&ctx, (const unsigned char *)pw, pwlen);
+ SHA256_Final(ai->digest, &ctx);
+}
+
+#ifdef SHA512_256_DIGEST_LENGTH
+static void mod_authn_file_digest_sha512_256(http_auth_info_t *ai, const char *pw, size_t pwlen) {
+ SHA512_CTX ctx;
+ SHA512_256_Init(&ctx);
+ SHA512_256_Update(&ctx, (const unsigned char *)ai->username, ai->ulen);
+ SHA512_256_Update(&ctx, CONST_STR_LEN(":"));
+ SHA512_256_Update(&ctx, (const unsigned char *)ai->realm, ai->rlen);
+ SHA512_256_Update(&ctx, CONST_STR_LEN(":"));
+ SHA512_256_Update(&ctx, (const unsigned char *)pw, pwlen);
+ SHA512_256_Final(ai->digest, &ctx);
+}
+#endif
+
+#endif
+
+static void mod_authn_file_digest_md5(http_auth_info_t *ai, const char *pw, size_t pwlen) {
+ li_MD5_CTX ctx;
+ li_MD5_Init(&ctx);
+ li_MD5_Update(&ctx, (const unsigned char *)ai->username, ai->ulen);
+ li_MD5_Update(&ctx, CONST_STR_LEN(":"));
+ li_MD5_Update(&ctx, (const unsigned char *)ai->realm, ai->rlen);
+ li_MD5_Update(&ctx, CONST_STR_LEN(":"));
+ li_MD5_Update(&ctx, (const unsigned char *)pw, pwlen);
+ li_MD5_Final(ai->digest, &ctx);
+}
+
+static void mod_authn_file_digest(http_auth_info_t *ai, const char *pw, size_t pwlen) {
+
+ if (ai->dalgo & HTTP_AUTH_DIGEST_MD5)
+ mod_authn_file_digest_md5(ai, pw, pwlen);
+ #ifdef USE_OPENSSL_CRYPTO
+ else if (ai->dalgo & HTTP_AUTH_DIGEST_SHA256)
+ mod_authn_file_digest_sha256(ai, pw, pwlen);
+ #ifdef SHA512_256_DIGEST_LENGTH
+ else if (ai->dalgo & HTTP_AUTH_DIGEST_SHA512_256)
+ mod_authn_file_digest_sha512_256(ai, pw, pwlen);
+ #endif
+ #endif
+}
+
+
+
+
static int mod_authn_file_htdigest_get_loop(server *srv, FILE *fp, const buffer *auth_fn, http_auth_info_t *ai) {
char f_user[1024];
@@ -280,12 +338,12 @@ static handler_t mod_authn_file_htdigest_digest(server *srv, connection *con, vo
}
static handler_t mod_authn_file_htdigest_basic(server *srv, connection *con, void *p_d, const http_auth_require_t *require, const buffer *username, const char *pw) {
- li_MD5_CTX Md5Ctx;
- unsigned char HA1[16];
-
http_auth_info_t ai;
- ai.dalgo = HTTP_AUTH_DIGEST_MD5;
- ai.dlen = HTTP_AUTH_DIGEST_MD5_BINLEN;
+ unsigned char htdigest[sizeof(ai.digest)];
+
+ /* supports single choice of algorithm for digest stored in htdigest file */
+ ai.dalgo = (require->algorithm & ~HTTP_AUTH_DIGEST_SESS);
+ ai.dlen = http_auth_digest_len(ai.dalgo);
ai.username = username->ptr;
ai.ulen = buffer_string_length(username);
ai.realm = require->realm->ptr;
@@ -293,15 +351,12 @@ static handler_t mod_authn_file_htdigest_basic(server *srv, connection *con, voi
if (mod_authn_file_htdigest_get(srv, con, p_d, &ai)) return HANDLER_ERROR;
- li_MD5_Init(&Md5Ctx);
- li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(username));
- li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
- li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(require->realm));
- li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
- li_MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw));
- li_MD5_Final(HA1, &Md5Ctx);
+ if (ai.dlen > sizeof(htdigest)) return HANDLER_ERROR;/*(should not happen)*/
+ memcpy(htdigest, ai.digest, ai.dlen); /*(save digest before reuse of ai)*/
+
+ mod_authn_file_digest(&ai, pw, strlen(pw));
- return (0 == memcmp(HA1, ai.digest, ai.dlen)
+ return (0 == memcmp(htdigest, ai.digest, ai.dlen)
&& http_auth_match_rules(require, username->ptr, NULL, NULL))
? HANDLER_GO_ON
: HANDLER_ERROR;
@@ -310,11 +365,11 @@ static handler_t mod_authn_file_htdigest_basic(server *srv, connection *con, voi
-static int mod_authn_file_htpasswd_get(server *srv, const buffer *auth_fn, const buffer *username, buffer *password) {
+static int mod_authn_file_htpasswd_get(server *srv, const buffer *auth_fn, const char *username, size_t userlen, buffer *password) {
FILE *fp;
char f_user[1024];
- if (buffer_is_empty(username)) return -1;
+ if (NULL == username) return -1;
if (buffer_string_is_empty(auth_fn)) return -1;
fp = fopen(auth_fn->ptr, "r");
@@ -350,8 +405,7 @@ static int mod_authn_file_htpasswd_get(server *srv, const buffer *auth_fn, const
u_len = f_pwd - f_user;
f_pwd++;
- if (buffer_string_length(username) == u_len &&
- (0 == strncmp(username->ptr, f_user, u_len))) {
+ if (userlen == u_len && 0 == memcmp(username, f_user, u_len)) {
/* found */
size_t pwd_len = strlen(f_pwd);
@@ -370,26 +424,15 @@ static int mod_authn_file_htpasswd_get(server *srv, const buffer *auth_fn, const
static handler_t mod_authn_file_plain_digest(server *srv, connection *con, void *p_d, http_auth_info_t *ai) {
plugin_data *p = (plugin_data *)p_d;
- buffer *username_buf = buffer_init();
buffer *password_buf = buffer_init();/* password-string from auth-backend */
int rc;
mod_authn_file_patch_connection(srv, con, p);
- buffer_copy_string_len(username_buf, ai->username, ai->ulen);
- rc = mod_authn_file_htpasswd_get(srv, p->conf.auth_plain_userfile, username_buf, password_buf);
+ rc = mod_authn_file_htpasswd_get(srv, p->conf.auth_plain_userfile, ai->username, ai->ulen, password_buf);
if (0 == rc) {
/* generate password from plain-text */
- li_MD5_CTX Md5Ctx;
- li_MD5_Init(&Md5Ctx);
- li_MD5_Update(&Md5Ctx, (unsigned char *)username_buf->ptr, buffer_string_length(username_buf));
- li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
- li_MD5_Update(&Md5Ctx, (unsigned char *)ai->realm, ai->rlen);
- li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
- li_MD5_Update(&Md5Ctx, (unsigned char *)password_buf->ptr, buffer_string_length(password_buf));
- li_MD5_Final(ai->digest, &Md5Ctx);
+ mod_authn_file_digest(ai, CONST_BUF_LEN(password_buf));
}
buffer_free(password_buf);
- buffer_free(username_buf);
- UNUSED(con);
return (0 == rc) ? HANDLER_GO_ON : HANDLER_ERROR;
}
@@ -398,12 +441,11 @@ static handler_t mod_authn_file_plain_basic(server *srv, connection *con, void *
buffer *password_buf = buffer_init();/* password-string from auth-backend */
int rc;
mod_authn_file_patch_connection(srv, con, p);
- rc = mod_authn_file_htpasswd_get(srv, p->conf.auth_plain_userfile, username, password_buf);
+ rc = mod_authn_file_htpasswd_get(srv, p->conf.auth_plain_userfile, CONST_BUF_LEN(username), password_buf);
if (0 == rc) {
rc = http_auth_const_time_memeq(CONST_BUF_LEN(password_buf), pw, strlen(pw)) ? 0 : -1;
}
buffer_free(password_buf);
- UNUSED(con);
return 0 == rc && http_auth_match_rules(require, username->ptr, NULL, NULL)
? HANDLER_GO_ON
: HANDLER_ERROR;
@@ -623,7 +665,7 @@ static handler_t mod_authn_file_htpasswd_basic(server *srv, connection *con, voi
buffer *password = buffer_init();/* password-string from auth-backend */
int rc;
mod_authn_file_patch_connection(srv, con, p);
- rc = mod_authn_file_htpasswd_get(srv, p->conf.auth_htpasswd_userfile, username, password);
+ rc = mod_authn_file_htpasswd_get(srv, p->conf.auth_htpasswd_userfile, CONST_BUF_LEN(username), password);
if (0 == rc) {
char sample[256];
rc = -1;
@@ -719,7 +761,6 @@ static handler_t mod_authn_file_htpasswd_basic(server *srv, connection *con, voi
#endif
}
buffer_free(password);
- UNUSED(con);
return 0 == rc && http_auth_match_rules(require, username->ptr, NULL, NULL)
? HANDLER_GO_ON
: HANDLER_ERROR;