tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TRRServiceParent.cpp (7216B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set sw=2 ts=8 et tw=80 : */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/net/TRRServiceParent.h"
      8 
      9 #include "mozilla/ipc/FileDescriptor.h"
     10 #include "mozilla/net/SocketProcessParent.h"
     11 #include "mozilla/psm/PSMIPCTypes.h"
     12 #include "mozilla/Preferences.h"
     13 #include "nsHttpConnectionInfo.h"
     14 #include "nsICaptivePortalService.h"
     15 #include "nsIParentalControlsService.h"
     16 #include "nsINetworkLinkService.h"
     17 #include "nsIObserverService.h"
     18 #include "nsIOService.h"
     19 #include "nsNetCID.h"
     20 #include "TRRService.h"
     21 
     22 #include "DNSLogging.h"
     23 
     24 namespace mozilla {
     25 namespace net {
     26 
     27 static Atomic<TRRServiceParent*> sTRRServiceParentPtr;
     28 
     29 static const char* gTRRUriCallbackPrefs[] = {
     30    "network.trr.uri",  "network.trr.default_provider_uri",
     31    "network.trr.mode", kRolloutURIPref,
     32    kRolloutModePref,   nullptr,
     33 };
     34 
     35 NS_IMPL_ISUPPORTS_INHERITED(TRRServiceParent, TRRServiceBase, nsIObserver,
     36                            nsISupportsWeakReference)
     37 
     38 TRRServiceParent::~TRRServiceParent() = default;
     39 
     40 void TRRServiceParent::Init() {
     41  MOZ_ASSERT(gIOService);
     42 
     43  if (!gIOService->SocketProcessReady()) {
     44    RefPtr<TRRServiceParent> self = this;
     45    gIOService->CallOrWaitForSocketProcess([self]() { self->Init(); });
     46    return;
     47  }
     48 
     49  RefPtr<SocketProcessParent> socketParent =
     50      SocketProcessParent::GetSingleton();
     51  if (!socketParent) {
     52    return;
     53  }
     54 
     55  nsCOMPtr<nsIObserverService> obs =
     56      static_cast<nsIObserverService*>(gIOService);
     57  TRRService::AddObserver(this, obs);
     58 
     59  bool captiveIsPassed = TRRService::CheckCaptivePortalIsPassed();
     60  bool parentalControlEnabled =
     61      TRRService::GetParentalControlsEnabledInternal();
     62 
     63  nsCOMPtr<nsINetworkLinkService> nls =
     64      do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID);
     65  nsTArray<nsCString> suffixList;
     66  if (nls) {
     67    nls->GetDnsSuffixList(suffixList);
     68  }
     69 
     70  Preferences::RegisterPrefixCallbacks(TRRServiceParent::PrefsChanged,
     71                                       gTRRUriCallbackPrefs, this);
     72  prefsChanged(nullptr);
     73 
     74  if (socketParent->SendPTRRServiceConstructor(
     75          this, captiveIsPassed, parentalControlEnabled, suffixList)) {
     76    sTRRServiceParentPtr = this;
     77  }
     78 }
     79 
     80 NS_IMETHODIMP
     81 TRRServiceParent::Observe(nsISupports* aSubject, const char* aTopic,
     82                          const char16_t* aData) {
     83  if (!strcmp(aTopic, NS_DNS_SUFFIX_LIST_UPDATED_TOPIC) ||
     84      !strcmp(aTopic, NS_NETWORK_LINK_TOPIC)) {
     85    nsCOMPtr<nsINetworkLinkService> link = do_QueryInterface(aSubject);
     86    // The network link service notification normally passes itself as the
     87    // subject, but some unit tests will sometimes pass a null subject.
     88    if (link) {
     89      nsTArray<nsCString> suffixList;
     90      link->GetDnsSuffixList(suffixList);
     91      (void)SendUpdatePlatformDNSInformation(suffixList);
     92    }
     93 
     94    if (!strcmp(aTopic, NS_NETWORK_LINK_TOPIC) && mURISetByDetection) {
     95      CheckURIPrefs();
     96    }
     97  }
     98 
     99  return NS_OK;
    100 }
    101 
    102 mozilla::ipc::IPCResult
    103 TRRServiceParent::RecvNotifyNetworkConnectivityServiceObservers(
    104    const nsCString& aTopic) {
    105  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    106  if (obs) {
    107    obs->NotifyObservers(nullptr, aTopic.get(), nullptr);
    108  }
    109  return IPC_OK();
    110 }
    111 
    112 bool TRRServiceParent::MaybeSetPrivateURI(const nsACString& aURI) {
    113  nsAutoCString newURI(aURI);
    114  ProcessURITemplate(newURI);
    115 
    116  if (mPrivateURI.Equals(newURI)) {
    117    return false;
    118  }
    119 
    120  mPrivateURI = newURI;
    121  AsyncCreateTRRConnectionInfo(mPrivateURI);
    122 
    123  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    124  if (obs) {
    125    obs->NotifyObservers(nullptr, NS_NETWORK_TRR_URI_CHANGED_TOPIC, nullptr);
    126  }
    127  return true;
    128 }
    129 
    130 void TRRServiceParent::SetDetectedTrrURI(const nsACString& aURI) {
    131  if (!mURIPref.IsEmpty()) {
    132    return;
    133  }
    134 
    135  mURISetByDetection = MaybeSetPrivateURI(aURI);
    136  gIOService->CallOrWaitForSocketProcess(
    137      [self = RefPtr{this}, uri = nsAutoCString(aURI)]() {
    138        (void)self->SendSetDetectedTrrURI(uri);
    139      });
    140 }
    141 
    142 void TRRServiceParent::GetURI(nsACString& aURI) {
    143  // We don't need a lock here, since mPrivateURI is only touched on main
    144  // thread.
    145  MOZ_ASSERT(NS_IsMainThread());
    146  aURI = mPrivateURI;
    147 }
    148 
    149 void TRRServiceParent::ReloadParentalControlsEnabled() {
    150  bool enabled = TRRService::ReloadParentalControlsEnabled();
    151  RefPtr<TRRServiceParent> self = this;
    152  gIOService->CallOrWaitForSocketProcess([self, enabled]() {
    153    (void)self->SendUpdateParentalControlEnabled(enabled);
    154  });
    155 }
    156 
    157 // static
    158 void TRRServiceParent::PrefsChanged(const char* aName, void* aSelf) {
    159  static_cast<TRRServiceParent*>(aSelf)->prefsChanged(aName);
    160 }
    161 
    162 void TRRServiceParent::prefsChanged(const char* aName) {
    163  if (!aName || !strcmp(aName, "network.trr.uri") ||
    164      !strcmp(aName, "network.trr.default_provider_uri") ||
    165      !strcmp(aName, kRolloutURIPref) ||
    166      !strcmp(aName, "network.trr.ohttp.uri")) {
    167    OnTRRURIChange();
    168  }
    169 
    170  if (!aName || !strcmp(aName, "network.trr.mode") ||
    171      !strcmp(aName, kRolloutModePref)) {
    172    OnTRRModeChange();
    173  }
    174 }
    175 
    176 void TRRServiceParent::ActorDestroy(ActorDestroyReason why) {
    177  sTRRServiceParentPtr = nullptr;
    178  Preferences::UnregisterPrefixCallbacks(TRRServiceParent::PrefsChanged,
    179                                         gTRRUriCallbackPrefs, this);
    180 }
    181 
    182 NS_IMETHODIMP TRRServiceParent::OnProxyConfigChanged() {
    183  LOG(("TRRServiceParent::OnProxyConfigChanged"));
    184 
    185  AsyncCreateTRRConnectionInfo(mPrivateURI);
    186  return NS_OK;
    187 }
    188 
    189 void TRRServiceParent::SetDefaultTRRConnectionInfo(
    190    nsHttpConnectionInfo* aConnInfo) {
    191  TRRServiceBase::SetDefaultTRRConnectionInfo(aConnInfo);
    192 
    193  if (!CanSend()) {
    194    return;
    195  }
    196 
    197  if (!aConnInfo) {
    198    (void)SendSetDefaultTRRConnectionInfo(Nothing());
    199    return;
    200  }
    201 
    202  HttpConnectionInfoCloneArgs infoArgs;
    203  nsHttpConnectionInfo::SerializeHttpConnectionInfo(aConnInfo, infoArgs);
    204  (void)SendSetDefaultTRRConnectionInfo(Some(infoArgs));
    205 }
    206 
    207 mozilla::ipc::IPCResult TRRServiceParent::RecvInitTRRConnectionInfo(
    208    bool aForceReinit) {
    209  InitTRRConnectionInfo(aForceReinit);
    210  return IPC_OK();
    211 }
    212 
    213 mozilla::ipc::IPCResult TRRServiceParent::RecvSetConfirmationState(
    214    uint32_t aNewState) {
    215  mConfirmationState = aNewState;
    216  return IPC_OK();
    217 }
    218 
    219 void TRRServiceParent::ReadEtcHostsFile() {
    220  if (!sTRRServiceParentPtr) {
    221    return;
    222  }
    223 
    224  DoReadEtcHostsFile([](const nsTArray<nsCString>* aArray) -> bool {
    225    RefPtr<TRRServiceParent> service(sTRRServiceParentPtr);
    226    if (service && aArray) {
    227      nsTArray<nsCString> hosts(aArray->Clone());
    228      NS_DispatchToMainThread(
    229          NS_NewRunnableFunction("TRRServiceParent::ReadEtcHostsFile",
    230                                 [service, hosts = std::move(hosts)]() mutable {
    231                                   if (service->CanSend()) {
    232                                     (void)service->SendUpdateEtcHosts(hosts);
    233                                   }
    234                                 }));
    235    }
    236    return !!service;
    237  });
    238 }
    239 
    240 }  // namespace net
    241 }  // namespace mozilla