Beispiel #1
0
    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))
Beispiel #2
0
 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))
Beispiel #3
0
 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))
Beispiel #4
0
 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
Beispiel #5
0
 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
Beispiel #6
0
    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))