1 /* 2 * mod_auth_api - HTTP Auth backend registration, low-level shared funcs 3 * 4 * Fully-rewritten from original 5 * Copyright(c) 2016 Glenn Strauss gstrauss()gluelogic.com All rights reserved 6 * License: BSD 3-clause (same as lighttpd) 7 */ 8 #include "first.h" 9 10 #include "mod_auth_api.h" 11 #include "http_header.h" 12 13 #include <stdlib.h> 14 #include <string.h> 15 16 17 static http_auth_scheme_t http_auth_schemes[8]; 18 19 const http_auth_scheme_t * http_auth_scheme_get (const buffer *name) 20 { 21 int i = 0; 22 while (NULL != http_auth_schemes[i].name 23 && 0 != strcmp(http_auth_schemes[i].name, name->ptr)) { 24 ++i; 25 } 26 return (NULL != http_auth_schemes[i].name) ? http_auth_schemes+i : NULL; 27 } 28 29 void http_auth_scheme_set (const http_auth_scheme_t *scheme) 30 { 31 unsigned int i = 0; 32 while (NULL != http_auth_schemes[i].name) ++i; 33 /*(must resize http_auth_schemes[] if too many different auth schemes)*/ 34 force_assert(i<(sizeof(http_auth_schemes)/sizeof(http_auth_scheme_t))-1); 35 memcpy(http_auth_schemes+i, scheme, sizeof(http_auth_scheme_t)); 36 } 37 38 39 static http_auth_backend_t http_auth_backends[12]; 40 41 const http_auth_backend_t * http_auth_backend_get (const buffer *name) 42 { 43 int i = 0; 44 while (NULL != http_auth_backends[i].name 45 && 0 != strcmp(http_auth_backends[i].name, name->ptr)) { 46 ++i; 47 } 48 return (NULL != http_auth_backends[i].name) ? http_auth_backends+i : NULL; 49 } 50 51 void http_auth_backend_set (const http_auth_backend_t *backend) 52 { 53 unsigned int i = 0; 54 while (NULL != http_auth_backends[i].name) ++i; 55 /*(must resize http_auth_backends[] if too many different auth backends)*/ 56 force_assert(i<(sizeof(http_auth_backends)/sizeof(http_auth_backend_t))-1); 57 memcpy(http_auth_backends+i, backend, sizeof(http_auth_backend_t)); 58 } 59 60 61 void http_auth_dumbdata_reset (void) 62 { 63 memset(http_auth_schemes, 0, sizeof(http_auth_schemes)); 64 memset(http_auth_backends, 0, sizeof(http_auth_backends)); 65 } 66 67 68 http_auth_require_t * http_auth_require_init (void) 69 { 70 http_auth_require_t *require = calloc(1, sizeof(http_auth_require_t)); 71 force_assert(NULL != require); 72 return require; 73 } 74 75 void http_auth_require_free (http_auth_require_t * const require) 76 { 77 array_free_data(&require->user); 78 array_free_data(&require->group); 79 array_free_data(&require->host); 80 free(require); 81 } 82 83 /* (case-sensitive version of array.c:array_get_index(), 84 * and common case expects small num of allowed tokens, 85 * so it is reasonably performant to simply walk the array) */ 86 __attribute_pure__ 87 static int http_auth_array_contains (const array * const a, const char * const k, const size_t klen) 88 { 89 for (size_t i = 0, used = a->used; i < used; ++i) { 90 if (buffer_eq_slen(&((data_string *)a->data[i])->value, k, klen)) 91 return 1; 92 } 93 return 0; 94 } 95 96 int http_auth_match_rules (const http_auth_require_t * const require, const char * const user, const char * const group, const char * const host) 97 { 98 if (NULL != user 99 && (require->valid_user 100 || http_auth_array_contains(&require->user, user, strlen(user)))) { 101 return 1; /* match */ 102 } 103 104 if (NULL != group 105 && http_auth_array_contains(&require->group, group, strlen(group))) { 106 return 1; /* match */ 107 } 108 109 if (NULL != host 110 && http_auth_array_contains(&require->host, host, strlen(host))) { 111 return 1; /* match */ 112 } 113 114 return 0; /* no match */ 115 } 116 117 void http_auth_setenv(request_st * const r, const char *username, size_t ulen, const char *auth_type, size_t alen) { 118 http_header_env_set(r, CONST_STR_LEN("REMOTE_USER"), username, ulen); 119 http_header_env_set(r, CONST_STR_LEN("AUTH_TYPE"), auth_type, alen); 120 } 121 122 unsigned int http_auth_digest_len (int algo) 123 { 124 if (algo & (HTTP_AUTH_DIGEST_SHA256 | HTTP_AUTH_DIGEST_SHA512_256)) { 125 /* HTTP_AUTH_DIGEST_SHA512_256_BINLEN */ 126 return HTTP_AUTH_DIGEST_SHA256_BINLEN; 127 } 128 if (algo & HTTP_AUTH_DIGEST_MD5) { 129 return HTTP_AUTH_DIGEST_MD5_BINLEN; 130 } 131 132 return 0; 133 } 134