thread-safe basicauth

This commit is contained in:
roberto@precise64
2012-02-12 09:26:38 +01:00
parent e431936a8e
commit c06b4773c7
4 changed files with 62 additions and 7 deletions
+35 -5
View File
@@ -4,6 +4,10 @@
#ifdef __linux__
#include <crypt.h>
#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
+24
View File
@@ -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;
+1
View File
@@ -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 *);
+2 -2
View File
@@ -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 """
<img src="/logo"/> version %s running on %s<br/>
<img src="/logo"/> version %s running on %s (remote user: %s)<br/>
<hr size="1"/>
Configuration<br/>
@@ -119,7 +119,7 @@ Workers and applications<br/>
%s
</table>
""" % (uwsgi.version, uwsgi.hostname, workers)
""" % (uwsgi.version, uwsgi.hostname, env.get('REMOTE_USER','None'), workers)