fc6b6aff28f9aeb95601eb7fbd36f4b4dce10699
[krb5.git] / src / lib / gssapi / krb5 / import_sec_context.c
1 /* -*- mode: c; indent-tabs-mode: nil -*- */
2 /*
3  * lib/gssapi/krb5/import_sec_context.c
4  *
5  * Copyright 1995,2004,2007,2008 by the Massachusetts Institute of Technology.
6  * All Rights Reserved.
7  *
8  * Export of this software from the United States of America may
9  *   require a specific license from the United States Government.
10  *   It is the responsibility of any person or organization contemplating
11  *   export to obtain such a license before exporting.
12  *
13  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
14  * distribute this software and its documentation for any purpose and
15  * without fee is hereby granted, provided that the above copyright
16  * notice appear in all copies and that both that copyright notice and
17  * this permission notice appear in supporting documentation, and that
18  * the name of M.I.T. not be used in advertising or publicity pertaining
19  * to distribution of the software without specific, written prior
20  * permission.  Furthermore if you modify this software you must label
21  * your software as modified software and not distribute it in such a
22  * fashion that it might be confused with the original M.I.T. software.
23  * M.I.T. makes no representations about the suitability of
24  * this software for any purpose.  It is provided "as is" without express
25  * or implied warranty.
26  *
27  */
28
29 /*
30  * import_sec_context.c - Internalize the security context.
31  */
32 #include "gssapiP_krb5.h"
33 /* for serialization initialization functions */
34 #include "k5-int.h"
35
36 /*
37  * Fix up the OID of the mechanism so that uses the static version of
38  * the OID if possible.
39  */
40 gss_OID krb5_gss_convert_static_mech_oid(oid)
41     gss_OID    oid;
42 {
43     const gss_OID_desc      *p;
44     OM_uint32               minor_status;
45
46     for (p = krb5_gss_oid_array; p->length; p++) {
47         if ((oid->length == p->length) &&
48             (memcmp(oid->elements, p->elements, p->length) == 0)) {
49             gss_release_oid(&minor_status, &oid);
50             return (gss_OID) p;
51         }
52     }
53     return oid;
54 }
55
56 krb5_error_code
57 krb5_gss_ser_init (krb5_context context)
58 {
59     krb5_error_code code;
60     static krb5_error_code (KRB5_CALLCONV *const fns[])(krb5_context) = {
61         krb5_ser_context_init, krb5_ser_auth_context_init,
62         krb5_ser_ccache_init, krb5_ser_rcache_init, krb5_ser_keytab_init,
63     };
64     unsigned int i;
65
66     for (i = 0; i < sizeof(fns)/sizeof(fns[0]); i++)
67         if ((code = (fns[i])(context)) != 0)
68             return code;
69     return 0;
70 }
71
72 OM_uint32
73 krb5_gss_import_sec_context(minor_status, interprocess_token, context_handle)
74     OM_uint32           *minor_status;
75     gss_buffer_t        interprocess_token;
76     gss_ctx_id_t        *context_handle;
77 {
78     krb5_context        context;
79     krb5_error_code     kret = 0;
80     size_t              blen;
81     krb5_gss_ctx_id_t   ctx;
82     krb5_octet          *ibp;
83
84     /* This is a bit screwy.  We create a krb5 context because we need
85        one when calling the serialization code.  However, one of the
86        objects we're unpacking is a krb5 context, so when we finish,
87        we can throw this one away.  */
88     kret = krb5_gss_init_context(&context);
89     if (kret) {
90         *minor_status = kret;
91         return GSS_S_FAILURE;
92     }
93     kret = krb5_gss_ser_init(context);
94     if (kret) {
95         *minor_status = kret;
96         save_error_info(*minor_status, context);
97         krb5_free_context(context);
98         return GSS_S_FAILURE;
99     }
100
101     /* Assume a tragic failure */
102     ctx = (krb5_gss_ctx_id_t) NULL;
103     *minor_status = 0;
104
105     /* Internalize the context */
106     ibp = (krb5_octet *) interprocess_token->value;
107     blen = (size_t) interprocess_token->length;
108     kret = kg_ctx_internalize(context, (krb5_pointer *) &ctx, &ibp, &blen);
109     krb5_free_context(context);
110     if (kret) {
111         *minor_status = (OM_uint32) kret;
112         save_error_info(*minor_status, context);
113         return(GSS_S_FAILURE);
114     }
115
116     /* intern the context handle */
117     if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
118         (void)krb5_gss_delete_sec_context(minor_status,
119                                           (gss_ctx_id_t *) &ctx, NULL);
120         *minor_status = (OM_uint32) G_VALIDATE_FAILED;
121         return(GSS_S_FAILURE);
122     }
123     ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
124
125     *context_handle = (gss_ctx_id_t) ctx;
126
127     *minor_status = 0;
128     return (GSS_S_COMPLETE);
129 }