2424*/
2525
2626#include "gss_plugin.h"
27+ #include <gssapi/gssapi_krb5.h>
2728
2829static OM_uint32 get_local_def_creds (OM_uint32 * minor_status ,
2930 struct gpp_name_handle * name ,
@@ -264,6 +265,91 @@ OM_uint32 gssi_inquire_cred_by_oid(OM_uint32 *minor_status,
264265 return maj ;
265266}
266267
268+ #define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID_LENGTH 11
269+ #define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x04"
270+
271+ const gss_OID_desc gpp_allowed_enctypes_oid = {
272+ .length = GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID_LENGTH ,
273+ .elements = GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID
274+ };
275+
276+ struct gpp_allowable_enctypes {
277+ uint32_t num_ktypes ;
278+ krb5_enctype * ktypes ;
279+ };
280+
281+ #define KRB5_SET_ALLOWED_ENCTYPE "krb5_set_allowed_enctype_values"
282+
283+ static uint32_t gpp_set_opt_allowable_entypes (uint32_t * min , gssx_cred * cred ,
284+ const gss_buffer_t value )
285+ {
286+ struct gpp_allowable_enctypes * ae ;
287+ struct gssx_cred_element * ce = NULL ;
288+ gss_OID_desc mech ;
289+ gssx_option * to ;
290+ gssx_buffer * tb ;
291+ int i ;
292+
293+ /* Find the first element that matches one of the krb related OIDs */
294+ for (i = 0 ; i < cred -> elements .elements_len ; i ++ ) {
295+ gp_conv_gssx_to_oid (& cred -> elements .elements_val [i ].mech , & mech );
296+ if (gpp_is_krb5_oid (& mech )) {
297+ ce = & cred -> elements .elements_val [i ];
298+ break ;
299+ }
300+ }
301+
302+ if (!ce ) {
303+ * min = EINVAL ;
304+ return GSS_S_FAILURE ;
305+ }
306+
307+ to = realloc (ce -> options .options_val ,
308+ sizeof (gssx_option ) * (ce -> options .options_len + 1 ));
309+ if (!to ) {
310+ * min = ENOMEM ;
311+ return GSS_S_FAILURE ;
312+ }
313+ ce -> options .options_val = to ;
314+ i = ce -> options .options_len ;
315+
316+ tb = & ce -> options .options_val [i ].option ;
317+ tb -> octet_string_len = sizeof (KRB5_SET_ALLOWED_ENCTYPE );
318+ tb -> octet_string_val = strdup (KRB5_SET_ALLOWED_ENCTYPE );
319+ if (!tb -> octet_string_val ) {
320+ * min = ENOMEM ;
321+ return GSS_S_FAILURE ;
322+ }
323+
324+ ae = (struct gpp_allowable_enctypes * )value -> value ;
325+ tb = & ce -> options .options_val [i ].value ;
326+ tb -> octet_string_len = sizeof (krb5_enctype ) * ae -> num_ktypes ;
327+ tb -> octet_string_val = malloc (tb -> octet_string_len );
328+ if (!tb -> octet_string_val ) {
329+ * min = ENOMEM ;
330+ return GSS_S_FAILURE ;
331+ }
332+ memcpy (tb -> octet_string_val , ae -> ktypes , tb -> octet_string_len );
333+
334+ ce -> options .options_len ++ ;
335+
336+ * min = 0 ;
337+ return GSS_S_COMPLETE ;
338+ }
339+
340+ static uint32_t gpp_remote_options (uint32_t * min , gssx_cred * cred ,
341+ const gss_OID desired_object ,
342+ const gss_buffer_t value )
343+ {
344+ uint32_t maj = GSS_S_UNAVAILABLE ;
345+
346+ if (gss_oid_equal (& gpp_allowed_enctypes_oid , desired_object )) {
347+ maj = gpp_set_opt_allowable_entypes (min , cred , value );
348+ }
349+
350+ return maj ;
351+ }
352+
267353OM_uint32 gssi_set_cred_option (OM_uint32 * minor_status ,
268354 gss_cred_id_t * cred_handle ,
269355 const gss_OID desired_object ,
@@ -280,7 +366,12 @@ OM_uint32 gssi_set_cred_option(OM_uint32 *minor_status,
280366 }
281367 cred = (struct gpp_cred_handle * )* cred_handle ;
282368
283- /* NOTE: For now we can do this only for local credentials */
369+ /* NOTE: For now we can do this only for known objects
370+ * or local credentials */
371+ if (cred -> remote ) {
372+ return gpp_remote_options (minor_status , cred -> remote ,
373+ desired_object , value );
374+ }
284375 if (!cred -> local ) {
285376 return GSS_S_UNAVAILABLE ;
286377 }
0 commit comments