1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-23 03:33:35 +00:00

Updated Proxy Support: (DNS resolved by proxy)

1. Added ILibAsyncSocket_ConnectToProxyEx()
2. Updated net.socket and tls.socket to use updated proxy method
This commit is contained in:
Bryan Roe
2021-06-20 21:40:34 -07:00
parent 0ea6e28021
commit f38283a9d8
2 changed files with 75 additions and 21 deletions

View File

@@ -544,6 +544,21 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx)
ILibDuktape_CreateReadonlyProperty(ctx, "remoteHost"); // [socket] ILibDuktape_CreateReadonlyProperty(ctx, "remoteHost"); // [socket]
duk_pop(ctx); // ... duk_pop(ctx); // ...
if (duk_is_object(ctx, 0) && duk_has_prop_string(ctx, 0, "proxy"))
{
duk_get_prop_string(ctx, 0, "proxy");
ILibResolveEx(Duktape_GetStringPropertyValue(ctx, -1, "host", NULL), (unsigned short)Duktape_GetIntPropertyValue(ctx, -1, "port", 0), &proxy);
duk_pop(ctx);
// If we are going to use a proxy, we need to have the proxy resolve the remote host
duk_push_sprintf(ctx, "%s:%d", host, port); // [socket][string]
duk_swap_top(ctx, -2); // [string][socket]
ILibAsyncSocket_ConnectToProxyEx(ptrs->socketModule, NULL, (char*)duk_get_string(ctx, -2), (struct sockaddr*)&proxy, Duktape_GetStringPropertyValue(ctx, -1, "username", NULL), Duktape_GetStringPropertyValue(ctx, -1, "password", NULL), NULL, ptrs);
return(0);
}
ILibResolveEx(host, (unsigned short)port, &dest); ILibResolveEx(host, (unsigned short)port, &dest);
if (dest.sin6_family == AF_UNSPEC || (duk_is_object(ctx, 0) && duk_has_prop_string(ctx, 0, "proxy") && proxy.sin6_family == AF_UNSPEC)) if (dest.sin6_family == AF_UNSPEC || (duk_is_object(ctx, 0) && duk_has_prop_string(ctx, 0, "proxy") && proxy.sin6_family == AF_UNSPEC))
{ {
@@ -578,17 +593,8 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx)
duk_pop(ptrs->ctx); duk_pop(ptrs->ctx);
} }
else else
{
if(duk_is_object(ctx, 0) && duk_has_prop_string(ctx, 0, "proxy"))
{
duk_get_prop_string(ctx, 0, "proxy");
ILibAsyncSocket_ConnectToProxy(ptrs->socketModule, NULL, (struct sockaddr*)&dest, (struct sockaddr*)&proxy, Duktape_GetStringPropertyValue(ctx, -1, "username", NULL), Duktape_GetStringPropertyValue(ctx, -1, "password", NULL), NULL, ptrs);
duk_pop(ctx);
}
else
{ {
ILibAsyncSocket_ConnectTo(ptrs->socketModule, NULL, (struct sockaddr*)&dest, NULL, ptrs); ILibAsyncSocket_ConnectTo(ptrs->socketModule, NULL, (struct sockaddr*)&dest, NULL, ptrs);
}
duk_push_heapptr(ptrs->ctx, ptrs->object); // [sockat] duk_push_heapptr(ptrs->ctx, ptrs->object); // [sockat]
duk_push_true(ptrs->ctx); // [socket][connecting] duk_push_true(ptrs->ctx); // [socket][connecting]
@@ -2473,6 +2479,15 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
duk_get_prop_string(ctx, 0, "proxy"); duk_get_prop_string(ctx, 0, "proxy");
ILibResolveEx(Duktape_GetStringPropertyValue(ctx, -1, "host", NULL), (unsigned short)Duktape_GetIntPropertyValue(ctx, -1, "port", 0), &proxy); ILibResolveEx(Duktape_GetStringPropertyValue(ctx, -1, "host", NULL), (unsigned short)Duktape_GetIntPropertyValue(ctx, -1, "port", 0), &proxy);
duk_pop(ctx); duk_pop(ctx);
// If we are going to use a proxy, we need to have the proxy resolve the remote host
duk_push_sprintf(ctx, "%s:%d", host, port); // [socket][string]
duk_swap_top(ctx, -2); // [string][socket]
ILibAsyncSocket_ConnectToProxyEx(data->socketModule, NULL, (char*)duk_get_string(ctx, -2), (struct sockaddr*)&proxy, Duktape_GetStringPropertyValue(ctx, -1, "username", NULL), Duktape_GetStringPropertyValue(ctx, -1, "password", NULL), NULL, data);
data->ssl = ILibAsyncSocket_SetSSLContextEx(data->socketModule, data->ssl_ctx, ILibAsyncSocket_TLS_Mode_Client, sniname);
SSL_set_ex_data(data->ssl, ILibDuktape_TLS_ctx2socket, data);
return(1);
} }
if (hostLen > 0 && hostLen < 1024 && host[0] == '[') if (hostLen > 0 && hostLen < 1024 && host[0] == '[')

