- Complete re-write of sasc.
[dragonfly.git] / crypto / heimdal / lib / hdb / print.c
1 /*
2  * Copyright (c) 1999-2002 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden). 
4  * All rights reserved. 
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met: 
9  *
10  * 1. Redistributions of source code must retain the above copyright 
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright 
14  *    notice, this list of conditions and the following disclaimer in the 
15  *    documentation and/or other materials provided with the distribution. 
16  *
17  * 3. Neither the name of KTH nor the names of its contributors may be
18  *    used to endorse or promote products derived from this software without
19  *    specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
32
33 #include "hdb_locl.h"
34 #include <ctype.h>
35
36 RCSID("$Id: print.c,v 1.8 2002/05/24 15:18:02 joda Exp $");
37
38 /* 
39    This is the present contents of a dump line. This might change at
40    any time. Fields are separated by white space.
41
42   principal
43   keyblock
44         kvno
45         keys...
46                 mkvno
47                 enctype
48                 keyvalue
49                 salt (- means use normal salt)
50   creation date and principal
51   modification date and principal
52   principal valid from date (not used)
53   principal valid end date (not used)
54   principal key expires (not used)
55   max ticket life
56   max renewable life
57   flags
58   generation number
59   */
60
61 static krb5_error_code
62 append_string(krb5_context context, krb5_storage *sp, const char *fmt, ...)
63 {
64     krb5_error_code ret;
65     char *s;
66     va_list ap;
67     va_start(ap, fmt);
68     vasprintf(&s, fmt, ap);
69     va_end(ap);
70     if(s == NULL) {
71         krb5_set_error_string(context, "malloc: out of memory");
72         return ENOMEM;
73     }
74     ret = krb5_storage_write(sp, s, strlen(s));
75     free(s);
76     return ret;
77 }
78
79 static krb5_error_code
80 append_hex(krb5_context context, krb5_storage *sp, krb5_data *data)
81 {
82     int i, printable = 1;
83     char *p;
84
85     p = data->data;
86     for(i = 0; i < data->length; i++)
87         if(!isalnum((unsigned char)p[i]) && p[i] != '.'){
88             printable = 0;
89             break;
90         }
91     if(printable)
92         return append_string(context, sp, "\"%.*s\"",
93                              data->length, data->data);
94     for(i = 0; i < data->length; i++) 
95         append_string(context, sp, "%02x", ((unsigned char*)data->data)[i]);
96     return 0;
97 }
98
99 static char *
100 time2str(time_t t)
101 {
102     static char buf[128];
103     strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", gmtime(&t));
104     return buf;
105 }
106
107 static krb5_error_code
108 append_event(krb5_context context, krb5_storage *sp, Event *ev)
109 {
110     char *pr = NULL;
111     krb5_error_code ret;
112     if(ev == NULL)
113         return append_string(context, sp, "- ");
114     if (ev->principal != NULL) {
115        ret = krb5_unparse_name(context, ev->principal, &pr);
116        if(ret)
117            return ret;
118     }
119     ret = append_string(context, sp, "%s:%s ",
120                         time2str(ev->time), pr ? pr : "UNKNOWN");
121     free(pr);
122     return ret;
123 }
124
125 static krb5_error_code
126 entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent)
127 {
128     char *p;
129     int i;
130     krb5_error_code ret;
131
132     /* --- principal */
133     ret = krb5_unparse_name(context, ent->principal, &p);
134     if(ret)
135         return ret;
136     append_string(context, sp, "%s ", p);
137     free(p);
138     /* --- kvno */
139     append_string(context, sp, "%d", ent->kvno);
140     /* --- keys */
141     for(i = 0; i < ent->keys.len; i++){
142         /* --- mkvno, keytype */
143         if(ent->keys.val[i].mkvno)
144             append_string(context, sp, ":%d:%d:", 
145                           *ent->keys.val[i].mkvno, 
146                           ent->keys.val[i].key.keytype);
147         else
148             append_string(context, sp, "::%d:", 
149                           ent->keys.val[i].key.keytype);
150         /* --- keydata */
151         append_hex(context, sp, &ent->keys.val[i].key.keyvalue);
152         append_string(context, sp, ":");
153         /* --- salt */
154         if(ent->keys.val[i].salt){
155             append_string(context, sp, "%u/", ent->keys.val[i].salt->type);
156             append_hex(context, sp, &ent->keys.val[i].salt->salt);
157         }else
158             append_string(context, sp, "-");
159     }
160     append_string(context, sp, " ");
161     /* --- created by */
162     append_event(context, sp, &ent->created_by);
163     /* --- modified by */
164     append_event(context, sp, ent->modified_by);
165
166     /* --- valid start */
167     if(ent->valid_start)
168         append_string(context, sp, "%s ", time2str(*ent->valid_start));
169     else
170         append_string(context, sp, "- ");
171
172     /* --- valid end */
173     if(ent->valid_end)
174         append_string(context, sp, "%s ", time2str(*ent->valid_end));
175     else
176         append_string(context, sp, "- ");
177     
178     /* --- password ends */
179     if(ent->pw_end)
180         append_string(context, sp, "%s ", time2str(*ent->pw_end));
181     else
182         append_string(context, sp, "- ");
183
184     /* --- max life */
185     if(ent->max_life)
186         append_string(context, sp, "%d ", *ent->max_life);
187     else
188         append_string(context, sp, "- ");
189
190     /* --- max renewable life */
191     if(ent->max_renew)
192         append_string(context, sp, "%d ", *ent->max_renew);
193     else
194         append_string(context, sp, "- ");
195     
196     /* --- flags */
197     append_string(context, sp, "%d ", HDBFlags2int(ent->flags));
198
199     /* --- generation number */
200     if(ent->generation) {
201         append_string(context, sp, "%s:%d:%d", time2str(ent->generation->time),
202                       ent->generation->usec,
203                       ent->generation->gen);
204     } else
205         append_string(context, sp, "-");
206     
207     return 0;
208 }
209
210 krb5_error_code
211 hdb_entry2string (krb5_context context, hdb_entry *ent, char **str)
212 {
213     krb5_error_code ret;
214     krb5_data data;
215     krb5_storage *sp;
216
217     sp = krb5_storage_emem();
218     if(sp == NULL) {
219         krb5_set_error_string(context, "malloc: out of memory");
220         return ENOMEM;
221     }
222     
223     ret = entry2string_int(context, sp, ent);
224     if(ret) {
225         krb5_storage_free(sp);
226         return ret;
227     }
228
229     krb5_storage_write(sp, "\0", 1);
230     krb5_storage_to_data(sp, &data);
231     krb5_storage_free(sp);
232     *str = data.data;
233     return 0;
234 }
235
236 /* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */
237
238 krb5_error_code
239 hdb_print_entry(krb5_context context, HDB *db, hdb_entry *entry, void *data)
240 {
241     krb5_error_code ret;
242     krb5_storage *sp;
243
244     FILE *f = data;
245
246     fflush(f);
247     sp = krb5_storage_from_fd(fileno(f));
248     if(sp == NULL) {
249         krb5_set_error_string(context, "malloc: out of memory");
250         return ENOMEM;
251     }
252     
253     ret = entry2string_int(context, sp, entry);
254     if(ret) {
255         krb5_storage_free(sp);
256         return ret;
257     }
258
259     krb5_storage_write(sp, "\n", 1);
260     krb5_storage_free(sp);
261     return 0;
262 }