/*
 * Copyright (c) 1995, by Sun Microsystems, Inc.
 * All rights reserved.
 */
 
/* XXX: I know where to find this header, but it really is using a
 * private interface.  I dont want to export the gss_mechanism
 * structure, so I hide it in a non-published header.  Thats ok,
 * we know where to find it.
 */
#include "../mechglue/mglueP.h"

/*
 * These are the extern declarations, one group per mechanism. They are
 * contained in the files named <mech>_gssd_extern_srvr.conf.
 */

/* ident  "@(#)krb5_gssd_extern_srvr.conf 1.10     95/08/01 SMI" */

/** declarations of internal name mechanism functions **/

/* This should somehow be generated by the internal mechanism
 * routine library... But for now I've hand-copied over from
 * gssapiP_krb5.h
 */

/* XXX: Should replace these with #include "gssapiP_krb5.h" , once
 * the function prototypes are fixed (e.g., need a void*, not a
 * krb5_context.
 */

OM_uint32 krb5_gss_acquire_cred
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_name_t,       /* desired_name */
            OM_uint32,        /* time_req */
            gss_OID_set,      /* desired_mechs */
            int,              /* cred_usage */
            gss_cred_id_t*,   /* output_cred_handle */
            gss_OID_set*,     /* actual_mechs */
            OM_uint32*        /* time_rec */
           );

OM_uint32 krb5_gss_release_cred
 	  (void *,
	    OM_uint32*,       /* minor_status */
            gss_cred_id_t*    /* cred_handle */
           );

OM_uint32 krb5_gss_init_sec_context
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_cred_id_t,    /* claimant_cred_handle */
            gss_ctx_id_t*,    /* context_handle */
            gss_name_t,       /* target_name */
            gss_OID,    	/* mech_type */
            int,              /* req_flags */
            OM_uint32,        /* time_req */
            gss_channel_bindings_t,
                              /* input_chan_bindings */
            gss_buffer_t,     /* input_token */
            gss_OID*,         /* actual_mech_type */
            gss_buffer_t,     /* output_token */
            int*,             /* ret_flags */
            OM_uint32*        /* time_rec */
           );

OM_uint32 krb5_gss_accept_sec_context
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_ctx_id_t*,    /* context_handle */
            gss_cred_id_t,    /* verifier_cred_handle */
            gss_buffer_t,     /* input_token_buffer */
            gss_channel_bindings_t,
                              /* input_chan_bindings */
            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 */
           );

OM_uint32 krb5_gss_process_context_token
 	  (void *,
	    OM_uint32*,       /* minor_status */
            gss_ctx_id_t,     /* context_handle */
            gss_buffer_t      /* token_buffer */
           );

OM_uint32 krb5_gss_delete_sec_context
 	  (void *,
	    OM_uint32*,       /* minor_status */
            gss_ctx_id_t*,    /* context_handle */
            gss_buffer_t      /* output_token */
           );

OM_uint32 krb5_gss_context_time
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_ctx_id_t,     /* context_handle */
            OM_uint32*        /* time_rec */
           );

OM_uint32 krb5_gss_sign
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_ctx_id_t,     /* context_handle */
            int,              /* qop_req */
            gss_buffer_t,     /* message_buffer */
            gss_buffer_t      /* message_token */
           );

OM_uint32 krb5_gss_verify
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_ctx_id_t,     /* context_handle */
            gss_buffer_t,     /* message_buffer */
            gss_buffer_t,     /* token_buffer */
            int*              /* qop_state */
           );

OM_uint32 krb5_gss_seal
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_ctx_id_t,     /* context_handle */
            int,              /* conf_req_flag */
            int,              /* qop_req */
            gss_buffer_t,     /* input_message_buffer */
            int*,             /* conf_state */
            gss_buffer_t      /* output_message_buffer */
           );

OM_uint32 krb5_gss_unseal
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_ctx_id_t,     /* context_handle */
            gss_buffer_t,     /* input_message_buffer */
            gss_buffer_t,     /* output_message_buffer */
            int*,             /* conf_state */
            int*              /* qop_state */
           );

OM_uint32 krb5_gss_display_status
	   (void *,
	    OM_uint32*,       /* minor_status */
            OM_uint32,        /* status_value */
            int,              /* status_type */
            gss_OID,          /* mech_type */
            int*,             /* message_context */
            gss_buffer_t      /* status_string */
           );

OM_uint32 krb5_gss_indicate_mechs
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_OID_set*      /* mech_set */
           );

OM_uint32 krb5_gss_compare_name
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_name_t,       /* name1 */
            gss_name_t,       /* name2 */
            int*              /* name_equal */
           );

OM_uint32 krb5_gss_display_name
	   (void *,
	    OM_uint32*,      /* minor_status */
            gss_name_t,      /* input_name */
            gss_buffer_t,     /* output_name_buffer */
            gss_OID*         /* output_name_type */
           );

OM_uint32 krb5_gss_import_name
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_buffer_t,     /* input_name_buffer */
            gss_OID,   	      /* input_name_type */
            gss_name_t*       /* output_name */
           );

