Begin basic login/logout
authorChip Black <bytex64@bytex64.net>
Thu, 30 Dec 2010 09:31:28 +0000 (03:31 -0600)
committerChip Black <bytex64@bytex64.net>
Thu, 30 Dec 2010 09:31:28 +0000 (03:31 -0600)
common/auth.c
common/auth.h
http/http_blerg.c

index 0a3a8f5..0116462 100644 (file)
@@ -3,9 +3,12 @@
 #include <fcntl.h>
 #include <string.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include "config.h"
 #include "auth.h"
 
+#define TOKEN_SIZE 16
+
 int auth_set_password(const char *username, const char *password) {
        char filename[512];
        int fd;
@@ -49,3 +52,83 @@ int auth_check_password(const char *username, const char *password) {
        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;
+}
+
+int auth_login(const char *username, const char *password) {
+       char filename[512];
+       int token_fd;
+
+       if (!auth_check_password(username, password))
+               return 0;
+
+       sprintf(filename, "%s/%s/token", DATA_PATH, username);
+       token_fd = open(filename, O_WRONLY | O_CREAT, 0600);
+       if (token_fd == -1) {
+               perror("Could not open token");
+               return 0;
+       }
+
+       char *token = create_random_token();
+       write(token_fd, token, TOKEN_SIZE * 2);
+       close(token_fd);
+       free(token);
+
+       return 1;
+}
+
+int auth_logout(const char *username) {
+       char filename[512];
+       sprintf(filename, "%s/%s/token", DATA_PATH, username);
+       if (unlink(filename) == -1)
+               return 0;
+
+       return 1;
+}
+
+char *auth_get_token(const char *username) {
+       char filename[512];
+       char *token;
+       int token_fd;
+
+       sprintf(filename, "%s/%s/token", DATA_PATH, username);
+       token_fd = open(filename, O_RDONLY, 0600);
+       if (token_fd == -1) {
+               perror("Could not open token");
+               return NULL;
+       }
+
+       token = malloc(TOKEN_SIZE * 2 + 1);
+       read(token_fd, token, TOKEN_SIZE * 2);
+       close(token_fd);
+
+       return token;
+}
index da024c9..f73701b 100644 (file)
@@ -4,5 +4,8 @@
 int auth_set_password(const char *, const char *);
 int auth_get_password(const char *, char *);
 int auth_check_password(const char *, const char *);
+int auth_login(const char *username, const char *password);
+int auth_logout(const char *username);
+char *auth_get_token(const char *username);
 
 #endif //_AUTH_H
index 1d272eb..f481671 100644 (file)
@@ -12,7 +12,7 @@
 
 yajl_gen_config yajl_c = { 0, 0 };
 
-struct create_state {
+struct auth_state {
        struct MHD_PostProcessor *pp;
        char username[33];
        char password[33];
@@ -163,17 +163,17 @@ void GET_generate_taglist_free(void *cls) {
        free(ts);
 }
 
-int POST_create_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
-       struct create_state *cs = cls;
+int POST_auth_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
+       struct auth_state *as = cls;
 
        if (strncmp(key, "username", 9) == 0) {
                if (size > 32) size = 32;
-               memcpy(cs->username, data, size);
-               cs->username[size] = 0;
+               memcpy(as->username, data, size);
+               as->username[size] = 0;
        } else if (strncmp(key, "password", 9) == 0) {
                if (size > 32) size = 32;
-               memcpy(cs->password, data, size);
-               cs->password[size] = 0;
+               memcpy(as->password, data, size);
+               as->password[size] = 0;
        }
 
        return MHD_YES;
@@ -435,39 +435,105 @@ ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const c
 
                return ret;
        } else if (strncmp(url, "/create", 8) == 0) {
-               struct create_state *cs = (struct create_state *) *ptr;
+               struct auth_state *as = (struct auth_state *) *ptr;
 
-               if (cs == NULL) {
+               if (as == NULL) {
                        if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
                                return respond_405(connection);
 
-                       struct create_state *cs = malloc(sizeof(struct create_state));
-                       cs->username[0] = cs->password[0] = 0;
-                       cs->pp = MHD_create_post_processor(connection, 1024, &POST_create_iterator, cs);
-                       *ptr = cs;
+                       struct auth_state *as = malloc(sizeof(struct auth_state));
+                       as->username[0] = as->password[0] = 0;
+                       as->pp = MHD_create_post_processor(connection, 1024, &POST_auth_iterator, as);
+                       *ptr = as;
                        return MHD_YES;
                }
 
                if (*upload_data_size) {
-                       MHD_post_process(cs->pp, upload_data, *upload_data_size);
+                       MHD_post_process(as->pp, upload_data, *upload_data_size);
                        *upload_data_size = 0;
                        return MHD_YES;
                }
 
-               if (cs->username[0] == 0 || cs->password[0] == 0)
+               if (as->username[0] == 0 || as->password[0] == 0)
                        return respond_JSON_Failure(connection);
 
-               if (blerg_exists(cs->username))
+               if (blerg_exists(as->username))
                        return respond_JSON_Failure(connection);
 
-               struct blerg *b = blerg_open(cs->username);
+               struct blerg *b = blerg_open(as->username);
                blerg_close(b);
-               auth_set_password(cs->username, cs->password);
+               auth_set_password(as->username, as->password);
 
-               MHD_destroy_post_processor(cs->pp);
-               free(cs);
+               MHD_destroy_post_processor(as->pp);
+               free(as);
                *ptr = NULL;
 
+               return respond_JSON_Success(connection);
+       } else if (strncmp(url, "/login", 7) == 0) {
+               struct auth_state *as = (struct auth_state *) *ptr;
+
+               if (as == NULL) {
+                       if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+                               return respond_405(connection);
+
+                       struct auth_state *as = malloc(sizeof(struct auth_state));
+                       as->username[0] = as->password[0] = 0;
+                       as->pp = MHD_create_post_processor(connection, 1024, &POST_auth_iterator, as);
+                       *ptr = as;
+                       return MHD_YES;
+               }
+
+               if (*upload_data_size) {
+                       MHD_post_process(as->pp, upload_data, *upload_data_size);
+                       *upload_data_size = 0;
+                       return MHD_YES;
+               }
+
+               if (as->username[0] == 0 || as->password[0] == 0)
+                       return respond_JSON_Failure(connection);
+
+               if (!auth_login(as->username, as->password))
+                       return respond_JSON_Failure(connection);
+
+               response = MHD_create_response_from_data(strlen(JSON_SUCCESS), JSON_SUCCESS, MHD_NO, MHD_NO);
+
+               char *token = auth_get_token(as->username);
+               data = malloc(512);
+               snprintf(data, 512, "auth=%s", token);
+               MHD_add_response_header(response, "Set-Cookie", data);
+               free(token);
+               free(data);
+
+               MHD_destroy_post_processor(as->pp);
+               free(as);
+               *ptr = NULL;
+
+               ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+               MHD_destroy_response(response);
+
+               return ret;
+       } else if (strncmp(url, "/logout", 8) == 0) {
+               struct auth_state *as = (struct auth_state *) *ptr;
+
+               if (as == NULL) {
+                       if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+                               return respond_405(connection);
+
+                       struct auth_state *as = malloc(sizeof(struct auth_state));
+                       as->username[0] = as->password[0] = 0;
+                       as->pp = MHD_create_post_processor(connection, 1024, &POST_auth_iterator, as);
+                       *ptr = as;
+                       return MHD_YES;
+               }
+
+               if (*upload_data_size) {
+                       MHD_post_process(as->pp, upload_data, *upload_data_size);
+                       *upload_data_size = 0;
+                       return MHD_YES;
+               }
+
+               auth_logout(as->username);
+
                return respond_JSON_Success(connection);
        } else {
                return respond_404(connection);