Exemplo n.º 1
0
 def test_has_mail_data(self) -> None:
     state = State()
     state.greeted = True
     state.mail_data = ""
     code, message = handle_mail(state, "FROM:<*****@*****.**>")
     assert code == SMTPStatus.BAD_SEQUENCE
     assert message == "Bad command sequence"
Exemplo n.º 2
0
 def test_empty_path(self) -> None:
     state = State()
     state.greeted = True
     code, message = handle_mail(state, "FROM:<>")
     assert code == SMTPStatus.OK
     assert message == "Sender OK"
     assert state.reverse_path == ""
Exemplo n.º 3
0
 def test_no_reverse_path(self) -> None:
     state = State()
     state.greeted = True
     state.reverse_path = None
     code, message = handle_rcpt(state, "TO:<*****@*****.**>")
     assert code == SMTPStatus.BAD_SEQUENCE
     assert message == "Bad command sequence"
Exemplo n.º 4
0
 def test_forward_paths_added(self) -> None:
     state = State()
     state.greeted = True
     state.reverse_path = "*****@*****.**"
     handle_rcpt(state, "TO:<*****@*****.**>")
     handle_rcpt(state, "TO:<*****@*****.**>")
     assert state.forward_path == ["*****@*****.**", "*****@*****.**"]
Exemplo n.º 5
0
 def test_with_mailbox(self) -> None:
     state = State()
     state.greeted = True
     code, message = handle_mail(state, "FROM:<*****@*****.**>")
     assert code == SMTPStatus.OK
     assert message == "Sender OK"
     assert state.reverse_path == "*****@*****.**"
Exemplo n.º 6
0
 def test_has_forward_path(self) -> None:
     state = State()
     state.greeted = True
     state.forward_path = ["*****@*****.**"]
     code, message = handle_mail(state, "FROM:<*****@*****.**>")
     assert code == SMTPStatus.BAD_SEQUENCE
     assert message == "Bad command sequence"
Exemplo n.º 7
0
 def test_response(self) -> None:
     state = State()
     state.greeted = True
     state.reverse_path = "*****@*****.**"
     code, message = handle_rcpt(state, "TO:<*****@*****.**>")
     assert code == SMTPStatus.OK
     assert message == "Receiver OK"
Exemplo n.º 8
0
 def test_mail_data(self) -> None:
     state = State()
     state.greeted = True
     state.reverse_path = "*****@*****.**"
     state.mail_data = ""
     code, message = handle_rcpt(state, "TO:<*****@*****.**>")
     assert code == SMTPStatus.BAD_SEQUENCE
     assert message == "Bad command sequence"
Exemplo n.º 9
0
 def test_with_arguments(self) -> None:
     state = State()
     state.greeted = True
     state.reverse_path = "*****@*****.**"
     code, message = handle_rcpt(state, "TO:<*****@*****.**> foo=bar baz")
     assert code == SMTPStatus.OK
     assert message == "Receiver OK"
     assert state.forward_path == ["*****@*****.**"]
Exemplo n.º 10
0
 def test_domain(self, getfqdn: Mock) -> None:
     state = State()
     state.greeted = False
     getfqdn.return_value = "smtp.example.org"
     code, message = handle_ehlo(state, "example.com")
     assert code == SMTPStatus.OK
     assert message == "smtp.example.org Hello example.com"
     assert state.greeted
Exemplo n.º 11
0
 def test_address_literal(self, getfqdn: Mock) -> None:
     state = State()
     state.greeted = False
     getfqdn.return_value = "smtp.example.org"
     code, message = handle_ehlo(state, "[192.168.99.22]")
     assert code == SMTPStatus.OK
     assert message == "smtp.example.org Hello [192.168.99.22]"
     assert state.greeted
Exemplo n.º 12
0
 def test_postmaster(self) -> None:
     state = State()
     state.greeted = True
     state.reverse_path = "*****@*****.**"
     code, message = handle_rcpt(state, "TO:<postMaster> foo")
     assert code == SMTPStatus.OK
     assert message == "Receiver OK"
     assert state.forward_path == ["postMaster"]
Exemplo n.º 13
0
 def test_with_arguments_and_quoted_local_part(self) -> None:
     state = State()
     state.greeted = True
     code, message = handle_mail(
         state, 'FROM:<"foo bar"@example.com> foo=bar'
     )
     assert code == SMTPStatus.OK
     assert message == "Sender OK"
     assert state.reverse_path == '"foo bar"@example.com'
Exemplo n.º 14
0
 def __init__(
     self,
     reader: _StreamReaderProto,
     writer: _StreamWriterProto,
     print_mail: Callable[[State], None],
 ) -> None:
     self.reader = reader
     self.writer = writer
     self.print_mail = print_mail
     self.state = State()
Exemplo n.º 15
0
def handle_rcpt(state: State, arguments: str) -> Reply:
    if arguments[:3].upper() != "TO:":
        return handle_wrong_arguments()
    try:
        path, rest = parse_receiver(arguments[3:])
    except ValueError as exc:
        return handle_wrong_arguments(str(exc))
    if not is_valid_smtp_arguments(rest):
        return handle_wrong_arguments()
    if not state.rcpt_allowed:
        return handle_bad_command_sequence()
    state.add_forward_path(path)
    return SMTPStatus.OK, "Receiver OK"
