1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include <openssl/sha.h>
34 #if defined(__sun) && defined(__SunOS_5_10)
35 #include <sha2.h>
36 #define SHA256_Init SHA256Init
37 #define SHA256_Update SHA256Update
38 #define SHA256_Final SHA256Final
39 #endif
40
41 #include "../util/atomic.h"
42 #include "../util/util.h"
43
44 #include "keyfile_auth.h"
45
46 Keyfile* keyfile_new() {
47 Keyfile *keyfile = malloc(
sizeof(Keyfile));
48 keyfile->authdb.get_user = keyfile_get_user;
49 keyfile->authdb.use_cache =
0;
50 keyfile->users = ucx_map_new(
16);
51 keyfile->ref =
1;
52 return keyfile;
53 }
54
55 void keyfile_ref(Keyfile *keyfile) {
56 ws_atomic_inc32(&keyfile->ref);
57 }
58
59 void keyfile_unref(Keyfile *keyfile) {
60 uint32_t ref = ws_atomic_dec32(&keyfile->ref);
61 if(ref ==
0) {
62 UcxMapIterator i = ucx_map_iterator(keyfile->users);
63 KeyfileUser *user;
64 UCX_MAP_FOREACH(key, user, i) {
65 free(user->user.name);
66 free(user->hash);
67 for(
int n=
0;n<user->numgroups;n++) {
68 free(user->groups[n].ptr);
69 }
70 free(user->groups);
71 }
72 ucx_map_free(keyfile->users);
73
74 free(keyfile->authdb.name);
75 free(keyfile);
76 }
77 }
78
79 void keyfile_add_user(
80 Keyfile *keyfile,
81 sstr_t name,
82 enum KeyfileHashType hash_type,
83 sstr_t hash,
84 sstr_t *groups,
85 size_t ngroups)
86 {
87 if(hash.length <
12) {
88
89
90 return;
91 }
92
93 KeyfileUser *user = malloc(
sizeof(KeyfileUser));
94 user->user.name = sstrdup(name).ptr;
95 user->user.uid = -
1;
96 user->user.gid = -
1;
97 user->user.verify_password = keyfile_user_verify_password;
98 user->user.check_group = keyfile_user_check_group;
99 user->user.free = keyfile_user_free;
100
101 user->hash_type = hash_type;
102 user->hash = malloc(hash.length +
1);
103 user->hashlen = util_base64decode(hash.ptr, hash.length, user->hash);
104
105 user->groups = calloc(ngroups,
sizeof(
sstr_t));
106 for(
int i=
0;i<ngroups;i++) {
107 user->groups[i] = sstrdup(groups[i]);
108 }
109
110
111 ucx_map_sstr_put(keyfile->users, name, user);
112 }
113
114
115
116 User* keyfile_get_user(AuthDB *db,
char *user) {
117 Keyfile *keyfile = (Keyfile*)db;
118 return ucx_map_cstr_get(keyfile->users, user);
119 }
120
121 int keyfile_user_verify_password(User *user,
char *password) {
122 KeyfileUser *usr = (KeyfileUser*)user;
123 return ssha_verify(usr, password);
124 }
125
126 int keyfile_user_check_group(User *user,
char *group) {
127 KeyfileUser *usr = (KeyfileUser*)user;
128 sstr_t grp = sstr(group);
129 for(
int i=
0;i<usr->numgroups;i++) {
130 if(!sstrcmp(usr->groups[i], grp)) {
131 return 1;
132 }
133 }
134 return 0;
135 }
136
137 void keyfile_user_free(User *user) {
138
139 }
140
141
142 int ssha_verify(KeyfileUser *user,
char *password) {
143
144
145
146
147
148 size_t hlen;
149 switch(user->hash_type) {
150 case KEYFILE_SSHA: hlen =
20;
break;
151 case KEYFILE_SSHA256: hlen =
32;
break;
152 case KEYFILE_SSHA512: hlen =
64;
break;
153 }
154
155 char *salt = user->hash + hlen;
156 size_t saltlen = user->hashlen - hlen;
157
158 size_t pwlen = strlen(password);
159
160 unsigned char pwhash[
64];
161 switch(user->hash_type) {
162 case KEYFILE_SSHA: {
163 SHA_CTX ctx;
164 SHA1_Init(&ctx);
165 SHA1_Update(&ctx, password, pwlen);
166 SHA1_Update(&ctx, salt, saltlen);
167 SHA1_Final(pwhash, &ctx);
168 break;
169 }
170 case KEYFILE_SSHA256: {
171 SHA256_CTX ctx;
172 SHA256_Init(&ctx);
173 SHA256_Update(&ctx, password, pwlen);
174 SHA256_Update(&ctx, salt, saltlen);
175 SHA256_Final(pwhash, &ctx);
176 break;
177 }
178 case KEYFILE_SSHA512: {
179 SHA512_CTX ctx;
180 SHA512_Init(&ctx);
181 SHA512_Update(&ctx, password, pwlen);
182 SHA512_Update(&ctx, salt, saltlen);
183 SHA512_Final(pwhash, &ctx);
184 break;
185 }
186 }
187
188 if(!memcmp(user->hash, pwhash, hlen)) {
189 return 1;
190 }
else {
191 return 0;
192 }
193 }
194
195