summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/btr/proxy/search/browser/firefox
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/btr/proxy/search/browser/firefox')
-rw-r--r--src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProfileSource.java23
-rw-r--r--src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java267
-rw-r--r--src/main/java/com/btr/proxy/search/browser/firefox/FirefoxSettingParser.java79
-rw-r--r--src/main/java/com/btr/proxy/search/browser/firefox/LinuxFirefoxProfileSource.java46
-rw-r--r--src/main/java/com/btr/proxy/search/browser/firefox/WinFirefoxProfileSource.java71
5 files changed, 486 insertions, 0 deletions
diff --git a/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProfileSource.java b/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProfileSource.java
new file mode 100644
index 0000000..8517074
--- /dev/null
+++ b/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProfileSource.java
@@ -0,0 +1,23 @@
+package com.btr.proxy.search.browser.firefox;
+
+import java.io.File;
+import java.io.IOException;
+
+/*****************************************************************************
+ * A profile source for Firefox profiles.
+ *
+ * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
+ ****************************************************************************/
+
+interface FirefoxProfileSource {
+
+ /*************************************************************************
+ * Gets a profile folder found on the current system.
+ * If multiple profile folders are available the "default" profile is chosen.
+ * @return a profile folder.
+ * @throws IOException on error.
+ ************************************************************************/
+
+ public File getProfileFolder() throws IOException;
+
+}
diff --git a/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java
new file mode 100644
index 0000000..30c3be1
--- /dev/null
+++ b/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java
@@ -0,0 +1,267 @@
+package com.btr.proxy.search.browser.firefox;
+
+import java.io.IOException;
+import java.net.ProxySelector;
+import java.util.Properties;
+
+import com.btr.proxy.search.ProxySearchStrategy;
+import com.btr.proxy.search.desktop.DesktopProxySearchStrategy;
+import com.btr.proxy.search.wpad.WpadProxySearchStrategy;
+import com.btr.proxy.selector.direct.NoProxySelector;
+import com.btr.proxy.selector.fixed.FixedProxySelector;
+import com.btr.proxy.selector.fixed.FixedSocksSelector;
+import com.btr.proxy.selector.misc.ProtocolDispatchSelector;
+import com.btr.proxy.selector.whitelist.ProxyBypassListSelector;
+import com.btr.proxy.util.Logger;
+import com.btr.proxy.util.Logger.LogLevel;
+import com.btr.proxy.util.PlatformUtil;
+import com.btr.proxy.util.PlatformUtil.Platform;
+import com.btr.proxy.util.ProxyException;
+import com.btr.proxy.util.ProxyUtil;
+
+/*****************************************************************************
+ * Loads the Firefox3 proxy settings from the users Firefox3 settings.
+ * This will load the file <i>prefs.js</i> that is located in the
+ * <p>
+ * <i>.mozilla/firefox/(profile)/</i> folder.
+ * </p>
+ *
+ * See <a href="https://developer.mozilla.org/En/Mozilla_Networking_Preferences">Mozilla_Networking_Preferences</a>
+ * for an explanation of the proxy settings.
+ * <p>
+ * The following settings are extracted from
+ * this file:
+ * </p>
+ * Some generic settings:<br/>
+ * <ul>
+ * <li><i>network.proxy.type</i> -> n/a = use system settings, 0 = direct, 1 = Fixed proxy settings, 2 = proxy script (PAC), 3 = also direct , 4 = auto detect (WPAD)</li>
+ * <li><i>network.proxy.share_proxy_settings</i> -> true = use same proxy for all protocols</li>
+ * <li><i>network.proxy.no_proxies_on</i> -> a comma separated ignore list. </li>
+ * <li><i>network.proxy.autoconfig_url</i> -> a URL to an proxy configuration script</li>
+ * </ul>
+ * Host names and ports per protocol are stored in the following settings:
+ * <ul>
+ * <li><i>network.proxy.http</i></li>
+ * <li><i>network.proxy.http_port</i></li>
+ * <li><i>network.proxy.ssl</i></li>
+ * <li><i>network.proxy.ssl_port</i></li>
+ * <li><i>network.proxy.ftp</i></li>
+ * <li><i>network.proxy.ftp_port</i></li>
+ * <li><i>network.proxy.gopher</i></li>
+ * <li><i>network.proxy.gopher_port</i></li>
+ * <li><i>network.proxy.socks</i></li>
+ * <li><i>network.proxy.socks_port</i></li>
+ * <li><i>network.proxy.socks_version</i> -> 4 or 5</li>
+ * </u>
+ * <p>
+ * Note that if there are more than one profile the first profile found will be used.
+ * </p>
+ * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
+ ****************************************************************************/
+
+public class FirefoxProxySearchStrategy implements ProxySearchStrategy {
+
+ private FirefoxProfileSource profileScanner;
+ private FirefoxSettingParser settingsParser;
+
+ /*************************************************************************
+ * ProxySelector
+ * @see java.net.ProxySelector#ProxySelector()
+ ************************************************************************/
+
+ public FirefoxProxySearchStrategy() {
+ super();
+ if (PlatformUtil.getCurrentPlattform() == Platform.WIN) {
+ this.profileScanner = new WinFirefoxProfileSource();
+ } else {
+ this.profileScanner = new LinuxFirefoxProfileSource();
+ }
+ this.settingsParser = new FirefoxSettingParser();
+ }
+
+ /*************************************************************************
+ * Loads the proxy settings and initializes a proxy selector for the firefox
+ * proxy settings.
+ * @return a configured ProxySelector, null if none is found.
+ * @throws ProxyException on file reading error.
+ ************************************************************************/
+
+ public ProxySelector getProxySelector() throws ProxyException {
+ Logger.log(getClass(), LogLevel.TRACE, "Detecting Firefox settings.");
+
+ Properties settings = readSettings();
+
+ ProxySelector result = null;
+ int type = Integer.parseInt(settings.getProperty("network.proxy.type", "-1"));
+ switch (type) {
+ case -1: // Use system settings
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox uses system settings");
+ result = new DesktopProxySearchStrategy().getProxySelector();
+ break;
+ case 0: // Use no proxy
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox uses no proxy");
+ result = NoProxySelector.getInstance();
+ break;
+ case 1: // Fixed settings
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox uses manual settings");
+ result = setupFixedProxySelector(settings);
+ break;
+ case 2: // PAC Script
+ String pacScriptUrl = settings.getProperty("network.proxy.autoconfig_url", "");
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox uses script (PAC) {0}", pacScriptUrl);
+ result = ProxyUtil.buildPacSelectorForUrl(pacScriptUrl);
+ break;
+ case 3: // Backward compatibility to netscape.
+ Logger.log(getClass(), LogLevel.TRACE, "Netscape compability mode -> uses no proxy");
+ result = NoProxySelector.getInstance();
+ break;
+ case 4: // WPAD auto config
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox uses automatic detection (WPAD)");
+ result = new WpadProxySearchStrategy().getProxySelector();
+ break;
+ default:
+ break;
+ }
+
+ // Wrap in white list filter.
+ String noProxyList = settings.getProperty("network.proxy.no_proxies_on", null);
+ if (result != null && noProxyList != null && noProxyList.trim().length() > 0) {
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox uses proxy bypass list for: {0}", noProxyList);
+ result = new ProxyBypassListSelector(noProxyList, result);
+ }
+
+ return result;
+ }
+
+ /*************************************************************************
+ * Reads the settings file and stores all settings in a Properties map.
+ * @return the parsed settings.
+ * @throws ProxyException on read error.
+ ************************************************************************/
+
+ public Properties readSettings() throws ProxyException {
+ try {
+ Properties settings = this.settingsParser.parseSettings(this.profileScanner);
+ return settings;
+ } catch (IOException e) {
+ Logger.log(getClass(), LogLevel.ERROR, "Error parsing settings", e);
+ throw new ProxyException(e);
+ }
+ }
+
+ /*************************************************************************
+ * Parse the fixed proxy settings and build an ProxySelector for this a
+ * chained configuration.
+ * @param settings the proxy settings to evaluate.
+ ************************************************************************/
+
+ private ProxySelector setupFixedProxySelector(Properties settings) {
+ ProtocolDispatchSelector ps = new ProtocolDispatchSelector();
+ installHttpProxy(ps, settings);
+ if (isProxyShared(settings)) {
+ installSharedProxy(ps);
+ } else {
+ installFtpProxy(ps, settings);
+ installSecureProxy(ps, settings);
+ installSocksProxy(ps, settings);
+ }
+ return ps;
+ }
+
+ /*************************************************************************
+ * @param ps
+ * @param settings
+ * @throws NumberFormatException
+ ************************************************************************/
+
+ private void installFtpProxy(ProtocolDispatchSelector ps,
+ Properties settings) throws NumberFormatException {
+ installSelectorForProtocol(ps, settings, "ftp");
+ }
+
+ /*************************************************************************
+ * @param ps
+ * @param settings
+ * @throws NumberFormatException
+ ************************************************************************/
+
+ private void installHttpProxy(ProtocolDispatchSelector ps,
+ Properties settings) throws NumberFormatException {
+ installSelectorForProtocol(ps, settings, "http");
+ }
+
+ /*************************************************************************
+ * @param settings
+ * @return
+ ************************************************************************/
+
+ private boolean isProxyShared(Properties settings) {
+ return Boolean.TRUE.toString().equals(settings.getProperty("network.proxy.share_proxy_settings", "false").toLowerCase());
+ }
+
+ /*************************************************************************
+ * @param ps
+ ************************************************************************/
+
+ private void installSharedProxy(ProtocolDispatchSelector ps) {
+ ProxySelector httpProxy = ps.getSelector("http");
+ if (httpProxy != null) {
+ ps.setFallbackSelector(httpProxy);
+ }
+ }
+
+ /*************************************************************************
+ * @param ps
+ * @param settings
+ * @throws NumberFormatException
+ ************************************************************************/
+
+ private void installSocksProxy(ProtocolDispatchSelector ps,
+ Properties settings) throws NumberFormatException {
+ String proxyHost = settings.getProperty("network.proxy.socks", null);
+ int proxyPort = Integer.parseInt(settings.getProperty("network.proxy.socks_port", "0"));
+ if (proxyHost != null && proxyPort != 0) {
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox socks proxy is {0}:{1}", proxyHost, proxyPort);
+ ps.setSelector("socks", new FixedSocksSelector(proxyHost, proxyPort));
+ }
+ }
+
+ /*************************************************************************
+ * @param ps
+ * @param settings
+ * @throws NumberFormatException
+ ************************************************************************/
+
+ private void installSecureProxy(ProtocolDispatchSelector ps,
+ Properties settings) throws NumberFormatException {
+ String proxyHost = settings.getProperty("network.proxy.ssl", null);
+ int proxyPort = Integer.parseInt(settings.getProperty("network.proxy.ssl_port", "0"));
+ if (proxyHost != null && proxyPort != 0) {
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox secure proxy is {0}:{1}", proxyHost, proxyPort);
+ ps.setSelector("https", new FixedProxySelector(proxyHost, proxyPort));
+ ps.setSelector("sftp", new FixedProxySelector(proxyHost, proxyPort));
+ }
+ }
+
+ /*************************************************************************
+ * Installs a proxy selector for the given protocol when settings are
+ * available.
+ * @param ps a ProtocolDispatchSelector to configure.
+ * @param settings to read the config from.
+ * @param protocol to configure.
+ * @throws NumberFormatException
+ ************************************************************************/
+
+ private void installSelectorForProtocol(ProtocolDispatchSelector ps,
+ Properties settings, String protocol) throws NumberFormatException {
+
+ String proxyHost = settings.getProperty("network.proxy."+protocol, null);
+ int proxyPort = Integer.parseInt(settings.getProperty("network.proxy."+protocol+"_port", "0"));
+ if (proxyHost != null && proxyPort != 0) {
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox "+protocol+" proxy is {0}:{1}", proxyHost, proxyPort);
+ ps.setSelector(protocol, new FixedProxySelector(proxyHost, proxyPort));
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxSettingParser.java b/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxSettingParser.java
new file mode 100644
index 0000000..b793299
--- /dev/null
+++ b/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxSettingParser.java
@@ -0,0 +1,79 @@
+package com.btr.proxy.search.browser.firefox;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Properties;
+
+/*****************************************************************************
+ * Parser for the Firefox settings file.
+ * Will extract all relevant proxy settings form the configuration file.
+ *
+ * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
+ ****************************************************************************/
+
+class FirefoxSettingParser {
+
+ /*************************************************************************
+ * Constructor
+ ************************************************************************/
+
+ public FirefoxSettingParser() {
+ super();
+ }
+
+ /*************************************************************************
+ * Parse the settings file and extract all network.proxy.* settings from it.
+ * @param source of the Firefox profiles.
+ * @return the parsed properties.
+ * @throws IOException on read error.
+ ************************************************************************/
+
+ public Properties parseSettings(FirefoxProfileSource source) throws IOException {
+ // Search settings folder
+ File profileFolder = source.getProfileFolder();
+
+ // Read settings from file
+ File settingsFile = new File(profileFolder, "prefs.js");
+
+ BufferedReader fin = new BufferedReader(
+ new InputStreamReader(
+ new FileInputStream(settingsFile)));
+
+ Properties result = new Properties();
+ try {
+ String line = fin.readLine();
+ while (line != null) {
+ line = line.trim();
+ if (line.startsWith("user_pref(\"network.proxy")) {
+ line = line.substring(10, line.length()-2);
+ int index = line.indexOf(",");
+ String key = line.substring(0, index).trim();
+ if (key.startsWith("\"")) {
+ key = key.substring(1);
+ }
+ if (key.endsWith("\"")) {
+ key = key.substring(0, key.length()-1);
+ }
+ String value = line.substring(index+1).trim();
+ if (value.startsWith("\"")) {
+ value = value.substring(1);
+ }
+ if (value.endsWith("\"")) {
+ value = value.substring(0, value.length()-1);
+ }
+ result.put(key, value);
+ }
+ line = fin.readLine();
+ }
+ } finally {
+ fin.close();
+ }
+
+ return result;
+ }
+
+
+}
diff --git a/src/main/java/com/btr/proxy/search/browser/firefox/LinuxFirefoxProfileSource.java b/src/main/java/com/btr/proxy/search/browser/firefox/LinuxFirefoxProfileSource.java
new file mode 100644
index 0000000..38b1553
--- /dev/null
+++ b/src/main/java/com/btr/proxy/search/browser/firefox/LinuxFirefoxProfileSource.java
@@ -0,0 +1,46 @@
+package com.btr.proxy.search.browser.firefox;
+
+import java.io.File;
+
+import com.btr.proxy.util.Logger;
+import com.btr.proxy.util.Logger.LogLevel;
+
+/*****************************************************************************
+ * Searches for Firefox profile on an Linux / Unix base system.
+ * This will scan the <i>.mozilla</i> folder in the users home directory to find the
+ * profiles.
+ *
+ * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
+ ****************************************************************************/
+
+class LinuxFirefoxProfileSource implements FirefoxProfileSource {
+
+ /*************************************************************************
+ * Get profile folder for the Linux Firefox profile
+ ************************************************************************/
+
+ public File getProfileFolder() {
+ File userDir = new File(System.getProperty("user.home"));
+ File cfgDir = new File(userDir, ".mozilla"+File.separator+"firefox"+File.separator);
+ if (!cfgDir.exists()) {
+ Logger.log(getClass(), LogLevel.DEBUG, "Firefox settings folder not found!");
+ return null;
+ }
+ File[] profiles = cfgDir.listFiles();
+ if (profiles == null || profiles.length == 0) {
+ Logger.log(getClass(), LogLevel.DEBUG, "Firefox settings folder not found!");
+ return null;
+ }
+ for (File p : profiles) {
+ if (p.getName().endsWith(".default")) {
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox settings folder is {0}", p);
+ return p;
+ }
+ }
+
+ // Fall back -> take the first one found.
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox settings folder is {0}", profiles[0]);
+ return profiles[0];
+ }
+
+}
diff --git a/src/main/java/com/btr/proxy/search/browser/firefox/WinFirefoxProfileSource.java b/src/main/java/com/btr/proxy/search/browser/firefox/WinFirefoxProfileSource.java
new file mode 100644
index 0000000..9189585
--- /dev/null
+++ b/src/main/java/com/btr/proxy/search/browser/firefox/WinFirefoxProfileSource.java
@@ -0,0 +1,71 @@
+package com.btr.proxy.search.browser.firefox;
+
+import java.io.File;
+import java.io.IOException;
+
+import com.btr.proxy.search.desktop.win.Win32ProxyUtils;
+import com.btr.proxy.util.Logger;
+import com.btr.proxy.util.Logger.LogLevel;
+
+/*****************************************************************************
+ * Finds the Firefox profile on Windows platforms.
+ * On Windows the profiles are located in the users appdata directory under:
+ * <p>
+ * <i>Mozilla\Firefox\Profiles\</i>
+ * </p>
+ * The location of the appdata folder is read from the windows registry.
+ *
+ * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
+ ****************************************************************************/
+
+class WinFirefoxProfileSource implements FirefoxProfileSource {
+
+ /*************************************************************************
+ * Constructor
+ ************************************************************************/
+
+ public WinFirefoxProfileSource() {
+ super();
+ }
+
+ /*************************************************************************
+ * Reads the current location of the app data folder from the registry.
+ * @return a path to the folder.
+ ************************************************************************/
+
+ private String getAppFolder() {
+ return new Win32ProxyUtils().readUserHomedir();
+ }
+
+ /*************************************************************************
+ * Get profile folder for the Windows Firefox profile
+ * @throws IOException on error.
+ ************************************************************************/
+
+ public File getProfileFolder() throws IOException {
+
+ File appDataDir = new File(getAppFolder());
+ File cfgDir = new File(appDataDir, "Mozilla"+File.separator+"Firefox"+File.separator+"Profiles");
+
+ if (!cfgDir.exists()) {
+ Logger.log(getClass(), LogLevel.DEBUG, "Firefox windows settings folder not found.");
+ return null;
+ }
+ File[] profiles = cfgDir.listFiles();
+ if (profiles == null || profiles.length == 0) {
+ Logger.log(getClass(), LogLevel.DEBUG, "Firefox windows settings folder not found.");
+ return null;
+ }
+ for (File p : profiles) {
+ if (p.getName().endsWith(".default")) {
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox windows settings folder is {0}.", p);
+ return p;
+ }
+ }
+
+ // Fall back -> take the first one found.
+ Logger.log(getClass(), LogLevel.TRACE, "Firefox windows settings folder is {0}.", profiles[0]);
+ return profiles[0];
+ }
+
+}