Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / lib / kadm / kadm_stream.c
1 /* 
2   Copyright (C) 1989 by the Massachusetts Institute of Technology
3
4    Export of this software from the United States of America is assumed
5    to require a specific license from the United States Government.
6    It is the responsibility of any person or organization contemplating
7    export to obtain such a license before exporting.
8
9 WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
10 distribute this software and its documentation for any purpose and
11 without fee is hereby granted, provided that the above copyright
12 notice appear in all copies and that both that copyright notice and
13 this permission notice appear in supporting documentation, and that
14 the name of M.I.T. not be used in advertising or publicity pertaining
15 to distribution of the software without specific, written prior
16 permission.  M.I.T. makes no representations about the suitability of
17 this software for any purpose.  It is provided "as is" without express
18 or implied warranty.
19
20   */
21
22 /*
23  * Stream conversion functions for Kerberos administration server
24  */
25
26 /*
27   kadm_stream.c
28   this holds the stream support routines for the kerberos administration server
29
30     vals_to_stream: converts a vals struct to a stream for transmission
31        internals build_field_header, vts_[string, char, long, short]
32     stream_to_vals: converts a stream to a vals struct
33        internals check_field_header, stv_[string, char, long, short]
34     error: prints out a kadm error message, returns
35     fatal: prints out a kadm fatal error message, exits
36 */
37
38 #include "kadm_locl.h"
39
40 RCSID("$Id: kadm_stream.c,v 1.13 1998/10/22 15:38:01 joda Exp $");
41
42 static int
43 build_field_header(u_char *cont, /* container for fields data */
44                    u_char **st) /* stream */
45 {
46   *st = malloc (4);
47   if (*st == NULL)
48       return -1;
49   memcpy(*st, cont, 4);
50   return 4;                     /* return pointer to current stream location */
51 }
52
53 static int
54 check_field_header(u_char *st,  /* stream */
55                    u_char *cont, /* container for fields data */
56                    int maxlen)
57 {
58   if (4 > maxlen)
59       return(-1);
60   memcpy(cont, st, 4);
61   return 4;                     /* return pointer to current stream location */
62 }
63
64 int
65 vts_string(char *dat,           /* a string to put on the stream */
66            u_char **st,         /* base pointer to the stream */
67            int loc)             /* offset into the stream for current data */
68 {
69   void *tmp;
70
71   tmp = realloc(*st, loc + strlen(dat) + 1);
72   if(tmp == NULL)
73     return -1;
74   memcpy((char *)tmp + loc, dat, strlen(dat)+1);
75   *st = tmp;
76   return strlen(dat)+1;
77 }
78
79
80 static int
81 vts_short(u_int16_t dat,        /* the attributes field */
82           u_char **st,          /* a base pointer to the stream */
83           int loc)              /* offset into the stream for current data */
84 {
85     unsigned char *p;
86
87     p = realloc(*st, loc + 2);
88     if(p == NULL)
89         return -1;
90     p[loc] = (dat >> 8) & 0xff;
91     p[loc+1] = dat & 0xff;
92     *st = p;
93     return 2;
94 }
95
96 static int
97 vts_char(u_char dat,            /* the attributes field */
98          u_char **st,           /* a base pointer to the stream */
99          int loc)               /* offset into the stream for current data */
100 {
101     unsigned char *p;
102
103     p = realloc(*st, loc + 1);
104
105     if(p == NULL)
106         return -1;
107     p[loc] = dat;
108     *st = p;
109     return 1;
110 }
111
112 int
113 vts_long(u_int32_t dat,         /* the attributes field */
114          u_char **st,           /* a base pointer to the stream */
115          int loc)               /* offset into the stream for current data */
116 {
117     unsigned char *p;
118
119     p = realloc(*st, loc + 4);
120     if(p == NULL)
121         return -1;
122     p[loc] = (dat >> 24) & 0xff;
123     p[loc+1] = (dat >> 16) & 0xff;
124     p[loc+2] = (dat >> 8) & 0xff;
125     p[loc+3] = dat & 0xff;
126     *st = p;
127     return 4;
128 }
129     
130 int
131 stv_string(u_char *st,          /* base pointer to the stream */
132            char *dat,           /* a string to read from the stream */
133            int loc,             /* offset into the stream for current data */
134            int stlen,           /* max length of string to copy in */
135            int maxlen)          /* max length of input stream */
136 {
137   int maxcount;                         /* max count of chars to copy */
138   int len;
139
140   maxcount = min(maxlen - loc, stlen);
141
142   if(maxcount <= 0)
143       return -1;
144
145   len = strnlen ((char *)st + loc, maxlen - loc);
146
147   if (len >= stlen)
148       return -1;
149
150   memcpy(dat, st + loc, len);
151   dat[len] = '\0';
152   return len + 1;
153 }
154
155 static int
156 stv_short(u_char *st,           /* a base pointer to the stream */
157           u_int16_t *dat,       /* the attributes field */
158           int loc,              /* offset into the stream for current data */
159           int maxlen)
160 {
161   if (maxlen - loc < 2)
162       return -1;
163   
164   *dat = (st[loc] << 8) | st[loc + 1];
165   return 2;
166 }
167
168 int
169 stv_long(u_char *st,            /* a base pointer to the stream */
170          u_int32_t *dat,        /* the attributes field */
171          int loc,               /* offset into the stream for current data */
172          int maxlen)            /* maximum length of st */
173 {
174   if (maxlen - loc < 4)
175       return -1;
176   
177   *dat = (st[loc] << 24) | (st[loc+1] << 16) | (st[loc+2] << 8) | st[loc+3];
178   return 4;
179 }
180     
181 static int
182 stv_char(u_char *st,            /* a base pointer to the stream */
183          u_char *dat,           /* the attributes field */
184          int loc,               /* offset into the stream for current data */
185          int maxlen)
186 {
187   if (maxlen - loc < 1)
188       return -1;
189   
190   *dat = st[loc];
191   return 1;
192 }
193
194 /* 
195 vals_to_stream
196   recieves    : kadm_vals *, u_char *
197   returns     : a realloced and filled in u_char *
198      
199 this function creates a byte-stream representation of the kadm_vals structure
200 */
201 int
202 vals_to_stream(Kadm_vals *dt_in, u_char **dt_out)
203 {
204   int vsloop, stsize;           /* loop counter, stream size */
205
206   stsize = build_field_header(dt_in->fields, dt_out);
207   if (stsize < 0)
208       return stsize;
209   for (vsloop=31; vsloop>=0; vsloop--)
210     if (IS_FIELD(vsloop,dt_in->fields)) {
211       int tmp = 0;
212
213       switch (vsloop) {
214       case KADM_NAME:
215           tmp = vts_string(dt_in->name, dt_out, stsize);
216           break;
217       case KADM_INST:
218           tmp = vts_string(dt_in->instance, dt_out, stsize);
219           break;
220       case KADM_EXPDATE:
221           tmp = vts_long(dt_in->exp_date, dt_out, stsize);
222           break;
223       case KADM_ATTR:
224           tmp = vts_short(dt_in->attributes, dt_out, stsize);
225           break;
226       case KADM_MAXLIFE:
227           tmp = vts_char(dt_in->max_life, dt_out, stsize);
228           break;
229       case KADM_DESKEY: 
230           tmp = vts_long(dt_in->key_high, dt_out, stsize);
231           if(tmp > 0)
232               tmp += vts_long(dt_in->key_low, dt_out, stsize + tmp);
233           break;
234 #ifdef EXTENDED_KADM
235       case KADM_MODDATE:
236           tmp = vts_long(dt_in->mod_date, dt_out, stsize);
237           break;
238       case KADM_MODNAME:
239           tmp = vts_string(dt_in->mod_name, dt_out, stsize);
240           break;
241       case KADM_MODINST:
242           tmp = vts_string(dt_in->mod_instance, dt_out, stsize);
243           break;
244       case KADM_KVNO:
245           tmp = vts_char(dt_in->key_version, dt_out, stsize);
246           break;
247 #endif
248       default:
249           break;
250       }
251       if (tmp < 0) {
252           free(*dt_out);
253           return tmp;
254       }
255       stsize += tmp;
256     }
257   return(stsize);
258 }  
259
260 /* 
261 stream_to_vals
262   recieves    : u_char *, kadm_vals *
263   returns     : a kadm_vals filled in according to u_char *
264      
265 this decodes a byte stream represntation of a vals struct into kadm_vals
266 */
267 int
268 stream_to_vals(u_char *dt_in,
269                Kadm_vals *dt_out,
270                int maxlen)      /* max length to use */
271 {
272     int vsloop, stsize;         /* loop counter, stream size */
273     int status;
274
275     memset(dt_out, 0, sizeof(*dt_out));
276
277     stsize = check_field_header(dt_in, dt_out->fields, maxlen);
278     if (stsize < 0)
279         return(-1);
280     for (vsloop=31; vsloop>=0; vsloop--)
281         if (IS_FIELD(vsloop,dt_out->fields))
282             switch (vsloop) {
283             case KADM_NAME:
284                 if ((status = stv_string(dt_in, dt_out->name, stsize,
285                                          sizeof(dt_out->name), maxlen)) < 0)
286                     return(-1);
287                 stsize += status;
288                 break;
289             case KADM_INST:
290                 if ((status = stv_string(dt_in, dt_out->instance, stsize,
291                                          sizeof(dt_out->instance), maxlen)) < 0)
292                     return(-1);
293                 stsize += status;
294                 break;
295             case KADM_EXPDATE:
296                 if ((status = stv_long(dt_in, &dt_out->exp_date, stsize,
297                                        maxlen)) < 0)
298                     return(-1);
299                 stsize += status;
300                 break;
301             case KADM_ATTR:
302                 if ((status = stv_short(dt_in, &dt_out->attributes, stsize,
303                                         maxlen)) < 0)
304                     return(-1);
305                 stsize += status;
306                 break;
307             case KADM_MAXLIFE:
308                 if ((status = stv_char(dt_in, &dt_out->max_life, stsize,
309                                        maxlen)) < 0)
310                     return(-1);
311                 stsize += status;
312                 break;
313             case KADM_DESKEY:
314                 if ((status = stv_long(dt_in, &dt_out->key_high, stsize,
315                                        maxlen)) < 0)
316                     return(-1);
317                 stsize += status;
318                 if ((status = stv_long(dt_in, &dt_out->key_low, stsize,
319                                        maxlen)) < 0)
320                     return(-1);
321                 stsize += status;
322                 break;
323 #ifdef EXTENDED_KADM
324             case KADM_MODDATE:
325                 if ((status = stv_long(dt_in, &dt_out->mod_date, stsize,
326                                        maxlen)) < 0)
327                     return(-1);
328                 stsize += status;
329                 break;
330             case KADM_MODNAME:
331                 if ((status = stv_string(dt_in, dt_out->mod_name, stsize,
332                                          sizeof(dt_out->mod_name), maxlen)) < 0)
333                     return(-1);
334                 stsize += status;
335                 break;
336             case KADM_MODINST:
337                 if ((status = stv_string(dt_in, dt_out->mod_instance, stsize,
338                                          sizeof(dt_out->mod_instance), maxlen)) < 0)
339                     return(-1);
340                 stsize += status;
341                 break;
342             case KADM_KVNO:
343                 if ((status = stv_char(dt_in, &dt_out->key_version, stsize,
344                                        maxlen)) < 0)
345                     return(-1);
346                 stsize += status;
347                 break;
348 #endif
349             default:
350                 break;
351             }
352     return stsize;
353 }