#!/usr/bin/env python2 import os.path as path import time from distutils.util import strtobool class Module: def __init__(self, incoming=False, verbose=False, options=None): # extract the file name from __file__. __file__ is proxymodules/name.py self.name = path.splitext(path.basename(__file__))[0] self.description = 'Change HTTP responses of a certain size to 404.' self.incoming = incoming # incoming means module is on -im chain self.size = 2392 # if a response has this value as content-length, it will become a 404 self.verbose = False self.custom = False self.rewriteall = False # will we block the first occurence? self.firstfound = False # have we found the first occurence yet? self.resetinterval = None # if we haven't found a fitting response in this many seconds, reset the state and set first to False again self.timer = time.time() if options is not None: if 'size' in options.keys(): try: self.size = int(options['size']) except ValueError: pass # use the default if you can't parse the parameter if 'verbose' in options.keys(): self.verbose = bool(strtobool(options['verbose'])) if 'custom' in options.keys(): try: with open(options['custom'], 'rb') as handle: self.custom = handle.read() except Exception: print('Can\'t open custom error file, not using it.') self.custom = False if 'rewriteall' in options.keys(): self.rewriteall = bool(strtobool(options['rewriteall'])) if 'reset' in options.keys(): try: self.resetinterval = float(options['reset']) except ValueError: pass # use the default if you can't parse the parameter def execute(self, data): contentlength = b'content-length: ' + bytes(str(self.size), 'ascii') if data.startswith(b'HTTP/1.1 200 OK') and contentlength in data.lower(): if self.resetinterval is not None: t = time.time() if t - self.timer >= self.resetinterval: if self.verbose: print('Timer elapsed') self.firstfound = False self.timer = t if self.rewriteall is False and self.firstfound is False: # we have seen this response size for the first time and are not blocking the first one self.firstfound = True if self.verbose: print('Letting this response through') return data if self.custom is not False: data = self.custom if self.verbose: print('Replaced response with custom response') else: data = data.replace(b'200 OK', b'404 Not Found', 1) if self.verbose: print('Edited return code') return data def help(self): h = '\tsize: if a response has this value as content-length, it will become a 404\n' h += ('\tverbose: print a message if a string is replaced\n' '\tcustom: path to a file containing a custom response, will replace the received response\n' '\trewriteall: if set, it will rewrite all responses. Default is to let the first on through' '\treset: number of seconds after which we will reset the state and will let the next response through.') return h if __name__ == '__main__': print('This module is not supposed to be executed alone!')