1321936Shselasky/* 2321936Shselasky * Copyright (c) 1999-2005 Kungliga Tekniska H��gskolan 3321936Shselasky * (Royal Institute of Technology, Stockholm, Sweden). 4321936Shselasky * All rights reserved. 5321936Shselasky * 6321936Shselasky * Redistribution and use in source and binary forms, with or without 7321936Shselasky * modification, are permitted provided that the following conditions 8321936Shselasky * are met: 9321936Shselasky * 10321936Shselasky * 1. Redistributions of source code must retain the above copyright 11321936Shselasky * notice, this list of conditions and the following disclaimer. 12321936Shselasky * 13321936Shselasky * 2. Redistributions in binary form must reproduce the above copyright 14321936Shselasky * notice, this list of conditions and the following disclaimer in the 15321936Shselasky * documentation and/or other materials provided with the distribution. 16321936Shselasky * 17321936Shselasky * 3. Neither the name of KTH nor the names of its contributors may be 18321936Shselasky * used to endorse or promote products derived from this software without 19321936Shselasky * specific prior written permission. 20321936Shselasky * 21321936Shselasky * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 22321936Shselasky * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23321936Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24321936Shselasky * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 25321936Shselasky * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26321936Shselasky * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27321936Shselasky * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28321936Shselasky * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29321936Shselasky * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30321936Shselasky * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31321936Shselasky * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 32321936Shselasky 33321936Shselasky#include "hdb_locl.h" 34321936Shselasky#include <hex.h> 35321936Shselasky#include <ctype.h> 36321936Shselasky 37321936Shselasky/* 38321936Shselasky This is the present contents of a dump line. This might change at 39321936Shselasky any time. Fields are separated by white space. 40321936Shselasky 41321936Shselasky principal 42321936Shselasky keyblock 43321936Shselasky kvno 44321936Shselasky keys... 45321936Shselasky mkvno 46321936Shselasky enctype 47321936Shselasky keyvalue 48321936Shselasky salt (- means use normal salt) 49321936Shselasky creation date and principal 50321936Shselasky modification date and principal 51321936Shselasky principal valid from date (not used) 52321936Shselasky principal valid end date (not used) 53321936Shselasky principal key expires (not used) 54321936Shselasky max ticket life 55321936Shselasky max renewable life 56321936Shselasky flags 57321936Shselasky generation number 58321936Shselasky */ 59321936Shselasky 60321936Shselaskystatic krb5_error_code 61321936Shselaskyappend_string(krb5_context context, krb5_storage *sp, const char *fmt, ...) 62321936Shselasky{ 63321936Shselasky krb5_error_code ret; 64321936Shselasky char *s; 65321936Shselasky va_list ap; 66321936Shselasky va_start(ap, fmt); 67321936Shselasky vasprintf(&s, fmt, ap); 68321936Shselasky va_end(ap); 69321936Shselasky if(s == NULL) { 70321936Shselasky krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 71321936Shselasky return ENOMEM; 72321936Shselasky } 73321936Shselasky ret = krb5_storage_write(sp, s, strlen(s)); 74321936Shselasky free(s); 75321936Shselasky return ret; 76321936Shselasky} 77321936Shselasky 78321936Shselaskystatic krb5_error_code 79321936Shselaskyappend_hex(krb5_context context, krb5_storage *sp, krb5_data *data) 80321936Shselasky{ 81321936Shselasky int printable = 1; 82321936Shselasky size_t i; 83321936Shselasky char *p; 84321936Shselasky 85321936Shselasky p = data->data; 86321936Shselasky for(i = 0; i < data->length; i++) 87321936Shselasky if(!isalnum((unsigned char)p[i]) && p[i] != '.'){ 88321936Shselasky printable = 0; 89321936Shselasky break; 90321936Shselasky } 91321936Shselasky if(printable) 92321936Shselasky return append_string(context, sp, "\"%.*s\"", 93321936Shselasky data->length, data->data); 94321936Shselasky hex_encode(data->data, data->length, &p); 95321936Shselasky append_string(context, sp, "%s", p); 96321936Shselasky free(p); 97321936Shselasky return 0; 98321936Shselasky} 99321936Shselasky 100321936Shselaskystatic char * 101321936Shselaskytime2str(time_t t) 102321936Shselasky{ 103321936Shselasky static char buf[128]; 104321936Shselasky strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", gmtime(&t)); 105321936Shselasky return buf; 106321936Shselasky} 107321936Shselasky 108321936Shselaskystatic krb5_error_code 109321936Shselaskyappend_event(krb5_context context, krb5_storage *sp, Event *ev) 110321936Shselasky{ 111321936Shselasky char *pr = NULL; 112321936Shselasky krb5_error_code ret; 113321936Shselasky if(ev == NULL) 114321936Shselasky return append_string(context, sp, "- "); 115321936Shselasky if (ev->principal != NULL) { 116321936Shselasky ret = krb5_unparse_name(context, ev->principal, &pr); 117321936Shselasky if(ret) 118321936Shselasky return ret; 119321936Shselasky } 120321936Shselasky ret = append_string(context, sp, "%s:%s ", 121321936Shselasky time2str(ev->time), pr ? pr : "UNKNOWN"); 122321936Shselasky free(pr); 123321936Shselasky return ret; 124321936Shselasky} 125321936Shselasky 126321936Shselaskystatic krb5_error_code 127321936Shselaskyentry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) 128321936Shselasky{ 129321936Shselasky char *p; 130321936Shselasky size_t i; 131321936Shselasky krb5_error_code ret; 132321936Shselasky 133321936Shselasky /* --- principal */ 134321936Shselasky ret = krb5_unparse_name(context, ent->principal, &p); 135321936Shselasky if(ret) 136321936Shselasky return ret; 137321936Shselasky append_string(context, sp, "%s ", p); 138321936Shselasky free(p); 139321936Shselasky /* --- kvno */ 140321936Shselasky append_string(context, sp, "%d", ent->kvno); 141321936Shselasky /* --- keys */ 142321936Shselasky for(i = 0; i < ent->keys.len; i++){ 143321936Shselasky /* --- mkvno, keytype */ 144321936Shselasky if(ent->keys.val[i].mkvno) 145321936Shselasky append_string(context, sp, ":%d:%d:", 146321936Shselasky *ent->keys.val[i].mkvno, 147321936Shselasky ent->keys.val[i].key.keytype); 148321936Shselasky else 149321936Shselasky append_string(context, sp, "::%d:", 150321936Shselasky ent->keys.val[i].key.keytype); 151321936Shselasky /* --- keydata */ 152321936Shselasky append_hex(context, sp, &ent->keys.val[i].key.keyvalue); 153321936Shselasky append_string(context, sp, ":"); 154321936Shselasky /* --- salt */ 155321936Shselasky if(ent->keys.val[i].salt){ 156321936Shselasky append_string(context, sp, "%u/", ent->keys.val[i].salt->type); 157321936Shselasky append_hex(context, sp, &ent->keys.val[i].salt->salt); 158321936Shselasky }else 159321936Shselasky append_string(context, sp, "-"); 160321936Shselasky } 161321936Shselasky append_string(context, sp, " "); 162321936Shselasky /* --- created by */ 163321936Shselasky append_event(context, sp, &ent->created_by); 164321936Shselasky /* --- modified by */ 165321936Shselasky append_event(context, sp, ent->modified_by); 166321936Shselasky 167321936Shselasky /* --- valid start */ 168321936Shselasky if(ent->valid_start) 169321936Shselasky append_string(context, sp, "%s ", time2str(*ent->valid_start)); 170321936Shselasky else 171321936Shselasky append_string(context, sp, "- "); 172321936Shselasky 173321936Shselasky /* --- valid end */ 174321936Shselasky if(ent->valid_end) 175321936Shselasky append_string(context, sp, "%s ", time2str(*ent->valid_end)); 176321936Shselasky else 177321936Shselasky append_string(context, sp, "- "); 178321936Shselasky 179321936Shselasky /* --- password ends */ 180321936Shselasky if(ent->pw_end) 181321936Shselasky append_string(context, sp, "%s ", time2str(*ent->pw_end)); 182321936Shselasky else 183321936Shselasky append_string(context, sp, "- "); 184321936Shselasky 185321936Shselasky /* --- max life */ 186321936Shselasky if(ent->max_life) 187321936Shselasky append_string(context, sp, "%d ", *ent->max_life); 188321936Shselasky else 189321936Shselasky append_string(context, sp, "- "); 190321936Shselasky 191321936Shselasky /* --- max renewable life */ 192321936Shselasky if(ent->max_renew) 193321936Shselasky append_string(context, sp, "%d ", *ent->max_renew); 194321936Shselasky else 195321936Shselasky append_string(context, sp, "- "); 196321936Shselasky 197321936Shselasky /* --- flags */ 198321936Shselasky append_string(context, sp, "%d ", HDBFlags2int(ent->flags)); 199321936Shselasky 200321936Shselasky /* --- generation number */ 201321936Shselasky if(ent->generation) { 202321936Shselasky append_string(context, sp, "%s:%d:%d ", time2str(ent->generation->time), 203321936Shselasky ent->generation->usec, 204321936Shselasky ent->generation->gen); 205321936Shselasky } else 206321936Shselasky append_string(context, sp, "- "); 207321936Shselasky 208321936Shselasky /* --- extensions */ 209321936Shselasky if(ent->extensions && ent->extensions->len > 0) { 210321936Shselasky for(i = 0; i < ent->extensions->len; i++) { 211321936Shselasky void *d; 212321936Shselasky size_t size, sz = 0; 213321936Shselasky 214321936Shselasky ASN1_MALLOC_ENCODE(HDB_extension, d, size, 215321936Shselasky &ent->extensions->val[i], &sz, ret); 216321936Shselasky if (ret) { 217321936Shselasky krb5_clear_error_message(context); 218321936Shselasky return ret; 219321936Shselasky } 220321936Shselasky if(size != sz) 221321936Shselasky krb5_abortx(context, "internal asn.1 encoder error"); 222321936Shselasky 223321936Shselasky if (hex_encode(d, size, &p) < 0) { 224321936Shselasky free(d); 225321936Shselasky krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 226321936Shselasky return ENOMEM; 227321936Shselasky } 228321936Shselasky 229321936Shselasky free(d); 230321936Shselasky append_string(context, sp, "%s%s", p, 231321936Shselasky ent->extensions->len - 1 != i ? ":" : ""); 232321936Shselasky free(p); 233321936Shselasky } 234321936Shselasky } else 235321936Shselasky append_string(context, sp, "-"); 236321936Shselasky 237321936Shselasky 238321936Shselasky return 0; 239321936Shselasky} 240321936Shselasky 241321936Shselaskykrb5_error_code 242321936Shselaskyhdb_entry2string (krb5_context context, hdb_entry *ent, char **str) 243321936Shselasky{ 244321936Shselasky krb5_error_code ret; 245321936Shselasky krb5_data data; 246321936Shselasky krb5_storage *sp; 247321936Shselasky 248321936Shselasky sp = krb5_storage_emem(); 249321936Shselasky if(sp == NULL) { 250321936Shselasky krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 251321936Shselasky return ENOMEM; 252321936Shselasky } 253321936Shselasky 254321936Shselasky ret = entry2string_int(context, sp, ent); 255321936Shselasky if(ret) { 256321936Shselasky krb5_storage_free(sp); 257321936Shselasky return ret; 258321936Shselasky } 259321936Shselasky 260 krb5_storage_write(sp, "\0", 1); 261 krb5_storage_to_data(sp, &data); 262 krb5_storage_free(sp); 263 *str = data.data; 264 return 0; 265} 266 267/* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */ 268 269krb5_error_code 270hdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry, void *data) 271{ 272 krb5_error_code ret; 273 krb5_storage *sp; 274 275 FILE *f = data; 276 277 fflush(f); 278 sp = krb5_storage_from_fd(fileno(f)); 279 if(sp == NULL) { 280 krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 281 return ENOMEM; 282 } 283 284 ret = entry2string_int(context, sp, &entry->entry); 285 if(ret) { 286 krb5_storage_free(sp); 287 return ret; 288 } 289 290 krb5_storage_write(sp, "\n", 1); 291 krb5_storage_free(sp); 292 return 0; 293} 294