codekingpro/portable-devtools
115k
1import logging2import shutil3import subprocess4import tempfile5 6from mitmproxy import command7from mitmproxy import ctx8from mitmproxy.log import ALERT9 10 11def find_executable_cmd(*search_paths) -> list[str] | None:12 for browser in search_paths:13 if shutil.which(browser):14 return [browser]15 16 return None17 18 19def find_flatpak_cmd(*search_paths) -> list[str] | None:20 if shutil.which("flatpak"):21 for browser in search_paths:22 if (23 subprocess.run(24 ["flatpak", "info", browser],25 stdout=subprocess.DEVNULL,26 stderr=subprocess.DEVNULL,27 ).returncode28 == 029 ):30 return ["flatpak", "run", "-p", browser]31 32 return None33 34 35class Browser:36 browser: list[subprocess.Popen] = []37 tdir: list[tempfile.TemporaryDirectory] = []38 39 @command.command("browser.start")40 def start(self, browser: str = "chrome") -> None:41 if len(self.browser) > 0:42 logging.log(ALERT, "Starting additional browser")43 44 if browser in ("chrome", "chromium"):45 self.launch_chrome()46 elif browser == "firefox":47 self.launch_firefox()48 else:49 logging.log(ALERT, "Invalid browser name.")50 51 def launch_chrome(self) -> None:52 """53 Start an isolated instance of Chrome that points to the currently54 running proxy.55 """56 cmd = find_executable_cmd(57 "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",58 # https://stackoverflow.com/questions/40674914/google-chrome-path-in-windows-1059 r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",60 r"C:\Program Files (x86)\Google\Application\chrome.exe",61 # Linux binary names from Python's webbrowser module.62 "google-chrome",63 "google-chrome-stable",64 "chrome",65 "chromium",66 "chromium-browser",67 "google-chrome-unstable",68 ) or find_flatpak_cmd(69 "com.google.Chrome",70 "org.chromium.Chromium",71 "com.github.Eloston.UngoogledChromium",72 "com.google.ChromeDev",73 )74 75 if not cmd:76 logging.log(77 ALERT, "Your platform is not supported yet - please submit a patch."78 )79 return80 81 tdir = tempfile.TemporaryDirectory()82 self.tdir.append(tdir)83 self.browser.append(84 subprocess.Popen(85 [86 *cmd,87 "--user-data-dir=%s" % str(tdir.name),88 "--proxy-server={}:{}".format(89 ctx.options.listen_host or "127.0.0.1",90 ctx.options.listen_port or "8080",91 ),92 "--disable-fre",93 "--no-default-browser-check",94 "--no-first-run",95 "--disable-extensions",96 "about:blank",97 ],98 stdout=subprocess.DEVNULL,99 stderr=subprocess.DEVNULL,100 )101 )102 103 def launch_firefox(self) -> None:104 """105 Start an isolated instance of Firefox that points to the currently106 running proxy.107 """108 cmd = find_executable_cmd(109 "/Applications/Firefox.app/Contents/MacOS/firefox",110 r"C:\Program Files\Mozilla Firefox\firefox.exe",111 "firefox",112 "mozilla-firefox",113 "mozilla",114 ) or find_flatpak_cmd("org.mozilla.firefox")115 116 if not cmd:117 logging.log(118 ALERT, "Your platform is not supported yet - please submit a patch."119 )120 return121 122 host = ctx.options.listen_host or "127.0.0.1"123 port = ctx.options.listen_port or 8080124 prefs = [125 'user_pref("datareporting.policy.firstRunURL", "");',126 'user_pref("network.proxy.type", 1);',127 'user_pref("network.proxy.share_proxy_settings", true);',128 'user_pref("datareporting.healthreport.uploadEnabled", false);',129 'user_pref("app.normandy.enabled", false);',130 'user_pref("app.update.auto", false);',131 'user_pref("app.update.enabled", false);',132 'user_pref("app.update.autoInstallEnabled", false);',133 'user_pref("app.shield.optoutstudies.enabled", false);'134 'user_pref("extensions.blocklist.enabled", false);',135 'user_pref("browser.safebrowsing.downloads.remote.enabled", false);',136 'user_pref("browser.region.network.url", "");',137 'user_pref("browser.region.update.enabled", false);',138 'user_pref("browser.region.local-geocoding", false);',139 'user_pref("extensions.pocket.enabled", false);',140 'user_pref("network.captive-portal-service.enabled", false);',141 'user_pref("network.connectivity-service.enabled", false);',142 'user_pref("toolkit.telemetry.server", "");',143 'user_pref("dom.push.serverURL", "");',144 'user_pref("services.settings.enabled", false);',145 'user_pref("browser.newtab.preload", false);',146 'user_pref("browser.safebrowsing.provider.google4.updateURL", "");',147 'user_pref("browser.safebrowsing.provider.mozilla.updateURL", "");',148 'user_pref("browser.newtabpage.activity-stream.feeds.topsites", false);',149 'user_pref("browser.newtabpage.activity-stream.default.sites", "");',150 'user_pref("browser.newtabpage.activity-stream.showSponsoredTopSites", false);',151 'user_pref("browser.bookmarks.restore_default_bookmarks", false);',152 'user_pref("browser.bookmarks.file", "");',153 ]154 for service in ("http", "ssl"):155 prefs += [156 f'user_pref("network.proxy.{service}", "{host}");',157 f'user_pref("network.proxy.{service}_port", {port});',158 ]159 160 tdir = tempfile.TemporaryDirectory()161 162 with open(tdir.name + "/prefs.js", "w") as file:163 file.writelines(prefs)164 165 self.tdir.append(tdir)166 self.browser.append(167 subprocess.Popen(168 [169 *cmd,170 "--profile",171 str(tdir.name),172 "--new-window",173 "about:blank",174 ],175 stdout=subprocess.DEVNULL,176 stderr=subprocess.DEVNULL,177 )178 )179 180 def done(self):181 for browser in self.browser:182 browser.kill()183 for tdir in self.tdir:184 tdir.cleanup()185 self.browser = []186 self.tdir = []187 