Ejemplo n.º 1
0
def pretty_print_body(fmt, body):
    try:
        if fmt.lower() == 'json':
            d = json.loads(body.strip())
            s = json.dumps(d, indent=4, sort_keys=True)
            print pygments.highlight(s, JsonLexer(), TerminalFormatter())
        elif fmt.lower() == 'form':
            qs = repeatable_parse_qs(body)
            for k, v in qs.all_pairs():
                s = Colors.GREEN
                s += '%s: ' % urllib.unquote(k)
                s += Colors.ENDC
                s += urllib.unquote(v)
                print s
        elif fmt.lower() == 'text':
            print body
        elif fmt.lower() == 'xml':
            import xml.dom.minidom
            xml = xml.dom.minidom.parseString(body)
            print pygments.highlight(xml.toprettyxml(), XmlLexer(),
                                     TerminalFormatter())
        else:
            raise PappyException('"%s" is not a valid format' % fmt)
    except PappyException as e:
        raise e
    except:
        raise PappyException('Body could not be parsed as "%s"' % fmt)
Ejemplo n.º 2
0
    def load(self):
        if self.filename:
            match = re.findall('.*int_(.*).py$', self.filename)
            if len(match) > 0:
                self.file_name = match[0]
            else:
                self.file_name = self.filename
            st = os.stat(self.filename)
            if (st.st_mode & stat.S_IWOTH):
                raise PappyException("Refusing to load world-writable macro: %s" % self.filename)
            module_name = os.path.basename(os.path.splitext(self.filename)[0])
            self.source = imp.load_source('%s'%module_name, self.filename)
            self.name = self.source.MACRO_NAME
            if self.name == '':
                raise PappyException('Macro in %s cannot have a blank name' % self.filename)
            if hasattr(self.source, 'SHORT_NAME'):
                self.short_name = self.source.SHORT_NAME
            else:
                self.short_name = None

            if hasattr(self.source, 'mangle_request') and \
               hasattr(self.source, 'async_mangle_request'):
                raise PappyException('Intercepting macro in %s cannot define both mangle_request and async_mangle_request' % self.filename)
            if hasattr(self.source, 'mangle_response') and \
               hasattr(self.source, 'async_mangle_response'):
                raise PappyException('Intercepting macro in %s cannot define both mangle_response and async_mangle_response' % self.filename)
            if hasattr(self.source, 'mangle_ws') and \
               hasattr(self.source, 'async_mangle_ws'):
                raise PappyException('Intercepting macro in %s cannot define both mangle_ws and async_mangle_ws' % self.filename)
        else:
            self.source = None

        # Update what we can do
        if self.source and hasattr(self.source, 'mangle_request'):
           self.intercept_requests = True
           self.async_req = False
        elif self.source and hasattr(self.source, 'async_mangle_request'):
           self.intercept_requests = True
           self.async_req = True
        else:
           self.intercept_requests = True

        if self.source and hasattr(self.source, 'mangle_response'):
            self.intercept_responses = True
            self.async_rsp = False
        elif self.source and hasattr(self.source, 'async_mangle_response'):
            self.intercept_responses = True
            self.async_rsp = True
        else:
            self.intercept_responses = False

        if self.source and hasattr(self.source, 'mangle_ws'):
            self.intercept_ws = True
            self.async_ws = False
        elif self.source and hasattr(self.source, 'async_mangle_ws'):
            self.intercept_ws = True
            self.async_ws = True
        else:
            self.intercept_ws = False
Ejemplo n.º 3
0
 def do_stop_int_macro(self, line):
     global int_macro_dict
     global loaded_int_macros
     if not line:
         raise PappyException(
             'You must give an intercepting macro to run. You can give its short name, or the name in the filename.'
         )
     if line not in int_macro_dict:
         raise PappyException('%s not a loaded intercepting macro' % line)
     macro = int_macro_dict[line]
     pappyproxy.proxy.remove_intercepting_macro(macro.name)
     print '"%s" stopped' % macro.name
