src/server/daemon/keyfile_auth.c

changeset 62
c47e081b6c0f
child 63
66442f81f823
equal deleted inserted replaced
61:c858850f3d3a 62:c47e081b6c0f
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2013 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <openssl/sha.h>
33
34 #include "../util/atomic.h"
35 #include "../util/util.h"
36
37 #include "keyfile_auth.h"
38
39 Keyfile* keyfile_new() {
40 Keyfile *keyfile = malloc(sizeof(Keyfile));
41 keyfile->authdb.get_user = keyfile_get_user;
42 keyfile->users = ucx_map_new(16);
43 keyfile->ref = 1;
44 return keyfile;
45 }
46
47 void keyfile_ref(Keyfile *keyfile) {
48 ws_atomic_inc32(&keyfile->ref);
49 }
50
51 void keyfile_unref(Keyfile *keyfile) {
52 uint32_t ref = ws_atomic_dec32(&keyfile->ref);
53 if(ref == 0) {
54 UcxMapIterator i = ucx_map_iterator(keyfile->users);
55 KeyfileUser *user;
56 UCX_MAP_FOREACH(user, i) {
57 free(user->user.name);
58 free(user->hash);
59 for(int i=0;i<user->numgroups;i++) {
60 free(user->groups[i].ptr);
61 }
62 free(user->groups);
63 }
64 ucx_map_free(keyfile->users);
65
66 free(keyfile->authdb.name);
67 free(keyfile);
68 }
69 }
70
71 void keyfile_add_user(
72 Keyfile *keyfile,
73 sstr_t name,
74 enum KeyfileHashType hash_type,
75 sstr_t hash,
76 sstr_t *groups,
77 size_t ngroups)
78 {
79 if(hash.length < 12) {
80 // hash too short
81 // TODO: log
82 return;
83 }
84
85 KeyfileUser *user = malloc(sizeof(KeyfileUser));
86 user->user.name = sstrdup(name).ptr;
87 user->user.verify_password = keyfile_user_verify_password;
88 user->user.check_group = keyfile_user_check_group;
89 user->user.free = keyfile_user_free;
90
91 user->hash_type = hash_type;
92 user->hash = malloc(hash.length + 1);
93 user->hashlen = util_base64decode(hash.ptr, hash.length, user->hash);
94
95 user->groups = calloc(ngroups, sizeof(sstr_t));
96 for(int i=0;i<ngroups;i++) {
97 //user->groups[i] = sstrdup(groups[i]);
98 sstrdup(groups[i]);
99 }
100
101 // add to keyfile
102 ucx_map_sstr_put(keyfile->users, name, user);
103 }
104
105 // authdb functions
106
107 User* keyfile_get_user(AuthDB *db, char *user) {
108 Keyfile *keyfile = (Keyfile*)db;
109 return ucx_map_cstr_get(keyfile->users, user);
110 }
111
112 int keyfile_user_verify_password(User *user, char *password) {
113 KeyfileUser *usr = (KeyfileUser*)user;
114 switch(usr->hash_type) {
115 case KEYFILE_SSHA: return ssha_verify(usr, password);
116 }
117 return 0;
118 }
119
120 int keyfile_user_check_group(User *user, char *group) {
121 KeyfileUser *usr = (KeyfileUser*)user;
122 sstr_t grp = sstr(group);
123 for(int i=0;i<usr->numgroups;i++) {
124 if(!sstrcmp(usr->groups[i], grp)) {
125 return 1;
126 }
127 }
128 return 0;
129 }
130
131 void keyfile_user_free(User *user) {
132 // don't free, it will be freed by keyfile_unref
133 }
134
135
136 int ssha_verify(KeyfileUser *user, char *password) {
137 /*
138 * SSHA: SHA1(pw + salt) + 8 bytes salt
139 * the SSHA hash is already base64 decoded
140 */
141
142 char *salt = user->hash + user->hashlen - 8; // last 8 bytes are salt
143 size_t pwlen = strlen(password);
144
145 size_t saltpwlen = pwlen + 8;
146 char *saltpw = malloc(saltpwlen);
147 memcpy(saltpw, password, pwlen);
148 memcpy(saltpw + pwlen, salt, 8);
149
150 unsigned char pwhash[20];
151 SHA1((const unsigned char*)saltpw, saltpwlen, pwhash);
152
153 if(!memcmp(user->hash, pwhash, 20)) {
154 return 1;
155 }
156
157 return 0;
158 }

mercurial