diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /netwerk/socket/nsSOCKSSocketProvider.cpp | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | netwerk/socket/nsSOCKSSocketProvider.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/netwerk/socket/nsSOCKSSocketProvider.cpp b/netwerk/socket/nsSOCKSSocketProvider.cpp new file mode 100644 index 0000000000..536e06c962 --- /dev/null +++ b/netwerk/socket/nsSOCKSSocketProvider.cpp @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsNamedPipeIOLayer.h" +#include "nsSOCKSSocketProvider.h" +#include "nsSOCKSIOLayer.h" +#include "nsCOMPtr.h" +#include "nsError.h" + +using mozilla::OriginAttributes; + +////////////////////////////////////////////////////////////////////////// + +NS_IMPL_ISUPPORTS(nsSOCKSSocketProvider, nsISocketProvider) + +nsresult nsSOCKSSocketProvider::CreateV4(nsISupports* aOuter, REFNSIID aIID, + void** aResult) { + nsresult rv; + nsCOMPtr<nsISocketProvider> inst = + new nsSOCKSSocketProvider(NS_SOCKS_VERSION_4); + if (!inst) + rv = NS_ERROR_OUT_OF_MEMORY; + else + rv = inst->QueryInterface(aIID, aResult); + return rv; +} + +nsresult nsSOCKSSocketProvider::CreateV5(nsISupports* aOuter, REFNSIID aIID, + void** aResult) { + nsresult rv; + nsCOMPtr<nsISocketProvider> inst = + new nsSOCKSSocketProvider(NS_SOCKS_VERSION_5); + if (!inst) + rv = NS_ERROR_OUT_OF_MEMORY; + else + rv = inst->QueryInterface(aIID, aResult); + return rv; +} + +// Per-platform implemenation of OpenTCPSocket helper function +// Different platforms have special cases to handle + +#if defined(XP_WIN) +// The proxy host on Windows may be a named pipe uri, in which +// case a named-pipe (rather than a socket) should be returned +static PRFileDesc* OpenTCPSocket(int32_t family, nsIProxyInfo* proxy) { + PRFileDesc* sock = nullptr; + + nsAutoCString proxyHost; + proxy->GetHost(proxyHost); + if (IsNamedPipePath(proxyHost)) { + sock = CreateNamedPipeLayer(); + } else { + sock = PR_OpenTCPSocket(family); + } + + return sock; +} +#elif defined(XP_UNIX) +// The proxy host on UNIX systems may point to a local file uri +// in which case we should create an AF_LOCAL (UNIX Domain) socket +// instead of the requested AF_INET or AF_INET6 socket. + +// Normally,this socket would get thrown out and recreated later on +// with the proper family, but we want to do it early here so that +// we can enforce seccomp policy to blacklist socket(AF_INET) calls +// to prevent the content sandbox from creating network requests +static PRFileDesc* OpenTCPSocket(int32_t family, nsIProxyInfo* proxy) { + nsAutoCString proxyHost; + proxy->GetHost(proxyHost); + if (StringBeginsWith(proxyHost, "file://"_ns)) { + family = AF_LOCAL; + } + + return PR_OpenTCPSocket(family); +} +#else +// Default, pass-through to PR_OpenTCPSocket +static PRFileDesc* OpenTCPSocket(int32_t family, nsIProxyInfo*) { + return PR_OpenTCPSocket(family); +} +#endif + +NS_IMETHODIMP +nsSOCKSSocketProvider::NewSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + uint32_t flags, uint32_t tlsFlags, + PRFileDesc** result, nsISupports** socksInfo) { + PRFileDesc* sock = OpenTCPSocket(family, proxy); + if (!sock) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsresult rv = nsSOCKSIOLayerAddToSocket(family, host, port, proxy, mVersion, + flags, tlsFlags, sock, socksInfo); + if (NS_SUCCEEDED(rv)) { + *result = sock; + return NS_OK; + } + + return NS_ERROR_SOCKET_CREATE_FAILED; +} + +NS_IMETHODIMP +nsSOCKSSocketProvider::AddToSocket(int32_t family, const char* host, + int32_t port, nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + uint32_t flags, uint32_t tlsFlags, + PRFileDesc* sock, nsISupports** socksInfo) { + nsresult rv = nsSOCKSIOLayerAddToSocket(family, host, port, proxy, mVersion, + flags, tlsFlags, sock, socksInfo); + + if (NS_FAILED(rv)) rv = NS_ERROR_SOCKET_CREATE_FAILED; + return rv; +} |