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