1 /*
2 * lib/krb5/ccache/ser_rc.c
3 *
4 * Copyright 1995 by the Massachusetts Institute of Technology.
5 * All Rights Reserved.
6 *
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
11 *
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
25 *
26 */
27
28 /*
29 * ser_rcdfl.c - Serialize replay cache context.
30 */
31 #include "k5-int.h"
32
33 /*
34 * Routines to deal with externalizing krb5_ccache.
35 * krb5_ccache_size();
36 * krb5_ccache_externalize();
37 * krb5_ccache_internalize();
38 */
39 static krb5_error_code krb5_ccache_size
40 (krb5_context, krb5_pointer, size_t *);
41 static krb5_error_code krb5_ccache_externalize
42 (krb5_context, krb5_pointer, krb5_octet **, size_t *);
43 static krb5_error_code krb5_ccache_internalize
44 (krb5_context,krb5_pointer *, krb5_octet **, size_t *);
45
46 /*
47 * Serialization entry for this type.
48 */
49 static const krb5_ser_entry krb5_ccache_ser_entry = {
50 KV5M_CCACHE, /* Type */
51 krb5_ccache_size, /* Sizer routine */
52 krb5_ccache_externalize, /* Externalize routine */
53 krb5_ccache_internalize /* Internalize routine */
54 };
55
56 /*
57 * krb5_ccache_size() - Determine the size required to externalize
58 * this krb5_ccache variant.
59 */
60 static krb5_error_code
krb5_ccache_size(krb5_context kcontext,krb5_pointer arg,size_t * sizep)61 krb5_ccache_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
62 {
63 krb5_error_code kret;
64 krb5_ccache ccache;
65 size_t required;
66
67 kret = EINVAL;
68 if ((ccache = (krb5_ccache) arg)) {
69 /*
70 * Saving FILE: variants of krb5_ccache requires at minimum:
71 * krb5_int32 for KV5M_CCACHE
72 * krb5_int32 for length of ccache name.
73 * krb5_int32 for KV5M_CCACHE
74 */
75 required = sizeof(krb5_int32) * 3;
76 if (ccache->ops && ccache->ops->prefix)
77 required += (strlen(ccache->ops->prefix)+1);
78
79 /*
80 * The ccache name is formed as follows:
81 * <prefix>:<name>
82 */
83 required += strlen(krb5_cc_get_name(kcontext, ccache));
84
85 kret = 0;
86 *sizep += required;
87 }
88 return(kret);
89 }
90
91 /*
92 * krb5_ccache_externalize() - Externalize the krb5_ccache.
93 */
94 static krb5_error_code
krb5_ccache_externalize(krb5_context kcontext,krb5_pointer arg,krb5_octet ** buffer,size_t * lenremain)95 krb5_ccache_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **buffer, size_t *lenremain)
96 {
97 krb5_error_code kret;
98 krb5_ccache ccache;
99 size_t required;
100 krb5_octet *bp;
101 size_t remain;
102 char *ccname;
103 size_t namelen;
104 const char *fnamep;
105
106 required = 0;
107 bp = *buffer;
108 remain = *lenremain;
109 kret = EINVAL;
110 if ((ccache = (krb5_ccache) arg)) {
111 kret = ENOMEM;
112 if (!krb5_ccache_size(kcontext, arg, &required) &&
113 (required <= remain)) {
114 /* Our identifier */
115 (void) krb5_ser_pack_int32(KV5M_CCACHE, &bp, &remain);
116
117 /* Calculate the length of the name */
118 namelen = (ccache->ops && ccache->ops->prefix) ?
119 strlen(ccache->ops->prefix)+1 : 0;
120 fnamep = krb5_cc_get_name(kcontext, ccache);
121 namelen += (strlen(fnamep)+1);
122
123 if ((ccname = (char *) malloc(namelen))) {
124 /* Format the ccache name. */
125 if (ccache->ops && ccache->ops->prefix)
126 sprintf(ccname, "%s:%s", ccache->ops->prefix, fnamep);
127 else
128 strcpy(ccname, fnamep);
129
130 /* Put the length of the file name */
131 (void) krb5_ser_pack_int32((krb5_int32) strlen(ccname),
132 &bp, &remain);
133
134 /* Put the name */
135 (void) krb5_ser_pack_bytes((krb5_octet *) ccname,
136 strlen(ccname),
137 &bp, &remain);
138
139 /* Put the trailer */
140 (void) krb5_ser_pack_int32(KV5M_CCACHE, &bp, &remain);
141 kret = 0;
142 *buffer = bp;
143 *lenremain = remain;
144 free(ccname);
145 }
146 }
147 }
148 return(kret);
149 }
150
151 /*
152 * krb5_ccache_internalize() - Internalize the krb5_ccache.
153 */
154 static krb5_error_code
krb5_ccache_internalize(krb5_context kcontext,krb5_pointer * argp,krb5_octet ** buffer,size_t * lenremain)155 krb5_ccache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
156 {
157 krb5_error_code kret;
158 krb5_ccache ccache;
159 krb5_int32 ibuf;
160 krb5_octet *bp;
161 size_t remain;
162 char *ccname;
163
164 bp = *buffer;
165 remain = *lenremain;
166 kret = EINVAL;
167 /* Read our magic number */
168 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
169 ibuf = 0;
170 if (ibuf == KV5M_CCACHE) {
171 kret = ENOMEM;
172
173 /* Get the length of the ccache name */
174 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
175
176 if (!kret &&
177 (ccname = (char *) malloc((size_t) (ibuf+1))) &&
178 !(kret = krb5_ser_unpack_bytes((krb5_octet *) ccname,
179 (size_t) ibuf,
180 &bp, &remain))) {
181 ccname[ibuf] = '\0';
182 if (!(kret = krb5_cc_resolve(kcontext, ccname, &ccache)) &&
183 !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) &&
184 (ibuf == KV5M_CCACHE)) {
185 *buffer = bp;
186 *lenremain = remain;
187 *argp = (krb5_pointer) ccache;
188 }
189 free(ccname);
190 }
191 }
192 return(kret);
193 }
194
195 /*
196 * Register the ccache serializer.
197 */
198 krb5_error_code KRB5_CALLCONV
krb5_ser_ccache_init(krb5_context kcontext)199 krb5_ser_ccache_init(krb5_context kcontext)
200 {
201 return(krb5_register_serializer(kcontext, &krb5_ccache_ser_entry));
202 }
203