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