1 /*
2  * Copyright 2001-2003 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 #include <sys/debug.h>
43 /*
44  * Fix up the OID of the mechanism so that uses the static version of
45  * the OID if possible.
46  *
47  * Solaris Kerberos: this is not necessary.  Our mech_used is allocated
48  * as part of the context structure.  This function attempts to point to
49  * the corresponding gss_OID in the array krb5_gss_oid_array.
50  */
51 #if 0
52 gss_OID_desc krb5_gss_convert_static_mech_oid(oid)
53      gss_OID	FAR oid;
54 {
55 	const gss_OID_desc 	*p;
56 	OM_uint32		minor_status;
57 
58 	for (p = krb5_gss_oid_array; p->length; p++) {
59 		if ((oid->length == p->length) &&
60 		    (memcmp(oid->elements, p->elements, p->length) == 0)) {
61 			gss_release_oid(&minor_status, &oid);
62 			return *p;
63 		}
64 	}
65 	return *oid;
66 }
67 #endif
68 
69 OM_uint32
70 krb5_gss_import_sec_context(ct, minor_status, interprocess_token, context_handle)
71     void		*ct;
72     OM_uint32		*minor_status;
73     gss_buffer_t	interprocess_token;
74     gss_ctx_id_t	*context_handle;
75 {
76     krb5_context	context;
77     krb5_error_code	kret = 0;
78     size_t		blen;
79     krb5_gss_ctx_id_t	ctx;
80     krb5_octet		*ibp;
81 
82    /* Solaris Kerberos:  we use the global kg_context for MT safe */
83 #if 0
84     if (GSS_ERROR(kg_get_context(minor_status, &context)))
85        return(GSS_S_FAILURE);
86 #endif
87 
88     KRB5_LOG0(KRB5_INFO, "krb5_gss_import_sec_context() start\n");
89 
90     mutex_lock(&krb5_mutex);
91     context = ct;
92 
93     /* Assume a tragic failure */
94     ctx = (krb5_gss_ctx_id_t) NULL;
95     *minor_status = 0;
96 
97     /* Internalize the context */
98     ibp = (krb5_octet *) interprocess_token->value;
99     blen = (size_t) interprocess_token->length;
100     if ((kret = kg_ctx_internalize(context,
101 				   (krb5_pointer *) &ctx,
102 				   &ibp, &blen))) {
103        *minor_status = (OM_uint32) kret;
104        mutex_unlock(&krb5_mutex);
105 
106        KRB5_LOG(KRB5_ERR, "krb5_gss_import_sec_context() end,"
107 		"kg_ctx_internalize() error kret = %d\n", kret);
108 
109        if (kret == ENOMEM)
110            return(GSS_S_FAILURE);
111        else
112            return(GSS_S_DEFECTIVE_TOKEN);
113     }
114 
115     /* intern the context handle */
116     if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
117        (void)krb5_gss_delete_sec_context_no_lock(context, minor_status,
118 					 (gss_ctx_id_t *) &ctx, NULL
119 #ifdef _KERNEL
120 					,0  /* gssd_ctx_verifier */
121 #endif
122 					);
123        *minor_status = (OM_uint32) G_VALIDATE_FAILED;
124        mutex_unlock(&krb5_mutex);
125 
126        KRB5_LOG0(KRB5_ERR, "krb5_gss_import_sec_context() end,"
127 		"kg_save_ctx_id() error\n");
128 
129        return(GSS_S_FAILURE);
130     }
131     if (! kg_validate_ctx_id((gss_ctx_id_t) ctx)) {
132        *minor_status = (OM_uint32) G_VALIDATE_FAILED;
133         mutex_unlock(&krb5_mutex);
134 
135 	KRB5_LOG0(KRB5_ERR, "krb5_gss_import_sec_context() end,"
136 		"kg_validate_ctx_id() error\n");
137 
138         return(GSS_S_FAILURE);
139     }
140 
141     /* Solaris Kerberos:  our mech_used is part of the ctx structure */
142     /* ctx->mech_used = krb5_gss_convert_static_mech_oid(&(ctx->mech_used)); */
143 
144     *context_handle = (gss_ctx_id_t) ctx;
145 
146     *minor_status = 0;
147     mutex_unlock(&krb5_mutex);
148 
149     KRB5_LOG0(KRB5_INFO, "krb5_gss_import_sec_context() end\n");
150 
151     return (GSS_S_COMPLETE);
152 }
153