aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/main.py
blob: 316db91a83e1c3bad65b4ceb4ceed4b98912a010 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
from __future__ import absolute_import, print_function, division

import os
import signal
import sys

from six.moves import _thread  # PY3: We only need _thread.error, which is an alias of RuntimeError in 3.3+

from mitmproxy import cmdline
from mitmproxy import exceptions
from mitmproxy.proxy import config
from mitmproxy.proxy import server
from netlib import version_check
from netlib import debug


def assert_utf8_env():
    spec = ""
    for i in ["LANG", "LC_CTYPE", "LC_ALL"]:
        spec += os.environ.get(i, "").lower()
    if "utf" not in spec:
        print(
            "Error: mitmproxy requires a UTF console environment.",
            file=sys.stderr
        )
        print(
            "Set your LANG enviroment variable to something like en_US.UTF-8",
            file=sys.stderr
        )
        sys.exit(1)


def get_server(dummy_server, options):
    if dummy_server:
        return server.DummyServer(options)
    else:
        try:
            return server.ProxyServer(options)
        except exceptions.ServerException as v:
            print(str(v), file=sys.stderr)
            sys.exit(1)


def process_options(parser, options):
    if options.sysinfo:
        print(debug.sysinfo())
        sys.exit(0)
    if options.quiet:
        options.verbose = 0
    debug.register_info_dumpers()
    return config.process_proxy_options(parser, options)


def mitmproxy(args=None):  # pragma: no cover
    if os.name == "nt":
        print("Error: mitmproxy's console interface is not supported on Windows. "
              "You can run mitmdump or mitmweb instead.", file=sys.stderr)
        sys.exit(1)
    from . import console

    version_check.check_pyopenssl_version()
    assert_utf8_env()

    parser = cmdline.mitmproxy()
    options = parser.parse_args(args)
    proxy_config = process_options(parser, options)

    console_options = console.master.Options(**cmdline.get_common_options(options))
    console_options.palette = options.palette
    console_options.palette_transparent = options.palette_transparent
    console_options.eventlog = options.eventlog
    console_options.follow = options.follow
    console_options.intercept = options.intercept
    console_options.limit = options.limit
    console_options.no_mouse = options.no_mouse

    server = get_server(console_options.no_server, proxy_config)

    try:
        m = console.master.ConsoleMaster(server, console_options)
    except exceptions.OptionsError as e:
        print("mitmproxy: %s" % e, file=sys.stderr)
        sys.exit(1)
    try:
        m.run()
    except (KeyboardInterrupt, _thread.error):
        pass


def mitmdump(args=None):  # pragma: no cover
    from . import dump

    version_check.check_pyopenssl_version()

    parser = cmdline.mitmdump()
    options = parser.parse_args(args)
    proxy_config = process_options(parser, options)
    if options.quiet:
        options.flow_detail = 0

    dump_options = dump.Options(**cmdline.get_common_options(options))
    dump_options.flow_detail = options.flow_detail
    dump_options.keepserving = options.keepserving
    dump_options.filtstr = " ".join(options.args) if options.args else None

    server = get_server(dump_options.no_server, proxy_config)

    try:
        master = dump.DumpMaster(server, dump_options)

        def cleankill(*args, **kwargs):
            master.shutdown()

        signal.signal(signal.SIGTERM, cleankill)
        master.run()
    except (dump.DumpError, exceptions.OptionsError) as e:
        print("mitmdump: %s" % e, file=sys.stderr)
        sys.exit(1)
    except (KeyboardInterrupt, _thread.error):
        pass
    if master.has_errored:
        print("mitmdump: errors occurred during run", file=sys.stderr)
        sys.exit(1)


def mitmweb(args=None):  # pragma: no cover
    from . import web

    version_check.check_pyopenssl_version()

    parser = cmdline.mitmweb()

    options = parser.parse_args(args)
    proxy_config = process_options(parser, options)

    web_options = web.master.Options(**cmdline.get_common_options(options))
    web_options.intercept = options.intercept
    web_options.wdebug = options.wdebug
    web_options.wiface = options.wiface
    web_options.wport = options.wport
    web_options.wsingleuser = options.wsingleuser
    web_options.whtpasswd = options.whtpasswd
    web_options.process_web_options(parser)

    server = get_server(web_options.no_server, proxy_config)

    try:
        m = web.master.WebMaster(server, web_options)
    except exceptions.OptionsError as e:
        print("mitmweb: %s" % e, file=sys.stderr)
        sys.exit(1)
    try:
        m.run()
    except (KeyboardInterrupt, _thread.error):
        pass