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
32 #include "keyfile.h"
33 #include "logging.h"
34
35 #define KEYFILE_MAX_TOKENS 4096
36
37 KeyfileConfig *load_keyfile_config(
const char *file) {
38 FILE *in = fopen(file,
"r");
39 if(in ==
NULL) {
40 return NULL;
41 }
42
43 KeyfileConfig *conf = malloc(
sizeof(KeyfileConfig));
44 conf->parser.parse = keyfile_parse;
45 conf->file = strdup(file);
46 conf->users_begin =
NULL;
47 conf->users_end =
NULL;
48
49 int r = cfg_parse_basic_file((ConfigParser*)conf, in);
50 if(r !=
0) {
51 fclose(in);
52 free(conf);
53
54 return NULL;
55 }
56
57 fclose(in);
58
59 return conf;
60 }
61
62 void free_keyfile_config(KeyfileConfig *conf) {
63
64
65
66
67
68
69 free(conf);
70 }
71
72 int keyfile_parse(
void *p, ConfigLine *begin, ConfigLine *end, cxmutstr line) {
73 KeyfileConfig *conf = p;
74 CxAllocator *mp = conf->parser.mp;
75
76 cxstring *tk =
NULL;
77 ssize_t tkn = cx_strsplit_a(mp, cx_strcast(line), cx_strn(
";",
1),
KEYFILE_MAX_TOKENS, &tk);
78
79 if(tkn <
2) {
80 return 1;
81 }
82
83 KeyfileEntry *entry =
OBJ_NEW(mp, KeyfileEntry);
84 ZERO(entry,
sizeof(KeyfileEntry));
85
86
87 entry->name = cx_strdup_a(mp, tk[
0]);
88
89
90 cxstring hash = cx_strtrim(tk[
1]);
91 if(hash.length <
4) {
92
93 return 1;
94 }
95 if(hash.ptr[
0] !=
'{') {
96
97 return 1;
98 }
99
100
101 cxstring hash_type;
102 cxstring hash_data;
103 for(
int i=
1;i<hash.length;i++) {
104 if(hash.ptr[i] ==
'}') {
105 hash_type = cx_strsubsl(hash,
1, i-
1);
106 hash_data = cx_strsubs(hash, i+
1);
107 }
108 }
109
110 if(!cx_strcmp(hash_type, cx_str(
"SSHA"))) {
111 entry->hashtype =
KEYFILE_SSHA;
112 }
else if(!cx_strcmp(hash_type, cx_str(
"SSHA256"))) {
113 entry->hashtype =
KEYFILE_SSHA256;
114 }
else if(!cx_strcmp(hash_type, cx_str(
"SSHA512"))) {
115 entry->hashtype =
KEYFILE_SSHA512;
116 }
else {
117
118 ws_cfg_log(
119 LOG_FAILURE,
120 "keyfile_parse: unknown hash type: %s",
121 cx_strdup_a(mp, hash_type).ptr);
122 return 1;
123 }
124
125 entry->hashdata = cx_strdup_a(mp, hash_data);
126
127
128 if(tkn ==
3) {
129 cxstring groups_str = cx_strtrim(tk[
2]);
130 cxstring *groups =
NULL;
131 ssize_t ngroups = cx_strsplit_a(mp, groups_str, cx_strn(
",",
1),
KEYFILE_MAX_TOKENS, &groups);
132 if(ngroups >
0) {
133 entry->groups = cxCalloc(mp, ngroups,
sizeof(cxmutstr));
134 entry->numgroups = ngroups;
135 for(
int i=
0;i<ngroups;i++) {
136 entry->groups[i] = cx_strdup_a(mp, cx_strtrim(groups[i]));
137 }
138 cxFree(mp, groups);
139 }
140 }
141
142
143 CFG_KEYFILE_ADD(&conf->users_begin, &conf->users_end, entry);
144
145
146 cxFree(mp, tk);
147
148 return 0;
149 }
150