UNIXworkcode

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 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 // TODO: free 54 return NULL; 55 } 56 57 fclose(in); 58 59 return conf; 60 } 61 62 void free_keyfile_config(KeyfileConfig *conf) { 63 /* 64 if(conf->users) { 65 ucx_list_free_a(conf->parser.mp, conf->users); 66 } 67 ucx_mempool_destroy(conf->parser.mp->pool); 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 // get user name 87 entry->name = cx_strdup_a(mp, tk[0]); 88 89 // get hash 90 cxstring hash = cx_strtrim(tk[1]); 91 if(hash.length < 4) { 92 // to short 93 return 1; 94 } 95 if(hash.ptr[0] != '{') { 96 // missing hash type specification 97 return 1; 98 } 99 100 // get hash type and data 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 // unkown hash type 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 // get groups 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 // add user 143 CFG_KEYFILE_ADD(&conf->users_begin, &conf->users_end, entry); 144 145 // free tokens 146 cxFree(mp, tk); 147 148 return 0; 149 } 150