Skip to content

Commit

Permalink
Merge pull request #73 from Psiphon-Inc/v164
Browse files Browse the repository at this point in the history
V164
  • Loading branch information
adamkruger authored Mar 16, 2021
2 parents 605e37c + 2bd515a commit 0037878
Show file tree
Hide file tree
Showing 20 changed files with 507 additions and 273 deletions.
Binary file modified src/3rdParty/psiphon-tunnel-core.exe
Binary file not shown.
30 changes: 22 additions & 8 deletions src/coretransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,24 @@ void CoreTransport::TransportConnectHelper()
}

m_systemProxySettings->SetSocksProxyPort(m_localSocksProxyPort);
my_print(NOT_SENSITIVE, false, _T("SOCKS proxy is running on localhost port %d."), m_localSocksProxyPort);

m_systemProxySettings->SetHttpProxyPort(m_localHttpProxyPort);
m_systemProxySettings->SetHttpsProxyPort(m_localHttpProxyPort);
my_print(NOT_SENSITIVE, false, _T("HTTP proxy is running on localhost port %d."), m_localHttpProxyPort);

vector<tstring> ipAddresses;
GetLocalIPv4Addresses(ipAddresses);
if (Settings::ExposeLocalProxiesToLAN() && ipAddresses.size() > 0)
{
for (const auto& ipAddress : ipAddresses)
{
my_print(SENSITIVE_FORMAT_ARGS, false, _T("SOCKS proxy is running on %s port %d."), ipAddress.c_str(), m_localSocksProxyPort);
my_print(SENSITIVE_FORMAT_ARGS, false, _T("HTTP proxy is running on %s port %d."), ipAddress.c_str(), m_localHttpProxyPort);
}
}
else
{
my_print(NOT_SENSITIVE, false, _T("SOCKS proxy is running on localhost port %d."), m_localSocksProxyPort);
my_print(NOT_SENSITIVE, false, _T("HTTP proxy is running on localhost port %d."), m_localHttpProxyPort);
}
}


