Add heimdal-0.6.3
[dragonfly.git] / crypto / heimdal-0.6.3 / lib / gssapi / export_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 "gssapi_locl.h"
35
36 RCSID("$Id: export_sec_context.c,v 1.6 2003/03/16 18:02:52 lha Exp $");
37
38 OM_uint32
39 gss_export_sec_context (
40     OM_uint32 * minor_status,
41     gss_ctx_id_t * context_handle,
42     gss_buffer_t interprocess_token
43     )
44 {
45     krb5_storage *sp;
46     krb5_auth_context ac;
47     OM_uint32 ret = GSS_S_COMPLETE;
48     krb5_data data;
49     gss_buffer_desc buffer;
50     int flags;
51     OM_uint32 minor;
52     krb5_error_code kret;
53
54     GSSAPI_KRB5_INIT ();
55     if (!((*context_handle)->flags & GSS_C_TRANS_FLAG)) {
56         *minor_status = 0;
57         return GSS_S_UNAVAILABLE;
58     }
59
60     sp = krb5_storage_emem ();
61     if (sp == NULL) {
62         *minor_status = ENOMEM;
63         return GSS_S_FAILURE;
64     }
65     ac = (*context_handle)->auth_context;
66
67     /* flagging included fields */
68
69     flags = 0;
70     if (ac->local_address)
71         flags |= SC_LOCAL_ADDRESS;
72     if (ac->remote_address)
73         flags |= SC_REMOTE_ADDRESS;
74     if (ac->keyblock)
75         flags |= SC_KEYBLOCK;
76     if (ac->local_subkey)
77         flags |= SC_LOCAL_SUBKEY;
78     if (ac->remote_subkey)
79         flags |= SC_REMOTE_SUBKEY;
80
81     kret = krb5_store_int32 (sp, flags);
82     if (kret) {
83         *minor_status = kret;
84         goto failure;
85     }
86
87     /* marshall auth context */
88
89     kret = krb5_store_int32 (sp, ac->flags);
90     if (kret) {
91         *minor_status = kret;
92         goto failure;
93     }
94     if (ac->local_address) {
95         kret = krb5_store_address (sp, *ac->local_address);
96         if (kret) {
97             *minor_status = kret;
98             goto failure;
99         }
100     }
101     if (ac->remote_address) {
102         kret = krb5_store_address (sp, *ac->remote_address);
103         if (kret) {
104             *minor_status = kret;
105             goto failure;
106         }
107     }
108     kret = krb5_store_int16 (sp, ac->local_port);
109     if (kret) {
110         *minor_status = kret;
111         goto failure;
112     }
113     kret = krb5_store_int16 (sp, ac->remote_port);
114     if (kret) {
115         *minor_status = kret;
116         goto failure;
117     }
118     if (ac->keyblock) {
119         kret = krb5_store_keyblock (sp, *ac->keyblock);
120         if (kret) {
121             *minor_status = kret;
122             goto failure;
123         }
124     }
125     if (ac->local_subkey) {
126         kret = krb5_store_keyblock (sp, *ac->local_subkey);
127         if (kret) {
128             *minor_status = kret;
129             goto failure;
130         }
131     }
132     if (ac->remote_subkey) {
133         kret = krb5_store_keyblock (sp, *ac->remote_subkey);
134         if (kret) {
135             *minor_status = kret;
136             goto failure;
137         }
138     }
139     kret = krb5_store_int32 (sp, ac->local_seqnumber);
140         if (kret) {
141             *minor_status = kret;
142             goto failure;
143         }
144     kret = krb5_store_int32 (sp, ac->remote_seqnumber);
145         if (kret) {
146             *minor_status = kret;
147             goto failure;
148         }
149
150     kret = krb5_store_int32 (sp, ac->keytype);
151     if (kret) {
152         *minor_status = kret;
153         goto failure;
154     }
155     kret = krb5_store_int32 (sp, ac->cksumtype);
156     if (kret) {
157         *minor_status = kret;
158         goto failure;
159     }
160
161     /* names */
162
163     ret = gss_export_name (minor_status, (*context_handle)->source, &buffer);
164     if (ret)
165         goto failure;
166     data.data   = buffer.value;
167     data.length = buffer.length;
168     kret = krb5_store_data (sp, data);
169     gss_release_buffer (&minor, &buffer);
170     if (kret) {
171         *minor_status = kret;
172         goto failure;
173     }
174
175     ret = gss_export_name (minor_status, (*context_handle)->target, &buffer);
176     if (ret)
177         goto failure;
178     data.data   = buffer.value;
179     data.length = buffer.length;
180
181     ret = GSS_S_FAILURE;
182
183     kret = krb5_store_data (sp, data);
184     gss_release_buffer (&minor, &buffer);
185     if (kret) {
186         *minor_status = kret;
187         goto failure;
188     }
189
190     kret = krb5_store_int32 (sp, (*context_handle)->flags);
191     if (kret) {
192         *minor_status = kret;
193         goto failure;
194     }
195     kret = krb5_store_int32 (sp, (*context_handle)->more_flags);
196     if (kret) {
197         *minor_status = kret;
198         goto failure;
199     }
200     kret = krb5_store_int32 (sp, (*context_handle)->lifetime);
201     if (kret) {
202         *minor_status = kret;
203         goto failure;
204     }
205
206     kret = krb5_storage_to_data (sp, &data);
207     krb5_storage_free (sp);
208     if (kret) {
209         *minor_status = kret;
210         return GSS_S_FAILURE;
211     }
212     interprocess_token->length = data.length;
213     interprocess_token->value  = data.data;
214     ret = gss_delete_sec_context (minor_status, context_handle,
215                                   GSS_C_NO_BUFFER);
216     if (ret != GSS_S_COMPLETE)
217         gss_release_buffer (NULL, interprocess_token);
218     *minor_status = 0;
219     return ret;
220  failure:
221     krb5_storage_free (sp);
222     return ret;
223 }