summaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi/acc_sec.c
diff options
context:
space:
mode:
authorTheodore Tso <tytso@mit.edu>1991-05-06 15:14:31 +0000
committerTheodore Tso <tytso@mit.edu>1991-05-06 15:14:31 +0000
commitde8c3b49f993fa7583c710451cac8f7407f8859c (patch)
treefed1419e5656ababa393248d50b69707dc210a61 /src/lib/gssapi/acc_sec.c
parenteab25e18ca94480e73d70f57b5cbc5cc04b87d45 (diff)
downloadkrb5-de8c3b49f993fa7583c710451cac8f7407f8859c.tar.gz
krb5-de8c3b49f993fa7583c710451cac8f7407f8859c.tar.xz
krb5-de8c3b49f993fa7583c710451cac8f7407f8859c.zip
Initial Revision
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2099 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi/acc_sec.c')
-rw-r--r--src/lib/gssapi/acc_sec.c264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/lib/gssapi/acc_sec.c b/src/lib/gssapi/acc_sec.c
new file mode 100644
index 000000000..0cf361dea
--- /dev/null
+++ b/src/lib/gssapi/acc_sec.c
@@ -0,0 +1,264 @@
+/*
+ * acc_sec.c --- accept security context
+ *
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ */
+
+#include <gssapi.h>
+
+extern krb5_flags krb5_kdc_default_options;
+
+/*
+ * To do in the future:
+ *
+ * * Support replay cache
+ *
+ * * Support delegation of credentials
+ *
+ * * Do something with time_rec
+ *
+ * * Should handle Kerberos error packets being sent back and
+ * forth.
+ */
+
+static krb5_error_code gss_krb5_keyproc(cred_handle, principal, vno, key)
+ krb5_pointer cred_handle;
+ krb5_principal principal;
+ krb5_kvno vno;
+ krb5_keyblock **key;
+{
+ gss_cred_id_t *creds;
+
+ creds = (gss_cred_id_t *) cred_handle;
+
+ if (krb5_principal_compare(creds->principal, principal)) {
+ if (creds->cred_flags & GSS_KRB_HAS_SRVTAB) {
+ *key = &creds->srvtab;
+ return(0);
+ } else
+ return(KRB5_KT_NOTFOUND);
+ } else
+ return(KRB5_KT_NOTFOUND);
+}
+
+
+OM_uint32 gss_accept_sec_context(minor_status, context_handle,
+ verifier_cred_handle, input_token,
+ channel, src_name,
+ mech_type, output_token,
+ ret_flags, time_rec,
+ delegated_cred_handle)
+ OM_uint32 *minor_status;
+ gss_ctx_id_t *context_handle;
+ gss_cred_id_t verifier_cred_handle;
+ gss_buffer_t input_token;
+ gss_channel_bindings channel;
+ gss_name_t *src_name;
+ gss_OID *mech_type;
+ gss_buffer_t output_token;
+ int *ret_flags;
+ OM_uint32 *time_rec;
+ gss_cred_id_t *delegated_cred_handle;
+{
+ krb5_rcache rcache;
+ krb5_address sender_addr;
+ krb5_data inbuf, outbuf;
+ krb5_principal server;
+ krb5_tkt_authent *authdat;
+ OM_uint32 retval;
+ gss_ctx_id_t context;
+
+ *minor_status = 0;
+
+ if (!context_handle) {
+ /*
+ * This is first call to accept_sec_context
+ *
+ * Make sure the input token is sane.
+ */
+ if (retval = gss_check_token(minor_status, input_token,
+ GSS_API_KRB5_TYPE,
+ GSS_API_KRB5_REQ))
+ return(retval);
+ inbuf.length = input_token->length-5;
+ inbuf.data = ( (char *) input_token->value)+5;
+ sender_addr.addrtype = channel.sender_addrtype;
+ sender_addr.length = channel.sender_address.length;
+ sender_addr.contents = channel.sender_address.value;
+ server = verifier_cred_handle.principal;
+ /*
+ * Setup the replay cache.
+ */
+ if (*minor_status = krb5_get_server_rcache(server[1]->data,
+ &rcache))
+ return(gss_make_re(GSS_RE_FAILURE));
+ /*
+ * Now let's rip apart the packet
+ */
+ if (*minor_status = krb5_rd_req(&inbuf, server, &sender_addr,
+ 0, gss_krb5_keyproc,
+ &verifier_cred_handle,
+ rcache, &authdat))
+ return(gss_make_re(GSS_RE_FAILURE));
+ if (*minor_status = krb5_rc_close(rcache))
+ return(gss_make_re(GSS_RE_FAILURE));
+
+ /*
+ * Allocate the context handle structure
+ */
+ if (!(context = malloc(sizeof(struct gss_ctx_id_desc)))) {
+ *minor_status = ENOMEM;
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ context->mech_type = &gss_OID_krb5;
+ context->flags = 0;
+ context->state = GSS_KRB_STATE_DOWN;
+ context->am_client = 0;
+
+ context->my_address.addrtype = channel.sender_addrtype;
+ context->my_address.length = channel.sender_address.length;
+ if (!(context->my_address.contents =
+ malloc(context->my_address.length))) {
+ xfree(context);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ memcpy((char *) context->my_address.contents,
+ (char *) channel.sender_address.value,
+ context->my_address.length);
+ context->his_address.addrtype = channel.receiver_addrtype;
+ context->his_address.length = channel.receiver_address.length;
+ if (!(context->his_address.contents =
+ malloc(context->my_address.length))) {
+ xfree(context->my_address.contents);
+ xfree(context);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ memcpy((char *) context->his_address.contents,
+ (char *) channel.receiver_address.value,
+ context->his_address.length);
+
+ /*
+ * Do mutual authentication if requested.
+ */
+ output_token->length = 0;
+ if ((authdat->ap_options & AP_OPTS_MUTUAL_REQUIRED)) {
+ krb5_ap_rep_enc_part repl;
+ /*
+ * Generate a random sequence number
+ */
+ if (*minor_status =
+ krb5_generate_seq_number(authdat->ticket->enc_part2->session,
+ &context->my_seq_num)) {
+ xfree(context->his_address.contents);
+ xfree(context->my_address.contents);
+ xfree(context);
+ krb5_free_tkt_authent(authdat);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+
+ repl.ctime = authdat->authenticator->ctime;
+ repl.cusec = authdat->authenticator->cusec;
+ repl.subkey = authdat->authenticator->subkey;
+ repl.seq_number = context->my_seq_num;
+
+ if (*minor_status =
+ krb5_mk_rep(&repl,
+ authdat->ticket->enc_part2->session,
+ &outbuf)) {
+ xfree(context->his_address.contents);
+ xfree(context->my_address.contents);
+ xfree(context);
+ krb5_free_tkt_authent(authdat);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ if (*minor_status = gss_make_token(minor_status,
+ GSS_API_KRB5_TYPE,
+ GSS_API_KRB5_REQ,
+ outbuf.length,
+ outbuf.data,
+ output_token)) {
+ xfree(context->his_address.contents);
+ xfree(context->my_address.contents);
+ xfree(context);
+ xfree(outbuf.data);
+ krb5_free_tkt_authent(authdat);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ }
+
+ /*
+ * Fill in context handle structure
+ */
+ if (*minor_status =
+ krb5_copy_principal(verifier_cred_handle.principal,
+ &context->me)) {
+ xfree(context->his_address.contents);
+ xfree(context->my_address.contents);
+ xfree(context);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ if (*minor_status =
+ krb5_copy_principal(authdat->authenticator->client,
+ &context->him)) {
+ krb5_free_principal(context->me);
+ xfree(context->his_address.contents);
+ xfree(context->my_address.contents);
+ xfree(context);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ if (*minor_status =
+ krb5_copy_keyblock(authdat->ticket->enc_part2->session,
+ &context->session_key)) {
+ krb5_free_principal(context->me);
+ krb5_free_principal(context->him);
+ xfree(context->his_address.contents);
+ xfree(context->my_address.contents);
+ xfree(context);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ context->his_seq_num = authdat->authenticator->seq_number;
+ context->cusec = authdat->authenticator->cusec;
+ context->ctime = authdat->authenticator->ctime;
+ context->flags = ((char *) input_token->value)[4];
+ /*
+ * Strip out flags we don't support (yet) XXX
+ */
+ context->flags &= ~(GSS_C_DELEG_FLAG | GSS_C_REPLAY_FLAG);
+ /*
+ * Deliver output parameters
+ */
+ if (src_name) {
+ if (*minor_status = krb5_copy_principal(context->him,
+ src_name)) {
+ xfree(context->session_key->contents);
+ krb5_free_principal(context->me);
+ krb5_free_principal(context->him);
+ xfree(context->his_address.contents);
+ xfree(context->my_address.contents);
+ xfree(context);
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+ }
+ if (mech_type)
+ *mech_type = &gss_OID_krb5;
+ *ret_flags = context->flags;
+ if (time_rec)
+ *time_rec = GSS_TIME_REC_INDEFINITE;
+ return(GSS_S_COMPLETE);
+ } else {
+ /*
+ * Context is non-null, this is the second time through....
+ */
+ return(gss_make_re(GSS_RE_FAILURE));
+ }
+}
+