Blob Blame History Raw
/*********************************************************/
/*  toksvc: a framework-native token broker service      */
/*  Copyright (C) 2020  SysDeer Technologies, LLC        */
/*  Released under GPLv2 and GPLv3; see COPYING.TOKSVC.  */
/*********************************************************/

#include <psxtypes/psxtypes.h>
#include <ntapi/ntapi.h>

#include <toksvc/toksvc.h>
#include "toksvc_daemon_impl.h"
#include "toksvc_driver_impl.h"

static int32_t toks_daemon_client_wait(void * rapunzel)
{
	struct toks_client_ctx * client;

	client = (struct toks_client_ctx *)rapunzel;

	ntapi->zw_set_event(client->hswap,0);

	ntapi->zw_wait_for_single_object(
		client->hprocess,
		NT_SYNC_NON_ALERTABLE,
		0);

	ntapi->zw_close(client->hprocess);
	ntapi->zw_close(client->hport);

	return ntapi->zw_terminate_thread(
		NT_CURRENT_THREAD_HANDLE,
		NT_STATUS_SUCCESS);
}

static int32_t toks_daemon_client_instance(struct toks_client_ctx * client)
{
	int32_t			status;
	nt_thread_params	params;

	if ((status = ntapi->tt_create_private_event(
			&client->hswap,
			NT_NOTIFICATION_EVENT,
			NT_EVENT_NOT_SIGNALED)))
		return status;

	ntapi->tt_aligned_block_memset(
		&params,0,sizeof(params));

	params.hprocess		  = NT_CURRENT_PROCESS_HANDLE;
	params.start		  = toks_daemon_client_wait;
	params.ext_ctx            = client;
	params.ext_ctx_size       = sizeof(*client);
	params.stack_size_commit  = 4 * 1024;
	params.stack_size_reserve = 4 * 1024;
	params.creation_flags	  = NT_CREATE_LOCAL_THREAD;

	if ((status = ntapi->tt_create_thread(&params)))
		return status;

	if ((status = ntapi->zw_wait_for_single_object(
			client->hswap,
			NT_SYNC_NON_ALERTABLE,
			0)))
		return status;

	ntapi->zw_close(client->hswap);

	return ntapi->zw_close(params.hthread);
}

int32_t __stdcall toks_daemon_connect(struct toks_daemon_ctx * dctx)
{
	int32_t                     status;
	nt_tty_port_msg *           msg;
	struct toks_client_ctx      client;
	nt_oa                       oa;

	msg                   = &dctx->reply;
	msg->ttyinfo.opdata   = 0;

	client.hport          = 0;
	client.hprocess       = 0;
	client.hswap          = 0;
	client.cid.process_id = msg->header.client_id.process_id;
	client.cid.thread_id  = 0;

	oa.len      = sizeof(oa);
	oa.root_dir = 0;
	oa.obj_name = 0;
	oa.obj_attr = 0;
	oa.sec_desc = 0;
	oa.sec_qos  = 0;

	status = ntapi->zw_open_process(
		&client.hprocess,
		NT_PROCESS_SYNCHRONIZE | NT_PROCESS_QUERY_INFORMATION,
		&oa,&client.cid);

	status = ntapi->zw_accept_connect_port(
		&client.hport,
		client.cid.process_id,
		&msg->header,
		NT_LPC_ACCEPT_CONNECTION,0,0);

	if (status) {
		ntapi->zw_close(client.hprocess);
		return status;
	}

	ntapi->zw_complete_connect_port(client.hport);

	return toks_daemon_client_instance(&client);
}