Exemplo n.º 16
0
 async def _handle_mail_text(self) -> None:
     try:
         await self._read_mail_text()
     except UnexpectedEOFError:
         pass
     except ValueError:
         self._write_reply(SMTPStatus.SYNTAX_ERROR, "Line too long.")
     else:
         self._write_reply(SMTPStatus.OK, "OK")
         self.state.date = datetime.datetime.utcnow()
         state = self.state
         self.print_mail(state)
         self.state = State()
         self.state.greeted = state.greeted
Exemplo n.º 17
0
def handle_helo(state: State, arguments: str) -> Reply:
    if not arguments.strip():
        return handle_missing_arguments()
    if not is_valid_domain(arguments):
        return handle_wrong_arguments()
    state.greeted = True
    return SMTPStatus.OK, f"{getfqdn()} Hello {arguments}"
Exemplo n.º 18
0
def handle_mail(state: State, arguments: str) -> Reply:
    if arguments[:5].upper() != "FROM:":
        return handle_wrong_arguments()
    try:
        path, rest = parse_reverse_path(arguments[5:])
    except ValueError as exc:
        return handle_wrong_arguments(str(exc))
    if not is_valid_smtp_arguments(rest):
        return handle_wrong_arguments()
    if not state.greeted:
        return handle_no_greeting()
    if not state.mail_allowed:
        return handle_bad_command_sequence()
    state.clear()
    state.reverse_path = path
    return SMTPStatus.OK, "Sender OK"
Exemplo n.º 19
0
 def test_print(self) -> None:
     out = StringIO()
     state = State()
     state.date = datetime.datetime(2017, 6, 4, 14, 34, 15)
     state.reverse_path = "*****@*****.**"
     state.forward_path = ["*****@*****.**", "*****@*****.**"]
     state.mail_data = "Subject: Foo\r\n\r\nText\r\n"
     write_mbox_mail(out, state)
     assert out.getvalue() == (
         "From [email protected] Sun Jun  4 14:34:15 2017\n"
         "X-FakeSMTPd-Receiver: [email protected]\n"
         "X-FakeSMTPd-Receiver: [email protected]\n"
         "Subject: Foo\n"
         "\n"
         "Text\n"
         "\n"
     )
Exemplo n.º 20
0
 def test_not_greeted(self) -> None:
     state = State()
     state.greeted = False
     code, message = handle_mail(state, "FROM:<*****@*****.**>")
     assert code == SMTPStatus.BAD_SEQUENCE
     assert message == "No EHLO sent"
Exemplo n.º 21
0
 def test_local_part_too_long(self) -> None:
     code, message = handle_rcpt(
         State(), f"TO:<{'a' * (SMTP_LOCAL_PART_LIMIT + 1)}@example.com>"
     )
     assert code == SMTPStatus.SYNTAX_ERROR_IN_PARAMETERS
     assert message == "Path too long"
Exemplo n.º 22
0
 def test_invalid_domain(self) -> None:
     code, message = handle_helo(State(), "*")
     assert code == SMTPStatus.SYNTAX_ERROR_IN_PARAMETERS
     assert message == "Syntax error in arguments"
Exemplo n.º 23
0
 def test_empty_path(self) -> None:
     code, message = handle_rcpt(State(), "TO:<>")
     assert code == SMTPStatus.SYNTAX_ERROR_IN_PARAMETERS
     assert message == "Syntax error in arguments"
Exemplo n.º 24
0
 def test_response(self, getfqdn: Mock) -> None:
     getfqdn.return_value = "smtp.example.org"
     code, message = handle_helo(State(), "example.com")
     assert code == SMTPStatus.OK
     assert message == "smtp.example.org Hello example.com"
Exemplo n.º 25
0
 def test_no_argument(self) -> None:
     code, message = handle_helo(State(), "")
     assert code == SMTPStatus.SYNTAX_ERROR_IN_PARAMETERS
     assert message == "Missing arguments"
Exemplo n.º 26
0
 def test_set_greeted(self) -> None:
     state = State()
     state.greeted = False
     handle_helo(state, "example.com")
     assert state.greeted
Exemplo n.º 27
0
 def test_path_too_long(self) -> None:
     code, message = handle_rcpt(
         State(), f"TO:<{'a' * 60}@{'a' * (SMTP_PATH_LIMIT - 61)}>"
     )
     assert code == SMTPStatus.SYNTAX_ERROR_IN_PARAMETERS
     assert message == "Path too long"
Exemplo n.º 28
0
 def test_domain_too_long(self) -> None:
     code, message = handle_rcpt(
         State(), f"TO:<foo@{'a' * (SMTP_DOMAIN_LIMIT + 1)}>"
     )
     assert code == SMTPStatus.SYNTAX_ERROR_IN_PARAMETERS
     assert message == "Path too long"
Exemplo n.º 29
0
 def test_path_with_trailing_chars(self) -> None:
     code, message = handle_rcpt(State(), "TO:<*****@*****.**>foo=bar")
     assert code == SMTPStatus.SYNTAX_ERROR_IN_PARAMETERS
     assert message == "Syntax error in arguments"
Exemplo n.º 30
0
 def test_invalid_argument(self) -> None:
     code, message = handle_rcpt(State(), "TO:<*****@*****.**> -foo")
     assert code == SMTPStatus.SYNTAX_ERROR_IN_PARAMETERS
     assert message == "Syntax error in arguments"