def test_bad_mode(self): tftp = TFTP(DummyBackend(), _clock=self.clock) tftp.transport = self.transport wrq_datagram = WRQDatagram('foobar', 'badmode', {}) tftp.datagramReceived(wrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ILLEGAL_OP)
def test_file_not_found(self): tftp = TFTP(BackendFactory(FileNotFound("Not found")), _clock=self.clock) tftp.transport = self.transport rrq_datagram = RRQDatagram('foobar', 'netascii', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_FILE_NOT_FOUND)
def test_non_rq_datagram(self): tftp = TFTP(DummyBackend(), _clock=self.clock) tftp.transport = self.transport ack_datagram = ACKDatagram(14) tftp.datagramReceived(ack_datagram.to_wire(), ("127.0.0.1", 1111)) self.failIf(self.transport.disconnecting) self.failIf(self.transport.value())
def test_non_rq_datagram(self): tftp = TFTP(DummyBackend(), _clock=self.clock) tftp.transport = self.transport ack_datagram = ACKDatagram(14) tftp.datagramReceived(ack_datagram.to_wire(), ('127.0.0.1', 1111)) self.failIf(self.transport.disconnecting) self.failIf(self.transport.value())
class SuccessfulAsyncDispatch(unittest.TestCase): def setUp(self): self.clock = Clock() self.temp_dir = FilePath(tempfile.mkdtemp()).asBytesMode() with self.temp_dir.child(b"nonempty").open("w") as fd: fd.write(b"Something uninteresting") self.backend = FilesystemAsyncBackend(self.temp_dir, self.clock) self.tftp = TFTP(self.backend, self.clock) def test_get_reader_defers(self): rrq_datagram = RRQDatagram(b"nonempty", b"NetASCiI", {}) rrq_addr = ("127.0.0.1", 1069) rrq_mode = b"octet" d = self.tftp._startSession(rrq_datagram, rrq_addr, rrq_mode) self.assertFalse(d.called) self.clock.advance(1) self.assertTrue(d.called) self.assertTrue(IReader.providedBy(d.result.backend)) def test_get_writer_defers(self): wrq_datagram = WRQDatagram(b"foobar", b"NetASCiI", {}) wrq_addr = ("127.0.0.1", 1069) wrq_mode = b"octet" d = self.tftp._startSession(wrq_datagram, wrq_addr, wrq_mode) self.assertFalse(d.called) self.clock.advance(1) self.assertTrue(d.called) self.assertTrue(IWriter.providedBy(d.result.backend))
class BackendCallingContext(unittest.TestCase): def setUp(self): super(BackendCallingContext, self).setUp() self.backend = ContextCapturingBackend("local", "remote") self.tftp = TFTP(self.backend) self.tftp.transport = HostTransport(("12.34.56.78", 1234)) @inlineCallbacks def test_context_rrq(self): rrq_datagram = RRQDatagram('nonempty', 'NetASCiI', {}) rrq_addr = ('127.0.0.1', 1069) error = yield self.assertFailure( self.tftp._startSession(rrq_datagram, rrq_addr, "octet"), CapturedContext) self.assertEqual(("get_reader", rrq_datagram.filename), error.args) self.assertEqual( {"local": self.tftp.transport.host, "remote": rrq_addr}, error.context) @inlineCallbacks def test_context_wrq(self): wrq_datagram = WRQDatagram('nonempty', 'NetASCiI', {}) wrq_addr = ('127.0.0.1', 1069) error = yield self.assertFailure( self.tftp._startSession(wrq_datagram, wrq_addr, "octet"), CapturedContext) self.assertEqual(("get_writer", wrq_datagram.filename), error.args) self.assertEqual( {"local": self.tftp.transport.host, "remote": wrq_addr}, error.context)
class SuccessfulAsyncDispatch(unittest.TestCase): def setUp(self): self.clock = Clock() self.tmp_dir_path = tempfile.mkdtemp() with FilePath(self.tmp_dir_path).child('nonempty').open('w') as fd: fd.write('Something uninteresting') self.backend = FilesystemAsyncBackend(self.tmp_dir_path, self.clock) self.tftp = TFTP(self.backend, self.clock) def test_get_reader_defers(self): rrq_datagram = RRQDatagram('nonempty', 'NetASCiI', {}) rrq_addr = ('127.0.0.1', 1069) rrq_mode = "octet" d = self.tftp._startSession(rrq_datagram, rrq_addr, rrq_mode) self.assertFalse(d.called) self.clock.advance(1) self.assertTrue(d.called) self.assertTrue(IReader.providedBy(d.result.backend)) def test_get_writer_defers(self): wrq_datagram = WRQDatagram('foobar', 'NetASCiI', {}) wrq_addr = ('127.0.0.1', 1069) wrq_mode = "octet" d = self.tftp._startSession(wrq_datagram, wrq_addr, wrq_mode) self.assertFalse(d.called) self.clock.advance(1) self.assertTrue(d.called) self.assertTrue(IWriter.providedBy(d.result.backend))
class SuccessfulAsyncDispatch(unittest.TestCase): def setUp(self): self.clock = Clock() self.temp_dir = FilePath(tempfile.mkdtemp()).asBytesMode() with self.temp_dir.child(b'nonempty').open('w') as fd: fd.write(b'Something uninteresting') self.backend = FilesystemAsyncBackend(self.temp_dir, self.clock) self.tftp = TFTP(self.backend, self.clock) def test_get_reader_defers(self): rrq_datagram = RRQDatagram(b'nonempty', b'NetASCiI', {}) rrq_addr = ('127.0.0.1', 1069) rrq_mode = b"octet" d = self.tftp._startSession(rrq_datagram, rrq_addr, rrq_mode) self.assertFalse(d.called) self.clock.advance(1) self.assertTrue(d.called) self.assertTrue(IReader.providedBy(d.result.backend)) def test_get_writer_defers(self): wrq_datagram = WRQDatagram(b'foobar', b'NetASCiI', {}) wrq_addr = ('127.0.0.1', 1069) wrq_mode = b"octet" d = self.tftp._startSession(wrq_datagram, wrq_addr, wrq_mode) self.assertFalse(d.called) self.clock.advance(1) self.assertTrue(d.called) self.assertTrue(IWriter.providedBy(d.result.backend))
def setUp(self): self.clock = Clock() self.temp_dir = FilePath(tempfile.mkdtemp()).asBytesMode() with self.temp_dir.child(b'nonempty').open('w') as fd: fd.write(b'Something uninteresting') self.backend = FilesystemAsyncBackend(self.temp_dir, self.clock) self.tftp = TFTP(self.backend, self.clock)
def test_file_exists(self): tftp = TFTP(BackendFactory(FileExists("Already have one")), _clock=self.clock) tftp.transport = self.transport wrq_datagram = WRQDatagram('foobar', 'netascii', {}) tftp.datagramReceived(wrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_FILE_EXISTS)
class BackendCallingContext(unittest.TestCase): def setUp(self): super(BackendCallingContext, self).setUp() self.backend = ContextCapturingBackend("local", "remote") self.tftp = TFTP(self.backend) self.tftp.transport = HostTransport(("12.34.56.78", 1234)) @inlineCallbacks def test_context_rrq(self): rrq_datagram = RRQDatagram(b'nonempty', b'NetASCiI', {}) rrq_addr = ('127.0.0.1', 1069) error = yield self.assertFailure( self.tftp._startSession(rrq_datagram, rrq_addr, b"octet"), CapturedContext) self.assertEqual(("get_reader", rrq_datagram.filename), error.args) self.assertEqual( { "local": self.tftp.transport.host, "remote": rrq_addr }, error.context) @inlineCallbacks def test_context_wrq(self): wrq_datagram = WRQDatagram(b'nonempty', b'NetASCiI', {}) wrq_addr = ('127.0.0.1', 1069) error = yield self.assertFailure( self.tftp._startSession(wrq_datagram, wrq_addr, b"octet"), CapturedContext) self.assertEqual(("get_writer", wrq_datagram.filename), error.args) self.assertEqual( { "local": self.tftp.transport.host, "remote": wrq_addr }, error.context)
def setUp(self): self.clock = Clock() self.tmp_dir_path = tempfile.mkdtemp() with FilePath(self.tmp_dir_path).child('nonempty').open('w') as fd: fd.write('Something uninteresting') self.backend = FilesystemAsyncBackend(self.tmp_dir_path, self.clock) self.tftp = TFTP(self.backend, self.clock)
def test_bad_mode(self): tftp = TFTP(DummyBackend(), _clock=self.clock) tftp.transport = self.transport wrq_datagram = WRQDatagram(b'foobar', b'badmode', {}) tftp.datagramReceived(wrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ILLEGAL_OP)
def test_file_exists(self): tftp = TFTP(BackendFactory(FileExists("Already have one")), _clock=self.clock) tftp.transport = self.transport wrq_datagram = WRQDatagram(b'foobar', b'netascii', {}) tftp.datagramReceived(wrq_datagram.to_wire(), ('127.0.0.1', 1111)) self.clock.advance(1) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_FILE_EXISTS)
def test_file_not_found(self): tftp = TFTP(BackendFactory(FileNotFound("Not found")), _clock=self.clock) tftp.transport = self.transport rrq_datagram = RRQDatagram(b'foobar', b'netascii', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) self.clock.advance(1) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_FILE_NOT_FOUND)
def setUp(self): self.clock = Clock() self.temp_dir = FilePath(tempfile.mkdtemp()).asBytesMode() with self.temp_dir.child(b"nonempty").open("w") as fd: fd.write(b"Something uninteresting") self.backend = FilesystemAsyncBackend(self.temp_dir, self.clock) self.tftp = TFTP(self.backend, self.clock)
def _startSession(self, *args, **kwargs): d = TFTP._startSession(self, *args, **kwargs) def save_session(session): self.session = session return session d.addCallback(save_session) return d
def main(): from tftp.backend import FilesystemSynchronousBackend from tftp.protocol import TFTP from twisted.internet import reactor from twisted.python import log random.seed() log.startLogging(sys.stdout) #reactor.listenUDP(1069, TFTP(FilesystemSynchronousBackend('output'))) cwd = os.getcwd() reactor.listenUDP(69, TFTP(FilesystemSynchronousBackend(cwd))) reactor.run()
def _makeTFTPService(self, tftp_config): """Create the dynamic TFTP service.""" backend = TFTPBackend(tftp_config["root"], tftp_config["generator"]) # Create a UDP server individually for each discovered network # interface, so that we can detect the interface via which we have # received a datagram. tftp_services = MultiService() tftp_services.setName("tftp") for address in get_all_interface_addresses(): tftp_service = internet.UDPServer(tftp_config["port"], TFTP(backend), interface=address) tftp_service.setName(address) tftp_service.setServiceParent(tftp_services) return tftp_services
def test_access_violation(self): tftp = TFTP(BackendFactory(AccessViolation("No!")), _clock=self.clock) tftp.transport = self.transport wrq_datagram = WRQDatagram('foobar', 'netascii', {}) tftp.datagramReceived(wrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ACCESS_VIOLATION) self.transport.clear() rrq_datagram = RRQDatagram('foobar', 'octet', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ACCESS_VIOLATION)
def test_unsupported(self): tftp = TFTP(BackendFactory(Unsupported("I don't support you")), _clock=self.clock) tftp.transport = self.transport wrq_datagram = WRQDatagram('foobar', 'netascii', {}) tftp.datagramReceived(wrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ILLEGAL_OP) self.transport.clear() rrq_datagram = RRQDatagram('foobar', 'octet', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ILLEGAL_OP)
def test_generic_backend_error(self): tftp = TFTP(BackendFactory(BackendError("A backend that couldn't")), _clock=self.clock) tftp.transport = self.transport rrq_datagram = RRQDatagram('foobar', 'netascii', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_NOT_DEFINED) self.transport.clear() rrq_datagram = RRQDatagram('foobar', 'octet', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) error_datagram = TFTPDatagramFactory(*split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_NOT_DEFINED)
def test_access_violation(self): tftp = TFTP(BackendFactory(AccessViolation("No!")), _clock=self.clock) tftp.transport = self.transport wrq_datagram = WRQDatagram(b'foobar', b'netascii', {}) tftp.datagramReceived(wrq_datagram.to_wire(), ('127.0.0.1', 1111)) self.clock.advance(1) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ACCESS_VIOLATION) self.transport.clear() rrq_datagram = RRQDatagram(b'foobar', b'octet', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) self.clock.advance(1) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ACCESS_VIOLATION)
def test_generic_backend_error(self): tftp = TFTP(BackendFactory(BackendError("A backend that couldn't")), _clock=self.clock) tftp.transport = self.transport rrq_datagram = RRQDatagram(b'foobar', b'netascii', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) self.clock.advance(1) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_NOT_DEFINED) self.transport.clear() rrq_datagram = RRQDatagram(b'foobar', b'octet', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) self.clock.advance(1) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_NOT_DEFINED)
def test_unsupported(self): tftp = TFTP(BackendFactory(Unsupported("I don't support you")), _clock=self.clock) tftp.transport = self.transport wrq_datagram = WRQDatagram(b'foobar', b'netascii', {}) tftp.datagramReceived(wrq_datagram.to_wire(), ('127.0.0.1', 1111)) self.clock.advance(1) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ILLEGAL_OP) self.transport.clear() rrq_datagram = RRQDatagram(b'foobar', b'octet', {}) tftp.datagramReceived(rrq_datagram.to_wire(), ('127.0.0.1', 1111)) self.clock.advance(1) error_datagram = TFTPDatagramFactory( *split_opcode(self.transport.value())) self.assertEqual(error_datagram.errorcode, ERR_ILLEGAL_OP)
def updateServers(self): """Run a server on every interface. For each configured network interface this will start a TFTP server. If called later it will bring up servers on newly configured interfaces and bring down servers on deconfigured interfaces. """ addrs_established = set(service.name for service in self.getServers()) addrs_desired = set(get_all_interface_addresses()) for address in addrs_desired - addrs_established: if not IPAddress(address).is_link_local(): tftp_service = UDPServer(self.port, TFTP(self.backend), interface=address) tftp_service.setName(address) tftp_service.setServiceParent(self) for address in addrs_established - addrs_desired: tftp_service = self.getServiceNamed(address) tftp_service.disownServiceParent()
def datagramReceived(self, *args, **kwargs): self.session = TFTP.datagramReceived(self, *args, **kwargs)
def test_malformed_datagram(self): tftp = TFTP(BackendFactory(), _clock=self.clock) tftp.datagramReceived('foobar', ('127.0.0.1', 1111)) self.failIf(self.transport.disconnecting) self.failIf(self.transport.value())
def setUp(self): super(BackendCallingContext, self).setUp() self.backend = ContextCapturingBackend("local", "remote") self.tftp = TFTP(self.backend) self.tftp.transport = HostTransport(("12.34.56.78", 1234))
def makeService(self, options): backend = FilesystemSynchronousBackend( options["root-directory"], can_read=options['enable-reading'], can_write=options['enable-writing']) return internet.UDPServer(options['port'], TFTP(backend))
def main(): random.seed() log.startLogging(sys.stdout) reactor.listenUDP(1069, TFTP(FilesystemSynchronousBackend('output'))) reactor.run()
def test_malformed_datagram(self): tftp = TFTP(BackendFactory(), _clock=self.clock) tftp.datagramReceived(b"foobar", ("127.0.0.1", 1111)) self.assertFalse(self.transport.disconnecting) self.assertFalse(self.transport.value())
def test_malformed_datagram(self): tftp = TFTP(BackendFactory(), _clock=self.clock) tftp.datagramReceived(b'foobar', ('127.0.0.1', 1111)) self.assertFalse(self.transport.disconnecting) self.assertFalse(self.transport.value())