Ejemplo n.º 4
0
 def get(name):
     if name not in BuiltinFilters._filters:
         raise PappyException('%s not a bult in filter' % name)
     if name in BuiltinFilters._filters:
         filters = [
             pappyproxy.context.Filter(f)
             for f in BuiltinFilters._filters[name][0]
         ]
         for f in filters:
             yield f.generate()
         defer.returnValue(filters)
     raise PappyException('"%s" is not a built-in filter' % name)
Ejemplo n.º 5
0
 def do_run_macro(self, line):
     global macro_dict
     global loaded_macros
     args = shlex.split(line)
     if not args:
         raise PappyException(
             'You must give a macro to run. You can give its short name, or the name in the filename.'
         )
     mname = args[0]
     if mname not in macro_dict:
         raise PappyException('%s not a loaded macro' % mname)
     macro = macro_dict[mname]
     macro.execute(args[1:])
Ejemplo n.º 6
0
def stop_int_macro(line):
    """
    Stop a running intercepting macro
    Usage: stop_int_macro <macro name or macro short name>
    """
    global int_macro_dict
    global loaded_int_macros
    if not line:
        raise PappyException('You must give an intercepting macro to run. You can give its short name, or the name in the filename.')
    if line not in int_macro_dict:
        raise PappyException('%s not a loaded intercepting macro' % line)
    macro = int_macro_dict[line]
    remove_intercepting_macro(macro.name)
    print '"%s" stopped' % macro.name
Ejemplo n.º 7
0
def load_certs_from_dir(cert_dir):
    try:
        with open(cert_dir + '/' + config.SSL_CA_FILE, 'rt') as f:
            ca_raw = f.read()
    except IOError:
        raise PappyException("Could not load CA cert!")

    try:
        with open(cert_dir + '/' + config.SSL_PKEY_FILE, 'rt') as f:
            ca_key_raw = f.read()
    except IOError:
        raise PappyException("Could not load CA private key!")

    return (ca_raw, ca_key_raw)
Ejemplo n.º 8
0
def save_filter_set(line):
    if line == '':
        raise PappyException("Must give name to save filters as")
    strs = yield _save_filters_to(line)
    print 'Filters saved to %s:' % line
    for s in strs:
        print '  %s' % s
Ejemplo n.º 9
0
def export(line):
    """
    Write the full request/response of a request/response to a file.
    Usage: export [req|rsp] <reqid(s)>
    """
    args = shlex.split(line)
    if len(args) < 2:
        print 'Requires req/rsp and and request id(s)'
        defer.returnValue(None)

    if args[0] not in ('req', 'rsp'):
        raise PappyException('Request or response not specified')

    reqs = yield load_reqlist(args[1])
    for req in reqs:
        try:
            if args[0] == 'req':
                fname = 'req_%s.txt' % req.reqid
                with open(fname, 'w') as f:
                    f.write(req.full_request)
                print 'Full request written to %s' % fname
            elif args[0] == 'rsp':
                fname = 'rsp_%s.txt' % req.reqid
                with open(fname, 'w') as f:
                    f.write(req.full_response)
                print 'Full response written to %s' % fname
        except PappyException as e:
            print 'Unable to export %s: %s' % (req.reqid, e)
Ejemplo n.º 10
0
def load_certs_from_dir(cert_dir):
    try:
        with open(cert_dir + '/' + config.SSL_CA_FILE, 'rt') as f:
            ca_raw = f.read()
    except IOError:
        raise PappyException(
            "Could not load CA cert! Generate certs using the `gencerts` command then add the .crt file to your browser."
        )

    try:
        with open(cert_dir + '/' + config.SSL_PKEY_FILE, 'rt') as f:
            ca_key_raw = f.read()
    except IOError:
        raise PappyException("Could not load CA private key!")

    return (ca_raw, ca_key_raw)
Ejemplo n.º 11
0
 def respond_failure(self, message):
     """
     Closes the connection to the remote server and returns an error message.
     The request object will have a response of None.
     """
     #self.transport.loseConnection()
     self.data_defer.errback(PappyException(message))
