Bug 40039: added min-height rule to Tor Circuit heading so onion icon is not cropped
[torbutton.git] / components / startup-observer.js
blobf969798704e5cf7d1d5d45ecbd4d5d0732375788
1 // Bug 1506 P1-3: This code is mostly hackish remnants of session store
2 // support. There are a couple of observer events that *might* be worth
3 // listening to. Search for 1506 in the code.
5 /*************************************************************************
6  * Startup observer (JavaScript XPCOM component)
7  *
8  * Cases tested (each during Tor and Non-Tor, FF4 and FF3.6)
9  *    1. Crash
10  *    2. Upgrade
11  *    3. Fresh install
12  *
13  *************************************************************************/
15 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
16 const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
18 XPCOMUtils.defineLazyModuleGetters(this, {
19   ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
20 });
22 XPCOMUtils.defineLazyModuleGetters(this, {
23   FileUtils: "resource://gre/modules/FileUtils.jsm",
24   FileSource: "resource://gre/modules/L10nRegistry.jsm",
25   L10nRegistry: "resource://gre/modules/L10nRegistry.jsm",
26 });
28 let NoScriptControl = ChromeUtils.import("resource://torbutton/modules/noscript-control.js", {});
29 let SecurityPrefs = ChromeUtils.import("resource://torbutton/modules/security-prefs.js", {});
31 // Module specific constants
32 const kMODULE_NAME = "Startup";
33 const kMODULE_CONTRACTID = "@torproject.org/startup-observer;1";
34 const kMODULE_CID = Components.ID("06322def-6fde-4c06-aef6-47ae8e799629");
36 function cleanupCookies() {
37   const migratedPref = "extensions.torbutton.cookiejar_migrated";
38   if (!Services.prefs.getBoolPref(migratedPref, false)) {
39     // Cleanup stored cookie-jar-selector json files
40     const profileFolder = Services.dirsvc.get("ProfD", Ci.nsIFile).clone();
41     for (const file of profileFolder.directoryEntries) {
42       if (file.leafName.match(/^(cookies|protected)-.*[.]json$/)) {
43         try {
44           file.remove(false);
45         } catch (e) {}
46       }
47     }
48     Services.prefs.setBoolPref(migratedPref, true);
49   }
52 function StartupObserver() {
53     this.logger = Cc["@torproject.org/torbutton-logger;1"]
54                     .getService(Ci.nsISupports).wrappedJSObject;
55     this._prefs = Services.prefs;
56     this.logger.log(3, "Startup Observer created");
58     var env = Cc["@mozilla.org/process/environment;1"]
59                 .getService(Ci.nsIEnvironment);
60     var prefName = "browser.startup.homepage";
61     if (env.exists("TOR_DEFAULT_HOMEPAGE")) {
62       // if the user has set this value in a previous installation, don't override it
63       if (!this._prefs.prefHasUserValue(prefName)) {
64         this._prefs.setCharPref(prefName, env.get("TOR_DEFAULT_HOMEPAGE"));
65       }
66     }
68     try {
69       var test = this._prefs.getCharPref("torbrowser.version");
70       this.is_tbb = true;
71       this.logger.log(3, "This is a Tor Browser's XPCOM");
72     } catch(e) {
73       this.logger.log(3, "This is not a Tor Browser's XPCOM");
74     }
76     try {
77       // XXX: We're in a race with HTTPS-Everywhere to update our proxy settings
78       // before the initial SSL-Observatory test... If we lose the race, Firefox
79       // caches the old proxy settings for check.tp.o somehwere, and it never loads :(
80       this.setProxySettings();
81     } catch(e) {
82       this.logger.log(4, "Early proxy change failed. Will try again at profile load. Error: "+e);
83     }
85     cleanupCookies();
87     // Using all possible locales so that we do not have to change this list every time we support
88     // a new one.
89     const allLocales = [
90       "en-US", "ach", "af", "an", "ar", "ast", "az", "be", "bg", "bn", "br", "bs", "ca", "cak",
91       "crh", "cs", "cy", "da", "de", "dsb", "el", "en-CA", "en-GB", "eo", "es-AR", "es-CL",
92       "es-ES", "es-MX", "et", "eu", "fa", "ff", "fi", "fr", "fy-NL", "ga-IE", "gd", "gl", "gn",
93       "gu-IN", "he", "hi-IN", "hr", "hsb", "hu", "hy-AM", "ia", "id", "is", "it", "ja",
94       "ja-JP-mac", "ka", "kab", "kk", "km", "kn", "ko", "lij", "lo", "lt", "ltg", "lv", "mk", "mr",
95       "ms", "my", "nb-NO", "ne-NP", "nl", "nn-NO", "oc", "pa-IN", "pl", "pt-BR", "pt-PT", "rm",
96       "ro", "ru", "si", "sk", "sl", "son", "sq", "sr", "sv-SE", "ta", "te", "th", "tl", "tr",
97       "trs", "uk", "ur", "uz", "vi", "wo", "xh", "zh-CN", "zh-TW"
98     ];
99     let torSource = new FileSource(
100       "torbutton",
101       allLocales,
102       "resource://torbutton/locale/{locale}/",
103       true, // skip this FileSource locales when computing Services.locale.availableLocales
104     );
105     if (L10nRegistry.registerSources) {
106       L10nRegistry.registerSources([torSource]);
107     } else {
108       L10nRegistry.registerSource(torSource);
109     }
112 StartupObserver.prototype = {
113     // Bug 6803: We need to get the env vars early due to
114     // some weird proxy caching code that showed up in FF15.
115     // Otherwise, homepage domain loads fail forever.
116     setProxySettings: function() {
117       if (!this.is_tbb)
118         return;
120       // Bug 1506: Still want to get these env vars
121       let environ = Cc["@mozilla.org/process/environment;1"]
122                       .getService(Ci.nsIEnvironment);
123       if (environ.exists("TOR_TRANSPROXY")) {
124         this.logger.log(3, "Resetting Tor settings to transproxy");
125         this._prefs.setBoolPref("network.proxy.socks_remote_dns", false);
126         this._prefs.setIntPref("network.proxy.type", 0);
127         this._prefs.setIntPref("network.proxy.socks_port", 0);
128         this._prefs.setCharPref("network.proxy.socks", "");
129       } else {
130         // Try to retrieve SOCKS proxy settings from Tor Launcher.
131         let socksPortInfo;
132         try {
133           let tlps = Cc["@torproject.org/torlauncher-protocol-service;1"]
134                      .getService(Ci.nsISupports).wrappedJSObject;
135           socksPortInfo = tlps.TorGetSOCKSPortInfo();
136         } catch(e) {
137           this.logger.log(3, "tor launcher failed " + e);
138         }
140         // If Tor Launcher is not available, check environment variables.
141         if (!socksPortInfo) {
142           socksPortInfo = { ipcFile: undefined, host: undefined, port: 0 };
144           let isWindows = Services.appinfo.OS === "WINNT";
145           if (!isWindows && environ.exists("TOR_SOCKS_IPC_PATH")) {
146             socksPortInfo.ipcFile = new FileUtils.File(
147                                            environ.get("TOR_SOCKS_IPC_PATH"));
148           }
149           else
150           {
151             if (environ.exists("TOR_SOCKS_HOST"))
152               socksPortInfo.host = environ.get("TOR_SOCKS_HOST");
153             if (environ.exists("TOR_SOCKS_PORT"))
154               socksPortInfo.port = parseInt(environ.get("TOR_SOCKS_PORT"));
155           }
156         }
158         // Adjust network.proxy prefs.
159         if (socksPortInfo.ipcFile) {
160           let fph = Services.io.getProtocolHandler("file")
161                                .QueryInterface(Ci.nsIFileProtocolHandler);
162           let fileURI = fph.newFileURI(socksPortInfo.ipcFile);
163           this.logger.log(3, "Reset socks to "+fileURI.spec);
164           this._prefs.setCharPref("network.proxy.socks", fileURI.spec);
165           this._prefs.setIntPref("network.proxy.socks_port", 0);
166         } else {
167           if (socksPortInfo.host) {
168             this._prefs.setCharPref("network.proxy.socks", socksPortInfo.host);
169             this.logger.log(3, "Reset socks host to "+socksPortInfo.host);
170           }
171           if (socksPortInfo.port) {
172             this._prefs.setIntPref("network.proxy.socks_port",
173                                    socksPortInfo.port);
174             this.logger.log(3, "Reset socks port to "+socksPortInfo.port);
175           }
176         }
178         if (socksPortInfo.ipcFile || socksPortInfo.host || socksPortInfo.port) {
179           this._prefs.setBoolPref("network.proxy.socks_remote_dns", true);
180           this._prefs.setIntPref("network.proxy.type", 1);
181         }
182       }
184       // Force prefs to be synced to disk
185       Services.prefs.savePrefFile(null);
187       this.logger.log(3, "Synced network settings to environment.");
188     },
190     observe: function(subject, topic, data) {
191       if(topic == "profile-after-change") {
192         // Bug 1506 P1: We listen to these prefs as signals for startup,
193         // but only for hackish reasons.
194         this._prefs.setBoolPref("extensions.torbutton.startup", true);
196         // We need to listen for NoScript before it starts.
197         NoScriptControl.initialize();
199         SecurityPrefs.initialize();
201         this.setProxySettings();
202       }
204       // In all cases, force prefs to be synced to disk
205       Services.prefs.savePrefFile(null);
206     },
208   QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
210   // method of nsIClassInfo
211   classDescription: "Torbutton Startup Observer",
212   classID: kMODULE_CID,
213   contractID: kMODULE_CONTRACTID,
215   // Hack to get us registered early to observe recovery
216   _xpcom_categories: [{category:"profile-after-change"}],
219 // Assign factory to global object.
220 const NSGetFactory = XPCOMUtils.generateNSGetFactory
221   ? XPCOMUtils.generateNSGetFactory([StartupObserver])
222   : ComponentUtils.generateNSGetFactory([StartupObserver]);