1 /* 2 * Copyright (c) 1999-2005 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * 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 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of KTH nor the names of its contributors may be 18 * used to endorse or promote products derived from this software without 19 * specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 32 33 #include "hdb_locl.h" 34 #include <hex.h> 35 #include <ctype.h> 36 37 RCSID("$Id: print.c 16378 2005-12-12 12:40:12Z lha $"); 38 39 /* 40 This is the present contents of a dump line. This might change at 41 any time. Fields are separated by white space. 42 43 principal 44 keyblock 45 kvno 46 keys... 47 mkvno 48 enctype 49 keyvalue 50 salt (- means use normal salt) 51 creation date and principal 52 modification date and principal 53 principal valid from date (not used) 54 principal valid end date (not used) 55 principal key expires (not used) 56 max ticket life 57 max renewable life 58 flags 59 generation number 60 */ 61 62 static krb5_error_code 63 append_string(krb5_context context, krb5_storage *sp, const char *fmt, ...) 64 { 65 krb5_error_code ret; 66 char *s; 67 va_list ap; 68 va_start(ap, fmt); 69 vasprintf(&s, fmt, ap); 70 va_end(ap); 71 if(s == NULL) { 72 krb5_set_error_string(context, "malloc: out of memory"); 73 return ENOMEM; 74 } 75 ret = krb5_storage_write(sp, s, strlen(s)); 76 free(s); 77 return ret; 78 } 79 80 static krb5_error_code 81 append_hex(krb5_context context, krb5_storage *sp, krb5_data *data) 82 { 83 int i, printable = 1; 84 char *p; 85 86 p = data->data; 87 for(i = 0; i < data->length; i++) 88 if(!isalnum((unsigned char)p[i]) && p[i] != '.'){ 89 printable = 0; 90 break; 91 } 92 if(printable) 93 return append_string(context, sp, "\"%.*s\"", 94 data->length, data->data); 95 hex_encode(data->data, data->length, &p); 96 append_string(context, sp, "%s", p); 97 free(p); 98 return 0; 99 } 100 101 static char * 102 time2str(time_t t) 103 { 104 static char buf[128]; 105 strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", gmtime(&t)); 106 return buf; 107 } 108 109 static krb5_error_code 110 append_event(krb5_context context, krb5_storage *sp, Event *ev) 111 { 112 char *pr = NULL; 113 krb5_error_code ret; 114 if(ev == NULL) 115 return append_string(context, sp, "- "); 116 if (ev->principal != NULL) { 117 ret = krb5_unparse_name(context, ev->principal, &pr); 118 if(ret) 119 return ret; 120 } 121 ret = append_string(context, sp, "%s:%s ", 122 time2str(ev->time), pr ? pr : "UNKNOWN"); 123 free(pr); 124 return ret; 125 } 126 127 static krb5_error_code 128 entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) 129 { 130 char *p; 131 int i; 132 krb5_error_code ret; 133 134 /* --- principal */ 135 ret = krb5_unparse_name(context, ent->principal, &p); 136 if(ret) 137 return ret; 138 append_string(context, sp, "%s ", p); 139 free(p); 140 /* --- kvno */ 141 append_string(context, sp, "%d", ent->kvno); 142 /* --- keys */ 143 for(i = 0; i < ent->keys.len; i++){ 144 /* --- mkvno, keytype */ 145 if(ent->keys.val[i].mkvno) 146 append_string(context, sp, ":%d:%d:", 147 *ent->keys.val[i].mkvno, 148 ent->keys.val[i].key.keytype); 149 else 150 append_string(context, sp, "::%d:", 151 ent->keys.val[i].key.keytype); 152 /* --- keydata */ 153 append_hex(context, sp, &ent->keys.val[i].key.keyvalue); 154 append_string(context, sp, ":"); 155 /* --- salt */ 156 if(ent->keys.val[i].salt){ 157 append_string(context, sp, "%u/", ent->keys.val[i].salt->type); 158 append_hex(context, sp, &ent->keys.val[i].salt->salt); 159 }else 160 append_string(context, sp, "-"); 161 } 162 append_string(context, sp, " "); 163 /* --- created by */ 164 append_event(context, sp, &ent->created_by); 165 /* --- modified by */ 166 append_event(context, sp, ent->modified_by); 167 168 /* --- valid start */ 169 if(ent->valid_start) 170 append_string(context, sp, "%s ", time2str(*ent->valid_start)); 171 else 172 append_string(context, sp, "- "); 173 174 /* --- valid end */ 175 if(ent->valid_end) 176 append_string(context, sp, "%s ", time2str(*ent->valid_end)); 177 else 178 append_string(context, sp, "- "); 179 180 /* --- password ends */ 181 if(ent->pw_end) 182 append_string(context, sp, "%s ", time2str(*ent->pw_end)); 183 else 184 append_string(context, sp, "- "); 185 186 /* --- max life */ 187 if(ent->max_life) 188 append_string(context, sp, "%d ", *ent->max_life); 189 else 190 append_string(context, sp, "- "); 191 192 /* --- max renewable life */ 193 if(ent->max_renew) 194 append_string(context, sp, "%d ", *ent->max_renew); 195 else 196 append_string(context, sp, "- "); 197 198 /* --- flags */ 199 append_string(context, sp, "%d ", HDBFlags2int(ent->flags)); 200 201 /* --- generation number */ 202 if(ent->generation) { 203 append_string(context, sp, "%s:%d:%d ", time2str(ent->generation->time), 204 ent->generation->usec, 205 ent->generation->gen); 206 } else 207 append_string(context, sp, "- "); 208 209 /* --- extensions */ 210 if(ent->extensions && ent->extensions->len > 0) { 211 for(i = 0; i < ent->extensions->len; i++) { 212 void *d; 213 size_t size, sz; 214 215 ASN1_MALLOC_ENCODE(HDB_extension, d, size, 216 &ent->extensions->val[i], &sz, ret); 217 if (ret) { 218 krb5_clear_error_string(context); 219 return ret; 220 } 221 if(size != sz) 222 krb5_abortx(context, "internal asn.1 encoder error"); 223 224 if (hex_encode(d, size, &p) < 0) { 225 free(d); 226 krb5_set_error_string(context, "malloc: out of memory"); 227 return ENOMEM; 228 } 229 230 free(d); 231 append_string(context, sp, "%s%s", p, 232 ent->extensions->len - 1 != i ? ":" : ""); 233 free(p); 234 } 235 } else 236 append_string(context, sp, "-"); 237 238 239 return 0; 240 } 241 242 krb5_error_code 243 hdb_entry2string (krb5_context context, hdb_entry *ent, char **str) 244 { 245 krb5_error_code ret; 246 krb5_data data; 247 krb5_storage *sp; 248 249 sp = krb5_storage_emem(); 250 if(sp == NULL) { 251 krb5_set_error_string(context, "malloc: out of memory"); 252 return ENOMEM; 253 } 254 255 ret = entry2string_int(context, sp, ent); 256 if(ret) { 257 krb5_storage_free(sp); 258 return ret; 259 } 260 261 krb5_storage_write(sp, "\0", 1); 262 krb5_storage_to_data(sp, &data); 263 krb5_storage_free(sp); 264 *str = data.data; 265 return 0; 266 } 267 268 /* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */ 269 270 krb5_error_code 271 hdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry, void *data) 272 { 273 krb5_error_code ret; 274 krb5_storage *sp; 275 276 FILE *f = data; 277 278 fflush(f); 279 sp = krb5_storage_from_fd(fileno(f)); 280 if(sp == NULL) { 281 krb5_set_error_string(context, "malloc: out of memory"); 282 return ENOMEM; 283 } 284 285 ret = entry2string_int(context, sp, &entry->entry); 286 if(ret) { 287 krb5_storage_free(sp); 288 return ret; 289 } 290 291 krb5_storage_write(sp, "\n", 1); 292 krb5_storage_free(sp); 293 return 0; 294 } 295