コード例 #1
0
ファイル: test_proto.py プロジェクト: rpcope1/pxe-tools
def test_opt_ack_decode(raw_opt_ack_packet, option_map):
    decoded = decode_tftp_datagram(raw_opt_ack_packet)
    assert isinstance(decoded, OptionsAcknowledgementPacket)
    for opt in decoded.options:
        assert isinstance(opt, TFTPOption)
        assert option_map.get(opt.name) == opt.value
    assert raw_opt_ack_packet == encode_tftp_datagram(decoded)
コード例 #2
0
ファイル: test_server.py プロジェクト: rpcope1/pxe-tools
def test_server_get_file_no_options(read_handler_factory, listen_port,
                                    target_file, file_map):
    s = TFTPServer(read_handler_factory, disable_factory, "127.0.0.1",
                   listen_port)
    t = threading.Thread(target=s.serve_forever)
    t.start()
    time.sleep(1)

    client_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        client_sock.sendto(
            ReadRequestPacket(target_file, "octet").encode(),
            ("127.0.0.1", listen_port))
        has_data = True
        expected_block = 1
        reconstructed = bytearray()
        while has_data:
            raw, addr = client_sock.recvfrom(600)
            decoded = decode_tftp_datagram(raw)
            assert isinstance(decoded, DataPacket)
            assert decoded.block_number == expected_block
            reconstructed.extend(decoded.data)
            if len(decoded.data) < 512:
                has_data = False
            client_sock.sendto(
                AcknowledgementPacket(decoded.block_number).encode(), addr)
            expected_block += 1
        assert reconstructed.decode("utf-8") == file_map[target_file]
    finally:
        client_sock.close()
    s.shutdown()
    t.join(30)
コード例 #3
0
ファイル: test_proto.py プロジェクト: rpcope1/pxe-tools
def test_write_request_with_options(raw_write_request_with_options, request_filename, request_mode, option_map):
    decoded = decode_tftp_datagram(raw_write_request_with_options)
    assert isinstance(decoded, WriteRequestPacket)
    assert decoded.filename == request_filename
    assert decoded.mode == request_mode
    for opt in decoded.options:
        assert isinstance(opt, TFTPOption)
        assert option_map.get(opt.name) == opt.value
    assert raw_write_request_with_options == encode_tftp_datagram(decoded)
コード例 #4
0
    def step(self):
        if self.completed:
            return
        packet, address = self._sock.recvfrom(66000)

        assert address == self.remote_addr
        self._last_seen = time.time()
        self._retries = 0
        try:
            decoded_packet = decode_tftp_datagram(packet)
            if self._mode == self.Modes.READ:
                if isinstance(decoded_packet, AcknowledgementPacket):
                    self._last_packet_received = decoded_packet
                    if self._final_block_sent and decoded_packet.block_number == self._last_block_num:
                        server_logger.debug(
                            "Final Acknowledgement received from {0}.".format(
                                self.remote_addr))
                        self._done = True
                    elif decoded_packet.block_number >= self._last_packet_received.block_number:
                        server_logger.debug(
                            "Acknowledgement received from {0}.".format(
                                self.remote_addr))
                        server_logger.debug("Sending next data packet.")
                        self._send_read_data()
                    else:
                        self._send_error(ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                         "Received invalid ACK packet.")
                else:
                    self._send_error(ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                     "Did not receive expected ACK packet.")
            elif self._mode == self.Modes.WRITE:
                if isinstance(decoded_packet, DataPacket):
                    if decoded_packet.block_number == self._last_block_num + 1:
                        self._handler.write(decoded_packet.data)
                        self._send_write_ack()
                else:
                    self._send_error(ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                     "Did not receive expected DATA packet.")
            else:
                assert False
        except HandlerException as e:
            self._send_error(e.error_code, e.msg)
        except BaseException as e:
            self._send_error(ErrorPacket.ErrorCodes.NOT_DEFINED, str(e))
コード例 #5
0
ファイル: test_proto.py プロジェクト: rpcope1/pxe-tools
def test_read_request_decode(raw_read_request, request_filename, request_mode):
    decoded = decode_tftp_datagram(raw_read_request)
    assert isinstance(decoded, ReadRequestPacket)
    assert decoded.filename == request_filename
    assert decoded.mode == request_mode
    assert raw_read_request == encode_tftp_datagram(decoded)
コード例 #6
0
ファイル: test_proto.py プロジェクト: rpcope1/pxe-tools
def test_error_packet_decode(raw_error_packet, error_code, error_message):
    decoded = decode_tftp_datagram(raw_error_packet)
    assert isinstance(decoded, ErrorPacket)
    assert decoded.error_code == error_code
    assert decoded.error_message == error_message
    assert raw_error_packet == encode_tftp_datagram(decoded)
コード例 #7
0
ファイル: test_proto.py プロジェクト: rpcope1/pxe-tools
def test_ack_decode(raw_ack_packet, block_number):
    decoded = decode_tftp_datagram(raw_ack_packet)
    assert isinstance(decoded, AcknowledgementPacket)
    assert decoded.block_number == block_number
    assert raw_ack_packet == encode_tftp_datagram(decoded)
コード例 #8
0
ファイル: test_proto.py プロジェクト: rpcope1/pxe-tools
def test_data_decode(raw_data_packet, block_number, data_payload):
    decoded = decode_tftp_datagram(raw_data_packet)
    assert isinstance(decoded, DataPacket)
    assert decoded.block_number == block_number
    assert decoded.data == data_payload
    assert raw_data_packet == encode_tftp_datagram(decoded)
