X-Git-Url: http://git.bytex64.net/?a=blobdiff_plain;f=common%2Fauth.c;h=e2f7407d9cbf8ce69c7b5a6908ceeb424e9d0d5f;hb=d67dd1bf5a247e20141b9907f5a452da73624235;hp=6638748edb54a0b71e7ee6b163fff01f1c3f0e0b;hpb=7a1c06730feac986e1bf29f202b6afe910b56f14;p=blerg.git diff --git a/common/auth.c b/common/auth.c index 6638748..e2f7407 100644 --- a/common/auth.c +++ b/common/auth.c @@ -1,6 +1,7 @@ /* Blerg is (C) 2011 The Dominion of Awesome, and is distributed under a * BSD-style license. Please see the COPYING file for details. */ +#include #include #include #include @@ -14,6 +15,7 @@ #include "database.h" #include "auth.h" #include "util.h" +#include "stringring.h" #include "md5.h" int auth_set_password(const char *username, const char *password) { @@ -225,7 +227,7 @@ int auth_check_scrypt(struct auth_v2 *auth, const char *username, const char *pa unsigned char givenpw[SCRYPT_OUTPUT_SIZE]; int r; - r = crypto_scrypt(password, strlen(password), auth->salt, SCRYPT_SALT_SIZE, SCRYPT_N, SCRYPT_r, SCRYPT_p, givenpw, SCRYPT_OUTPUT_SIZE); + r = crypto_scrypt((const uint8_t *)password, strlen(password), auth->salt, SCRYPT_SALT_SIZE, SCRYPT_N, SCRYPT_r, SCRYPT_p, givenpw, SCRYPT_OUTPUT_SIZE); if (r != 0) { fprintf(stderr, "Failure in scrypt for %s\n", username); return 0; @@ -239,7 +241,6 @@ int auth_check_scrypt(struct auth_v2 *auth, const char *username, const char *pa int auth_check_password_v1(const char *username, const char *password) { struct auth_v2 auth; - int r; if (auth_get_password(username, (char *)auth.password) == 0) return 0; @@ -252,7 +253,6 @@ int auth_check_password_v1(const char *username, const char *password) { int auth_check_password_v2(const char *username, const char *password) { struct auth_v2 auth; - int r; if (auth_get_data(username, (void *) &auth, sizeof(struct auth_v2)) == 0) return 0; @@ -321,34 +321,33 @@ char *create_random_token() { char * auth_login(const char *username, const char *password) { char filename[FILENAME_MAX]; - int token_fd; + struct stringring *sr; + char *token; + if (!auth_check_password(username, password)) return NULL; - char *token = create_random_token(); - snprintf(filename, FILENAME_MAX, "%s/%s/tokens", blergconf.data_path, username); - if (access(filename, F_OK) != 0) { - if (mkdir(filename, 0700) == -1) { - perror("Could not create auth token dir"); - return NULL; - } + sr = stringring_open(filename); + if (sr == NULL) { + return NULL; } - - snprintf(filename, FILENAME_MAX, "%s/%s/tokens/%s", blergconf.data_path, username, token); - token_fd = open(filename, O_WRONLY | O_CREAT, 0600); - if (token_fd == -1) { - perror("Could not open token"); + token = create_random_token(); + if (!stringring_add(sr, token)) { + free(token); + stringring_close(sr); return NULL; } - close(token_fd); + stringring_close(sr); return token; } int auth_logout(const char *username, const char *token) { char filename[FILENAME_MAX]; + struct stringring *sr; + int ret; if (!valid_name(username)) return 0; @@ -357,18 +356,60 @@ int auth_logout(const char *username, const char *token) { if (access(filename, F_OK) != 0) { return 0; } - - snprintf(filename, FILENAME_MAX, "%s/%s/tokens/%s", blergconf.data_path, username, token); - if (unlink(filename) == -1) + sr = stringring_open(filename); + if (sr == NULL) { return 0; + } + ret = stringring_remove(sr, token); + stringring_close(sr); - return 1; + return ret; } int auth_check_token(const char *username, const char *given_token) { char filename[FILENAME_MAX]; + struct stringring *sr; + int ret; - snprintf(filename, FILENAME_MAX, "%s/%s/tokens/%s", blergconf.data_path, username, given_token); + snprintf(filename, FILENAME_MAX, "%s/%s/tokens", blergconf.data_path, username); + if (access(filename, F_OK) != 0) { + return 0; + } + sr = stringring_open(filename); + if (sr == NULL) { + return 0; + } + ret = (stringring_find(sr, given_token, AUTHENTICATION_TIMEOUT) != -1); + if (ret == 1) { + /* Update token timestamp */ + stringring_touch(sr, given_token); + } + stringring_close(sr); + + return ret; +} + +/* Return a 32-bit integer "counter" that will change when the password is + * updated. Used to invalidate password recovery schemes after the password is + * updated. Returns the counter in the "counter" argument, and returns + * true/false on success/failure. */ +int auth_get_counter(const char *username, uint32_t *counter) { + struct auth_v2 auth; + struct MD5Context ctx; + uint8_t md5hash[MD5_DIGEST_SIZE]; - return (access(filename, F_OK) == 0); + if (auth_get_data(username, (void *) &auth, sizeof(struct auth_v2)) == 0) + return 0; + + /* There's probably going to be some question about using MD5 here. + * All I really need is to quickly and repeatably scramble some bits. + * MD5 can still do that. */ + MD5Init(&ctx); + MD5Update(&ctx, auth.password, SCRYPT_OUTPUT_SIZE); + MD5Update(&ctx, auth.salt, SCRYPT_SALT_SIZE); + MD5Final((unsigned char *)md5hash, &ctx); + + *counter = ((uint32_t *)md5hash)[0]; + + return 1; }