parent $root object $backdoor var $root dbref 'backdoor var $root child_index 27 var $root fertile 0 var $root manager $backdoor var $root owned [$backdoor, $] var $root owners [$] var $root writable [] var $root readable [] var $root inited 1 var $backdoor buffer `[] var $backdoor ip "" var $backdoor hostname "" var $backdoor line_buffer [] var $backdoor valid_hosts [""] var $backdoor passwords #[["back1", "*"], ["back2", "*"]] var $backdoor connected 1 var $backdoor programming 0 var $backdoor port 1169 var $backdoor who "" method init_backdoor if (caller() != $root) throw(~perm, "Caller is not $root."); buffer = `[]; ip = ""; hostname = ""; line_buffer = []; programming = #[]; who = ""; . method uninit_backdoor if (caller() != $root) throw(~perm, "Caller is not $root."); buffer = `[]; ip = ""; hostname = ""; line_buffer = []; programming = []; . method parse arg incoming; var lines, line, index; // called by the server with an incoming buffer if (sender() || caller()) throw(~perm, "Sender and caller are not the server"); lines = buffer_to_strings(buffer_append(buffer, incoming)); index = listlen(lines); buffer = lines[index]; lines = delete(lines, index); line_buffer = [@line_buffer, @lines]; while (line_buffer) { line = line_buffer[1]; line_buffer = delete(line_buffer, 1); (| .parse_line(line) |); } . method parse_line arg line; var l; if (sender() != this()) throw(~perm, "Sender is not this."); catch any { if (connected) { if (programming) ._handle_programming_line(line); else ._handle_command_line(line); } else { ._handle_login(line); } } with handler { for l in ($parse.traceback(traceback())) .echo(l); } . method quit_cmd arg [cmd]; if (sender() != this()) throw(~perm, "Sender is not this."); .echo("Goodbye."); .backdoor_log(("Disconnect <" + (.address())) + ">"); .close(); . method eval_cmd arg cmd, [args]; var code, result; if (sender() != this()) throw(~perm, "Sender is not this."); code = (args.to_string()) + ";"; result = .eval([code], this()); if ((result[1]) == 'errors) .echo(result[2]); else .echo("=> " + toliteral(result[2])); . method eval_as_cmd arg cmd, [args]; var result, code, obj; if (sender() != this()) throw(~perm, "Sender is not this."); args = args.to_string(); result = match_template("* eval *", args); if (!result) { .echo("Syntax: `as <object> eval <code>`"); return; } obj = (| $object.to_dbref(result[1]) |); if (!obj) { .echo(("Unable to find object \"" + (result[1])) + "\"."); return; } code = (result[3]) + ";"; result = obj.eval([code]); if ((result[1]) == 'errors) .echo(result[2]); else .echo("as eval => " + toliteral(result[2])); . method echo arg what; var line; if (type(what) == 'list) { for line in (what) .echo(line); } else { ._echo(what); } . method eval_as_to_cmd arg cmd, [args]; var result, code, obj, target; if (sender() != this()) throw(~perm, "Sender is not this."); args = args.to_string(); result = match_template("* as * eval *", args); if (!result) { .echo("Syntax: `definer <object> as <object> eval <code>`"); return; } obj = (| $object.to_dbref(result[1]) |); target = (| $object.to_dbref(result[3]) |); if (!obj) { .echo(("Unable to find object \"" + (result[1])) + "\"."); return; } if (!target) { .echo(("Unable to find object \"" + (result[3])) + "\"."); return; } code = (result[5]) + ";"; result = obj.eval([code], target); if ((result[1]) == 'errors) .echo(result[2]); else .echo("definer as eval => " + toliteral(result[2])); . method close if (sender() != this()) throw(~perm, "Sender is not this."); close_connection(); if (sender() != definer()) .destroy(); . method set_password arg what, word; var x, i, a, cword; if (!($sys.is_admin(sender()))) { .log_backdoor("Invalid set password attempt by " + (sender().namef('xref))); throw(~perm, "Permission denied, only admins may set backdoor passwords."); } if (strlen(word) < 6) throw(~badpasswd, "Passwords must be at least 6 characters long."); for x in [1 .. strlen(word)] { if ((word[x]) in "1234567890") i = i + 1; else a = a + 1; } if ((a < 2) || (i < 2)) throw(~badpasswd, "Passwords must contain at least 2 numeric characters and 2 non-numeric characters."); cword = crypt(word); if (cword in (passwords.values())) throw(~badpasswd, "That password already exists."); passwords = dict_add(passwords, what, cword); . method del_password arg what; if (!($sys.is_admin(sender()))) { .log_backdoor("Invalid password removal attempt by " + (sender().namef('xref))); throw(~perm, "Permission denied, only admins may adjust backdoor passwords."); } passwords = dict_del(passwords, what); . method address arg [args]; if (sender() != this()) throw(~perm, "Sender is not this."); args = [@args, 'hostname][1]; switch (args) { case 'ip: return ip; case 'hostname: return hostname; } . method set_address arg host; if ((sender() != this()) && (!(sender().has_ancestor(definer())))) throw(~perm, "Sender is not this."); ip = host; hostname = hostname(ip); . method connect arg host, socket; var c; if (sender() || caller()) throw(~perm, "Sender is not the server."); if (!(host in valid_hosts)) { .backdoor_log("Connection from invalid host: " + host); .echo("Your host is not one of the valid hosts."); .close(); return; } .backdoor_log("Connection from: " + host); c = .spawn(); if ($sys.reassign_connection(c)) c.set_address(host); else c.destroy(); . method program if (sender() != this()) throw(~perm, "Sender is not this."); programming = #[['task_id, task_id()], ['code, []]]; return $sys.suspend(); . method check_passwords arg str; var line, pwd; if (sender() != this()) throw(~perm, "Sender is not this."); line = explode(str); pwd = $backdoor.passwords(); if ((!(| pwd[line[1]] |)) || ((listlen(line) != 4) || ((!(.check_encrypted(line[1], line[2]))) || ((!(.check_encrypted("back1", line[3]))) || (!(.check_encrypted("back2", line[4]))))))) return 0; return 1; . method disconnect arg [args]; if (sender() || caller()) throw(~perm, "Sender is not the server."); .close(); . method startup arg [args]; var opt, curr_port; (> .perms(caller(), $sys) <); catch any { opt = "-pbackdoor" in args; curr_port = (| toint(args[opt + 1]) |) || port; $sys.log(("** Starting $backdoor on port " + tostr(curr_port)) + " **"); $sys.bind_port(curr_port, this()); } with handler { $sys.log($parse.traceback(traceback())); } . method passwords if (!(sender().has_ancestor(this()))) throw(~perm, "Sender is not descended from this."); return passwords; . method backdoor_log arg str; if (sender() != this()) throw(~perm, "Sender is not this."); $sys.log(((((.dbref()) + " (") + who) + "): ") + str); . method check_encrypted arg key, str; var pwd; pwd = ($backdoor.passwords())[key]; if (sender() != this()) throw(~perm, "Sender is not this."); return crypt(str, substr(pwd, 1, 2)) == pwd; . method _echo arg what; // send off a string or buffer if (sender() != this()) throw(~perm, "Sender is not this."); (> echo(buffer_from_strings([what])) <); . method program_cmd arg cmd, what; var code, ref, ignore, errors; if (sender() != this()) throw(~perm, "Sender is not this."); ref = $parse.full_reference(what); if (((ref[1]) != 'method) || (!(ref[3]))) { .echo("Invalid object.method() reference, ignoring code until \".\""); ignore = 1; } .echo(((("-- Enter text for " + ((ref[2]).dbref())) + ".") + tostr(ref[3])) + " --"); code = .program(); if (code == 'aborted) { .echo("** Aborted **"); } else if (ignore) { .echo("Finished ignoring text."); } else { errors = (ref[2]).compile(code, ref[3]); if (errors) .echo(errors); else .echo("Method compiled."); } . method _handle_programming_line arg line; if (sender() != this()) throw(~perm, "Sender is not this."); if (!line) { programming = programming.add_elem('code, ""); } else if (line == ".") { $sys.resume(programming['task_id], programming['code]); programming = #[]; } else if (line == "@abort") { $sys.cancel(programming['task_id]); programming = #[]; .echo("** Aborted **"); } else { programming = programming.add_elem('code, line); } . method _handle_command_line arg line; var cmds, cmd; if (sender() != this()) throw(~perm, "Sender is not this."); // cmds = "list, program, quit, eval, as eval, def as eval"; if (!line) { .echo("Available commands: " + cmds); return; } // because I'm lazy, check for ';' if ((line[1]) == ";") line = "eval " + substr(line, 2); .backdoor_log("Command: " + line); cmd = explode(line); switch (cmd[1]) { case "@program", ".program", "program": .program_cmd(@cmd); case "@quit", "quit": .quit_cmd(@cmd); case "eval": .eval_cmd(@cmd); case "as": .eval_as_cmd(@cmd); case "definer", "def": .eval_as_to_cmd(@cmd); case "list", "@list", "@nlist": .list_cmd(@cmd); default: .echo("Available commands: " + cmds); } . method _handle_login arg line; if (sender() != this()) throw(~perm, "Sender is not the definer."); if (.check_passwords(line)) { connected = 1; who = (line.explode())[1]; .backdoor_log("Valid login sequence."); .echo("Valid login sequence."); } else { .backdoor_log((("Invalid login sequence (" + ((| line[1] |) || "<none>")) + " ...) from: ") + (.address())); .echo("Invalid login sequence."); .close(); } . method list_cmd arg cmd, what; var code, ref, ancestor, nums, line; if (sender() != this()) throw(~perm, "Sender is not this."); ref = $parse.full_reference(what); nums = cmd == "@nlist"; if (((ref[1]) != 'method) || (!(ref[3]))) { .echo("Invalid object.method() reference."); return; } ancestor = (ref[2]).find_method(ref[3]); code = ancestor.list_method(ref[3]); if (nums) { for line in [1 .. listlen(code)] code = replace(code, line, ((((line < 10) ? " " | "") + tostr(line)) + ": ") + (code[line])); } else { for line in [1 .. listlen(code)] code = replace(code, line, " " + (code[line])); } .echo((("program " + ((ref[2]).dbref())) + ".") + tostr(ref[3])); .echo(code); .echo("."); .