aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/main.py
blob: 32ab738e37f3a323ae859aa76b9b52a77df71a8a (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
156
157
158
159
160
161
162
163
from __future__ import print_function, absolute_import
import os
import signal
import sys
import netlib.version
from . import version, cmdline
from .proxy import process_proxy_options, ProxyServerError
from .proxy.server import DummyServer, ProxyServer


# This file is not included in coverage analysis or tests - anything that can be
# tested should live elsewhere.

def check_versions():
    """
    Having installed a wrong version of pyOpenSSL or netlib is unfortunately a
    very common source of error. Check before every start that both versions are
    somewhat okay.
    """
    # We don't introduce backward-incompatible changes in patch versions. Only
    # consider major and minor version.
    if netlib.version.IVERSION[:2] != version.IVERSION[:2]:
        print(
            "Warning: You are using mitmdump %s with netlib %s. "
            "Most likely, that won't work - please upgrade!" % (
                version.VERSION, netlib.version.VERSION
            ),
            file=sys.stderr
        )
    import OpenSSL
    import inspect
    v = tuple([int(x) for x in OpenSSL.__version__.split(".")][:2])
    if v < (0, 14):
        print(
            "You are using an outdated version of pyOpenSSL:"
            " mitmproxy requires pyOpenSSL 0.14 or greater.",
            file=sys.stderr
        )
        # Some users apparently have multiple versions of pyOpenSSL installed.
        # Report which one we got.
        pyopenssl_path = os.path.dirname(inspect.getfile(OpenSSL))
        print(
            "Your pyOpenSSL %s installation is located at %s" % (
                OpenSSL.__version__, pyopenssl_path
            ),
            file=sys.stderr
        )
        sys.exit(1)


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 DummyServer(options)
    else:
        try:
            return ProxyServer(options)
        except ProxyServerError, v:
            print(str(v), file=sys.stderr)
            sys.exit(1)


def mitmproxy(args=None):  # pragma: nocover
    from . import console

    check_versions()
    assert_utf8_env()

    parser = cmdline.mitmproxy()
    options = parser.parse_args(args)
    if options.quiet:
        options.verbose = 0

    proxy_config = process_proxy_options(parser, options)
    console_options = console.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.intercept = options.intercept
    console_options.limit = options.limit

    server = get_server(console_options.no_server, proxy_config)

    m = console.ConsoleMaster(server, console_options)
    try:
        m.run()
    except KeyboardInterrupt:
        pass


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

    check_versions()

    parser = cmdline.mitmdump()
    options = parser.parse_args(args)
    if options.quiet:
        options.verbose = 0
        options.flow_detail = 0

    proxy_config = process_proxy_options(parser, options)
    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 as e:
        print("mitmdump: %s" % e, file=sys.stderr)
        sys.exit(1)
    except KeyboardInterrupt:
        pass


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

    check_versions()
    parser = cmdline.mitmweb()

    options = parser.parse_args(args)
    if options.quiet:
        options.verbose = 0

    proxy_config = process_proxy_options(parser, options)
    web_options = web.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

    server = get_server(web_options.no_server, proxy_config)

    m = web.WebMaster(server, web_options)
    try:
        m.run()
    except KeyboardInterrupt:
        pass