/* Module auth */

#define EXPORT_BOOLEAN
#include <mach/boolean.h>
#include <mach/kern_return.h>
#include <mach/message.h>
#include <mach/mig_errors.h>

#ifndef	mig_internal
#define	mig_internal	static
#endif

#ifndef	mig_external
#define mig_external
#endif

#ifndef	TypeCheck
#define	TypeCheck 1
#endif

#ifndef	UseExternRCSId
#ifdef	hc
#define	UseExternRCSId		1
#endif
#endif

#ifndef	UseStaticMsgType
#if	!defined(hc) || defined(__STDC__)
#define	UseStaticMsgType	1
#endif
#endif

/* Due to pcc compiler bug, cannot use void */
#if	(defined(__STDC__) || defined(c_plusplus)) || defined(hc)
#define novalue void
#else
#define novalue int
#endif

#define msgh_request_port	msgh_local_port
#define MACH_MSGH_BITS_REQUEST(bits)	MACH_MSGH_BITS_LOCAL(bits)
#define msgh_reply_port		msgh_remote_port
#define MACH_MSGH_BITS_REPLY(bits)	MACH_MSGH_BITS_REMOTE(bits)

#include <mach/std_types.h>
#include <mach/mach_types.h>
#include <device/device_types.h>
#include <device/net_status.h>
#include <gnu/types.h>
#include <hurd/hurd_types.h>
#include <lib/libhurd.h>
#include "auth_mig.h"

/* Routine auth_getids */
mig_internal novalue _Xauth_getids
#if	(defined(__STDC__) || defined(c_plusplus))
	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
#else
	(InHeadP, OutHeadP)
	mach_msg_header_t *InHeadP, *OutHeadP;
#endif
{
	typedef struct {
		mach_msg_header_t Head;
	} Request;

	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t RetCodeType;
		kern_return_t RetCode;
		mach_msg_type_t idType;
		idblock_t id;
	} Reply;

	register Request *In0P = (Request *) InHeadP;
	register Reply *OutP = (Reply *) OutHeadP;
	mig_external kern_return_t auth_getids
#if	(defined(__STDC__) || defined(c_plusplus))
		(idblockptr_t handle, idblock_t *id);
#else
		();
#endif

	boolean_t msgh_simple;

	unsigned int msgh_size;

#if	UseStaticMsgType
	static mach_msg_type_t idType = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_16,
		/* msgt_size = */		16,
		/* msgt_number = */		256,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	TypeCheck
	msgh_size = In0P->Head.msgh_size;
	msgh_simple = !(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
	if ((msgh_size != 24) || !msgh_simple)
		{ OutP->RetCode = MIG_BAD_ARGUMENTS; return; }
#endif	TypeCheck

	OutP->RetCode = auth_getids(convert_auth_to_idblock(In0P->Head.msgh_request_port), &OutP->id);
	if (OutP->RetCode != KERN_SUCCESS)
		return;

	msgh_simple = TRUE;
	msgh_size = 548;

#if	UseStaticMsgType
	OutP->idType = idType;
#else	UseStaticMsgType
	OutP->idType.msgt_name = MACH_MSG_TYPE_INTEGER_16;
	OutP->idType.msgt_size = 16;
	OutP->idType.msgt_number = 256;
	OutP->idType.msgt_inline = TRUE;
	OutP->idType.msgt_longform = FALSE;
	OutP->idType.msgt_deallocate = FALSE;
	OutP->idType.msgt_unused = 0;
#endif	UseStaticMsgType

	if (!msgh_simple)
		OutP->Head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
	OutP->Head.msgh_size = msgh_size;
}

/* Routine auth_makeauth */
mig_internal novalue _Xauth_makeauth
#if	(defined(__STDC__) || defined(c_plusplus))
	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
#else
	(InHeadP, OutHeadP)
	mach_msg_header_t *InHeadP, *OutHeadP;