Ejemplo n.º 12
0
def untag(line):
    """
    Remove a tag from requests
    Usage: untag <tag> <request ids>
    You can provide as many request ids as you want and the tag will
    be removed from all of them. If no ids are given, the tag will 
    be removed from all in-context requests.
    """
    args = shlex.split(line)
    if len(args) == 0:
        raise PappyException("Tag and request ids are required")
    tag = args[0]

    ids = []
    if len(args) > 1:
        reqids = yield load_reqlist(args[1], False, ids_only=True)
        print 'Removing tag %s from %s' % (tag, ', '.join(reqids))
    else:
        print "Removing tag %s from all in-context requests" % tag
        reqids = yield async_main_context_ids()

    for reqid in reqids:
        req = yield Request.load_request(reqid)
        if tag in req.tags:
            req.tags.discard(tag)
            if req.saved:
                yield req.async_save()
    if ids:
        print 'Tag %s removed from %s' % (tag, ', '.join(ids))
Ejemplo n.º 13
0
def tag(line):
    """
    Add a tag to requests.
    Usage: tag <tag> [request ids]
    You can tag as many requests as you want at the same time. If no
    ids are given, the tag will be applied to all in-context requests.
    """
    args = shlex.split(line)
    if len(args) == 0:
        raise PappyException('Tag name is required')
    tag = args[0]

    if len(args) > 1:
        reqids = yield load_reqlist(args[1], False, ids_only=True)
        print 'Tagging %s with %s' % (', '.join(reqids), tag)
    else:
        print "Tagging all in-context requests with %s" % tag
        reqids = yield async_main_context_ids()

    for reqid in reqids:
        req = yield Request.load_request(reqid)
        if tag not in req.tags:
            req.tags.add(tag)
            if req.saved:
                yield req.async_save()
        else:
            print 'Request %s already has tag %s' % (req.reqid, tag)
Ejemplo n.º 14
0
def check_reqid(reqid):
    # Used for the repeater command. Must not be async
    try:
        yield pappyproxy.http.Request.load_request(reqid)
    except:
        raise PappyException('"%s" is not a valid request id' % reqid)
    defer.returnValue(None)
Ejemplo n.º 15
0
def load_certs_from_dir(cert_dir):
    from pappyproxy.pappy import session
    try:
        with open(cert_dir + '/' + session.config.ssl_ca_file, 'rt') as f:
            ca_raw = f.read()
    except IOError:
        raise PappyException(
            "Could not load CA cert! Generate certs using the `gencerts` command then add the .crt file to your browser."
        )

    try:
        with open(cert_dir + '/' + session.config.ssl_pkey_file, 'rt') as f:
            ca_key_raw = f.read()
    except IOError:
        raise PappyException("Could not load CA private key!")

    return (ca_raw, ca_key_raw)
Ejemplo n.º 16
0
    def do_builtin_filter(self, line):
        if not line:
            raise PappyException("Filter name required")

        filters_to_add = pappyproxy.context.BuiltinFilters.get(line)
        for f in filters_to_add:
            print f.filter_string
            pappyproxy.context.add_filter(f)
Ejemplo n.º 17
0
def load_macros_cmd(line):
    """
    Load macros from a directory. By default loads macros in the current directory.
    Usage: load_macros [dir]
    """
    global macro_dict
    global int_macro_dict
    global loaded_macros
    global loaded_int_macros

    if line:
        load_dir = line
    else:
        load_dir = '.'
    (to_load, int_to_load) = load_macros(load_dir)
    if not to_load and not int_to_load:
        raise PappyException('No macros to load.')

    macro_dict = {}
    loaded_macros = []
    int_macro_dict = {}
    loaded_int_macros = []

    for macro in to_load:
        if macro.name in macro_dict:
            print 'Name conflict in %s! "%s" already in use, not loading.' % (
                macro.filename, macro.name)
        elif macro.short_name and macro.short_name in macro_dict:
            print 'Name conflict in %s! "%s" already in use, not loading.' % (
                macro.filename, macro.short_name)
        elif macro.file_name in macro_dict:
            print 'Name conflict in %s! "%s" already in use, not loading.' % (
                macro.filename, macro.file_name)
        else:
            macro_dict[macro.name] = macro
            macro_dict[macro.file_name] = macro
            if macro.short_name:
                macro_dict[macro.short_name] = macro
            loaded_macros.append(macro)
            print 'Loaded "%s"' % macro

    for macro in int_to_load:
        if macro.name in int_macro_dict:
            print 'Name conflict in %s! "%s" already in use, not loading.' % (
                macro.filename, macro.name)
        elif macro.short_name and macro.short_name in int_macro_dict:
            print 'Name conflict in %s! "%s" already in use, not loading.' % (
                macro.filename, macro.short_name)
        elif macro.file_name in int_macro_dict:
            print 'Name conflict in %s! "%s" already in use, not loading.' % (
                macro.filename, macro.file_name)
        else:
            int_macro_dict[macro.name] = macro
            int_macro_dict[macro.file_name] = macro
            if macro.short_name:
                int_macro_dict[macro.short_name] = macro
            loaded_int_macros.append(macro)
            print 'Loaded "%s"' % macro
