|
|
2420c2 |
/*********************************************************/
|
|
|
2420c2 |
/* toksvc: a framework-native token broker service */
|
|
|
2420c2 |
/* Copyright (C) 2020 Z. Gilboa */
|
|
|
2420c2 |
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
|
|
|
2420c2 |
/*********************************************************/
|
|
|
2420c2 |
|
|
|
2420c2 |
#include <ntapi/ntapi.h>
|
|
|
2420c2 |
#include <ntapi/nt_atomic.h>
|
|
|
2420c2 |
|
|
|
2420c2 |
#include <stdint.h>
|
|
|
2420c2 |
|
|
|
2420c2 |
#include <toksvc/toksvc.h>
|
|
|
2420c2 |
#include "toksvc_init_impl.h"
|
|
|
2420c2 |
#include "toksvc_nolibc_impl.h"
|
|
|
2420c2 |
|
|
|
2420c2 |
#define ARGV_DRIVER
|
|
|
2420c2 |
|
|
|
2420c2 |
#include "toksvc_version.h"
|
|
|
2420c2 |
#include "toksvc_daemon_impl.h"
|
|
|
2420c2 |
#include "toksvc_dprintf_impl.h"
|
|
|
2420c2 |
#include "toksvc_driver_impl.h"
|
|
|
2420c2 |
#include "argv/argv.h"
|
|
|
2420c2 |
|
|
|
2420c2 |
/* pty integration */
|
|
|
2420c2 |
#include <psxtypes/section/freestd.h>
|
|
|
2420c2 |
|
|
|
2420c2 |
__attr_section_decl__(".freestd")
|
|
|
2420c2 |
static const nt_tty_affiliation tty_affiliation
|
|
|
2420c2 |
__attr_section__(".freestd")
|
|
|
2420c2 |
= NT_TTY_AFFILIATION_DEFAULT;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* ntapi accessor table */
|
|
|
2420c2 |
const ntapi_vtbl * toks_ntapi;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* daemon */
|
|
|
2420c2 |
static struct toks_daemon_ctx toks_daemon_ctx;
|
|
|
618937 |
static const nt_guid toks_daemon_default_guid = TOKS_PORT_GUID_DAEMON;
|
|
|
00069c |
static const wchar16_t toks_service_name[6] = TOKS_PORT_NAME_PREFIX;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* package info */
|
|
|
2420c2 |
static const struct toks_source_version toks_src_version = {
|
|
|
2420c2 |
TOKS_TAG_VER_MAJOR,
|
|
|
2420c2 |
TOKS_TAG_VER_MINOR,
|
|
|
2420c2 |
TOKS_TAG_VER_PATCH,
|
|
|
2420c2 |
TOKSVC_GIT_VERSION
|
|
|
2420c2 |
};
|
|
|
2420c2 |
|
|
|
2420c2 |
struct toks_driver_ctx_alloc {
|
|
|
2420c2 |
struct argv_meta * meta;
|
|
|
2420c2 |
struct toks_driver_ctx_impl ctx;
|
|
|
2420c2 |
uint64_t guard;
|
|
|
2420c2 |
};
|
|
|
2420c2 |
|
|
|
2420c2 |
struct toks_split_vector {
|
|
|
2420c2 |
char ** targv;
|
|
|
2420c2 |
char ** eargv;
|
|
|
2420c2 |
};
|
|
|
2420c2 |
|
|
|
2420c2 |
static uint32_t toks_argv_flags(uint32_t flags)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
uint32_t ret = ARGV_CLONE_VECTOR;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_NONE)
|
|
|
2420c2 |
ret |= ARGV_VERBOSITY_NONE;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2420c2 |
ret |= ARGV_VERBOSITY_ERRORS;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_STATUS)
|
|
|
2420c2 |
ret |= ARGV_VERBOSITY_STATUS;
|
|
|
2420c2 |
|
|
|
2420c2 |
return ret;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
static int toks_driver_usage(
|
|
|
2420c2 |
const char * program,
|
|
|
2420c2 |
const char * arg,
|
|
|
2420c2 |
const struct argv_option ** optv,
|
|
|
2420c2 |
struct argv_meta * meta)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
char header[512];
|
|
|
2420c2 |
|
|
|
2420c2 |
snprintf(header,sizeof(header),
|
|
|
2420c2 |
"Usage: %s [options] <file>...\n" "Options:\n",
|
|
|
2420c2 |
program);
|
|
|
2420c2 |
|
|
|
2420c2 |
argv_usage(STDOUT_FILENO,header,optv,arg);
|
|
|
2420c2 |
argv_free(meta);
|
|
|
2420c2 |
|
|
|
2420c2 |
return TOKS_USAGE;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
ff65f1 |
static int64_t toks_arg_to_int64(struct argv_entry * entry)
|
|
|
ff65f1 |
{
|
|
|
ff65f1 |
int64_t ret;
|
|
|
ff65f1 |
const char * ch;
|
|
|
ff65f1 |
|
|
|
ff65f1 |
for (ret=0, ch=entry->arg; *ch && (ret>=0); ch++) {
|
|
|
ff65f1 |
if ((*ch < '0') || (*ch >'9'))
|
|
|
ff65f1 |
return (-1);
|
|
|
ff65f1 |
|
|
|
ff65f1 |
ret *= 10;
|
|
|
ff65f1 |
ret += (*ch - '0');
|
|
|
ff65f1 |
}
|
|
|
ff65f1 |
|
|
|
ff65f1 |
return ret;
|
|
|
ff65f1 |
}
|
|
|
ff65f1 |
|
|
|
ff65f1 |
static int32_t toks_arg_to_int32(struct argv_entry * entry)
|
|
|
ff65f1 |
{
|
|
|
ff65f1 |
int64_t ret = toks_arg_to_int64(entry);
|
|
|
ff65f1 |
return (ret >= 0) && (ret <= 0x7fffffff)
|
|
|
ff65f1 |
? ret : (-1);
|
|
|
ff65f1 |
}
|
|
|
ff65f1 |
|
|
|
2f270e |
static int32_t toks_query_performance_counters_failover(nt_filetime * ticks)
|
|
|
2f270e |
{
|
|
|
2f270e |
(void)ticks;
|
|
|
2f270e |
return 0;
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
23494d |
static int32_t toks_daemon_library_once;
|
|
|
23494d |
|
|
|
23494d |
static int32_t toks_daemon_library_init(void)
|
|
|
23494d |
{
|
|
|
23494d |
int32_t status;
|
|
|
23494d |
int argc;
|
|
|
23494d |
char ** argv;
|
|
|
23494d |
char ** envp;
|
|
|
23494d |
nt_rtdata * rtdata;
|
|
|
23494d |
nt_timeout timeout;
|
|
|
23494d |
|
|
|
23494d |
switch (at_locked_cas_32(&toks_daemon_library_once,0,1)) {
|
|
|
23494d |
case 0:
|
|
|
23494d |
status = ntapi->tt_get_argv_envp_utf8(
|
|
|
23494d |
&argc,&argv,&envp,
|
|
|
23494d |
0,0,0);
|
|
|
23494d |
|
|
|
23494d |
if (status) {
|
|
|
23494d |
at_store_32(&toks_daemon_library_once,3);
|
|
|
23494d |
return status;
|
|
|
23494d |
}
|
|
|
23494d |
|
|
|
23494d |
if ((status = ntapi->tt_get_runtime_data(&rtdata,0))) {
|
|
|
23494d |
at_store_32(&toks_daemon_library_once,3);
|
|
|
23494d |
return status;
|
|
|
23494d |
}
|
|
|
23494d |
|
|
|
15a6ec |
if (!rtdata->argv) {
|
|
|
15a6ec |
rtdata->argc = argc;
|
|
|
15a6ec |
rtdata->argv = argv;
|
|
|
15a6ec |
rtdata->envp = envp;
|
|
|
15a6ec |
}
|
|
|
15a6ec |
|
|
|
23494d |
ntapi->tt_guid_copy(
|
|
|
23494d |
&rtdata->srv_guid,
|
|
|
23494d |
&toks_daemon_default_guid);
|
|
|
23494d |
|
|
|
23494d |
at_locked_inc_32(&toks_daemon_library_once);
|
|
|
23494d |
return 0;
|
|
|
23494d |
|
|
|
23494d |
case 1:
|
|
|
23494d |
timeout.quad = -10;
|
|
|
23494d |
|
|
|
23494d |
for (; (at_locked_cas_32(&toks_daemon_library_once,0,1) == 1); )
|
|
|
23494d |
ntapi->zw_delay_execution(
|
|
|
23494d |
NT_SYNC_ALERTABLE,
|
|
|
23494d |
&timeout);
|
|
|
23494d |
|
|
|
23494d |
return (toks_daemon_library_once == 2)
|
|
|
23494d |
? 0 : -1;
|
|
|
23494d |
|
|
|
23494d |
case 2:
|
|
|
23494d |
return 0;
|
|
|
23494d |
|
|
|
23494d |
case 3:
|
|
|
23494d |
default:
|
|
|
23494d |
return -1;
|
|
|
23494d |
}
|
|
|
23494d |
|
|
|
23494d |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
23494d |
}
|
|
|
23494d |
|
|
|
2420c2 |
static struct toks_driver_ctx_impl * toks_driver_ctx_alloc(
|
|
|
2420c2 |
struct argv_meta * meta,
|
|
|
2420c2 |
const struct toks_common_ctx * cctx)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
struct toks_driver_ctx_alloc * ictx;
|
|
|
2420c2 |
size_t size;
|
|
|
2420c2 |
nt_runtime_data * rtdata;
|
|
|
2420c2 |
|
|
|
23494d |
switch (ntapi->tt_get_runtime_data(&rtdata,0)) {
|
|
|
23494d |
case NT_STATUS_SUCCESS:
|
|
|
23494d |
break;
|
|
|
23494d |
|
|
|
23494d |
case NT_STATUS_MORE_PROCESSING_REQUIRED:
|
|
|
23494d |
toks_daemon_library_init();
|
|
|
23494d |
|
|
|
23494d |
if (ntapi->tt_get_runtime_data(&rtdata,0))
|
|
|
23494d |
return 0;
|
|
|
23494d |
|
|
|
75adfe |
break;
|
|
|
75adfe |
|
|
|
23494d |
default:
|
|
|
23494d |
return 0;
|
|
|
23494d |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
size = sizeof(struct toks_driver_ctx_alloc);
|
|
|
2420c2 |
|
|
|
2420c2 |
if (!(ictx = calloc(1,size)))
|
|
|
2420c2 |
return 0;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (cctx)
|
|
|
2420c2 |
memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
|
|
|
2420c2 |
|
|
|
2f270e |
ictx->ctx.ticks.qpc = toks_query_performance_counters_failover;
|
|
|
2f270e |
ictx->ctx.ticks.pcfreq.quad = 0;
|
|
|
2f270e |
|
|
|
2420c2 |
ictx->meta = meta;
|
|
|
2420c2 |
ictx->ctx.rtdata = rtdata;
|
|
|
2420c2 |
return &ictx->ctx;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
static int toks_get_driver_ctx_fail(struct argv_meta * meta)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
argv_free(meta);
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
#define TOKS_SARGV_ELEMENTS 1024
|
|
|
2420c2 |
|
|
|
2420c2 |
static int toks_split_argv(
|
|
|
2420c2 |
char ** argv,
|
|
|
2420c2 |
struct toks_split_vector * sargv)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
ptrdiff_t argc;
|
|
|
2420c2 |
char ** parg;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* argc */
|
|
|
2420c2 |
for (parg=argv; *parg; )
|
|
|
2420c2 |
parg++;
|
|
|
2420c2 |
|
|
|
2420c2 |
if ((argc = parg - argv) >= TOKS_SARGV_ELEMENTS)
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* clone argv into targv */
|
|
|
2420c2 |
ntapi->tt_aligned_block_memset(
|
|
|
2420c2 |
(uintptr_t *)sargv->targv,
|
|
|
2420c2 |
0,TOKS_SARGV_ELEMENTS*sizeof(char *));
|
|
|
2420c2 |
|
|
|
2420c2 |
ntapi->tt_aligned_block_memcpy(
|
|
|
2420c2 |
(uintptr_t *)sargv->targv,
|
|
|
2420c2 |
(uintptr_t *)argv,
|
|
|
2420c2 |
argc*sizeof(char *));
|
|
|
2420c2 |
|
|
|
2420c2 |
/* eargv */
|
|
|
2420c2 |
for (parg=sargv->targv; *parg; parg++) {
|
|
|
2420c2 |
if (!(strcmp(*parg,"-e")) || !(strcmp(*parg,"--exec"))) {
|
|
|
2420c2 |
sargv->eargv = &argv[parg-sargv->targv];
|
|
|
2420c2 |
sargv->eargv++;
|
|
|
2420c2 |
*parg = 0;
|
|
|
2420c2 |
return 0;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
return 0;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
int toks_get_driver_ctx(
|
|
|
2420c2 |
char ** argv,
|
|
|
2420c2 |
char ** envp,
|
|
|
2420c2 |
uint32_t flags,
|
|
|
2420c2 |
struct toks_driver_ctx ** pctx)
|
|
|
2420c2 |
{
|
|
|
2c9219 |
int32_t status;
|
|
|
2420c2 |
struct toks_driver_ctx_impl * ctx;
|
|
|
2420c2 |
struct toks_common_ctx cctx;
|
|
|
2420c2 |
struct toks_split_vector sargv;
|
|
|
2420c2 |
const struct argv_option * optv[TOKS_OPTV_ELEMENTS];
|
|
|
2420c2 |
struct argv_meta * meta;
|
|
|
2420c2 |
struct argv_entry * entry;
|
|
|
618937 |
struct argv_entry * uuid;
|
|
|
e3e583 |
struct argv_entry * pid;
|
|
|
201fd7 |
struct argv_entry * syspid;
|
|
|
35e873 |
struct argv_entry * cfpid;
|
|
|
35e873 |
struct argv_entry * cspid;
|
|
|
b27e56 |
struct argv_entry * msecs;
|
|
|
867b30 |
struct toks_token_string key;
|
|
|
867b30 |
size_t keylen;
|
|
|
bd4f0c |
uintptr_t opdata;
|
|
|
618937 |
nt_guid svcguid;
|
|
|
2420c2 |
const char * program;
|
|
|
79252f |
const char * refstr;
|
|
|
c847e3 |
int ntokens;
|
|
|
8f6a66 |
int atokens;
|
|
|
ee5c9c |
int loglevel;
|
|
|
e3e583 |
int32_t tokpid;
|
|
|
201fd7 |
int32_t tsyspid;
|
|
|
35e873 |
int32_t ctrlpid;
|
|
|
35e873 |
int32_t csyspid;
|
|
|
b27e56 |
int64_t timeout;
|
|
|
ed52e5 |
void * hlog;
|
|
|
2f270e |
void * hkernel32;
|
|
|
2420c2 |
char * targv[TOKS_SARGV_ELEMENTS];
|
|
|
2420c2 |
|
|
|
2420c2 |
(void)envp;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (toks_init())
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
|
|
|
2420c2 |
argv_optv_init(toks_default_options,optv);
|
|
|
2420c2 |
|
|
|
2420c2 |
sargv.targv = targv;
|
|
|
2420c2 |
sargv.eargv = 0;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (toks_split_argv(argv,&sargv))
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (!(meta = argv_get(
|
|
|
2420c2 |
sargv.targv,optv,
|
|
|
2420c2 |
toks_argv_flags(flags),
|
|
|
2420c2 |
STDERR_FILENO)))
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
|
|
|
618937 |
if (!(flags & TOKS_DRIVER_MODE_CLIENT))
|
|
|
618937 |
flags |= TOKS_DRIVER_MODE_SERVER;
|
|
|
618937 |
|
|
|
ed52e5 |
hlog = 0;
|
|
|
6832b9 |
uuid = 0;
|
|
|
6832b9 |
tokpid = 0;
|
|
|
6832b9 |
tsyspid = 0;
|
|
|
35e873 |
ctrlpid = 0;
|
|
|
35e873 |
csyspid = 0;
|
|
|
6832b9 |
keylen = 0;
|
|
|
35c599 |
refstr = 0;
|
|
|
6832b9 |
ntokens = 0;
|
|
|
ee5c9c |
loglevel = 0;
|
|
|
6832b9 |
timeout = (-1);
|
|
|
6832b9 |
program = argv_program_name(argv[0]);
|
|
|
618937 |
|
|
|
2420c2 |
memset(&cctx,0,sizeof(cctx));
|
|
|
2420c2 |
cctx.drvflags = flags;
|
|
|
2420c2 |
cctx.eargv = sargv.eargv;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (!argv[1] && (flags & TOKS_DRIVER_VERBOSITY_USAGE))
|
|
|
2420c2 |
return toks_driver_usage(program,0,optv,meta);
|
|
|
2420c2 |
|
|
|
2420c2 |
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
|
|
|
2420c2 |
if (entry->fopt) {
|
|
|
2420c2 |
switch (entry->tag) {
|
|
|
2420c2 |
case TAG_HELP:
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_USAGE)
|
|
|
2420c2 |
return toks_driver_usage(program,entry->arg,optv,meta);
|
|
|
2420c2 |
|
|
|
2420c2 |
case TAG_VERSION:
|
|
|
2420c2 |
cctx.drvflags |= TOKS_DRIVER_VERSION;
|
|
|
2420c2 |
break;
|
|
|
2420c2 |
|
|
|
2420c2 |
case TAG_DAEMON:
|
|
|
2420c2 |
if (!strcmp("always",entry->arg))
|
|
|
2420c2 |
cctx.drvflags |= TOKS_DRIVER_DAEMON_ALWAYS;
|
|
|
2420c2 |
|
|
|
2420c2 |
else if (!strcmp("never",entry->arg))
|
|
|
2420c2 |
cctx.drvflags |= TOKS_DRIVER_DAEMON_NEVER;
|
|
|
2420c2 |
|
|
|
2420c2 |
break;
|
|
|
2420c2 |
|
|
|
2420c2 |
case TAG_SYSROOT:
|
|
|
2420c2 |
cctx.sysroot = entry->arg;
|
|
|
2420c2 |
break;
|
|
|
618937 |
|
|
|
618937 |
case TAG_UUID:
|
|
|
618937 |
uuid = entry;
|
|
|
618937 |
break;
|
|
|
486fcd |
|
|
|
79252f |
case TAG_REFSTR:
|
|
|
79252f |
refstr = entry->arg;
|
|
|
79252f |
break;
|
|
|
79252f |
|
|
|
e3e583 |
case TAG_PID:
|
|
|
ff65f1 |
tokpid = toks_arg_to_int32((pid=entry));
|
|
|
e3e583 |
break;
|
|
|
e3e583 |
|
|
|
201fd7 |
case TAG_SYSPID:
|
|
|
ff65f1 |
tsyspid = toks_arg_to_int32((syspid=entry));
|
|
|
201fd7 |
break;
|
|
|
201fd7 |
|
|
|
35e873 |
case TAG_CTRLPID:
|
|
|
35e873 |
ctrlpid = toks_arg_to_int32((cfpid=entry));
|
|
|
35e873 |
break;
|
|
|
35e873 |
|
|
|
35e873 |
case TAG_CSYSPID:
|
|
|
35e873 |
csyspid = toks_arg_to_int32((cspid=entry));
|
|
|
35e873 |
break;
|
|
|
35e873 |
|
|
|
ee5c9c |
case TAG_LOGLEVEL:
|
|
|
ee5c9c |
loglevel = toks_arg_to_int32(entry);
|
|
|
ee5c9c |
loglevel = (loglevel > 9) ? (-1) : loglevel;
|
|
|
ee5c9c |
cctx.loglevel = loglevel;
|
|
|
ee5c9c |
break;
|
|
|
ee5c9c |
|
|
|
b27e56 |
case TAG_TIMEOUT:
|
|
|
ff65f1 |
timeout = toks_arg_to_int64((msecs=entry));
|
|
|
ff65f1 |
timeout = (timeout < 0) ? (-2) : timeout;
|
|
|
b27e56 |
break;
|
|
|
b27e56 |
|
|
|
c847e3 |
case TAG_TOKENS:
|
|
|
ff65f1 |
ntokens = toks_arg_to_int32(entry);
|
|
|
ff65f1 |
ntokens = (ntokens > 9999) ? (-1) : ntokens;
|
|
|
c847e3 |
break;
|
|
|
c847e3 |
|
|
|
486fcd |
case TAG_CONNECT:
|
|
|
486fcd |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
486fcd |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
486fcd |
break;
|
|
|
02451d |
|
|
|
520f51 |
case TAG_ABORT:
|
|
|
520f51 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
520f51 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
520f51 |
cctx.drvflags |= TOKS_DRIVER_ACTION_ABORT;
|
|
|
520f51 |
break;
|
|
|
520f51 |
|
|
|
02451d |
case TAG_ACQUIRE:
|
|
|
02451d |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
02451d |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
02451d |
cctx.drvflags |= TOKS_DRIVER_ACTION_ACQUIRE;
|
|
|
02451d |
break;
|
|
|
867b30 |
|
|
|
867b30 |
case TAG_RELEASE:
|
|
|
867b30 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
867b30 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
867b30 |
cctx.drvflags |= TOKS_DRIVER_ACTION_RELEASE;
|
|
|
867b30 |
|
|
|
867b30 |
keylen = toks_strlen(entry->arg);
|
|
|
867b30 |
|
|
|
867b30 |
ntapi->tt_generic_memset(
|
|
|
867b30 |
&key,0,sizeof(key));
|
|
|
867b30 |
|
|
|
867b30 |
if (keylen < sizeof(key.token))
|
|
|
867b30 |
ntapi->tt_generic_memcpy(
|
|
|
867b30 |
&key.token,entry->arg,
|
|
|
867b30 |
keylen);
|
|
|
867b30 |
break;
|
|
|
ed52e5 |
|
|
|
ed52e5 |
case TAG_LOGFILE:
|
|
|
ed52e5 |
cctx.logfile = entry->arg;
|
|
|
ed52e5 |
break;
|
|
|
bd4f0c |
|
|
|
bd4f0c |
case TAG_NTOKENSGET:
|
|
|
bd4f0c |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
bd4f0c |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
bd4f0c |
cctx.drvflags |= TOKS_DRIVER_ACTION_NTOKENS_GET;
|
|
|
bd4f0c |
break;
|
|
|
0f44d8 |
|
|
|
0f44d8 |
case TAG_NTOKENSSET:
|
|
|
0f44d8 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
0f44d8 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
0f44d8 |
cctx.drvflags |= TOKS_DRIVER_ACTION_NTOKENS_SET;
|
|
|
0f44d8 |
ntokens = toks_arg_to_int32(entry);
|
|
|
0f44d8 |
break;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
} else
|
|
|
2420c2 |
/* strict */
|
|
|
2420c2 |
return toks_driver_usage(program,0,optv,meta);
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
e3e583 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) && (tokpid < 0)) {
|
|
|
e3e583 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
e3e583 |
toks_dprintf(STDERR_FILENO,
|
|
|
201fd7 |
"%s: error: %s is not a valid framework process id.",
|
|
|
e3e583 |
program,pid->arg);
|
|
|
e3e583 |
return toks_get_driver_ctx_fail(meta);
|
|
|
e3e583 |
}
|
|
|
e3e583 |
|
|
|
201fd7 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) && (tsyspid < 0)) {
|
|
|
201fd7 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
201fd7 |
toks_dprintf(STDERR_FILENO,
|
|
|
201fd7 |
"%s: error: %s is not a valid system process id.",
|
|
|
201fd7 |
program,syspid->arg);
|
|
|
201fd7 |
return toks_get_driver_ctx_fail(meta);
|
|
|
201fd7 |
}
|
|
|
201fd7 |
|
|
|
35e873 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (ctrlpid < 0)) {
|
|
|
35e873 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
35e873 |
toks_dprintf(STDERR_FILENO,
|
|
|
35e873 |
"%s: error: %s is not a valid controlling "
|
|
|
35e873 |
"framework process id.",
|
|
|
35e873 |
program,cfpid->arg);
|
|
|
35e873 |
return toks_get_driver_ctx_fail(meta);
|
|
|
35e873 |
}
|
|
|
35e873 |
|
|
|
35e873 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (csyspid < 0)) {
|
|
|
35e873 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
35e873 |
toks_dprintf(STDERR_FILENO,
|
|
|
35e873 |
"%s: error: %s is not a valid controlling "
|
|
|
35e873 |
"system process id.",
|
|
|
35e873 |
program,cspid->arg);
|
|
|
35e873 |
return toks_get_driver_ctx_fail(meta);
|
|
|
35e873 |
}
|
|
|
35e873 |
|
|
|
b27e56 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) && (timeout < (-1))) {
|
|
|
b27e56 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
b27e56 |
toks_dprintf(STDERR_FILENO,
|
|
|
b27e56 |
"%s: error: %s is not a valid timeout in milliseconds.",
|
|
|
b27e56 |
program,msecs->arg);
|
|
|
b27e56 |
return toks_get_driver_ctx_fail(meta);
|
|
|
b27e56 |
}
|
|
|
b27e56 |
|
|
|
d5c778 |
if ((ntokens == 0) && !(cctx.drvflags & TOKS_DRIVER_VERSION)) {
|
|
|
d5c778 |
ntokens = (-1);
|
|
|
d5c778 |
}
|
|
|
d5c778 |
|
|
|
d5c778 |
if (ntokens == 0) {
|
|
|
d5c778 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
d5c778 |
}
|
|
|
d5c778 |
|
|
|
d5c778 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (ntokens < 0)) {
|
|
|
c847e3 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
c847e3 |
toks_dprintf(STDERR_FILENO,
|
|
|
c847e3 |
"%s: error: number of tokens not set or is invalid.",
|
|
|
c847e3 |
program);
|
|
|
c847e3 |
return toks_get_driver_ctx_fail(meta);
|
|
|
c847e3 |
}
|
|
|
c847e3 |
|
|
|
ee5c9c |
if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (loglevel < 0)) {
|
|
|
ee5c9c |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
ee5c9c |
toks_dprintf(STDERR_FILENO,
|
|
|
ee5c9c |
"%s: error: loglevel must be in the range of 0..9.",
|
|
|
ee5c9c |
program);
|
|
|
ee5c9c |
return toks_get_driver_ctx_fail(meta);
|
|
|
ee5c9c |
}
|
|
|
ee5c9c |
|
|
|
618937 |
if (uuid && ntapi->tt_string_to_guid_utf8(uuid->arg,&svcguid)) {
|
|
|
618937 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
618937 |
toks_dprintf(STDERR_FILENO,
|
|
|
618937 |
"%s: error: '%s' is not a valid service guid (did you forget the braces?)",
|
|
|
618937 |
program,uuid->arg);
|
|
|
618937 |
return toks_get_driver_ctx_fail(meta);
|
|
|
618937 |
|
|
|
618937 |
}
|
|
|
618937 |
|
|
|
2420c2 |
if (cctx.sysroot && toks_open_dir(&cctx.hroot,0,cctx.sysroot,false)) {
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2420c2 |
toks_dprintf(STDERR_FILENO,
|
|
|
2420c2 |
"%s: error: could not open sysroot directory '%s'",
|
|
|
2420c2 |
program,cctx.sysroot);
|
|
|
2420c2 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
if (!(ctx = toks_driver_ctx_alloc(meta,&cctx)))
|
|
|
2420c2 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2420c2 |
|
|
|
a830d3 |
if (ctx->rtdata->hroot && cctx.sysroot) {
|
|
|
ed52e5 |
ntapi->zw_close(ctx->rtdata->hroot);
|
|
|
ed52e5 |
ctx->rtdata->hroot = cctx.hroot;
|
|
|
a830d3 |
} else {
|
|
|
a830d3 |
cctx.hroot = ctx->rtdata->hroot;
|
|
|
ed52e5 |
}
|
|
|
ed52e5 |
|
|
|
ed52e5 |
if (cctx.logfile && toks_open_log_file(&hlog,ctx->rtdata->hroot,cctx.logfile,false)) {
|
|
|
ed52e5 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
ed52e5 |
toks_dprintf(STDERR_FILENO,
|
|
|
ed52e5 |
"%s: error: could not create logfile '%s'",
|
|
|
ed52e5 |
program,cctx.logfile);
|
|
|
ed52e5 |
return toks_get_driver_ctx_fail(meta);
|
|
|
ed52e5 |
}
|
|
|
ed52e5 |
|
|
|
ed52e5 |
if (ctx->rtdata->hlog && cctx.logfile) {
|
|
|
ed52e5 |
ntapi->zw_close(ctx->rtdata->hlog);
|
|
|
ed52e5 |
ctx->rtdata->hlog = hlog;
|
|
|
ed52e5 |
}
|
|
|
ed52e5 |
|
|
|
867b30 |
if ((cctx.drvflags & TOKS_DRIVER_ACTION_RELEASE)) {
|
|
|
867b30 |
if (toks_client_str_to_token(&ctx->ctx,&key)) {
|
|
|
867b30 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
867b30 |
toks_dprintf(STDERR_FILENO,
|
|
|
867b30 |
"%s: error: [%s] is not a valid token.",
|
|
|
867b30 |
program,key.token);
|
|
|
867b30 |
return toks_get_driver_ctx_fail(meta);
|
|
|
867b30 |
}
|
|
|
867b30 |
}
|
|
|
867b30 |
|
|
|
618937 |
ntapi->tt_guid_copy(
|
|
|
618937 |
&ctx->uuid,
|
|
|
618937 |
uuid ? &svcguid : &ctx->rtdata->srv_guid);
|
|
|
618937 |
|
|
|
2f270e |
if ((toks_ntapi->tt_create_private_event(
|
|
|
2f270e |
&ctx->hevent,
|
|
|
2f270e |
NT_NOTIFICATION_EVENT,
|
|
|
2f270e |
NT_EVENT_NOT_SIGNALED)))
|
|
|
2f270e |
return toks_get_driver_ctx_fail(meta);
|
|
|
2f270e |
|
|
|
00069c |
if ((ntapi->tt_open_dev_object_directory(
|
|
|
00069c |
&ctx->hsvcdir,
|
|
|
2c26a1 |
NT_SEC_READ_CONTROL
|
|
|
2c26a1 |
| NT_DIRECTORY_QUERY
|
|
|
2c26a1 |
| NT_DIRECTORY_TRAVERSE
|
|
|
2c26a1 |
| NT_DIRECTORY_CREATE_OBJECT
|
|
|
2c26a1 |
| NT_DIRECTORY_CREATE_SUBDIRECTORY,
|
|
|
00069c |
toks_service_name,
|
|
|
00069c |
&toks_daemon_default_guid)))
|
|
|
00069c |
return toks_get_driver_ctx_fail(meta);
|
|
|
00069c |
|
|
|
2f270e |
if ((hkernel32 = pe_get_kernel32_module_handle()))
|
|
|
2f270e |
if ((ctx->ticks.qpc = pe_get_procedure_address(
|
|
|
2f270e |
hkernel32,"QueryPerformanceCounter")))
|
|
|
2f270e |
ntapi->zw_query_performance_counter(
|
|
|
2f270e |
&(nt_filetime){{0,0}},
|
|
|
2f270e |
&ctx->ticks.pcfreq);
|
|
|
2f270e |
|
|
|
ed52e5 |
|
|
|
8f6a66 |
atokens = ntokens;
|
|
|
8f6a66 |
atokens += 0x1fff;
|
|
|
8f6a66 |
atokens |= 0xfff;
|
|
|
8f6a66 |
atokens ^= 0xfff;
|
|
|
8f6a66 |
|
|
|
ed52e5 |
ctx->hlog = hlog;
|
|
|
e3e583 |
ctx->tokpid = tokpid;
|
|
|
201fd7 |
ctx->tsyspid = tsyspid;
|
|
|
35e873 |
ctx->ctrlpid = ctrlpid;
|
|
|
35e873 |
ctx->csyspid = csyspid;
|
|
|
c847e3 |
ctx->ntokens = ntokens;
|
|
|
8f6a66 |
ctx->atokens = atokens;
|
|
|
b27e56 |
ctx->timeout = timeout;
|
|
|
2420c2 |
ctx->ctx.program = program;
|
|
|
2420c2 |
ctx->ctx.cctx = &ctx->cctx;
|
|
|
618937 |
ctx->cctx.uuid = &ctx->uuid;
|
|
|
2420c2 |
|
|
|
ed52e5 |
ctx->rtdata->hroot = cctx.hroot;
|
|
|
7fcdf2 |
ctx->rtdata->hlog = hlog ? hlog : ctx->rtdata->hlog;
|
|
|
ed52e5 |
|
|
|
79252f |
toks_set_driver_refstr(&ctx->ctx,refstr);
|
|
|
79252f |
|
|
|
c847e3 |
if (cctx.drvflags & TOKS_DRIVER_MODE_SERVER) {
|
|
|
681a45 |
if (!(ctx->waiters = toks_calloc(
|
|
|
681a45 |
TOKS_MAX_WAITERS,
|
|
|
681a45 |
sizeof(struct toks_waiter))))
|
|
|
d73408 |
return toks_get_driver_ctx_fail(meta);
|
|
|
d73408 |
|
|
|
681a45 |
toks_daemon_ctx.driver_ctx = &ctx->ctx;
|
|
|
681a45 |
toks_daemon_ctx.waiter_base = ctx->waiters;
|
|
|
681a45 |
toks_daemon_ctx.waiter_first = ctx->waiters;
|
|
|
681a45 |
toks_daemon_ctx.waiter_next = ctx->waiters;
|
|
|
681a45 |
toks_daemon_ctx.waiter_cap = &ctx->waiters[TOKS_MAX_WAITERS];
|
|
|
681a45 |
|
|
|
681a45 |
|
|
|
8f6a66 |
if (!(ctx->tokens = toks_calloc(atokens,sizeof(*ctx->tokens))))
|
|
|
c847e3 |
return toks_get_driver_ctx_fail(meta);
|
|
|
c847e3 |
|
|
|
f2a689 |
if (toks_daemon_init(&toks_daemon_ctx,&ctx->uuid))
|
|
|
f2a689 |
return toks_get_driver_ctx_fail(meta);
|
|
|
c847e3 |
}
|
|
|
f2a689 |
|
|
|
2c9219 |
if (cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) {
|
|
|
3e9813 |
if (cctx.drvflags & TOKS_DRIVER_DAEMON_ALWAYS) {
|
|
|
3e9813 |
toks_daemon_ctx.driver_ctx = &ctx->ctx;
|
|
|
3e9813 |
|
|
|
3e9813 |
switch ((status = toks_daemon_init(&toks_daemon_ctx,0))) {
|
|
|
3e9813 |
case NT_STATUS_SUCCESS:
|
|
|
3e9813 |
break;
|
|
|
3e9813 |
|
|
|
3e9813 |
default:
|
|
|
3e9813 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
3e9813 |
toks_dprintf(STDERR_FILENO,
|
|
|
3e9813 |
"%s: error: failed to initialize signal handling "
|
|
|
3e9813 |
"(check the system's documentation) [0x%x].",
|
|
|
3e9813 |
program,status);
|
|
|
3e9813 |
|
|
|
3e9813 |
return toks_get_driver_ctx_fail(meta);
|
|
|
3e9813 |
}
|
|
|
3e9813 |
}
|
|
|
3e9813 |
|
|
|
2c9219 |
switch ((status = toks_client_connect(&ctx->ctx))) {
|
|
|
2c9219 |
case NT_STATUS_SUCCESS:
|
|
|
2c9219 |
break;
|
|
|
2c9219 |
|
|
|
2c9219 |
case NT_STATUS_OBJECT_NAME_NOT_FOUND:
|
|
|
2c9219 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2c9219 |
toks_dprintf(STDERR_FILENO,
|
|
|
2c9219 |
"%s: error: could not connect "
|
|
|
2c9219 |
"(server not running) [0x%x].",
|
|
|
2c9219 |
program,status);
|
|
|
2c9219 |
|
|
|
2c9219 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2c9219 |
|
|
|
2c9219 |
case NT_STATUS_CONNECTION_REFUSED:
|
|
|
2c9219 |
case NT_STATUS_PORT_CONNECTION_REFUSED:
|
|
|
2c9219 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2c9219 |
toks_dprintf(STDERR_FILENO,
|
|
|
2c9219 |
"%s: error: could not connect "
|
|
|
2c9219 |
"(connection refused) [0x%x].",
|
|
|
2c9219 |
program,status);
|
|
|
2c9219 |
|
|
|
2c9219 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2c9219 |
|
|
|
2c9219 |
case NT_STATUS_ACCESS_DENIED:
|
|
|
2c9219 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2c9219 |
toks_dprintf(STDERR_FILENO,
|
|
|
2c9219 |
"%s: error: could not connect "
|
|
|
2c9219 |
"(access denied) [0x%x].",
|
|
|
2c9219 |
program,status);
|
|
|
2c9219 |
|
|
|
2c9219 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2c9219 |
|
|
|
2c9219 |
default:
|
|
|
2c9219 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2c9219 |
toks_dprintf(STDERR_FILENO,
|
|
|
2c9219 |
"%s: error: could not connect "
|
|
|
2c9219 |
"(check the system's documentation) [0x%x].",
|
|
|
2c9219 |
program,status);
|
|
|
2c9219 |
|
|
|
2c9219 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2c9219 |
}
|
|
|
bd4f0c |
|
|
|
bd4f0c |
if (cctx.drvflags & TOKS_DRIVER_ACTION_NTOKENS_GET) {
|
|
|
bd4f0c |
status = toks_service_ioctl(
|
|
|
bd4f0c |
&ctx->ctx,TOKS_IOCTL_GET_TOKEN_COUNT,
|
|
|
bd4f0c |
&opdata,0);
|
|
|
bd4f0c |
|
|
|
bd4f0c |
switch (status) {
|
|
|
bd4f0c |
case NT_STATUS_SUCCESS:
|
|
|
bd4f0c |
ctx->ntokens = opdata;
|
|
|
bd4f0c |
break;
|
|
|
bd4f0c |
|
|
|
bd4f0c |
default:
|
|
|
bd4f0c |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
bd4f0c |
toks_dprintf(STDERR_FILENO,
|
|
|
bd4f0c |
"%s: error: could not obtain the current "
|
|
|
bd4f0c |
"overall number of tokens "
|
|
|
bd4f0c |
"(check the system's documentation) [0x%x].",
|
|
|
bd4f0c |
program,status);
|
|
|
bd4f0c |
|
|
|
bd4f0c |
return toks_get_driver_ctx_fail(meta);
|
|
|
bd4f0c |
}
|
|
|
bd4f0c |
}
|
|
|
2c9219 |
}
|
|
|
486fcd |
|
|
|
2420c2 |
*pctx = &ctx->ctx;
|
|
|
2420c2 |
return TOKS_OK;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
static void toks_free_driver_ctx_impl(struct toks_driver_ctx_alloc * ictx)
|
|
|
2420c2 |
{
|
|
|
2f270e |
if (ictx->ctx.hevent)
|
|
|
2f270e |
ntapi->zw_close(ictx->ctx.hevent);
|
|
|
2f270e |
|
|
|
00069c |
if (ictx->ctx.hsvcdir)
|
|
|
00069c |
ntapi->zw_close(ictx->ctx.hsvcdir);
|
|
|
00069c |
|
|
|
00069c |
if (ictx->ctx.hsvclink)
|
|
|
00069c |
ntapi->zw_close(ictx->ctx.hsvclink);
|
|
|
00069c |
|
|
|
aba5a2 |
if (ictx->ctx.hservice)
|
|
|
aba5a2 |
ntapi->zw_close(ictx->ctx.hservice);
|
|
|
aba5a2 |
|
|
|
83e502 |
if (ictx->ctx.hserver)
|
|
|
83e502 |
ntapi->zw_close(ictx->ctx.hserver);
|
|
|
83e502 |
|
|
|
ed52e5 |
if (ictx->ctx.hlog)
|
|
|
ed52e5 |
ntapi->zw_close(ictx->ctx.hlog);
|
|
|
ed52e5 |
|
|
|
c847e3 |
if (ictx->ctx.tokens)
|
|
|
c847e3 |
toks_free(ictx->ctx.tokens);
|
|
|
c847e3 |
|
|
|
d73408 |
if (ictx->ctx.waiters)
|
|
|
d73408 |
toks_free(ictx->ctx.waiters);
|
|
|
d73408 |
|
|
|
2420c2 |
argv_free(ictx->meta);
|
|
|
2420c2 |
free(ictx);
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
void toks_free_driver_ctx(struct toks_driver_ctx * ctx)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
struct toks_driver_ctx_alloc * ictx;
|
|
|
2420c2 |
uintptr_t addr;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (ctx) {
|
|
|
2420c2 |
addr = (uintptr_t)ctx - offsetof(struct toks_driver_ctx_impl,ctx);
|
|
|
2420c2 |
addr = addr - offsetof(struct toks_driver_ctx_alloc,ctx);
|
|
|
2420c2 |
ictx = (struct toks_driver_ctx_alloc *)addr;
|
|
|
2420c2 |
toks_free_driver_ctx_impl(ictx);
|
|
|
2420c2 |
}
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
b27e56 |
void toks_driver_set_timeout(struct toks_driver_ctx * dctx, int64_t millisecs)
|
|
|
b27e56 |
{
|
|
|
b27e56 |
toks_set_driver_timeout(dctx,millisecs);
|
|
|
b27e56 |
}
|
|
|
b27e56 |
|
|
|
b27e56 |
void toks_driver_unset_timeout(struct toks_driver_ctx * dctx)
|
|
|
b27e56 |
{
|
|
|
b27e56 |
toks_set_driver_timeout(dctx,(-1));
|
|
|
b27e56 |
}
|
|
|
b27e56 |
|
|
|
2420c2 |
const struct toks_source_version * toks_source_version(void)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
return &toks_src_version;
|
|
|
2420c2 |
}
|