#endif
{
	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t idType;
		idblock_t id;
	} Request;

	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t RetCodeType;
		kern_return_t RetCode;
		mach_msg_type_t newhandleType;
		mach_port_t newhandle;
	} Reply;

	register Request *In0P = (Request *) InHeadP;
	register Reply *OutP = (Reply *) OutHeadP;
	mig_external kern_return_t auth_makeauth
#if	(defined(__STDC__) || defined(c_plusplus))
		(idblockptr_t handle, idblock_t id, mach_port_t *newhandle);
#else
		();
#endif

	boolean_t msgh_simple;

	unsigned int msgh_size;

#if	UseStaticMsgType
	static mach_msg_type_t idCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_16,
		/* msgt_size = */		16,
		/* msgt_number = */		256,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t newhandleType = {
		/* msgt_name = */		MACH_MSG_TYPE_MAKE_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	TypeCheck
	msgh_size = In0P->Head.msgh_size;
	msgh_simple = !(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
	if ((msgh_size != 540) || !msgh_simple)
		{ OutP->RetCode = MIG_BAD_ARGUMENTS; return; }
#endif	TypeCheck

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &In0P->idType != * (int *) &idCheck)
#else	UseStaticMsgType
	if ((In0P->idType.msgt_inline != TRUE) ||
	    (In0P->idType.msgt_longform != FALSE) ||
	    (In0P->idType.msgt_name != MACH_MSG_TYPE_INTEGER_16) ||
	    (In0P->idType.msgt_number != 256) ||
	    (In0P->idType.msgt_size != 16))
#endif	UseStaticMsgType
		{ OutP->RetCode = MIG_BAD_ARGUMENTS; return; }
#endif	TypeCheck

	OutP->RetCode = auth_makeauth(convert_auth_to_idblock(In0P->Head.msgh_request_port), In0P->id, &OutP->newhandle);
	if (OutP->RetCode != KERN_SUCCESS)
		return;

	msgh_simple = FALSE;
	msgh_size = 40;

#if	UseStaticMsgType
	OutP->newhandleType = newhandleType;
#else	UseStaticMsgType
	OutP->newhandleType.msgt_name = MACH_MSG_TYPE_MAKE_SEND;
	OutP->newhandleType.msgt_size = 32;
	OutP->newhandleType.msgt_number = 1;
	OutP->newhandleType.msgt_inline = TRUE;
	OutP->newhandleType.msgt_longform = FALSE;
	OutP->newhandleType.msgt_deallocate = FALSE;
	OutP->newhandleType.msgt_unused = 0;
#endif	UseStaticMsgType

	if (!msgh_simple)
		OutP->Head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
	OutP->Head.msgh_size = msgh_size;
}

/* Routine auth_user_authenticate */
mig_internal novalue _Xauth_user_authenticate
#if	(defined(__STDC__) || defined(c_plusplus))
	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
#else
	(InHeadP, OutHeadP)
	mach_msg_header_t *InHeadP, *OutHeadP;
#endif
{
	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t rendezvousType;
		mach_port_t rendezvous;
	} Request;

	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t RetCodeType;
		kern_return_t RetCode;
		mach_msg_type_t newportType;
		mach_port_t newport;
	} Reply;

	register Request *In0P = (Request *) InHeadP;
	register Reply *OutP = (Reply *) OutHeadP;
	mig_external kern_return_t auth_user_authenticate
#if	(defined(__STDC__) || defined(c_plusplus))
		(idblockptr_t handle, mach_port_t reply_port, mach_msg_type_name_t reply_portPoly, mach_port_t rendezvous, mach_port_t *newport);
#else
		();
#endif

	boolean_t msgh_simple;

	unsigned int msgh_size;

