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 34 KeyfileConfig *load_keyfile_config(char *file) { 35 FILE *in = fopen(file, "r"); 36 if(in == NULL) { 37 return NULL; 38 } 39 40 KeyfileConfig *conf = malloc(sizeof(KeyfileConfig)); 41 conf->parser.parse = keyfile_parse; 42 conf->file = file; 43 conf->users = NULL; 44 45 int r = cfg_parse_basic_file((ConfigParser*)conf, in); 46 if(r != 0) { 47 fclose(in); 48 free(conf); 49 // TODO: free 50 return NULL; 51 } 52 53 fclose(in); 54 55 return conf; 56 } 57 58 void free_keyfile_config(KeyfileConfig *conf) { 59 if(conf->users) { 60 ucx_list_free_a(conf->parser.mp, conf->users); 61 } 62 ucx_mempool_destroy(conf->parser.mp->pool); 63 free(conf); 64 } 65 66 int keyfile_parse(void *p, ConfigLine *begin, ConfigLine *end, sstr_t line) { 67 KeyfileConfig *conf = p; 68 UcxAllocator *mp = conf->parser.mp; 69 70 ssize_t tkn = 0; 71 sstr_t *tk = sstrsplit(line, sstrn(";", 1), &tkn); 72 73 if(tkn < 2) { 74 return 1; 75 } 76 77 KeyfileEntry *entry = OBJ_NEW(mp, KeyfileEntry); 78 entry->groups = NULL; 79 entry->numgroups = 0; 80 81 // get user name 82 entry->name = sstrdup_a(mp, tk[0]); 83 84 // get hash 85 sstr_t hash = sstrtrim(tk[1]); 86 if(hash.length < 4) { 87 // to short 88 return 1; 89 } 90 if(hash.ptr[0] != '{') { 91 // missing hash type specification 92 return 1; 93 } 94 95 // get hash type and data 96 sstr_t hash_type; 97 sstr_t hash_data; 98 for(int i=1;i<hash.length;i++) { 99 if(hash.ptr[i] == '}') { 100 hash_type = sstrsubsl(hash, 1, i-1); 101 hash_data = sstrsubs(hash, i+1); 102 } 103 } 104 105 if(!sstrcmp(hash_type, sstr("SSHA"))) { 106 entry->hashtype = KEYFILE_SSHA; 107 } else if(!sstrcmp(hash_type, sstr("SSHA256"))) { 108 entry->hashtype = KEYFILE_SSHA256; 109 } else if(!sstrcmp(hash_type, sstr("SSHA512"))) { 110 entry->hashtype = KEYFILE_SSHA512; 111 } else { 112 // unkown hash type 113 log_ereport( 114 LOG_FAILURE, 115 "keyfile_parse: unknown hash type: %s", 116 sstrdup_a(mp, hash_type).ptr); 117 return 1; 118 } 119 120 entry->hashdata = sstrdup_a(mp, hash_data); 121 122 // get groups 123 if(tkn == 3) { 124 sstr_t groups_str = sstrtrim(tk[2]); 125 ssize_t ngroups = 0; 126 sstr_t *groups = sstrsplit(groups_str, sstrn(",", 1), &ngroups); 127 if(ngroups > 0) { 128 entry->groups = mp->calloc(mp->pool, ngroups, sizeof(sstr_t)); 129 entry->numgroups = ngroups; 130 for(int i=0;i<ngroups;i++) { 131 entry->groups[i] = sstrdup_a(mp, sstrtrim(groups[i])); 132 free(groups[i].ptr); 133 } 134 free(groups); 135 } 136 } 137 138 // add user 139 conf->users = ucx_list_append_a(mp, conf->users, entry); 140 141 // free tokens 142 for(int i=0;i<tkn;i++) { 143 free(tk[i].ptr); 144 } 145 free(tk); 146 147 return 0; 148 } 149