nts: improve NTS-KE server/client code

Add more assertions and comments, refactor initialization of the helper,
and make other changes to make the code more robust.
This commit is contained in:
Miroslav Lichvar 2020-07-13 14:25:57 +02:00
parent 51d77d6cfc
commit 66e097e3e6
11 changed files with 191 additions and 105 deletions

12
main.c
View file

@ -121,13 +121,15 @@ MAI_CleanupAndExit(void)
NCR_Finalise(); NCR_Finalise();
NIO_Finalise(); NIO_Finalise();
CAM_Finalise(); CAM_Finalise();
SCK_Finalise();
KEY_Finalise(); KEY_Finalise();
RCL_Finalise(); RCL_Finalise();
SRC_Finalise(); SRC_Finalise();
REF_Finalise(); REF_Finalise();
RTC_Finalise(); RTC_Finalise();
SYS_Finalise(); SYS_Finalise();
SCK_Finalise();
SCH_Finalise(); SCH_Finalise();
LCL_Finalise(); LCL_Finalise();
PRV_Finalise(); PRV_Finalise();
@ -563,12 +565,16 @@ int main
PRV_Initialise(); PRV_Initialise();
LCL_Initialise(); LCL_Initialise();
SCH_Initialise(); SCH_Initialise();
SCK_Initialise(address_family);
/* Start helper processes if needed */
NKS_PreInitialise(pw->pw_uid, pw->pw_gid, scfilter_level);
SYS_Initialise(clock_control); SYS_Initialise(clock_control);
RTC_Initialise(do_init_rtc); RTC_Initialise(do_init_rtc);
SRC_Initialise(); SRC_Initialise();
RCL_Initialise(); RCL_Initialise();
KEY_Initialise(); KEY_Initialise();
SCK_Initialise(address_family);
/* Open privileged ports before dropping root */ /* Open privileged ports before dropping root */
CAM_Initialise(); CAM_Initialise();
@ -597,7 +603,7 @@ int main
NSR_Initialise(); NSR_Initialise();
NSD_Initialise(); NSD_Initialise();
NNS_Initialise(); NNS_Initialise();
NKS_Initialise(scfilter_level); NKS_Initialise();
CLG_Initialise(); CLG_Initialise();
MNL_Initialise(); MNL_Initialise();
TMC_Initialise(); TMC_Initialise();

View file

