This commit is contained in:
DavidXanatos 2024-07-21 19:29:08 +02:00
parent 892238fcde
commit 05b0ff6302
5 changed files with 96 additions and 16 deletions

View File

@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- added hwid display - added hwid display
- added Language Spoof "CustomLCID=1033" [#4024](https://github.com/sandboxie-plus/Sandboxie/pull/4024) (thanks Yeyixiao) - added Language Spoof "CustomLCID=1033" [#4024](https://github.com/sandboxie-plus/Sandboxie/pull/4024) (thanks Yeyixiao)
- added option to always run the sandman UI as admin [#4090](https://github.com/sandboxie-plus/Sandboxie/issues/4090) - added option to always run the sandman UI as admin [#4090](https://github.com/sandboxie-plus/Sandboxie/issues/4090)
- added Proxy exclusion [#4036](https://github.com/sandboxie-plus/Sandboxie/issues/4036)
### Fixed ### Fixed
- fixed two supporter certificate popping up every time a Sandboxes' settings are opened [#4074](https://github.com/sandboxie-plus/Sandboxie/issues/4074) - fixed two supporter certificate popping up every time a Sandboxes' settings are opened [#4074](https://github.com/sandboxie-plus/Sandboxie/issues/4074)

View File

@ -21,7 +21,7 @@ struct _NETFW_RULE
int protocol; int protocol;
}; };
static int NetFw_PortCmp(const void * l, const void * r) int NetFw_PortCmp(const void * l, const void * r)
{ {
if (*((USHORT*)l) > *((USHORT*)r)) if (*((USHORT*)l) > *((USHORT*)r))
return 1; return 1;
@ -30,7 +30,7 @@ static int NetFw_PortCmp(const void * l, const void * r)
return 0; return 0;
} }
static int NetFw_IpCmp(const void * l, const void * r) int NetFw_IpCmp(const void * l, const void * r)
{ {
IP_ADDRESS* L = (IP_ADDRESS*)l; IP_ADDRESS* L = (IP_ADDRESS*)l;
IP_ADDRESS* R = (IP_ADDRESS*)r; IP_ADDRESS* R = (IP_ADDRESS*)r;

View File

@ -35,6 +35,7 @@
#include "common/base64.c" #include "common/base64.c"
#include "core/drv/api_defs.h" #include "core/drv/api_defs.h"
#include "core/drv/verify.h" #include "core/drv/verify.h"
#include "common/rbtree.h"
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -280,6 +281,8 @@ struct NETPROXY_RULE {
BOOLEAN auth; BOOLEAN auth;
WCHAR login[255]; WCHAR login[255];
WCHAR pass[255]; WCHAR pass[255];
rbtree_t ip_map;
}; };
extern POOL* Dll_Pool; extern POOL* Dll_Pool;
@ -752,12 +755,25 @@ _FX int WSA_IsBlockedTraffic(const short *addr, int addrlen, int protocol)
// WSA_GetProxy // WSA_GetProxy
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#define NETFW_MATCH_NONE 0
_FX BOOLEAN WSA_GetProxy(const SOCKADDR* name, void** proxy, int* proxylen) ULONG NetFw_MatchAddress(rbtree_t* ip_map, IP_ADDRESS* ip);
_FX BOOLEAN WSA_GetProxy(const short *addr, int addrlen, void** proxy, int* proxylen)
{ {
if (!WSA_Proxy) if (!WSA_Proxy)
return FALSE; return FALSE;
// check if there are any IP's specified for which wes should bypass the proxy
if (WSA_Proxy->ip_map.count > 0) {
IP_ADDRESS ip;
if (WSA_GetIP(addr, addrlen, &ip)) {
if (NetFw_MatchAddress(&WSA_Proxy->ip_map, &ip) != NETFW_MATCH_NONE)
return FALSE;
}
}
const SOCKADDR* name = (SOCKADDR*)addr;
if (name->sa_family == AF_INET && WSA_Proxy->af == name->sa_family) { if (name->sa_family == AF_INET && WSA_Proxy->af == name->sa_family) {
*proxy = &WSA_Proxy->WSA_ProxyAddr; *proxy = &WSA_Proxy->WSA_ProxyAddr;
*proxylen = sizeof(SOCKADDR_IN); *proxylen = sizeof(SOCKADDR_IN);
@ -853,7 +869,7 @@ _FX int WSA_connect(
void* proxy; void* proxy;
int proxylen; int proxylen;
if (WSA_ProxyEnabled && !is_localhost(name) && WSA_GetProxy(name, &proxy, &proxylen)) { if (WSA_ProxyEnabled && !is_localhost(name) && WSA_GetProxy(name, namelen, &proxy, &proxylen)) {
WSA_SOCK* pSock = WSA_GetSock(s, FALSE); WSA_SOCK* pSock = WSA_GetSock(s, FALSE);
if (pSock) WSA_begin_connect(pSock, s); if (pSock) WSA_begin_connect(pSock, s);
@ -902,7 +918,7 @@ _FX int WSA_WSAConnect(
void* proxy; void* proxy;
int proxylen; int proxylen;
if (WSA_ProxyEnabled && !is_localhost(name) && WSA_GetProxy(name, &proxy, &proxylen)) { if (WSA_ProxyEnabled && !is_localhost(name) && WSA_GetProxy(name, namelen, &proxy, &proxylen)) {
WSA_SOCK* pSock = WSA_GetSock(s, FALSE); WSA_SOCK* pSock = WSA_GetSock(s, FALSE);
if (pSock) WSA_begin_connect(pSock, s); if (pSock) WSA_begin_connect(pSock, s);
@ -951,7 +967,7 @@ _FX int WSA_ConnectEx(
void* proxy; void* proxy;
int proxylen; int proxylen;
if (WSA_ProxyEnabled && !is_localhost(name) && WSA_GetProxy(name, &proxy, &proxylen)) { if (WSA_ProxyEnabled && !is_localhost(name) && WSA_GetProxy(name, namelen, &proxy, &proxylen)) {
WSA_SOCK* pSock = WSA_GetSock(s, FALSE); WSA_SOCK* pSock = WSA_GetSock(s, FALSE);
if (pSock) WSA_begin_connect(pSock, s); if (pSock) WSA_begin_connect(pSock, s);
@ -1188,31 +1204,36 @@ _FX void WSA_InitNetFwRules()
} }
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// WSA_ParseNetProxy // WSA_ParseNetProxy
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void NetFw_RuleAddIpRange(rbtree_t* tree, IP_ADDRESS* IpBegin, IP_ADDRESS* IpEnd, POOL* pool);
const WCHAR* wcsnchr(const WCHAR* str, size_t max, WCHAR ch);
BOOLEAN WSA_ParseNetProxy(NETPROXY_RULE* proxy, const WCHAR* found_value) BOOLEAN WSA_ParseNetProxy(NETPROXY_RULE* proxy, const WCHAR* found_value)
{ {
// NetworkUseProxy=explorer.exe,Address=198.98.55.77;Port=40000;Auth=No;Login=l2sxbnjqR5JJAAoCnA;Password=12OxyLTW9nma5HbNjC // NetworkUseProxy=explorer.exe,Address=198.98.55.77;Port=40000;Auth=No;Login=l2sxbnjqR5JJAAoCnA;Password=12OxyLTW9nma5HbNjC
// NetworkUseProxy=*,Address=abcd:0123:ffff:1d5c;Port=24;Auth=No // NetworkUseProxy=*,Address=abcd:0123:ffff:1d5c;Port=24;Auth=No
WCHAR* ip_value; WCHAR* addr_value;
ULONG ip_len; ULONG addr_len;
if (SbieDll_FindTagValuePtr(found_value, L"Address", &ip_value, &ip_len, L'=', L';')) { if (SbieDll_FindTagValuePtr(found_value, L"Address", &addr_value, &addr_len, L'=', L';')) {
ip_value[ip_len] = L'\0'; addr_value[addr_len] = L'\0';
if (_inet_aton(ip_value, &proxy->WSA_ProxyAddr.sin_addr) == 1) { if (_inet_aton(addr_value, &proxy->WSA_ProxyAddr.sin_addr) == 1) {
proxy->WSA_ProxyAddr.sin_family = AF_INET; proxy->WSA_ProxyAddr.sin_family = AF_INET;
proxy->af = AF_INET; proxy->af = AF_INET;
} }
else if (_inet_pton(AF_INET6, ip_value, &proxy->WSA_ProxyAddr6.sin6_addr) == 1) else if (_inet_pton(AF_INET6, addr_value, &proxy->WSA_ProxyAddr6.sin6_addr) == 1)
{ {
proxy->WSA_ProxyAddr6.sin6_family = AF_INET6; proxy->WSA_ProxyAddr6.sin6_family = AF_INET6;
proxy->af = AF_INET6; proxy->af = AF_INET6;
} }
else else
return FALSE; return FALSE;
ip_value[ip_len] = L';'; addr_value[addr_len] = L';';
} }
else else
return FALSE; return FALSE;
@ -1233,6 +1254,37 @@ BOOLEAN WSA_ParseNetProxy(NETPROXY_RULE* proxy, const WCHAR* found_value)
else else
return FALSE; return FALSE;
const WCHAR* ip_value;
ULONG ip_len;
if (SbieDll_FindTagValuePtr(found_value, L"Bypass", &ip_value, &ip_len, L'=', L';')) {
for (const WCHAR* ip_end = ip_value + ip_len; ip_value < ip_end;) {
const WCHAR* ip_str1;
ULONG ip_len1;
ip_value = SbieDll_GetTagValue(ip_value, ip_end, &ip_str1, &ip_len1, L',');
const WCHAR* ip_str2 = wcsnchr(ip_str1, ip_len1, L'-');
if (ip_str2) {
ip_len1 = (ULONG)(ip_str2 - ip_str1);
ip_str2++; // skip dash
ULONG ip_len2 = (ULONG)(ip_value - ip_str2);
IP_ADDRESS ip1;
_inet_xton(ip_str1, ip_len1, &ip1, NULL);
IP_ADDRESS ip2;
_inet_xton(ip_str2, ip_len2, &ip2, NULL);
NetFw_RuleAddIpRange(&proxy->ip_map, &ip1, &ip2, Dll_Pool);
}
else
{
IP_ADDRESS ip;
_inet_xton(ip_str1, ip_len1, &ip, NULL);
NetFw_RuleAddIpRange(&proxy->ip_map, &ip, &ip, Dll_Pool);
}
}
}
WCHAR* auth_value; WCHAR* auth_value;
ULONG auth_len; ULONG auth_len;
if (SbieDll_FindTagValuePtr(found_value, L"Auth", &auth_value, &auth_len, L'=', L';')) if (SbieDll_FindTagValuePtr(found_value, L"Auth", &auth_value, &auth_len, L'=', L';'))
@ -1246,7 +1298,6 @@ BOOLEAN WSA_ParseNetProxy(NETPROXY_RULE* proxy, const WCHAR* found_value)
if (login_len > 255) if (login_len > 255)
return FALSE; return FALSE;
wmemcpy(proxy->login, login_value, login_len); wmemcpy(proxy->login, login_value, login_len);
proxy->login[login_len] = L'\0';
} }
WCHAR* pass_value; WCHAR* pass_value;
@ -1265,11 +1316,15 @@ BOOLEAN WSA_ParseNetProxy(NETPROXY_RULE* proxy, const WCHAR* found_value)
SBIE_INI_RC4_CRYPT_REQ req; SBIE_INI_RC4_CRYPT_REQ req;
SBIE_INI_RC4_CRYPT_RPL *rpl; SBIE_INI_RC4_CRYPT_RPL *rpl;
pass_value[pass_len] = L'\0';
req.h.length = sizeof(SBIE_INI_RC4_CRYPT_REQ) + 255; req.h.length = sizeof(SBIE_INI_RC4_CRYPT_REQ) + 255;
req.h.msgid = MSGID_SBIE_INI_RC4_CRYPT; req.h.msgid = MSGID_SBIE_INI_RC4_CRYPT;
req.value_len = b64_decoded_size(pass_value); req.value_len = b64_decoded_size(pass_value);
b64_decode(pass_value, req.value, req.value_len); b64_decode(pass_value, req.value, req.value_len);
pass_value[pass_len] = L'\0';
rpl = (SBIE_INI_RC4_CRYPT_RPL *)SbieDll_CallServer(&req.h); rpl = (SBIE_INI_RC4_CRYPT_RPL *)SbieDll_CallServer(&req.h);
if (rpl){ if (rpl){
@ -1296,12 +1351,16 @@ BOOLEAN WSA_ParseNetProxy(NETPROXY_RULE* proxy, const WCHAR* found_value)
#define NETPROXY_MATCH_GLOBAL 2 #define NETPROXY_MATCH_GLOBAL 2
#define NETPROXY_MATCH_EXACT 0 #define NETPROXY_MATCH_EXACT 0
int NetFw_IpCmp(const void* l, const void* r);
_FX BOOLEAN WSA_InitNetProxy() _FX BOOLEAN WSA_InitNetProxy()
{ {
WCHAR proxy_buf[1024]; WCHAR proxy_buf[2048];
WSA_Proxy = Dll_Alloc(sizeof(NETPROXY_RULE)); WSA_Proxy = Dll_Alloc(sizeof(NETPROXY_RULE));
memset(WSA_Proxy, 0, sizeof(NETPROXY_RULE)); memset(WSA_Proxy, 0, sizeof(NETPROXY_RULE));
rbtree_init(&WSA_Proxy->ip_map, NetFw_IpCmp);
BOOLEAN ok = FALSE; BOOLEAN ok = FALSE;
for (ULONG index = 0; ; ++index) { for (ULONG index = 0; ; ++index) {

View File

@ -3707,6 +3707,11 @@ The process match level has a higher priority than the specificity and describes
<string>Password</string> <string>Password</string>
</property> </property>
</column> </column>
<column>
<property name="text">
<string>Bypass IPs</string>
</property>
</column>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="4" column="1">

View File

@ -946,6 +946,10 @@ void COptionsWindow::OnNetProxyItemDoubleClicked(QTreeWidgetItem* pItem, int Col
pPass->setMaxLength(255); pPass->setMaxLength(255);
pPass->setText(pItem->data(5, Qt::UserRole).toString()); pPass->setText(pItem->data(5, Qt::UserRole).toString());
ui.treeProxy->setItemWidget(pItem, 5, pPass); ui.treeProxy->setItemWidget(pItem, 5, pPass);
QLineEdit* pBypass = new QLineEdit();
pBypass->setText(pItem->data(6, Qt::UserRole).toString());
ui.treeProxy->setItemWidget(pItem, 6, pBypass);
} }
void COptionsWindow::LoadNetProxy() void COptionsWindow::LoadNetProxy()
@ -1004,6 +1008,10 @@ void COptionsWindow::ParseAndAddNetProxy(const QString& Value, bool disabled, co
pItem->setText(5, Pass); pItem->setText(5, Pass);
pItem->setData(5, Qt::UserRole, Pass); pItem->setData(5, Qt::UserRole, Pass);
QString Bypass = Tags.value("bypass");
pItem->setText(6, Bypass);
pItem->setData(6, Qt::UserRole, Bypass);
if(Template.isEmpty()) if(Template.isEmpty())
pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); pItem->setFlags(pItem->flags() | Qt::ItemIsEditable);
ui.treeProxy->addTopLevelItem(pItem); ui.treeProxy->addTopLevelItem(pItem);
@ -1025,6 +1033,7 @@ void COptionsWindow::SaveNetProxy()
int iAuth = pItem->data(3, Qt::UserRole).toInt(); int iAuth = pItem->data(3, Qt::UserRole).toInt();
QString Login = pItem->data(4, Qt::UserRole).toString(); QString Login = pItem->data(4, Qt::UserRole).toString();
QString Pass = pItem->data(5, Qt::UserRole).toString(); QString Pass = pItem->data(5, Qt::UserRole).toString();
QString Bypass = pItem->data(6, Qt::UserRole).toString();
if (IP.isEmpty() || Port.isEmpty()) { if (IP.isEmpty() || Port.isEmpty()) {
QMessageBox::warning(this, "SandboxiePlus", QString::number(i + 1) + tr(" entry: IP or Port cannot be empty")); QMessageBox::warning(this, "SandboxiePlus", QString::number(i + 1) + tr(" entry: IP or Port cannot be empty"));
@ -1048,6 +1057,8 @@ void COptionsWindow::SaveNetProxy()
else else
Tags.append("EncryptedPW=" + res.GetValue().toBase64(QByteArray::OmitTrailingEquals)); Tags.append("EncryptedPW=" + res.GetValue().toBase64(QByteArray::OmitTrailingEquals));
} }
Tags.append("Bypass=" + Bypass);
QString Entry = Tags.join(";").prepend(Program + ","); QString Entry = Tags.join(";").prepend(Program + ",");
if (pItem->checkState(0) == Qt::Checked) if (pItem->checkState(0) == Qt::Checked)
@ -1092,6 +1103,7 @@ void COptionsWindow::CloseNetProxyEdit(QTreeWidgetItem* pItem, bool bSave)
QComboBox* pAuth = (QComboBox*)ui.treeProxy->itemWidget(pItem, 3); QComboBox* pAuth = (QComboBox*)ui.treeProxy->itemWidget(pItem, 3);
QLineEdit* pLogin = (QLineEdit*)ui.treeProxy->itemWidget(pItem, 4); QLineEdit* pLogin = (QLineEdit*)ui.treeProxy->itemWidget(pItem, 4);
QLineEdit* pPass = (QLineEdit*)ui.treeProxy->itemWidget(pItem, 5); QLineEdit* pPass = (QLineEdit*)ui.treeProxy->itemWidget(pItem, 5);
QLineEdit* pBypass = (QLineEdit*)ui.treeProxy->itemWidget(pItem, 6);
QString Program = pCombo->currentText(); QString Program = pCombo->currentText();
int Index = pCombo->findText(Program); int Index = pCombo->findText(Program);
@ -1116,11 +1128,14 @@ void COptionsWindow::CloseNetProxyEdit(QTreeWidgetItem* pItem, bool bSave)
pItem->setText(5, pPass->text()); pItem->setText(5, pPass->text());
pItem->setData(5, Qt::UserRole, pPass->text()); pItem->setData(5, Qt::UserRole, pPass->text());
pItem->setText(6, pBypass->text());
pItem->setData(6, Qt::UserRole, pBypass->text());
m_NetProxyChanged = true; m_NetProxyChanged = true;
OnOptChanged(); OnOptChanged();
} }
for (int i = 0; i < 6; i++) for (int i = 0; i <= 6; i++)
ui.treeProxy->setItemWidget(pItem, i, NULL); ui.treeProxy->setItemWidget(pItem, i, NULL);
} }