1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-06 00:13:33 +00:00

1. Fixed bug where NetworkTimeout Error, caused duplicate connection

2. Fixed dispatcher on Windows to put username in quotes
3. Added additional logging
4. Added TLS/ALPN support
This commit is contained in:
Bryan Roe
2021-02-04 12:57:36 -08:00
parent 4a42d731b0
commit 6f28cdb484
8 changed files with 189 additions and 34 deletions

View File

@@ -3389,7 +3389,7 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
{
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)user1;
ILibChain_Link_SetMetadata(ILibChain_GetCurrentLink(agent->chain), "MeshServer_ControlChannel");
if (agent->controlChannelRequest != NULL)
{
ILibLifeTime_Remove(ILibGetBaseTimer(agent->chain), agent->controlChannelRequest);
@@ -3408,8 +3408,8 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
{
if (agent->controlChannelDebug != 0)
{
printf("Control Channel Connection Established...\n");
ILIBLOGMESSAGEX("Control Channel Connection Established...");
printf("Control Channel Connection Established [%d]...\n", ILibWebClient_GetDescriptorValue_FromStateObject(WebStateObject));
ILIBLOGMESSAGEX("Control Channel Connection Established [%d]...", ILibWebClient_GetDescriptorValue_FromStateObject(WebStateObject));
}
#ifndef MICROSTACK_NOTLS
int len;
@@ -3471,8 +3471,8 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
{
if (agent->controlChannelDebug != 0)
{
printf("TLS Server Cert matches Mesh Server Cert...\n");
ILIBLOGMESSAGEX("TLS Server Cert matches Mesh Server Cert...");
printf("TLS Server Cert matches Mesh Server Cert [%d]...\n", ILibWebClient_GetDescriptorValue_FromStateObject(WebStateObject));
ILIBLOGMESSAGEX("TLS Server Cert matches Mesh Server Cert [%d]...", ILibWebClient_GetDescriptorValue_FromStateObject(WebStateObject));
}
// The TLS certificate of this server is correct, no need to authenticate further.
unsigned short response = htons(MeshCommand_AuthConfirm); // Send indication to the server that it's already authenticated
@@ -3503,8 +3503,8 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
case ILibWebClient_ReceiveStatus_Complete: // Disconnection
if (agent->controlChannelDebug != 0)
{
printf("Control Channel Disconnected...\n");
ILIBLOGMESSAGEX("Control Channel Disconnected...");
printf("Control Channel Disconnected [%d]...\n", ILibWebClient_GetDescriptorValue_FromStateObject(WebStateObject));
ILIBLOGMESSAGEX("Control Channel Disconnected [%d]...", ILibWebClient_GetDescriptorValue_FromStateObject(WebStateObject));
}
// If the channel had been authenticated, inform JavaScript core module that we are not disconnected
@@ -3565,11 +3565,11 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
{
if (ILibIsChainBeingDestroyed(agent->chain)) { return; }
ILibRemoteLogging_printf(ILibChainGetLogger(ILibWebClient_GetChainFromWebStateObject(WebStateObject)), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "Agent Host Container: Mesh Server Connection Error, trying again later.");
printf("Mesh Server Connection Error\n");
printf("Mesh Server Connection Error [%d]\n", ILibWebClient_GetDescriptorValue_FromStateObject(WebStateObject));
if (agent->logUpdate != 0)
{
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "Connection Error [%p, %d]...\n", WebStateObject, InterruptFlag);
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "Connection Error [%p, %d, [%d]]...\n", WebStateObject, InterruptFlag, ILibWebClient_GetDescriptorValue_FromStateObject(WebStateObject));
ILIBLOGMESSSAGE(ILibScratchPad);
}

File diff suppressed because one or more lines are too long

View File

@@ -203,7 +203,19 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
#ifndef MICROSTACK_NOTLS
if (ptrs->ssl != NULL)
{
const unsigned char *alpn = NULL;
size_t alpnLen = 0;
SSL_SESSION_get0_alpn_selected(SSL_get_session(ptrs->ssl), &alpn, &alpnLen);
duk_push_heapptr(ptrs->ctx, ptrs->object); // [socket]
if (alpnLen != 0)
{
duk_push_lstring(ptrs->ctx, alpn, alpnLen);
}
else
{
duk_push_null(ptrs->ctx);
}
duk_put_prop_string(ptrs->ctx, -2, "alpnProtocol");
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [socket][emit]
duk_swap_top(ptrs->ctx, -2); // [emit][this]
duk_push_string(ptrs->ctx, "secureConnect"); // [emit][this][secureConnect]
@@ -2116,6 +2128,55 @@ static int ILibDuktape_tls_server_sniCallback(SSL *s, int *ad, void *arg)
duk_pop_2(data->ctx); // ...
return(SSL_TLSEXT_ERR_OK);
}
int ILibDuktape_tls_server_alpnSink(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
{
int ret = SSL_TLSEXT_ERR_ALERT_FATAL;
ILibDuktape_net_server *server = (ILibDuktape_net_server*)arg;
duk_push_heapptr(server->ctx, server->self); // [server]
duk_push_array(server->ctx); // [server][array]
while (inlen > 0)
{
duk_push_lstring(server->ctx, (const char*)in + 1, (duk_size_t)in[0]); // [server][array][string]
duk_array_push(server->ctx, -2); // [server][array]
inlen -= (1 + in[0]);
in += (1 + in[0]);
}
duk_get_prop_string(server->ctx, -2, ILibDuktape_SERVER2OPTIONS); // [server][array][options]
duk_get_prop_string(server->ctx, -1, "alpnCallback"); // [server][array][options][callback]
if (!duk_is_null_or_undefined(server->ctx, -1))
{
duk_dup(server->ctx, -4); // [server][array][options][callback][this]
duk_dup(server->ctx, -4); // [server][array][options][callback][this][array]
if (duk_pcall_method(server->ctx, 1) == 0) // [server][array][options][ret]
{
while (duk_get_length(server->ctx, -3) > 0)
{
duk_array_pop(server->ctx, -3); // [server][array][options][ret][string]
const char *str1 = duk_get_string(server->ctx, -2);
const char *str2 = duk_get_string(server->ctx, -1);
if (strcmp(str1, str2) == 0)
{
char *a = (char*)Duktape_PushBuffer(server->ctx, duk_get_length(server->ctx, -1));
duk_put_prop_string(server->ctx, -5, "_alpnselect");
memcpy_s(a, ILibMemory_Size(a), str2, ILibMemory_Size(a));
*out = a;
*outlen = (unsigned char)ILibMemory_Size(a);
ret = SSL_TLSEXT_ERR_OK;
duk_pop(server->ctx); // [server][array][options][ret]
break;
}
duk_pop(server->ctx); // [server][array][options][ret]
}
}
duk_pop(server->ctx); // [server][array][options]
}
else
{
duk_pop(server->ctx); // [server][array][options]
}
duk_pop_3(server->ctx); // ...
return(ret);
}
duk_ret_t ILibDuktape_tls_server_addContext(duk_context *ctx)
{
duk_size_t hostLen;
@@ -2137,6 +2198,43 @@ duk_ret_t ILibDuktape_tls_server_addContext(duk_context *ctx)
{
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, ILibDuktape_TLS_server_verify);
}
if (duk_has_prop_string(ctx, -1, "ALPNProtocols"))
{
int status = 0;
duk_size_t protoLen = 0;
unsigned char *alpn = NULL;
duk_push_this(ctx); // [options][server]
duk_uarridx_t i;
duk_get_prop_string(ctx, -2, "ALPNProtocols"); // [options][server][Array]
duk_uarridx_t len = (duk_uarridx_t)duk_get_length(ctx, -1);
for (i = 0; i < len; ++i)
{
duk_get_prop_index(ctx, -1, i); // [options][server][Array][string]
protoLen += (1 + duk_get_length(ctx, -1));
duk_pop(ctx); // [options][server][Array]
}
if (protoLen > 0)
{
char *buf; duk_size_t bufLen;
alpn = (unsigned char*)Duktape_PushBuffer(ctx, protoLen); // [options][server][Array][buffer]
duk_put_prop_string(ctx, -3, "_ALPN"); // [options][server][Array]
protoLen = 0;
for (i = 0; i < len; ++i)
{
duk_get_prop_index(ctx, -1, i); // [options][server][Array][buffer]
buf = (char*)duk_get_lstring(ctx, -1, &bufLen);
alpn[protoLen] = (unsigned char)bufLen; ++protoLen;
memcpy_s(alpn + protoLen, ILibMemory_Size(alpn) - protoLen, buf, bufLen);
protoLen += bufLen;
duk_pop(ctx); // [options][server][Array]
}
status = SSL_CTX_set_alpn_protos(ssl_ctx, alpn, (unsigned int)protoLen);
SSL_CTX_set_alpn_select_cb(ssl_ctx, ILibDuktape_tls_server_alpnSink, Duktape_GetBufferProperty(ctx, -3, ILibDuktape_net_Server_buffer));
}
duk_pop_2(ctx); // [options]
}
duk_get_prop_string(ctx, -3, ILibDuktape_net_Server_buffer);// [server][table][options][buffer]
ILibDuktape_net_server *server = (ILibDuktape_net_server*)Duktape_GetBuffer(ctx, -1, NULL);
if (server->server != NULL)
@@ -2181,8 +2279,15 @@ duk_ret_t ILibDuktape_TLS_exportKeys(duk_context *ctx)
return(ILibDuktape_Error(ctx, "Error exporting OpenSSL Keys"));
}
#endif
int ILibDuktape_TLS_ALPNCB(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
{
return(SSL_TLSEXT_ERR_OK);
}
duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
{
int status = 0;
unsigned char* alpn = NULL;
unsigned int protoLen = 0;
int nargs = duk_get_top(ctx), i;
if (nargs > 0 && duk_is_number(ctx, 0))
{
@@ -2256,7 +2361,39 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
{
return(ILibDuktape_Error(ctx, "Invalid SecureContext Object"));
}
SSL_CTX_set_verify(data->ssl_ctx, SSL_VERIFY_PEER, ILibDuktape_TLS_verify); /* Ask for authentication */
SSL_CTX_set_verify(data->ssl_ctx, SSL_VERIFY_PEER, ILibDuktape_TLS_verify); /* Ask for authentication */
SSL_CTX_set_next_proto_select_cb(data->ssl_ctx, ILibDuktape_TLS_ALPNCB, data);
if (duk_has_prop_string(ctx, 0, "ALPNProtocols"))
{
duk_uarridx_t i;
duk_get_prop_string(ctx, 0, "ALPNProtocols"); // [Array]
duk_uarridx_t len = (duk_uarridx_t)duk_get_length(ctx, -1);
for (i = 0; i < len; ++i)
{
duk_get_prop_index(ctx, -1, i); // [socket][options][secureContext][Array][string]
protoLen += (1 + (unsigned int)duk_get_length(ctx, -1));
duk_pop(ctx); // [socket][options][secureContext][Array]
}
if (protoLen > 0)
{
char *buf; duk_size_t bufLen;
alpn = (unsigned char*)Duktape_PushBuffer(ctx, protoLen);// [socket][options][secureContext][Array][buffer]
duk_put_prop_string(ctx, -5, "_ALPN"); // [socket][options][secureContext][Array]
protoLen = 0;
for (i = 0; i < len; ++i)
{
duk_get_prop_index(ctx, -1, i); // [socket][options][secureContext][Array][buffer]
buf = (char*)duk_get_lstring(ctx, -1, &bufLen);
alpn[protoLen] = (unsigned char)bufLen; ++protoLen;
memcpy_s(alpn + protoLen, ILibMemory_Size(alpn) - protoLen, buf, bufLen);
protoLen += (unsigned int)bufLen;
duk_pop(ctx); // [socket][options][secureContext][Array]
}
status = SSL_CTX_set_alpn_protos(data->ssl_ctx, alpn, protoLen);
}
duk_pop(ctx); // [socket][options][secureContext]
}
duk_remove(ctx, -2); // [socket][secureContext]
duk_put_prop_string(ctx, -2, ILibDuktape_TLSSocket2SecureContext);
@@ -2357,6 +2494,7 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
}
data->ssl = ILibAsyncSocket_SetSSLContextEx(data->socketModule, data->ssl_ctx, ILibAsyncSocket_TLS_Mode_Client, sniname);
SSL_set_ex_data(data->ssl, ILibDuktape_TLS_ctx2socket, data);
//status = SSL_set_alpn_protos(data->ssl, alpn, protoLen);
}
return(1);

View File

@@ -244,6 +244,7 @@ typedef struct ILibWebClientDataObject
ILibWebClient_TimeoutHandler timeoutHandler;
void *timeoutUser;
int __tmpDescriptor;
#ifndef MICROSTACK_NOTLS
ILibWebClient_RequestToken_HTTPS requestMode;
@@ -314,6 +315,10 @@ typedef struct ILibWebClient_WebSocketState
void* pingPongUser;
}ILibWebClient_WebSocketState;
int ILibWebClient_GetDescriptorValue_FromStateObject(ILibWebClient_StateObject state)
{
return((state != NULL ? ((ILibWebClientDataObject*)state)->__tmpDescriptor : -1));
}
int *ILibWebClient_WCDO_ServerFlag(ILibWebClient_StateObject j)
{
return(&(((ILibWebClientDataObject*)j)->Server));
@@ -2069,6 +2074,14 @@ void ILibWebClient_OnConnect(ILibAsyncSocket_SocketModule socketModule, int Conn
if (wcdo->Closing != 0) return; // Already closing, exit now
wcdo->SOCK = socketModule;
if (socketModule != NULL)
{
#ifdef WIN32
wcdo->__tmpDescriptor = (int)((SOCKET*)ILibAsyncSocket_GetSocket(socketModule))[0];
#else
wcdo->__tmpDescriptor = ((int*)ILibAsyncSocket_GetSocket(socketModule))[0];
#endif
}
wcdo->InitialRequestAnswered = 0;
wcdo->DisconnectSent = 0;
wcdo->PendingConnectionIndex = 0;
@@ -2345,7 +2358,15 @@ void ILibWebClient_PreProcess(void* WebClientModule, fd_set *readset, fd_set *wr
// We need SOCKET information to timeout connect for Network Discovery purpose.
wcdo->SOCK = wcm->socks[i];
if (wcm->socks[i] != NULL)
{
#ifdef WIN32
wcdo->__tmpDescriptor = (int)((SOCKET*)ILibAsyncSocket_GetSocket(wcm->socks[i]))[0];
#else
wcdo->__tmpDescriptor = ((int*)ILibAsyncSocket_GetSocket(wcm->socks[i]))[0];
#endif
}
// Addition for TLS purpose
#ifndef MICROSTACK_NOTLS
if (wcm->ssl_ctx != NULL && wcdo->requestMode == ILibWebClient_RequestToken_USE_HTTPS)
@@ -2453,6 +2474,14 @@ ILibWebClient_StateObject ILibCreateWebClientEx(ILibWebClient_OnResponse OnRespo
wcdo->Server = 1;
wcdo->SOCK = socketModule;
wcdo->PendingConnectionIndex = -1;
if (socketModule != NULL)
{
#ifdef WIN32
wcdo->__tmpDescriptor = (int)((SOCKET*)ILibAsyncSocket_GetSocket(socketModule))[0];
#else
wcdo->__tmpDescriptor = ((int*)ILibAsyncSocket_GetSocket(socketModule))[0];
#endif
}
wr = (struct ILibWebRequest*)ILibMemory_SmartAllocate(sizeof(struct ILibWebRequest));
wr->OnResponse = OnResponse;
@@ -3141,7 +3170,7 @@ void ILibWebClient_CancelRequestEx(void *chain, void *RequestToken)
*/
void ILibWebClient_CancelRequest(ILibWebClient_RequestToken RequestToken)
{
if (ILibMemory_CanaryOK(RequestToken))
if (ILibMemory_CanaryOK(((ILibWebClient_PipelineRequestToken*)RequestToken)->parent))
{
ILibChain_RunOnMicrostackThread(((struct ILibWebClient_PipelineRequestToken*)RequestToken)->wcdo->Parent->ChainLink.ParentChain, ILibWebClient_CancelRequestEx, RequestToken);
}

View File

@@ -306,6 +306,8 @@ void ILibWebClient_WebSocket_SetPingPongHandler(ILibWebClient_StateObject state,
typedef void(*ILibWebClient_TimeoutHandler)(ILibWebClient_StateObject state, void *user);
void ILibWebClient_SetTimeout(ILibWebClient_StateObject state, int timeoutSeconds, ILibWebClient_TimeoutHandler handler, void *user);
int ILibWebClient_GetDescriptorValue_FromStateObject(ILibWebClient_StateObject state);
// OpenSSL supporting code
#ifndef MICROSTACK_NOTLS
X509* ILibWebClient_SslGetCert(void* socketModule);

View File

@@ -28,7 +28,7 @@ function task()
{
this.getTaskXml = function getTaskXml(name)
{
var child = require('child_process').execFile(process.env['windir'] + '\\system32\\schtasks.exe', ['schtasks', '/QUERY', '/TN ' + name, '/XML']);
var child = require('child_process').execFile(process.env['windir'] + '\\system32\\schtasks.exe', ['schtasks', '/QUERY', '/TN "' + name+'"', '/XML']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
child.waitExit();
@@ -39,7 +39,7 @@ function task()
{
if (!xml)
{
var child = require('child_process').execFile(process.env['windir'] + '\\system32\\schtasks.exe', ['schtasks', '/QUERY', '/TN ' + name, '/XML']);
var child = require('child_process').execFile(process.env['windir'] + '\\system32\\schtasks.exe', ['schtasks', '/QUERY', '/TN "' + name + '"', '/XML']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
child.waitExit();
@@ -54,7 +54,7 @@ function task()
{
if (!xml)
{
var child = require('child_process').execFile(process.env['windir'] + '\\system32\\schtasks.exe', ['schtasks', '/QUERY', '/TN ' + name, '/XML']);
var child = require('child_process').execFile(process.env['windir'] + '\\system32\\schtasks.exe', ['schtasks', '/QUERY', '/TN "' + name + '"', '/XML']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
child.waitExit();

View File

@@ -112,11 +112,13 @@ function _execv(exePath, argarr)
}
var i;
var tmp = [];
var path = require('_GenericMarshal').CreateVariable(exePath);
var args = require('_GenericMarshal').CreateVariable((1 + argarr.length) * require('_GenericMarshal').PointerSize);
for (i = 0; i < argarr.length; ++i)
{
var arg = require('_GenericMarshal').CreateVariable(argarr[i]);
tmp.push(arg);
arg.pointerBuffer().copy(args.toBuffer(), i * require('_GenericMarshal').PointerSize);
}

View File

@@ -80,23 +80,7 @@ function dispatch(options)
this.parent.emit('connection', s);
});
var parms = '/C SCHTASKS /CREATE /F /TN MeshUserTask /SC ONCE /ST 00:00 ';
if (options.user)
{
// Specified User
parms += ('/RU ' + options.user + ' ');
}
else
{
if (require('user-sessions').getProcessOwnerName(process.pid).tsid == 0)
{
// LocalSystem
parms += ('/RU SYSTEM ');
}
}
parms += ('/TR "\\"' + process.execPath + '\\" -b64exec ' + str + '"');
var taskoptions = { env: { _target: process.execPath, _args: '-b64exec ' + str, _user: options.user } };
var taskoptions = { env: { _target: process.execPath, _args: '-b64exec ' + str, _user: '"' + options.user + '"' } };
for (var c1e in process.env)
{
taskoptions.env[c1e] = process.env[c1e];