def __init__(self, **server_settings): self.bd = server_settings.get('block_device', '') self.netboot_directory = server_settings.get('netboot_directory', '.') self.write = server_settings.get('write', False) # write? self.cow = server_settings.get('cow', True) # COW is the safe default self.in_mem = server_settings.get('in_mem', False) self.copy_to_ram = server_settings.get('copy_to_ram', False) self.ip = server_settings.get('ip', '0.0.0.0') self.port = int(server_settings.get('port', 10809)) self.mode_debug = server_settings.get('mode_debug', False) # debug mode self.mode_verbose = server_settings.get('mode_verbose', False) # debug mode self.logger = server_settings.get('logger', None) # setup logger if self.logger == None: self.logger = logging.getLogger('NBD') handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s %(name)s [%(levelname)s] %(message)s') handler.setFormatter(formatter) self.logger.addHandler(handler) if self.mode_debug: self.logger.setLevel(logging.DEBUG) elif self.mode_verbose: self.logger.setLevel(logging.INFO) else: self.logger.setLevel(logging.WARN) self.logger.debug('NOTICE: NBD server started in debug mode. NBD server is using the following:') self.logger.info('Server IP: {0}'.format(self.ip)) self.logger.info('Server Port: {0}'.format(self.port)) self.logger.info('Block Device: {0}'.format(self.bd)) self.logger.info('Block Device Writes: {0}'.format(self.write)) self.logger.info('Block Write Method: {0} ({1})'.format("Copy-On-Write" if self.cow else 'File', 'Memory' if self.in_mem else 'Disk')) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind((self.ip, self.port)) self.sock.listen(4) # if we have COW on, we write elsewhere so we don't need write ability self.openbd = open(helpers.normalize_path(self.netboot_directory, self.bd), 'r+b' if self.write and not self.cow else 'rb') # go to EOF self.openbd.seek(0, 2) # we need this when clients mount us self.bdsize = self.openbd.tell() # go back to start self.openbd.seek(0) if self.copy_to_ram and self.cow: self.logger.info('Starting copying {0} to RAM'.format(self.bd)) self.openbd = io.BytesIO(self.openbd.read()) self.logger.info('Finished copying {0} to RAM'.format(self.bd))
def handle_request(self, connection, addr): '''This method handles HTTP request.''' request = connection.recv(1024) self.logger.debug( 'Received message from {addr}'.format(addr=repr(addr))) self.logger.debug('<--BEGIN MESSAGE-->') self.logger.debug('{0}'.format(repr(request))) self.logger.debug('<--END MESSAGE-->') method, target, version = request.decode('ascii').split( '\r\n')[0].split(' ') target = target.lstrip('/') try: self.logger.debug("Netboot: {0}, Target: {1}".format( self.netboot_directory, target)) target = helpers.normalize_path(self.netboot_directory, target) if not os.path.lexists(target) or not os.path.isfile(target): status = '404 Not Found' elif method not in ('GET', 'HEAD'): status = '501 Not Implemented' else: status = '200 OK' except helpers.PathTraversalException: status = '403 Forbidden' response = 'HTTP/1.1 {0}\r\n'.format(status) if status[:3] != '200': # fail out connection.send(response.encode('ascii')) connection.close() self.logger.warn( 'Sending {status} to {addr[0]}:{addr[1]} for {target}'.format( status=status, target=target, addr=addr)) self.logger.debug('Sending message to {0}'.format(repr(addr))) self.logger.debug('<--BEING MESSAGE-->') self.logger.debug('{0}'.format(repr(response))) self.logger.debug('<--END MESSAGE-->') return response += 'Content-Length: {0}\r\n'.format(os.path.getsize(target)) response += '\r\n' if method == 'HEAD': connection.send(response) connection.close() self.logger.debug('Sending message to {0}'.format(repr(addr))) self.logger.debug('<--BEING MESSAGE-->') self.logger.debug('{0}'.format(repr(response))) self.logger.debug('<--END MESSAGE-->') return connection.send(response.encode('ascii')) with open(target, 'rb') as handle: while True: data = handle.read(8192) if not data: break connection.send(data) connection.close() self.logger.info('File Sent - {target} -> {addr[0]}:{addr[1]}'.format( target=target, addr=addr))
def handle_request(self, connection, addr): '''This method handles HTTP request.''' request = connection.recv(1024) self.logger.debug('Recieved message from {addr}'.format(addr = repr(addr))) self.logger.debug('<--BEGIN MESSAGE-->') self.logger.debug('{0}'.format(repr(request))) self.logger.debug('<--END MESSAGE-->') method, target, version = request.split('\r\n')[0].split(' ') target = target.lstrip('/') try: self.logger.debug("Netboot: {0}, Target: {1}".format(self.netboot_directory, target)) target = helpers.normalize_path(self.netboot_directory, target) if not os.path.lexists(target) or not os.path.isfile(target): status = '404 Not Found' elif method not in ('GET', 'HEAD'): status = '501 Not Implemented' else: status = '200 OK' except helpers.PathTraversalException: status = '403 Forbidden' response = 'HTTP/1.1 {0}\r\n'.format(status) if status[:3] != '200': # fail out connection.send(response) connection.close() self.logger.warn('Sending {status} to {addr[0]}:{addr[1]} for {target}'.format(status = status, target = target, addr = addr)) self.logger.debug('Sending message to {0}'.format(repr(addr))) self.logger.debug('<--BEING MESSAGE-->') self.logger.debug('{0}'.format(repr(response))) self.logger.debug('<--END MESSAGE-->') return response += 'Content-Length: {0}\r\n'.format(os.path.getsize(target)) response += '\r\n' if method == 'HEAD': connection.send(response) connection.close() self.logger.debug('Sending message to {0}'.format(repr(addr))) self.logger.debug('<--BEING MESSAGE-->') self.logger.debug('{0}'.format(repr(response))) self.logger.debug('<--END MESSAGE-->') return connection.send(response) with open(target, 'rb') as handle: while True: data = handle.read(8192) if not data: break connection.send(data) connection.close() self.logger.info('File Sent - {target} -> {addr[0]}:{addr[1]}'.format(target = target, addr = addr))
def check_file(self): ''' Determines if the file exists under the netboot_directory, and if it is a file; if not, send an error. ''' filename = self.message.split(chr(0))[0].lstrip('/') try: filename = helpers.normalize_path(self.netboot_directory, filename) except helpers.PathTraversalException: self.send_error(2, 'Path traversal error', filename = filename) return False if os.path.lexists(filename) and os.path.isfile(filename): self.filename = filename return True self.send_error(1, 'File Not Found', filename = filename) return False
def check_file(self): ''' Determines if the file exists under the netboot_directory, and if it is a file; if not, send an error. ''' filename = self.message.split(b'\x00')[0].decode('ascii').lstrip('/') try: filename = helpers.normalize_path(self.netboot_directory, filename) except helpers.PathTraversalException: self.send_error(2, 'Path traversal error', filename = filename) return False if os.path.lexists(filename) and os.path.isfile(filename): self.filename = filename return True self.send_error(1, 'File Not Found', filename = filename) return False
def __init__(self, **server_settings): self.bd = server_settings.get('block_device', '') self.netboot_directory = server_settings.get('netboot_directory', '.') self.write = server_settings.get('write', False) # write? self.cow = server_settings.get('cow', True) # COW is the safe default self.in_mem = server_settings.get('in_mem', False) self.copy_to_ram = server_settings.get('copy_to_ram', False) self.ip = server_settings.get('ip', '0.0.0.0') self.port = int(server_settings.get('port', 10809)) self.mode_debug = server_settings.get('mode_debug', False) # debug mode self.mode_verbose = server_settings.get('mode_verbose', False) # debug mode self.logger = server_settings.get('logger', None) # setup logger if self.logger == None: self.logger = logging.getLogger('NBD') handler = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s %(name)s [%(levelname)s] %(message)s') handler.setFormatter(formatter) self.logger.addHandler(handler) if self.mode_debug: self.logger.setLevel(logging.DEBUG) elif self.mode_verbose: self.logger.setLevel(logging.INFO) else: self.logger.setLevel(logging.WARN) self.logger.debug( 'NOTICE: NBD server started in debug mode. NBD server is using the following:' ) self.logger.info('Server IP: {0}'.format(self.ip)) self.logger.info('Server Port: {0}'.format(self.port)) self.logger.info('Block Device: {0}'.format(self.bd)) self.logger.info('Block Device Writes: {0}'.format(self.write)) self.logger.info('Block Write Method: {0} ({1})'.format( "Copy-On-Write" if self.cow else 'File', 'Memory' if self.in_mem else 'Disk')) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind((self.ip, self.port)) self.sock.listen(4) # if we have COW on, we write elsewhere so we don't need write ability self.openbd = open( helpers.normalize_path(self.netboot_directory, self.bd), 'r+b' if self.write and not self.cow else 'rb') # go to EOF self.openbd.seek(0, 2) # we need this when clients mount us self.bdsize = self.openbd.tell() # go back to start self.openbd.seek(0) if self.copy_to_ram and self.cow: self.logger.info('Starting copying {0} to RAM'.format(self.bd)) self.openbd = io.BytesIO(self.openbd.read()) self.logger.info('Finished copying {0} to RAM'.format(self.bd))