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