Authen-Krb5

 view release on metacpan or  search on metacpan

lib/Authen/Krb5.xs  view on Meta::CPAN

#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

/* We currently provide some private functions and probably shouldn't. */
#define KRB5_PRIVATE 1
#include <krb5.h>

/* Recent versions of Kerberos include com_err on their own.  Uncomment if you
 * have an older version and the complier complains about missing headers.
 */
/* #include <com_err.h> */

#include <errno.h>
#include "krb5_constants.c"

#ifdef __cplusplus
}
#endif

/* change this if 10 hours doesn't suit you */
#define KRB5_DEFAULT_LIFE 60*60*10

typedef krb5_ccache		Authen__Krb5__Ccache;
typedef krb5_context		Authen__Krb5__Context;
typedef krb5_principal		Authen__Krb5__Principal;
typedef krb5_auth_context	Authen__Krb5__AuthContext;
typedef krb5_rcache		Authen__Krb5__Rcache;
typedef krb5_creds		*Authen__Krb5__Creds;
typedef krb5_ap_rep_enc_part	*Authen__Krb5__ApRepEncPart;
typedef krb5_ticket		*Authen__Krb5__Ticket;
typedef krb5_keytab		Authen__Krb5__Keytab;
typedef krb5_enc_tkt_part	*Authen__Krb5__EncTktPart;
typedef krb5_error		*Authen__Krb5__Error;
typedef krb5_address		*Authen__Krb5__Address;
typedef krb5_keyblock		*Authen__Krb5__Keyblock;
typedef krb5_keytab_entry	*Authen__Krb5__KeytabEntry;
typedef krb5_kt_cursor          *Authen__Krb5__KeytabCursor;
typedef krb5_cc_cursor          *Authen__Krb5__CcacheCursor;
typedef krb5_keyblock		*Authen__Krb5__KeyBlock;

static krb5_context context = NULL;
static krb5_error_code err;
static krb5_keytab_entry keytab_entry_init;


/*
 * function prototypes against implicit declaration of functions,
 * taken from k5-int.h
 */

krb5_error_code krb5_gen_portaddr(krb5_context, const krb5_address *,
                                  krb5_const_pointer, krb5_address **);
krb5_error_code krb5_gen_replay_name(krb5_context, const krb5_address *,
                                     const char *, char **);
void KRB5_CALLCONV krb5_free_enc_tkt_part(krb5_context, krb5_enc_tkt_part *);
void KRB5_CALLCONV krb5_free_address(krb5_context, krb5_address *);


/*
 * The following three routines implement a "safehouse" for nested Kerberos
 * data structures which shouldn't be freed before their parent data
 * structures are freed.  Without this, "Bad free() ignored" errors as well
 * as core dumps could occur when the parent structures are eventually freed.
 *
 * If a method returns a newly allocated object, it calls can_free() to
 * register the object as "freeable," since the memory was not in use
 * beforehand.  This module will only free objects that have been registered
 * with can_free(), and lets Kerberos free the others.
 *
 * Doing it the other way (registering objects which *shouldn't* be freed)
 * is more complicated than it first seems, so I did it this way.
 */


HV *free_hash = NULL; /* might as well take advantage of Perl! */

void can_free(SV *sv)
{
	char key[80];

	sprintf(key,"%p",sv);
	if (!free_hash) free_hash = newHV();
	hv_store(free_hash,key,strlen(key),&PL_sv_yes,0);
}

int should_free(SV *sv)
{
	char key[80];

	if (!free_hash) return 0;
	sprintf(key,"%p",sv);
	return hv_exists(free_hash,key,strlen(key));
}

