]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - crypto/heimdal/lib/gssapi/krb5/import_sec_context.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / crypto / heimdal / lib / gssapi / krb5 / import_sec_context.c
1 /*
2  * Copyright (c) 1999 - 2003 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 the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include "gsskrb5_locl.h"
35
36 OM_uint32 GSSAPI_CALLCONV
37 _gsskrb5_import_sec_context (
38     OM_uint32 * minor_status,
39     const gss_buffer_t interprocess_token,
40     gss_ctx_id_t * context_handle
41     )
42 {
43     OM_uint32 ret = GSS_S_FAILURE;
44     krb5_context context;
45     krb5_error_code kret;
46     krb5_storage *sp;
47     krb5_auth_context ac;
48     krb5_address local, remote;
49     krb5_address *localp, *remotep;
50     krb5_data data;
51     gss_buffer_desc buffer;
52     krb5_keyblock keyblock;
53     int32_t flags, tmp;
54     gsskrb5_ctx ctx;
55     gss_name_t name;
56
57     GSSAPI_KRB5_INIT (&context);
58
59     *context_handle = GSS_C_NO_CONTEXT;
60
61     localp = remotep = NULL;
62
63     sp = krb5_storage_from_mem (interprocess_token->value,
64                                 interprocess_token->length);
65     if (sp == NULL) {
66         *minor_status = ENOMEM;
67         return GSS_S_FAILURE;
68     }
69
70     ctx = calloc(1, sizeof(*ctx));
71     if (ctx == NULL) {
72         *minor_status = ENOMEM;
73         krb5_storage_free (sp);
74         return GSS_S_FAILURE;
75     }
76     HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
77
78     kret = krb5_auth_con_init (context,
79                                &ctx->auth_context);
80     if (kret) {
81         *minor_status = kret;
82         ret = GSS_S_FAILURE;
83         goto failure;
84     }
85
86     /* flags */
87
88     *minor_status = 0;
89
90     if (krb5_ret_int32 (sp, &flags) != 0)
91         goto failure;
92
93     /* retrieve the auth context */
94
95     ac = ctx->auth_context;
96     if (krb5_ret_int32 (sp, &tmp) != 0)
97         goto failure;
98     ac->flags = tmp;
99     if (flags & SC_LOCAL_ADDRESS) {
100         if (krb5_ret_address (sp, localp = &local) != 0)
101             goto failure;
102     }
103
104     if (flags & SC_REMOTE_ADDRESS) {
105         if (krb5_ret_address (sp, remotep = &remote) != 0)
106             goto failure;
107     }
108
109     krb5_auth_con_setaddrs (context, ac, localp, remotep);
110     if (localp)
111         krb5_free_address (context, localp);
112     if (remotep)
113         krb5_free_address (context, remotep);
114     localp = remotep = NULL;
115
116     if (krb5_ret_int16 (sp, &ac->local_port) != 0)
117         goto failure;
118
119     if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
120         goto failure;
121     if (flags & SC_KEYBLOCK) {
122         if (krb5_ret_keyblock (sp, &keyblock) != 0)
123             goto failure;
124         krb5_auth_con_setkey (context, ac, &keyblock);
125         krb5_free_keyblock_contents (context, &keyblock);
126     }
127     if (flags & SC_LOCAL_SUBKEY) {
128         if (krb5_ret_keyblock (sp, &keyblock) != 0)
129             goto failure;
130         krb5_auth_con_setlocalsubkey (context, ac, &keyblock);
131         krb5_free_keyblock_contents (context, &keyblock);
132     }
133     if (flags & SC_REMOTE_SUBKEY) {
134         if (krb5_ret_keyblock (sp, &keyblock) != 0)
135             goto failure;
136         krb5_auth_con_setremotesubkey (context, ac, &keyblock);
137         krb5_free_keyblock_contents (context, &keyblock);
138     }
139     if (krb5_ret_uint32 (sp, &ac->local_seqnumber))
140         goto failure;
141     if (krb5_ret_uint32 (sp, &ac->remote_seqnumber))
142         goto failure;
143
144     if (krb5_ret_int32 (sp, &tmp) != 0)
145         goto failure;
146     ac->keytype = tmp;
147     if (krb5_ret_int32 (sp, &tmp) != 0)
148         goto failure;
149     ac->cksumtype = tmp;
150
151     /* names */
152
153     if (krb5_ret_data (sp, &data))
154         goto failure;
155     buffer.value  = data.data;
156     buffer.length = data.length;
157
158     ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
159                                 &name);
160     if (ret) {
161         ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
162                                     &name);
163         if (ret) {
164             krb5_data_free (&data);
165             goto failure;
166         }
167     }
168     ctx->source = (krb5_principal)name;
169     krb5_data_free (&data);
170
171     if (krb5_ret_data (sp, &data) != 0)
172         goto failure;
173     buffer.value  = data.data;
174     buffer.length = data.length;
175
176     ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
177                                 &name);
178     if (ret) {
179         ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
180                                     &name);
181         if (ret) {
182             krb5_data_free (&data);
183             goto failure;
184         }
185     }
186     ctx->target = (krb5_principal)name;
187     krb5_data_free (&data);
188
189     if (krb5_ret_int32 (sp, &tmp))
190         goto failure;
191     ctx->flags = tmp;
192     if (krb5_ret_int32 (sp, &tmp))
193         goto failure;
194     ctx->more_flags = tmp;
195     if (krb5_ret_int32 (sp, &tmp))
196         goto failure;
197     ctx->lifetime = tmp;
198
199     ret = _gssapi_msg_order_import(minor_status, sp, &ctx->order);
200     if (ret)
201         goto failure;
202
203     krb5_storage_free (sp);
204
205     _gsskrb5i_is_cfx(context, ctx, (ctx->more_flags & LOCAL) == 0);
206
207     *context_handle = (gss_ctx_id_t)ctx;
208
209     return GSS_S_COMPLETE;
210
211 failure:
212     krb5_auth_con_free (context,
213                         ctx->auth_context);
214     if (ctx->source != NULL)
215         krb5_free_principal(context, ctx->source);
216     if (ctx->target != NULL)
217         krb5_free_principal(context, ctx->target);
218     if (localp)
219         krb5_free_address (context, localp);
220     if (remotep)
221         krb5_free_address (context, remotep);
222     if(ctx->order)
223         _gssapi_msg_order_destroy(&ctx->order);
224     HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
225     krb5_storage_free (sp);
226     free (ctx);
227     *context_handle = GSS_C_NO_CONTEXT;
228     return ret;
229 }