Ejemplo n.º 18
0
def builtin_filter(line):
    if not line:
        raise PappyException("Filter name required")

    filters_to_add = yield BuiltinFilters.get(line)
    for f in filters_to_add:
        print f.filter_string
        yield pappyproxy.pappy.main_context.add_filter(f)
    defer.returnValue(None)
Ejemplo n.º 19
0
def asciihex_decode_helper(s):
    ret = []
    try:
        for a, b in zip(s[0::2], s[1::2]):
            c = a + b
            ret.append(chr(int(c, 16)))
        return ''.join(ret)
    except Exception as e:
        raise PappyException(e)
Ejemplo n.º 20
0
 def do_generate_int_macro(self, line):
     if line == '':
         raise PappyException('Macro name is required')
     args = shlex.split(line)
     name = args[0]
     script_str = gen_imacro()
     fname = 'int_%s.py' % name
     with open(fname, 'wc') as f:
         f.write(script_str)
     print 'Wrote script to %s' % fname
Ejemplo n.º 21
0
def load_filter_set(line):
    if line == '':
        raise PappyException("Must give name to save filters as")
    strs = yield get_saved_context(line, pappyproxy.http.dbpool)
    yield _save_filters_to('_')
    pappyproxy.pappy.main_context.set_filters([])
    for s in strs:
        yield pappyproxy.pappy.main_context.add_filter_string(s)
    print 'Set the context to:'
    for s in strs:
        print '  %s' % s
Ejemplo n.º 22
0
 def load(self):
     if self.filename:
         match = re.findall('.*macro_(.*).py$', self.filename)
         self.file_name = match[0]
         st = os.stat(self.filename)
         if (st.st_mode & stat.S_IWOTH):
             raise PappyException("Refusing to load world-writable macro: %s" % self.filename)
         module_name = os.path.basename(os.path.splitext(self.filename)[0])
         self.source = imp.load_source('%s'%module_name, self.filename)
         if not hasattr(self.source, 'MACRO_NAME'):
             raise PappyException('Macro in %s does not define MACRO_NAME' % self.filename)
         self.name = self.source.MACRO_NAME
         if self.name == '':
             raise PappyException('Macro in %s cannot have a blank name' % self.filename)
         if hasattr(self.source, 'SHORT_NAME'):
             self.short_name = self.source.SHORT_NAME
         else:
             self.short_name = None
     else:
         self.source = None
Ejemplo n.º 23
0
def base64_decode_helper(s):
    try:
        return base64.b64decode(s)
    except TypeError:
        for i in range(1, 5):
            try:
                s_padded = base64.b64decode(s + '=' * i)
                return s_padded
            except:
                pass
        raise PappyException("Unable to base64 decode string")