void freed(SV *sv)
{
	char key[80];

lib/Authen/Krb5.xs  view on Meta::CPAN

	Authen::Krb5::Ccache cc
	Authen::Krb5::Principal p

	CODE:
	err = krb5_cc_initialize(context, cc, p);
	if (err) XSRETURN_UNDEF;
	else {
		can_free((SV *)cc);
		XSRETURN_YES;
	}

void
store_cred(cc, creds)
	Authen::Krb5::Ccache cc
	Authen::Krb5::Creds creds

	CODE:
	err = krb5_cc_store_cred(context, cc, creds);
	if (err) XSRETURN_UNDEF;
	XSRETURN_YES;

const char *
get_name(cc)
	Authen::Krb5::Ccache cc

	CODE:
	RETVAL = krb5_cc_get_name(context, cc);

	OUTPUT:
	RETVAL

Authen::Krb5::Principal
get_principal(cc)
	Authen::Krb5::Ccache cc

	CODE:
	err = krb5_cc_get_principal(context, cc, &RETVAL);
	if (err) XSRETURN_UNDEF;

	can_free((SV *)RETVAL);

	OUTPUT:
	RETVAL

void
destroy(cc)
	Authen::Krb5::Ccache cc

	CODE:
	if (!should_free((SV*)cc)) XSRETURN_UNDEF;

	err = krb5_cc_destroy(context, cc);
	if (err) {
		XSRETURN_UNDEF;
	}
	else {
		freed((SV*)cc);
		XSRETURN_YES;
	}

krb5_cc_cursor *
start_seq_get(cc)
	Authen::Krb5::Ccache cc

	CODE:
	if (!New(0, RETVAL, 1, krb5_cc_cursor))
		XSRETURN_UNDEF;
        err = krb5_cc_start_seq_get(context, cc, RETVAL);
	if (err)
                XSRETURN_UNDEF;

        OUTPUT:
        RETVAL

Authen::Krb5::Creds
next_cred(cc, cursor)
        krb5_cc_cursor *cursor
        Authen::Krb5::Ccache cc

        CODE:
	if (!New(0, RETVAL, 1, krb5_creds))
		XSRETURN_UNDEF;
        err = krb5_cc_next_cred(context, cc, cursor, RETVAL);
	if (err)
                XSRETURN_UNDEF;
        can_free((SV *)RETVAL);

        OUTPUT:
        RETVAL

void
end_seq_get(cc, cursor)
        Authen::Krb5::Ccache cc
        krb5_cc_cursor *cursor

        CODE:
        err = krb5_cc_end_seq_get(context, cc, cursor);
        if (err)
                XSRETURN_UNDEF;
        XSRETURN_YES;

void
DESTROY(cc)
	Authen::Krb5::Ccache cc

	CODE:
	if (should_free((SV *)cc)) {
		krb5_cc_close(context, cc);
		freed((SV *)cc);
	}

MODULE = Authen::Krb5	PACKAGE = Authen::Krb5::KeyBlock

int
length(kb)
	Authen::Krb5::KeyBlock kb

	CODE:
	RETVAL = kb->length;

	OUTPUT:
	RETVAL

void
contents(kb)
	Authen::Krb5::KeyBlock kb

	PPCODE:
	/* sv_2mortal here causes 'Attempt to free unreferenced scalar' later */
	XPUSHs(newSVpvn((char*)(kb->contents), kb->length));

int
enctype(kb)
	Authen::Krb5::KeyBlock kb

	CODE:
	RETVAL = (int)kb->enctype;

	OUTPUT:
	RETVAL

void
enctype_string(kb)
	Authen::Krb5::KeyBlock kb

	PREINIT:
	char buf[256];

	PPCODE:
	err = krb5_enctype_to_string(kb->enctype, buf, 255);
	if (err) {
		XSRETURN_UNDEF;
	}
	XPUSHs(newSVpv(buf, 0));

void
DESTROY(kb)

lib/Authen/Krb5.xs  view on Meta::CPAN

MODULE = Authen::Krb5	PACKAGE = Authen::Krb5::Keyblock

 
krb5_enctype
enctype(keyblock)
	Authen::Krb5::Keyblock keyblock

        CODE:
        RETVAL = keyblock->enctype;

        OUTPUT:
        RETVAL
 
unsigned int
length(keyblock)
        Authen::Krb5::Keyblock keyblock

        CODE:
        RETVAL = keyblock->length;

        OUTPUT:
        RETVAL

SV *
contents(keyblock)
        Authen::Krb5::Keyblock keyblock

	CODE:
	if (keyblock->contents == NULL)
		XSRETURN_UNDEF;
	RETVAL = newSVpv((char *) keyblock->contents, keyblock->length);

	OUTPUT:
	RETVAL

void
DESTROY(keyblock)
	Authen::Krb5::Keyblock	keyblock

        CODE:
	if (keyblock->contents) {
		memset(keyblock->contents, 0, keyblock->length);
		free(keyblock->contents);
		keyblock->contents = NULL;
	}

MODULE = Authen::Krb5   PACKAGE = Authen::Krb5::Keytab

void
add_entry(keytab, entry)
        Authen::Krb5::Keytab keytab
        Authen::Krb5::KeytabEntry entry

        CODE:
        err = krb5_kt_add_entry(context, keytab, entry);
	if (err)
                XSRETURN_UNDEF;
	XSRETURN_YES;

void
end_seq_get(keytab, cursor)
        Authen::Krb5::Keytab keytab
        krb5_kt_cursor *cursor

        CODE:
        err = krb5_kt_end_seq_get(context, keytab, cursor);
        if (err)
                XSRETURN_UNDEF;
        XSRETURN_YES;

Authen::Krb5::KeytabEntry
get_entry(keytab, principal, vno = 0, enctype = 0)
        Authen::Krb5::Keytab keytab
        Authen::Krb5::Principal principal
        krb5_kvno vno
        krb5_enctype enctype

        CODE:
	if (!New(0, RETVAL, 1, krb5_keytab_entry))
		XSRETURN_UNDEF;
        err = krb5_kt_get_entry(context, keytab, principal, vno, enctype,
            RETVAL);
	if (err)
		XSRETURN_UNDEF;
        can_free((SV *)RETVAL);
	
	OUTPUT:
	RETVAL
        
SV *
get_name(keytab)
        Authen::Krb5::Keytab keytab

        PREINIT:
        char name[MAX_KEYTAB_NAME_LEN+1];

        CODE:
        err = krb5_kt_get_name(context, keytab, name, MAX_KEYTAB_NAME_LEN);
	if (err)
                XSRETURN_UNDEF;
	RETVAL = sv_2mortal(newSVpv(name, 0));
        can_free((SV *)RETVAL);

        OUTPUT:
        RETVAL

Authen::Krb5::KeytabEntry
next_entry(keytab, cursor)
        krb5_kt_cursor *cursor
        Authen::Krb5::Keytab keytab

        CODE:
	if (!New(0, RETVAL, 1, krb5_keytab_entry))
		XSRETURN_UNDEF;
        err = krb5_kt_next_entry(context, keytab, RETVAL, cursor);
	if (err)
                XSRETURN_UNDEF;
        can_free((SV *)RETVAL);

        OUTPUT:
        RETVAL

void
remove_entry(keytab, entry)
        Authen::Krb5::Keytab keytab
        Authen::Krb5::KeytabEntry entry

        CODE:
        err = krb5_kt_remove_entry(context, keytab, entry);
	if (err)
                XSRETURN_UNDEF;
	XSRETURN_YES;

krb5_kt_cursor *
start_seq_get(keytab)
        Authen::Krb5::Keytab keytab

        CODE:
	if (!New(0, RETVAL, 1, krb5_kt_cursor))
		XSRETURN_UNDEF;
        err = krb5_kt_start_seq_get(context, keytab, RETVAL);
	if (err)
                XSRETURN_UNDEF;

        OUTPUT:
        RETVAL

void
DESTROY(keytab)
        Authen::Krb5::Keytab keytab

        CODE:
        if (keytab && should_free((SV *)keytab)) {
                krb5_kt_close(context, keytab);
                freed((SV *)keytab);
        }

MODULE = Authen::Krb5   PACKAGE = Authen::Krb5::KeytabEntry

Authen::Krb5::KeytabEntry
new(class, principal, vno, key)
	char *class
	Authen::Krb5::Principal principal
	krb5_kvno vno
        Authen::Krb5::Keyblock key

	CODE:
	if (!New(0, RETVAL, 1, krb5_keytab_entry))
		XSRETURN_UNDEF;
        *RETVAL = keytab_entry_init;
	RETVAL->principal = principal;
	RETVAL->vno = vno;
        RETVAL->key = *key;

        can_free((SV *)RETVAL);
	
	OUTPUT:
	RETVAL

Authen::Krb5::Principal
principal(entry)
	Authen::Krb5::KeytabEntry entry

        CODE:
        err = krb5_copy_principal(context, entry->principal, &RETVAL);
        if (err)
                XSRETURN_UNDEF;
        can_free((SV *)RETVAL);

        OUTPUT:
        RETVAL

krb5_timestamp
timestamp(entry)
	Authen::Krb5::KeytabEntry entry

        CODE:
        RETVAL = entry->timestamp;



( run in 2.420 seconds using v1.01-cache-2.11-cpan-ceb78f64989 )