|
|
f9f1df |
/*********************************************************/
|
|
|
f9f1df |
/* toksvc: a framework-native token broker service */
|
|
|
d91fa0 |
/* Copyright (C) 2020 SysDeer Technologies, LLC */
|
|
|
f9f1df |
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
|
|
|
f9f1df |
/*********************************************************/
|
|
|
f9f1df |
|
|
|
f9f1df |
#include <pemagine/pemagine.h>
|
|
|
f9f1df |
#include <ntapi/ntapi.h>
|
|
|
f9f1df |
#include <toksvc/toksvc.h>
|
|
|
f9f1df |
#include "toksvc_init_impl.h"
|
|
|
f9f1df |
#include "toksvc_driver_impl.h"
|
|
|
f9f1df |
|
|
|
f9f1df |
static const nt_guid toksvc_daemon_guid = TOKS_PORT_GUID_DAEMON;
|
|
|
f9f1df |
|
|
|
f9f1df |
static void toksvc_exit(int code)
|
|
|
f9f1df |
{
|
|
|
618937 |
/* server mode? */
|
|
|
618937 |
if (code == NT_STATUS_SERVICE_NOTIFICATION)
|
|
|
618937 |
ntapi->zw_terminate_thread(
|
|
|
618937 |
NT_CURRENT_THREAD_HANDLE,
|
|
|
618937 |
code);
|
|
|
618937 |
|
|
|
f9f1df |
/* posix exit code? */
|
|
|
f9f1df |
if ((code >= 0) && (code <= 0xff))
|
|
|
f9f1df |
code <<= 8;
|
|
|
f9f1df |
|
|
|
f9f1df |
ntapi->zw_terminate_process(
|
|
|
f9f1df |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
f9f1df |
code);
|
|
|
f9f1df |
}
|
|
|
f9f1df |
|
|
|
f9f1df |
static int toksvc_dbg_helper(int32_t status)
|
|
|
f9f1df |
{
|
|
|
f9f1df |
return status ? -1 : 0;
|
|
|
f9f1df |
}
|
|
|
f9f1df |
|
|
|
f9f1df |
static int toksvc_dbg_init(char ** argv)
|
|
|
f9f1df |
{
|
|
|
f9f1df |
if (argv[1] && !(ntapi->tt_strcmp_multibyte(argv[1],"--wait")))
|
|
|
f9f1df |
return toksvc_dbg_helper(
|
|
|
f9f1df |
ntapi->tt_wait_for_dummy_event());
|
|
|
f9f1df |
return 0;
|
|
|
f9f1df |
}
|
|
|
f9f1df |
|
|
|
f9f1df |
static int32_t toksvc_start(char ** argv, char ** envp)
|
|
|
f9f1df |
{
|
|
|
f9f1df |
int32_t status;
|
|
|
f9f1df |
nt_runtime_data * rtdata;
|
|
|
f9f1df |
nt_port_attr port_attr;
|
|
|
f9f1df |
nt_pty_client_info client_info;
|
|
|
f9f1df |
nt_iosb iosb;
|
|
|
0651e1 |
nt_sd_common_buffer sd;
|
|
|
f9f1df |
|
|
|
f9f1df |
/* rtdata */
|
|
|
f9f1df |
if ((status = ntapi->tt_get_runtime_data(&rtdata,0)))
|
|
|
f9f1df |
return status;
|
|
|
f9f1df |
|
|
|
f9f1df |
if (rtdata->argv) {
|
|
|
f9f1df |
argv = rtdata->argv;
|
|
|
f9f1df |
envp = rtdata->envp;
|
|
|
f9f1df |
}
|
|
|
f9f1df |
|
|
|
0651e1 |
/* process sd */
|
|
|
0651e1 |
ntapi->acl_init_common_descriptor(
|
|
|
0651e1 |
&sd,0,0,0,0,
|
|
|
0651e1 |
NT_PROCESS_ALL_ACCESS,0,
|
|
|
0651e1 |
NT_PROCESS_SYNCHRONIZE | NT_SEC_READ_CONTROL,0,
|
|
|
0651e1 |
NT_PROCESS_SYNCHRONIZE | NT_SEC_READ_CONTROL,
|
|
|
0651e1 |
0);
|
|
|
0651e1 |
|
|
|
0651e1 |
if ((status = ntapi->zw_set_security_object(
|
|
|
0651e1 |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
0651e1 |
NT_OWNER_SECURITY_INFORMATION
|
|
|
0651e1 |
| NT_DACL_SECURITY_INFORMATION,
|
|
|
0651e1 |
&sd.sd)))
|
|
|
0651e1 |
return status;
|
|
|
0651e1 |
|
|
|
f9f1df |
/* early debug (optional) */
|
|
|
f9f1df |
toksvc_dbg_init(argv);
|
|
|
f9f1df |
|
|
|
f9f1df |
/* daemon */
|
|
|
f9f1df |
if (!(ntapi->tt_guid_compare(
|
|
|
f9f1df |
&rtdata->srv_guid,
|
|
|
f9f1df |
&(nt_guid)NT_PORT_GUID_DEFAULT)))
|
|
|
f9f1df |
ntapi->tt_guid_copy(
|
|
|
f9f1df |
&rtdata->srv_guid,
|
|
|
f9f1df |
&toksvc_daemon_guid);
|
|
|
f9f1df |
|
|
|
f9f1df |
/* no tty session? */
|
|
|
32933a |
if (!rtdata->tty_keys[0]) {
|
|
|
32933a |
if (rtdata->hready)
|
|
|
32933a |
if ((status = ntapi->zw_set_event(rtdata->hready,0)))
|
|
|
32933a |
return status;
|
|
|
32933a |
|
|
|
f9f1df |
return toks_main(argv,envp);
|
|
|
32933a |
}
|
|
|
f9f1df |
|
|
|
f9f1df |
/* tty */
|
|
|
f9f1df |
ntapi->tt_aligned_block_memset(
|
|
|
f9f1df |
&port_attr,0,sizeof(port_attr));
|
|
|
f9f1df |
|
|
|
f9f1df |
port_attr.type = NT_PORT_TYPE_SUBSYSTEM;
|
|
|
f9f1df |
port_attr.subtype = NT_PORT_SUBTYPE_DEFAULT;
|
|
|
f9f1df |
|
|
|
f9f1df |
port_attr.keys.key[0] = rtdata->tty_keys[0];
|
|
|
f9f1df |
port_attr.keys.key[1] = rtdata->tty_keys[1];
|
|
|
f9f1df |
port_attr.keys.key[2] = rtdata->tty_keys[2];
|
|
|
f9f1df |
port_attr.keys.key[3] = rtdata->tty_keys[3];
|
|
|
f9f1df |
port_attr.keys.key[4] = rtdata->tty_keys[4];
|
|
|
f9f1df |
port_attr.keys.key[5] = rtdata->tty_keys[5];
|
|
|
f9f1df |
|
|
|
f9f1df |
ntapi->tt_guid_copy(
|
|
|
f9f1df |
&port_attr.guid,
|
|
|
f9f1df |
&rtdata->tty_guid);
|
|
|
f9f1df |
|
|
|
f9f1df |
if ((status = ntapi->tty_join_session(
|
|
|
f9f1df |
&rtdata->hsession,0,
|
|
|
f9f1df |
&port_attr,
|
|
|
f9f1df |
NT_TTY_SESSION_PRIMARY)))
|
|
|
f9f1df |
return status;
|
|
|
f9f1df |
|
|
|
f9f1df |
/* pty */
|
|
|
f9f1df |
if ((status = ntapi->pty_inherit_runtime_ctty(
|
|
|
f9f1df |
rtdata->hsession,
|
|
|
f9f1df |
rtdata)))
|
|
|
f9f1df |
return status;
|
|
|
f9f1df |
|
|
|
f9f1df |
/* ctty identification */
|
|
|
f9f1df |
if (rtdata->hctty) {
|
|
|
f9f1df |
client_info.any[0] = 0;
|
|
|
f9f1df |
client_info.any[1] = 0;
|
|
|
f9f1df |
client_info.any[2] = 0;
|
|
|
f9f1df |
client_info.any[3] = 0;
|
|
|
f9f1df |
|
|
|
f9f1df |
if ((status = ntapi->pty_set(
|
|
|
f9f1df |
rtdata->hctty,&iosb,
|
|
|
f9f1df |
&client_info,sizeof(client_info),
|
|
|
f9f1df |
NT_PTY_CLIENT_INFORMATION)))
|
|
|
f9f1df |
return status;
|
|
|
f9f1df |
}
|
|
|
f9f1df |
|
|
|
f9f1df |
/* ready */
|
|
|
f9f1df |
if (rtdata->hready)
|
|
|
f9f1df |
if ((status = ntapi->zw_set_event(rtdata->hready,0)))
|
|
|
f9f1df |
return status;
|
|
|
f9f1df |
|
|
|
f9f1df |
/* main */
|
|
|
f9f1df |
return toks_main(argv,envp);
|
|
|
f9f1df |
}
|
|
|
f9f1df |
|
|
|
f9f1df |
static int __stdcall toksvc_daemon_entry_point(void * hswap)
|
|
|
f9f1df |
{
|
|
|
f9f1df |
int32_t status;
|
|
|
f9f1df |
int argc;
|
|
|
f9f1df |
char ** argv;
|
|
|
f9f1df |
char ** envp;
|
|
|
f9f1df |
|
|
|
f9f1df |
ntapi->zw_set_event(hswap,0);
|
|
|
f9f1df |
ntapi->zw_close(hswap);
|
|
|
f9f1df |
|
|
|
f9f1df |
if ((status = ntapi->tt_get_argv_envp_utf8(
|
|
|
f9f1df |
&argc,&argv,&envp,
|
|
|
f9f1df |
0,0,0)))
|
|
|
f9f1df |
toksvc_exit(status);
|
|
|
f9f1df |
|
|
|
f9f1df |
toksvc_exit(toksvc_start(argv,envp));
|
|
|
f9f1df |
|
|
|
f9f1df |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
f9f1df |
}
|
|
|
f9f1df |
|
|
|
f9f1df |
int toksvc_entry_point(void)
|
|
|
f9f1df |
{
|
|
|
f9f1df |
int32_t status;
|
|
|
f9f1df |
nt_thread_params params;
|
|
|
f9f1df |
void * hswap;
|
|
|
f9f1df |
|
|
|
f9f1df |
if ((status = toks_init()))
|
|
|
f9f1df |
return status;
|
|
|
f9f1df |
|
|
|
f9f1df |
if ((status = ntapi->tt_create_private_event(
|
|
|
f9f1df |
&hswap,
|
|
|
f9f1df |
NT_NOTIFICATION_EVENT,
|
|
|
f9f1df |
NT_EVENT_NOT_SIGNALED)))
|
|
|
f9f1df |
return status;
|
|
|
f9f1df |
|
|
|
f9f1df |
ntapi->tt_aligned_block_memset(
|
|
|
f9f1df |
¶ms,0,sizeof(params));
|
|
|
f9f1df |
|
|
|
f9f1df |
params.hprocess = NT_CURRENT_PROCESS_HANDLE;
|
|
|
f9f1df |
params.start = toksvc_daemon_entry_point;
|
|
|
f9f1df |
params.arg = hswap;
|
|
|
f9f1df |
params.stack_size_commit = 128 * 1024;
|
|
|
f9f1df |
params.stack_size_reserve = 128 * 1024;
|
|
|
f9f1df |
params.creation_flags = NT_CREATE_LOCAL_THREAD;
|
|
|
f9f1df |
|
|
|
f9f1df |
if ((status = ntapi->tt_create_thread(¶ms)))
|
|
|
f9f1df |
toksvc_exit(status);
|
|
|
f9f1df |
|
|
|
f9f1df |
ntapi->zw_wait_for_single_object(
|
|
|
f9f1df |
hswap,NT_SYNC_NON_ALERTABLE,0);
|
|
|
f9f1df |
|
|
|
f9f1df |
ntapi->zw_close(
|
|
|
f9f1df |
params.hthread);
|
|
|
f9f1df |
|
|
|
f9f1df |
ntapi->zw_terminate_thread(
|
|
|
f9f1df |
NT_CURRENT_THREAD_HANDLE,
|
|
|
f9f1df |
NT_STATUS_SUCCESS);
|
|
|
f9f1df |
|
|
|
f9f1df |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
f9f1df |
}
|