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