Home | History | Annotate | Line # | Download | only in hdb
print.c revision 1.1
      1 /*	$NetBSD: print.c,v 1.1 2011/04/13 18:14:42 elric 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 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_message(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_message(context, ENOMEM, "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_message(context, ENOMEM, "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_message(context, ENOMEM, "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