# SPDX-License-Identifier: GPL-3.0-or-later # Code for starting mitmproxy # # This file is part of Hydrilla # # Copyright (C) 2021, 2022 Wojtek Kosior # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # # I, Wojtek Kosior, thereby promise not to sue for violation of this # file's license. Although I request that you do not make use of this # code in a proprietary program, I am not going to enforce this in # court. import sys import os import subprocess as sp import typing as t from pathlib import Path from shutil import copytree # The following import requires at least Python 3.8. There is no point adding # a workaround for Python 3.7 because mitmproxy itself (which we're loading # here) relies on Python 3.9+. This does not affect the Hydrilla server and # builder which continue to work under Python 3.7. from importlib.metadata import distribution import click from .. import _version from ..translations import smart_gettext as _ xdg_state_home = os.environ.get('XDG_STATE_HOME', '.local/state') default_dir = str(Path.home() / xdg_state_home / 'haketilo') old_default_dir_path = Path.home() / '.haketilo/' addon_script_text = ''' from hydrilla.proxy.addon import HaketiloAddon addons = [HaketiloAddon()] ''' @click.command(help=_('cli_help.haketilo')) @click.option('-l', '--listen-host', default='127.0.0.1', type=click.STRING, help=_('cli_opt.haketilo.listen_host')) @click.option('-p', '--port', default=8080, type=click.IntRange(1, 65535), help=_('cli_opt.haketilo.port')) @click.option('-L/-l', '--launch-browser/--no-launch-browser', default=True, help=_('cli_opt.haketilo.launch_browser')) @click.option('-d', '--directory', default=default_dir, type=click.Path(file_okay=False), help=_('cli_opt.haketilo.dir_defaults_to_{}').format(default_dir)) @click.version_option(version=_version.version, prog_name='Haketilo proxy', message=_('%(prog)s_%(version)s_license'), help=_('cli_opt.haketilo.version')) def launch(listen_host: str, port: int, launch_browser: bool, directory: str) \ -> t.NoReturn: directory_path = Path(os.path.expanduser(directory)).resolve() # Before we started using XDG_STATE_HOME, we were storing files by default # under ~/.haketilo. Let's make sync state from there to our new default # state directory if directory == default_dir and \ old_default_dir_path.exists() and \ not directory_path.exists(): directory_path.parent.mkdir(parents=True, exist_ok=True) copytree(old_default_dir_path, directory_path, symlinks=True) directory_path.mkdir(parents=True, exist_ok=True) script_path = directory_path / 'addon.py' script_path.write_text(addon_script_text) launch_browser_str = 'true' if launch_browser else 'false' sys.argv = [ 'mitmdump', '--listen-host', listen_host, '-p', str(port), '--set', f'confdir={directory_path / "mitmproxy"}', '--set', 'upstream_cert=false', '--set', 'connection_strategy=lazy', '--set', f'haketilo_dir={directory_path}', '--set', f'haketilo_listen_host={listen_host}', '--set', f'haketilo_listen_port={port}', '--set', f'haketilo_launch_browser={launch_browser_str}', '--scripts', str(script_path) ] for entry_point in distribution('mitmproxy').entry_points: if entry_point.group == 'console_scripts' and \ entry_point.name == 'mitmdump': sys.exit(entry_point.load()()) sys.exit(1)