Bug 1048131 - Make some network events trigger a captive portal recheck r=mcmanus

This commit is contained in:
Valentin Gosu 2014-10-14 00:35:51 +03:00
parent c50130a020
commit d899d34e26
3 changed files with 106 additions and 1 deletions

View File

@ -44,6 +44,8 @@
#include "mozilla/LoadInfo.h"
#include "mozilla/net/NeckoCommon.h"
#include "mozilla/Telemetry.h"
#include "mozilla/net/DNS.h"
#include "CaptivePortalService.h"
#ifdef MOZ_WIDGET_GONK
#include "nsINetworkManager.h"
@ -55,6 +57,7 @@
using namespace mozilla;
using mozilla::net::IsNeckoChild;
using mozilla::net::CaptivePortalService;
#define PORT_PREF_PREFIX "network.security.ports."
#define PORT_PREF(x) PORT_PREF_PREFIX x
@ -68,6 +71,7 @@ using mozilla::net::IsNeckoChild;
#define NECKO_BUFFER_CACHE_COUNT_PREF "network.buffer.cache.count"
#define NECKO_BUFFER_CACHE_SIZE_PREF "network.buffer.cache.size"
#define NETWORK_NOTIFY_CHANGED_PREF "network.notify.changed"
#define NETWORK_CAPTIVE_PORTAL_PREF "network.captive-portal-service.enabled"
#define MAX_RECURSION_COUNT 50
@ -196,7 +200,9 @@ nsIOService::Init()
}
else
NS_WARNING("failed to get error service");
InitializeCaptivePortalService();
// setup our bad port list stuff
for(int i=0; gBadPortList[i]; i++)
mRestrictedPortList.AppendElement(gBadPortList[i]);
@ -211,6 +217,7 @@ nsIOService::Init()
prefBranch->AddObserver(NECKO_BUFFER_CACHE_COUNT_PREF, this, true);
prefBranch->AddObserver(NECKO_BUFFER_CACHE_SIZE_PREF, this, true);
prefBranch->AddObserver(NETWORK_NOTIFY_CHANGED_PREF, this, true);
prefBranch->AddObserver(NETWORK_CAPTIVE_PORTAL_PREF, this, true);
PrefsChanged(prefBranch);
}
@ -246,6 +253,22 @@ nsIOService::~nsIOService()
gIOService = nullptr;
}
nsresult
nsIOService::InitializeCaptivePortalService()
{
if (XRE_GetProcessType() != GeckoProcessType_Default) {
// We only initalize a captive portal service in the main process
return NS_OK;
}
mCaptivePortalService = do_GetService(NS_CAPTIVEPORTAL_CID);
if (mCaptivePortalService) {
return static_cast<CaptivePortalService*>(mCaptivePortalService.get())->Initialize();
}
return NS_OK;
}
nsresult
nsIOService::InitializeSocketTransportService()
{
@ -327,11 +350,53 @@ NS_IMPL_ISUPPORTS(nsIOService,
////////////////////////////////////////////////////////////////////////////////
nsresult
nsIOService::RecheckCaptivePortalIfLocalRedirect(nsIChannel* newChan)
{
nsresult rv;
if (!mCaptivePortalService) {
return NS_OK;
}
nsCOMPtr<nsIURI> uri;
rv = newChan->GetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) {
return rv;
}
nsCString host;
rv = uri->GetHost(host);
if (NS_FAILED(rv)) {
return rv;
}
PRNetAddr prAddr;
if (PR_StringToNetAddr(host.BeginReading(), &prAddr) != PR_SUCCESS) {
// The redirect wasn't to an IP literal, so there's probably no need
// to trigger the captive portal detection right now. It can wait.
return NS_OK;
}
mozilla::net::NetAddr netAddr;
PRNetAddrToNetAddr(&prAddr, &netAddr);
if (IsIPAddrLocal(&netAddr)) {
// Redirects to local IP addresses are probably captive portals
mCaptivePortalService->RecheckCaptivePortal();
}
return NS_OK;
}
nsresult
nsIOService::AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
uint32_t flags,
nsAsyncRedirectVerifyHelper *helper)
{
// If a redirect to a local network address occurs, then chances are we
// are in a captive portal, so we trigger a recheck.
RecheckCaptivePortalIfLocalRedirect(newChan);
nsCOMPtr<nsIChannelEventSink> sink =
do_GetService(NS_GLOBAL_CHANNELEVENTSINK_CONTRACTID);
if (sink) {
@ -1155,6 +1220,28 @@ nsIOService::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
mNetworkNotifyChanged = allow;
}
}
if (!pref || strcmp(pref, NETWORK_CAPTIVE_PORTAL_PREF) == 0) {
static int disabledForTest = -1;
if (disabledForTest == -1) {
char *s = getenv("MOZ_DISABLE_NONLOCAL_CONNECTIONS");
if (s) {
disabledForTest = (strncmp(s, "0", 1) == 0) ? 0 : 1;
} else {
disabledForTest = 0;
}
}
bool captivePortalEnabled;
nsresult rv = prefs->GetBoolPref(NETWORK_CAPTIVE_PORTAL_PREF, &captivePortalEnabled);
if (NS_SUCCEEDED(rv) && mCaptivePortalService) {
if (captivePortalEnabled && !disabledForTest) {
static_cast<CaptivePortalService*>(mCaptivePortalService.get())->Start();
} else {
static_cast<CaptivePortalService*>(mCaptivePortalService.get())->Stop();
}
}
}
}
void
@ -1305,6 +1392,10 @@ nsIOService::Observe(nsISupports *subject,
SetOffline(true);
if (mCaptivePortalService) {
static_cast<CaptivePortalService*>(mCaptivePortalService.get())->Stop();
}
// Break circular reference.
mProxyService = nullptr;
} else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
@ -1322,6 +1413,10 @@ nsIOService::Observe(nsISupports *subject,
NS_NETWORK_LINK_TOPIC,
MOZ_UTF16(NS_NETWORK_LINK_DATA_CHANGED));
}
if (mCaptivePortalService) {
mCaptivePortalService->RecheckCaptivePortal();
}
} else if (!strcmp(topic, kNetworkActiveChanged)) {
#ifdef MOZ_WIDGET_GONK
if (IsNeckoChild()) {
@ -1517,6 +1612,10 @@ nsIOService::OnNetworkLinkEvent(const char *data)
} else if (!strcmp(data, NS_NETWORK_LINK_DATA_DOWN)) {
isUp = false;
} else if (!strcmp(data, NS_NETWORK_LINK_DATA_UP)) {
if (mCaptivePortalService) {
// Interface is up. Triggering a captive portal recheck.
mCaptivePortalService->RecheckCaptivePortal();
}
isUp = true;
} else if (!strcmp(data, NS_NETWORK_LINK_DATA_UNKNOWN)) {
nsresult rv = mNetworkLinkService->GetIsLinkUp(&isUp);

View File

@ -19,6 +19,7 @@
#include "nsISpeculativeConnect.h"
#include "nsDataHashtable.h"
#include "mozilla/Attributes.h"
#include "nsICaptivePortalService.h"
#define NS_N(x) (sizeof(x)/sizeof(*x))
@ -101,6 +102,9 @@ private:
nsresult CacheProtocolHandler(const char *scheme,
nsIProtocolHandler* hdlr);
nsresult InitializeCaptivePortalService();
nsresult RecheckCaptivePortalIfLocalRedirect(nsIChannel* newChan);
// Prefs wrangling
void PrefsChanged(nsIPrefBranch *prefs, const char *pref = nullptr);
void GetPrefBranch(nsIPrefBranch **);
@ -147,6 +151,7 @@ private:
nsCOMPtr<nsPISocketTransportService> mSocketTransportService;
nsCOMPtr<nsPIDNSService> mDNSService;
nsCOMPtr<nsIProtocolProxyService2> mProxyService;
nsCOMPtr<nsICaptivePortalService> mCaptivePortalService;
nsCOMPtr<nsINetworkLinkService> mNetworkLinkService;
bool mNetworkLinkServiceInitialized;

View File

@ -15,6 +15,7 @@
#include "nsICacheStorageService.h"
#include "nsICacheStorage.h"
#include "nsICacheEntry.h"
#include "nsICaptivePortalService.h"
#include "nsICryptoHash.h"
#include "nsINetworkInterceptController.h"
#include "nsIStringBundle.h"