protoize
[krb5.git] / src / lib / krb5 / krb / auth_con.c
1 #include "k5-int.h"
2 #include "auth_con.h"
3
4 static krb5_error_code
5 actx_copy_addr(krb5_context context, const krb5_address *inad, krb5_address **outad)
6 {
7     krb5_address *tmpad;
8
9     if (!(tmpad = (krb5_address *)malloc(sizeof(*tmpad))))
10         return ENOMEM;
11 #ifdef HAVE_C_STRUCTURE_ASSIGNMENT
12     *tmpad = *inad;
13 #else
14     memcpy(tmpad, inad, sizeof(krb5_address));
15 #endif
16     if (!(tmpad->contents = (krb5_octet *)malloc(inad->length))) {
17         krb5_xfree(tmpad);
18         return ENOMEM;
19     }
20     memcpy((char *)tmpad->contents, (char *)inad->contents, inad->length);
21     *outad = tmpad;
22     return 0;
23 }
24
25 krb5_error_code KRB5_CALLCONV
26 krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context)
27 {
28     *auth_context =
29             (krb5_auth_context)malloc(sizeof(struct _krb5_auth_context));
30     if (!*auth_context)
31             return ENOMEM;
32     
33     memset(*auth_context, 0, sizeof(struct _krb5_auth_context));
34
35     /* Default flags, do time not seq */
36     (*auth_context)->auth_context_flags = 
37             KRB5_AUTH_CONTEXT_DO_TIME |  KRB5_AUTH_CONN_INITIALIZED;
38
39     (*auth_context)->req_cksumtype = context->default_ap_req_sumtype;
40     (*auth_context)->safe_cksumtype = context->default_safe_sumtype;
41     (*auth_context)->magic = KV5M_AUTH_CONTEXT;
42     return 0;
43 }
44
45 krb5_error_code KRB5_CALLCONV
46 krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
47 {
48     if (auth_context->local_addr) 
49         krb5_free_address(context, auth_context->local_addr);
50     if (auth_context->remote_addr) 
51         krb5_free_address(context, auth_context->remote_addr);
52     if (auth_context->local_port) 
53         krb5_free_address(context, auth_context->local_port);
54     if (auth_context->remote_port) 
55         krb5_free_address(context, auth_context->remote_port);
56     if (auth_context->authentp) 
57         krb5_free_authenticator(context, auth_context->authentp);
58     if (auth_context->keyblock) 
59         krb5_free_keyblock(context, auth_context->keyblock);
60     if (auth_context->local_subkey) 
61         krb5_free_keyblock(context, auth_context->local_subkey);
62     if (auth_context->remote_subkey) 
63         krb5_free_keyblock(context, auth_context->remote_subkey);
64     if (auth_context->rcache)
65         krb5_rc_close(context, auth_context->rcache);
66     if (auth_context->permitted_etypes)
67         krb5_xfree(auth_context->permitted_etypes);
68     free(auth_context);
69     return 0;
70 }
71
72 krb5_error_code
73 krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address *local_addr, krb5_address *remote_addr)
74 {
75     krb5_error_code     retval;
76
77     /* Free old addresses */
78     if (auth_context->local_addr)
79         (void) krb5_free_address(context, auth_context->local_addr);
80     if (auth_context->remote_addr)
81         (void) krb5_free_address(context, auth_context->remote_addr);
82
83     retval = 0;
84     if (local_addr)
85         retval = actx_copy_addr(context,
86                                 local_addr,
87                                 &auth_context->local_addr);
88     else
89         auth_context->local_addr = NULL;
90
91     if (!retval && remote_addr)
92         retval = actx_copy_addr(context,
93                                 remote_addr,
94                                 &auth_context->remote_addr);
95     else
96         auth_context->remote_addr = NULL;
97
98     return retval;
99 }
100
101 krb5_error_code KRB5_CALLCONV
102 krb5_auth_con_getaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address **local_addr, krb5_address **remote_addr)
103 {
104     krb5_error_code     retval;
105
106     retval = 0;
107     if (local_addr && auth_context->local_addr) {
108         retval = actx_copy_addr(context,
109                                 auth_context->local_addr,
110                                 local_addr);
111     }
112     if (!retval && (remote_addr) && auth_context->remote_addr) {
113         retval = actx_copy_addr(context,
114                                 auth_context->remote_addr,
115                                 remote_addr);
116     }
117     return retval;
118 }
119
120 krb5_error_code KRB5_CALLCONV
121 krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb5_address *local_port, krb5_address *remote_port)
122 {
123     krb5_error_code     retval;
124
125     /* Free old addresses */
126     if (auth_context->local_port)
127         (void) krb5_free_address(context, auth_context->local_port);
128     if (auth_context->remote_port)
129         (void) krb5_free_address(context, auth_context->remote_port);
130
131     retval = 0;
132     if (local_port)
133         retval = actx_copy_addr(context,
134                                 local_port,
135                                 &auth_context->local_port);
136     else
137         auth_context->local_port = NULL;
138
139     if (!retval && remote_port)
140         retval = actx_copy_addr(context,
141                                 remote_port,
142                                 &auth_context->remote_port);
143     else
144         auth_context->remote_port = NULL;
145
146     return retval;
147 }
148
149
150 /*
151  * This function overloads the keyblock field. It is only useful prior to
152  * a krb5_rd_req_decode() call for user to user authentication where the
153  * server has the key and needs to use it to decrypt the incoming request.
154  * Once decrypted this key is no longer necessary and is then overwritten
155  * with the session key sent by the client.
156  */
157 krb5_error_code KRB5_CALLCONV
158 krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock)
159 {
160     if (auth_context->keyblock)
161         krb5_free_keyblock(context, auth_context->keyblock);
162     return(krb5_copy_keyblock(context, keyblock, &(auth_context->keyblock)));
163 }
164
165 krb5_error_code KRB5_CALLCONV
166 krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
167 {
168     if (auth_context->keyblock)
169         return krb5_copy_keyblock(context, auth_context->keyblock, keyblock);
170     *keyblock = NULL;
171     return 0;
172 }
173
174 krb5_error_code KRB5_CALLCONV
175 krb5_auth_con_getlocalsubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
176 {
177     if (auth_context->local_subkey)
178         return krb5_copy_keyblock(context,auth_context->local_subkey,keyblock);
179     *keyblock = NULL;
180     return 0;
181 }
182
183 krb5_error_code KRB5_CALLCONV
184 krb5_auth_con_getremotesubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
185 {
186     if (auth_context->remote_subkey)
187         return krb5_copy_keyblock(context,auth_context->remote_subkey,keyblock);
188     *keyblock = NULL;
189     return 0;
190 }
191
192 krb5_error_code KRB5_CALLCONV
193 krb5_auth_con_set_req_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
194 {
195     auth_context->req_cksumtype = cksumtype;
196     return 0;
197 }
198
199 krb5_error_code
200 krb5_auth_con_set_safe_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
201 {
202     auth_context->safe_cksumtype = cksumtype;
203     return 0;
204 }
205
206 krb5_error_code KRB5_CALLCONV
207 krb5_auth_con_getlocalseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
208 {
209     *seqnumber = auth_context->local_seq_number;
210     return 0;
211 }
212
213 krb5_error_code KRB5_CALLCONV
214 krb5_auth_con_getauthenticator(krb5_context context, krb5_auth_context auth_context, krb5_authenticator **authenticator)
215 {
216     return (krb5_copy_authenticator(context, auth_context->authentp,
217                                     authenticator));
218 }
219
220 krb5_error_code KRB5_CALLCONV
221 krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
222 {
223     *seqnumber = auth_context->remote_seq_number;
224     return 0;
225 }
226
227 krb5_error_code KRB5_CALLCONV
228 krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context)
229 {
230     krb5_error_code ret;
231
232     if (auth_context->keyblock) {
233         size_t blocksize;
234
235         if ((ret = krb5_c_block_size(context, auth_context->keyblock->enctype,
236                                     &blocksize)))
237             return(ret);
238         if ((auth_context->i_vector = (krb5_pointer)malloc(blocksize))) {
239             memset(auth_context->i_vector, 0, blocksize);
240             return 0;
241         }
242         return ENOMEM;
243     }
244     return EINVAL; /* XXX need an error for no keyblock */
245 }
246
247 krb5_error_code
248 krb5_auth_con_setivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer ivector)
249 {
250     auth_context->i_vector = ivector;
251     return 0;
252 }
253
254 krb5_error_code
255 krb5_auth_con_getivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer *ivector)
256 {
257     *ivector = auth_context->i_vector;
258     return 0;
259 }
260
261 krb5_error_code KRB5_CALLCONV
262 krb5_auth_con_setflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 flags)
263 {
264     auth_context->auth_context_flags = flags;
265     return 0;
266 }
267
268 krb5_error_code KRB5_CALLCONV
269 krb5_auth_con_getflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 *flags)
270 {
271     *flags = auth_context->auth_context_flags;
272     return 0;
273 }
274
275 krb5_error_code KRB5_CALLCONV
276 krb5_auth_con_setrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache rcache)
277 {
278     auth_context->rcache = rcache;
279     return 0;
280 }
281     
282 krb5_error_code
283 krb5_auth_con_getrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache *rcache)
284 {
285     *rcache = auth_context->rcache;
286     return 0;
287 }
288     
289 krb5_error_code
290 krb5_auth_con_setpermetypes(krb5_context context, krb5_auth_context auth_context, const krb5_enctype *permetypes)
291 {
292     krb5_enctype        * newpe;
293     int i;
294
295     for (i=0; permetypes[i]; i++)
296         ;
297     i++; /* include the zero */
298
299     if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype)))
300         == NULL)
301         return(ENOMEM);
302
303     if (auth_context->permitted_etypes)
304         krb5_xfree(auth_context->permitted_etypes);
305
306     auth_context->permitted_etypes = newpe;
307
308     memcpy(newpe, permetypes, i*sizeof(krb5_enctype));
309
310     return 0;
311 }
312
313 krb5_error_code
314 krb5_auth_con_getpermetypes(krb5_context context, krb5_auth_context auth_context, krb5_enctype **permetypes)
315 {
316     krb5_enctype        * newpe;
317     int i;
318
319     if (! auth_context->permitted_etypes) {
320         *permetypes = NULL;
321         return(0);
322     }
323
324     for (i=0; auth_context->permitted_etypes[i]; i++)
325         ;
326     i++; /* include the zero */
327
328     if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype)))
329         == NULL)
330         return(ENOMEM);
331
332     *permetypes = newpe;
333
334     memcpy(newpe, auth_context->permitted_etypes, i*sizeof(krb5_enctype));
335
336     return(0);
337 }