155682Smarkm/* 2233294Sstas * Copyright (c) 1999-2005 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of KTH nor the names of its contributors may be 1855682Smarkm * used to endorse or promote products derived from this software without 1955682Smarkm * specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 2255682Smarkm * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2455682Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 2555682Smarkm * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2655682Smarkm * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2755682Smarkm * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 2855682Smarkm * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2955682Smarkm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 3055682Smarkm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 3155682Smarkm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 3255682Smarkm 3355682Smarkm#include "hdb_locl.h" 34178825Sdfr#include <hex.h> 3555682Smarkm#include <ctype.h> 3655682Smarkm 37233294Sstas/* 3855682Smarkm This is the present contents of a dump line. This might change at 3955682Smarkm any time. Fields are separated by white space. 4055682Smarkm 4155682Smarkm principal 4255682Smarkm keyblock 4355682Smarkm kvno 4455682Smarkm keys... 4555682Smarkm mkvno 4655682Smarkm enctype 4755682Smarkm keyvalue 4855682Smarkm salt (- means use normal salt) 4955682Smarkm creation date and principal 5055682Smarkm modification date and principal 5155682Smarkm principal valid from date (not used) 5255682Smarkm principal valid end date (not used) 5355682Smarkm principal key expires (not used) 5455682Smarkm max ticket life 5555682Smarkm max renewable life 5655682Smarkm flags 5790926Snectar generation number 5855682Smarkm */ 5955682Smarkm 6090926Snectarstatic krb5_error_code 6190926Snectarappend_string(krb5_context context, krb5_storage *sp, const char *fmt, ...) 6255682Smarkm{ 6390926Snectar krb5_error_code ret; 6490926Snectar char *s; 6590926Snectar va_list ap; 6690926Snectar va_start(ap, fmt); 6790926Snectar vasprintf(&s, fmt, ap); 6890926Snectar va_end(ap); 6990926Snectar if(s == NULL) { 70233294Sstas krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 7190926Snectar return ENOMEM; 7290926Snectar } 73102644Snectar ret = krb5_storage_write(sp, s, strlen(s)); 7490926Snectar free(s); 7590926Snectar return ret; 7690926Snectar} 7790926Snectar 7890926Snectarstatic krb5_error_code 7990926Snectarappend_hex(krb5_context context, krb5_storage *sp, krb5_data *data) 8090926Snectar{ 81233294Sstas int printable = 1; 82233294Sstas size_t i; 8355682Smarkm char *p; 8455682Smarkm 8555682Smarkm p = data->data; 8655682Smarkm for(i = 0; i < data->length; i++) 8755682Smarkm if(!isalnum((unsigned char)p[i]) && p[i] != '.'){ 8890926Snectar printable = 0; 8955682Smarkm break; 9055682Smarkm } 9190926Snectar if(printable) 9290926Snectar return append_string(context, sp, "\"%.*s\"", 9390926Snectar data->length, data->data); 94178825Sdfr hex_encode(data->data, data->length, &p); 95178825Sdfr append_string(context, sp, "%s", p); 96178825Sdfr free(p); 9790926Snectar return 0; 9855682Smarkm} 9955682Smarkm 10055682Smarkmstatic char * 10155682Smarkmtime2str(time_t t) 10255682Smarkm{ 10355682Smarkm static char buf[128]; 10455682Smarkm strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", gmtime(&t)); 10555682Smarkm return buf; 10655682Smarkm} 10755682Smarkm 10855682Smarkmstatic krb5_error_code 10990926Snectarappend_event(krb5_context context, krb5_storage *sp, Event *ev) 11055682Smarkm{ 11190926Snectar char *pr = NULL; 11255682Smarkm krb5_error_code ret; 11390926Snectar if(ev == NULL) 11490926Snectar return append_string(context, sp, "- "); 11590926Snectar if (ev->principal != NULL) { 11655682Smarkm ret = krb5_unparse_name(context, ev->principal, &pr); 11755682Smarkm if(ret) 11855682Smarkm return ret; 11955682Smarkm } 12090926Snectar ret = append_string(context, sp, "%s:%s ", 12190926Snectar time2str(ev->time), pr ? pr : "UNKNOWN"); 12255682Smarkm free(pr); 12390926Snectar return ret; 12455682Smarkm} 12555682Smarkm 12690926Snectarstatic krb5_error_code 12790926Snectarentry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) 12855682Smarkm{ 12955682Smarkm char *p; 130233294Sstas size_t i; 13155682Smarkm krb5_error_code ret; 13255682Smarkm 13355682Smarkm /* --- principal */ 13455682Smarkm ret = krb5_unparse_name(context, ent->principal, &p); 13555682Smarkm if(ret) 13655682Smarkm return ret; 13790926Snectar append_string(context, sp, "%s ", p); 13855682Smarkm free(p); 13955682Smarkm /* --- kvno */ 14090926Snectar append_string(context, sp, "%d", ent->kvno); 14155682Smarkm /* --- keys */ 14255682Smarkm for(i = 0; i < ent->keys.len; i++){ 14355682Smarkm /* --- mkvno, keytype */ 14455682Smarkm if(ent->keys.val[i].mkvno) 145233294Sstas append_string(context, sp, ":%d:%d:", 146233294Sstas *ent->keys.val[i].mkvno, 14790926Snectar ent->keys.val[i].key.keytype); 14855682Smarkm else 149233294Sstas append_string(context, sp, "::%d:", 15090926Snectar ent->keys.val[i].key.keytype); 15155682Smarkm /* --- keydata */ 15290926Snectar append_hex(context, sp, &ent->keys.val[i].key.keyvalue); 15390926Snectar append_string(context, sp, ":"); 15455682Smarkm /* --- salt */ 15555682Smarkm if(ent->keys.val[i].salt){ 15690926Snectar append_string(context, sp, "%u/", ent->keys.val[i].salt->type); 15790926Snectar append_hex(context, sp, &ent->keys.val[i].salt->salt); 15855682Smarkm }else 15990926Snectar append_string(context, sp, "-"); 16055682Smarkm } 16190926Snectar append_string(context, sp, " "); 16255682Smarkm /* --- created by */ 16390926Snectar append_event(context, sp, &ent->created_by); 16455682Smarkm /* --- modified by */ 16590926Snectar append_event(context, sp, ent->modified_by); 16655682Smarkm 16755682Smarkm /* --- valid start */ 16855682Smarkm if(ent->valid_start) 16990926Snectar append_string(context, sp, "%s ", time2str(*ent->valid_start)); 17055682Smarkm else 17190926Snectar append_string(context, sp, "- "); 17255682Smarkm 17355682Smarkm /* --- valid end */ 17455682Smarkm if(ent->valid_end) 17590926Snectar append_string(context, sp, "%s ", time2str(*ent->valid_end)); 17655682Smarkm else 17790926Snectar append_string(context, sp, "- "); 178233294Sstas 17955682Smarkm /* --- password ends */ 18055682Smarkm if(ent->pw_end) 18190926Snectar append_string(context, sp, "%s ", time2str(*ent->pw_end)); 18255682Smarkm else 18390926Snectar append_string(context, sp, "- "); 18455682Smarkm 18555682Smarkm /* --- max life */ 18690926Snectar if(ent->max_life) 18790926Snectar append_string(context, sp, "%d ", *ent->max_life); 18890926Snectar else 18990926Snectar append_string(context, sp, "- "); 19055682Smarkm 19155682Smarkm /* --- max renewable life */ 19290926Snectar if(ent->max_renew) 19390926Snectar append_string(context, sp, "%d ", *ent->max_renew); 19490926Snectar else 19590926Snectar append_string(context, sp, "- "); 196233294Sstas 19790926Snectar /* --- flags */ 19890926Snectar append_string(context, sp, "%d ", HDBFlags2int(ent->flags)); 19955682Smarkm 20090926Snectar /* --- generation number */ 20190926Snectar if(ent->generation) { 202178825Sdfr append_string(context, sp, "%s:%d:%d ", time2str(ent->generation->time), 20390926Snectar ent->generation->usec, 20490926Snectar ent->generation->gen); 20590926Snectar } else 206178825Sdfr append_string(context, sp, "- "); 207178825Sdfr 208178825Sdfr /* --- extensions */ 209178825Sdfr if(ent->extensions && ent->extensions->len > 0) { 210178825Sdfr for(i = 0; i < ent->extensions->len; i++) { 211178825Sdfr void *d; 212233294Sstas size_t size, sz = 0; 213178825Sdfr 214178825Sdfr ASN1_MALLOC_ENCODE(HDB_extension, d, size, 215178825Sdfr &ent->extensions->val[i], &sz, ret); 216178825Sdfr if (ret) { 217233294Sstas krb5_clear_error_message(context); 218178825Sdfr return ret; 219178825Sdfr } 220178825Sdfr if(size != sz) 221178825Sdfr krb5_abortx(context, "internal asn.1 encoder error"); 222178825Sdfr 223178825Sdfr if (hex_encode(d, size, &p) < 0) { 224178825Sdfr free(d); 225233294Sstas krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 226178825Sdfr return ENOMEM; 227178825Sdfr } 228178825Sdfr 229178825Sdfr free(d); 230233294Sstas append_string(context, sp, "%s%s", p, 231178825Sdfr ent->extensions->len - 1 != i ? ":" : ""); 232178825Sdfr free(p); 233178825Sdfr } 234178825Sdfr } else 23590926Snectar append_string(context, sp, "-"); 236178825Sdfr 237233294Sstas 23890926Snectar return 0; 23990926Snectar} 24090926Snectar 24190926Snectarkrb5_error_code 24290926Snectarhdb_entry2string (krb5_context context, hdb_entry *ent, char **str) 24390926Snectar{ 24490926Snectar krb5_error_code ret; 24590926Snectar krb5_data data; 24690926Snectar krb5_storage *sp; 24790926Snectar 24890926Snectar sp = krb5_storage_emem(); 24990926Snectar if(sp == NULL) { 250233294Sstas krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 25190926Snectar return ENOMEM; 25290926Snectar } 253233294Sstas 25490926Snectar ret = entry2string_int(context, sp, ent); 25590926Snectar if(ret) { 25690926Snectar krb5_storage_free(sp); 25790926Snectar return ret; 25890926Snectar } 25990926Snectar 260102644Snectar krb5_storage_write(sp, "\0", 1); 26190926Snectar krb5_storage_to_data(sp, &data); 26290926Snectar krb5_storage_free(sp); 26390926Snectar *str = data.data; 26455682Smarkm return 0; 26555682Smarkm} 26655682Smarkm 26755682Smarkm/* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */ 26855682Smarkm 26955682Smarkmkrb5_error_code 270178825Sdfrhdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry, void *data) 27155682Smarkm{ 27290926Snectar krb5_error_code ret; 27390926Snectar krb5_storage *sp; 27490926Snectar 27590926Snectar FILE *f = data; 27690926Snectar 27790926Snectar fflush(f); 27890926Snectar sp = krb5_storage_from_fd(fileno(f)); 27990926Snectar if(sp == NULL) { 280233294Sstas krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 28190926Snectar return ENOMEM; 28290926Snectar } 283233294Sstas 284178825Sdfr ret = entry2string_int(context, sp, &entry->entry); 28590926Snectar if(ret) { 28690926Snectar krb5_storage_free(sp); 28790926Snectar return ret; 28890926Snectar } 28990926Snectar 290102644Snectar krb5_storage_write(sp, "\n", 1); 29190926Snectar krb5_storage_free(sp); 29255682Smarkm return 0; 29355682Smarkm} 294