xref: /minix3/crypto/external/bsd/heimdal/dist/lib/hdb/print.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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 Högskolan
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
append_string(krb5_context context,krb5_storage * sp,const char * fmt,...)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
append_hex(krb5_context context,krb5_storage * sp,krb5_data * data)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 *
time2str(time_t t)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
append_event(krb5_context context,krb5_storage * sp,Event * ev)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
entry2string_int(krb5_context context,krb5_storage * sp,hdb_entry * ent)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
hdb_entry2string(krb5_context context,hdb_entry * ent,char ** str)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
hdb_print_entry(krb5_context context,HDB * db,hdb_entry_ex * entry,void * data)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