X-Git-Url: http://git.bytex64.net/?a=blobdiff_plain;f=common%2Fauth.c;h=0d4045520b26a6f2812535c4faa6d76bef069637;hb=756f2f096cf6a6f7126e053846c1b87b089e30ce;hp=0a3a8f5c664c07f0d1175f66679c5ad6c3a6e332;hpb=3d27274b36b44816c736ea8a411341b5a36556f9;p=blerg.git diff --git a/common/auth.c b/common/auth.c index 0a3a8f5..0d40455 100644 --- a/common/auth.c +++ b/common/auth.c @@ -1,21 +1,41 @@ +/* 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 #include +#include #include "config.h" #include "auth.h" +#include "util.h" +#include "md5.h" + +#define TOKEN_SIZE 16 +#define MAX_PASSWORD_LENGTH 64 int auth_set_password(const char *username, const char *password) { char filename[512]; - int fd; + unsigned char md5pass[MD5_DIGEST_SIZE]; + struct MD5Context ctx; + int fd, n; + + if (!valid_name(username) || !blerg_exists(username)) + return 0; - if (!blerg_exists(username)) + n = strlen(password); + if (n > MAX_PASSWORD_LENGTH) return 0; + MD5Init(&ctx); + MD5Update(&ctx, username, strlen(username)); + MD5Update(&ctx, password, n); + MD5Final(md5pass, &ctx); + snprintf(filename, 512, "%s/%s/password", DATA_PATH, username); fd = open(filename, O_WRONLY | O_CREAT, 0600); - write(fd, password, strlen(password)); + write(fd, md5pass, MD5_DIGEST_SIZE); close(fd); return 1; @@ -26,11 +46,14 @@ int auth_get_password(const char *username, char *password) { int fd; int len = 0; + if (!valid_name(username)) + return 0; + sprintf(filename, "%s/%s/password", DATA_PATH, username); fd = open(filename, O_RDONLY); if (fd == -1) return 0; - len = read(fd, password, 32); + len = read(fd, password, MD5_DIGEST_SIZE); close(fd); password[len] = 0; @@ -39,13 +62,104 @@ int auth_get_password(const char *username, char *password) { } int auth_check_password(const char *username, const char *password) { - char epw[33]; + char epw[MD5_DIGEST_SIZE + 1]; + unsigned char givenpw[MD5_DIGEST_SIZE]; + struct MD5Context ctx; if (auth_get_password(username, epw) == 0) return 0; - if (strncmp(password, epw, 32) == 0) + MD5Init(&ctx); + MD5Update(&ctx, username, strlen(username)); + MD5Update(&ctx, password, strlen(password)); + MD5Final(givenpw, &ctx); + + if (strncmp(givenpw, epw, MD5_DIGEST_SIZE) == 0) return 1; else return 0; } + +void hexify(char *dst, char *src, int len) { + static char hex[] = "0123456789abcdef"; + int i; + + for (i = 0; i < len; i++) { + dst[i * 2] = hex[(src[i] & 0xF0) >> 4]; + dst[i * 2 + 1] = hex[src[i] & 0xF]; + } +} + +char *create_random_token() { + unsigned char buf[TOKEN_SIZE]; + char *token; + int rand_fd; + + rand_fd = open("/dev/urandom", O_RDONLY); + if (rand_fd == -1) { + perror("Could not open /dev/urandom\n"); + return 0; + } + read(rand_fd, buf, TOKEN_SIZE); + close(rand_fd); + + token = malloc(TOKEN_SIZE * 2 + 1); + hexify(token, buf, TOKEN_SIZE); + token[TOKEN_SIZE * 2] = 0; + + return token; +} + +char * auth_login(const char *username, const char *password) { + char filename[512]; + int token_fd; + + if (!auth_check_password(username, password)) + return NULL; + + char *token = create_random_token(); + + sprintf(filename, "%s/%s/tokens", DATA_PATH, username); + if (access(filename, F_OK) != 0) { + if (mkdir(filename, 0700) == -1) { + perror("Could not create auth token dir"); + return NULL; + } + } + + sprintf(filename, "%s/%s/tokens/%s", DATA_PATH, username, token); + token_fd = open(filename, O_WRONLY | O_CREAT, 0600); + if (token_fd == -1) { + perror("Could not open token"); + return NULL; + } + close(token_fd); + + return token; +} + +int auth_logout(const char *username, const char *token) { + char filename[512]; + + if (!valid_name(username)) + return 0; + + sprintf(filename, "%s/%s/tokens", DATA_PATH, username); + if (access(filename, F_OK) != 0) { + return 0; + } + + sprintf(filename, "%s/%s/tokens/%s", DATA_PATH, username, token); + if (unlink(filename) == -1) + return 0; + + return 1; +} + +int auth_check_token(const char *username, const char *given_token) { + char filename[512]; + + sprintf(filename, "%s/%s/tokens/%s", DATA_PATH, username, given_token); + + return (access(filename, F_OK) == 0); +}