Ejemplo n.º 24
0
    def do_load_macros(self, line):
        global macro_dict
        global int_macro_dict
        global loaded_macros
        global loaded_int_macros

        if line:
            load_dir = line
        else:
            load_dir = '.'
        (to_load, int_to_load) = load_macros(load_dir)
        if not to_load and not int_to_load:
            raise PappyException('No macros to load.')

        macro_dict = {}
        loaded_macros = []
        int_macro_dict = {}
        loaded_int_macros = []

        for macro in to_load:
            if macro.name in macro_dict:
                print 'Name conflict in %s! "%s" already in use, not loading.' % (
                    macro.filename, macro.name)
            elif macro.short_name and macro.short_name in macro_dict:
                print 'Name conflict in %s! "%s" already in use, not loading.' % (
                    macro.filename, macro.short_name)
            elif macro.file_name in macro_dict:
                print 'Name conflict in %s! "%s" already in use, not loading.' % (
                    macro.filename, macro.file_name)
            else:
                macro_dict[macro.name] = macro
                macro_dict[macro.file_name] = macro
                if macro.short_name:
                    macro_dict[macro.short_name] = macro
                loaded_macros.append(macro)
                print 'Loaded "%s"' % macro

        for macro in int_to_load:
            if macro.name in int_macro_dict:
                print 'Name conflict in %s! "%s" already in use, not loading.' % (
                    macro.filename, macro.name)
            elif macro.short_name and macro.short_name in int_macro_dict:
                print 'Name conflict in %s! "%s" already in use, not loading.' % (
                    macro.filename, macro.short_name)
            elif macro.file_name in int_macro_dict:
                print 'Name conflict in %s! "%s" already in use, not loading.' % (
                    macro.filename, macro.file_name)
            else:
                int_macro_dict[macro.name] = macro
                int_macro_dict[macro.file_name] = macro
                if macro.short_name:
                    int_macro_dict[macro.short_name] = macro
                loaded_int_macros.append(macro)
                print 'Loaded "%s"' % macro
Ejemplo n.º 25
0
 def do_generate_macro(self, line):
     if line == '':
         raise PappyException('Macro name is required')
     args = shlex.split(line)
     name = args[0]
     reqs = yield load_reqlist(args[1])
     script_str = macro_from_requests(reqs)
     fname = 'macro_%s.py' % name
     with open(fname, 'wc') as f:
         f.write(script_str)
     print 'Wrote script to %s' % fname
Ejemplo n.º 26
0
def run_int_macro(line):
    """
    Activate an intercepting macro
    Usage: run_int_macro <macro name or macro short name>
    Macro can be stopped with stop_int_macro
    """
    global int_macro_dict
    global loaded_int_macros
    args = shlex.split(line)
    if len(args) == 0:
        raise PappyException('You must give an intercepting macro to run. You can give its short name, or the name in the filename.')
    if args[0] not in int_macro_dict:
        raise PappyException('%s not a loaded intercepting macro' % line)
    macro = int_macro_dict[args[0]]
    try:
        macro.init(args[1:])
        add_intercepting_macro(macro.name, macro)
        print '"%s" started' % macro.name
    except Exception as e:
        print 'Error initializing macro:'
        raise e
Ejemplo n.º 27
0
def filtercmd(line):
    """
    Apply a filter to the current context
    Usage: filter <filter string>
    See README.md for information on filter strings
    """
    if not line:
        raise PappyException("Filter string required")

    filter_to_add = pappyproxy.context.Filter(line)
    yield filter_to_add.generate()
    pappyproxy.pappy.main_context.add_filter(filter_to_add)
Ejemplo n.º 28
0
def pretty_print_request(line):
    """
    Print the body of the request pretty printed.
    Usage: pretty_print_request <format> <reqid(s)>
    """
    args = shlex.split(line)
    if len(args) < 2:
        raise PappyException("Usage: pretty_print_request <format> <reqid(s)>")
    reqids = args[1]

    reqs = yield load_reqlist(reqids)
    for req in reqs:
        pretty_print_body(args[0], req.body)
Ejemplo n.º 29
0
def generate_int_macro(line):
    """
    Generate an intercepting macro script
    Usage: generate_int_macro <name>
    """
    if line == '':
        raise PappyException('Macro name is required')
    args = shlex.split(line)
    name = args[0]
    script_str = gen_imacro()
    fname = 'int_%s.py' % name
    with open(fname, 'wc') as f:
        f.write(script_str)
    print 'Wrote script to %s' % fname
Ejemplo n.º 30
0
def pretty_print_response(line):
    """
    Print the body of the request pretty printed.
    Usage: pretty_print_request <format> <reqid(s)>
    """
    args = shlex.split(line)
    if len(args) < 2:
        raise PappyException("Usage: pretty_print_request <format> <reqid(s)>")
    reqids = args[1]

    reqs = yield load_reqlist(reqids)
    for req in reqs:
        if req.response:
            pretty_print_body(args[0], req.response.body)
        else:
            print 'No response associated with request %s' % req.reqid