@ -85,7 +85,7 @@ name_resolve_handler(DNS_Status status, int n_addrs, IPAddr *ip_addrs, void *arg
inst->ntp_address.ip_addr = ip_addrs[0]; inst->ntp_address.ip_addr = ip_addrs[0];
/* Prefer an address of the same family as NTS-KE */ /* Prefer an address in the same family as the NTS-KE server */
for (i = 0; i < n_addrs; i++) { for (i = 0; i < n_addrs; i++) {
DEBUG_LOG("%s resolved to %s", inst->server_name, UTI_IPToString(&ip_addrs[i])); DEBUG_LOG("%s resolved to %s", inst->server_name, UTI_IPToString(&ip_addrs[i]));
if (ip_addrs[i].family == inst->address.ip_addr.family) { if (ip_addrs[i].family == inst->address.ip_addr.family) {
@ -169,13 +169,21 @@ process_response(NKC_Instance inst)
error = 1; error = 1;
break; break;
case NKE_RECORD_COOKIE: case NKE_RECORD_COOKIE:
DEBUG_LOG("Got cookie #%d length=%d", inst->num_cookies + 1, length); DEBUG_LOG("Got cookie length=%d", length);
assert(NKE_MAX_COOKIE_LENGTH == sizeof (inst->cookies[inst->num_cookies].cookie));
if (length <= NKE_MAX_COOKIE_LENGTH && inst->num_cookies < NKE_MAX_COOKIES) { if (length < 1 || length > NKE_MAX_COOKIE_LENGTH || length % 4 != 0 ||
inst->cookies[inst->num_cookies].length = length; inst->num_cookies >= NKE_MAX_COOKIES) {
memcpy(inst->cookies[inst->num_cookies].cookie, data, length); DEBUG_LOG("Unexpected length/cookie");
inst->num_cookies++; break;
} }
assert(NKE_MAX_COOKIE_LENGTH == sizeof (inst->cookies[inst->num_cookies].cookie));
assert(NKE_MAX_COOKIES == sizeof (inst->cookies) /
sizeof (inst->cookies[inst->num_cookies]));
inst->cookies[inst->num_cookies].length = length;
memcpy(inst->cookies[inst->num_cookies].cookie, data, length);
inst->num_cookies++;
break; break;
case NKE_RECORD_NTPV4_SERVER_NEGOTIATION: case NKE_RECORD_NTPV4_SERVER_NEGOTIATION:
if (length < 1 || length >= sizeof (inst->server_name)) { if (length < 1 || length >= sizeof (inst->server_name)) {
@ -313,6 +321,8 @@ NKC_Start(NKC_Instance inst)
assert(!NKC_IsActive(inst)); assert(!NKC_IsActive(inst));
inst->got_response = 0;
if (!client_credentials) { if (!client_credentials) {
DEBUG_LOG("Missing client credentials"); DEBUG_LOG("Missing client credentials");
return 0; return 0;
@ -332,7 +342,7 @@ NKC_Start(NKC_Instance inst)
UTI_IPSockAddrToString(&inst->address), inst->name) >= sizeof (label)) UTI_IPSockAddrToString(&inst->address), inst->name) >= sizeof (label))
; ;
/* Start a NTS-KE session */ /* Start an NTS-KE session */
if (!NKSN_StartSession(inst->session, sock_fd, label, client_credentials, CLIENT_TIMEOUT)) { if (!NKSN_StartSession(inst->session, sock_fd, label, client_credentials, CLIENT_TIMEOUT)) {
SCK_CloseSocket(sock_fd); SCK_CloseSocket(sock_fd);
return 0; return 0;
@ -376,7 +386,7 @@ NKC_GetNtsData(NKC_Instance inst, NKE_Context *context,
*ntp_address = inst->ntp_address; *ntp_address = inst->ntp_address;
return i; return 1;
} }
/* ================================================== */ /* ================================================== */

View file

@ -33,10 +33,12 @@
#include "array.h" #include "array.h"
#include "conf.h" #include "conf.h"
#include "clientlog.h" #include "clientlog.h"
#include "local.h"
#include "logging.h" #include "logging.h"
#include "memory.h" #include "memory.h"
#include "ntp_core.h" #include "ntp_core.h"
#include "nts_ke_session.h" #include "nts_ke_session.h"
#include "privops.h"
#include "siv.h" #include "siv.h"
#include "socket.h" #include "socket.h"
#include "sched.h" #include "sched.h"
@ -59,7 +61,7 @@
typedef struct { typedef struct {
uint32_t key_id; uint32_t key_id;
uint8_t nonce[SERVER_COOKIE_NONCE_LENGTH]; unsigned char nonce[SERVER_COOKIE_NONCE_LENGTH];
} ServerCookieHeader; } ServerCookieHeader;
typedef struct { typedef struct {
@ -87,6 +89,7 @@ static int server_sock_fd4;
static int server_sock_fd6; static int server_sock_fd6;
static int helper_sock_fd; static int helper_sock_fd;
static int is_helper;
static int initialised = 0; static int initialised = 0;
@ -106,13 +109,15 @@ handle_client(int sock_fd, IPSockAddr *addr)
NKSN_Instance inst, *instp; NKSN_Instance inst, *instp;
int i; int i;
/* Leave at least half of the descriptors which can handled by select()
to other use */
if (sock_fd > FD_SETSIZE / 2) { if (sock_fd > FD_SETSIZE / 2) {
DEBUG_LOG("Rejected connection from %s (%s)", DEBUG_LOG("Rejected connection from %s (%s)",
UTI_IPSockAddrToString(addr), "too many descriptors"); UTI_IPSockAddrToString(addr), "too many descriptors");
return 0; return 0;
} }
/* Find a slot which is free or has a stopped session */ /* Find an unused server slot or one with an already stopped session */
for (i = 0, inst = NULL; i < ARR_GetSize(sessions); i++) { for (i = 0, inst = NULL; i < ARR_GetSize(sessions); i++) {
instp = ARR_GetElement(sessions, i); instp = ARR_GetElement(sessions, i);
if (!*instp) { if (!*instp) {
@ -132,6 +137,8 @@ handle_client(int sock_fd, IPSockAddr *addr)
return 0; return 0;
} }
assert(server_credentials);
if (!NKSN_StartSession(inst, sock_fd, UTI_IPSockAddrToString(addr), if (!NKSN_StartSession(inst, sock_fd, UTI_IPSockAddrToString(addr),
server_credentials, SERVER_TIMEOUT)) server_credentials, SERVER_TIMEOUT))
return 0; return 0;
@ -149,6 +156,8 @@ handle_helper_request(int fd, int event, void *arg)
IPSockAddr client_addr; IPSockAddr client_addr;
int sock_fd; int sock_fd;
/* Receive the helper request with the NTS-KE session socket.
With multiple helpers EAGAIN errors are expected here. */
message = SCK_ReceiveMessage(fd, SCK_FLAG_MSG_DESCRIPTOR); message = SCK_ReceiveMessage(fd, SCK_FLAG_MSG_DESCRIPTOR);
if (!message) if (!message)
return; return;
@ -160,16 +169,20 @@ handle_helper_request(int fd, int event, void *arg)
return; return;
} }
if (message->length != sizeof (HelperRequest)) { if (!initialised) {
DEBUG_LOG("Unexpected message length"); DEBUG_LOG("Uninitialised helper");
SCK_CloseSocket(sock_fd); SCK_CloseSocket(sock_fd);
return; return;
} }
if (message->length != sizeof (HelperRequest))
LOG_FATAL("Invalid helper request");
req = message->data; req = message->data;
/* Extract the server key and client address from the request */ /* Extract the current server key and client address from the request */
server_keys[current_server_key].id = ntohl(req->key_id); server_keys[current_server_key].id = ntohl(req->key_id);
assert(sizeof (server_keys[current_server_key].key) == sizeof (req->key));
memcpy(server_keys[current_server_key].key, req->key, memcpy(server_keys[current_server_key].key, req->key,
sizeof (server_keys[current_server_key].key)); sizeof (server_keys[current_server_key].key));
UTI_IPNetworkToHost(&req->client_addr, &client_addr.ip_addr); UTI_IPNetworkToHost(&req->client_addr, &client_addr.ip_addr);
@ -177,7 +190,7 @@ handle_helper_request(int fd, int event, void *arg)
if (!SIV_SetKey(server_keys[current_server_key].siv, server_keys[current_server_key].key, if (!SIV_SetKey(server_keys[current_server_key].siv, server_keys[current_server_key].key,
SIV_GetKeyLength(SERVER_COOKIE_SIV))) SIV_GetKeyLength(SERVER_COOKIE_SIV)))
assert(0); LOG_FATAL("Could not set SIV key");
if (!handle_client(sock_fd, &client_addr)) { if (!handle_client(sock_fd, &client_addr)) {
SCK_CloseSocket(sock_fd); SCK_CloseSocket(sock_fd);
@ -190,14 +203,14 @@ handle_helper_request(int fd, int event, void *arg)
/* ================================================== */ /* ================================================== */
static void static void
accept_connection(int server_fd, int event, void *arg) accept_connection(int listening_fd, int event, void *arg)
{ {
SCK_Message message; SCK_Message message;
IPSockAddr addr; IPSockAddr addr;
int log_index, sock_fd; int log_index, sock_fd;
struct timespec now; struct timespec now;
sock_fd = SCK_AcceptConnection(server_fd, &addr); sock_fd = SCK_AcceptConnection(listening_fd, &addr);
if (sock_fd < 0) if (sock_fd < 0)
return; return;
@ -209,6 +222,7 @@ accept_connection(int server_fd, int event, void *arg)
} }
SCH_GetLastEventTime(&now, NULL, NULL); SCH_GetLastEventTime(&now, NULL, NULL);
log_index = CLG_LogServiceAccess(CLG_NTSKE, &addr.ip_addr, &now); log_index = CLG_LogServiceAccess(CLG_NTSKE, &addr.ip_addr, &now);
if (log_index >= 0 && CLG_LimitServiceRate(CLG_NTSKE, log_index)) { if (log_index >= 0 && CLG_LimitServiceRate(CLG_NTSKE, log_index)) {
DEBUG_LOG("Rejected connection from %s (%s)", DEBUG_LOG("Rejected connection from %s (%s)",
@ -222,9 +236,11 @@ accept_connection(int server_fd, int event, void *arg)
if (helper_sock_fd != INVALID_SOCK_FD) { if (helper_sock_fd != INVALID_SOCK_FD) {
HelperRequest req; HelperRequest req;
/* Include the current server key and client address in the request */
memset(&req, 0, sizeof (req)); memset(&req, 0, sizeof (req));
/* Include the current server key and client address in the request */
req.key_id = htonl(server_keys[current_server_key].id); req.key_id = htonl(server_keys[current_server_key].id);
assert(sizeof (req.key) == sizeof (server_keys[current_server_key].key));
memcpy(req.key, server_keys[current_server_key].key, sizeof (req.key)); memcpy(req.key, server_keys[current_server_key].key, sizeof (req.key));
UTI_IPHostToNetwork(&addr.ip_addr, &req.client_addr); UTI_IPHostToNetwork(&addr.ip_addr, &req.client_addr);
req.client_port = htons(addr.port); req.client_port = htons(addr.port);
@ -234,7 +250,12 @@ accept_connection(int server_fd, int event, void *arg)
message.length = sizeof (req); message.length = sizeof (req);
message.descriptor = sock_fd; message.descriptor = sock_fd;
errno = 0;
if (!SCK_SendMessage(helper_sock_fd, &message, SCK_FLAG_MSG_DESCRIPTOR)) { if (!SCK_SendMessage(helper_sock_fd, &message, SCK_FLAG_MSG_DESCRIPTOR)) {
/* If sending failed with EPIPE, it means all helpers closed their end of
the socket (e.g. due to a fatal error) */
if (errno == EPIPE)
LOG_FATAL("NTS-KE helpers failed");
SCK_CloseSocket(sock_fd); SCK_CloseSocket(sock_fd);
return; return;
} }
@ -253,7 +274,7 @@ accept_connection(int server_fd, int event, void *arg)
/* ================================================== */ /* ================================================== */
static int static int
open_socket(int family, int port) open_socket(int family)
{ {
IPSockAddr local_addr; IPSockAddr local_addr;
char *iface; char *iface;
@ -263,10 +284,9 @@ open_socket(int family, int port)
return INVALID_SOCK_FD; return INVALID_SOCK_FD;
CNF_GetBindAddress(family, &local_addr.ip_addr); CNF_GetBindAddress(family, &local_addr.ip_addr);
local_addr.port = CNF_GetNtsServerPort();
iface = CNF_GetBindNtpInterface(); iface = CNF_GetBindNtpInterface();
local_addr.port = port;
sock_fd = SCK_OpenTcpSocket(NULL, &local_addr, iface, 0); sock_fd = SCK_OpenTcpSocket(NULL, &local_addr, iface, 0);
if (sock_fd < 0) { if (sock_fd < 0) {
LOG(LOGS_ERR, "Could not open NTS-KE socket on %s", UTI_IPSockAddrToString(&local_addr)); LOG(LOGS_ERR, "Could not open NTS-KE socket on %s", UTI_IPSockAddrToString(&local_addr));
@ -425,7 +445,8 @@ generate_key(int index)
{ {
int key_length; int key_length;
assert(index < MAX_SERVER_KEYS); if (index < 0 || index >= MAX_SERVER_KEYS)
assert(0);
key_length = SIV_GetKeyLength(SERVER_COOKIE_SIV); key_length = SIV_GetKeyLength(SERVER_COOKIE_SIV);
if (key_length > sizeof (server_keys[index].key)) if (key_length > sizeof (server_keys[index].key))
@ -434,12 +455,12 @@ generate_key(int index)
UTI_GetRandomBytesUrandom(server_keys[index].key, key_length); UTI_GetRandomBytesUrandom(server_keys[index].key, key_length);
if (!server_keys[index].siv || if (!server_keys[index].siv ||
!SIV_SetKey(server_keys[index].siv, server_keys[index].key, key_length)) { !SIV_SetKey(server_keys[index].siv, server_keys[index].key, key_length))
LOG_FATAL("Could not set SIV key"); LOG_FATAL("Could not set SIV key");
}
UTI_GetRandomBytes(&server_keys[index].id, sizeof (server_keys[index].id)); UTI_GetRandomBytes(&server_keys[index].id, sizeof (server_keys[index].id));
/* Encode the index in the lowest bits of the ID */
server_keys[index].id &= -1U << KEY_ID_INDEX_BITS; server_keys[index].id &= -1U << KEY_ID_INDEX_BITS;
server_keys[index].id |= index; server_keys[index].id |= index;
@ -488,6 +509,7 @@ save_keys(void)
fclose(f); fclose(f);
/* Rename the temporary file, or remove it if that fails */
if (!UTI_RenameTempFile(dump_dir, DUMP_FILENAME, ".tmp", NULL)) { if (!UTI_RenameTempFile(dump_dir, DUMP_FILENAME, ".tmp", NULL)) {
if (!UTI_RemoveFile(dump_dir, DUMP_FILENAME, ".tmp")) if (!UTI_RemoveFile(dump_dir, DUMP_FILENAME, ".tmp"))
; ;
@ -546,7 +568,7 @@ load_keys(void)
server_keys[index].id = id; server_keys[index].id = id;
if (!SIV_SetKey(server_keys[index].siv, server_keys[index].key, key_length)) if (!SIV_SetKey(server_keys[index].siv, server_keys[index].key, key_length))
assert(0); LOG_FATAL("Could not set SIV key");
DEBUG_LOG("Loaded key %"PRIX32, id); DEBUG_LOG("Loaded key %"PRIX32, id);
@ -577,36 +599,43 @@ key_timeout(void *arg)
/* ================================================== */ /* ================================================== */
static void static void
start_helper(int id, int scfilter_level, int main_fd, int helper_fd) run_helper(uid_t uid, gid_t gid, int scfilter_level)
{ {
pid_t pid; LOG_Severity log_severity;
pid = fork(); /* Finish minimal initialisation and run using the scheduler loop
similarly to the main process */
if (pid < 0) DEBUG_LOG("Helper started");
LOG_FATAL("fork() failed : %s", strerror(errno));
if (pid > 0) /* Suppress a log message about disabled clock control */
return; log_severity = LOG_GetMinSeverity();
LOG_SetMinSeverity(LOGS_ERR);
SCK_CloseSocket(main_fd); SYS_Initialise(0);
LOG_SetMinSeverity(log_severity);
if (!geteuid() && (uid || gid))
SYS_DropRoot(uid, gid);
LOG_CloseParentFd();
SCH_Reset();
SCH_AddFileHandler(helper_fd, SCH_FILE_INPUT, handle_helper_request, NULL);
UTI_SetQuitSignalsHandler(helper_signal, 1); UTI_SetQuitSignalsHandler(helper_signal, 1);
if (scfilter_level != 0) if (scfilter_level != 0)
SYS_EnableSystemCallFilter(scfilter_level, SYS_NTSKE_HELPER); SYS_EnableSystemCallFilter(scfilter_level, SYS_NTSKE_HELPER);
initialised = 1; NKS_Initialise();
DEBUG_LOG("NTS-KE helper #%d started", id);
SCH_MainLoop(); SCH_MainLoop();
NKS_Finalise(); DEBUG_LOG("Helper exiting");
DEBUG_LOG("NTS-KE helper #%d exiting", id); NKS_Finalise();
SCK_Finalise();
SYS_Finalise();
SCH_Finalise();
LCL_Finalise();
PRV_Finalise();
CNF_Finalise();
LOG_Finalise();
exit(0); exit(0);
} }
@ -614,15 +643,65 @@ start_helper(int id, int scfilter_level, int main_fd, int helper_fd)
/* ================================================== */ /* ================================================== */
void void
NKS_Initialise(int scfilter_level) NKS_PreInitialise(uid_t uid, gid_t gid, int scfilter_level)
{
int i, processes, sock_fd1, sock_fd2;
char prefix[16];
pid_t pid;
helper_sock_fd = INVALID_SOCK_FD;
is_helper = 0;
if (!CNF_GetNtsServerCertFile() || !CNF_GetNtsServerKeyFile())
return;
processes = CNF_GetNtsServerProcesses();
if (processes <= 0)
return;
/* Start helper processes to perform (computationally expensive) NTS-KE
sessions with clients on sockets forwarded from the main process */
sock_fd1 = SCK_OpenUnixSocketPair(0, &sock_fd2);
if (sock_fd1 < 0)
LOG_FATAL("Could not open socket pair");
for (i = 0; i < processes; i++) {
pid = fork();
if (pid < 0)
LOG_FATAL("fork() failed : %s", strerror(errno));
if (pid > 0)
continue;
is_helper = 1;
snprintf(prefix, sizeof (prefix), "nks#%d:", i + 1);
LOG_SetDebugPrefix(prefix);
LOG_CloseParentFd();
SCK_CloseSocket(sock_fd1);
SCH_AddFileHandler(sock_fd2, SCH_FILE_INPUT, handle_helper_request, NULL);
run_helper(uid, gid, scfilter_level);
}
SCK_CloseSocket(sock_fd2);
helper_sock_fd = sock_fd1;
}
/* ================================================== */
void
NKS_Initialise(void)
{ {
char *cert, *key; char *cert, *key;
int i, processes;
double key_delay; double key_delay;
int i;
server_sock_fd4 = INVALID_SOCK_FD; server_sock_fd4 = INVALID_SOCK_FD;
server_sock_fd6 = INVALID_SOCK_FD; server_sock_fd6 = INVALID_SOCK_FD;
helper_sock_fd = INVALID_SOCK_FD;
cert = CNF_GetNtsServerCertFile(); cert = CNF_GetNtsServerCertFile();
key = CNF_GetNtsServerKeyFile(); key = CNF_GetNtsServerKeyFile();
@ -630,19 +709,20 @@ NKS_Initialise(int scfilter_level)
if (!cert || !key) if (!cert || !key)
return; return;
server_credentials = NKSN_CreateCertCredentials(cert, key, NULL); if (helper_sock_fd == INVALID_SOCK_FD) {
if (!server_credentials) server_credentials = NKSN_CreateCertCredentials(cert, key, NULL);
return; if (!server_credentials)
return;
} else {
server_credentials = NULL;
}
sessions = ARR_CreateInstance(sizeof (NKSN_Instance)); sessions = ARR_CreateInstance(sizeof (NKSN_Instance));
for (i = 0; i < CNF_GetNtsServerConnections(); i++) for (i = 0; i < CNF_GetNtsServerConnections(); i++)
*(NKSN_Instance *)ARR_GetNewElement(sessions) = NULL; *(NKSN_Instance *)ARR_GetNewElement(sessions) = NULL;
for (i = 0; i < MAX_SERVER_KEYS; i++)
server_keys[i].siv = NULL;
server_sock_fd4 = open_socket(IPADDR_INET4, CNF_GetNtsServerPort());
server_sock_fd6 = open_socket(IPADDR_INET6, CNF_GetNtsServerPort());
/* Generate random keys, even if they will be replaced by reloaded keys,
or unused (in the helper) */
for (i = 0; i < MAX_SERVER_KEYS; i++) { for (i = 0; i < MAX_SERVER_KEYS; i++) {
server_keys[i].siv = SIV_CreateInstance(SERVER_COOKIE_SIV); server_keys[i].siv = SIV_CreateInstance(SERVER_COOKIE_SIV);
generate_key(i); generate_key(i);
@ -650,29 +730,18 @@ NKS_Initialise(int scfilter_level)
current_server_key = MAX_SERVER_KEYS - 1; current_server_key = MAX_SERVER_KEYS - 1;
load_keys(); if (!is_helper) {
server_sock_fd4 = open_socket(IPADDR_INET4);
server_sock_fd6 = open_socket(IPADDR_INET6);
key_rotation_interval = MAX(CNF_GetNtsRotate(), 0); load_keys();
if (key_rotation_interval > 0) { key_rotation_interval = MAX(CNF_GetNtsRotate(), 0);
key_delay = key_rotation_interval - (SCH_GetLastEventMonoTime() - last_server_key_ts);
SCH_AddTimeoutByDelay(MAX(key_delay, 0.0), key_timeout, NULL);
}
processes = CNF_GetNtsServerProcesses(); if (key_rotation_interval > 0) {
key_delay = key_rotation_interval - (SCH_GetLastEventMonoTime() - last_server_key_ts);
if (processes > 0) { SCH_AddTimeoutByDelay(MAX(key_delay, 0.0), key_timeout, NULL);
int sock_fd1, sock_fd2; }
sock_fd1 = SCK_OpenUnixSocketPair(0, &sock_fd2);
if (sock_fd1 < 0)
LOG_FATAL("Could not open socket pair");
for (i = 0; i < processes; i++)
start_helper(i + 1, scfilter_level, sock_fd1, sock_fd2);
SCK_CloseSocket(sock_fd2);
helper_sock_fd = sock_fd1;
} }
initialised = 1; initialised = 1;
@ -689,6 +758,7 @@ NKS_Finalise(void)
return; return;
if (helper_sock_fd != INVALID_SOCK_FD) { if (helper_sock_fd != INVALID_SOCK_FD) {
/* Send the helpers a request to exit */
for (i = 0; i < CNF_GetNtsServerProcesses(); i++) { for (i = 0; i < CNF_GetNtsServerProcesses(); i++) {
if (!SCK_Send(helper_sock_fd, "", 1, 0)) if (!SCK_Send(helper_sock_fd, "", 1, 0))
; ;
@ -700,11 +770,11 @@ NKS_Finalise(void)
if (server_sock_fd6 != INVALID_SOCK_FD) if (server_sock_fd6 != INVALID_SOCK_FD)
SCK_CloseSocket(server_sock_fd6); SCK_CloseSocket(server_sock_fd6);
save_keys(); if (!is_helper)
for (i = 0; i < MAX_SERVER_KEYS; i++) { save_keys();
if (server_keys[i].siv != NULL)
SIV_DestroyInstance(server_keys[i].siv); for (i = 0; i < MAX_SERVER_KEYS; i++)
} SIV_DestroyInstance(server_keys[i].siv);
for (i = 0; i < ARR_GetSize(sessions); i++) { for (i = 0; i < ARR_GetSize(sessions); i++) {
NKSN_Instance session = *(NKSN_Instance *)ARR_GetElement(sessions, i); NKSN_Instance session = *(NKSN_Instance *)ARR_GetElement(sessions, i);
@ -713,7 +783,8 @@ NKS_Finalise(void)
} }
ARR_DestroyInstance(sessions); ARR_DestroyInstance(sessions);
NKSN_DestroyCertCredentials(server_credentials); if (server_credentials)
NKSN_DestroyCertCredentials(server_credentials);
} }
/* ================================================== */ /* ================================================== */
@ -810,7 +881,7 @@ NKS_DecodeCookie(NKE_Cookie *cookie, NKE_Context *context)
return 0; return 0;
} }
if (cookie->length <= sizeof (*header)) { if (cookie->length <= (int)sizeof (*header)) {
DEBUG_LOG("Invalid cookie length"); DEBUG_LOG("Invalid cookie length");
return 0; return 0;
} }

View file

@ -30,7 +30,8 @@
#include "nts_ke.h" #include "nts_ke.h"
/* Init and fini functions */ /* Init and fini functions */
extern void NKS_Initialise(int scfilter_level); extern void NKS_PreInitialise(uid_t uid, gid_t gid, int scfilter_level);
extern void NKS_Initialise(void);
extern void NKS_Finalise(void); extern void NKS_Finalise(void);
/* Save the current server keys */ /* Save the current server keys */

View file

@ -154,6 +154,7 @@ get_record(struct Message *message, int *critical, int *type, int *body_length,
blen = ntohs(header.body_length); blen = ntohs(header.body_length);
rlen = sizeof (header) + blen; rlen = sizeof (header) + blen;
assert(blen >= 0 && rlen > 0);
if (message->length < message->parsed + rlen) if (message->length < message->parsed + rlen)
return 0; return 0;
@ -802,6 +803,9 @@ NKSN_GetRecord(NKSN_Instance inst, int *critical, int *type, int *body_length,
assert(inst->message.complete); assert(inst->message.complete);
if (body_length)
*body_length = 0;
if (!get_record(&inst->message, critical, &type2, body_length, body, buffer_length)) if (!get_record(&inst->message, critical, &type2, body_length, body, buffer_length))
return 0; return 0;

14
sched.c
View file

@ -490,20 +490,6 @@ SCH_RemoveTimeout(SCH_TimeoutID id)
assert(0); assert(0);
} }
/* ================================================== */
void
SCH_Reset(void)
{
while (n_timer_queue_entries > 0)
SCH_RemoveTimeout(timer_queue.next->id);
while (one_highest_fd > 0) {
close(one_highest_fd - 1);
SCH_RemoveFileHandler(one_highest_fd - 1);
}
}
/* ================================================== */ /* ================================================== */
/* Try to dispatch any timeouts that have already gone by, and /* Try to dispatch any timeouts that have already gone by, and
keep going until all are done. (The earlier ones may take so keep going until all are done. (The earlier ones may take so

View file

@ -85,9 +85,6 @@ extern SCH_TimeoutID SCH_AddTimeoutInClass(double min_delay, double separation,
/* The next one probably ought to return a status code */ /* The next one probably ought to return a status code */
extern void SCH_RemoveTimeout(SCH_TimeoutID); extern void SCH_RemoveTimeout(SCH_TimeoutID);
/* Remove all timeouts and close all file descriptors */
extern void SCH_Reset(void);
extern void SCH_MainLoop(void); extern void SCH_MainLoop(void);
extern void SCH_QuitProgram(void); extern void SCH_QuitProgram(void);

View file

@ -539,7 +539,12 @@ NNC_GetReport(NNC_Instance inst, RPT_AuthReport *report)
} }
void void
NKS_Initialise(int scfilter_level) NKS_PreInitialise(uid_t uid, gid_t gid, int scfilter_level)
{
}
void
NKS_Initialise(void)
{ {
} }

View file

@ -35,7 +35,7 @@ prepare_response(NKSN_Instance session, int valid)
if (valid) if (valid)
index = -1; index = -1;
else else
index = random() % 9; index = random() % 10;
DEBUG_LOG("index=%d", index); DEBUG_LOG("index=%d", index);
NKSN_BeginMessage(session); NKSN_BeginMessage(session);
@ -89,8 +89,12 @@ prepare_response(NKSN_Instance session, int valid)
} }
if (index != 8) { if (index != 8) {
for (i = 0; i < NKE_MAX_COOKIES; i++) for (i = 0; i < NKE_MAX_COOKIES; i++) {
length = (random() % sizeof (data) + 1) / 4 * 4;
if (index == 9)
length += random() % 3 + 1;
TEST_CHECK(NKSN_AddRecord(session, 0, NKE_RECORD_COOKIE, data, length)); TEST_CHECK(NKSN_AddRecord(session, 0, NKE_RECORD_COOKIE, data, length));
}
} }
TEST_CHECK(NKSN_EndMessage(session)); TEST_CHECK(NKSN_EndMessage(session));

View file

@ -154,7 +154,8 @@ test_unit(void)
SCH_Initialise(); SCH_Initialise();
unlink("ntskeys"); unlink("ntskeys");
NKS_Initialise(0); NKS_PreInitialise(0, 0, 0);
NKS_Initialise();
session = NKSN_CreateInstance(1, NULL, handle_message, NULL); session = NKSN_CreateInstance(1, NULL, handle_message, NULL);

View file

@ -126,7 +126,8 @@ test_unit(void)
LCL_Initialise(); LCL_Initialise();
TST_RegisterDummyDrivers(); TST_RegisterDummyDrivers();
SCH_Initialise(); SCH_Initialise();
NKS_Initialise(0); NKS_PreInitialise(0, 0, 0);
NKS_Initialise();
NNS_Initialise(); NNS_Initialise();
for (i = 0; i < 50000; i++) { for (i = 0; i < 50000; i++) {