tor-browser

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

HttpWinUtils.cpp (3877B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "HttpWinUtils.h"
      6 #include "nsIURI.h"
      7 #include "nsHttpChannel.h"
      8 #include "mozilla/ClearOnShutdown.h"
      9 #include <proofofpossessioncookieinfo.h>
     10 
     11 namespace mozilla {
     12 namespace net {
     13 
     14 static StaticRefPtr<IProofOfPossessionCookieInfoManager> sPopCookieManager;
     15 static bool sPopCookieManagerAvailable = true;
     16 
     17 void AddWindowsSSO(nsHttpChannel* channel) {
     18  if (!sPopCookieManagerAvailable) {
     19    MOZ_LOG(gHttpLog, mozilla::LogLevel::Debug,
     20            ("HttpWinUtils::AddWindowsSSO: sPopCookieManager is not available "
     21             "from the beginning"));
     22    return;
     23  }
     24  HRESULT hr;
     25  if (!sPopCookieManager) {
     26    GUID CLSID_ProofOfPossessionCookieInfoManager;
     27    GUID IID_IProofOfPossessionCookieInfoManager;
     28 
     29    CLSIDFromString(L"{A9927F85-A304-4390-8B23-A75F1C668600}",
     30                    &CLSID_ProofOfPossessionCookieInfoManager);
     31    IIDFromString(L"{CDAECE56-4EDF-43DF-B113-88E4556FA1BB}",
     32                  &IID_IProofOfPossessionCookieInfoManager);
     33 
     34    hr = CoCreateInstance(CLSID_ProofOfPossessionCookieInfoManager, NULL,
     35                          CLSCTX_INPROC_SERVER,
     36                          IID_IProofOfPossessionCookieInfoManager,
     37                          reinterpret_cast<void**>(&sPopCookieManager));
     38    if (FAILED(hr)) {
     39      sPopCookieManagerAvailable = false;
     40      MOZ_LOG(
     41          gHttpLog, mozilla::LogLevel::Debug,
     42          ("HttpWinUtils::AddWindowsSSO: sPopCookieManager is not available"));
     43      return;
     44    }
     45 
     46    RunOnShutdown([&] {
     47      if (sPopCookieManager) {
     48        sPopCookieManager = nullptr;
     49      }
     50    });
     51  }
     52 
     53  DWORD cookieCount = 0;
     54  ProofOfPossessionCookieInfo* cookieInfo = nullptr;
     55 
     56  nsCOMPtr<nsIURI> uri;
     57  channel->GetURI(getter_AddRefs(uri));
     58 
     59  nsAutoCString urispec;
     60  uri->GetSpec(urispec);
     61 
     62  hr = sPopCookieManager->GetCookieInfoForUri(
     63      NS_ConvertUTF8toUTF16(urispec).get(), &cookieCount, &cookieInfo);
     64  if (FAILED(hr)) {
     65    MOZ_LOG(gHttpLog, mozilla::LogLevel::Debug,
     66            ("HttpWinUtils::AddWindowsSSO: GetCookieInfoForUri failed"));
     67    return;
     68  }
     69 
     70  nsAutoCString host;
     71  uri->GetHost(host);
     72  bool addCookies = false;
     73  if (StringEndsWith(host, ".live.com"_ns)) {
     74    addCookies = true;
     75  }
     76 
     77  nsAutoString allCookies;
     78 
     79  for (DWORD i = 0; i < cookieCount; i++) {
     80    nsAutoString cookieData;
     81    cookieData.Assign(cookieInfo[i].data);
     82    // Strip old Set-Cookie info for WinInet
     83    int32_t semicolon = cookieData.FindChar(';');
     84    if (semicolon >= 0) {
     85      cookieData.SetLength(semicolon);
     86    }
     87    if (StringBeginsWith(nsDependentString(cookieInfo[i].name), u"x-ms-"_ns)) {
     88      channel->SetRequestHeader(NS_ConvertUTF16toUTF8(cookieInfo[i].name),
     89                                NS_ConvertUTF16toUTF8(cookieData),
     90                                true /* merge */);
     91    } else if (addCookies) {
     92      if (!allCookies.IsEmpty()) {
     93        allCookies.AppendLiteral("; ");
     94      }
     95      allCookies.Append(cookieInfo[i].name);
     96      allCookies.AppendLiteral("=");
     97      allCookies.Append(cookieData);
     98    }
     99  }
    100 
    101  // Merging cookie headers doesn't work correctly as it separates the new
    102  // cookies using commas instead of semicolons, so we have to replace
    103  // the entire header.
    104  if (!allCookies.IsEmpty()) {
    105    nsAutoCString cookieHeader;
    106    channel->GetRequestHeader(nsHttp::Cookie.val(), cookieHeader);
    107    if (!cookieHeader.IsEmpty()) {
    108      cookieHeader.AppendLiteral("; ");
    109    }
    110    cookieHeader.Append(NS_ConvertUTF16toUTF8(allCookies));
    111    channel->SetRequestHeader(nsHttp::Cookie.val(), cookieHeader, false);
    112  }
    113  if (cookieInfo) {
    114    FreeProofOfPossessionCookieInfoArray(cookieInfo, cookieCount);
    115  }
    116 }
    117 
    118 }  // namespace net
    119 }  // namespace mozilla