#if	UseStaticMsgType
	static mach_msg_type_t rendezvousCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_PORT_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t newportType = {
		/* msgt_name = */		MACH_MSG_TYPE_COPY_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	TypeCheck
	msgh_size = In0P->Head.msgh_size;
	msgh_simple = !(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
	if ((msgh_size != 32) || msgh_simple)
		{ OutP->RetCode = MIG_BAD_ARGUMENTS; return; }
#endif	TypeCheck

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &In0P->rendezvousType != * (int *) &rendezvousCheck)
#else	UseStaticMsgType
	if ((In0P->rendezvousType.msgt_inline != TRUE) ||
	    (In0P->rendezvousType.msgt_longform != FALSE) ||
	    (In0P->rendezvousType.msgt_name != MACH_MSG_TYPE_PORT_SEND) ||
	    (In0P->rendezvousType.msgt_number != 1) ||
	    (In0P->rendezvousType.msgt_size != 32))
#endif	UseStaticMsgType
		{ OutP->RetCode = MIG_BAD_ARGUMENTS; return; }
#endif	TypeCheck

	OutP->RetCode = auth_user_authenticate(convert_auth_to_idblock(In0P->Head.msgh_request_port), In0P->Head.msgh_reply_port, MACH_MSGH_BITS_REPLY(In0P->Head.msgh_bits), In0P->rendezvous, &OutP->newport);
	if (OutP->RetCode != KERN_SUCCESS)
		return;

	msgh_simple = FALSE;
	msgh_size = 40;

#if	UseStaticMsgType
	OutP->newportType = newportType;
#else	UseStaticMsgType
	OutP->newportType.msgt_name = MACH_MSG_TYPE_COPY_SEND;
	OutP->newportType.msgt_size = 32;
	OutP->newportType.msgt_number = 1;
	OutP->newportType.msgt_inline = TRUE;
	OutP->newportType.msgt_longform = FALSE;
	OutP->newportType.msgt_deallocate = FALSE;
	OutP->newportType.msgt_unused = 0;
#endif	UseStaticMsgType

	if (!msgh_simple)
		OutP->Head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
	OutP->Head.msgh_size = msgh_size;
}

/* Routine auth_server_authenticate */
mig_internal novalue _Xauth_server_authenticate
#if	(defined(__STDC__) || defined(c_plusplus))
	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
#else
	(InHeadP, OutHeadP)
	mach_msg_header_t *InHeadP, *OutHeadP;
#endif
{
	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t rendezvousType;
		mach_port_t rendezvous;
		mach_msg_type_t newportType;
		mach_port_t newport;
	} Request;

	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t RetCodeType;
		kern_return_t RetCode;
		mach_msg_type_t idType;
		idblock_t id;
	} Reply;

	register Request *In0P = (Request *) InHeadP;
	register Reply *OutP = (Reply *) OutHeadP;
	mig_external kern_return_t auth_server_authenticate
#if	(defined(__STDC__) || defined(c_plusplus))
		(idblockptr_t handle, mach_port_t reply_port, mach_msg_type_name_t reply_portPoly, mach_port_t rendezvous, mach_port_t newport, idblock_t *id);
#else
		();
#endif

	boolean_t msgh_simple;

	unsigned int msgh_size;

#if	UseStaticMsgType
	static mach_msg_type_t rendezvousCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_PORT_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t newportCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_PORT_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t idType = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_16,
		/* msgt_size = */		16,
		/* msgt_number = */		256,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	TypeCheck
	msgh_size = In0P->Head.msgh_size;
	msgh_simple = !(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
	if ((msgh_size != 40) || msgh_simple)
		{ OutP->RetCode = MIG_BAD_ARGUMENTS; return; }
#endif	TypeCheck

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &In0P->rendezvousType != * (int *) &rendezvousCheck)
#else	UseStaticMsgType
	if ((In0P->rendezvousType.msgt_inline != TRUE) ||
	    (In0P->rendezvousType.msgt_longform != FALSE) ||
	    (In0P->rendezvousType.msgt_name != MACH_MSG_TYPE_PORT_SEND) ||
	    (In0P->rendezvousType.msgt_number != 1) ||
	    (In0P->rendezvousType.msgt_size != 32))
#endif	UseStaticMsgType
		{ OutP->RetCode = MIG_BAD_ARGUMENTS; return; }
