[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
GSS extension implementation for Heimdal
Hello all,
I've implemented part (hope the most important) of the GSS-API Extension
draft issued by the Global Grid Forum (take a look at
http://www.gridforum.org/2_SEC/GSI.htm --> GSS-API Extensions). The
implementation can be found in attachament (it's based om Heimdal 0.4e).
The implementation contains functions addressing credential handling
(gss_export_cred(), gss_import_cred()) and delegation on demand
(gss_init_delegation() and gss_accept_delegation()). Usage of these functions
can be found in testing examples, which are part of the patch. The patch also
contains some bugfixes for Heimdal implementation of GSS-API.
regards
--
Dan
Index: heimdal/appl/test/gssapi_client.c
diff -u heimdal/appl/test/gssapi_client.c:1.1.1.1 heimdal/appl/test/gssapi_client.c:1.1.1.1.4.1
--- heimdal/appl/test/gssapi_client.c:1.1.1.1 Tue Feb 26 15:42:03 2002
+++ heimdal/appl/test/gssapi_client.c Fri Aug 16 12:45:41 2002
@@ -40,9 +40,34 @@
do_trans (int sock, gss_ctx_id_t context_hdl)
{
OM_uint32 maj_stat, min_stat;
- gss_buffer_desc real_input_token, real_output_token;
+ gss_buffer_desc real_input_token = GSS_C_EMPTY_BUFFER, real_output_token;
gss_buffer_t input_token = &real_input_token,
- output_token = &real_output_token;
+ output_token = &real_output_token;
+ int delegation_done = 0;
+
+ /* First try delegating credentials */
+ while (!delegation_done) {
+ maj_stat = gss_init_delegation(&min_stat,
+ context_hdl,
+ GSS_C_NO_CREDENTIAL,
+ GSS_C_NO_OID,
+ GSS_C_NO_OID_SET,
+ NULL,
+ input_token,
+ 0,
+ output_token);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_init_sec_context()");
+ if (output_token->length != 0) {
+ write_token (sock, output_token);
+ gss_release_buffer(&min_stat, output_token);
+ }
+
+ if (maj_stat & GSS_S_CONTINUE_NEEDED)
+ read_token (sock, input_token);
+ else
+ delegation_done = 1;
+ }
/* get_mic */
Index: heimdal/appl/test/gssapi_server.c
diff -u heimdal/appl/test/gssapi_server.c:1.1.1.1 heimdal/appl/test/gssapi_server.c:1.1.1.1.4.1
--- heimdal/appl/test/gssapi_server.c:1.1.1.1 Tue Feb 26 15:42:03 2002
+++ heimdal/appl/test/gssapi_server.c Fri Aug 16 12:45:41 2002
@@ -46,7 +46,11 @@
gss_buffer_desc name_token;
gss_buffer_desc real_input_token, real_output_token;
gss_buffer_t input_token = &real_input_token,
- output_token = &real_output_token;
+ output_token = &real_output_token;
+ gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+
+
+
maj_stat = gss_display_name (&min_stat,
client_name,
@@ -59,6 +63,48 @@
(char *)name_token.value);
gss_release_buffer (&min_stat, &name_token);
+
+ do {
+ read_token (sock, input_token);
+ maj_stat = gss_accept_delegation(&min_stat,
+ context_hdl,
+ GSS_C_NO_OID_SET,
+ NULL,
+ input_token,
+ 0,
+ 0,
+ &delegated_cred_handle,
+ NULL,
+ output_token);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_accept_delegation()");
+ if (output_token->length != 0) {
+ write_token (sock, output_token);
+ gss_release_buffer(&min_stat, output_token);
+ }
+ } while(maj_stat & GSS_S_CONTINUE_NEEDED);
+
+ {
+ gss_buffer_desc export_cred = GSS_C_EMPTY_BUFFER;
+ gss_cred_id_t creds;
+
+ maj_stat = gss_export_cred(&min_stat, delegated_cred_handle,
+ GSS_C_NO_OID, 0, &export_cred);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_export_cred()");
+
+ maj_stat = gss_import_cred(&min_stat, &creds, GSS_C_NO_OID, 0,
+ &export_cred, 0, NULL);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_import_creds()");
+
+ memset(&export_cred, 0, sizeof(export_cred));
+ maj_stat = gss_export_cred(&min_stat, creds, GSS_C_NO_OID,
+ 1, &export_cred);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_export_cred()");
+ }
+
/* gss_verify_mic */
@@ -113,8 +159,10 @@
OM_uint32 maj_stat, min_stat;
gss_name_t client_name;
struct gss_channel_bindings_struct input_chan_bindings;
+ /*
gss_cred_id_t delegated_cred_handle = NULL;
krb5_ccache ccache;
+ */
u_char init_buf[4];
u_char acct_buf[4];
@@ -156,8 +204,10 @@
input_chan_bindings.application_data.value = NULL;
#endif
+ /*
delegated_cred_handle = emalloc(sizeof(*delegated_cred_handle));
memset((char*)delegated_cred_handle, 0, sizeof(*delegated_cred_handle));
+ */
do {
read_token (sock, input_token);
@@ -186,6 +236,7 @@
}
} while(maj_stat & GSS_S_CONTINUE_NEEDED);
+#if 0
if (delegated_cred_handle->ccache) {
krb5_context context;
@@ -196,6 +247,7 @@
krb5_cc_close(context, ccache);
krb5_cc_destroy(context, delegated_cred_handle->ccache);
}
+#endif
if (fork_flag) {
pid_t pid;
Index: heimdal/lib/gssapi/Makefile.am
diff -u heimdal/lib/gssapi/Makefile.am:1.1.1.1 heimdal/lib/gssapi/Makefile.am:1.1.1.1.2.2
--- heimdal/lib/gssapi/Makefile.am:1.1.1.1 Tue Feb 26 15:42:04 2002
+++ heimdal/lib/gssapi/Makefile.am Mon Aug 12 14:20:29 2002
@@ -12,6 +12,7 @@
libgssapi_la_SOURCES = \
8003.c \
+ accept_delegation.c \
accept_sec_context.c \
acquire_cred.c \
add_oid_set_member.c \
@@ -26,19 +27,23 @@
display_status.c \
duplicate_name.c \
encapsulate.c \
+ export_cred.c \
export_sec_context.c \
export_name.c \
external.c \
get_mic.c \
gssapi.h \
gssapi_locl.h \
+ import_cred.c \
import_name.c \
import_sec_context.c \
indicate_mechs.c \
init.c \
+ init_delegation.c \
init_sec_context.c \
inquire_context.c \
inquire_cred.c \
+ padding.c \
release_buffer.c \
release_cred.c \
release_name.c \
Index: heimdal/lib/gssapi/Makefile.in
diff -u heimdal/lib/gssapi/Makefile.in:1.1.1.1 heimdal/lib/gssapi/Makefile.in:1.1.1.1.2.3
--- heimdal/lib/gssapi/Makefile.in:1.1.1.1 Tue Feb 26 15:42:04 2002
+++ heimdal/lib/gssapi/Makefile.in Mon Aug 12 14:20:29 2002
@@ -207,6 +207,7 @@
libgssapi_la_SOURCES = \
8003.c \
+ accept_delegation.c \
accept_sec_context.c \
acquire_cred.c \
add_oid_set_member.c \
@@ -221,19 +222,23 @@
display_status.c \
duplicate_name.c \
encapsulate.c \
+ export_cred.c \
export_sec_context.c \
export_name.c \
external.c \
get_mic.c \
gssapi.h \
gssapi_locl.h \
+ import_cred.c \
import_name.c \
import_sec_context.c \
indicate_mechs.c \
init.c \
+ init_delegation.c \
init_sec_context.c \
inquire_context.c \
inquire_cred.c \
+ padding.c \
release_buffer.c \
release_cred.c \
release_name.c \
@@ -261,16 +266,17 @@
X_PRE_LIBS = @X_PRE_LIBS@
libgssapi_la_DEPENDENCIES = ../krb5/libkrb5.la ../asn1/libasn1.la \
../roken/libroken.la
-am_libgssapi_la_OBJECTS = 8003.lo accept_sec_context.lo acquire_cred.lo \
-add_oid_set_member.lo canonicalize_name.lo compare_name.lo \
-context_time.lo copy_ccache.lo create_emtpy_oid_set.lo decapsulate.lo \
-delete_sec_context.lo display_name.lo display_status.lo \
-duplicate_name.lo encapsulate.lo export_sec_context.lo export_name.lo \
-external.lo get_mic.lo import_name.lo import_sec_context.lo \
-indicate_mechs.lo init.lo init_sec_context.lo inquire_context.lo \
-inquire_cred.lo release_buffer.lo release_cred.lo release_name.lo \
-release_oid_set.lo test_oid_set_member.lo unwrap.lo v1.lo verify_mic.lo \
-wrap.lo address_to_krb5addr.lo
+am_libgssapi_la_OBJECTS = 8003.lo accept_delegation.lo \
+accept_sec_context.lo acquire_cred.lo add_oid_set_member.lo \
+canonicalize_name.lo compare_name.lo context_time.lo copy_ccache.lo \
+create_emtpy_oid_set.lo decapsulate.lo delete_sec_context.lo \
+display_name.lo display_status.lo duplicate_name.lo encapsulate.lo \
+export_cred.lo export_sec_context.lo export_name.lo external.lo \
+get_mic.lo import_cred.lo import_name.lo import_sec_context.lo \
+indicate_mechs.lo init.lo init_delegation.lo init_sec_context.lo \
+inquire_context.lo inquire_cred.lo padding.lo release_buffer.lo \
+release_cred.lo release_name.lo release_oid_set.lo test_oid_set_member.lo \
+unwrap.lo v1.lo verify_mic.lo wrap.lo address_to_krb5addr.lo
libgssapi_la_OBJECTS = $(am_libgssapi_la_OBJECTS)
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
Index: heimdal/lib/gssapi/accept_delegation.c
diff -u /dev/null heimdal/lib/gssapi/accept_delegation.c:1.1.2.1
--- /dev/null Sun Aug 18 17:18:27 2002
+++ heimdal/lib/gssapi/accept_delegation.c Mon Aug 12 13:11:31 2002
@@ -0,0 +1,51 @@
+#include "gssapi_locl.h"
+
+RCSID("$Id$");
+
+OM_uint32
+gss_accept_delegation(
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID_set extension_oids,
+ const gss_buffer_set_t extension_buffers,
+ const gss_buffer_t input_token,
+ OM_uint32 time_req,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle,
+ gss_OID * mech_type,
+ gss_buffer_t output_token)
+{
+ OM_uint32 ret;
+ krb5_data fwd_data;
+
+ krb5_data_zero(&fwd_data);
+
+ gssapi_krb5_init ();
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_FAILURE;
+
+ if (input_token == GSS_C_NO_BUFFER || input_token->length <= 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ if (delegated_cred_handle == NULL)
+ return GSS_S_FAILURE;
+
+ ret = gssapi_krb5_decapsulate(minor_status, input_token, &fwd_data,
+ "\x05\x01");
+ if (ret)
+ return ret;
+
+ if (fwd_data.length <= 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ ret = gssapi_krb5_rd_delegation(minor_status,
+ gssapi_krb5_context,
+ context_handle->auth_context,
+ &fwd_data,
+ delegated_cred_handle);
+ krb5_data_free(&fwd_data);
+
+ return ret;
+}
Index: heimdal/lib/gssapi/accept_sec_context.c
diff -u heimdal/lib/gssapi/accept_sec_context.c:1.1.1.1 heimdal/lib/gssapi/accept_sec_context.c:1.1.1.1.2.1
--- heimdal/lib/gssapi/accept_sec_context.c:1.1.1.1 Tue Feb 26 15:42:04 2002
+++ heimdal/lib/gssapi/accept_sec_context.c Mon Aug 12 13:11:31 2002
@@ -62,6 +62,84 @@
}
OM_uint32
+gssapi_krb5_rd_delegation(OM_uint32 *minor_status,
+ krb5_context context,
+ krb5_auth_context ac,
+ krb5_data *fwd_creds,
+ gss_cred_id_t *delegated_cred_handle)
+{
+ krb5_error_code kret;
+ krb5_creds **creds = NULL;
+ gss_cred_id_t cred_handle = NULL;
+ OM_uint32 ret;
+ OM_uint32 minor_status2;
+
+ kret = krb5_rd_cred(context, ac, fwd_creds, &creds, NULL);
+ if (kret)
+ goto krb5_bad;
+
+ cred_handle = malloc(sizeof(*cred_handle));
+ if (cred_handle == NULL) {
+ kret = ENOMEM;
+ goto krb5_bad;
+ }
+ memset(cred_handle, 0, sizeof(*cred_handle));
+
+ ret = gss_duplicate_name(minor_status, (*creds)->client,
+ &cred_handle->principal);
+ if (kret)
+ goto gssapi_bad;
+
+ cred_handle->keytab = NULL;
+ cred_handle->lifetime = (*creds)->times.endtime;
+ cred_handle->usage = GSS_C_BOTH;
+
+ ret = gss_create_empty_oid_set(minor_status, &cred_handle->mechanisms);
+ if (ret)
+ goto gssapi_bad;
+
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &cred_handle->mechanisms);
+ if (ret)
+ goto gssapi_bad;
+
+ kret = krb5_cc_gen_new(context, &krb5_mcc_ops, &cred_handle->ccache);
+ if (kret)
+ goto krb5_bad;
+
+ kret = krb5_cc_initialize(context, cred_handle->ccache, (*creds)->client);
+ if (kret)
+ goto krb5_bad;
+
+ kret = krb5_cc_store_cred(context, cred_handle->ccache, *creds);
+ if (kret)
+ goto krb5_bad;
+
+ if (*delegated_cred_handle != GSS_C_NO_CREDENTIAL)
+ gss_release_cred(&minor_status2, delegated_cred_handle);
+
+ *delegated_cred_handle = cred_handle;
+ cred_handle = NULL;
+
+ krb5_free_creds(context, *creds);
+
+ return GSS_S_COMPLETE;
+
+krb5_bad:
+ *minor_status = kret;
+ gssapi_krb5_set_error_string();
+ ret = GSS_S_FAILURE;
+
+gssapi_bad:
+ if (creds)
+ krb5_free_creds(context, *creds);
+ if (cred_handle)
+ gss_release_cred(&minor_status2, &cred_handle);
+
+ return ret;
+}
+
+OM_uint32
gss_accept_sec_context
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
@@ -284,76 +362,18 @@
goto failure;
}
- if (fwd_data.length > 0 && (flags & GSS_C_DELEG_FLAG)) {
-
- krb5_ccache ccache;
-
- if (delegated_cred_handle == NULL)
- /* XXX Create a new delegated_cred_handle? */
- kret = krb5_cc_default (gssapi_krb5_context, &ccache);
- else if (*delegated_cred_handle == NULL) {
- if ((*delegated_cred_handle =
- calloc(1, sizeof(**delegated_cred_handle))) == NULL) {
- ret = GSS_S_FAILURE;
- *minor_status = ENOMEM;
- krb5_set_error_string(gssapi_krb5_context, "out of memory");
- gssapi_krb5_set_error_string();
- goto failure;
- }
- if ((ret = gss_duplicate_name(minor_status, ticket->client,
- &(*delegated_cred_handle)->principal)) != 0) {
- flags &= ~GSS_C_DELEG_FLAG;
- free(*delegated_cred_handle);
- *delegated_cred_handle = NULL;
- goto end_fwd;
- }
- }
- if (delegated_cred_handle != NULL &&
- (*delegated_cred_handle)->ccache == NULL) {
- kret = krb5_cc_gen_new (gssapi_krb5_context,
- &krb5_mcc_ops,
- &(*delegated_cred_handle)->ccache);
- ccache = (*delegated_cred_handle)->ccache;
- }
- if (delegated_cred_handle != NULL &&
- (*delegated_cred_handle)->mechanisms == NULL) {
- ret = gss_create_empty_oid_set(minor_status,
- &(*delegated_cred_handle)->mechanisms);
- if (ret)
- goto failure;
- ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- &(*delegated_cred_handle)->mechanisms);
- if (ret)
- goto failure;
- }
-
- if (kret) {
- flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
-
- kret = krb5_cc_initialize(gssapi_krb5_context,
- ccache,
- *src_name);
- if (kret) {
- flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
-
- kret = krb5_rd_cred2(gssapi_krb5_context,
- (*context_handle)->auth_context,
- ccache,
- &fwd_data);
- if (kret) {
- flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
+ if (delegated_cred_handle != NULL &&
+ fwd_data.length > 0 && (flags & GSS_C_DELEG_FLAG)) {
-end_fwd:
- free(fwd_data.data);
+ ret = gssapi_krb5_rd_delegation(minor_status,
+ gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ &fwd_data,
+ delegated_cred_handle);
+ if (ret)
+ goto failure;
}
-
-
+
flags |= GSS_C_TRANS_FLAG;
if (ret_flags)
Index: heimdal/lib/gssapi/display_status.c
diff -u heimdal/lib/gssapi/display_status.c:1.1.1.1 heimdal/lib/gssapi/display_status.c:1.1.1.1.2.1
--- heimdal/lib/gssapi/display_status.c:1.1.1.1 Tue Feb 26 15:42:04 2002
+++ heimdal/lib/gssapi/display_status.c Mon Aug 12 14:50:45 2002
@@ -122,7 +122,7 @@
*minor_status = 0;
if (mech_type != GSS_C_NO_OID &&
- mech_type != GSS_KRB5_MECHANISM)
+ !g_OID_equal(mech_type, GSS_KRB5_MECHANISM))
return GSS_S_BAD_MECH;
if (status_type == GSS_C_GSS_CODE) {
Index: heimdal/lib/gssapi/export_cred.c
diff -u /dev/null heimdal/lib/gssapi/export_cred.c:1.1.2.4
--- /dev/null Sun Aug 18 17:18:27 2002
+++ heimdal/lib/gssapi/export_cred.c Fri Aug 16 11:52:59 2002
@@ -0,0 +1,157 @@
+#include "gssapi_locl.h"
+
+RCSID("$Id$");
+
+#if 0
+/* lze pouzit gss_release_buffer() na output token? Nejaka takova fce na
+ * vymazani
+ exportovanych cred by mela existovat. Stacilo by rict, ze vysledek
+ gss_export_cred() musi byt uvolnitelny pres gss_release_buffer() */
+
+/* lze rict pouzij defaultni ccache ?? */
+
+/* lze delegovat vice creds naraz? */
+
+/* je k necemu parametr time_req v gss_import_cred ? */
+#endif
+
+/* Dump credentials to buffer. Simple gss_release_buffer can be used to free
+ them. */
+static krb5_error_code
+cred_encode(krb5_context context,
+ krb5_ccache ccache,
+ gss_buffer_t buffer)
+{
+ krb5_storage *sp;
+ krb5_error_code ret;
+ krb5_cc_cursor cursor;
+ krb5_creds creds;
+ krb5_data encoded_creds;
+
+ memset(&creds, 0, sizeof(creds));
+ memset(&encoded_creds, 0, sizeof(encoded_creds));
+
+ sp = krb5_storage_emem();
+ if (sp == NULL)
+ return ENOMEM;
+
+ /* suppose only one ticket is delegated by the client so it's sufficient to
+ process only the first credential from ccache. */
+ krb5_cc_start_seq_get(context, ccache, &cursor);
+ ret = krb5_cc_next_cred(context, ccache, &cursor, &creds);
+ krb5_cc_end_seq_get(context, ccache, &cursor);
+ if (ret)
+ goto end;
+
+ ret = krb5_store_creds(sp, &creds);
+ if (ret)
+ goto end;
+
+ ret = krb5_storage_to_data(sp, &encoded_creds);
+ if (ret)
+ goto end;
+
+ buffer->length = encoded_creds.length;
+ buffer->value = encoded_creds.data;
+ krb5_data_zero(&encoded_creds);
+
+ ret = 0;
+
+end:
+ krb5_free_creds_contents(context, &creds);
+ if (encoded_creds.length > 0)
+ krb5_data_free(&encoded_creds);
+ krb5_storage_free(sp);
+
+ return ret;
+}
+
+/* Copy ccache to disc and return its identificator (filename) */
+static krb5_error_code
+cred_store(krb5_context context,
+ krb5_ccache src_ccache,
+ gss_buffer_t buffer)
+{
+ krb5_error_code problem;
+ krb5_ccache ccache = NULL;
+ krb5_principal princ = NULL;
+
+ problem = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache);
+ if (problem)
+ return problem;
+
+ problem = krb5_cc_get_principal(context, src_ccache, &princ);
+ if (problem)
+ goto end;
+
+ problem = krb5_cc_initialize(context, ccache, princ);
+ if (problem)
+ goto end;
+
+ problem = krb5_cc_copy_cache(context, src_ccache, ccache);
+ if (problem)
+ goto end;
+
+ buffer->length = asprintf((char**) &buffer->value, "KRB5CCNAME=%s",
+ krb5_cc_get_name(context, ccache));
+ if (buffer->length == 0) {
+ problem = ENOMEM;
+ goto end;
+ }
+
+ problem = 0;
+
+end:
+ if (problem)
+ krb5_cc_destroy(context, ccache);
+ else
+ krb5_cc_close(context, ccache);
+
+ if (princ)
+ krb5_free_principal(context, princ);
+
+ return problem;
+}
+
+OM_uint32 gss_export_cred
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_mech,
+ OM_uint32 option_req,
+ gss_buffer_t export_buffer
+ )
+{
+ krb5_error_code problem;
+
+ gssapi_krb5_init();
+ *minor_status = 0;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_NO_CRED;
+
+ if (desired_mech != GSS_C_NO_OID &&
+ !g_OID_equal(desired_mech, GSS_KRB5_MECHANISM))
+ return GSS_S_BAD_MECH;
+
+ if (export_buffer == GSS_C_NO_BUFFER)
+ return GSS_S_FAILURE;
+
+ if (option_req == 0)
+ problem = cred_encode(gssapi_krb5_context, cred_handle->ccache,
+ export_buffer);
+ else if (option_req == 1) {
+ problem = cred_store(gssapi_krb5_context, cred_handle->ccache,
+ export_buffer);
+ } else {
+ *minor_status = KRB5KRB_ERR_GENERIC;
+ return GSS_S_FAILURE;
+ }
+
+ if (problem) {
+ gssapi_krb5_set_error_string();
+ *minor_status = problem;
+ return GSS_S_FAILURE;
+ }
+
+ return GSS_S_COMPLETE;
+}
Index: heimdal/lib/gssapi/gssapi.h
diff -u heimdal/lib/gssapi/gssapi.h:1.1.1.1 heimdal/lib/gssapi/gssapi.h:1.1.1.1.2.1
--- heimdal/lib/gssapi/gssapi.h:1.1.1.1 Tue Feb 26 15:42:04 2002
+++ heimdal/lib/gssapi/gssapi.h Mon Aug 12 13:11:31 2002
@@ -770,4 +770,97 @@
gss_cred_id_t cred,
struct krb5_ccache_data *out);
+/*
+ * GSS-API extensions defined by GGF draft
+ * (http://www.gridforum.org/2_SEC/GSI.htm)
+ */
+
+typedef struct gss_buffer_set_desc_struct {
+ size_t count;
+ gss_buffer_desc * elements;
+} gss_buffer_set_desc, *gss_buffer_set_t;
+
+OM_uint32
+gss_create_empty_buffer_set(
+ OM_uint32 * minor_status,
+ gss_buffer_set_t * buffer_set);
+
+OM_uint32
+gss_add_buffer_set_member(
+ OM_uint32 * minor_status,
+ const gss_buffer_t member_buffer,
+ gss_buffer_set_t * buffer_set);
+
+OM_uint32
+gss_release_buffer_set(
+ OM_uint32 * minor_status,
+ gss_buffer_set_t buffer_set);
+
+OM_uint32
+gss_export_cred(
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_mech,
+ OM_uint32 option_req,
+ gss_buffer_t export_buffer);
+
+OM_uint32
+gss_import_cred(
+ OM_uint32 * minor_status,
+ gss_cred_id_t * output_cred_handle,
+ const gss_OID desired_mech,
+ OM_uint32 option_req,
+ const gss_buffer_t import_buffer,
+ OM_uint32 time_req,
+ OM_uint32 * time_rec);
+
+OM_uint32
+gss_init_delegation(
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_mech,
+ const gss_OID_set extension_oids,
+ const gss_buffer_set_t extension_buffers,
+ const gss_buffer_t input_token,
+ OM_uint32 time_req,
+ gss_buffer_t output_token);
+
+OM_uint32
+gss_accept_delegation(
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID_set extension_oids,
+ const gss_buffer_set_t extension_buffers,
+ const gss_buffer_t input_token,
+ OM_uint32 time_req,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle,
+ gss_OID * mech_type,
+ gss_buffer_t output_token);
+
+
+OM_uint32
+gss_inquire_sec_context_by_oid(
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_OID desired_object,
+ gss_buffer_set_t data_set);
+
+
+OM_uint32
+gss_inquire_cred_by_oid(
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t * data_set);
+
+OM_uint32
+gss_set_sec_context_option(
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_OID option,
+ gss_buffer_t value);
+
+
#endif /* GSSAPI_H_ */
Index: heimdal/lib/gssapi/gssapi_locl.h
diff -u heimdal/lib/gssapi/gssapi_locl.h:1.1.1.1 heimdal/lib/gssapi/gssapi_locl.h:1.1.1.1.2.2
--- heimdal/lib/gssapi/gssapi_locl.h:1.1.1.1 Tue Feb 26 15:42:04 2002
+++ heimdal/lib/gssapi/gssapi_locl.h Mon Aug 12 14:50:45 2002
@@ -44,6 +44,11 @@
#include <gssapi.h>
#include <assert.h>
+#define g_OID_equal(o1,o2) \
+ (((o1) == (o2)) || \
+ ((o1) && (o2) && ((o1)->length == (o2)->length) && \
+ (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)))
+
extern krb5_context gssapi_krb5_context;
extern krb5_keytab gssapi_krb5_keytab;
@@ -123,4 +128,18 @@
char *
gssapi_krb5_get_error_string (void);
+void
+gssapi_krb5_do_delegation (krb5_auth_context ac,
+ krb5_ccache ccache,
+ krb5_creds *cred,
+ const gss_name_t target_name,
+ krb5_data *fwd_data,
+ int *flags);
+
+OM_uint32
+gssapi_krb5_rd_delegation(OM_uint32 *minor_status,
+ krb5_context context,
+ krb5_auth_context ac,
+ krb5_data *fwd_creds,
+ gss_cred_id_t *delegated_cred_handle);
#endif
Index: heimdal/lib/gssapi/import_cred.c
diff -u /dev/null heimdal/lib/gssapi/import_cred.c:1.1.2.6
--- /dev/null Sun Aug 18 17:18:27 2002
+++ heimdal/lib/gssapi/import_cred.c Fri Aug 16 12:46:25 2002
@@ -0,0 +1,165 @@
+#include "gssapi_locl.h"
+
+RCSID("$Id$");
+
+#if 0
+- neni desired_mech zbytecny? gss_import_sec_context nic takoveho nema.
+#endif
+
+OM_uint32 gss_import_cred
+ (OM_uint32 * minor_status,
+ gss_cred_id_t * output_cred_handle,
+ const gss_OID desired_mech,
+ OM_uint32 option_req,
+ const gss_buffer_t import_buffer,
+ OM_uint32 time_req,
+ OM_uint32 * time_rec)
+{
+ krb5_error_code problem;
+ OM_uint32 ret;
+ gss_cred_id_t handle = NULL;
+ krb5_ccache ccache = NULL;
+ krb5_creds creds;
+ krb5_timestamp now;
+ krb5_storage *sp = NULL;
+
+ gssapi_krb5_init();
+ *minor_status = 0;
+
+ memset(&creds, 0, sizeof(creds));
+
+ if (output_cred_handle == NULL)
+ return GSS_S_NO_CRED;
+
+ if (desired_mech != GSS_C_NO_OID &&
+ !g_OID_equal(desired_mech, GSS_KRB5_MECHANISM))
+ return GSS_S_BAD_MECH;
+
+ if (option_req != 0 && option_req != 1) {
+ return GSS_S_FAILURE;
+ }
+
+ if (import_buffer == GSS_C_NO_BUFFER || import_buffer->length <= 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ if (option_req == 0) {
+ sp = krb5_storage_from_mem (import_buffer->value,
+ import_buffer->length);
+ if (sp == NULL) {
+ problem = ENOMEM;
+ goto krb5_bad;
+ }
+
+ problem = krb5_ret_creds(sp, &creds);
+ if (problem)
+ goto krb5_bad;
+
+ problem = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops, &ccache);
+ if (problem)
+ goto krb5_bad;
+
+ problem = krb5_cc_initialize(gssapi_krb5_context, ccache, creds.client);
+ if (problem)
+ goto krb5_bad;
+
+ problem = krb5_cc_store_cred(gssapi_krb5_context, ccache, &creds);
+ if (problem)
+ goto krb5_bad;
+ } else {
+ char *filename = NULL;
+ krb5_cc_cursor cursor;
+
+ filename = strchr((char *) import_buffer->value, '=');
+ if (filename == NULL) {
+ ret = GSS_S_DEFECTIVE_TOKEN;
+ goto gssapi_bad;
+ }
+ filename++;
+ problem = krb5_cc_resolve(gssapi_krb5_context, filename, &ccache);
+ if (problem)
+ goto krb5_bad;
+
+ krb5_cc_start_seq_get(gssapi_krb5_context, ccache, &cursor);
+ problem = krb5_cc_next_cred(gssapi_krb5_context, ccache, &cursor, &creds);
+ krb5_cc_end_seq_get(gssapi_krb5_context, ccache, &cursor);
+ if (problem)
+ goto krb5_bad;
+ }
+
+ handle = (gss_cred_id_t)malloc(sizeof(*handle));
+ if (handle == NULL) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ goto gssapi_bad;
+ }
+ memset(handle, 0, sizeof (*handle));
+
+ problem = krb5_cc_get_principal(gssapi_krb5_context, ccache,
+ &handle->principal);
+ if (problem)
+ goto krb5_bad;
+
+ handle->usage = GSS_C_BOTH;
+
+ ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret)
+ goto gssapi_bad;
+
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret)
+ goto gssapi_bad;
+
+ if (handle->ccache)
+ krb5_cc_destroy(gssapi_krb5_context, handle->ccache);
+ handle->ccache = ccache;
+
+ problem = krb5_timeofday(gssapi_krb5_context, &now);
+ if (problem)
+ goto krb5_bad;
+
+ if (creds.times.endtime <= now) {
+ ret = GSS_S_CREDENTIALS_EXPIRED;
+ goto gssapi_bad;
+ }
+
+ if (time_req > 0)
+ /* XXX lifetime of the ticket is not changed -- another ticket would have
+ to be fetched from KDC */
+ handle->lifetime = (time_req + now < creds.times.endtime) ?
+ time_req + now :
+ creds.times.endtime;
+ else
+ handle->lifetime = creds.times.endtime;
+
+ if (time_rec != NULL)
+ *time_rec = handle->lifetime - now;
+
+ krb5_free_creds_contents(gssapi_krb5_context, &creds);
+ if (sp)
+ krb5_storage_free(sp);
+
+ *output_cred_handle = handle;
+ return GSS_S_COMPLETE;
+
+krb5_bad:
+ ret = GSS_S_FAILURE;
+ *minor_status = problem;
+ gssapi_krb5_set_error_string ();
+
+gssapi_bad:
+ if (sp)
+ krb5_storage_free(sp);
+ krb5_free_creds_contents(gssapi_krb5_context, &creds);
+ if (ccache)
+ krb5_cc_close(gssapi_krb5_context, ccache);
+ if (handle) {
+ if (handle->principal)
+ krb5_free_principal(gssapi_krb5_context, handle->principal);
+ if (handle->mechanisms)
+ gss_release_oid_set(NULL, &handle->mechanisms);
+ free(handle);
+ }
+
+ return ret;
+}
Index: heimdal/lib/gssapi/import_name.c
diff -u heimdal/lib/gssapi/import_name.c:1.1.1.1 heimdal/lib/gssapi/import_name.c:1.1.1.1.2.1
--- heimdal/lib/gssapi/import_name.c:1.1.1.1 Tue Feb 26 15:42:04 2002
+++ heimdal/lib/gssapi/import_name.c Mon Aug 12 14:50:45 2002
@@ -133,13 +133,13 @@
{
gssapi_krb5_init ();
- if (input_name_type == GSS_C_NT_HOSTBASED_SERVICE)
+ if (g_OID_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE))
return import_hostbased_name (minor_status,
input_name_buffer,
output_name);
else if (input_name_type == GSS_C_NO_OID
- || input_name_type == GSS_C_NT_USER_NAME
- || input_name_type == GSS_KRB5_NT_PRINCIPAL_NAME)
+ || g_OID_equal(input_name_type, GSS_C_NT_USER_NAME)
+ || g_OID_equal(input_name_type, GSS_KRB5_NT_PRINCIPAL_NAME))
/* default printable syntax */
return import_krb5_name (minor_status,
input_name_buffer,
Index: heimdal/lib/gssapi/init_delegation.c
diff -u /dev/null heimdal/lib/gssapi/init_delegation.c:1.1.2.3
--- /dev/null Sun Aug 18 17:18:27 2002
+++ heimdal/lib/gssapi/init_delegation.c Mon Aug 12 14:50:45 2002
@@ -0,0 +1,64 @@
+#include "gssapi_locl.h"
+
+RCSID("$Id$");
+
+OM_uint32 gss_init_delegation(
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_mech,
+ const gss_OID_set extension_oids,
+ const gss_buffer_set_t extension_buffers,
+ const gss_buffer_t input_token,
+ OM_uint32 time_req,
+ gss_buffer_t output_token)
+{
+ krb5_error_code kret = 0;
+ OM_uint32 ret;
+ krb5_ccache ccache = NULL;
+ krb5_creds creds;
+ u_int32_t flags = 0;
+ krb5_data fwd_data;
+
+ memset(&creds, 0, sizeof(&creds));
+ krb5_data_zero(&fwd_data);
+
+ gssapi_krb5_init();
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_FAILURE;
+
+ if (desired_mech != GSS_C_NO_OID &&
+ !g_OID_equal(desired_mech, GSS_KRB5_MECHANISM))
+ return GSS_S_BAD_MECH;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ kret = krb5_cc_default(gssapi_krb5_context, &ccache);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ gssapi_krb5_set_error_string ();
+ goto end;
+ }
+ } else
+ ccache = cred_handle->ccache;
+
+ flags = 0;
+ gssapi_krb5_do_delegation(context_handle->auth_context, ccache, &creds,
+ context_handle->target, &fwd_data, &flags);
+ if (!(flags & GSS_C_DELEG_FLAG)) {
+ ret = GSS_S_FAILURE;
+ goto end;
+ }
+
+ ret = gssapi_krb5_encapsulate(minor_status, &fwd_data, output_token,
+ "\x05\x01");
+ if (ret)
+ goto end;
+
+ ret = GSS_S_COMPLETE;
+
+end:
+ return ret;
+}
Index: heimdal/lib/gssapi/init_sec_context.c
diff -u heimdal/lib/gssapi/init_sec_context.c:1.1.1.1 heimdal/lib/gssapi/init_sec_context.c:1.1.1.1.2.2
--- heimdal/lib/gssapi/init_sec_context.c:1.1.1.1 Tue Feb 26 15:42:04 2002
+++ heimdal/lib/gssapi/init_sec_context.c Mon Aug 12 14:00:51 2002
@@ -101,13 +101,13 @@
* handle delegated creds in init-sec-context
*/
-static void
-do_delegation (krb5_auth_context ac,
- krb5_ccache ccache,
- krb5_creds *cred,
- const gss_name_t target_name,
- krb5_data *fwd_data,
- int *flags)
+void
+gssapi_krb5_do_delegation (krb5_auth_context ac,
+ krb5_ccache ccache,
+ krb5_creds *cred,
+ const gss_name_t target_name,
+ krb5_data *fwd_data,
+ int *flags)
{
krb5_creds creds;
krb5_kdc_flags fwd_flags;
@@ -117,14 +117,16 @@
memset (&creds, 0, sizeof(creds));
krb5_data_zero (fwd_data);
- kret = krb5_generate_subkey (gssapi_krb5_context, &cred->session, &subkey);
- if (kret)
- goto out;
-
- kret = krb5_auth_con_setlocalsubkey(gssapi_krb5_context, ac, subkey);
- krb5_free_keyblock (gssapi_krb5_context, subkey);
- if (kret)
- goto out;
+ if (ac->local_subkey == NULL) {
+ kret = krb5_generate_subkey (gssapi_krb5_context, &cred->session, &subkey);
+ if (kret)
+ goto out;
+
+ kret = krb5_auth_con_setlocalsubkey(gssapi_krb5_context, ac, subkey);
+ krb5_free_keyblock (gssapi_krb5_context, subkey);
+ if (kret)
+ goto out;
+ }
kret = krb5_cc_get_principal(gssapi_krb5_context, ccache, &creds.client);
if (kret)
@@ -320,8 +322,8 @@
flags = 0;
ap_options = 0;
if (req_flags & GSS_C_DELEG_FLAG)
- do_delegation ((*context_handle)->auth_context,
- ccache, cred, target_name, &fwd_data, &flags);
+ gssapi_krb5_do_delegation((*context_handle)->auth_context,
+ ccache, cred, target_name, &fwd_data, &flags);
if (req_flags & GSS_C_MUTUAL_FLAG) {
flags |= GSS_C_MUTUAL_FLAG;
Index: heimdal/lib/gssapi/padding.c
diff -u /dev/null heimdal/lib/gssapi/padding.c:1.1.2.3
--- /dev/null Sun Aug 18 17:18:27 2002
+++ heimdal/lib/gssapi/padding.c Mon Aug 12 14:28:28 2002
@@ -0,0 +1,116 @@
+#include "gssapi_locl.h"
+
+RCSID("$Id$");
+
+/* This file contains fake implementations of those functions which are
+ described by the GSS-API rfc or GSS Extension draft and which are not
+ implemented in Heimdal. */
+
+OM_uint32
+gss_process_context_token
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer
+ )
+{
+ return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_add_cred (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * initiator_time_rec,
+ OM_uint32 * acceptor_time_rec
+ )
+{
+ return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_inquire_cred_by_mech (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t * name,
+ OM_uint32 * initiator_lifetime,
+ OM_uint32 * acceptor_lifetime,
+ gss_cred_usage_t * cred_usage
+ )
+{
+ return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_inquire_names_for_mech (
+ OM_uint32 * minor_status,
+ const gss_OID mechanism,
+ gss_OID_set * name_types
+ )
+{
+ return GSS_S_FAILURE;
+}
+
+/*
+ Functions from GSS-API Extension draft
+*/
+
+OM_uint32
+gss_create_empty_buffer_set(
+ OM_uint32 * minor_status,
+ gss_buffer_set_t * buffer_set)
+{
+ return GSS_S_FAILURE;
+}
+
+OM_uint32
+gss_add_buffer_set_member(
+ OM_uint32 * minor_status,
+ const gss_buffer_t member_buffer,
+ gss_buffer_set_t * buffer_set)
+{
+ return GSS_S_FAILURE;
+}
+
+OM_uint32
+gss_release_buffer_set(
+ OM_uint32 * minor_status,
+ gss_buffer_set_t buffer_set)
+{
+ return GSS_S_FAILURE;
+}
+
+OM_uint32
+gss_inquire_sec_context_by_oid(
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_OID desired_object,
+ gss_buffer_set_t data_set)
+{
+ return GSS_S_FAILURE;
+}
+
+
+OM_uint32
+gss_inquire_cred_by_oid(
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t * data_set)
+{
+ return GSS_S_FAILURE;
+}
+
+OM_uint32
+gss_set_sec_context_option(
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_OID option,
+ gss_buffer_t value)
+{
+ return GSS_S_FAILURE;
+}