|
|
1a07be |
/*********************************************************/
|
|
|
1a07be |
/* toksvc: a framework-native token broker service */
|
|
|
d91fa0 |
/* Copyright (C) 2020 SysDeer Technologies, LLC */
|
|
|
1a07be |
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
|
|
|
1a07be |
/*********************************************************/
|
|
|
1a07be |
|
|
|
1a07be |
#include <psxtypes/psxtypes.h>
|
|
|
1a07be |
#include <ntapi/ntapi.h>
|
|
|
1a07be |
|
|
|
1a07be |
#include <toksvc/toksvc.h>
|
|
|
1a07be |
#include "toksvc_driver_impl.h"
|
|
|
1a07be |
#include "toksvc_daemon_impl.h"
|
|
|
1a07be |
|
|
|
b59b0a |
#define TOKS_STR(x) #x
|
|
|
b59b0a |
#define TOKS_XSTR(x) TOKS_STR(x)
|
|
|
b59b0a |
|
|
|
b59b0a |
static char toks_service_image[] = TOKS_XSTR(TOKS_SERVICE_IMAGE);
|
|
|
1a07be |
|
|
|
1a07be |
static int32_t toks_spawn_child_exit_code(void * hprocess)
|
|
|
1a07be |
{
|
|
|
1a07be |
nt_process_basic_information pbi;
|
|
|
1a07be |
|
|
|
1a07be |
if (ntapi->zw_query_information_process(
|
|
|
1a07be |
hprocess,
|
|
|
1a07be |
NT_PROCESS_BASIC_INFORMATION,
|
|
|
1a07be |
&pbi,sizeof(pbi),
|
|
|
1a07be |
&(uint32_t){0}))
|
|
|
1a07be |
return NT_STATUS_GENERIC_COMMAND_FAILED;
|
|
|
1a07be |
|
|
|
1a07be |
return pbi.exit_status;
|
|
|
1a07be |
}
|
|
|
1a07be |
|
|
|
1a07be |
static int toks_spawn_impl(
|
|
|
1a07be |
struct toks_driver_ctx * dctx,
|
|
|
1a07be |
struct toks_common_ctx * cctx,
|
|
|
1a07be |
int ntokens,
|
|
|
1a07be |
int32_t ctrlpid,
|
|
|
1a07be |
int32_t csyspid)
|
|
|
1a07be |
{
|
|
|
1a07be |
int32_t status;
|
|
|
1a07be |
nt_spawn_process_params sparams;
|
|
|
1a07be |
nt_runtime_data rtctx;
|
|
|
1a07be |
nt_rtdata * self;
|
|
|
1a07be |
char * img;
|
|
|
1a07be |
void * hroot;
|
|
|
1a07be |
void * hlog;
|
|
|
1a07be |
const char * logfile;
|
|
|
1a07be |
char ** pearg;
|
|
|
1a07be |
char * eargv[10];
|
|
|
1a07be |
char tokbuf[32];
|
|
|
1a07be |
char pidbuf[32];
|
|
|
cd7e30 |
char logbuf[32];
|
|
|
2c8e4f |
char guidstr[40];
|
|
|
8cf1b0 |
void * hduo[2];
|
|
|
1a07be |
|
|
|
1a07be |
/* init */
|
|
|
1a07be |
self = toks_get_driver_rtdata(dctx);
|
|
|
1a07be |
img = toks_service_image;
|
|
|
1a07be |
|
|
|
1a07be |
if (!(hroot = cctx->hroot) && cctx->sysroot)
|
|
|
1a07be |
if ((status = toks_open_dir(&hroot,0,cctx->sysroot,false)))
|
|
|
1a07be |
return status;
|
|
|
1a07be |
|
|
|
1a07be |
if (hroot && (img[0] == '/'))
|
|
|
1a07be |
img++;
|
|
|
1a07be |
|
|
|
1a07be |
logfile = cctx->logfile;
|
|
|
1a07be |
|
|
|
1a07be |
if (hroot && logfile && (logfile[0] == '/'))
|
|
|
1a07be |
logfile++;
|
|
|
1a07be |
|
|
|
1a07be |
if (logfile && (status = toks_open_log_file(&hlog,hroot,logfile,false)))
|
|
|
1a07be |
return status;
|
|
|
1a07be |
|
|
|
1a07be |
/* eargv */
|
|
|
1a07be |
pearg = eargv;
|
|
|
1a07be |
*pearg++ = img;
|
|
|
1a07be |
|
|
|
1a07be |
ntapi->sprintf(tokbuf,"%d",ntokens);
|
|
|
1a07be |
*pearg++ = "-t";
|
|
|
1a07be |
*pearg++ = tokbuf;
|
|
|
1a07be |
|
|
|
cd7e30 |
ntapi->sprintf(logbuf,"%d",cctx->loglevel);
|
|
|
cd7e30 |
*pearg++ = "-O";
|
|
|
cd7e30 |
*pearg++ = logbuf;
|
|
|
cd7e30 |
|
|
|
2c8e4f |
if (cctx->uuid) {
|
|
|
0021e3 |
toks_uuid_to_string(cctx->uuid,&guidstr);
|
|
|
2c8e4f |
*pearg++ = "-u";
|
|
|
2c8e4f |
*pearg++ = guidstr;
|
|
|
2c8e4f |
}
|
|
|
2c8e4f |
|
|
|
1a07be |
if (ctrlpid) {
|
|
|
1a07be |
ntapi->sprintf(pidbuf,"%d",ctrlpid);
|
|
|
52fec3 |
*pearg++ = "-l";
|
|
|
1a07be |
*pearg++ = pidbuf;
|
|
|
1a07be |
} else if (csyspid) {
|
|
|
1a07be |
ntapi->sprintf(pidbuf,"%d",csyspid);
|
|
|
52fec3 |
*pearg++ = "-L";
|
|
|
1a07be |
*pearg++ = pidbuf;
|
|
|
1a07be |
}
|
|
|
1a07be |
|
|
|
1a07be |
*pearg++ = 0;
|
|
|
1a07be |
|
|
|
1a07be |
/* sparams */
|
|
|
1a07be |
ntapi->tt_aligned_block_memset(
|
|
|
1a07be |
&sparams,0,sizeof(sparams));
|
|
|
1a07be |
|
|
|
1a07be |
sparams.rtctx = &rtctx;
|
|
|
1a07be |
sparams.patharg = img;
|
|
|
1a07be |
sparams.argv = eargv;
|
|
|
1a07be |
sparams.envp = self->envp;
|
|
|
1a07be |
sparams.hroot = hroot ? hroot : self->hroot;
|
|
|
1a07be |
|
|
|
1a07be |
if ((status = toks_open_file(&sparams.himage,hroot,img,true)))
|
|
|
1a07be |
return status;
|
|
|
1a07be |
|
|
|
1a07be |
/* rtctx */
|
|
|
1a07be |
ntapi->tt_aligned_block_memset(
|
|
|
1a07be |
&rtctx,0,sizeof(rtctx));
|
|
|
1a07be |
|
|
|
1a07be |
ntapi->tt_aligned_block_memcpy(
|
|
|
1a07be |
(uintptr_t *)&rtctx.cid_parent,
|
|
|
1a07be |
(uintptr_t *)&self->cid_self,
|
|
|
1a07be |
sizeof(nt_cid));
|
|
|
1a07be |
|
|
|
1a07be |
rtctx.hlog = hlog;
|
|
|
1a07be |
rtctx.hcwd = self->hcwd;
|
|
|
1a07be |
rtctx.hroot = sparams.hroot;
|
|
|
1a07be |
rtctx.flags = self->flags | NT_RUNTIME_DATA_TTY_TOP_LEVEL;
|
|
|
1a07be |
|
|
|
1a07be |
rtctx.dbg_level = 0;
|
|
|
1a07be |
rtctx.log_level = self->log_level;
|
|
|
1a07be |
|
|
|
1a07be |
rtctx.hstdin = NT_INVALID_HANDLE_VALUE;
|
|
|
1a07be |
rtctx.hstdout = NT_INVALID_HANDLE_VALUE;
|
|
|
1a07be |
rtctx.hstderr = NT_INVALID_HANDLE_VALUE;
|
|
|
1a07be |
|
|
|
1a07be |
rtctx.stdin_type = NT_FILE_TYPE_UNKNOWN;
|
|
|
1a07be |
rtctx.stdout_type = NT_FILE_TYPE_UNKNOWN;
|
|
|
1a07be |
rtctx.stderr_type = NT_FILE_TYPE_UNKNOWN;
|
|
|
1a07be |
|
|
|
8cf1b0 |
/* service synchronization */
|
|
|
8cf1b0 |
if ((status = ntapi->tt_create_inheritable_event(
|
|
|
8cf1b0 |
&rtctx.hsync,
|
|
|
8cf1b0 |
NT_NOTIFICATION_EVENT,
|
|
|
8cf1b0 |
NT_EVENT_NOT_SIGNALED)))
|
|
|
8cf1b0 |
return status;
|
|
|
8cf1b0 |
|
|
|
1a07be |
/* hoppla */
|
|
|
1a07be |
status = ntapi->tt_spawn_native_process(&sparams);
|
|
|
1a07be |
|
|
|
1a07be |
if (sparams.himage)
|
|
|
1a07be |
ntapi->zw_close(sparams.himage);
|
|
|
1a07be |
|
|
|
1a07be |
if (status)
|
|
|
1a07be |
return status;
|
|
|
1a07be |
|
|
|
1a07be |
/* child ready? */
|
|
|
1a07be |
if (!(sparams.eready.signal_state))
|
|
|
1a07be |
status = toks_spawn_child_exit_code(sparams.hprocess);
|
|
|
1a07be |
|
|
|
8cf1b0 |
/* service synchronization */
|
|
|
8cf1b0 |
hduo[0] = sparams.hprocess;
|
|
|
8cf1b0 |
hduo[1] = rtctx.hsync;
|
|
|
8cf1b0 |
|
|
|
8cf1b0 |
ntapi->zw_wait_for_multiple_objects(
|
|
|
8cf1b0 |
2,hduo,
|
|
|
8cf1b0 |
NT_WAIT_ANY,
|
|
|
8cf1b0 |
NT_SYNC_NON_ALERTABLE,
|
|
|
8cf1b0 |
0);
|
|
|
8cf1b0 |
|
|
|
1a07be |
/* finalize */
|
|
|
1a07be |
ntapi->zw_close(sparams.hprocess);
|
|
|
1a07be |
ntapi->zw_close(sparams.hthread);
|
|
|
1a07be |
|
|
|
1a07be |
/* all done */
|
|
|
1a07be |
return status;
|
|
|
1a07be |
}
|
|
|
1a07be |
|
|
|
1a07be |
int32_t toks_service_start(
|
|
|
1a07be |
struct toks_common_ctx * cctx,
|
|
|
1a07be |
int ntokens,
|
|
|
1a07be |
int32_t ctrlpid,
|
|
|
1a07be |
int32_t csyspid)
|
|
|
1a07be |
{
|
|
|
1a07be |
int32_t status;
|
|
|
1a07be |
struct toks_driver_ctx * dctx;
|
|
|
1a07be |
char * eargv[2];
|
|
|
1a07be |
|
|
|
1a07be |
eargv[0] = "toksvc.driver";
|
|
|
1a07be |
eargv[1] = 0;
|
|
|
1a07be |
|
|
|
1a07be |
status = toks_get_driver_ctx(eargv,0,TOKS_DRIVER_VERSION,&dctx);
|
|
|
1a07be |
|
|
|
1a07be |
if (status == NT_STATUS_SUCCESS) {
|
|
|
1a07be |
status = toks_spawn_impl(dctx,cctx,ntokens,ctrlpid,csyspid);
|
|
|
1a07be |
toks_free_driver_ctx(dctx);
|
|
|
1a07be |
}
|
|
|
1a07be |
|
|
|
1a07be |
return status;
|
|
|
1a07be |
}
|