tor-browser

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

main.cpp (6798B)


      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 <windows.h>
      6 #include "resource.h"
      7 #include "WebBrowser.h"
      8 #include "exdll.h"
      9 
     10 // These variables are global because they're needed by more than one of
     11 // our plugin methods. The expectation is that these are safe because the
     12 // NSIS framework doesn't really support more than one dialog or thread
     13 // at a time, and that means we don't have to either.
     14 
     15 // Instance handle for this DLL
     16 HINSTANCE gHInst = nullptr;
     17 // Parent window proc which we'll need to override and then restore
     18 WNDPROC gWndProcOld = nullptr;
     19 // Handle to the dialog we'll create
     20 HWND gHwnd = nullptr;
     21 // Set to true when our dialog should be destroyed
     22 bool gDone = false;
     23 // Web browser OLE site
     24 WebBrowser* gBrowser = nullptr;
     25 
     26 // Set web browser control feature flags that are configured on a per-process
     27 // basis, not for individual instances of the control. This mainly means
     28 // disabling things that could turn into security holes.
     29 static void ConfigurePerProcessBrowserFeatures() {
     30  // For most of the features we're configuring, setting them to TRUE means
     31  // we're disabling something, but for a few setting them to FALSE disables the
     32  // thing. We don't necessarily care about *every* feature that's in the
     33  // INTERNETFEATURELIST enum, but it seems safer to set them all anyway, to
     34  // make sure we don't miss anything we *do* care about.
     35  struct Feature {
     36    INTERNETFEATURELIST id;
     37    BOOL value;
     38  } features[] = {{FEATURE_OBJECT_CACHING, TRUE},
     39                  {FEATURE_ZONE_ELEVATION, TRUE},
     40                  {FEATURE_MIME_HANDLING, TRUE},
     41                  {FEATURE_MIME_SNIFFING, FALSE},
     42                  {FEATURE_WINDOW_RESTRICTIONS, TRUE},
     43                  {FEATURE_WEBOC_POPUPMANAGEMENT, TRUE},
     44                  {FEATURE_BEHAVIORS, TRUE},
     45                  {FEATURE_DISABLE_MK_PROTOCOL, TRUE},
     46                  // It isn't possible to set FEATURE_LOCALMACHINE_LOCKDOWN
     47                  // using the SET_FEATURE_ON_PROCESS mode; see the MSDN page
     48                  // on CoInternetSetFeatureEnabled for the explanation.
     49                  //{FEATURE_LOCALMACHINE_LOCKDOWN, TRUE},
     50                  {FEATURE_SECURITYBAND, FALSE},
     51                  {FEATURE_RESTRICT_ACTIVEXINSTALL, TRUE},
     52                  {FEATURE_VALIDATE_NAVIGATE_URL, TRUE},
     53                  {FEATURE_RESTRICT_FILEDOWNLOAD, TRUE},
     54                  {FEATURE_ADDON_MANAGEMENT, TRUE},
     55                  {FEATURE_PROTOCOL_LOCKDOWN, TRUE},
     56                  {FEATURE_HTTP_USERNAME_PASSWORD_DISABLE, TRUE},
     57                  {FEATURE_SAFE_BINDTOOBJECT, TRUE},
     58                  {FEATURE_UNC_SAVEDFILECHECK, TRUE},
     59                  {FEATURE_GET_URL_DOM_FILEPATH_UNENCODED, FALSE},
     60                  {FEATURE_TABBED_BROWSING, FALSE},
     61                  {FEATURE_SSLUX, FALSE},
     62                  {FEATURE_DISABLE_NAVIGATION_SOUNDS, TRUE},
     63                  {FEATURE_DISABLE_LEGACY_COMPRESSION, TRUE},
     64                  {FEATURE_FORCE_ADDR_AND_STATUS, FALSE},
     65                  {FEATURE_XMLHTTP, FALSE},
     66                  {FEATURE_DISABLE_TELNET_PROTOCOL, TRUE},
     67                  {FEATURE_FEEDS, FALSE},
     68                  {FEATURE_BLOCK_INPUT_PROMPTS, TRUE}};
     69 
     70  for (Feature feature : features) {
     71    CoInternetSetFeatureEnabled(feature.id, SET_FEATURE_ON_PROCESS,
     72                                feature.value);
     73  }
     74 }
     75 
     76 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID) {
     77  if (reason == DLL_PROCESS_ATTACH) {
     78    gHInst = instance;
     79    (void)OleInitialize(nullptr);
     80    ConfigurePerProcessBrowserFeatures();
     81  }
     82  return TRUE;
     83 }
     84 
     85 UINT_PTR __cdecl NSISPluginCallback(NSPIM msg) {
     86  if (msg == NSPIM_UNLOAD) {
     87    OleUninitialize();
     88  }
     89  return 0;
     90 }
     91 
     92 BOOL CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam,
     93                            LPARAM lParam) {
     94  BOOL bRes =
     95      CallWindowProc((WNDPROC)gWndProcOld, hwnd, message, wParam, lParam);
     96  if (!bRes && message == WM_NOTIFY_OUTER_NEXT) {
     97    gDone = true;
     98    PostMessage(gHwnd, WM_CLOSE, 0, 0);
     99  }
    100  return bRes;
    101 }
    102 
    103 BOOL CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    104  return FALSE;
    105 }
    106 
    107 void Init(HWND hWndParent, int string_size, TCHAR* variables,
    108          stack_t** stacktop, extra_parameters* extra) {
    109  EXDLL_INIT();
    110  extra->RegisterPluginCallback(gHInst, NSISPluginCallback);
    111 
    112  HWND hwndChild = GetDlgItem(hWndParent, 1018);
    113  if (!hwndChild) {
    114    return;
    115  }
    116 
    117  HWND hwnd =
    118      CreateDialog(gHInst, MAKEINTRESOURCE(IDD_DIALOG1), hWndParent, DlgProc);
    119  if (!hwnd) {
    120    gDone = true;
    121  } else {
    122    gDone = false;
    123    gWndProcOld =
    124        (WNDPROC)SetWindowLong(hWndParent, DWL_DLGPROC, (LONG)ParentWndProc);
    125 
    126    // Tell NSIS to replace its inner dialog with ours.
    127    SendMessage(hWndParent, WM_NOTIFY_CUSTOM_READY, (WPARAM)hwnd, 0);
    128 
    129    // Initialize the browser control.
    130    if (gBrowser) {
    131      gBrowser->Shutdown();
    132      gBrowser->Release();
    133    }
    134    gBrowser = new WebBrowser(hwnd);
    135 
    136    if (!gBrowser || !gBrowser->IsInitialized()) {
    137      return;
    138    }
    139 
    140    gHwnd = hwnd;
    141 
    142    // Move our dialog to match the size of the parent.
    143    RECT r;
    144    GetClientRect(hwndChild, &r);
    145    MoveWindow(hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, FALSE);
    146    gBrowser->SetRect(r);
    147  }
    148 }
    149 
    150 PLUGINFUNCTION(ShowPage) {
    151  if (!gBrowser) {
    152    Init(hWndParent, string_size, variables, stacktop, extra);
    153  }
    154 
    155  if (!gBrowser->IsInitialized()) {
    156    return;
    157  }
    158 
    159  TCHAR* sUrl =
    160      (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR));
    161  popstring(sUrl);
    162 
    163  if (gBrowser) {
    164    gBrowser->Navigate(sUrl);
    165 
    166    ShowWindow(gHwnd, SW_SHOWNA);
    167    UpdateWindow(gHwnd);
    168 
    169    while (!gDone) {
    170      // This explicit wait call is needed rather than just a blocking
    171      // GetMessage because we need this thread to be alertable so that our
    172      // timers can wake it up and run their callbacks.
    173      MsgWaitForMultipleObjectsEx(0, nullptr, 100, QS_ALLINPUT,
    174                                  MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
    175      MSG msg;
    176      if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
    177        bool tab = msg.message == WM_KEYDOWN && msg.wParam == VK_TAB;
    178 
    179        if (gBrowser->ActiveObjectTranslateAccelerator(tab, &msg) != S_OK &&
    180            !IsDialogMessage(gHwnd, &msg) &&
    181            !IsDialogMessage(g_hwndParent, &msg)) {
    182          TranslateMessage(&msg);
    183          DispatchMessage(&msg);
    184        }
    185      }
    186    }
    187 
    188    SetWindowLong(g_hwndParent, DWL_DLGPROC, (LONG)gWndProcOld);
    189    if (gHwnd) {
    190      DestroyWindow(gHwnd);
    191    }
    192 
    193    gBrowser->Shutdown();
    194    gBrowser->Release();
    195    gBrowser = nullptr;
    196  }
    197 
    198  HeapFree(GetProcessHeap(), 0, (char*)sUrl);
    199 }