def test_literal_parse(self): state = ParsingState(continuations=[v(b'test\x01abc')]) ret, buf = String.parse(b'{5}\r\n', Params(state)) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'test\x01', ret.value) self.assertFalse(ret.binary) self.assertEqual(b'abc', buf)
def test_literal_binary(self): ret, buf = String.parse( b'~{3}\r\n', Params(continuations=[b'\x00\x01\02abc'])) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'\x00\x01\x02', ret.value) self.assertTrue(ret.binary) self.assertEqual(b'abc', buf)
def test_literal_binary(self): state = ParsingState(continuations=[v(b'\x00\x01\02abc')]) ret, buf = String.parse(b'~{3}\r\n', Params(state)) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'\x00\x01\x02', ret.value) self.assertTrue(ret.binary) self.assertEqual(b'abc', buf)
def test_literal_parse(self): ret, buf = String.parse( b'{5}\r\n', Params(continuations=[b'test\x01abc'])) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'test\x01', ret.value) self.assertFalse(ret.binary) self.assertEqual(b'abc', buf)
def test_quoted_parse_failure(self): with self.assertRaises(NotParseable): String.parse(b'test', Params()) with self.assertRaises(NotParseable): String.parse(b'"one\r\ntwo"', Params()) with self.assertRaises(NotParseable): String.parse(br'"one\ two"', Params()) with self.assertRaises(NotParseable): String.parse(b'"test', Params())
def parse(cls, buf: memoryview, params: Params) \ -> Tuple[AuthenticateCommand, memoryview]: mech_name, buf = QuotedString.parse(buf, params) try: data_obj, buf = String.parse(buf, params) except NotParseable: initial_data: Optional[bytes] = None else: initial_data = data_obj.value return cls(mech_name.value, initial_data), buf
def parse(cls, buf: memoryview, params: Params) \ -> Tuple['AuthenticateCommand', memoryview]: mech_name, buf = QuotedString.parse(buf, params) try: data_obj, buf = String.parse(buf, params) except NotParseable: initial_data: Optional[bytes] = None else: initial_data = data_obj.value return cls(mech_name.value, initial_data), buf
def _parse_script_name(self, buf: memoryview, params: Params, allow_empty: bool = False) \ -> Tuple[str, memoryview]: name_obj, after = String.parse(buf, params) if not allow_empty and not name_obj.value: raise NotParseable(buf) try: return name_obj.value.decode('utf-8'), after except UnicodeError as exc: raise NotParseable(buf) from exc
def parse(cls, buf: memoryview, params: Params) \ -> Tuple['NoOpCommand', memoryview]: whitespace = cls._whitespace_length(buf) tag: Optional[bytes] = None if whitespace > 0: buf = buf[whitespace:] try: tag_obj, buf = String.parse(buf, params) except NotParseable: pass else: tag = tag_obj.value _, buf = EndLine.parse(buf, params) return cls(tag), buf
def parse(cls, buf: memoryview, params: Params) \ -> Tuple[NoOpCommand, memoryview]: whitespace = cls._whitespace_length(buf) tag: Optional[bytes] = None if whitespace > 0: buf = buf[whitespace:] try: tag_obj, buf = String.parse(buf, params) except NotParseable: pass else: tag = tag_obj.value _, buf = EndLine.parse(buf, params) return cls(tag), buf
async def _do_authenticate(self, login: LoginProtocol, cmd: AuthenticateCommand) -> Response: mech = self.auth.get_server(cmd.mech_name) if not mech: return Response(Condition.NO, text='Invalid SASL mechanism.') responses: List[ServerChallenge] = [] if cmd.initial_data is not None: chal = ServerChallenge(b'') chal.set_response(b64decode(cmd.initial_data)) responses.append(chal) while True: try: creds, final = mech.server_attempt(responses) except ServerChallenge as chal: chal_bytes = b64encode(chal.get_challenge()) chal_str = String.build(chal_bytes) chal_str.write(self.writer) self.writer.write(b'\r\n') await self.writer.drain() resp_bytes = await self._read_data() resp_str, _ = String.parse(resp_bytes, self.params) chal.set_response(b64decode(resp_str.value)) if resp_str.value == b'*': raise AuthenticationError('Authentication cancelled.') responses.append(chal) except AuthenticationError as exc: return Response(Condition.NO, text=str(exc)) else: break if final is None: code: Optional[bytes] = None else: code = BytesFormat(b'SASL %b') % String.build(final) try: session = await login(creds, self.config) except InvalidAuth as exc: return Response(Condition.NO, text=str(exc)) else: if session.filter_set is None: return Response(Condition.NO, text='Filters not supported.') self._session = session return Response(Condition.OK, code=code)
async def _do_authenticate(self, cmd: AuthenticateCommand) -> Response: mech = self.auth.get_server(cmd.mech_name) if not mech: return Response(Condition.NO, text='Invalid SASL mechanism.') responses: List[ServerChallenge] = [] if cmd.initial_data is not None: chal = ServerChallenge(b'') chal.set_response(b64decode(cmd.initial_data)) responses.append(chal) while True: try: creds, final = mech.server_attempt(responses) except ServerChallenge as chal: chal_bytes = b64encode(chal.get_challenge()) chal_str = String.build(chal_bytes) chal_str.write(self.writer) self.writer.write(b'\r\n') await self.writer.drain() resp_bytes = await self._read_data() resp_str, _ = String.parse(resp_bytes, self.params) chal.set_response(b64decode(resp_str.value)) if resp_str.value == b'*': raise AuthenticationError('Authentication cancelled.') responses.append(chal) except AuthenticationError as exc: return Response(Condition.NO, text=str(exc)) else: break if final is None: code: Optional[bytes] = None else: code = BytesFormat(b'SASL %b') % String.build(final) try: session = await self._login(creds) except InvalidAuth as exc: return Response(Condition.NO, text=str(exc)) try: self._state = self._get_state(session) except ValueError as exc: return Response(Condition.NO, text=str(exc)) return Response(Condition.OK, code=code)
def test_quoted_parse_empty(self): ret, buf = String.parse(br' "" ', Params()) self.assertIsInstance(ret, QuotedString) self.assertEqual(br'', ret.value) self.assertEqual(b' ', buf)
def test_literal_plus(self): ret, buf = String.parse(v(b'{5+}\r\ntest\x01abc'), Params()) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'test\x01', ret.value) self.assertFalse(ret.binary) self.assertEqual(b'abc', buf)
def test_literal_parse_failure(self): with self.assertRaises(NotParseable): String.parse(b'{}\r\n', Params()) with self.assertRaises(NotParseable): String.parse(b'{10}', Params()) with self.assertRaises(NotParseable): String.parse(b'{10}\r\nabc', Params()) with self.assertRaises(RequiresContinuation): String.parse(b'{10}\r\n', Params()) with self.assertRaises(NotParseable): String.parse(b'{10}\r\n', Params(continuations=[b'a'*9])) with self.assertRaises(NotParseable): String.parse(b'{10+}\r\n' + (b'a'*9), Params()) with self.assertRaises(NotParseable) as raised: String.parse(b'{4097}\r\n', Params()) self.assertEqual(b'[TOOBIG]', bytes(raised.exception.code))
def test_quoted_parse(self): ret, buf = String.parse(br' "one\"two\\three" ', Params()) self.assertIsInstance(ret, QuotedString) self.assertEqual(br'one"two\three', ret.value) self.assertEqual(b' ', buf)
def test_literal_plus_binary(self): ret, buf = String.parse(b'~{3+}\r\n\x00\x01\02abc', Params()) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'\x00\x01\x02', ret.value) self.assertTrue(ret.binary) self.assertEqual(b'abc', buf)
def test_literal_parse_empty(self): ret, buf = String.parse( b'{0}\r\n', Params(continuations=[b'abc'])) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'', ret.value) self.assertEqual(b'abc', buf)
def test_literal_plus(self): ret, buf = String.parse(b'{5+}\r\ntest\x01abc', Params()) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'test\x01', ret.value) self.assertFalse(ret.binary) self.assertEqual(b'abc', buf)
def parse(cls, buf: memoryview, params: Params) \ -> Tuple['PutScriptCommand', memoryview]: script_name, buf = cls._parse_script_name(buf, params) script_data, buf = String.parse(buf, params) _, buf = EndLine.parse(buf, params) return cls(script_name, script_data.value), buf
def test_literal_parse_failure(self): with self.assertRaises(NotParseable): String.parse(b'{}\r\n', Params()) with self.assertRaises(NotParseable): String.parse(b'{10}', Params()) with self.assertRaises(NotParseable): String.parse(b'{10}\r\nabc', Params()) with self.assertRaises(NotParseable): state = ParsingState(continuations=[v(b'a' * 9)]) String.parse(b'{10}\r\n', Params(state)) with self.assertRaises(NotParseable): String.parse(b'{10+}\r\n' + (b'a' * 9), Params()) with self.assertRaises(ParsingInterrupt) as raised1: String.parse(b'{10}\r\n', Params()) self.assertIsInstance(raised1.exception.expected, ExpectContinuation) with self.assertRaises(NotParseable) as raised2: String.parse(b'{4097}\r\n', Params()) self.assertEqual(b'[TOOBIG]', bytes(raised2.exception.code))
def parse(cls, buf: memoryview, params: Params) \ -> Tuple[CheckScriptCommand, memoryview]: script_data, buf = String.parse(buf, params) _, buf = EndLine.parse(buf, params) return cls(script_data.value), buf
def parse(cls, buf: memoryview, params: Params) \ -> Tuple[PutScriptCommand, memoryview]: script_name, buf = cls._parse_script_name(buf, params) script_data, buf = String.parse(buf, params) _, buf = EndLine.parse(buf, params) return cls(script_name, script_data.value), buf
def test_literal_parse_empty(self): state = ParsingState(continuations=[v(b'abc')]) ret, buf = String.parse(b'{0}\r\n', Params(state)) self.assertIsInstance(ret, LiteralString) self.assertEqual(b'', ret.value) self.assertEqual(b'abc', buf)
def parse(cls, buf: memoryview, params: Params) \ -> Tuple['CheckScriptCommand', memoryview]: script_data, buf = String.parse(buf, params) _, buf = EndLine.parse(buf, params) return cls(script_data.value), buf