-# Copyright (c) 2004-2018 mudpy authors. Permission to use, copy,
+# Copyright (c) 2004-2019 mudpy authors. Permission to use, copy,
# modify, and distribute this software is granted under terms
# provided in the LICENSE file distributed with this software.
(2, "Whom would you like to awaken?", ""),
)
+test_preferences = (
+ (0, "> ", "preferences"),
+ (0, r"prompt \x1b\[32m.*> ", "preferences prompt #"),
+ (0, r"# ", "preferences prompt"),
+ (0, r"#.*# ", "preferences prompt >"),
+ (2, "> ", "preferences loglevel 0"),
+ (2, "> ", "preferences"),
+ (2, r"loglevel \x1b\[32m0\x1b\[0m.*> ", "preferences loglevel zero"),
+ (2, r'''cannot be set to type "<class 'str'>"\..*> ''', ""),
+)
+
test_crlf_eol = (
# Send a CR+LF at the end of the line instead of the default CR+NUL,
# to make sure they're treated the same
(2, r"Non-ASCII characters from admin: b'say argle\\xffbargle'.*> ", ""),
)
-test_telnet_unknown = (
+test_telnet_unknown_command = (
# Send an unsupported negotiation command #127 which should get filtered
# from the line of input
(2, "> ", b"say glop\xff\x7fglyf\r\0"),
(2, r'Ignored unknown command 127 from admin\..*"Glopglyf\.".*> ', ""),
)
+test_telnet_unknown_option = (
+ # Send an unassigned negotiation option #127 which should get logged
+ (2, "> ", b"\xff\xfe\x7f\r\0"),
+ (2, r'''Received "don't 127" from admin\..*> ''', ""),
+)
+
test_admin_restriction = (
(0, "> ", "help halt"),
(0, r"That is not an available command\.", "halt"),
(test_actor_disappears, "actor spontaneous disappearance"),
(test_account1_teardown, "second account teardown"),
(test_admin_setup, "admin account setup"),
+ (test_preferences, "set and show preferences"),
(test_crlf_eol, "send crlf from the client as eol"),
(test_telnet_iac, "escape stray telnet iac bytes"),
- (test_telnet_unknown, "strip unknown telnet command"),
+ (test_telnet_unknown_command, "strip unknown telnet command"),
+ (test_telnet_unknown_option, "log unknown telnet option"),
(test_admin_restriction, "restricted admin commands"),
(test_admin_help, "admin help"),
(test_reload, "reload"),
return True
+def option_callback(telnet_socket, command, option):
+ if option == b'\x7f':
+ # We use this unassigned option value as a canary, so short-circuit
+ # any response to avoid endlessly looping
+ pass
+ elif command in (telnetlib.DO, telnetlib.DONT):
+ telnet_socket.send(b"%s%s%s" % (telnetlib.IAC, telnetlib.WONT, option))
+ elif command in (telnetlib.WILL, telnetlib.WONT):
+ telnet_socket.send(b"%s%s%s" % (telnetlib.IAC, telnetlib.DONT, option))
+
+
def main():
captures = ["", "", ""]
lusers = [telnetlib.Telnet(), telnetlib.Telnet(), telnetlib.Telnet()]
service = start_service(sys.argv[1])
for luser in lusers:
luser.open("::1", 4000)
+ luser.set_option_negotiation_callback(option_callback)
for test, description in dialogue:
tlog("\nTesting %s..." % description)
test_start = time.time()
conversant].read_very_eager().decode("utf-8")
except Exception:
pass
- if index is not 0:
+ if index != 0:
tlog("\nERROR: luser%s did not receive expected string:\n\n"
"%s\n\n"
"Check the end of capture_%s.log for received data."