4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
25 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
30 #pragma ident "%Z%%M% %I% %E% SMI"
34 #include "dh_gssapi.h"
37 * This module supports the GSS credential family of routines for
38 * Diffie-Hellman mechanism.
42 * __dh_gss_acquire_cred: Get the credential associated with principal
43 * with the requested expire time and usage. Return the credential with
44 * the optional set of supported mechs and actual time left on the credential.
46 * Note in Diffie-Hellman the supplied principal name must be that of
47 * the caller. There is no way to delegate credentials.
49 * Libgss alwas sets desired_mechs to GSS_C_NO_OID_SET and set the return
50 * set of mechs to NULL.
54 __dh_gss_acquire_cred(void *ctx
, /* Per mechanism context */
55 OM_uint32
*minor
, /* Mechanism status */
56 gss_name_t principal
, /* Requested principal */
57 OM_uint32 expire_req
, /* Requested Expire time */
58 gss_OID_set desired_mechs
, /* Set of desired mechs */
59 gss_cred_usage_t usage
, /* Usage: init, accept, both */
60 gss_cred_id_t
*cred
, /* The return credential */
61 gss_OID_set
*mechs
, /* The return set of mechs */
62 OM_uint32
*expire_rec
/* The expire time received*/)
64 /* Diffie-Hellman mechanism context is ctx */
65 dh_context_t cntx
= (dh_context_t
)ctx
;
69 /* Need to write to these */
70 if (minor
== 0 || cred
== 0)
71 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
73 /* Set sane outputs */
76 *mechs
= GSS_C_NO_OID_SET
;
79 *cred
= GSS_C_NO_CREDENTIAL
;
82 * If not GSS_C_NO_OID_SET then the set must contain the
83 * Diffie-Hellman mechanism
85 if (desired_mechs
!= GSS_C_NO_OID_SET
&&
86 !__OID_is_member(desired_mechs
, cntx
->mech
))
87 return (GSS_S_BAD_MECH
);
89 /* See if the callers secretkey is available */
90 if (!cntx
->keyopts
->key_secretkey_is_set())
91 return (GSS_S_NO_CRED
);
93 /* Get the principal name of the caller */
94 if ((netname
= cntx
->keyopts
->get_principal()) == NULL
)
95 return (GSS_S_NO_CRED
);
98 * Diffie-Hellman requires the principal to be the principal
103 strncmp(netname
, (char *)principal
, MAXNETNAMELEN
) != 0) {
105 return (GSS_S_NO_CRED
);
108 /* Allocate the credential */
109 dh_cred
= New(dh_cred_id_desc
, 1);
110 if (dh_cred
== NULL
) {
112 *minor
= DH_NOMEM_FAILURE
;
113 return (GSS_S_FAILURE
);
116 /* Set credential state */
117 dh_cred
->uid
= geteuid();
118 dh_cred
->usage
= usage
;
119 dh_cred
->principal
= netname
;
120 dh_cred
->expire
= expire_req
? time(0) + expire_req
: GSS_C_INDEFINITE
;
123 * If mechs set it to the set that contains the appropriate
124 * Diffie-Hellman mechanism
126 if (mechs
&& (*minor
= __OID_to_OID_set(mechs
, cntx
->mech
))) {
129 return (GSS_S_FAILURE
);
132 /* Register the credential */
133 if ((*minor
= __dh_install_cred(dh_cred
)) != DH_SUCCESS
) {
136 return (GSS_S_FAILURE
);
140 *expire_rec
= expire_req
? expire_req
: GSS_C_INDEFINITE
;
142 /* Return the Diffie-Hellman credential through cred */
143 *cred
= (gss_cred_id_t
)dh_cred
;
145 return (GSS_S_COMPLETE
);
150 * __dh_gss_add_cred is currently a no-op. All the work is done at the
151 * libgss layer. That layer will invoke the mechanism specific gss_acquire_cred
152 * routine. This entry point should never be called. The entry point for
153 * this routine is set to NULL in dhmech.c.
158 * __dh_gss_add_cred(void * ctx, OM_uint32 *minor, gss_cred_id_t cred_in,
159 * gss_name_t name, gss_OID mech, gss_cred_usage_t usage,
160 * OM_uint32 init_time_req, OM_uint32 accep_time_req,
161 * gss_cred_id_t *cred_out, gss_OID_set *mechs,
162 * OM_uint32 *init_time_rec, OM_uint32 *accep_time_rec)
164 * return (GSS_S_UNAVAILABLE);
169 * __dh_gss_inquire_cred: Return tracked state of the supplied credential.
172 __dh_gss_inquire_cred(void *ctx
, /* Per mechanism context */
173 OM_uint32
*minor
, /* Mechanism status */
174 gss_cred_id_t cred
, /* cred of interest */
175 gss_name_t
*name
, /* name of principal */
176 OM_uint32
*lifetime
, /* return the time remainning */
177 gss_cred_usage_t
*usage
, /* usage: init, accept, both */
178 gss_OID_set
*mechs
/* Set containing mech_dh */)
180 /* cred is a Diffie-Hellman credential */
181 dh_cred_id_t crid
= (dh_cred_id_t
)cred
;
182 /* ctx is a Diffie-Hellman context */
183 dh_context_t cntx
= (dh_context_t
)ctx
;
184 OM_uint32 t
= GSS_C_INDEFINITE
;
187 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
189 return (GSS_S_CALL_INACCESSIBLE_READ
);
194 if (cred
== GSS_C_NO_CREDENTIAL
) {
195 if (!(*cntx
->keyopts
->key_secretkey_is_set
)())
196 return (GSS_S_NO_CRED
);
198 *name
= (gss_name_t
)(*cntx
->keyopts
->get_principal
)();
200 *lifetime
= GSS_C_INDEFINITE
;
204 /* Validate creditial */
205 if ((*minor
= __dh_validate_cred(crid
)) != DH_SUCCESS
)
206 return (GSS_S_DEFECTIVE_CREDENTIAL
);
208 *name
= (gss_name_t
)strdup(crid
->principal
);
210 if (crid
->expire
== GSS_C_INDEFINITE
)
211 *lifetime
= GSS_C_INDEFINITE
;
213 time_t now
= time(0);
214 t
= crid
->expire
> now
? crid
->expire
-now
: 0;
219 *usage
= crid
->usage
;
222 if (name
&& *name
== 0)
223 return (GSS_S_FAILURE
);
227 (*minor
= __OID_to_OID_set(mechs
, cntx
->mech
)) != DH_SUCCESS
) {
229 return (GSS_S_FAILURE
);
232 /* Check if the credential is still valid */
233 return (t
? GSS_S_COMPLETE
: GSS_S_CREDENTIALS_EXPIRED
);
238 * __dh_gss_inquire_cred_by_mech: Return the information associated with
239 * cred and mech. Since we're a backend, mech must be our mech.
241 * We verify that passed in mech is correct and use the above routine
245 __dh_gss_inquire_cred_by_mech(void *ctx
, /* Per mechananism context */
246 OM_uint32
*minor
, /* Mechanism status */
247 gss_cred_id_t cred
, /* Cred to iquire about */
248 gss_OID mech
, /* Along with the mechanism */
249 gss_name_t
*name
, /* where to return principal */
250 OM_uint32
*init_time
, /* Init time left */
251 OM_uint32
*accept_time
, /* Accept time left */
252 gss_cred_usage_t
*usage
/* cred usage */)
254 /* ctx is them Diffie-Hellman mechanism context */
255 dh_context_t context
= (dh_context_t
)ctx
;
258 gss_cred_usage_t use
;
260 /* This should never happen. It would indicate a libgss failure */
261 if (!__OID_equal(mech
, context
->mech
)) {
262 *minor
= DH_BAD_CONTEXT
;
263 return (GSS_S_FAILURE
);
266 /* Fetch cred info */
267 major
= __dh_gss_inquire_cred(ctx
, minor
, cred
, name
,
268 &lifetime
, &use
, NULL
);
270 /* Return option values */
271 if (major
== GSS_S_COMPLETE
) {
272 /* set init_time if we can */
274 *init_time
= (use
== GSS_C_BOTH
||
275 use
== GSS_C_INITIATE
) ? lifetime
: 0;
276 /* Ditto for accept time */
278 *accept_time
= (use
== GSS_C_BOTH
||
279 use
== GSS_C_ACCEPT
) ? lifetime
: 0;
288 * __dh_gss_release_cred: Release the resources associated with cred.
291 __dh_gss_release_cred(void *ctx
, /* Per mechananism context (not used) */
292 OM_uint32
*minor
, /* Mechanism status */
293 gss_cred_id_t
*cred
/* The cred to free */)
295 _NOTE(ARGUNUSED(ctx
))
296 dh_cred_id_t dh_cred
= (dh_cred_id_t
)*cred
;
298 /* Check that we can read and write required parameters */
299 if (minor
== 0 || cred
== 0)
300 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
303 if (*cred
== GSS_C_NO_CREDENTIAL
)
304 return (GSS_S_COMPLETE
);
306 /* Check if the credential is valid */
307 if ((*minor
= __dh_validate_cred(dh_cred
)) != DH_SUCCESS
)
308 return (GSS_S_NO_CRED
);
310 /* Unregister the credential */
311 *minor
= __dh_remove_cred(dh_cred
);
313 /* Free the principal and the cred itself */
314 Free(dh_cred
->principal
);
317 /* Set cred to no credential */
318 *cred
= GSS_C_NO_CREDENTIAL
;
320 return (GSS_S_COMPLETE
);