|
|
44e933 |
/*********************************************************/
|
|
|
44e933 |
/* toksvc: a framework-native token broker service */
|
|
|
d91fa0 |
/* Copyright (C) 2020 SysDeer Technologies, LLC */
|
|
|
44e933 |
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
|
|
|
44e933 |
/*********************************************************/
|
|
|
44e933 |
|
|
|
44e933 |
#include <psxtypes/psxtypes.h>
|
|
|
44e933 |
#include <ntapi/ntapi.h>
|
|
|
44e933 |
|
|
|
44e933 |
#include <toksvc/toksvc.h>
|
|
|
44e933 |
#include "toksvc_daemon_impl.h"
|
|
|
44e933 |
#include "toksvc_driver_impl.h"
|
|
|
44e933 |
|
|
|
c78a06 |
static void toks_daemon_token_release(struct toks_token * token)
|
|
|
c78a06 |
{
|
|
|
c78a06 |
void * hport;
|
|
|
8b933d |
struct _nt_tty_sync_msg msg;
|
|
|
c78a06 |
uint32_t * keys;
|
|
|
c78a06 |
|
|
|
c78a06 |
hport = token->client.hdaemon;
|
|
|
c78a06 |
keys = token->keys.key;
|
|
|
c78a06 |
|
|
|
c78a06 |
ntapi->tt_aligned_block_memset(
|
|
|
c78a06 |
&msg,0,sizeof(msg));
|
|
|
c78a06 |
|
|
|
c78a06 |
msg.header.msg_type = NT_LPC_NEW_MESSAGE;
|
|
|
c78a06 |
msg.header.data_size = sizeof(msg.data);
|
|
|
c78a06 |
msg.header.msg_size = sizeof(msg);
|
|
|
c78a06 |
msg.data.ttyinfo.opcode = TOKS_DAEMON_RELEASE;
|
|
|
c78a06 |
|
|
|
8b933d |
msg.data.syncinfo.ipckeys[0] = keys[0];
|
|
|
8b933d |
msg.data.syncinfo.ipckeys[1] = keys[1];
|
|
|
8b933d |
msg.data.syncinfo.ipckeys[2] = keys[2];
|
|
|
8b933d |
msg.data.syncinfo.ipckeys[3] = keys[3];
|
|
|
8b933d |
msg.data.syncinfo.ipckeys[4] = keys[4];
|
|
|
8b933d |
msg.data.syncinfo.ipckeys[5] = keys[5];
|
|
|
c78a06 |
|
|
|
c78a06 |
ntapi->zw_request_wait_reply_port(
|
|
|
c78a06 |
hport,&msg,&msg;;
|
|
|
c78a06 |
}
|
|
|
c78a06 |
|
|
|
44e933 |
static int32_t toks_daemon_client_wait(void * rapunzel)
|
|
|
44e933 |
{
|
|
|
d08823 |
|
|
|
d08823 |
int32_t status;
|
|
|
d08823 |
nt_ebi syncebi;
|
|
|
44e933 |
struct toks_token * token;
|
|
|
44e933 |
struct toks_client_ctx * client;
|
|
|
44e933 |
void * hduo[2];
|
|
|
44e933 |
|
|
|
44e933 |
token = (struct toks_token *)rapunzel;
|
|
|
44e933 |
client = &token->client;
|
|
|
44e933 |
|
|
|
44e933 |
ntapi->zw_set_event(client->hswap,0);
|
|
|
44e933 |
|
|
|
44e933 |
hduo[0] = client->hprocess;
|
|
|
44e933 |
hduo[1] = client->halert;
|
|
|
44e933 |
|
|
|
44e933 |
ntapi->zw_wait_for_multiple_objects(
|
|
|
44e933 |
2,hduo,
|
|
|
44e933 |
NT_WAIT_ANY,
|
|
|
44e933 |
NT_SYNC_NON_ALERTABLE,
|
|
|
44e933 |
0);
|
|
|
44e933 |
|
|
|
d08823 |
status = ntapi->zw_query_event(
|
|
|
d08823 |
client->halert,
|
|
|
d08823 |
NT_EVENT_BASIC_INFORMATION,
|
|
|
d08823 |
&syncebi,sizeof(syncebi),
|
|
|
d08823 |
&(size_t){0});
|
|
|
d08823 |
|
|
|
d08823 |
if ((status == NT_STATUS_SUCCESS) && !syncebi.signal_state)
|
|
|
d08823 |
toks_daemon_token_release(token);
|
|
|
d08823 |
|
|
|
44e933 |
ntapi->zw_close(client->hprocess);
|
|
|
44e933 |
ntapi->zw_close(client->halert);
|
|
|
44e933 |
|
|
|
44e933 |
return ntapi->zw_terminate_thread(
|
|
|
44e933 |
NT_CURRENT_THREAD_HANDLE,
|
|
|
44e933 |
NT_STATUS_SUCCESS);
|
|
|
44e933 |
}
|
|
|
44e933 |
|
|
|
44e933 |
static void toks_daemon_token_reset(struct toks_token * token)
|
|
|
44e933 |
{
|
|
|
44e933 |
token->self = 0;
|
|
|
44e933 |
token->keys.key[0] = 0;
|
|
|
44e933 |
token->keys.key[1] = 0;
|
|
|
44e933 |
token->keys.key[2] = 0;
|
|
|
44e933 |
token->keys.key[3] = 0;
|
|
|
44e933 |
token->keys.key[4] = 0;
|
|
|
44e933 |
token->keys.key[5] = 0;
|
|
|
44e933 |
}
|
|
|
44e933 |
|
|
|
44e933 |
static int32_t toks_daemon_token_instance(
|
|
|
44e933 |
struct toks_token * token,
|
|
|
44e933 |
struct toks_client_ctx * client)
|
|
|
44e933 |
{
|
|
|
44e933 |
int32_t status;
|
|
|
44e933 |
nt_thread_params params;
|
|
|
44e933 |
|
|
|
44e933 |
if ((status = ntapi->tt_create_private_event(
|
|
|
44e933 |
&client->hswap,
|
|
|
44e933 |
NT_NOTIFICATION_EVENT,
|
|
|
44e933 |
NT_EVENT_NOT_SIGNALED)))
|
|
|
44e933 |
return status;
|
|
|
44e933 |
|
|
|
44e933 |
status = ntapi->tt_create_private_event(
|
|
|
44e933 |
&client->halert,
|
|
|
44e933 |
NT_NOTIFICATION_EVENT,
|
|
|
44e933 |
NT_EVENT_NOT_SIGNALED);
|
|
|
44e933 |
|
|
|
44e933 |
if (status) {
|
|
|
44e933 |
ntapi->zw_close(client->hswap);
|
|
|
44e933 |
return status;
|
|
|
44e933 |
}
|
|
|
44e933 |
|
|
|
44e933 |
token->self = token;
|
|
|
44e933 |
token->client.hprocess = client->hprocess;
|
|
|
44e933 |
token->client.hswap = client->hswap;
|
|
|
44e933 |
token->client.halert = client->halert;
|
|
|
c78a06 |
token->client.hdaemon = client->hdaemon;
|
|
|
44e933 |
token->client.cid.process_id = client->cid.process_id;
|
|
|
44e933 |
token->client.cid.thread_id = client->cid.thread_id;
|
|
|
9e3453 |
token->client.tokpid = client->tokpid;
|
|
|
44e933 |
|
|
|
44e933 |
ntapi->tt_aligned_block_memset(
|
|
|
44e933 |
¶ms,0,sizeof(params));
|
|
|
44e933 |
|
|
|
44e933 |
params.hprocess = NT_CURRENT_PROCESS_HANDLE;
|
|
|
44e933 |
params.start = toks_daemon_client_wait;
|
|
|
44e933 |
params.ext_ctx = token;
|
|
|
44e933 |
params.ext_ctx_size = sizeof(*token);
|
|
|
44e933 |
params.stack_size_commit = 4 * 1024;
|
|
|
44e933 |
params.stack_size_reserve = 4 * 1024;
|
|
|
44e933 |
params.creation_flags = NT_CREATE_LOCAL_THREAD;
|
|
|
44e933 |
|
|
|
44e933 |
if ((status = ntapi->tt_create_thread(¶ms))) {
|
|
|
44e933 |
toks_daemon_token_reset(token);
|
|
|
44e933 |
ntapi->zw_close(client->hswap);
|
|
|
44e933 |
ntapi->zw_close(client->halert);
|
|
|
44e933 |
return status;
|
|
|
44e933 |
}
|
|
|
44e933 |
|
|
|
44e933 |
status = ntapi->zw_wait_for_single_object(
|
|
|
44e933 |
client->hswap,
|
|
|
44e933 |
NT_SYNC_NON_ALERTABLE,
|
|
|
44e933 |
0);
|
|
|
44e933 |
|
|
|
c11340 |
ntapi->zw_close(client->hswap);
|
|
|
c11340 |
|
|
|
44e933 |
if (status) {
|
|
|
44e933 |
toks_daemon_token_reset(token);
|
|
|
44e933 |
ntapi->zw_close(client->halert);
|
|
|
44e933 |
return status;
|
|
|
44e933 |
}
|
|
|
44e933 |
|
|
|
44e933 |
token->client.hinstance = params.hthread;
|
|
|
44e933 |
|
|
|
44e933 |
return NT_STATUS_SUCCESS;
|
|
|
44e933 |
}
|
|
|
44e933 |
|
|
|
093128 |
static int32_t toks_daemon_queue(struct toks_daemon_ctx * dctx, const struct toks_client_ctx * client)
|
|
|
d73408 |
{
|
|
|
d73408 |
int nwaiters;
|
|
|
d73408 |
struct toks_waiter * waiter;
|
|
|
d73408 |
nt_tty_port_msg * msg;
|
|
|
658181 |
void * hevent;
|
|
|
658181 |
int32_t status;
|
|
|
d73408 |
|
|
|
d73408 |
msg = &dctx->reply;
|
|
|
d73408 |
nwaiters = toks_get_driver_nwaiters(dctx->driver_ctx);
|
|
|
d73408 |
|
|
|
d73408 |
if (nwaiters == TOKS_MAX_WAITERS)
|
|
|
d73408 |
return NT_STATUS_TIMEOUT;
|
|
|
d73408 |
|
|
|
658181 |
|
|
|
658181 |
status = ntapi->zw_duplicate_object(
|
|
|
093128 |
client->hcaller,
|
|
|
8b933d |
msg->syncinfo.hevent,
|
|
|
658181 |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
658181 |
&hevent,
|
|
|
658181 |
NT_EVENT_QUERY_STATE|NT_EVENT_MODIFY_STATE,
|
|
|
658181 |
0,0);
|
|
|
658181 |
|
|
|
658181 |
if (status) {
|
|
|
093128 |
ntapi->zw_close(client->hprocess);
|
|
|
658181 |
return status;
|
|
|
658181 |
}
|
|
|
658181 |
|
|
|
658181 |
if ((status = ntapi->zw_reset_event(hevent,&(int){0}))) {
|
|
|
093128 |
ntapi->zw_close(client->hprocess);
|
|
|
658181 |
ntapi->zw_close(hevent);
|
|
|
658181 |
return status;
|
|
|
658181 |
}
|
|
|
658181 |
|
|
|
658181 |
|
|
|
681a45 |
waiter = dctx->waiter_next;
|
|
|
d73408 |
|
|
|
093128 |
waiter->client.hprocess = client->hprocess;
|
|
|
093128 |
waiter->client.hcaller = client->hcaller;
|
|
|
658181 |
waiter->client.hevent = hevent;
|
|
|
658181 |
|
|
|
093128 |
waiter->client.tokpid = client->tokpid;
|
|
|
093128 |
waiter->client.cid.process_id = client->cid.process_id;
|
|
|
093128 |
|
|
|
d73408 |
toks_set_driver_nwaiters(
|
|
|
d73408 |
dctx->driver_ctx,
|
|
|
d73408 |
++nwaiters);
|
|
|
d73408 |
|
|
|
681a45 |
dctx->waiter_next++;
|
|
|
681a45 |
|
|
|
681a45 |
if (dctx->waiter_next == dctx->waiter_cap)
|
|
|
681a45 |
dctx->waiter_next = dctx->waiter_base;
|
|
|
681a45 |
|
|
|
d73408 |
ntapi->tt_generic_memcpy(
|
|
|
d73408 |
&waiter->msg,msg,
|
|
|
d73408 |
sizeof(*msg));
|
|
|
d73408 |
|
|
|
658181 |
return NT_STATUS_PENDING;
|
|
|
d73408 |
}
|
|
|
d73408 |
|
|
|
44e933 |
int32_t __stdcall toks_daemon_acquire(struct toks_daemon_ctx * dctx)
|
|
|
44e933 |
{
|
|
|
44e933 |
int32_t status;
|
|
|
44e933 |
nt_tty_port_msg * msg;
|
|
|
44e933 |
struct toks_client_ctx client;
|
|
|
44e933 |
nt_oa oa;
|
|
|
44e933 |
struct toks_token * token;
|
|
|
44e933 |
struct toks_token * tocap;
|
|
|
44e933 |
|
|
|
44e933 |
msg = &dctx->reply;
|
|
|
44e933 |
|
|
|
44e933 |
client.hport = 0;
|
|
|
44e933 |
client.hprocess = 0;
|
|
|
719840 |
client.hcaller = 0;
|
|
|
44e933 |
client.hswap = 0;
|
|
|
c78a06 |
client.hdaemon = dctx->hport_internal_client;
|
|
|
44e933 |
client.cid.process_id = msg->header.client_id.process_id;
|
|
|
44e933 |
client.cid.thread_id = 0;
|
|
|
344692 |
client.tokpid = 0;
|
|
|
44e933 |
|
|
|
44e933 |
oa.len = sizeof(oa);
|
|
|
44e933 |
oa.root_dir = 0;
|
|
|
44e933 |
oa.obj_name = 0;
|
|
|
44e933 |
oa.obj_attr = 0;
|
|
|
44e933 |
oa.sec_desc = 0;
|
|
|
44e933 |
oa.sec_qos = 0;
|
|
|
44e933 |
|
|
|
658181 |
if (dctx->opcode == TOKS_DAEMON_ACQUIRE) {
|
|
|
8b933d |
if ((dctx->reqtokpid = msg->syncinfo.ipcsvc.keys.reserved)) {
|
|
|
8b933d |
if (msg->syncinfo.ipcsvc.options & TOKS_OPT_FRAMEWORK_PID) {
|
|
|
c42b09 |
if ((status = toks_daemon_pidopen(dctx)))
|
|
|
c42b09 |
return status;
|
|
|
c42b09 |
} else {
|
|
|
c42b09 |
dctx->reqsyspid = dctx->reqtokpid;
|
|
|
c42b09 |
}
|
|
|
44e933 |
|
|
|
344692 |
client.tokpid = dctx->reqtokpid;
|
|
|
344692 |
client.cid.process_id = dctx->reqsyspid;
|
|
|
658181 |
}
|
|
|
500bc3 |
|
|
|
658181 |
if ((status = ntapi->zw_open_process(
|
|
|
658181 |
&client.hprocess,
|
|
|
658181 |
NT_PROCESS_SYNCHRONIZE
|
|
|
658181 |
| NT_PROCESS_QUERY_INFORMATION,
|
|
|
658181 |
&oa,&client.cid)))
|
|
|
658181 |
return status;
|
|
|
500bc3 |
}
|
|
|
500bc3 |
|
|
|
6f1c85 |
if ((dctx->ftokens == 0) && !msg->syncinfo.hevent) {
|
|
|
44e933 |
ntapi->zw_close(client.hprocess);
|
|
|
44e933 |
return NT_STATUS_TIMEOUT;
|
|
|
44e933 |
}
|
|
|
44e933 |
|
|
|
6f1c85 |
toks_query_performance_counters(dctx->driver_ctx,&dctx->pcnt);
|
|
|
658181 |
|
|
|
971724 |
if (dctx->ftokens == 0) {
|
|
|
658181 |
status = ntapi->zw_open_process(
|
|
|
719840 |
&client.hcaller,
|
|
|
658181 |
NT_PROCESS_SYNCHRONIZE
|
|
|
658181 |
| NT_PROCESS_DUP_HANDLE
|
|
|
658181 |
| NT_PROCESS_QUERY_INFORMATION,
|
|
|
658181 |
&oa,&msg->header.client_id);
|
|
|
658181 |
|
|
|
658181 |
if (status) {
|
|
|
658181 |
ntapi->zw_close(client.hprocess);
|
|
|
658181 |
return status;
|
|
|
658181 |
}
|
|
|
44e933 |
|
|
|
8b933d |
msg->syncinfo.ipckeys[0] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
6f1c85 |
&dctx->pcnt,sizeof(dctx->pcnt));
|
|
|
44e933 |
|
|
|
8b933d |
msg->syncinfo.ipckeys[1] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
658181 |
&msg->header,sizeof(msg->header));
|
|
|
658181 |
|
|
|
8b933d |
msg->syncinfo.ipckeys[2] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
8b933d |
&msg->syncinfo,sizeof(msg->syncinfo));
|
|
|
658181 |
|
|
|
8b933d |
msg->syncinfo.ipckeys[3] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
658181 |
&client,sizeof(client));
|
|
|
658181 |
|
|
|
8b933d |
msg->syncinfo.ipckeys[4] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
658181 |
toks_get_driver_tokens(dctx->driver_ctx),
|
|
|
658181 |
toks_get_driver_ntokens(dctx->driver_ctx)
|
|
|
658181 |
* sizeof(struct toks_token));
|
|
|
658181 |
|
|
|
8b933d |
msg->syncinfo.ipckeys[5] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
6f1c85 |
dctx,sizeof(*dctx));
|
|
|
658181 |
|
|
|
093128 |
return toks_daemon_queue(dctx,&client);
|
|
|
658181 |
}
|
|
|
658181 |
|
|
|
6f1c85 |
token = toks_get_driver_tokens(dctx->driver_ctx);
|
|
|
6f1c85 |
tocap = &token[toks_get_driver_atokens(dctx->driver_ctx)];
|
|
|
6f1c85 |
|
|
|
6f1c85 |
for (; token->self && (token
|
|
|
6f1c85 |
token++;
|
|
|
6f1c85 |
|
|
|
658181 |
if (dctx->opcode == TOKS_DAEMON_RELEASE) {
|
|
|
658181 |
client.hprocess = msg->ttyinfo.exarg;
|
|
|
658181 |
|
|
|
8b933d |
token->keys.key[0] = msg->syncinfo.ipckeys[0];
|
|
|
8b933d |
token->keys.key[1] = msg->syncinfo.ipckeys[1];
|
|
|
8b933d |
token->keys.key[2] = msg->syncinfo.ipckeys[2];
|
|
|
8b933d |
token->keys.key[3] = msg->syncinfo.ipckeys[3];
|
|
|
8b933d |
token->keys.key[4] = msg->syncinfo.ipckeys[4];
|
|
|
8b933d |
token->keys.key[5] = msg->syncinfo.ipckeys[5];
|
|
|
658181 |
} else {
|
|
|
658181 |
token->keys.key[0] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
6f1c85 |
&dctx->pcnt,sizeof(dctx->pcnt));
|
|
|
658181 |
|
|
|
658181 |
token->keys.key[1] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
658181 |
&msg->header,sizeof(msg->header));
|
|
|
658181 |
|
|
|
658181 |
token->keys.key[2] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
8b933d |
&msg->syncinfo,sizeof(msg->syncinfo));
|
|
|
658181 |
|
|
|
658181 |
token->keys.key[3] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
658181 |
&client,sizeof(client));
|
|
|
658181 |
|
|
|
658181 |
token->keys.key[4] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
658181 |
toks_get_driver_tokens(dctx->driver_ctx),
|
|
|
658181 |
toks_get_driver_ntokens(dctx->driver_ctx)
|
|
|
658181 |
* sizeof(struct toks_token));
|
|
|
658181 |
|
|
|
658181 |
token->keys.key[5] = ntapi->tt_buffer_crc32(
|
|
|
658181 |
msg->header.msg_id,
|
|
|
658181 |
&token->keys,sizeof(token->keys));
|
|
|
658181 |
|
|
|
8b933d |
msg->syncinfo.ipckeys[0] = token->keys.key[0];
|
|
|
8b933d |
msg->syncinfo.ipckeys[1] = token->keys.key[1];
|
|
|
8b933d |
msg->syncinfo.ipckeys[2] = token->keys.key[2];
|
|
|
8b933d |
msg->syncinfo.ipckeys[3] = token->keys.key[3];
|
|
|
8b933d |
msg->syncinfo.ipckeys[4] = token->keys.key[4];
|
|
|
8b933d |
msg->syncinfo.ipckeys[5] = token->keys.key[5];
|
|
|
658181 |
}
|
|
|
44e933 |
|
|
|
34ac34 |
if ((token->meta.key[0] = msg->syncinfo.ipcsvc.keys.key[0])) {
|
|
|
34ac34 |
token->meta.key[1] = msg->syncinfo.ipcsvc.keys.key[1];
|
|
|
34ac34 |
token->meta.key[2] = msg->syncinfo.ipcsvc.keys.key[2];
|
|
|
34ac34 |
token->meta.key[3] = msg->syncinfo.ipcsvc.keys.key[3];
|
|
|
34ac34 |
token->meta.key[4] = msg->syncinfo.ipcsvc.keys.key[4];
|
|
|
34ac34 |
token->meta.key[5] = msg->syncinfo.ipcsvc.keys.key[5];
|
|
|
34ac34 |
}
|
|
|
34ac34 |
|
|
|
44e933 |
if ((status = toks_daemon_token_instance(token,&client))) {
|
|
|
44e933 |
toks_daemon_token_reset(token);
|
|
|
44e933 |
ntapi->zw_close(client.hprocess);
|
|
|
44e933 |
return status;
|
|
|
44e933 |
}
|
|
|
44e933 |
|
|
|
8f6a66 |
dctx->utokens++;
|
|
|
971724 |
dctx->ftokens--;
|
|
|
8f6a66 |
|
|
|
44e933 |
return NT_STATUS_SUCCESS;
|
|
|
44e933 |
}
|