1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*
9  * lib/gssapi/krb5/import_sec_context.c
10  *
11  * Copyright 1995 by the Massachusetts Institute of Technology.
12  * All Rights Reserved.
13  *
14  * Export of this software from the United States of America may
15  *   require a specific license from the United States Government.
16  *   It is the responsibility of any person or organization contemplating
17  *   export to obtain such a license before exporting.
18  *
19  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
20  * distribute this software and its documentation for any purpose and
21  * without fee is hereby granted, provided that the above copyright
22  * notice appear in all copies and that both that copyright notice and
23  * this permission notice appear in supporting documentation, and that
24  * the name of M.I.T. not be used in advertising or publicity pertaining
25  * to distribution of the software without specific, written prior
26  * permission.  Furthermore if you modify this software you must label
27  * your software as modified software and not distribute it in such a
28  * fashion that it might be confused with the original M.I.T. software.
29  * M.I.T. makes no representations about the suitability of
30  * this software for any purpose.  It is provided "as is" without express
31  * or implied warranty.
32  *
33  */
34 
35 /*
36  * import_sec_context.c	- Internalize the security context.
37  */
38 #include <gssapiP_krb5.h>
39 #include <k5-int.h>
40 #include <gssapi/gssapi.h>
41 
42 /*
43  * Fix up the OID of the mechanism so that uses the static version of
44  * the OID if possible.
45  *
46  * Solaris Kerberos: this is not necessary.  Our mech_used is allocated
47  * as part of the context structure.  This function attempts to point to
48  * the corresponding gss_OID in the array krb5_gss_oid_array.
49  */
50 #if 0
51 gss_OID_desc krb5_gss_convert_static_mech_oid(oid)
52      gss_OID	FAR oid;
53 {
54 	const gss_OID_desc 	*p;
55 	OM_uint32		minor_status;
56 
57 	for (p = krb5_gss_oid_array; p->length; p++) {
58 		if ((oid->length == p->length) &&
59 		    (memcmp(oid->elements, p->elements, p->length) == 0)) {
60 			gss_release_oid(&minor_status, &oid);
61 			return *p;
62 		}
63 	}
64 	return *oid;
65 }
66 #endif
67 
68 OM_uint32
69 krb5_gss_import_sec_context(ct, minor_status, interprocess_token, context_handle)
70     void		*ct;
71     OM_uint32		*minor_status;
72     gss_buffer_t	interprocess_token;
73     gss_ctx_id_t	*context_handle;
74 {
75     krb5_context	context;
76     krb5_error_code	kret = 0;
77     size_t		blen;
78     krb5_gss_ctx_id_t	ctx;
79     krb5_octet		*ibp;
80 
81    /* Solaris Kerberos:  we use the global kg_context for MT safe */
82 #if 0
83     if (GSS_ERROR(kg_get_context(minor_status, &context)))
84        return(GSS_S_FAILURE);
85 #endif
86 
87     KRB5_LOG0(KRB5_INFO, "krb5_gss_import_sec_context() start\n");
88 
89     mutex_lock(&krb5_mutex);
90     context = ct;
91 
92     /* Assume a tragic failure */
93     ctx = (krb5_gss_ctx_id_t) NULL;
94     *minor_status = 0;
95 
96     /* Internalize the context */
97     ibp = (krb5_octet *) interprocess_token->value;
98     blen = (size_t) interprocess_token->length;
99     if ((kret = kg_ctx_internalize(context,
100 				   (krb5_pointer *) &ctx,
101 				   &ibp, &blen))) {
102        *minor_status = (OM_uint32) kret;
103        mutex_unlock(&krb5_mutex);
104 
105        KRB5_LOG(KRB5_ERR, "krb5_gss_import_sec_context() end,"
106 		"kg_ctx_internalize() error kret = %d\n", kret);
107 
108        if (kret == ENOMEM)
109            return(GSS_S_FAILURE);
110        else
111            return(GSS_S_DEFECTIVE_TOKEN);
112     }
113 
114     /* intern the context handle */
115     if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
116        (void)krb5_gss_delete_sec_context_no_lock(context, minor_status,
117 					 (gss_ctx_id_t *) &ctx, NULL
118 #ifdef _KERNEL
119 					,0  /* gssd_ctx_verifier */
120 #endif
121 					);
122        *minor_status = (OM_uint32) G_VALIDATE_FAILED;
123        mutex_unlock(&krb5_mutex);
124 
125        KRB5_LOG0(KRB5_ERR, "krb5_gss_import_sec_context() end,"
126 		"kg_save_ctx_id() error\n");
127 
128        return(GSS_S_FAILURE);
129     }
130     if (! kg_validate_ctx_id((gss_ctx_id_t) ctx)) {
131        *minor_status = (OM_uint32) G_VALIDATE_FAILED;
132         mutex_unlock(&krb5_mutex);
133 
134 	KRB5_LOG0(KRB5_ERR, "krb5_gss_import_sec_context() end,"
135 		"kg_validate_ctx_id() error\n");
136 
137         return(GSS_S_FAILURE);
138     }
139 
140     /* Solaris Kerberos:  our mech_used is part of the ctx structure */
141     /* ctx->mech_used = krb5_gss_convert_static_mech_oid(&(ctx->mech_used)); */
142 
143     *context_handle = (gss_ctx_id_t) ctx;
144 
145     *minor_status = 0;
146     mutex_unlock(&krb5_mutex);
147 
148     KRB5_LOG0(KRB5_INFO, "krb5_gss_import_sec_context() end\n");
149 
150     return (GSS_S_COMPLETE);
151 }
152