#include "quipu/config.h"
#include "isoaddrs.h"

#ifdef KERBEROS

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "quipu/bind.h"
#include "UNIV-types.h"

int extdebug;

encode_kerberos_parms( pe, kp )
PE			*pe;
struct kerberos_parms	*kp;
{
	PE	tmppe = NULLPE;

	*pe = pe_alloc( PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SEQ );

	/* the DN */
	(void) encode_IF_DistinguishedName( &tmppe, 0, 0, NULLCP, kp->kp_dn );
	if ( tmppe == NULLPE )
		return( NOTOK );
	seq_add( *pe, tmppe, -1 );

	/* kerberos version */
	tmppe = num2prim( kp->kp_version, PE_CLASS_UNIV, PE_PRIM_INT );
	if ( tmppe == NULLPE )
		return( NOTOK );
	seq_add( *pe, tmppe, -1 );

	/* checksum + 1 - leave room for encryption */
	tmppe = oct2prim( (char *) &(kp->kp_nonce), 8 );
	if ( tmppe == NULLPE )
		return( NOTOK );
	seq_add( *pe, tmppe, -1 );

	/* kerberos credentials */
	tmppe = oct2prim( (char *) kp->kp_ktxt.dat, kp->kp_ktxt.length );
	if ( tmppe == NULLPE )
		return( NOTOK );
	seq_add( *pe, tmppe, -1 );

	return( OK );
}

decode_kerberos_parms( pe, kp )
PE			pe;
struct kerberos_parms	**kp;
{
	PE	tmppe;
	char	*p;
	int	len;

	*kp = (struct kerberos_parms *)smalloc( sizeof(struct kerberos_parms) );

	/* the DN */
	tmppe = first_member( pe );
	if ( tmppe == NULLPE )
		return( NOTOK );
	if ( decode_IF_DistinguishedName( tmppe, 1, NULLIP, NULLVP,
	    &(*kp)->kp_dn ) == NOTOK )
		return( NOTOK );

	/* kerberos version */
	tmppe = next_member( pe, tmppe );
	if ( tmppe == NULLPE )
		return( NOTOK );
	if ( ((*kp)->kp_version = prim2num( tmppe )) == NOTOK && pe->pe_errno
	    != PE_ERR_NONE )
		return( NOTOK );

	/* checksum + 1 - leave room for encryption */
	tmppe = next_member( pe, tmppe );
	if ( tmppe == NULLPE )
		return( NOTOK );
	if ( (p = prim2str( tmppe, &len )) == NULL || len != 8 )
		return( NOTOK );
	memcpy( (char *) &(*kp)->kp_nonce, p, 8 );
	free( p );

	/* kerberos parameters */
	tmppe = next_member( pe, tmppe );
	if ( tmppe == NULLPE )
		return( NOTOK );
	if ( (p = prim2str( tmppe, &len )) == NULL )
		return( NOTOK );
	memcpy( (char *) (*kp)->kp_ktxt.dat, p, len );
	(*kp)->kp_ktxt.length = len;
	free( p );

	return( OK );
}

char *psap2hostname( pa )
struct PSAPaddr	*pa;
{
	int		naddrs = pa->pa_addr.sa_addr.ta_naddr;
	struct NSAPaddr	*na = pa->pa_addr.sa_addr.ta_addrs;
	unsigned long	addr;
	char		*p;
	struct hostent	*hp;

	if ( na->na_stack != NA_TCP )
		return( NULL );

	if ( (addr = inet_addr( na->na_domain )) == -1 ) {
		hp = gethostbyname( na->na_domain );
	} else {
		hp = gethostbyaddr( (char *) &addr, sizeof(addr), AF_INET );
	}
	if ( hp == NULL )
		return( NULL );

	if ( (p = strchr( hp->h_name, '.' )) != NULL )
		*p = '\0';

	return( hp->h_name );
}

#endif KERBEROS