コード例 #9
0
    def setup(self):

        server_logger.debug("Setting up session..")
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self._last_seen = time.time()
        try:
            self._sock.bind((self.host, self.port))
            server_logger.debug("Session for {0} bound to {1}".format(
                self.remote_addr, self._sock.getsockname()))
            self._sock.connect(self.remote_addr)
            self._sock.settimeout(int(1.2 * self._timeout))
            decoded_request = decode_tftp_datagram(self.initial_request)
            if isinstance(decoded_request, ReadRequestPacket):
                server_logger.debug("Read Request Received from {0}.".format(
                    self.remote_addr))
                server_logger.debug("Options: {0}".format(
                    decoded_request.options))
                self._mode = self.Modes.READ
                try:
                    self._handler = self.read_handler_factory(
                        decoded_request.filename, decoded_request.mode,
                        self.remote_addr)
                    assert isinstance(self._handler, AbstractReadHandler)
                    self._handler.open()

                    if decoded_request.options:
                        usable_options = []
                        for option in decoded_request.options:
                            if option.name.lower(
                            ) == self.KnownOptions.BLKSIZE:
                                requested_block_size = int(option.value)
                                if 8 <= requested_block_size <= 65464:
                                    self._block_size = requested_block_size
                                    usable_options.append(option)
                                else:
                                    self._send_error(
                                        ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                        "Invalid requested block size: {0}".
                                        format(requested_block_size))
                            elif option.name.lower(
                            ) == self.KnownOptions.TIMEOUT:
                                requested_timeout = int(option.value)
                                if 1 <= requested_timeout <= 255:
                                    self._timeout = requested_timeout
                                    self._sock.settimeout(
                                        int(1.2 * self._timeout))
                                    usable_options.append(option)
                                else:
                                    self._send_error(
                                        ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                        "Invalid timeout: {0}".format(
                                            requested_timeout))
                            elif option.name.lower(
                            ) == self.KnownOptions.TSIZE and self._handler.length is not None:
                                usable_options.append(
                                    TFTPOption(self.KnownOptions.TSIZE,
                                               str(self._handler.length)))
                            elif option.name.lower(
                            ) == self.KnownOptions.WINDOWSIZE:
                                requested_window_size = int(option.value)
                                if 1 <= requested_window_size <= 65535:
                                    self._window_size = requested_window_size
                                    usable_options.append(option)
                                else:
                                    self._send_error(
                                        ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                        "Invalid requested window size: {0}".
                                        format(requested_window_size))
                        server_logger.debug(
                            "Sending options acknowledgement to {0}".format(
                                self.remote_addr))
                        self._sock.send(
                            OptionsAcknowledgementPacket(
                                usable_options).encode())
                    else:
                        server_logger.debug(
                            "Sending first data block to {0}".format(
                                self.remote_addr))
                        self._send_read_data()
                except HandlerException as e:
                    server_logger.warning(
                        "Handler exception setting up for read request for {0} "
                        "(filename: {1}, mode: {2}, options: {3})..."
                        "".format(self.remote_addr, decoded_request.filename,
                                  decoded_request.mode,
                                  decoded_request.options),
                        exc_info=True)
                    self._send_error(e.error_code, e.msg)
                except BaseException as e:
                    server_logger.exception(
                        "Unhandled exception setting up for read request for {0} "
                        "(filename: {1}, mode: {2}, options: {3})..."
                        "".format(self.remote_addr, decoded_request.filename,
                                  decoded_request.mode,
                                  decoded_request.options))
                    self._send_error(ErrorPacket.ErrorCodes.NOT_DEFINED,
                                     str(e))
            elif isinstance(decoded_request, WriteRequestPacket):
                self._mode = self.Modes.WRITE
                try:
                    self._handler = self.write_handler_factory(
                        decoded_request.filename, decoded_request.mode,
                        self.remote_addr)
                    assert isinstance(self._handler, AbstractWriteHandler)
                    self._handler.open()
                    if decoded_request.options:
                        usable_options = []
                        for option in decoded_request.options:
                            if option.name.lower(
                            ) == self.KnownOptions.BLKSIZE:
                                requested_block_size = int(option.value)
                                if 8 <= requested_block_size <= 65464:
                                    self._block_size = requested_block_size
                                    usable_options.append(option)
                                else:
                                    self._send_error(
                                        ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                        "Invalid requested block size: {0}".
                                        format(requested_block_size))
                            elif option.name.lower(
                            ) == self.KnownOptions.TIMEOUT:
                                requested_timeout = int(option.value)
                                if 1 <= requested_timeout <= 255:
                                    self._timeout = requested_timeout
                                    usable_options.append(option)
                                else:
                                    self._send_error(
                                        ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                        "Invalid timeout: {0}".format(
                                            requested_timeout))
                        server_logger.debug(
                            "Sending options acknowledgement to {0}".format(
                                self.remote_addr))
                        self._sock.send(
                            OptionsAcknowledgementPacket(
                                usable_options).encode())
                    else:
                        self._send_write_ack()
                    self._last_seen = time.time()
                except HandlerException as e:
                    self._send_error(e.error_code, e.msg)
                except BaseException as e:
                    self._send_error(ErrorPacket.ErrorCodes.NOT_DEFINED,
                                     str(e))
            else:
                self._send_error(ErrorPacket.ErrorCodes.ILLEGAL_OP,
                                 "Session not started with RRQ or WRQ!")
        except BaseException:
            self._sock.close()
            raise