View File

@@ -154,6 +154,7 @@ typedef struct ILibAsyncSocketModule
// The address and port of a HTTPS proxy // The address and port of a HTTPS proxy
struct sockaddr_in6 ProxyAddress; struct sockaddr_in6 ProxyAddress;
char ProxiedHost[255]; char ProxiedHost[255];
char ProxiedRemoteHost[255];
int ProxyState; int ProxyState;
char* ProxyUser; char* ProxyUser;
char* ProxyPass; char* ProxyPass;
@@ -909,6 +910,8 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
#endif #endif
// Setup // Setup
if (remoteInterface != NULL)
{
if (remoteInterface->sa_family == AF_UNIX) if (remoteInterface->sa_family == AF_UNIX)
{ {
#ifdef _POSIX #ifdef _POSIX
@@ -920,6 +923,7 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
{ {
memcpy_s(&(module->RemoteAddress), sizeof(struct sockaddr_in6), remoteInterface, INET_SOCKADDR_LENGTH(remoteInterface->sa_family)); memcpy_s(&(module->RemoteAddress), sizeof(struct sockaddr_in6), remoteInterface, INET_SOCKADDR_LENGTH(remoteInterface->sa_family));
} }
}
module->PendingBytesToSend = 0; module->PendingBytesToSend = 0;
module->TotalBytesSent = 0; module->TotalBytesSent = 0;
module->PAUSE = 0; module->PAUSE = 0;
@@ -934,7 +938,14 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
{ {
memset(&any, 0, sizeof(struct sockaddr_in6)); memset(&any, 0, sizeof(struct sockaddr_in6));
#ifdef MICROSTACK_PROXY #ifdef MICROSTACK_PROXY
if (module->ProxyAddress.sin6_family == 0) any.sin6_family = remoteInterface->sa_family; else any.sin6_family = module->ProxyAddress.sin6_family; if (module->ProxyAddress.sin6_family == 0)
{
any.sin6_family = remoteInterface->sa_family;
}
else
{
any.sin6_family = module->ProxyAddress.sin6_family;
}
#else #else
any.sin6_family = remoteInterface->sa_family; any.sin6_family = remoteInterface->sa_family;
#endif #endif
@@ -1068,6 +1079,7 @@ void ILibAsyncSocket_ConnectToProxy(void* socketModule, struct sockaddr *localIn
{ {
struct ILibAsyncSocketModule *module = (struct ILibAsyncSocketModule*)socketModule; struct ILibAsyncSocketModule *module = (struct ILibAsyncSocketModule*)socketModule;
memset(&(module->ProxyAddress), 0, sizeof(struct sockaddr_in6)); memset(&(module->ProxyAddress), 0, sizeof(struct sockaddr_in6));
memset(module->ProxiedRemoteHost, 0, sizeof(module->ProxiedRemoteHost));
module->ProxyState = 0; module->ProxyState = 0;
module->ProxyUser = proxyUser; // Proxy user & password are kept by reference!!! module->ProxyUser = proxyUser; // Proxy user & password are kept by reference!!!
module->ProxyPass = proxyPass; module->ProxyPass = proxyPass;
@@ -1077,6 +1089,17 @@ void ILibAsyncSocket_ConnectToProxy(void* socketModule, struct sockaddr *localIn
} }
void ILibAsyncSocket_ConnectToProxyEx(void* socketModule, struct sockaddr *localInterface, char *remoteAddressAndPort, struct sockaddr *proxyAddress, char* proxyUser, char* proxyPass, ILibAsyncSocket_OnInterrupt InterruptPtr, void *user) void ILibAsyncSocket_ConnectToProxyEx(void* socketModule, struct sockaddr *localInterface, char *remoteAddressAndPort, struct sockaddr *proxyAddress, char* proxyUser, char* proxyPass, ILibAsyncSocket_OnInterrupt InterruptPtr, void *user)
{ {
struct ILibAsyncSocketModule *module = (struct ILibAsyncSocketModule*)socketModule;
memset(&(module->ProxyAddress), 0, sizeof(struct sockaddr_in6));
module->ProxyState = 0;
module->ProxyUser = proxyUser; // Proxy user & password are kept by reference!!!
module->ProxyPass = proxyPass;
size_t proxylen = strnlen_s(remoteAddressAndPort, sizeof(module->ProxiedRemoteHost) - 1);
memcpy_s(module->ProxiedRemoteHost, sizeof(module->ProxiedRemoteHost), remoteAddressAndPort, proxylen);
if (proxyAddress != NULL) memcpy_s(&(module->ProxyAddress), sizeof(struct sockaddr_in6), proxyAddress, INET_SOCKADDR_LENGTH(proxyAddress->sa_family));
ILibAsyncSocket_ConnectTo(socketModule, localInterface, NULL, InterruptPtr, user);
} }
#endif #endif
@@ -1812,13 +1835,29 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
int len2; int len2;
ILibInet_ntop((int)(module->RemoteAddress.sin6_family), (void*)&(((struct sockaddr_in*)&(module->RemoteAddress))->sin_addr), ILibScratchPad, 4096); ILibInet_ntop((int)(module->RemoteAddress.sin6_family), (void*)&(((struct sockaddr_in*)&(module->RemoteAddress))->sin_addr), ILibScratchPad, 4096);
if (module->ProxyUser == NULL || module->ProxyPass == NULL) if (module->ProxyUser == NULL || module->ProxyPass == NULL)
{
if (module->ProxiedRemoteHost[0] != 0)
{
len2 = sprintf_s(ILibScratchPad2, 4096, "CONNECT %s HTTP/1.1\r\nProxy-Connection: keep-alive\r\nHost: %s\r\n\r\n", module->ProxiedRemoteHost, module->ProxiedRemoteHost);
}
else
{ {
len2 = sprintf_s(ILibScratchPad2, 4096, "CONNECT %s:%u HTTP/1.1\r\nProxy-Connection: keep-alive\r\nHost: %s\r\n\r\n", ILibScratchPad, ntohs(module->RemoteAddress.sin6_port), ILibScratchPad); len2 = sprintf_s(ILibScratchPad2, 4096, "CONNECT %s:%u HTTP/1.1\r\nProxy-Connection: keep-alive\r\nHost: %s\r\n\r\n", ILibScratchPad, ntohs(module->RemoteAddress.sin6_port), ILibScratchPad);
} else { }
}
else
{
char* ProxyAuth = NULL; char* ProxyAuth = NULL;
len2 = sprintf_s(ILibScratchPad2, 4096, "%s:%s", module->ProxyUser, module->ProxyPass); len2 = sprintf_s(ILibScratchPad2, 4096, "%s:%s", module->ProxyUser, module->ProxyPass);
len2 = ILibBase64Encode((unsigned char*)ILibScratchPad2, len2, (unsigned char**)&ProxyAuth); len2 = ILibBase64Encode((unsigned char*)ILibScratchPad2, len2, (unsigned char**)&ProxyAuth);
if (module->ProxiedRemoteHost[0] != 0)
{
len2 = sprintf_s(ILibScratchPad2, 4096, "CONNECT %s HTTP/1.1\r\nProxy-Connection: keep-alive\r\nHost: %s\r\nProxy-authorization: basic %s\r\n\r\n", module->ProxiedRemoteHost, module->ProxiedRemoteHost, ProxyAuth);
}
else
{
len2 = sprintf_s(ILibScratchPad2, 4096, "CONNECT %s:%u HTTP/1.1\r\nProxy-Connection: keep-alive\r\nHost: %s\r\nProxy-authorization: basic %s\r\n\r\n", ILibScratchPad, ntohs(module->RemoteAddress.sin6_port), ILibScratchPad, ProxyAuth); len2 = sprintf_s(ILibScratchPad2, 4096, "CONNECT %s:%u HTTP/1.1\r\nProxy-Connection: keep-alive\r\nHost: %s\r\nProxy-authorization: basic %s\r\n\r\n", ILibScratchPad, ntohs(module->RemoteAddress.sin6_port), ILibScratchPad, ProxyAuth);
}
if (ProxyAuth != NULL) free(ProxyAuth); if (ProxyAuth != NULL) free(ProxyAuth);
} }
module->timeout_lastActivity = ILibGetUptime(); module->timeout_lastActivity = ILibGetUptime();