OM_uint32 krb5_gss_release_name
	   (void *,
	    OM_uint32*,       /* minor_status */
            gss_name_t*       /* input_name */
           );

OM_uint32 krb5_gss_inquire_cred
	   (void *,
	    OM_uint32 *,      /* minor_status */
            gss_cred_id_t,    /* cred_handle */
            gss_name_t *,     /* name */
            OM_uint32 *,      /* lifetime */
            int *,            /* cred_usage */
            gss_OID_set *     /* mechanisms */
           );

OM_uint32 krb5_gss_inquire_context
	   (void *,
	    OM_uint32*,       /* minor_status */
	    gss_ctx_id_t,     /* context_handle */
	    gss_name_t*,      /* initiator_name */
	    gss_name_t*,      /* acceptor_name */
	    OM_uint32*,       /* lifetime_rec */
	    gss_OID*,         /* mech_type */
	    OM_uint32*,	      /* ctx_flags */
	    int*,             /* ret_flags */
	    int*              /* locally_initiated */
	   );

OM_uint32 krb5_gss_internal_release_oid
      (void *,                /* context */
       OM_uint32 *,           /* minor_status */
       gss_OID *              /* OID */
      );

OM_uint32 krb5_gss_add_cred
	   (void *,
	    OM_uint32 *,		/* minor_status */
	    gss_cred_id_t,		/* input_cred_handle */
	    gss_name_t,			/* desired_name */
	    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 */
	   );


OM_uint32 krb5_gss_export_sec_context
           (void *,
	    OM_uint32 *,		/* minor_status */
	    gss_ctx_id_t *,		/* context_handle */
	    gss_buffer_t		/* interprocess_token */
	    );

OM_uint32 krb5_gss_import_sec_context
           (void *,
	    OM_uint32 *,		/* minor_status */
	    gss_buffer_t,		/* interprocess_token */
	    gss_ctx_id_t *		/* context_handle */
	    );

OM_uint32 krb5_gss_inquire_cred_by_mech
           (void *,
	    OM_uint32  *,		/* minor_status */
	    gss_cred_id_t,		/* cred_handle */
	    gss_OID,			/* mech_type */
	    gss_name_t *,		/* name */
	    OM_uint32 *,		/* initiator_lifetime */
	    OM_uint32 *,		/* acceptor_lifetime */
	    gss_cred_usage_t * 		/* cred_usage */
	   );

OM_uint32 krb5_gss_inquire_names_for_mech
           (void *,
	    OM_uint32 *,		/* minor_status */
	    gss_OID,			/* mechanism */
	    gss_OID_set *		/* name_types */
	   );

extern OM_uint32 krb5_gss_get_context
	   (void**
	   );

extern int krb5_pname_to_uid
             (void *,           /* context */
              char *,		/* principal name */
              gss_OID,		/* name_type */
	      gss_OID,		/* mech_type */
              uid_t *		/* uid (OUT) */
             );

/*
 * This is the declaration of the mechs_array table for Kerberos V5.
 * If the gss_mechanism structure changes, so should this array!  I
 * told you it was a private interface!
 */

/* ident  "@(#)krb5_gssd_init_srvr.conf 1.16     95/08/07 SMI" */

static struct gss_config krb5_mechanism =
	{{5,"\053\005\001\005\002"},
	0,				/* context, to be filled */
	krb5_gss_acquire_cred,
	krb5_gss_release_cred,
	krb5_gss_init_sec_context,
	krb5_gss_accept_sec_context,
	krb5_gss_process_context_token,
	krb5_gss_delete_sec_context,
	krb5_gss_context_time,
	krb5_gss_sign,
	krb5_gss_verify,
	krb5_gss_seal,
	krb5_gss_unseal,
	krb5_gss_display_status,
	krb5_gss_indicate_mechs,
	krb5_gss_compare_name,
	krb5_gss_display_name,
	krb5_gss_import_name,
	krb5_gss_release_name,
	krb5_gss_inquire_cred,
	krb5_gss_add_cred,
	krb5_gss_export_sec_context,
	krb5_gss_import_sec_context,
	krb5_gss_inquire_cred_by_mech,
	krb5_gss_inquire_names_for_mech,
	krb5_gss_inquire_context,
	krb5_gss_internal_release_oid,	 
	krb5_pname_to_uid,
	};

#include "k5-int.h"

/* 
 * Do we want to allocate a new kg_context everytime we call this?
 * I don't know -- for now, just allocate one of them.
 */
static krb5_context kg_context;

OM_uint32
krb5_gss_get_context(context)
void **	context;
{
    if (context == NULL)
	return GSS_S_FAILURE;

    if (kg_context) 
	*context = kg_context;
    else {
	if (krb5_init_context(&kg_context))
	    return GSS_S_FAILURE;
	else
	    *context = kg_context;
    }
    return GSS_S_COMPLETE;
}

gss_mechanism
krb5_gss_initialize()
{
	krb5_gss_get_context(&(krb5_mechanism.context));
	return (&krb5_mechanism);
}
