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 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 Proxy exclusion [#4036](https://github.com/sandboxie-plus/Sandboxie/issues/4036)
### Fixed
- 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;
};
static int NetFw_PortCmp(const void * l, const void * r)
int NetFw_PortCmp(const void * l, const void * r)
{
if (*((USHORT*)l) > *((USHORT*)r))
return 1;
@ -30,7 +30,7 @@ static int NetFw_PortCmp(const void * l, const void * r)
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* R = (IP_ADDRESS*)r;

View File

@ -35,6 +35,7 @@
#include "common/base64.c"
#include "core/drv/api_defs.h"
#include "core/drv/verify.h"
#include "common/rbtree.h"
//---------------------------------------------------------------------------
@ -280,6 +281,8 @@ struct NETPROXY_RULE {
BOOLEAN auth;
WCHAR login[255];
WCHAR pass[255];
rbtree_t ip_map;
};
extern POOL* Dll_Pool;
@ -752,12 +755,25 @@ _FX int WSA_IsBlockedTraffic(const short *addr, int addrlen, int protocol)
// 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)
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) {
*proxy = &WSA_Proxy->WSA_ProxyAddr;
*proxylen = sizeof(SOCKADDR_IN);
@ -853,7 +869,7 @@ _FX int WSA_connect(
void* proxy;
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);
if (pSock) WSA_begin_connect(pSock, s);
@ -902,7 +918,7 @@ _FX int WSA_WSAConnect(
void* proxy;
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);
if (pSock) WSA_begin_connect(pSock, s);
@ -951,7 +967,7 @@ _FX int WSA_ConnectEx(
void* proxy;
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);
if (pSock) WSA_begin_connect(pSock, s);
@ -1188,31 +1204,36 @@ _FX void WSA_InitNetFwRules()
}
}
//---------------------------------------------------------------------------
// 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)
{
// 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
WCHAR* ip_value;
ULONG ip_len;
if (SbieDll_FindTagValuePtr(found_value, L"Address", &ip_value, &ip_len, L'=', L';')) {
ip_value[ip_len] = L'\0';
if (_inet_aton(ip_value, &proxy->WSA_ProxyAddr.sin_addr) == 1) {
WCHAR* addr_value;
ULONG addr_len;
if (SbieDll_FindTagValuePtr(found_value, L"Address", &addr_value, &addr_len, L'=', L';')) {
addr_value[addr_len] = L'\0';
if (_inet_aton(addr_value, &proxy->WSA_ProxyAddr.sin_addr) == 1) {
proxy->WSA_ProxyAddr.sin_family = 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->af = AF_INET6;
}
else
return FALSE;
ip_value[ip_len] = L';';
addr_value[addr_len] = L';';
}
else
return FALSE;
@ -1233,6 +1254,37 @@ BOOLEAN WSA_ParseNetProxy(NETPROXY_RULE* proxy, const WCHAR* found_value)
else
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;
ULONG auth_len;
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)
return FALSE;
wmemcpy(proxy->login, login_value, login_len);
proxy->login[login_len] = L'\0';
}
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_RPL *rpl;
pass_value[pass_len] = L'\0';
req.h.length = sizeof(SBIE_INI_RC4_CRYPT_REQ) + 255;
req.h.msgid = MSGID_SBIE_INI_RC4_CRYPT;
req.value_len = b64_decoded_size(pass_value);
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);
if (rpl){
@ -1296,12 +1351,16 @@ BOOLEAN WSA_ParseNetProxy(NETPROXY_RULE* proxy, const WCHAR* found_value)
#define NETPROXY_MATCH_GLOBAL 2
#define NETPROXY_MATCH_EXACT 0
int NetFw_IpCmp(const void* l, const void* r);
_FX BOOLEAN WSA_InitNetProxy()
{
WCHAR proxy_buf[1024];
WCHAR proxy_buf[2048];
WSA_Proxy = Dll_Alloc(sizeof(NETPROXY_RULE));
memset(WSA_Proxy, 0, sizeof(NETPROXY_RULE));
rbtree_init(&WSA_Proxy->ip_map, NetFw_IpCmp);
BOOLEAN ok = FALSE;
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>
</property>
</column>
<column>
<property name="text">
<string>Bypass IPs</string>
</property>
</column>
</widget>
</item>
<item row="4" column="1">

View File

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