#include <stdio.h>
#include <stdlib.h>
#include "keyfile.h"
KeyfileConfig *load_keyfile_config(
char *file) {
FILE *in = fopen(file,
"r");
if(in ==
NULL) {
return NULL;
}
KeyfileConfig *conf = malloc(
sizeof(KeyfileConfig));
conf->parser.parse = keyfile_parse;
conf->file = file;
conf->users =
NULL;
int r = cfg_parse_basic_file((ConfigParser*)conf, in);
if(r !=
0) {
fclose(in);
free(conf);
return NULL;
}
fclose(in);
return conf;
}
void free_keyfile_config(KeyfileConfig *conf) {
if(conf->users) {
ucx_list_free_a(conf->parser.mp, conf->users);
}
ucx_mempool_destroy(conf->parser.mp->pool);
free(conf);
}
int keyfile_parse(
void *p, ConfigLine *begin, ConfigLine *end,
sstr_t line) {
KeyfileConfig *conf = p;
UcxAllocator *mp = conf->parser.mp;
ssize_t tkn =
0;
sstr_t *tk = sstrsplit(line, sstrn(
";",
1), &tkn);
if(tkn <
2) {
return 1;
}
KeyfileEntry *entry =
OBJ_NEW(mp, KeyfileEntry);
entry->groups =
NULL;
entry->numgroups =
0;
entry->name = sstrdup_a(mp, tk[
0]);
sstr_t hash = sstrtrim(tk[
1]);
if(hash.length <
4) {
return 1;
}
if(hash.ptr[
0] !=
'{') {
return 1;
}
sstr_t hash_type;
sstr_t hash_data;
for(
int i=
1;i<hash.length;i++) {
if(hash.ptr[i] ==
'}') {
hash_type = sstrsubsl(hash,
1, i-
1);
hash_data = sstrsubs(hash, i+
1);
}
}
if(!sstrcmp(hash_type, sstr(
"SSHA"))) {
entry->hashtype =
KEYFILE_SSHA;
}
else if(!sstrcmp(hash_type, sstr(
"SSHA256"))) {
entry->hashtype =
KEYFILE_SSHA256;
}
else if(!sstrcmp(hash_type, sstr(
"SSHA512"))) {
entry->hashtype =
KEYFILE_SSHA512;
}
else {
log_ereport(
LOG_FAILURE,
"keyfile_parse: unknown hash type: %s",
sstrdup_a(mp, hash_type).ptr);
return 1;
}
entry->hashdata = sstrdup_a(mp, hash_data);
if(tkn ==
3) {
sstr_t groups_str = sstrtrim(tk[
2]);
ssize_t ngroups =
0;
sstr_t *groups = sstrsplit(groups_str, sstrn(
",",
1), &ngroups);
if(ngroups >
0) {
entry->groups = mp->calloc(mp->pool, ngroups,
sizeof(
sstr_t));
entry->numgroups = ngroups;
for(
int i=
0;i<ngroups;i++) {
entry->groups[i] = sstrdup_a(mp, sstrtrim(groups[i]));
free(groups[i].ptr);
}
free(groups);
}
}
conf->users = ucx_list_append_a(mp, conf->users, entry);
for(
int i=
0;i<tkn;i++) {
free(tk[i].ptr);
}
free(tk);
return 0;
}