#endif	TypeCheck

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &In0P->newportType != * (int *) &newportCheck)
#else	UseStaticMsgType
	if ((In0P->newportType.msgt_inline != TRUE) ||
	    (In0P->newportType.msgt_longform != FALSE) ||
	    (In0P->newportType.msgt_name != MACH_MSG_TYPE_PORT_SEND) ||
	    (In0P->newportType.msgt_number != 1) ||
	    (In0P->newportType.msgt_size != 32))
#endif	UseStaticMsgType
		{ OutP->RetCode = MIG_BAD_ARGUMENTS; return; }
#endif	TypeCheck

	OutP->RetCode = auth_server_authenticate(convert_auth_to_idblock(In0P->Head.msgh_request_port), In0P->Head.msgh_reply_port, MACH_MSGH_BITS_REPLY(In0P->Head.msgh_bits), In0P->rendezvous, In0P->newport, &OutP->id);
	if (OutP->RetCode != KERN_SUCCESS)
		return;

	msgh_simple = TRUE;
	msgh_size = 548;

#if	UseStaticMsgType
	OutP->idType = idType;
#else	UseStaticMsgType
	OutP->idType.msgt_name = MACH_MSG_TYPE_INTEGER_16;
	OutP->idType.msgt_size = 16;
	OutP->idType.msgt_number = 256;
	OutP->idType.msgt_inline = TRUE;
	OutP->idType.msgt_longform = FALSE;
	OutP->idType.msgt_deallocate = FALSE;
	OutP->idType.msgt_unused = 0;
#endif	UseStaticMsgType

	if (!msgh_simple)
		OutP->Head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
	OutP->Head.msgh_size = msgh_size;
}

mig_external boolean_t auth_server
#if	(defined(__STDC__) || defined(c_plusplus))
	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
#else
	(InHeadP, OutHeadP)
	mach_msg_header_t *InHeadP, *OutHeadP;
#endif
{
	register mach_msg_header_t *InP =  InHeadP;
	register mig_reply_header_t *OutP = (mig_reply_header_t *) OutHeadP;

#if	UseStaticMsgType
	static mach_msg_type_t RetCodeType = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_32,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

	OutP->Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InP->msgh_bits), 0);
	OutP->Head.msgh_size = sizeof *OutP;
	OutP->Head.msgh_remote_port = InP->msgh_reply_port;
	OutP->Head.msgh_local_port = MACH_PORT_NULL;
	OutP->Head.msgh_kind = InP->msgh_kind;
	OutP->Head.msgh_id = InP->msgh_id + 100;

#if	UseStaticMsgType
	OutP->RetCodeType = RetCodeType;
#else	UseStaticMsgType
	OutP->RetCodeType.msgt_name = MACH_MSG_TYPE_INTEGER_32;
	OutP->RetCodeType.msgt_size = 32;
	OutP->RetCodeType.msgt_number = 1;
	OutP->RetCodeType.msgt_inline = TRUE;
	OutP->RetCodeType.msgt_longform = FALSE;
	OutP->RetCodeType.msgt_deallocate = FALSE;
	OutP->RetCodeType.msgt_unused = 0;
#endif	UseStaticMsgType
	OutP->RetCode = MIG_BAD_ID;

	if ((InP->msgh_id > 25003) || (InP->msgh_id < 25000))
		return FALSE;
	else {
		typedef novalue (*SERVER_STUB_PROC)
#if	(defined(__STDC__) || defined(c_plusplus))
			(mach_msg_header_t *, mach_msg_header_t *);
#else
			();
#endif
		static SERVER_STUB_PROC routines[] = {
			_Xauth_getids,
			_Xauth_makeauth,
			_Xauth_user_authenticate,
			_Xauth_server_authenticate,
		};

		if (routines[InP->msgh_id - 25000])
			(routines[InP->msgh_id - 25000]) (InP, &OutP->Head);
		 else
			return FALSE;
	}
	return TRUE;
}
