[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/tor-browser][tor-browser-154.0a1-17.0-2] fixup! TB 21952: Implement Onion-Location



Title: GitLab

Pier Angelo Vendrame pushed to branch tor-browser-154.0a1-17.0-2 at The Tor Project / Applications / Tor Browser

Commits:

  • 8154acd5
    by soni at 2026-10-15T01:09:18+02:00
    fixup! TB 21952: Implement Onion-Location
    

6 changed files:

Changes:

  • browser/components/BrowserComponents.manifest
    ... ... @@ -172,6 +172,7 @@ category browser-first-window-ready moz-src:///browser/modules/SecurityLevelNoti
    172 172
     category browser-first-window-ready moz-src:///toolkit/modules/DragDropFilter.sys.mjs DragDropFilter.init
    
    173 173
     category browser-first-window-ready moz-src:///browser/modules/TorSettingsNotification.sys.mjs TorSettingsNotification.ready
    
    174 174
     category browser-first-window-ready moz-src:///browser/components/onionservices/OnionAliasStore.sys.mjs OnionAliasStore.init
    
    175
    +category browser-first-window-ready moz-src:///browser/components/onionservices/OnionLocationWatch.sys.mjs OnionLocationWatch.init
    
    175 176
     
    
    176 177
     category browser-idle-startup moz-src:///browser/components/places/PlacesUIUtils.sys.mjs PlacesUIUtils.unblockToolbars
    
    177 178
     category browser-idle-startup resource:///modules/BuiltInThemes.sys.mjs BuiltInThemes.ensureBuiltInThemes
    
    ... ... @@ -220,5 +221,6 @@ category browser-quit-application-granted resource://gre/modules/UpdateListener.
    220 221
     #endif
    
    221 222
     category browser-quit-application-granted moz-src:///browser/components/urlbar/UrlbarSearchTermsPersistence.sys.mjs UrlbarSearchTermsPersistence.uninit
    
    222 223
     category browser-quit-application-granted moz-src:///browser/components/onionservices/OnionAliasStore.sys.mjs OnionAliasStore.uninit
    
    224
    +category browser-quit-application-granted moz-src:///browser/components/onionservices/OnionLocationWatch.sys.mjs OnionLocationWatch.uninit
    
    223 225
     
    
    224 226
     category browser-newtab-external-component moz-src:///browser/components/search/SearchUIUtils.sys.mjs SearchNewTabComponentsRegistrant

  • browser/components/DesktopActorRegistry.sys.mjs
    ... ... @@ -656,6 +656,7 @@ let JSWINDOWACTORS = {
    656 656
           },
    
    657 657
         },
    
    658 658
         messageManagerGroups: ["browsers"],
    
    659
    +    safeForUntrustedWebProcess: true,
    
    659 660
       },
    
    660 661
     
    
    661 662
       PageAssist: {
    

  • browser/components/onionservices/OnionLocationChild.sys.mjs
    ... ... @@ -14,32 +14,9 @@ export class OnionLocationChild extends JSWindowActorChild {
    14 14
         }
    
    15 15
         const onionLocationURI = this.document.onionLocationURI;
    
    16 16
         if (onionLocationURI) {
    
    17
    -      this.sendAsyncMessage("OnionLocation:Set");
    
    18
    -    }
    
    19
    -  }
    
    20
    -
    
    21
    -  receiveMessage(aMessage) {
    
    22
    -    if (aMessage.name == "OnionLocation:Refresh") {
    
    23
    -      const doc = this.document;
    
    24
    -      const docShell = this.docShell;
    
    25
    -      let onionLocationURI = doc.onionLocationURI;
    
    26
    -      const refreshURI = docShell.QueryInterface(Ci.nsIRefreshURI);
    
    27
    -      if (onionLocationURI && refreshURI) {
    
    28
    -        const docUrl = URL.parse(doc.URL);
    
    29
    -        let onionUrl = URL.parse(onionLocationURI.asciiSpec);
    
    30
    -        // Keep consistent with Location
    
    31
    -        if (!onionUrl?.hash && docUrl?.hash) {
    
    32
    -          onionUrl.hash = docUrl.hash;
    
    33
    -          onionLocationURI = Services.io.newURI(onionUrl?.toString() || "");
    
    34
    -        }
    
    35
    -        refreshURI.refreshURI(
    
    36
    -          onionLocationURI,
    
    37
    -          doc.nodePrincipal,
    
    38
    -          0,
    
    39
    -          false,
    
    40
    -          true
    
    41
    -        );
    
    42
    -      }
    
    17
    +      this.sendAsyncMessage("OnionLocation:Set", {
    
    18
    +        uri: onionLocationURI.asciiSpec,
    
    19
    +      });
    
    43 20
         }
    
    44 21
       }
    
    45 22
     }

  • browser/components/onionservices/OnionLocationParent.sys.mjs
    ... ... @@ -2,6 +2,8 @@
    2 2
     
    
    3 3
     import { TorStrings } from "moz-src:///toolkit/modules/TorStrings.sys.mjs";
    
    4 4
     
    
    5
    +import { BrowserUtils } from "resource://gre/modules/BrowserUtils.sys.mjs";
    
    6
    +
    
    5 7
     // Prefs
    
    6 8
     
    
    7 9
     // We keep the "prioritizeonions" name, even if obsolete, in order to
    
    ... ... @@ -36,36 +38,71 @@ export class OnionLocationParent extends JSWindowActorParent {
    36 38
         switch (aMsg.name) {
    
    37 39
           case "OnionLocation:Set": {
    
    38 40
             let browser = this.browsingContext.embedderElement;
    
    39
    -        OnionLocationParent.setOnionLocation(browser);
    
    41
    +        OnionLocationParent.setOnionLocationFallback(browser, aMsg);
    
    42
    +
    
    43
    +        // tor-browser #40100
    
    44
    +        // Wait for the page to fully load before showing the notification.
    
    45
    +        // This prevents redirects that occur before onPageShow from causing it to disappear.
    
    46
    +        // This could be handled more elegantly by changing the notification's "appear once and never again behaviour".
    
    47
    +        // Sites that redirect after the onPageShow event are not affected and will therefore cause the notification to disappear.
    
    48
    +        // https://gitlab.torproject.org/tpo/applications/tor-browser/-/merge_requests/2176#note_3459271
    
    49
    +        OnionLocationParent.showNotification(browser);
    
    40 50
             break;
    
    41 51
           }
    
    42 52
         }
    
    43 53
       }
    
    44 54
     
    
    55
    +  // Maintains compatibility with <meta http-equiv="onion-location">
    
    56
    +  static setOnionLocationFallback(browser, aMsg) {
    
    57
    +    let onionLocation;
    
    58
    +    try {
    
    59
    +      onionLocation = new URL(aMsg.data.uri);
    
    60
    +    } catch (e) {
    
    61
    +      return;
    
    62
    +    }
    
    63
    +
    
    64
    +    if (
    
    65
    +      browser &&
    
    66
    +      !browser._onionLocation &&
    
    67
    +      OnionLocationParent.validateOnionV3(onionLocation)
    
    68
    +    ) {
    
    69
    +      OnionLocationParent.setOnionLocation(browser, onionLocation);
    
    70
    +    }
    
    71
    +  }
    
    72
    +
    
    45 73
       static init(document) {
    
    46 74
         document
    
    47 75
           .getElementById(ONIONLOCATION_BOX_ID)
    
    48
    -      .addEventListener("click", event => this.buttonClick(event));
    
    76
    +      .addEventListener("click", event => this.openOnionLink(event));
    
    49 77
       }
    
    50 78
     
    
    51
    -  static buttonClick(event) {
    
    52
    -    if (event.button !== 0) {
    
    53
    -      return;
    
    54
    -    }
    
    79
    +  static openOnionLink(event) {
    
    55 80
         const win = event.target.documentGlobal;
    
    56
    -    if (win.gBrowser) {
    
    57
    -      const browser = win.gBrowser.selectedBrowser;
    
    58
    -      OnionLocationParent.redirect(browser);
    
    81
    +    const browser = win.gBrowser?.selectedBrowser;
    
    82
    +
    
    83
    +    if (!browser?._onionLocation || event.button > 1) {
    
    84
    +      return;
    
    59 85
         }
    
    60
    -  }
    
    61 86
     
    
    62
    -  static redirect(browser) {
    
    63
    -    let windowGlobal = browser.browsingContext.currentWindowGlobal;
    
    64
    -    let actor = windowGlobal.getActor("OnionLocation");
    
    65
    -    if (actor) {
    
    66
    -      actor.sendAsyncMessage("OnionLocation:Refresh", {});
    
    87
    +    const where = BrowserUtils.whereToOpenLink(event);
    
    88
    +    const triggeringPrincipal =
    
    89
    +      Services.scriptSecurityManager.getSystemPrincipal();
    
    90
    +
    
    91
    +    if (where == "current") {
    
    92
    +      browser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL);
    
    67 93
           OnionLocationParent.setDisabled(browser);
    
    68 94
         }
    
    95
    +
    
    96
    +    const onionUrl = browser._onionLocation;
    
    97
    +    const docUrl = new URL(browser.browsingContext.currentURI.asciiSpec);
    
    98
    +
    
    99
    +    if (docUrl.hash && docUrl.hash != onionUrl.hash) {
    
    100
    +      onionUrl.hash = docUrl.hash;
    
    101
    +    }
    
    102
    +
    
    103
    +    win.openLinkIn(onionUrl.href, where, {
    
    104
    +      triggeringPrincipal,
    
    105
    +    });
    
    69 106
       }
    
    70 107
     
    
    71 108
       static onStateChange(browser) {
    
    ... ... @@ -73,8 +110,8 @@ export class OnionLocationParent extends JSWindowActorParent {
    73 110
         OnionLocationParent.hideNotification(browser);
    
    74 111
       }
    
    75 112
     
    
    76
    -  static setOnionLocation(browser) {
    
    77
    -    browser._onionLocation = true;
    
    113
    +  static setOnionLocation(browser, onionLocation) {
    
    114
    +    browser._onionLocation = onionLocation;
    
    78 115
         let tabBrowser = browser.getTabBrowser();
    
    79 116
         if (tabBrowser && browser === tabBrowser.selectedBrowser) {
    
    80 117
           OnionLocationParent.updateOnionLocationBadge(browser);
    
    ... ... @@ -90,7 +127,7 @@ export class OnionLocationParent extends JSWindowActorParent {
    90 127
     
    
    91 128
       static showNotification(browser) {
    
    92 129
         const mustShow = Services.prefs.getBoolPref(NOTIFICATION_PREF, true);
    
    93
    -    if (!mustShow) {
    
    130
    +    if (!mustShow || !browser._onionLocation) {
    
    94 131
           return;
    
    95 132
         }
    
    96 133
     
    
    ... ... @@ -100,8 +137,8 @@ export class OnionLocationParent extends JSWindowActorParent {
    100 137
         const mainAction = {
    
    101 138
           label: NOTIFICATION_OK_LABEL,
    
    102 139
           accessKey: NOTIFICATION_OK_ACCESSKEY,
    
    103
    -      callback() {
    
    104
    -        OnionLocationParent.redirect(browser);
    
    140
    +      callback(obj) {
    
    141
    +        OnionLocationParent.openOnionLink(obj.event);
    
    105 142
           },
    
    106 143
         };
    
    107 144
     
    
    ... ... @@ -164,9 +201,15 @@ export class OnionLocationParent extends JSWindowActorParent {
    164 201
       static updateOnionLocationBadge(browser) {
    
    165 202
         if (browser._onionLocation) {
    
    166 203
           OnionLocationParent.setEnabled(browser);
    
    167
    -      OnionLocationParent.showNotification(browser);
    
    168 204
         } else {
    
    169 205
           OnionLocationParent.setDisabled(browser);
    
    170 206
         }
    
    171 207
       }
    
    208
    +
    
    209
    +  static validateOnionV3(url) {
    
    210
    +    if (!["http:", "https:"].includes(url.protocol)) {
    
    211
    +      return false;
    
    212
    +    }
    
    213
    +    return /(^|\.)[a-z2-7]{56}\.onion$/i.test(url.hostname);
    
    214
    +  }
    
    172 215
     }

  • browser/components/onionservices/OnionLocationWatch.sys.mjs
    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
    +import { OnionLocationParent } from "moz-src:///browser/components/onionservices/OnionLocationParent.sys.mjs";
    
    6
    +
    
    7
    +const log = console.createInstance({
    
    8
    +  prefix: "OnionLocationWatch",
    
    9
    +});
    
    10
    +
    
    11
    +/**
    
    12
    + * This request observer listens to http-on-examine-responses to know early if a clearnet site has an onion alternative.
    
    13
    + */
    
    14
    +class _OnionLocationWatch {
    
    15
    +  init() {
    
    16
    +    Services.obs.addObserver(this, "http-on-examine-response");
    
    17
    +    Services.obs.addObserver(this, "http-on-examine-cached-response");
    
    18
    +    Services.obs.addObserver(this, "http-on-examine-merged-response");
    
    19
    +    log.debug("Started");
    
    20
    +  }
    
    21
    +
    
    22
    +  uninit() {
    
    23
    +    Services.obs.removeObserver(this, "http-on-examine-response");
    
    24
    +    Services.obs.removeObserver(this, "http-on-examine-cached-response");
    
    25
    +    Services.obs.removeObserver(this, "http-on-examine-merged-response");
    
    26
    +    log.debug("Stopped");
    
    27
    +  }
    
    28
    +
    
    29
    +  // nsIObserver implementation
    
    30
    +  observe(subject, topic) {
    
    31
    +    try {
    
    32
    +      let channel = ChannelWrapper.get(
    
    33
    +        subject.QueryInterface(Ci.nsIHttpChannel)
    
    34
    +      );
    
    35
    +      switch (topic) {
    
    36
    +        case "http-on-examine-cached-response":
    
    37
    +        case "http-on-examine-merged-response":
    
    38
    +        case "http-on-examine-response":
    
    39
    +          this.onResponse(channel);
    
    40
    +          break;
    
    41
    +      }
    
    42
    +    } catch (e) {
    
    43
    +      log.error(e);
    
    44
    +    }
    
    45
    +  }
    
    46
    +
    
    47
    +  onResponse(channel) {
    
    48
    +    this.checkResponseForOnionLocation(channel);
    
    49
    +  }
    
    50
    +
    
    51
    +  checkResponseForOnionLocation(channel) {
    
    52
    +    const browser = channel.browserElement;
    
    53
    +    const uri = channel.finalURI;
    
    54
    +
    
    55
    +    if (!browser || uri?.scheme != "https") {
    
    56
    +      return;
    
    57
    +    }
    
    58
    +
    
    59
    +    const isTopLevelDoc =
    
    60
    +      channel.channel.loadInfo.isTopLevelLoad && channel.channel.isDocument;
    
    61
    +    const isOnion = uri.host?.toLowerCase().endsWith(".onion");
    
    62
    +
    
    63
    +    if (isTopLevelDoc && !isOnion && !browser._onionLocation) {
    
    64
    +      const onionLocation = this.getOnionLocation(channel);
    
    65
    +      if (onionLocation) {
    
    66
    +        OnionLocationParent.setOnionLocation(browser, onionLocation);
    
    67
    +      }
    
    68
    +    }
    
    69
    +  }
    
    70
    +
    
    71
    +  getOnionLocation(channel) {
    
    72
    +    let onionLocation = channel
    
    73
    +      .getResponseHeaders()
    
    74
    +      .find(el => el.name.toLowerCase() == "onion-location")?.value;
    
    75
    +
    
    76
    +    if (onionLocation) {
    
    77
    +      try {
    
    78
    +        onionLocation = new URL(onionLocation);
    
    79
    +      } catch (e) {
    
    80
    +        return null;
    
    81
    +      }
    
    82
    +
    
    83
    +      if (OnionLocationParent.validateOnionV3(onionLocation)) {
    
    84
    +        return onionLocation;
    
    85
    +      }
    
    86
    +    }
    
    87
    +    return null;
    
    88
    +  }
    
    89
    +}
    
    90
    +
    
    91
    +export const OnionLocationWatch = new _OnionLocationWatch();

  • browser/components/onionservices/moz.build
    ... ... @@ -4,5 +4,6 @@ MOZ_SRC_FILES += [
    4 4
         "OnionAliasStore.sys.mjs",
    
    5 5
         "OnionLocationChild.sys.mjs",
    
    6 6
         "OnionLocationParent.sys.mjs",
    
    7
    +    "OnionLocationWatch.sys.mjs",
    
    7 8
         "TorRequestWatch.sys.mjs",
    
    8 9
     ]

  • _______________________________________________
    tor-commits mailing list -- tor-commits@xxxxxxxxxxxxxxxxxxxx
    To unsubscribe send an email to tor-commits-leave@xxxxxxxxxxxxxxxxxxxx