Sanitize username inputs in the database layer
[blerg.git] / common / auth.c
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include "config.h"
8 #include "auth.h"
9 #include "util.h"
10
11 #define TOKEN_SIZE 16
12
13 int auth_set_password(const char *username, const char *password) {
14         char filename[512];
15         int fd;
16
17         if (!valid_name(username) || !blerg_exists(username))
18                 return 0;
19
20         snprintf(filename, 512, "%s/%s/password", DATA_PATH, username);
21         fd = open(filename, O_WRONLY | O_CREAT, 0600);
22         write(fd, password, strlen(password));
23         close(fd);
24         
25         return 1;
26 }
27
28 int auth_get_password(const char *username, char *password) {
29         char filename[512];
30         int fd;
31         int len = 0;
32
33         if (!valid_name(username))
34                 return 0;
35
36         sprintf(filename, "%s/%s/password", DATA_PATH, username);
37         fd = open(filename, O_RDONLY);
38         if (fd == -1)
39                 return 0;
40         len = read(fd, password, 32);
41         close(fd);
42
43         password[len] = 0;
44
45         return 1;
46 }
47
48 int auth_check_password(const char *username, const char *password) {
49         char epw[33];
50
51         if (auth_get_password(username, epw) == 0)
52                 return 0;
53
54         if (strncmp(password, epw, 32) == 0)
55                 return 1;
56         else
57                 return 0;
58 }
59
60 void hexify(char *dst, char *src, int len) {
61         static char hex[] = "0123456789abcdef";
62         int i;
63
64         for (i = 0; i < len; i++) {
65                 dst[i * 2]     = hex[(src[i] & 0xF0) >> 4];
66                 dst[i * 2 + 1] = hex[src[i] & 0xF];
67         }
68 }
69
70 char *create_random_token() {
71         unsigned char buf[TOKEN_SIZE];
72         char *token;
73         int rand_fd;
74
75         rand_fd = open("/dev/urandom", O_RDONLY);
76         if (rand_fd == -1) {
77                 perror("Could not open /dev/urandom\n");
78                 return 0;
79         }
80         read(rand_fd, buf, TOKEN_SIZE);
81         close(rand_fd);
82
83         token = malloc(TOKEN_SIZE * 2 + 1);
84         hexify(token, buf, TOKEN_SIZE);
85         token[TOKEN_SIZE * 2] = 0;
86
87         return token;
88 }
89
90 int auth_login(const char *username, const char *password) {
91         char filename[512];
92         int token_fd;
93
94         if (!auth_check_password(username, password))
95                 return 0;
96
97         sprintf(filename, "%s/%s/token", DATA_PATH, username);
98         token_fd = open(filename, O_WRONLY | O_CREAT, 0600);
99         if (token_fd == -1) {
100                 perror("Could not open token");
101                 return 0;
102         }
103
104         char *token = create_random_token();
105         write(token_fd, token, TOKEN_SIZE * 2);
106         close(token_fd);
107         free(token);
108
109         return 1;
110 }
111
112 int auth_logout(const char *username) {
113         char filename[512];
114
115         if (!valid_name(username))
116                 return 0;
117
118         sprintf(filename, "%s/%s/token", DATA_PATH, username);
119         if (unlink(filename) == -1)
120                 return 0;
121
122         return 1;
123 }
124
125 char *auth_get_token(const char *username) {
126         char filename[512];
127         char *token;
128         int token_fd;
129
130         if (!valid_name(username))
131                 return 0;
132
133         sprintf(filename, "%s/%s/token", DATA_PATH, username);
134         token_fd = open(filename, O_RDONLY, 0600);
135         if (token_fd == -1) {
136                 perror("Could not open token");
137                 return NULL;
138         }
139
140         token = malloc(TOKEN_SIZE * 2 + 1);
141         read(token_fd, token, TOKEN_SIZE * 2);
142         close(token_fd);
143
144         return token;
145 }
146
147 int auth_check_token(const char *username, const char *given_token) {
148         char *token = auth_get_token(username);
149         if (token != NULL && given_token != NULL) {
150                 int ret = (strncmp(token, given_token, TOKEN_SIZE * 2) == 0);
151                 free(token);
152                 return ret;
153         } else {
154                 return 0;
155         }
156 }