diff --git a/plugins/router_basicauth/router_basicauth.c b/plugins/router_basicauth/router_basicauth.c index 9f8957cb..7278e3fe 100644 --- a/plugins/router_basicauth/router_basicauth.c +++ b/plugins/router_basicauth/router_basicauth.c @@ -4,6 +4,10 @@ #ifdef __linux__ #include +#else +#ifdef UWSGI_THREADING +pthread_mutex_t ur_basicauth_crypt_mutex; +#endif #endif extern struct uwsgi_server uwsgi; @@ -74,7 +78,7 @@ static char *http_basic_auth_get(char *authorization, uint16_t len) { } -uint16_t check_htpasswd(char *filename, char *auth) { +static uint16_t htpasswd_check(char *filename, char *auth) { char line[1024]; @@ -102,13 +106,17 @@ uint16_t check_htpasswd(char *filename, char *auth) { cd.current_salt[0] = ~cpwd[0]; char *crypted = crypt_r( colon+1, cpwd, &cd); #else + if (uwsgi.threads > 1) pthread_mutex_lock(&ur_basicauth_crypt_mutex); char *crypted = crypt( colon+1, cpwd); + if (uwsgi.threads > 1) pthread_mutex_unlock(&ur_basicauth_crypt_mutex); #endif if (!crypted) continue; if (!strcmp( crypted, cpwd )) { - fclose(htpasswd); - return colon-auth; + if (!uwsgi_strncmp(auth, colon-auth, line, colon2-line)) { + fclose(htpasswd); + return colon-auth; + } } } @@ -137,11 +145,22 @@ int uwsgi_routing_func_basicauth(struct wsgi_request *wsgi_req, struct uwsgi_rou char *auth = http_basic_auth_get(wsgi_req->authorization+6, wsgi_req->authorization_len-6); if (auth) { - if (ur->custom) { + if (!ur->custom) { // check htpasswd-like file + uint16_t ulen = htpasswd_check(ur->data2, auth); + if (ulen > 0) { + wsgi_req->remote_user = uwsgi_req_append(wsgi_req, "REMOTE_USER", 11, auth, ulen); + if (wsgi_req->remote_user) + wsgi_req->remote_user_len = ulen; + free(auth); + return UWSGI_ROUTE_CONTINUE; + } } else { if (!strcmp(auth, ur->data2)) { + wsgi_req->remote_user = uwsgi_req_append(wsgi_req, "REMOTE_USER", 11, auth, ur->custom); + if (wsgi_req->remote_user) + wsgi_req->remote_user_len = ur->custom; free(auth); return UWSGI_ROUTE_CONTINUE; } @@ -170,6 +189,11 @@ forbidden: return UWSGI_ROUTE_BREAK; } +#ifndef __linux__ +void router_basicauth_init_lock() { + pthread_mutex_init(&ur_basicauth_crypt_mutex, NULL); +} +#endif int uwsgi_router_basicauth(struct uwsgi_route *ur, char *args) { @@ -186,7 +210,10 @@ int uwsgi_router_basicauth(struct uwsgi_route *ur, char *args) { char *colon = strchr(comma+1, ':'); // is an htpasswd-like file ? if (!colon) { - ur->custom = 1; + ur->custom = 0; + } + else { + ur->custom = colon-(comma+1); } ur->data = args; @@ -212,5 +239,8 @@ struct uwsgi_plugin router_basicauth_plugin = { #else struct uwsgi_plugin router_basicauth_plugin = { .name = "router_basicauth", +#ifndef __linux__ + .enable_threads = router_basicauth_init_lock; +#endif }; #endif diff --git a/protocol.c b/protocol.c index 25ef3961..668f9665 100644 --- a/protocol.c +++ b/protocol.c @@ -1423,6 +1423,30 @@ int uwsgi_simple_send_string2(char *socket_name, uint8_t modifier1, uint8_t modi return 0; } +char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, char *val, uint16_t vallen) { + + if (wsgi_req->uh.pktsize + (2+keylen+2+vallen) > uwsgi.buffer_size) { + uwsgi_log("not enough buffer space to add %.*s variable, consider increasing it with the --buffer-size option\n", keylen, key); + return NULL; + } + + char *ptr = wsgi_req->buffer + wsgi_req->uh.pktsize; + + *ptr++= (uint8_t) (keylen & 0xff); + *ptr++= (uint8_t) ((keylen >> 8) & 0xff); + + memcpy(ptr, key, keylen); ptr+=keylen; + + *ptr++= (uint8_t) (vallen & 0xff); + *ptr++= (uint8_t) ((vallen >> 8) & 0xff); + + memcpy(ptr, val, vallen); + + wsgi_req->uh.pktsize += (2+keylen+2+vallen); + + return ptr; +} + int uwsgi_simple_send_string(char *socket_name, uint8_t modifier1, uint8_t modifier2, char *item1, uint16_t item1_len, int timeout) { struct uwsgi_header uh; diff --git a/uwsgi.h b/uwsgi.h index 4307edd0..29459579 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2110,6 +2110,7 @@ void init_magic_table(char *[]); char *uwsgi_simple_message_string(char *, uint8_t, uint8_t, char *, uint16_t, char *, uint16_t *, int); int uwsgi_simple_send_string2(char *, uint8_t, uint8_t, char *, uint16_t, char *, uint16_t, int); int uwsgi_simple_send_string(char *, uint8_t, uint8_t, char *, uint16_t, int); +char *uwsgi_req_append(struct wsgi_request *, char *, uint16_t, char *, uint16_t); int is_unix(char *, int); int is_a_number(char *); diff --git a/welcome.py b/welcome.py index 1618a26f..d4842ddd 100644 --- a/welcome.py +++ b/welcome.py @@ -99,7 +99,7 @@ def application(env, start_response): """ % (w['id'], w['pid'], w['status'], w['running_time']/1000, w['avg_rt']/1000, w['tx'], apps) return """ - version %s running on %s
+ version %s running on %s (remote user: %s)

Configuration
@@ -119,7 +119,7 @@ Workers and applications
%s - """ % (uwsgi.version, uwsgi.hostname, workers) + """ % (uwsgi.version, uwsgi.hostname, env.get('REMOTE_USER','None'), workers)