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