Expand Down Expand Up @@ -505,11 +518,6 @@ void CoreTransport::HandlePsiphonTunnelCoreNotice(const string& noticeType, cons
// SENSITIVE_LOG: "address" is site user is browsing
my_print(SENSITIVE_LOG, false, _T("Untunneled: %S"), address.c_str());
}
else if (noticeType == "SplitTunnelRegion")
{
string region = data["region"].asString();
my_print(NOT_SENSITIVE, false, _T("Split Tunnel Region: %S"), region.c_str());
}
else if (noticeType == "UpstreamProxyError")
{
string message = data["message"].asString();
Expand Down Expand Up @@ -572,6 +580,12 @@ void CoreTransport::HandlePsiphonTunnelCoreNotice(const string& noticeType, cons
string region = data["region"].asString();
my_print(NOT_SENSITIVE, true, _T("Client region: %S"), region.c_str());
psicash::Lib::_().UpdateClientRegion(region);

if (Settings::SplitTunnel())
{
// Display split tunnel region to user
my_print(NOT_SENSITIVE, false, _T("Split Tunnel Country: %S"), region.c_str());
}
}
else if (noticeType == "TrafficRateLimits")
{
Expand Down
4 changes: 0 additions & 4 deletions src/embeddedvalues.h.stub
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,3 @@ static const char* GET_NEW_VERSION_URL = "https://s3.amazonaws.com/invalid_bucke
static const char* GET_NEW_VERSION_EMAIL = "[email protected]";
static const char* FAQ_URL = "https://s3.amazonaws.com/invalid_bucket_name/en.html#other_frequently_asked_questions";
static const char* DATA_COLLECTION_INFO_URL = "https://s3.amazonaws.com/invalid_bucket_name/en/index.html#what_user_information_does_psiphon_3_collect";

static const char* SPLIT_TUNNEL_ROUTES_URL_FORMAT = "https://s3.amazonaws.com/invalid_bucket_name/%s.route.zlib.json";
static const char* SPLIT_TUNNEL_ROUTES_SIGNATURE_PUBLIC_KEY = "";
static const char* SPLIT_TUNNEL_DNS_SERVER = "";
4 changes: 2 additions & 2 deletions src/psiclient2015.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>3rdParty\psicash\Debug2015\psicash.lib;3rdParty\mctrl\Debug2015\mCtrl.lib;3rdParty\cryptopp\Debug2015\cryptlib.lib;Winhttp.lib;rasapi32.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Comctl32.lib;wininet.lib;shlwapi.lib;urlmon.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>3rdParty\psicash\Debug2015\psicash.lib;3rdParty\mctrl\Debug2015\mCtrl.lib;3rdParty\cryptopp\Debug2015\cryptlib.lib;Winhttp.lib;rasapi32.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Comctl32.lib;wininet.lib;shlwapi.lib;urlmon.lib;Version.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
Expand All @@ -85,7 +85,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>3rdParty\psicash\Release2015\psicash.lib;3rdParty\mctrl\Release2015\mCtrl.lib;3rdParty\cryptopp\Release2015\cryptlib.lib;Winhttp.lib;rasapi32.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Comctl32.lib;wininet.lib;shlwapi.lib;urlmon.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>3rdParty\psicash\Release2015\psicash.lib;3rdParty\mctrl\Release2015\mCtrl.lib;3rdParty\cryptopp\Release2015\cryptlib.lib;Winhttp.lib;rasapi32.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Comctl32.lib;wininet.lib;shlwapi.lib;urlmon.lib;Version.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>
</IgnoreAllDefaultLibraries>
</Link>
Expand Down
25 changes: 20 additions & 5 deletions src/psiphon_tunnel_core_utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ bool WriteParameterFiles(const WriteParameterFilesIn& in, WriteParameterFilesOut

if (Settings::SplitTunnel())
{
config["SplitTunnelRoutesUrlFormat"] = SPLIT_TUNNEL_ROUTES_URL_FORMAT;
config["SplitTunnelRoutesSignaturePublicKey"] = SPLIT_TUNNEL_ROUTES_SIGNATURE_PUBLIC_KEY;
config["SplitTunnelDnsServer"] = SPLIT_TUNNEL_DNS_SERVER;
config["EnableSplitTunnel"] = true;
}

if (Settings::DisableTimeouts())
Expand Down Expand Up @@ -190,8 +188,25 @@ bool WriteParameterFiles(const WriteParameterFilesIn& in, WriteParameterFilesOut
else
{
config["EgressRegion"] = Settings::EgressRegion();
config["LocalHttpProxyPort"] = Settings::LocalHttpProxyPort();
config["LocalSocksProxyPort"] = Settings::LocalSocksProxyPort();

unsigned int localHttpProxyPortSetting = Settings::LocalHttpProxyPort();
unsigned int localSocksProxyPortSetting = Settings::LocalSocksProxyPort();
if (localHttpProxyPortSetting > 0)
{
my_print(NOT_SENSITIVE, true, _T("Setting LocalHttpProxyPort to a user configured value"));
}
if (localSocksProxyPortSetting > 0)
{
my_print(NOT_SENSITIVE, true, _T("Setting LocalSocksProxyPort to a user configured value"));
}
config["LocalHttpProxyPort"] = localHttpProxyPortSetting;
config["LocalSocksProxyPort"] = localSocksProxyPortSetting;

if (Settings::ExposeLocalProxiesToLAN())
{
config["ListenInterface"] = "any";
my_print(NOT_SENSITIVE, true, _T("Setting ListenInterface to any"));
}

auto remoteServerListFilename = filesystem::path(dataStoreDirectory)
.append(LOCAL_SETTINGS_APPDATA_REMOTE_SERVER_LIST_FILENAME);
Expand Down
4 changes: 2 additions & 2 deletions src/targetver.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.

// We only support Windows XP and later because we use L2TP/IPSec PSK and that is not supported
// We only support Windows Vista and later because we use inet_ntop and that is not supported
// on lower versions.
#define _WIN32_WINNT 0x0501
#define _WIN32_WINNT 0x0600

#include <SDKDDKVer.h>
15 changes: 15 additions & 0 deletions src/usersettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
#define SOCKS_PROXY_PORT_NAME "LocalSOCKSProxyPort"
#define SOCKS_PROXY_PORT_DEFAULT NULL_PORT

#define EXPOSE_LOCAL_PROXIES_TO_LAN_NAME "ExposeLocalProxiesToLAN"
#define EXPOSE_LOCAL_PROXIES_TO_LAN_DEFAULT FALSE

#define EGRESS_REGION_NAME "EgressRegion"
#define EGRESS_REGION_DEFAULT ""

Expand Down Expand Up @@ -190,6 +193,9 @@ void Settings::ToJson(Json::Value& o_json)
o_json["LocalSocksProxyPort"] = Settings::LocalSocksProxyPort();
o_json["defaults"]["LocalSocksProxyPort"] = SOCKS_PROXY_PORT_DEFAULT;

o_json["ExposeLocalProxiesToLAN"] = Settings::ExposeLocalProxiesToLAN() ? TRUE : FALSE;
o_json["defaults"]["ExposeLocalProxiesToLAN"] = EXPOSE_LOCAL_PROXIES_TO_LAN_DEFAULT;

o_json["SkipUpstreamProxy"] = Settings::SkipUpstreamProxy() ? TRUE : FALSE;
o_json["defaults"]["SkipUpstreamProxy"] = SKIP_UPSTREAM_PROXY_DEFAULT;
o_json["UpstreamProxyHostname"] = Settings::UpstreamProxyHostname();
Expand Down Expand Up @@ -263,6 +269,10 @@ bool Settings::FromJson(
reconnectRequiredValueChanged = reconnectRequiredValueChanged || socksPort != Settings::LocalSocksProxyPort();
WriteRegistryDwordValue(SOCKS_PROXY_PORT_NAME, socksPort);

BOOL exposeLocalProxiesToLAN = json.get("ExposeLocalProxiesToLAN", EXPOSE_LOCAL_PROXIES_TO_LAN_DEFAULT).asUInt();
reconnectRequiredValueChanged = reconnectRequiredValueChanged || !!exposeLocalProxiesToLAN != Settings::ExposeLocalProxiesToLAN();
WriteRegistryDwordValue(EXPOSE_LOCAL_PROXIES_TO_LAN_NAME, exposeLocalProxiesToLAN);

string upstreamProxyUsername = json.get("UpstreamProxyUsername", UPSTREAM_PROXY_USERNAME_DEFAULT).asString();
reconnectRequiredValueChanged = reconnectRequiredValueChanged || upstreamProxyUsername != Settings::UpstreamProxyUsername();
WriteRegistryStringValue(
Expand Down Expand Up @@ -365,6 +375,11 @@ unsigned int Settings::LocalSocksProxyPort()
return (unsigned int)port;
}

bool Settings::ExposeLocalProxiesToLAN()
{
return !!GetSettingDword(EXPOSE_LOCAL_PROXIES_TO_LAN_NAME, EXPOSE_LOCAL_PROXIES_TO_LAN_DEFAULT);
}

string Settings::UpstreamProxyType()
{
return UPSTREAM_PROXY_TYPE_DEFAULT;
Expand Down
2 changes: 2 additions & 0 deletions src/usersettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ namespace Settings
// Returns 0 if port should be chosen automatically.
unsigned int LocalSocksProxyPort();

bool ExposeLocalProxiesToLAN();

bool SkipUpstreamProxy();
string UpstreamProxyType();
string UpstreamProxyHostname();
Expand Down
73 changes: 73 additions & 0 deletions src/utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "diagnostic_info.h"
#include "webbrowser.h"
#include <iomanip>
#include <iphlpapi.h>
#include <ws2tcpip.h>


using namespace std::experimental;
Expand Down Expand Up @@ -1788,3 +1790,74 @@ float ConvertDpiToScaling(UINT dpi)
const UINT defaultDPI = 96;
return dpi / (float)defaultDPI;
}

/*
Network Interface Utilities
*/

void GetLocalIPv4Addresses(vector<tstring>& o_ipAddresses)
{
DWORD returnCode = ERROR_SUCCESS;
PIP_ADAPTER_ADDRESSES ipAddresses = NULL;
PIP_ADAPTER_ADDRESSES ipAddressesIterator = NULL;
ULONG ipAddressesBufferLength = 15000;

// Adapted from example at https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses

for (int attempts = 0; attempts < 3; ++attempts)
{
ipAddresses = (IP_ADAPTER_ADDRESSES *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ipAddressesBufferLength);

if (!ipAddresses)
{
my_print(NOT_SENSITIVE, false, _T("%s - HeapAlloc failed"), __TFUNCTION__);
throw std::exception(__FUNCTION__ ":" STRINGIZE(__LINE__) ": memory allocation failed");
}

returnCode = GetAdaptersAddresses(AF_INET,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,
NULL, ipAddresses, &ipAddressesBufferLength);

if (returnCode == ERROR_BUFFER_OVERFLOW)
{
HeapFree(GetProcessHeap(), 0, ipAddresses);
ipAddresses = NULL;
}
else
{
break;
}
}

if (returnCode == ERROR_SUCCESS)
{
ipAddressesIterator = ipAddresses;
while (ipAddressesIterator)
{
for (PIP_ADAPTER_UNICAST_ADDRESS unicastAddress = ipAddressesIterator->FirstUnicastAddress;
unicastAddress != NULL; unicastAddress = unicastAddress->Next)
{
if (unicastAddress->Address.lpSockaddr->sa_family == AF_INET)
{
sockaddr_in *sin = (sockaddr_in *)(unicastAddress->Address.lpSockaddr);
char ipv4Address[INET_ADDRSTRLEN] = {};
if (inet_ntop(AF_INET, &(sin->sin_addr), ipv4Address, sizeof(ipv4Address)))
{
o_ipAddresses.push_back(UTF8ToWString(ipv4Address));
}
}
}
ipAddressesIterator = ipAddressesIterator->Next;
}
}
else
{
my_print(NOT_SENSITIVE, false, _T("%s - GetAdaptersAddresses failed (%d)"), __TFUNCTION__, returnCode);
}

if (ipAddresses)
{
HeapFree(GetProcessHeap(), 0, ipAddresses);
ipAddresses = NULL;
}
}
7 changes: 7 additions & 0 deletions src/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,10 @@ HRESULT GetDpiScalingForMonitorFromPoint(POINT pt, float& o_scale);

// Helper for converting DPI value to scaling value.
float ConvertDpiToScaling(UINT dpi);


/*
Network Interface Utilities
*/

void GetLocalIPv4Addresses(vector<tstring>& o_ipAddresses);
12 changes: 12 additions & 0 deletions src/webui/_locales/devltr/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,18 @@
"message": "[Şḗḗŧŧīīƞɠş Ḗḗřřǿǿř]",
"description": "This modal dialog box is shown when the user tries to save their settings, but there is an error in the values they have entered. This string is the title of the modal box."
},
"settings#expose-local-proxies-to-lan#enable-label": {
"message": "[Ȧȧŀŀǿǿẇ ǿǿŧħḗḗř ḓḗḗṽīīƈḗḗş ǿǿƞ ẏǿǿŭŭř ƞḗḗŧẇǿǿřķ ŧǿǿ ŭŭşḗḗ ŧħḗḗ ŀǿǿƈȧȧŀ Ƥşīīƥħǿǿƞ ƥřǿǿẋīīḗḗş]",
"description": "Label for the setting to allow other devices on the network to use the local Psiphon proxies."
},
"settings#expose-local-proxies-to-lan#help-text": {
"message": "[Īīƒ ẏǿǿŭŭ ħȧȧṽḗḗ ǿǿŧħḗḗř ḓḗḗṽīīƈḗḗş ǿǿƞ ẏǿǿŭŭř ƞḗḗŧẇǿǿřķ, şŭŭƈħ ȧȧş ȧȧ şḿȧȧřŧ ŦṼ ǿǿř ɠȧȧḿīīƞɠ ƈǿǿƞşǿǿŀḗḗ, ẏǿǿŭŭ ƈȧȧƞ ȧȧŀŀǿǿẇ ŧħḗḗḿ ŧǿǿ ŭŭşḗḗ ŧħḗḗşḗḗ ĦŦŦƤ ȧȧƞḓ ŞǾǿƇĶŞ ƥřǿǿẋīīḗḗş ẇħīīŀḗḗ Ƥşīīƥħǿǿƞ īīş ƈǿǿƞƞḗḗƈŧḗḗḓ.]",
"description": "Help text explaining the setting to allow other devices on the network to use the local Psiphon proxies. Smart TV refers to televisions that have Internet connectivity and apps that access Internet services."
},
"settings#expose-local-proxies-to-lan#hint": {
"message": "[<strong>ĦĪīȠŦ:</strong> Ẏǿǿŭŭ şħǿǿŭŭŀḓ şƥḗḗƈīīƒẏ ȧȧŧ ŀḗḗȧȧşŧ ǿǿƞḗḗ ǿǿƒ ŧħḗḗ ƥǿǿřŧ ƞŭŭḿƀḗḗřş ȧȧƀǿǿṽḗḗ īīƞ ǿǿřḓḗḗř ŧǿǿ ŭŭşḗḗ ŧħīīş ƒḗḗȧȧŧŭŭřḗḗ. Ŧħḗḗ ȧȧḓḓřḗḗşşḗḗş ǿǿƒ ŧħḗḗ ŀǿǿƈȧȧŀ ƥřǿǿẋīīḗḗş ẇīīŀŀ ƀḗḗ ḓīīşƥŀȧȧẏḗḗḓ īīƞ ŧħḗḗ ŀǿǿɠş.]",
"description": "Helpful hint suggesting to set port numbers for the local Psiphon proxies when using the setting to allow other devices on the network to use the local Psiphon proxies."
},
"settings#local-proxy-ports#error-modal-body-http": {
"message": "[<p>\nẎǿǿŭŭ ħȧȧṽḗḗ ƈǿǿƞƒīīɠŭŭřḗḗḓ Ƥşīīƥħǿǿƞ ŧǿǿ ŭŭşḗḗ ȧȧ şƥḗḗƈīīƒīīƈ ŀǿǿƈȧȧŀ ƥǿǿřŧ ƒǿǿř īīŧş ĦŦŦƤ ƥřǿǿẋẏ.<br>\nĦǿǿẇḗḗṽḗḗř, ŧħȧȧŧ ƥǿǿřŧ ȧȧƥƥḗḗȧȧřş ŧǿǿ ƀḗḗ ȧȧŀřḗḗȧȧḓẏ īīƞ ŭŭşḗḗ ȧȧƞḓ şǿǿ Ƥşīīƥħǿǿƞ ƈȧȧƞƞǿǿŧ ŭŭşḗḗ īīŧ.\n</p>\n<p>\nƤŀḗḗȧȧşḗḗ ƈħȧȧƞɠḗḗ ŧħḗḗ ƈǿǿƞƒīīɠŭŭřḗḗḓ ĦŦŦƤ ƥřǿǿẋẏ ƥǿǿřŧ ṽȧȧŀŭŭḗḗ ȧȧƞḓ ŧřẏ ȧȧɠȧȧīīƞ. Ẇḗḗ řḗḗƈǿǿḿḿḗḗƞḓḗḗḓ ŧħȧȧŧ ẏǿǿŭŭ ƈŀḗḗȧȧř ŧħḗḗ ṽȧȧŀŭŭḗḗ şǿǿ ŧħȧȧŧ Ƥşīīƥħǿǿƞ ƈȧȧƞ ȧȧŭŭŧǿǿḿȧȧŧīīƈȧȧŀŀẏ ƥīīƈķ ȧȧƞ ȧȧṽȧȧīīŀȧȧƀŀḗḗ ƥǿǿřŧ.\n</p>]",
"description": "Main text in the 'Local Proxy Port Conflict' dialog box. This is shown when the conflict is with the HTTP proxy port, rather than the SOCKS proxy port. The word 'Psiphon' must not be translated or transliterated."
Expand Down
12 changes: 12 additions & 0 deletions src/webui/_locales/devrtl/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,18 @@
"message": "‮Sǝʇʇıuƃs‬ ‮Ǝɹɹoɹ‬",
"description": "This modal dialog box is shown when the user tries to save their settings, but there is an error in the values they have entered. This string is the title of the modal box."
},
"settings#expose-local-proxies-to-lan#enable-label": {
"message": "‮∀ʅʅoʍ‬ ‮oʇɥǝɹ‬ ‮pǝʌıɔǝs‬ ‮ou‬ ‮ʎonɹ‬ ‮uǝʇʍoɹʞ‬ ‮ʇo‬ ‮nsǝ‬ ‮ʇɥǝ‬ ‮ʅoɔɐʅ‬ ‮Ԁsıdɥou‬ ‮dɹoxıǝs‬",
"description": "Label for the setting to allow other devices on the network to use the local Psiphon proxies."
},
"settings#expose-local-proxies-to-lan#help-text": {
"message": "‮Iɟ‬ ‮ʎon‬ ‮ɥɐʌǝ‬ ‮oʇɥǝɹ‬ ‮pǝʌıɔǝs‬ ‮ou‬ ‮ʎonɹ‬ ‮uǝʇʍoɹʞ‬, ‮snɔɥ‬ ‮ɐs‬ ‮ɐ‬ ‮sɯɐɹʇ‬ ‮⊥Ʌ‬ ‮oɹ‬ ‮ƃɐɯıuƃ‬ ‮ɔousoʅǝ‬, ‮ʎon‬ ‮ɔɐu‬ ‮ɐʅʅoʍ‬ ‮ʇɥǝɯ‬ ‮ʇo‬ ‮nsǝ‬ ‮ʇɥǝsǝ‬ ‮H⊥⊥Ԁ‬ ‮ɐup‬ ‮SOↃӼS‬ ‮dɹoxıǝs‬ ‮ʍɥıʅǝ‬ ‮Ԁsıdɥou‬ ‮ıs‬ ‮ɔouuǝɔʇǝp‬.",
"description": "Help text explaining the setting to allow other devices on the network to use the local Psiphon proxies. Smart TV refers to televisions that have Internet connectivity and apps that access Internet services."
},
"settings#expose-local-proxies-to-lan#hint": {
"message": "<strong>‮HIN⊥‬:</strong> ‮ʎon‬ ‮sɥonʅp‬ ‮sdǝɔıɟʎ‬ ‮ɐʇ‬ ‮ʅǝɐsʇ‬ ‮ouǝ‬ ‮oɟ‬ ‮ʇɥǝ‬ ‮doɹʇ‬ ‮unɯqǝɹs‬ ‮ɐqoʌǝ‬ ‮ıu‬ ‮oɹpǝɹ‬ ‮ʇo‬ ‮nsǝ‬ ‮ʇɥıs‬ ‮ɟǝɐʇnɹǝ‬. ‮⊥ɥǝ‬ ‮ɐppɹǝssǝs‬ ‮oɟ‬ ‮ʇɥǝ‬ ‮ʅoɔɐʅ‬ ‮dɹoxıǝs‬ ‮ʍıʅʅ‬ ‮qǝ‬ ‮pısdʅɐʎǝp‬ ‮ıu‬ ‮ʇɥǝ‬ ‮ʅoƃs‬.",
"description": "Helpful hint suggesting to set port numbers for the local Psiphon proxies when using the setting to allow other devices on the network to use the local Psiphon proxies."
},
"settings#local-proxy-ports#error-modal-body-http": {
"message": "<p>\n‮ʎon‬ ‮ɥɐʌǝ‬ ‮ɔouɟıƃnɹǝp‬ ‮Ԁsıdɥou‬ ‮ʇo‬ ‮nsǝ‬ ‮ɐ‬ ‮sdǝɔıɟıɔ‬ ‮ʅoɔɐʅ‬ ‮doɹʇ‬ ‮ɟoɹ‬ ‮ıʇs‬ ‮H⊥⊥Ԁ‬ ‮dɹoxʎ‬.<br>\n‮Hoʍǝʌǝɹ‬, ‮ʇɥɐʇ‬ ‮doɹʇ‬ ‮ɐddǝɐɹs‬ ‮ʇo‬ ‮qǝ‬ ‮ɐʅɹǝɐpʎ‬ ‮ıu‬ ‮nsǝ‬ ‮ɐup‬ ‮so‬ ‮Ԁsıdɥou‬ ‮ɔɐuuoʇ‬ ‮nsǝ‬ ‮ıʇ‬.\n</p>\n<p>\n‮Ԁʅǝɐsǝ‬ ‮ɔɥɐuƃǝ‬ ‮ʇɥǝ‬ ‮ɔouɟıƃnɹǝp‬ ‮H⊥⊥Ԁ‬ ‮dɹoxʎ‬ ‮doɹʇ‬ ‮ʌɐʅnǝ‬ ‮ɐup‬ ‮ʇɹʎ‬ ‮ɐƃɐıu‬. ‮Mǝ‬ ‮ɹǝɔoɯɯǝupǝp‬ ‮ʇɥɐʇ‬ ‮ʎon‬ ‮ɔʅǝɐɹ‬ ‮ʇɥǝ‬ ‮ʌɐʅnǝ‬ ‮so‬ ‮ʇɥɐʇ‬ ‮Ԁsıdɥou‬ ‮ɔɐu‬ ‮ɐnʇoɯɐʇıɔɐʅʅʎ‬ ‮dıɔʞ‬ ‮ɐu‬ ‮ɐʌɐıʅɐqʅǝ‬ ‮doɹʇ‬.\n</p>",
"description": "Main text in the 'Local Proxy Port Conflict' dialog box. This is shown when the conflict is with the HTTP proxy port, rather than the SOCKS proxy port. The word 'Psiphon' must not be translated or transliterated."
Expand Down
Loading

0 comments on commit 0037878

Please sign in to comment.