From e4b5445b3ca844e568a84abbf931a026a6ca6226 Mon Sep 17 00:00:00 2001 From: Test_User Date: Wed, 3 May 2023 22:57:53 -0400 Subject: C HaxServ --- .gitignore | 7 +- CoupServ.lua | 200 ------ Makefile | 33 + commands.c | 65 ++ commands.h | 14 + commands.lua | 363 ----------- config.h | 17 + main.c | 189 ++++++ network.c | 463 +++++++++++++ network.h | 39 ++ network.lua | 310 --------- stdin.lua | 132 ---- stdout | 2049 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ table.c | 163 +++++ table.h | 17 + tls.c | 66 ++ tls.h | 7 + types.h | 12 + utils.c | 38 ++ utils.h | 4 + 20 files changed, 3179 insertions(+), 1009 deletions(-) delete mode 100755 CoupServ.lua create mode 100644 Makefile create mode 100644 commands.c create mode 100644 commands.h delete mode 100644 commands.lua create mode 100644 config.h create mode 100644 main.c create mode 100644 network.c create mode 100644 network.h delete mode 100644 network.lua delete mode 100644 stdin.lua create mode 100644 stdout create mode 100644 table.c create mode 100644 table.h create mode 100644 tls.c create mode 100644 tls.h create mode 100644 types.h create mode 100644 utils.c create mode 100644 utils.h diff --git a/.gitignore b/.gitignore index 71ea114..2e479f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -CoupServConfig.json - -# deprecated version -CoupServ.py +config.c +*.o +haxserv diff --git a/CoupServ.lua b/CoupServ.lua deleted file mode 100755 index 20ee42e..0000000 --- a/CoupServ.lua +++ /dev/null @@ -1,200 +0,0 @@ -#!/usr/bin/env lua ---[[ - -Main program for HaxServ, a pseudoserver for inspircd3. - -Written by: Test_User - -This is free and unencumbered software released into the public -domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -]] - -path = arg[0]:sub(1, -arg[0]:reverse():find('/')) - -socket = require("socket") -json = require("json") -ssl = require("ssl") - -servlist = {} -userlist = {} -chanlist = {} - -function has_permission(user, privs) - if not user or type(user) ~= "table" then - return false - end - - privs = privs or {} - for _, v in pairs(privs) do - if v == "Admin" then - if user.opertype ~= "Admin" then - return false - end - elseif v == "Owner" then -- not dealing with this yet, so just always return false for now - return false - else -- unknown priv, naturally no one has it - return false - end - end - return true -end - -config_file = io.open(path.."CoupServConfig.json", "r+") -config = json.decode(config_file:read("*a")) - -for file, _ in pairs(config.files) do - dofile(path..file) -end - -stdin = socket.tcp() -stdin:close() -stdin:setfd(0) --clearly a hack but it works - -while true do - servlist = {} - userlist = {} - chanlist = {} - - ::continue:: - - local s = socket.tcp4() - s:connect("irc.andrewyu.org", 7005) - local con = ssl.wrap(s, {mode = "client", protocol = "tlsv1_3"}) - - if not con:dohandshake() then - socket.select(nil, nil, 5) - con:close() - goto continue - end - - local time = tostring(os.time()) - - con:send("SERVER hax.irc.andrewyu.org "..config.send_password.." 0 1HC :HaxServ\n") - con:send("BURST "..time.."\n") - con:send("UID 1HC000000 "..time.." "..config.nick.." "..config.hostmask.." "..config.hostmask.." HaxServ 192.168.1.1 "..time.." +k :HaxServ\n") - con:send(":1HC000000 OPERTYPE Admin\n") - - userlist["1HC000000"] = { - server = "1HC", - nick_ts = time, - nick = config.nick, - hostname = config.hostmask, - vhost = config.hostmask, - ident = "HaxServ", - ip = "192.168.1.1", - user_ts = time, - modes = { - ["k"] = true, - }, - realname = "HaxServ", - - metadata = {}, - } - - for channel, _ in pairs(config.channels) do - con:send("FJOIN "..channel.." "..time.." + :,1HC000000\n") - con:send("MODE "..channel.." +o 1HC000000\n") - end - con:send("ENDBURST\n") - - local proceed = true - while proceed do - ready, _, err = socket.select({con, stdin}, {}, 120) - if err then - con:send("") -- hack to make it properly timeout due to annoying bugs - end - - for _, sock in ipairs(ready) do - if sock == con then - local msg, err = con:receive() - - local original = msg - - if err then - proceed = false - break - end - - local source = nil - if msg:sub(1, 1) == ":" then - source = msg:sub(2):match("^[^ ]*") - msg = msg:sub(string.len(source) + 3) -- 1 for the leading ':', 1 for the trailing ' ', and 1 for the offset - end - - local lastarg = msg:match(" :.*") - if lastarg ~= nil then - msg = msg:sub(1, -string.len(lastarg) - 1) -- only offset - lastarg = lastarg:sub(3) - end - - local args = {} - for arg in msg:gmatch("[^ ]*") do - table.insert(args, arg) - end - - local command = args[1] - table.remove(args, 1) - - if lastarg ~= nil then - table.insert(args, lastarg) - end - - if message_handler[command] then - local success, stop = pcall(message_handler[command], con, source, args, original) - if success and stop then - proceed = false - break - elseif not success then - print(stop) - end - else - print("Unhandled command:", ("%q"):format(original)) - end - elseif sock == stdin then - msg = io.stdin:read() - local args = {} - for arg in msg:gmatch("[^ ]*") do - table.insert(args, arg) - end - local command = args[1]:upper() - table.remove(args, 1) - - if stdin_commands[command] then - local success, err = pcall(stdin_commands[command], con, msg, args) - if not success then - print(err) - elseif err then - proceed = false - break - end - else - print("Unknown command.") - end - end - end - if err then break end - end - - con:close() -end diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..34dcb75 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +#INCLUDEFLAGS = + +CFLAGS += $(INCLUDEFLAGS) -D_REENTRANT -ggdb3 + +LDFLAGS = -lssl -lcrypto + +DEPS = $(shell $(CC) $(INCLUDEFLAGS) -MM -MT $(1).o $(1).c | sed -z 's/\\\n //g') + +.PHONY: all clean cleanall release +all: haxserv + +haxserv: main.o network.o commands.o table.o config.o tls.o utils.o + $(CC) $^ -o $@ $(LDFLAGS) + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +$(call DEPS,main) + +$(call DEPS,network) + +$(call DEPS,commands) + +$(call DEPS,table) + +$(call DEPS,config) + +$(call DEPS,tls) + +$(call DEPS,utils) + +clean: + $(RM) haxserv *.o diff --git a/commands.c b/commands.c new file mode 100644 index 0000000..ad0607d --- /dev/null +++ b/commands.c @@ -0,0 +1,65 @@ +#include +#include + +#include "types.h" +#include "table.h" +#include "commands.h" +#include "network.h" +#include "tls.h" + +struct table user_commands = {0}; + +int raw_command(struct string sender, struct string original_message, struct string to, uint64_t argc, struct string *argv) { + if (argv[0].len < original_message.len) { + original_message.data += argv[0].len + 1; + original_message.len -= argv[0].len + 1; + SEND(original_message); + } + SEND(STRING("\n")); + + return 0; +} +static struct command_def raw_command_def = { + .func = raw_command, + .privs = STRING("Admin"), + .local_only = 0, +}; + +static struct pref_type_suff { + struct string pref; + uint8_t type; + struct string suff; +} sus_strings[] = { + {STRING(":1HC000000 PRIVMSG "), 0, STRING(" :Andrew is very sus.\n")}, + {STRING(":1HC000000 PRIVMSG "), 0, STRING(" :I was the impostor, but you only know because I killed you.\n")}, + {STRING(":1HC000000 PRIVMSG "), 0, STRING(" :\x1b(0\n")}, + {STRING(":1HC000000 KILL "), 1, STRING(" :Ejected (1 Impostor remains)\n")}, + {STRING(":1HC000000 KILL "), 1, STRING(" :Ejected, and the crewmates have won.\n")}, +}; + +int sus_command(struct string sender, struct string original_message, struct string to, uint64_t argc, struct string *argv) { + uint64_t index = random() % (sizeof(sus_strings)/sizeof(sus_strings[0])); + + SEND(sus_strings[index].pref); + if (sus_strings[index].type == 0) + SEND(to); + else + SEND(sender); + SEND(sus_strings[index].suff); + + return 0; +} +static struct command_def sus_command_def = { + .func = sus_command, + .privs = {0}, + .local_only = 0, +}; + +int init_user_commands(void) { + user_commands.array = malloc(0); + + set_table_index(&user_commands, STRING(":"), &raw_command_def); + set_table_index(&user_commands, STRING("sus"), &sus_command_def); + + return 0; +} diff --git a/commands.h b/commands.h new file mode 100644 index 0000000..610ed89 --- /dev/null +++ b/commands.h @@ -0,0 +1,14 @@ +#include + +#include "types.h" +#include "table.h" + +struct command_def { + int (*func)(struct string sender, struct string original_message, struct string to, uint64_t argc, struct string *argv); + struct string privs; + uint8_t local_only; +}; + +extern struct table user_commands; + +extern int init_user_commands(void); diff --git a/commands.lua b/commands.lua deleted file mode 100644 index b758812..0000000 --- a/commands.lua +++ /dev/null @@ -1,363 +0,0 @@ ---[[ - -Commands file for HaxServ. - -Written by: Test_User - -This is free and unencumbered software released into the public -domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -]] - -commands = { - ["SANICK"] = { - func = function(con, user, cmd, args, resp) - if #args < 2 then - con:send(":1HC000000 NOTICE "..resp.." :Not enough args.\n") - else - con:send("SANICK "..args[1].." :"..table.concat(args, " ", 2).."\n") - end - end, - privs = {"Admin"}, - args = " ", - }, - - ["RELOAD"] = { - func = function(con, user, cmd, args, resp) - if #args == 0 then - config_file:seek("set", 0) - local success, value_or_err = pcall(json.decode, config_file:read("*a")) - if success then - config = value_or_err - con:send(":1HC000000 NOTICE "..resp.." :Successfully reloaded config.json\n") - else - con:send(":1HC000000 NOTICE "..resp.." :Unable to reload config.json, check /dev/stdout for details.\n") - print("config.json") - print(value_or_err) - end - - for file, _ in pairs(config.files) do - local success, err = pcall(dofile, path..file) - if success then - con:send(":1HC000000 NOTICE "..resp.." :Successfully reloaded "..file.."\n") - else - con:send(":1HC000000 NOTICE "..resp.." :Unable to reload "..file..", check /dev/stdout for details.\n") - print(file) - print(err) - end - end - else - local file = args[1]..".lua" - if config.files[file] then - local success, err = pcall(dofile, path..file) - if success then - con:send(":1HC000000 NOTICE "..resp.." :Successfully reloaded "..file.."\n") - else - con:send(":1HC000000 NOTICE "..resp.." :Unable to reload "..file..", check /dev/stdout for details.\n") - print(file) - print(err) - end - elseif args[1] == "config" then - config_file:seek("set", 0) - local success, value_or_err = pcall(json.decode, config_file:read("*a")) - if success then - config = value_or_err - con:send(":1HC000000 NOTICE "..resp.." :Successfully reloaded config.json\n") - else - con:send(":1HC000000 NOTICE "..resp.." :Unable to reload config.json, check /dev/stdout for details.\n") - print("CoupServConfig.json") - print(value_or_err) - end - else - con:send(":1HC000000 NOTICE "..resp.." :Invalid section.\n") - end - end - end, - privs = {"Admin"}, - args = "[
]", - }, - - ["RECONNECT"] = { - func = function(con, user, cmd, args, resp) - return true - end, - privs = {"Admin"}, - }, - - [":"] = { - func = function(con, user, cmd, args, resp) - con:send(table.concat(args, " ").."\n") - end, - privs = {"Admin"}, - args = "", - }, - - ["HELP"] = { - func = function(con, user, cmd, args, resp) - for command, tbl in pairs(commands) do - if has_permission(userlist[user], tbl.privs) then - if tbl.args then - con:send(":1HC000000 NOTICE "..resp.." :"..command.." "..tbl.args.."\n") - else - con:send(":1HC000000 NOTICE "..resp.." :"..command.."\n") - end - end - end - end, - }, - - ["SHUTDOWN"] = { - func = function(con, user, cmd, args, resp) - local crash_me = nil - crash_me() - end, - privs = {"Owner"}, - }, - - ["SPAM"] = { - func = function(con, user, cmd, args, resp) - if #args < 3 then - con:send(":1HC000000 NOTICE "..resp.." :Not enough args.\n") - elseif tonumber(args[2]) == nil then - con:send(":1HC000000 NOTICE "..resp.." :"..args[2]..": Not a valid positive integer.\n") - elseif tonumber(args[2]) < 1 then - con:send(":1HC000000 NOTICE "..resp.." :"..args[2]..": Not a valid positive integer.\n") - elseif tonumber(args[2]) > 65535 then - con:send(":1HC000000 NOTICE "..resp.." :"..args[2]..": Too large of a number, max is 65535.\n") - else - local msg = ":1HC000000 PRIVMSG "..args[1].." :"..table.concat(args, " ", 3).."\n" - for i=1, tonumber(args[2]), 1 do - con:send(msg) - end - end - end, - privs = {"Admin"}, - args = " ", - }, - - ["OP"] = { - func = function(con, user, cmd, args, resp) - if resp:sub(1, 1) ~= "#" then - con:send(":1HC000000 NOTICE "..resp.." :This command must be executed within a channel.\n") - return - end - - if #args == 0 then - con:send(":1HC000000 MODE "..resp.." +o "..user.."\n") - else - con:send(":1HC000000 MODE "..resp.." +o "..args[1].."\n") - end - end, - privs = {"Admin"}, - args = "[]", - }, - - ["GETUID"] = { - func = function(con, user, cmd, args, resp) - if #args == 0 then - con:send(":1HC000000 NOTICE "..resp.." :"..user.."\n") - else - local nick = table.concat(args, " ") - for uid, tbl in pairs(userlist) do - if tbl.nick == nick then - con:send(":1HC000000 NOTICE "..resp.." :"..uid.."\n") - return - end - end - con:send(":1HC000000 NOTICE "..resp.." :Nick not found.\n") - end - end, - args = "[]", - }, - - ["PRINT"] = { - func = function(con, user, cmd, args, resp) - if #args == 0 then - con:send(":1HC000000 NOTICE "..resp.." :Not enough args.\n") - else - local list - if args[1] == "userlist" then - list = userlist - elseif args[1] == "chanlist" then - list = chanlist - elseif args[1] == "servlist" then - list = servlist - else - con:send(":1HC000000 NOTICE "..resp.." :Unknown list.\n") - return - end - - for k, v in pairs(list) do - local msg = {} - for key, val in pairs(v) do - table.insert(msg, "["..(type(key) == "string" and ("%q"):format(key) or tostring(key)).."] = "..(type(val) == "string" and ("%q"):format(val) or tostring(val))) - end - print("["..(type(k) == "string" and ("%q"):format(k) or tostring(k)).."] = {"..table.concat(msg, ", ").."}") - end - end - end, - privs = {"Admin"}, - args = "", - }, - - ["GETUSERINFO"] = { - func = function(con, user, cmd, args, resp) - if #args == 0 then - args[1] = source - end - - if userlist[args[1]] then - local msg = {} - for key, val in pairs(userlist[args[1]]) do - table.insert(msg, "["..(type(key) == "string" and ("%q"):format(key) or tostring(key)).."] = "..(type(val) == "string" and ("%q"):format(val) or tostring(val))) - end - con:send(":1HC000000 PRIVMSG "..resp.." :{"..table.concat(msg, ", ").."}\n") - else - con:send(":1HC000000 PRIVMSG "..resp.." :Nonexistent UID\n") - end - end, - privs = {"Admin"}, - args = "[]", - }, - - ["GETNICK"] = { - func = function(con, user, cmd, args, resp) - if userlist[args[1]] then - con:send(":1HC000000 NOTICE "..resp.." :"..userlist[args[1]].nick.."\n") - else - con:send(":1HC000000 NOTICE "..resp.." :Nonexistent UID\n") - end - end, - args = "[]", - }, - - ["JUPE"] = { - func = function(con, user, cmd, args, resp) - if #args == 0 then - con:send(":1HC000000 NOTICE "..resp.." :Not enough args.\n") - else - for id, tbl in pairs(servlist) do - if tbl.address == args[1] then - con:send("RSQUIT "..args[1].." :"..table.concat(args, " ", 2).."\n") - con:send(":1HC SERVER "..args[1].." * 0 "..id.." :Juped.\n") - return - end - end - con:send(":1HC000000 NOTICE "..resp.." :Server not found.\n") - end - end, - privs = {"Admin"}, - args = "", - }, - - ["ALLOW"] = { - func = function(con, user, cmd, args, resp) - if #args == 0 then - con:send(":1HC000000 NOTICE "..resp.." :Not enough args.\n") - else - for id, tbl in pairs(userlist) do - if tbl.nick == args[1] then - userlist[id].opertype = "Admin" - con:send(":1HC000000 NOTICE "..resp.." :"..args[1].." is now considered an oper.\n") - return - end - end - con:send(":1HC000000 NOTICE "..resp.." :Nick not found.\n") - end - end, - privs = {"Admin"}, - args = "", - }, - - ["DENY"] = { - func = function(con, user, cmd, args, resp) - if #args == 0 then - con:send(":1HC000000 NOTICE "..resp.." :Not enough args.\n") - else - for id, tbl in pairs(userlist) do - if tbl.nick == args[1] then - userlist[id].opertype = nil - con:send(":1HC000000 MODE "..id.." -o\n") - con:send(":1HC000000 NOTICE "..resp.." :"..args[1].." is no longer an oper.\n") - return - end - end - con:send(":1HC000000 NOTICE "..resp.." :Nick not found.\n") - end - end, - privs = {"Admin"}, - args = "", - }, - - ["SH"] = { - func = function(con, user, cmd, args, resp) - local command = table.concat(args, " ") - if bash_command ~= nil and command == bash_command then - local fd = io.popen(command) - local message = fd:read("*a") - for line in message:gmatch("[^\n]*") do - if line == "" then - con:send(":1HC000000 PRIVMSG "..resp.." : \n") - else - con:send(":1HC000000 PRIVMSG "..resp.." :"..line:gsub("\t", (" "):rep(8)).."\n") - end - end - fd:close() - bash_command = nil - else - if user:sub(1, 1) == "1" and resp:sub(1, 1) == "#" then - con:send(":1HC000000 KICK "..resp.." "..user.." :Thought they could execute arbitrary code on hax's computer.)\n") - else - con:send(":1HC000000 KILL "..user.." :Killed (Thought they could execute arbitrary code on hax's computer.)\n") - end - end - end, - args = "", - }, - - ["SUS"] = { - func = function(con, user, cmd, args, resp) - local lines = { - ":1HC000000 PRIVMSG "..resp.." :Andrew is very sus.\n", - ":1HC000000 PRIVMSG "..resp.." :I was the impostor, but you only know because I killed you.\n", - ":1HC000000 PRIVMSG "..resp.." :\x1b(0\n", - ":1HC000000 KILL "..user.." :Ejected (1 Impostor remains)\n", - ":1HC000000 KILL "..user.." :Ejected, and the crewmates have won.\n", - } - con:send(lines[math.random(#lines)]) - end, - }, - - ["CR"] = { - func = function(con, user, cmd, args, resp) - local lines = { - ":1HC000000 PRIVMSG "..resp.." :You are now a cruxian toxicpod, kill the sharded crewmates.\n", - ":1HC000000 PRIVMSG "..resp.." :You are now a cruxian omura, kill the sharded crewmates.\n", - ":1HC000000 PRIVMSG "..resp.." :You are now a cruxian oct, but you ran out of reactors.\n", - ":1HC000000 KILL "..user.." :Eliminated (You became a cruxian eclipse, but were drawn to my bait reactor)\n", - ":1HC000000 PRIVMSG "..resp.." :You attempted to change into a cruxian navanax, but were caught in the act.\n", - } - con:send(lines[math.random(#lines)]) - end, - }, -} diff --git a/config.h b/config.h new file mode 100644 index 0000000..dc42263 --- /dev/null +++ b/config.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include "types.h" + +extern struct string address; +extern struct string port; +extern struct string nick; +extern struct string log_channel; +extern struct string recv_password; +extern struct string send_password; +extern struct string hostmask; +extern struct string prejoin_channels[]; +extern uint64_t num_prejoin_channels; + +extern struct string command_prefix; diff --git a/main.c b/main.c new file mode 100644 index 0000000..6bebabb --- /dev/null +++ b/main.c @@ -0,0 +1,189 @@ +#include +#include + +#include "network.h" +#include "config.h" +#include "types.h" +#include "tls.h" +#include "types.h" + +int main(void) { + initservernetwork(); + + struct string full_msg = {malloc(0), 0}; + while (1) { + uint8_t data[512]; + uint64_t new_len = SSL_read(ssl, data, 512); + + if (new_len == 0) { + puts("Disconnected."); + return 0; + } + + uint8_t found = 0; + uint64_t msg_len; + for (uint64_t i = 0; i < new_len; i++) { + if (data[i] == '\n') { + found = 1; + msg_len = i + full_msg.len; + break; + } + } + + void *tmp = realloc(full_msg.data, full_msg.len+new_len); + if (tmp == 0 && full_msg.len+new_len != 0) { + puts("OOM... currently just exiting bc there's no automatic reconnect in here yet, and the only sane solution to this is resyncing."); + return 1; + } + full_msg.data = tmp; + + memcpy(full_msg.data+full_msg.len, data, new_len); + + full_msg.len += new_len; + + if (!found) + continue; + + while (1) { + WRITES(1, STRING("Recvd: ")); + write(1, full_msg.data, msg_len+1); // +1: \n + + uint64_t offset = 0; + while (offset < msg_len && full_msg.data[offset] == ' ') + offset++; + + if (msg_len == offset) { + puts("Protocol violation: Empty message."); + return 2; + } + + struct string source; + if (full_msg.data[0] == ':') { + source.data = full_msg.data + 1; + found = 0; + for (uint64_t i = offset + 1; i < msg_len; i++) { + if (full_msg.data[i] == ' ') { + found = 1; + offset = i + 1; + source.len = i - 1; + break; + } + } + if (!found || source.len + 1 == msg_len) { + puts("Protocol violation: Sender but no command."); + return 2; + } + } else { + source = (struct string){0}; + offset = 0; + } + + while (offset < msg_len && full_msg.data[offset] == ' ') + offset++; + + if (offset == msg_len) { + puts("Protocol violation: No command."); + return 2; + } + + struct string command; + command.data = full_msg.data+offset; + found = 0; + for (uint64_t i = offset; i < msg_len; i++) { + if (full_msg.data[i] == ' ') { + found = 1; + command.len = i - offset; + offset = i; + break; + } + } + if (!found) { + command.len = msg_len - offset; + offset = msg_len; + } + + while (offset < msg_len && full_msg.data[offset] == ' ') + offset++; + + uint64_t argc = 0; + uint64_t old_offset = offset; + if (offset < msg_len) { + while (offset < msg_len) { + if (full_msg.data[offset] == ':') { + argc++; + break; + } + + while (offset < msg_len && full_msg.data[offset] != ' ') + offset++; + + argc++; + + while (offset < msg_len && full_msg.data[offset] == ' ') + offset++; + } + } + offset = old_offset; + + struct string argv[argc]; + if (offset < msg_len) { + uint64_t i = 0; + while (offset < msg_len) { + if (full_msg.data[offset] == ':') { + argv[i].data = full_msg.data+offset+1; + argv[i].len = msg_len - offset - 1; + break; + } + + argv[i].data = full_msg.data+offset; + uint64_t start = offset; + + while (offset < msg_len && full_msg.data[offset] != ' ') + offset++; + + argv[i].len = offset - start; + + while (offset < msg_len && full_msg.data[offset] == ' ') + offset++; + + i++; + } + } + + int (*func)(struct string source, uint64_t argc, struct string *argv) = get_table_index(network_commands, command); + + if (func == 0) { + WRITES(1, STRING("WARNING: Command is unknown, ignoring...\n")); + } else { + write(1, "\n", 1); + func(source, argc, argv); + } + write(1, "\n", 1); + + memmove(full_msg.data, full_msg.data+msg_len+1, full_msg.len - msg_len - 1); + full_msg.len -= msg_len+1; + + found = 0; + for (uint64_t i = 0; i < full_msg.len; i++) { + if (full_msg.data[i] == '\n') { + found = 1; + msg_len = i; + break; + } + } + + if (found == 0) { + void *tmp = realloc(full_msg.data, full_msg.len); + if (tmp == 0 && full_msg.len != 0) { + puts("AAAAAAAAA (OOM shrinking allocated data?)"); + return 1; + } + full_msg.data = tmp; + + break; + } + } + } + + return 0; +} diff --git a/network.c b/network.c new file mode 100644 index 0000000..3a92bd5 --- /dev/null +++ b/network.c @@ -0,0 +1,463 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "network.h" +#include "types.h" +#include "table.h" +#include "tls.h" +#include "config.h" +#include "utils.h" +#include "commands.h" + +int resolve(char *address, char *port, struct sockaddr *sockaddr) { + int success; + struct addrinfo hints = {0}, *info; + + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG; + + success = getaddrinfo(address, port, &hints, &info); + + if (success == 0) { + *sockaddr = *(info->ai_addr); + freeaddrinfo(info); + } + + return success; +} + +struct table network_commands = {0}; +struct table server_list = {0}; +struct table user_list = {0}; + +int ping_handler(struct string sender, uint64_t argc, struct string *argv) { + if (argc < 2) { + puts("Invalid PING recieved! (Missing parameters)"); + return 1; + } + + uint64_t len = 1 + argv[1].len + 6 + argv[1].len + 1 + sender.len + 1; + uint8_t msg[len]; + uint64_t offset = 0; + msg[0] = ':'; + offset++; + memcpy(msg+offset, argv[1].data, argv[1].len); + offset += argv[1].len; + memcpy(msg+offset, " PONG ", 6); + offset += 6; + memcpy(msg+offset, argv[1].data, argv[1].len); + offset += argv[1].len; + msg[offset] = ' '; + offset++; + memcpy(msg+offset, sender.data, sender.len); + offset += sender.len; + msg[offset] = '\n'; + + SSL_write(ssl, msg, len); + + return 0; +} + +int server_handler(struct string sender, uint64_t argc, struct string *argv) { + if (argc < 5) { + puts("Invalid SERVER recieved! (Missing parameters)"); + return 1; + } + + if (argv[2].len > 20) { + puts("Invalid SERVER recieved! (Distance too large)"); + return 1; + } + + uint8_t err; + uint64_t distance = str_to_unsigned(argv[2], &err); + if (err) { + puts("Invalid SERVER recieved! (Invalid distance given)"); + return 1; + } + + if (sender.len != 0) { + struct remote_server *from = get_table_index(server_list, sender); + if (!from) { + puts("Invalid SERVER recieved! (Unknown source)"); + return 1; + } + + distance += from->distance + 1; + } + + struct string address; + address.data = malloc(argv[0].len); + if (address.data == 0) + goto server_handler_oom; + + address.len = argv[0].len; + memcpy(address.data, argv[0].data, argv[0].len); + + struct string name; + name.data = malloc(argv[4].len); + if (name.data == 0) + goto server_handler_free_address; + + name.len = argv[4].len; + memcpy(name.data, argv[4].data, argv[4].len); + + struct remote_server *server = malloc(sizeof(*server)); + if (server == 0) + goto server_handler_free_name; + + struct string via; + if (sender.len != 0) { // connected to the sender + via.data = malloc(sender.len); + if (!via.data) + goto server_handler_free_server; + + via.len = sender.len; + memcpy(via.data, sender.data, sender.len); + } else { // connected directly to us + via = (struct string){0}; + } + + *server = (struct remote_server){ + .name = name, + .address = address, + .distance = distance, + .via = via, + }; + + if (set_table_index(&server_list, argv[3], server) != 0) + goto server_handler_free_via; + + return 0; + + server_handler_free_via: + if (sender.len != 0) + free(via.data); + server_handler_free_server: + free(server); + server_handler_free_name: + free(name.data); + server_handler_free_address: + free(address.data); + server_handler_oom: + puts("OOM! (server_handler)"); + + return 1; +} + +int uid_handler(struct string sender, uint64_t argc, struct string *argv) { + if (argc < 10) { + puts("Invalid UID recieved! (Missing parameters)"); + return 1; + } + + if (argv[1].len > 20 || argv[7].len > 20) { + puts("Invalid UID recieved! (Timestamp too long)"); + return 1; + } + + if (sender.len == 0) { + puts("Invalid UID recieved! (No source)"); + return 1; + } + + // TODO: modes + + uint8_t err; + uint64_t nick_ts = str_to_unsigned(argv[1], &err); + if (err) { + puts("Invalid UID recieved! (Invalid nick timestamp)"); + return 1; + } + + uint64_t user_ts = str_to_unsigned(argv[7], &err); + if (err) { + puts("Invalid UID recieved! (Invalid user timestamp)"); + return 1; + } + + struct string server; + server.data = malloc(sender.len); + if (!server.data) + goto uid_handler_oom; + server.len = sender.len; + memcpy(server.data, sender.data, sender.len); + + struct string nick; + nick.data = malloc(argv[2].len); + if (!nick.data) + goto uid_handler_free_server; + nick.len = argv[2].len; + + struct string hostname; + hostname.data = malloc(argv[3].len); + if (!hostname.data) + goto uid_handler_free_nick; + hostname.len = argv[3].len; + memcpy(hostname.data, argv[3].data, argv[3].len); + + struct string vhost; + vhost.data = malloc(argv[4].len); + if (!vhost.data) + goto uid_handler_free_hostname; + vhost.len = argv[4].len; + memcpy(vhost.data, argv[4].data, argv[4].len); + + struct string ident; + ident.data = malloc(argv[5].len); + if (!ident.data) + goto uid_handler_free_vhost; + ident.len = argv[5].len; + memcpy(ident.data, argv[5].data, argv[5].len); + + struct string ip; + ip.data = malloc(argv[6].len); + if (!ip.data) + goto uid_handler_free_ident; + ip.len = argv[6].len; + memcpy(ip.data, argv[6].data, argv[6].len); + + struct string realname; + realname.data = malloc(argv[argc - 1].len); + if (!realname.data) + goto uid_handler_free_ip; + realname.len = argv[argc - 1].len; + memcpy(realname.data, argv[argc - 1].data, argv[argc - 1].len); + + struct user_info *user = malloc(sizeof(*user)); + if (!user) + goto uid_handler_free_realname; + + *user = (struct user_info){ + .nick_ts = nick_ts, + .user_ts = user_ts, + .server = server, + .nick = nick, + .hostname = hostname, + .vhost = vhost, + .ident = ident, + .ip = ip, + .realname = realname, + .metadata = (struct table){.array = malloc(0), .len = 0}, + }; + + if (set_table_index(&user_list, argv[0], user) != 0) + goto uid_handler_free_user; + + return 0; + + uid_handler_free_user: + free(user); + uid_handler_free_realname: + free(realname.data); + uid_handler_free_ip: + free(ip.data); + uid_handler_free_ident: + free(ident.data); + uid_handler_free_vhost: + free(vhost.data); + uid_handler_free_hostname: + free(hostname.data); + uid_handler_free_nick: + free(nick.data); + uid_handler_free_server: + free(server.data); + uid_handler_oom: + puts("OOM! (uid_handler)"); + + return 1; +} + +int opertype_handler(struct string sender, uint64_t argc, struct string *argv) { + if (argc < 1) { + WRITES(2, STRING("Invalid OPERTYPE recieved! (Missing parameters)\n")); + return 1; + } + + if (sender.len == 0) { + WRITES(2, STRING("Invalid OPERTYPE recieved! (No source)\n")); + return 1; + } + + struct user_info *user = get_table_index(user_list, sender); + if (!user) { + WRITES(2, STRING("Server ")); + WRITES(2, sender); + WRITES(2, STRING(" attempted to set OPERTYPE on a nonexistent user!\n")); + return 1; + } + + struct string opertype = {.data = malloc(argv[0].len), .len = argv[0].len}; + if (!opertype.data) { + WRITES(2, STRING("OOM! (opertype_handler)\n")); + return 1; + } + memcpy(opertype.data, argv[0].data, argv[0].len); + + if (user->opertype.len) + free(user->opertype.data); + + user->opertype = opertype; + + return 0; +} + +int privmsg_handler(struct string sender, uint64_t argc, struct string *argv) { + if (argc < 2) { + WRITES(2, STRING("Invalid PRIVMSG recieved (Missing parameters)\n")); + return 1; + } + + if (sender.len == 0) { + WRITES(2, STRING("Invalid PRIVMSG recieved (No source)\n")); + return 1; + } + + uint64_t offset; + if (argv[0].data[0] == '#') { + if (argv[1].len < command_prefix.len || memcmp(argv[1].data, command_prefix.data, command_prefix.len) != 0) { + WRITES(1, STRING("Message is not a command.\n")); + return 0; // not for us + } + + offset = command_prefix.len; + } else { + offset = 0; + } + + if (offset >= argv[1].len || argv[1].data[offset] == ' ') { + // TODO: complain about empty command + WRITES(1, STRING("Command is empty?\n")); + return 0; + } + + uint64_t command_argc = 0; + uint64_t old_offset = offset; + while (offset < argv[1].len) { + while (offset < argv[1].len && argv[1].data[offset] != ' ') + offset++; + + command_argc++; + + while (offset < argv[1].len && argv[1].data[offset] == ' ') + offset++; + } + offset = old_offset; + + struct string command_argv[command_argc]; // argv[0] in this case is the command itself, unlike network command handlers... might change one of these two later to match + uint64_t i = 0; + while (offset < argv[1].len) { + command_argv[i].data = argv[1].data+offset; + uint64_t start = offset; + + while (offset < argv[1].len && argv[1].data[offset] != ' ') + offset++; + + command_argv[i].len = offset - start; + + while (offset < argv[1].len && argv[1].data[offset] == ' ') + offset++; + + i++; + } + + argv[1].data += old_offset; + argv[1].len -= old_offset; + struct command_def *cmd = get_table_index(user_commands, command_argv[0]); + if (cmd) { + if (!cmd->local_only) { + if (cmd->privs.len != 0 && sender.len != 3) { // servers always count as oper :P + struct user_info *user = get_table_index(user_list, sender); + if (!user) { + // TODO: complain about unknown user + WRITES(1, STRING("User is unknown!\n")); + return 0; + } + + if (user->opertype.len != cmd->privs.len || memcmp(user->opertype.data, cmd->privs.data, cmd->privs.len)) { + // TODO: complain about missing privs + WRITES(1, STRING("User lacks privs for this command!\n")); + return 0; + } + } + + WRITES(1, STRING("Executing command ")); + WRITES(1, command_argv[0]); + write(1, "\n", 1); + return cmd->func(sender, argv[1], argv[0], command_argc, command_argv); + } else { + // TODO: complain about remote access + WRITES(1, STRING("Not executing local-only command from a remote source!\n")); + return 0; + } + } else { + // TODO: complain about unknown command + WRITES(1, STRING("Command is unknown!\n")); + WRITES(1, command_argv[0]); + write(1, "\n", 1); + return 0; + } +} + +int initservernetwork(void) { + network_commands.array = malloc(0); + server_list.array = malloc(0); + user_list.array = malloc(0); + + set_table_index(&network_commands, STRING("PING"), &ping_handler); + set_table_index(&network_commands, STRING("SERVER"), &server_handler); + set_table_index(&network_commands, STRING("UID"), &uid_handler); + set_table_index(&network_commands, STRING("OPERTYPE"), &opertype_handler); + set_table_index(&network_commands, STRING("PRIVMSG"), &privmsg_handler); + + init_user_commands(); + + int retval = connect_tls(); + if (retval != 0) { + printf("connect_tls(): %d\n", retval); + return 1; + } + + // probably inefficient to be calling SSL_write this frequently, but also less effort + SEND(STRING("SERVER hax.irc.andrewyu.org ")); + SEND(send_password); + SEND(STRING(" 0 1HC :HaxServ\n")); + SEND(STRING("BURST ")); + uint8_t current_time[21]; // C HaxServ will be deprecated long before we reach 20-digit timestamps + snprintf(current_time, 21, "%d", time(NULL)); + SEND(((struct string){current_time, strlen(current_time)})); + SEND(STRING("\nUID 1HC000000 ")); + SEND(((struct string){current_time, strlen(current_time)})); + SEND(STRING(" ")); + SEND(nick); + SEND(STRING(" ")); + SEND(hostmask); + SEND(STRING(" ")); + SEND(hostmask); + SEND(STRING(" HaxServ 192.168.1.1 ")); + SEND(((struct string){current_time, strlen(current_time)})); + SEND(STRING(" +k :HaxServ\n:1HC000000 OPERTYPE Admin\n")); + + for (uint64_t i = 0; i < num_prejoin_channels; i++) { + SEND(STRING("FJOIN ")); + SEND(prejoin_channels[i]); + SEND(STRING(" ")); + SEND(((struct string){current_time, strlen(current_time)})); + SEND(STRING(" + :,1HC000000\nMODE ")); + SEND(prejoin_channels[i]); + SEND(STRING(" +o 1HC000000\n")); + } + + SEND(STRING("ENDBURST\n")); + + return 0; +} diff --git a/network.h b/network.h new file mode 100644 index 0000000..7cc4a28 --- /dev/null +++ b/network.h @@ -0,0 +1,39 @@ +#pragma once + +#include + +#include "types.h" +#include "table.h" + +// ID is the index you got this from +struct remote_server { + uint64_t distance; // gl if you exceed this + + struct string address; + struct string name; + struct string via; // netsplit purposes + // TODO: metadata +}; + +struct user_info { + uint64_t nick_ts; + uint64_t user_ts; + + struct string server; + struct string nick; + struct string hostname; + struct string vhost; + struct string ident; + struct string ip; + struct string realname; + struct string opertype; + + struct table metadata; +}; + +extern struct table network_commands; +extern struct table server_list; +extern struct table user_list; + +int resolve(char* address, char* port, struct sockaddr *server); +int initservernetwork(void); diff --git a/network.lua b/network.lua deleted file mode 100644 index 84cb712..0000000 --- a/network.lua +++ /dev/null @@ -1,310 +0,0 @@ ---[[ - -Network protocol file for HaxServ. - -Written by: Test_User - -This is free and unencumbered software released into the public -domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -]] - -local function mode_snomask(current, mode, dir, arg) - if dir == "+" then - current[mode] = current[mode] or {} - parse_modes(arg, {}, {}, current[mode]) - if not next(current[mode]) then - current[mode] = nil - end - return true - else - current[mode] = nil - end -end - -local function mode_replace(current, mode, dir, arg) - if dir == "+" then - current[mode] = arg - return true - else - current[mode] = nil - end -end - -local function mode_multi(current, mode, dir, arg) - if dir == "+" then - current[mode] = current[mode] or {} - current[mode][arg] = true - else - if current[mode] == nil then - print("Invalid mode change attempt!\n") - current[mode] = {} - end - current[mode][arg] = nil - if next(current[mode]) == nil then - current[mode] = nil - end - end - return true -end - -local usermodes = { - ["s"] = mode_snomask, -} - -local chanmodes = { - ["l"] = mode_replace, - ["L"] = mode_replace, - ["v"] = mode_multi, - ["o"] = mode_multi, - ["h"] = mode_multi, - ["a"] = mode_multi, - ["q"] = mode_multi, - ["Y"] = mode_multi, - ["d"] = mode_replace, - ["f"] = mode_replace, - ["g"] = mode_multi, - ["b"] = mode_multi, - ["e"] = mode_multi, - ["I"] = mode_multi, - ["k"] = mode_replace, - ["w"] = mode_multi, - ["E"] = mode_replace, - ["F"] = mode_replace, - ["H"] = mode_replace, - ["J"] = mode_replace, - ["X"] = mode_multi, -} - -local function parse_modes(modes, args, has_args, current) - local dir = "-" - for i = 1, #modes do - local mode = modes:sub(i, i) - - if mode == "+" or mode == "-" then - dir = mode - elseif has_args[mode] and has_args[mode][dir] then - if not args[1] then return false end - - if dir == "+" then - current[mode] = (type(current[mode]) == "table" and current[mode] or {}) - current[mode][args[1]] = true - else - if current[mode] then - current[mode][args[1]] = nil - end - end - table.remove(args, 1) - else - current[mode] = (dir == "+" and true or nil) - end - end - return true -end - -local function mode_to_string(modes) - local res = "+" - local args = {} - for mode, arg in pairs(modes) do - if arg == true then - res = res..mode - elseif type(arg) == "string" then - res = res..mode - table.insert(args, arg) - elseif type(arg) == "table" then - for _, a in pairs(arg) do - res = res..mode - table.insert(args, a) - end - end - end - - res = res.." "..table.concat(args, " ") - - return res -end - -message_handler = { - ["PING"] = function(con, source, args, original) - con:send(":"..args[2].." PONG "..args[2].." "..source.."\n") - end, - - ["SERVER"] = function(con, source, args, original) - if source then - servlist[args[4]] = {address = args[1], distance = args[3] + 1 + servlist[source].distance, name = args[5], metadata = {}} - else - servlist[args[4]] = {address = args[1], distance = args[3], name = args[5], metadata = {}} - end - end, - - ["METADATA"] = function(con, source, args, original) - if args[1] == "*" then - if servlist[source] then - servlist[source].metadata[args[2]] = args[3] - else - print("Got metadata command from an unknown server!\n") - end - elseif args[1]:sub(1, 1) == "#" then - print(string.format("%q", original)) - print("Channels not yet handled!\n") - else - if userlist[args[1]] then - userlist[args[1]].metadata[args[2]] = args[3] - else - print(("%q"):format(original)) - print("Got metadata for an unknown user!\n") - end - end - end, - - ["UID"] = function(con, source, args, original) - userlist[args[1]] = { - server = source, - nick_ts = args[2], - nick = args[3], - hostname = args[4], - vhost = args[5], - ident = args[6], - ip = args[7], - user_ts = args[8], - modes = {}, - realname = args[-1], -- last one is safer as any extra are arguments to umodes (or protocol violations, but at that point nothing is a safe option) - - metadata = {}, -- controlled by METADATA network commands - } - - if not parse_modes(args[9], {table.unpack(args, 10, #args-1)}, {["s"] = {["+"] = true, ["-"] = false}}, userlist[args[1]].modes) then return true end - end, - - ["OPERTYPE"] = function(con, source, args, original) - if userlist[source] then - userlist[source].opertype = args[1] - else - print("Server "..source.." attempted to set OPERTYPE on a nonexistent user!\n") - end - end, - - ["NICK"] = function(con, source, args, original) - if userlist[source] then - userlist[source].nick = args[1] - userlist[source].nick_ts = args[2] - end - end, - - ["PRIVMSG"] = function(con, source, args, original) - if args[1] == cur_channel then - print(("%q"):format("<"..userlist[source].nick.."> "..args[2])) - end - - local cmd_args = {} - for part in args[2]:gmatch("[^ ]*") do - table.insert(cmd_args, part) - end - cmd = cmd_args[1]:upper() - table.remove(cmd_args, 1) - - local resp - if args[1]:sub(1, 1) == "#" then - resp = args[1] - - if cmd:sub(1, 3) ~= "\x0304" then return end - - cmd = cmd:sub(4) -- remove leading '-' - else - resp = source - end - - if commands[cmd] then - if has_permission(userlist[source], commands[cmd].privs) then - print(("%q"):format(userlist[source].nick.." executed command: "..cmd)) - return commands[cmd].func(con, source, cmd, cmd_args, resp) - else - con:send(":1HC000000 NOTICE "..resp.." :You are not authorized to execute that command.\n") - end - else - con:send(":1HC000000 NOTICE "..resp.." :Unknown command: "..cmd.."\n") - end - end, - - ["MODE"] = function(con, source, args, original) - if args[1]:sub(1, 1) == "#" then - print("Channels not handled yet!\n") - else - if not userlist[args[1]] then - print("Attempted to set mode on an unknown user!\n") - elseif not parse_modes(args[2], {table.unpack(args, 3)}, usermodes, userlist[args[1]].modes) then - return true - elseif not userlist[args[1]].modes.o then - userlist[args[1]].opertype = nil - end - end - end, - - ["QUIT"] = function(con, source, args, original) - userlist[source] = nil - for name, chan in pairs(chanlist) do - chan["users"][source] = nil - if next(chan["users"]) == nil and not chan["modes"]["P"] then - chanlist[name] = nil - end - end - end, - - ["KILL"] = function(con, source, args, original) - if args[1]:sub(1,3) ~= "1HC" then - print("Kill remote", original) - userlist[source] = nil - for name, chan in pairs(chanlist) do - chan["users"][source] = nil - if next(chan["users"]) == nil and not chan["modes"]["P"] then - chanlist[name] = nil - end - end - else - print("Kill local", original) - local user = userlist[args[1]] - if type(user) == "table" then - con:send("UID "..args[1].." "..user.nick_ts.." "..user.nick.." "..user.hostname.." "..user.vhost.." "..user.ident.." "..user.ip.." "..user.user_ts.." "..mode_to_string(user.modes).." :"..user.realname.."\n") - - -- temporary before I handle channels - for channel, _ in pairs(config.channels) do - con:send(":"..args[1].." JOIN "..channel.."\n") - con:send("MODE "..channel.." +o "..args[1].."\n") - end - end - end - end, - - ["KICK"] = function(con, soure, args, original) - if args[2]:sub(1,3) == "1HC" then - con:send(":"..args[2].." JOIN "..args[1].."\n") - con:send("MODE "..args[1].." +o "..args[2].."\n") - else - print("Channels not yet handled: "..("%q"):format(original)) - end - end, - ---[[ ["FJOIN"] = function(con, source, args, original) - - end]] -} diff --git a/stdin.lua b/stdin.lua deleted file mode 100644 index 4b69590..0000000 --- a/stdin.lua +++ /dev/null @@ -1,132 +0,0 @@ ---[[ - -Network protocol file for HaxServ. - -Written by: Test_User - -This is free and unencumbered software released into the public -domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -]] - -stdin_commands = { - [":"] = function(con, msg, args) - con:send(msg:sub(3).."\n") - end, - - ["RELOAD"] = function(con, msg, args) - if #args == 0 then - config_file:seek("set", 0) - local success, value_or_err = pcall(json.decode, config_file:read("*a")) - if success then - config = value_or_err - print("Successfully reloaded config.json") - else - print("Unable to reload config.json") - print(value_or_err) - end - - for file, _ in pairs(config.files) do - local success, err = pcall(dofile, path..file) - if success then - print("Successfully reloaded "..file) - else - print("Unable to reload "..file) - print(err) - end - end - else - local file = args[1]..".lua" - if config.files[file] then - local success, err = pcall(dofile, path..file) - if success then - print("Successfully reloaded "..file) - else - print("Unable to reload "..file) - print(err) - end - elseif args[1] == "config" then - config_file:seek("set", 0) - local success, value_or_err = pcall(json.decode, config_file:read("*a")) - if success then - config = value_or_err - print("Successfully reloaded config.json") - else - print("Unable to reload config.json") - print(value_or_err) - end - else - print("Invalid section.") - end - end - end, - - ["ALLOW"] = function(con, msg, args) - if #args == 0 then - print("Not enough args.") - else - for id, tbl in pairs(userlist) do - if tbl.nick == args[1] then - userlist[id].opertype = "Admin" - print(args[1].." is now considered an oper.") - return - end - end - print("Nick not found.") - end - end, - - ["DENY"] = function(con, msg, args) - if #args == 0 then - print("Not enough args.") - else - for id, tbl in pairs(userlist) do - if tbl.nick == args[1] then - userlist[id].opertype = nil - con:send(":1HC000000 MODE "..id.." -o\n") - print(args[1].." is no longer an oper.") - return - end - end - print("Nick not found.") - end - end, - - ["ADDSH"] = function(con, msg, args) - if msg:find(" ") == nil then - print("Not enough args.") - else - local i = msg:find(" ") - bash_command = msg:sub(i + 1) -- yes, global - print(bash_command) - end - end, - - ["SET_CHANNEL"] = function(con, msg, args) - cur_channel = args[1] - end, - - ["M"] = function(con, msg, args) - con:send(":1HC000000 PRIVMSG "..cur_channel.." :"..table.concat(args, " ").."\n") - end, -} diff --git a/stdout b/stdout new file mode 100644 index 0000000..189c948 --- /dev/null +++ b/stdout @@ -0,0 +1,2049 @@ +Recvd: CAPAB START 1205 + +CAPAB +START +1205 +WARNING: Command is unknown, ignoring... + +Recvd: CAPAB MODULES :m_anticaps.so m_banredirect.so m_callerid.so m_cban.so=glob m_cloaking.so=guest/j0oku4e9.IP m_dccallow.so m_filter.so=regex/glob m_globalload.so m_ircv3_ctctags.so m_repeat.so=20:0:50:20 m_rline.so=regex/pcre m_shun.so m_svshold.so m_timedbans.so m_topiclock.so + +CAPAB +MODULES +m_anticaps.so m_banredirect.so m_callerid.so m_cban.so=glob m_cloaking.so=guest/j0oku4e9.IP m_dccallow.so m_filter.so=regex/glob m_globalload.so m_ircv3_ctctags.so m_repeat.so=20:0:50:20 m_rline.so=regex/pcre m_shun.so m_svshold.so m_timedbans.so m_topiclock.so +WARNING: Command is unknown, ignoring... + +Recvd: CAPAB MODSUPPORT :m_alltime.so m_channelban.so m_check.so m_chghost.so m_chgident.so m_chgname.so m_classban.so m_clearchan.so m_customtitle.so m_gecosban.so m_knock.so m_muteban.so m_nicklock.so m_nopartmsg.so m_remove.so m_sajoin.so m_sakick.so m_sanick.so m_sapart.so m_saquit.so m_serverban.so m_services_account.so m_showwhois.so m_silence.so m_swhois.so m_uninvite.so m_watch.so + +CAPAB +MODSUPPORT +m_alltime.so m_channelban.so m_check.so m_chghost.so m_chgident.so m_chgname.so m_classban.so m_clearchan.so m_customtitle.so m_gecosban.so m_knock.so m_muteban.so m_nicklock.so m_nopartmsg.so m_remove.so m_sajoin.so m_sakick.so m_sanick.so m_sapart.so m_saquit.so m_serverban.so m_services_account.so m_showwhois.so m_silence.so m_swhois.so m_uninvite.so m_watch.so +WARNING: Command is unknown, ignoring... + +Recvd: CAPAB CHANMODES :admin=&a allowinvite=A anticaps=B auditorium=u autoop=w ban=b banexception=e blockcolor=c c_registered=r censor=G delayjoin=D delaymsg=d exemptchanops=X filter=g flood=f founder=~q halfop=%h history=H invex=I inviteonly=i joinflood=j key=k kicknorejoin=J limit=l moderated=m namebase=Z nickflood=F noctcp=C noextmsg=n nokick=Q noknock=K nonick=N nonotice=T official-join=!Y op=@o operonly=O permanent=P private=p redirect=L reginvite=R regmoderated=M repeat=E secret=s sslonly=z stripcolor=S topiclock=t voice=+v + +CAPAB +CHANMODES +admin=&a allowinvite=A anticaps=B auditorium=u autoop=w ban=b banexception=e blockcolor=c c_registered=r censor=G delayjoin=D delaymsg=d exemptchanops=X filter=g flood=f founder=~q halfop=%h history=H invex=I inviteonly=i joinflood=j key=k kicknorejoin=J limit=l moderated=m namebase=Z nickflood=F noctcp=C noextmsg=n nokick=Q noknock=K nonick=N nonotice=T official-join=!Y op=@o operonly=O permanent=P private=p redirect=L reginvite=R regmoderated=M repeat=E secret=s sslonly=z stripcolor=S topiclock=t voice=+v +WARNING: Command is unknown, ignoring... + +Recvd: CAPAB USERMODES :antiredirect=L bot=B callerid=g cloak=x deaf=d deaf_commonchan=c helpop=h hidechans=I hideoper=H invisible=i nohistory=N oper=o override=O privdeaf=D regdeaf=R servprotect=k showwhois=W snomask=s sslqueries=z u_censor=G u_noctcp=T u_registered=r u_stripcolor=S wallops=w + +CAPAB +USERMODES +antiredirect=L bot=B callerid=g cloak=x deaf=d deaf_commonchan=c helpop=h hidechans=I hideoper=H invisible=i nohistory=N oper=o override=O privdeaf=D regdeaf=R servprotect=k showwhois=W snomask=s sslqueries=z u_censor=G u_noctcp=T u_registered=r u_stripcolor=S wallops=w +WARNING: Command is unknown, ignoring... + +Recvd: CAPAB CAPABILITIES :NICKMAX=30 CHANMAX=60 MAXMODES=20 IDENTMAX=10 MAXQUIT=300 MAXTOPIC=330 MAXKICK=300 MAXREAL=130 MAXAWAY=200 MAXHOST=64 MAXLINE=512 CHALLENGE=WDHJ|stab^bUSeFIVtnt EXTBANS=SzRUsOpTNQCmarnjwcA CASEMAPPING=ascii GLOBOPS=1 + +CAPAB +CAPABILITIES +NICKMAX=30 CHANMAX=60 MAXMODES=20 IDENTMAX=10 MAXQUIT=300 MAXTOPIC=330 MAXKICK=300 MAXREAL=130 MAXAWAY=200 MAXHOST=64 MAXLINE=512 CHALLENGE=WDHJ|stab^bUSeFIVtnt EXTBANS=SzRUsOpTNQCmarnjwcA CASEMAPPING=ascii GLOBOPS=1 +WARNING: Command is unknown, ignoring... + +Recvd: CAPAB END + +CAPAB +END +WARNING: Command is unknown, ignoring... + +Recvd: SERVER irc.andrewyu.org YJDtoVxBONGEoV04QIJfqaP8oUK9DzbDFGaJx84p 0 900 :LibreIRC Root Server + +SERVER +irc.andrewyu.org +YJDtoVxBONGEoV04QIJfqaP8oUK9DzbDFGaJx84p +0 +900 +LibreIRC Root Server + +#args: 2 +#args: 2 +#args: 2 +#args: 2 +#args: 2 +#args: 2 +#args: 1 +#args: 5 +Distance: 0 +Name: LibreIRC Root Server +Address: irc.andrewyu.org + +Recvd: :900 BURST 1683099334 +900 +BURST +1683099334 +WARNING: Command is unknown, ignoring... + +Recvd: :900 VERSION :InspIRCd-3. irc.andrewyu.org :LibreIRCd +900 +VERSION +InspIRCd-3. irc.andrewyu.org :LibreIRCd +WARNING: Command is unknown, ignoring... + +Recvd: :900 SERVER services.irc.andrewyu.org * 0 000 :Atheme IRC Services +900 +SERVER +services.irc.andrewyu.org +* +0 +000 +Atheme IRC Services + +#args: 1 +#args: 1 +#args: 5 +Distance: 1 +Name: Atheme IRC Services +Address: services.irc.andrewyu.org + +Recvd: :000 VERSION :atheme 7.2.11. services.irc.andrewyu.org v7.2.11-0-g82866a59bef5f1be76f3 :ceFljRrT [InspIRCd] [enc:posix] +000 +VERSION +atheme 7.2.11. services.irc.andrewyu.org v7.2.11-0-g82866a59bef5f1be76f3 :ceFljRrT [InspIRCd] [enc:posix] +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AACQ8I 1683084489 hax[xor] 2603-6081-4701-ccd2-06ea-56ff-fe86-cba8.res6.spectrum.com LibreIRC/staff/hax ~Test_User 2603:6081:4701:ccd2:6ea:56ff:fe86:cba8 1683084489 +iow :Test_User +900 +UID +900AACQ8I +1683084489 +hax[xor] +2603-6081-4701-ccd2-06ea-56ff-fe86-cba8.res6.spectrum.com +LibreIRC/staff/hax +~Test_User +2603:6081:4701:ccd2:6ea:56ff:fe86:cba8 +1683084489 ++iow +Test_User +WARNING: Command is unknown, ignoring... + +Recvd: :900AACQ8I OPERTYPE Admin +900AACQ8I +OPERTYPE +Admin +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACQ8I accountname :*!*@* +900 +METADATA +900AACQ8I +accountname +*!*@* +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACQ8I ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AACQ8I +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AACQ5M 1683082198 Discard 144.172.70.127 guest/q46.ksk.172.144.IP misc 144.172.70.127 1683082198 +iwx :Discard +900 +UID +900AACQ5M +1683082198 +Discard +144.172.70.127 +guest/q46.ksk.172.144.IP +misc +144.172.70.127 +1683082198 ++iwx +Discard +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACQ5M ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AACQ5M +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AACM9C 1682966754 Peaksol9 222.246.236.124 user/Peaksol ~Peaksol 222.246.236.124 1682966399 +iw :Rayan Wu +900 +UID +900AACM9C +1682966754 +Peaksol9 +222.246.236.124 +user/Peaksol +~Peaksol +222.246.236.124 +1682966399 ++iw +Rayan Wu +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACM9C accountname :Peaksol +900 +METADATA +900AACM9C +accountname +Peaksol +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACM9C ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AACM9C +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AACI4F 1682846953 Noisytoot cpc92718-cmbg20-2-0-cust83.5-4.cable.virginm.net LibreIRC/staff/Noisytoot noisytoot 82.20.110.84 1682846952 +ITWiosw +AFKLORXafgklortvx :Ron +900 +UID +900AACI4F +1682846953 +Noisytoot +cpc92718-cmbg20-2-0-cust83.5-4.cable.virginm.net +LibreIRC/staff/Noisytoot +noisytoot +82.20.110.84 +1682846952 ++ITWiosw ++AFKLORXafgklortvx +Ron +WARNING: Command is unknown, ignoring... + +Recvd: :900AACI4F OPERTYPE Admin +900AACI4F +OPERTYPE +Admin +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACI4F accountname :Noisytoot +900 +METADATA +900AACI4F +accountname +Noisytoot +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACI4F ssl_cert :vTrse 07793a9956a2d432cfcfee0b43b597298825f175dbb6d515b191349b5c20dd8a CN=Noisytoot CN=Noisytoot +900 +METADATA +900AACI4F +ssl_cert +vTrse 07793a9956a2d432cfcfee0b43b597298825f175dbb6d515b191349b5c20dd8a CN=Noisytoot CN=Noisytoot +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AAB9K2 1682572938 vernmatrixbridgebot mail.vern.cc guest/r03jg7.vern.cc ~vernmatri 5.161.108.85 1682572938 +iwx :vernmatrixbridgebot +900 +UID +900AAB9K2 +1682572938 +vernmatrixbridgebot +mail.vern.cc +guest/r03jg7.vern.cc +~vernmatri +5.161.108.85 +1682572938 ++iwx +vernmatrixbridgebot +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAB9K2 accountname :vernmatrixbridgebot +900 +METADATA +900AAB9K2 +accountname +vernmatrixbridgebot +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAB9K2 ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AAB9K2 +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AABYDC 1682240373 Doggie7112886 58.35.80.74 guest/3fo.dbe.35.58.IP ~doge 58.35.80.74 1682240368 +iwx :doge +900 +UID +900AABYDC +1682240373 +Doggie7112886 +58.35.80.74 +guest/3fo.dbe.35.58.IP +~doge +58.35.80.74 +1682240368 ++iwx +doge +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AABYBO 1682239043 tapuz4 58.35.80.74 guest/3fo.dbe.35.58.IP ~tapuz 58.35.80.74 1682239042 +iwx :tapuz +900 +UID +900AABYBO +1682239043 +tapuz4 +58.35.80.74 +guest/3fo.dbe.35.58.IP +~tapuz +58.35.80.74 +1682239042 ++iwx +tapuz +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAC 1680483093 ChanServ LibreIRC/service/ChanServ LibreIRC/service/ChanServ ChanServ 0.0.0.0 1680483093 +Iiko :Channel Services +000 +UID +000AAAAAC +1680483093 +ChanServ +LibreIRC/service/ChanServ +LibreIRC/service/ChanServ +ChanServ +0.0.0.0 +1680483093 ++Iiko +Channel Services +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAJ 1680483093 OperServ LibreIRC/service/OperServ LibreIRC/service/OperServ OperServ 0.0.0.0 1680483093 +Iiko :Operator Services +000 +UID +000AAAAAJ +1680483093 +OperServ +LibreIRC/service/OperServ +LibreIRC/service/OperServ +OperServ +0.0.0.0 +1680483093 ++Iiko +Operator Services +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAH 1680483093 MemoServ LibreIRC/service/MemoServ LibreIRC/service/MemoServ MemoServ 0.0.0.0 1680483093 +Iiko :Memo Services +000 +UID +000AAAAAH +1680483093 +MemoServ +LibreIRC/service/MemoServ +LibreIRC/service/MemoServ +MemoServ +0.0.0.0 +1680483093 ++Iiko +Memo Services +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AAACJK 1680554346 jjakob 2a01:260:8028:10f0::62 guest/a385ds.158v.n6po.0260.2a01.IP ~quassel 2a01:260:8028:10f0::62 1680554346 +iwx :jjakob +900 +UID +900AAACJK +1680554346 +jjakob +2a01:260:8028:10f0::62 +guest/a385ds.158v.n6po.0260.2a01.IP +~quassel +2a01:260:8028:10f0::62 +1680554346 ++iwx +jjakob +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAACJK ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AAACJK +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAI 1680483093 NickServ LibreIRC/service/NickServ LibreIRC/service/NickServ NickServ 0.0.0.0 1680483093 +Iiko :Nickname Services +000 +UID +000AAAAAI +1680483093 +NickServ +LibreIRC/service/NickServ +LibreIRC/service/NickServ +NickServ +0.0.0.0 +1680483093 ++Iiko +Nickname Services +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AACQ8M 1683084555 Test_Relay 066-026-006-176.inf.spectrum.com LibreIRC/staff/hax ~Test_Rela 66.26.6.176 1683084555 +Biow :Test_User's Relay +900 +UID +900AACQ8M +1683084555 +Test_Relay +066-026-006-176.inf.spectrum.com +LibreIRC/staff/hax +~Test_Rela +66.26.6.176 +1683084555 ++Biow +Test_User's Relay +WARNING: Command is unknown, ignoring... + +Recvd: :900AACQ8M OPERTYPE Admin +900AACQ8M +OPERTYPE +Admin +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACQ8M accountname :*!*@* +900 +METADATA +900AACQ8M +accountname +*!*@* +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACQ8M ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AACQ8M +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AAAAZV 1680574928 Andrew andrewyu.org LibreIRC/staff/Andrew andrew 2a02:c207:2078:7509::1 1680503392 +iow :andrew +900 +UID +900AAAAZV +1680574928 +Andrew +andrewyu.org +LibreIRC/staff/Andrew +andrew +2a02:c207:2078:7509::1 +1680503392 ++iow +andrew +WARNING: Command is unknown, ignoring... + +Recvd: :900AAAAZV OPERTYPE Admin +900AAAAZV +OPERTYPE +Admin +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAAAZV accountname :Andrew +900 +METADATA +900AAAAZV +accountname +Andrew +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAAAZV ssl_cert :vTrse c9c5e208bb4a63f7e7669650803502a82dd38314bba21264d5fbde70aaccac64 CN=Andrew CN=Andrew +900 +METADATA +900AAAAZV +ssl_cert +vTrse c9c5e208bb4a63f7e7669650803502a82dd38314bba21264d5fbde70aaccac64 CN=Andrew CN=Andrew +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAE 1680483093 GroupServ LibreIRC/service/GroupServ LibreIRC/service/GroupServ GroupServ 0.0.0.0 1680483093 +Iiko :Group Management Services +000 +UID +000AAAAAE +1680483093 +GroupServ +LibreIRC/service/GroupServ +LibreIRC/service/GroupServ +GroupServ +0.0.0.0 +1680483093 ++Iiko +Group Management Services +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AAABIS 1680518489 f_fasesbot 2001:1600:10:100::4b9 guest/n0228v.knv7.htp2.1600.2001.IP ~f_fasesbo 2001:1600:10:100::4b9 1680518489 +iwx :f_fasesbot +900 +UID +900AAABIS +1680518489 +f_fasesbot +2001:1600:10:100::4b9 +guest/n0228v.knv7.htp2.1600.2001.IP +~f_fasesbo +2001:1600:10:100::4b9 +1680518489 ++iwx +f_fasesbot +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAABIS ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AAABIS +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAB 1680483093 ALIS LibreIRC/service/ALIS LibreIRC/service/ALIS alis 0.0.0.0 1680483093 +Iiko :Channel Directory +000 +UID +000AAAAAB +1680483093 +ALIS +LibreIRC/service/ALIS +LibreIRC/service/ALIS +alis +0.0.0.0 +1680483093 ++Iiko +Channel Directory +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AACQDP 1683059391 lurk 144.172.70.127 LibreIRC/services/lurk lurk 144.172.70.127 1683059390 +iw :lurk +900 +UID +900AACQDP +1683059391 +lurk +144.172.70.127 +LibreIRC/services/lurk +lurk +144.172.70.127 +1683059390 ++iw +lurk +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACQDP accountname :lurk +900 +METADATA +900AACQDP +accountname +lurk +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACQDP ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AACQDP +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AAAAAE 1680483104 LibreBot andrewyu.org LibreIRC/services/LibreBot bot 2a02:c207:2078:7509::1 1680483104 +Biw :LibreBot +900 +UID +900AAAAAE +1680483104 +LibreBot +andrewyu.org +LibreIRC/services/LibreBot +bot +2a02:c207:2078:7509::1 +1680483104 ++Biw +LibreBot +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAAAAE accountname :LibreBot +900 +METADATA +900AAAAAE +accountname +LibreBot +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAAAAE ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AAAAAE +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAG 1680483093 InfoServ LibreIRC/service/InfoServ LibreIRC/service/InfoServ InfoServ 0.0.0.0 1680483093 +Iiko :Information Service +000 +UID +000AAAAAG +1680483093 +InfoServ +LibreIRC/service/InfoServ +LibreIRC/service/InfoServ +InfoServ +0.0.0.0 +1680483093 ++Iiko +Information Service +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAF 1680483093 HostServ LibreIRC/service/GroupServ LibreIRC/service/GroupServ HostServ 0.0.0.0 1680483093 +Iiko :Host Management Services +000 +UID +000AAAAAF +1680483093 +HostServ +LibreIRC/service/GroupServ +LibreIRC/service/GroupServ +HostServ +0.0.0.0 +1680483093 ++Iiko +Host Management Services +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AAAAAG 1680504503 aohifwueyaiu andrewyu.org LibreIRC/staff/Andrew Andrew 2a02:c207:2078:7509::1 1680483108 +iow :Andrew Yu +900 +UID +900AAAAAG +1680504503 +aohifwueyaiu +andrewyu.org +LibreIRC/staff/Andrew +Andrew +2a02:c207:2078:7509::1 +1680483108 ++iow +Andrew Yu +WARNING: Command is unknown, ignoring... + +Recvd: :900AAAAAG OPERTYPE Admin +900AAAAAG +OPERTYPE +Admin +WARNING: Command is unknown, ignoring... + +Recvd: :900AAAAAG AWAY 1680483109 :Auto away at Mon Apr 3 00:51:49 2023 UTC +900AAAAAG +AWAY +1680483109 +Auto away at Mon Apr 3 00:51:49 2023 UTC +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAAAAG accountname :Andrew +900 +METADATA +900AAAAAG +accountname +Andrew +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAAAAG ssl_cert :vTrse c9c5e208bb4a63f7e7669650803502a82dd38314bba21264d5fbde70aaccac64 CN=Andrew CN=Andrew +900 +METADATA +900AAAAAG +ssl_cert +vTrse c9c5e208bb4a63f7e7669650803502a82dd38314bba21264d5fbde70aaccac64 CN=Andrew CN=Andrew +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AACQ7C 1683083564 LibUser 185.220.101.77 guest/b5m.hcm.220.185.IP ~libuser 185.220.101.77 1683083557 +iwx :LibreIRC User +900 +UID +900AACQ7C +1683083564 +LibUser +185.220.101.77 +guest/b5m.hcm.220.185.IP +~libuser +185.220.101.77 +1683083557 ++iwx +LibreIRC User +WARNING: Command is unknown, ignoring... + +Recvd: :900AACQ7C AWAY 1683083566 :Sleeping +900AACQ7C +AWAY +1683083566 +Sleeping +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AACQ7C ssl_cert :vtrsE No certificate was found. +900 +METADATA +900AACQ7C +ssl_cert +vtrsE No certificate was found. +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAK 1680483093 SaslServ LibreIRC/service/SaslServ LibreIRC/service/SaslServ SaslServ 0.0.0.0 1680483093 +Iiko :SASL Authentication Agent +000 +UID +000AAAAAK +1680483093 +SaslServ +LibreIRC/service/SaslServ +LibreIRC/service/SaslServ +SaslServ +0.0.0.0 +1680483093 ++Iiko +SASL Authentication Agent +WARNING: Command is unknown, ignoring... + +Recvd: :000 UID 000AAAAAD 1680483093 Global LibreIRC/service/Global LibreIRC/service/Global Global 0.0.0.0 1680483093 +Iiko :Network Announcements +000 +UID +000AAAAAD +1680483093 +Global +LibreIRC/service/Global +LibreIRC/service/Global +Global +0.0.0.0 +1680483093 ++Iiko +Network Announcements +WARNING: Command is unknown, ignoring... + +Recvd: :900 UID 900AAAAAM 1680483131 luk3yx andrewyu.org LibreIRC/staff/luk3yx luk3yx 2a02:c207:2078:7509::1 1680483131 +iow :Luke +900 +UID +900AAAAAM +1680483131 +luk3yx +andrewyu.org +LibreIRC/staff/luk3yx +luk3yx +2a02:c207:2078:7509::1 +1680483131 ++iow +Luke +WARNING: Command is unknown, ignoring... + +Recvd: :900AAAAAM OPERTYPE Admin +900AAAAAM +OPERTYPE +Admin +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAAAAM accountname :luk3yx +900 +METADATA +900AAAAAM +accountname +luk3yx +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA 900AAAAAM ssl_cert :vTrse 7f724413ceadd1503643106d4bba5b95f7d5529464dab51528ec63eeff085d0e CN=Luke CN=Luke +900 +METADATA +900AAAAAM +ssl_cert +vTrse 7f724413ceadd1503643106d4bba5b95f7d5529464dab51528ec63eeff085d0e CN=Luke CN=Luke +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #main 1682846956 +Cnt :o,900AACI4F +900 +FJOIN +#main +1682846956 ++Cnt +o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #main maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#main +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN ##chaos 1682846956 +Cnt :o,900AACI4F +900 +FJOIN +##chaos +1682846956 ++Cnt +o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA ##chaos maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +##chaos +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN ###9pfs-bot-debug 1682846956 +Cnt :o,900AACI4F +900 +FJOIN +###9pfs-bot-debug +1682846956 ++Cnt +o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA ###9pfs-bot-debug maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +###9pfs-bot-debug +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #chaos 1682846956 +Cnt :o,000AAAAAC o,900AACI4F +900 +FJOIN +#chaos +1682846956 ++Cnt +o,000AAAAAC o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #chaos 1657179236 hello-smile6 :quiet time +900 +FTOPIC +#chaos +1657179236 +hello-smile6 +quiet time +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #chaos maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#chaos +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #chaos mlock :lL +900 +METADATA +#chaos +mlock +lL +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #services 1680712623 +Cnt :,900AACI4F +900 +FJOIN +#services +1680712623 ++Cnt +,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #services maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#services +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #fases 1680503394 +Cnt :o,000AAAAAC v,900AAABIS +900 +FJOIN +#fases +1680503394 ++Cnt +o,000AAAAAC v,900AAABIS +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #fases 1679163043 f_ :fases, simple core utilties for a fully functional UNIX-like system -- available in the FSF's software directory -- latest POSIX specification -- bridged to Libera.Chat (irc.libera.chat) and XMPP (conference.vitali64.duckdns.org) +900 +FTOPIC +#fases +1679163043 +f_ +fases, simple core utilties for a fully functional UNIX-like system -- available in the FSF's software directory -- latest POSIX specification -- bridged to Libera.Chat (irc.libera.chat) and XMPP (conference.vitali64.duckdns.org) +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #fases maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#fases +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #fases 1680503394 +b vernmatrixbridgebot!*@* +900 +FMODE +#fases +1680503394 ++b +vernmatrixbridgebot!*@* +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #fases mlock :ntlk +900 +METADATA +#fases +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #evosaur 1661187093 +CPnt :,900AACQ8I ,900AACI4F ,900AAAAAM ,900AAAAZV +900 +FJOIN +#evosaur +1661187093 ++CPnt +,900AACQ8I ,900AACI4F ,900AAAAAM ,900AAAAZV +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #evosaur 1665170638 ay!guy@LibreIRC/staff/Andrew :Evosaur - Sane computing | https://www.evosaur.org/ | https://mail.andrewyu.org/mailman/listinfo/evosaur-general +900 +FTOPIC +#evosaur +1665170638 +ay!guy@LibreIRC/staff/Andrew +Evosaur - Sane computing | https://www.evosaur.org/ | https://mail.andrewyu.org/mailman/listinfo/evosaur-general +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #evosaur maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#evosaur +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #evosaur mlock :ntCP +900 +METADATA +#evosaur +mlock +ntCP +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #fsi 1649354236 +CPnt :,900AACQ8I ,900AACM9C o,000AAAAAC o,900AAAAAE ,900AACI4F o,900AACQDP ,900AAAAAM v,900AACQ5M +900 +FJOIN +#fsi +1649354236 ++CPnt +,900AACQ8I ,900AACM9C o,000AAAAAC o,900AAAAAE ,900AACI4F o,900AACQDP ,900AAAAAM v,900AACQ5M +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #fsi 1652857784 Andrew!andrew@LibreIRC/staff/Andrew :Free/Libre Software Introductions +900 +FTOPIC +#fsi +1652857784 +Andrew!andrew@LibreIRC/staff/Andrew +Free/Libre Software Introductions +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #fsi maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#fsi +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #fsi 1649354236 +bbg _9pfs-bot*!*@* *!*pylink*@guest/*.googleusercontent.com *@everyone* +900 +FMODE +#fsi +1649354236 ++bbg +_9pfs-bot*!*@* +*!*pylink*@guest/*.googleusercontent.com +*@everyone* +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #fsi mlock :ntC +900 +METADATA +#fsi +mlock +ntC +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #LibreIRC-logs 1649353732 +Pinst :ao,900AACQ8I o,000AAAAAG o,000AAAAAF o,000AAAAAE o,000AAAAAD o,000AAAAAC o,000AAAAAB o,000AAAAAH o,000AAAAAI o,000AAAAAJ o,000AAAAAK qo,900AAAAAG ao,900AACI4F ao,900AAAAAM qo,900AAAAZV +900 +FJOIN +#LibreIRC-logs +1649353732 ++Pinst +ao,900AACQ8I o,000AAAAAG o,000AAAAAF o,000AAAAAE o,000AAAAAD o,000AAAAAC o,000AAAAAB o,000AAAAAH o,000AAAAAI o,000AAAAAJ o,000AAAAAK qo,900AAAAAG ao,900AACI4F ao,900AAAAAM qo,900AAAAZV +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #LibreIRC-logs 1653474628 Andrew!andrew@LibreIRC/staff/Andrew :logs +900 +FTOPIC +#LibreIRC-logs +1653474628 +Andrew!andrew@LibreIRC/staff/Andrew +logs +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #LibreIRC-logs maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#LibreIRC-logs +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #LibreIRC-logs 1649353732 +II R:Noisytoot O:* +900 +FMODE +#LibreIRC-logs +1649353732 ++II +R:Noisytoot +O:* +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #LibreIRC-logs mlock :ntlk +900 +METADATA +#LibreIRC-logs +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #test 1682846956 +Cnt :o,900AACI4F +900 +FJOIN +#test +1682846956 ++Cnt +o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #test maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#test +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #game 1680483109 +Cnt :,900AACQ8I ,900AACI4F ,900AAAAAM +900 +FJOIN +#game +1680483109 ++Cnt +,900AACQ8I ,900AACI4F ,900AAAAAM +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #game maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#game +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #discard 1680826776 +Cnt :,900AACQDP ,900AACQ5M +900 +FJOIN +#discard +1680826776 ++Cnt +,900AACQDP ,900AACQ5M +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #discard maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#discard +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #hackers 1649931400 +CPnt :,900AAAAAE ,900AACI4F +900 +FJOIN +#hackers +1649931400 ++CPnt +,900AAAAAE ,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #hackers 1665328575 Andrew!guy@LibreIRC/staff/Andrew :sus +900 +FTOPIC +#hackers +1665328575 +Andrew!guy@LibreIRC/staff/Andrew +sus +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #hackers maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#hackers +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #humans 1651372739 +CPnt :,900AACQ8I ,900AACI4F ,900AAAAAM ,900AAB9K2 +900 +FJOIN +#humans +1651372739 ++CPnt +,900AACQ8I ,900AACI4F ,900AAAAAM ,900AAB9K2 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #humans 1652503691 Andrew :Humans only | AIs and bots not allowed! | Discussions unrelated to any specific project, or ones about RFDs +900 +FTOPIC +#humans +1652503691 +Andrew +Humans only | AIs and bots not allowed! | Discussions unrelated to any specific project, or ones about RFDs +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #humans maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#humans +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #humans 1651372739 +be *!*@LibreIRC/services/* R:lurk +900 +FMODE +#humans +1651372739 ++be +*!*@LibreIRC/services/* +R:lurk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #hawkland 1650912031 +CPnt :,900AACQ8I o,000AAAAAC ,900AACI4F +900 +FJOIN +#hawkland +1650912031 ++CPnt +,900AACQ8I o,000AAAAAC ,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #hawkland 1661834471 Noisytoot!noisytoot@LibreIRC/staff/Noisytoot :Hawk's Minetest Server | hawk.minecity.online:30005 +900 +FTOPIC +#hawkland +1661834471 +Noisytoot!noisytoot@LibreIRC/staff/Noisytoot +Hawk's Minetest Server | hawk.minecity.online:30005 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #hawkland maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#hawkland +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #hawkland 1650912031 +w Y:R:Test_User +900 +FMODE +#hawkland +1650912031 ++w +Y:R:Test_User +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #hawkland mlock :ntlk +900 +METADATA +#hawkland +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #LibreIRC 1649353732 +CEPTnrt 3:60 :o,900AACQ8I ,900AACM9C o,000AAAAAC o,900AAAAAE qo,900AAAAAG o,900AACI4F o,900AACQDP ,900AACQ7C o,900AAAAAM qo,900AAAAZV ,900AABYDC ,900AABYBO +900 +FJOIN +#LibreIRC +1649353732 ++CEPTnrt +3:60 +o,900AACQ8I ,900AACM9C o,000AAAAAC o,900AAAAAE qo,900AAAAAG o,900AACI4F o,900AACQDP ,900AACQ7C o,900AAAAAM qo,900AAAAZV ,900AABYDC ,900AABYBO +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #LibreIRC 1666877583 Andrew :AndrewIRC network channel | This network is mainly English and has a bit of Chinese +900 +FTOPIC +#LibreIRC +1666877583 +Andrew +AndrewIRC network channel | This network is mainly English and has a bit of Chinese +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #LibreIRC maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#LibreIRC +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #LibreIRC 1649353732 +bwwweeeXXI _9pfs-bot-nodejs!~_9pfs@guest/*.googleusercontent.com o:R:Noisytoot o:*!*@LibreIRC/* Y:R:downgrade R:hax R:Noisytoot \Test_User/Libera!*@* flood:v repeat:v R:Noisytoot +900 +FMODE +#LibreIRC +1649353732 ++bwwweeeXXI +_9pfs-bot-nodejs!~_9pfs@guest/*.googleusercontent.com +o:R:Noisytoot +o:*!*@LibreIRC/* +Y:R:downgrade +R:hax +R:Noisytoot +\Test_User/Libera!*@* +flood:v +repeat:v +R:Noisytoot +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #LibreIRC mlock :nCP +900 +METADATA +#LibreIRC +mlock +nCP +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #LibreIRC topiclock :1 +900 +METADATA +#LibreIRC +topiclock +1 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #aviation 1657726600 +CPnt : +900 +FJOIN +#aviation +1657726600 ++CPnt + +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #aviation 1657726626 IDCUser!andrew@LibreIRC/staff/Andrew :What would you do in case of: Airspeed unreliable? +900 +FTOPIC +#aviation +1657726626 +IDCUser!andrew@LibreIRC/staff/Andrew +What would you do in case of: Airspeed unreliable? +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #aviation maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#aviation +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #vf-technic 1649480682 +CPnt :,900AACQDP Y,900AACQ8M +900 +FJOIN +#vf-technic +1649480682 ++CPnt +,900AACQDP Y,900AACQ8M +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #vf-technic 1655006390 Andrew!andrew@LibreIRC/staff/Andrew :Haxxorland +900 +FTOPIC +#vf-technic +1655006390 +Andrew!andrew@LibreIRC/staff/Andrew +Haxxorland +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #vf-technic maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#vf-technic +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #vf-technic 1649480682 +w Y:*!*@66.26.6.176 +900 +FMODE +#vf-technic +1649480682 ++w +Y:*!*@66.26.6.176 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #LibreIRC-opers 1649353732 +OPint :o,000AAAAAC o,900AACI4F o,900AAAAAM +900 +FJOIN +#LibreIRC-opers +1649353732 ++OPint +o,000AAAAAC o,900AACI4F o,900AAAAAM +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #LibreIRC-opers 1651610632 vitali64!~vitali64@LibreIRC/staff/vitali64 :LibreIRC Operator Discussions +900 +FTOPIC +#LibreIRC-opers +1651610632 +vitali64!~vitali64@LibreIRC/staff/vitali64 +LibreIRC Operator Discussions +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #LibreIRC-opers maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#LibreIRC-opers +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #LibreIRC-opers 1649353732 +II O:* R:Noisytoot +900 +FMODE +#LibreIRC-opers +1649353732 ++II +O:* +R:Noisytoot +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #LibreIRC-opers mlock :ntlk +900 +METADATA +#LibreIRC-opers +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #librespeech 1653494594 +Pt :o,900AACQ8I o,900AACM9C o,000AAAAAC o,900AAAAAE o,900AACI4F o,900AACQDP o,900AACQ7C o,900AAAAAM o,900AAAAZV o,900AABYBO +900 +FJOIN +#librespeech +1653494594 ++Pt +o,900AACQ8I o,900AACM9C o,000AAAAAC o,900AAAAAE o,900AACI4F o,900AACQDP o,900AACQ7C o,900AAAAAM o,900AAAAZV o,900AABYBO +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #librespeech 1682854685 Andrew!andrew@LibreIRC/staff/Andrew :YAY +900 +FTOPIC +#librespeech +1682854685 +Andrew!andrew@LibreIRC/staff/Andrew +YAY +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #librespeech maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#librespeech +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #librespeech 1653494594 +eeeeeeeegI luk3yx[m]!*@guest/hkda43.cc Rush!*@* MatrixBot!~matrixbot@guest/hkda43.cc *!*@*.xyz *!*@user/_9pfs R:luk3yx *!*@* O:* e *!*@*.noisytoot.org +900 +FMODE +#librespeech +1653494594 ++eeeeeeeegI +luk3yx[m]!*@guest/hkda43.cc +Rush!*@* +MatrixBot!~matrixbot@guest/hkda43.cc +*!*@*.xyz +*!*@user/_9pfs +R:luk3yx +*!*@* +O:* +e +*!*@*.noisytoot.org +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #pissnet 1682846956 +Cnt :o,900AACI4F +900 +FJOIN +#pissnet +1682846956 ++Cnt +o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #pissnet 1649040018 Noisytoot :Welcome to the pissnet autonomous zone +900 +FTOPIC +#pissnet +1649040018 +Noisytoot +Welcome to the pissnet autonomous zone +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #pissnet maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#pissnet +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #pissnet mlock :ntlk +900 +METADATA +#pissnet +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #lurklite 1682846956 +Cnt :o,900AACI4F +900 +FJOIN +#lurklite +1682846956 ++Cnt +o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #lurklite maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#lurklite +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #IDC 1649730748 +CPnt :,900AACQ8I o,000AAAAAC o,900AAAAAE ,900AAAAAG ,900AACI4F o,900AACQDP ,900AAAAAM +900 +FJOIN +#IDC +1649730748 ++CPnt +,900AACQ8I o,000AAAAAC o,900AAAAAE ,900AAAAAG ,900AACI4F o,900AACQDP ,900AAAAAM +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #IDC 1667013277 Andrew :Internet Delay Chat protocol | May see active development in a month or two | https://git.andrewyu.org/andrew/ememo.git/about/ +900 +FTOPIC +#IDC +1667013277 +Andrew +Internet Delay Chat protocol | May see active development in a month or two | https://git.andrewyu.org/andrew/ememo.git/about/ +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #IDC maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#IDC +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #IDC 1649730748 +bgg afads!*@* (IRC)?idcbot?has?joined?#IDC ^hi$ +900 +FMODE +#IDC +1649730748 ++bgg +afads!*@* +(IRC)?idcbot?has?joined?#IDC +^hi$ +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #IDC mlock :ntCP +900 +METADATA +#IDC +mlock +ntCP +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #botwar 1682846956 +Cnt :o,000AAAAAC o,900AACI4F +900 +FJOIN +#botwar +1682846956 ++Cnt +o,000AAAAAC o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #botwar maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#botwar +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #botwar mlock :ntlk +900 +METADATA +#botwar +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #spam 1680483105 +Cnt :o,900AAAAAE ,900AACI4F +900 +FJOIN +#spam +1680483105 ++Cnt +o,900AAAAAE ,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #spam maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#spam +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #ykpao 1652768120 +CPint : +900 +FJOIN +#ykpao +1652768120 ++CPint + +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #ykpao 1670135244 Andrew :Economics +900 +FTOPIC +#ykpao +1670135244 +Andrew +Economics +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #ykpao maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#ykpao +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #ykpao 1652768120 +II *!*@ykpao/* *!*@LibreIRC/staff/Andrew +900 +FMODE +#ykpao +1652768120 ++II +*!*@ykpao/* +*!*@LibreIRC/staff/Andrew +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #ykpao mlock :nCP +900 +METADATA +#ykpao +mlock +nCP +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #libresociety 1680483105 +ACQnt :o,000AAAAAC o,900AAAAAE ,900AAAAAG ,900AACI4F +900 +FJOIN +#libresociety +1680483105 ++ACQnt +o,000AAAAAC o,900AAAAAE ,900AAAAAG ,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #libresociety 1647580917 Andrew :https://libre.andrewyu.org | Creating a free (mathematical?) society +900 +FTOPIC +#libresociety +1647580917 +Andrew +https://libre.andrewyu.org | Creating a free (mathematical?) society +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #libresociety maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#libresociety +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #libresociety mlock :ntAQ +900 +METADATA +#libresociety +mlock +ntAQ +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #libresociety topiclock :1 +900 +METADATA +#libresociety +topiclock +1 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #school 1680483105 +Cnt :o,900AAAAAE +900 +FJOIN +#school +1680483105 ++Cnt +o,900AAAAAE +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #school maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#school +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #AmongTest 1680483105 +Cnt :o,900AAAAAE o,900AAAAAG ,900AACI4F +900 +FJOIN +#AmongTest +1680483105 ++Cnt +o,900AAAAAE o,900AAAAAG ,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #AmongTest 1652589039 Andrew :Among Test (Among Us 'Clone') Development Channel | Minetest version is at mt.andrewyu.org 30000 | PyGame 2D version is inside a Additive Reconstructer +900 +FTOPIC +#AmongTest +1652589039 +Andrew +Among Test (Among Us 'Clone') Development Channel | Minetest version is at mt.andrewyu.org 30000 | PyGame 2D version is inside a Additive Reconstructer +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #AmongTest maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#AmongTest +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #AmongTest mlock :ntlk +900 +METADATA +#AmongTest +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #:\ 1664085102 +CPinpst : +900 +FJOIN +#:\ +1664085102 ++CPinpst + +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #:\ 1664732287 ay!guy@LibreIRC/staff/Andrew :WebView2, basically Microsoft Edge with a chromium engine wrapped around native APIs +900 +FTOPIC +#:\ +1664732287 +ay!guy@LibreIRC/staff/Andrew +WebView2, basically Microsoft Edge with a chromium engine wrapped around native APIs +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #:\ maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#:\ +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #LibreIDC 1680483109 +Cnt :o,900AAAAAG ,900AACI4F +900 +FJOIN +#LibreIDC +1680483109 ++Cnt +o,900AAAAAG ,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #LibreIDC maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#LibreIDC +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #os 1680483109 +Cnt :,900AACQ8I o,000AAAAAC ,900AACI4F o,900AACQDP ,900AAAAAM +900 +FJOIN +#os +1680483109 ++Cnt +,900AACQ8I o,000AAAAAC ,900AACI4F o,900AACQDP ,900AAAAAM +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #os 1654274851 Andrew :Operating System Development | https://github.com/cfenollosa/os-tutorial | Better tutorial at https://segmentfault.com/a/1190000040124650 but you can't understand it | http://www.jamesmolloy.co.uk/tutorial_html/ | http://www.mmix.cs.hm.edu/doc/fasc1.pdf | http://harmful.cat-v.org/software/operating-systems/os-suck +900 +FTOPIC +#os +1654274851 +Andrew +Operating System Development | https://github.com/cfenollosa/os-tutorial | Better tutorial at https://segmentfault.com/a/1190000040124650 but you can't understand it | http://www.jamesmolloy.co.uk/tutorial_html/ | http://www.mmix.cs.hm.edu/doc/fasc1.pdf | http://harmful.cat-v.org/software/operating-systems/os-suck +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #os maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#os +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #os mlock :ntlk +900 +METADATA +#os +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN # 1682846956 +Cnt :o,000AAAAAC o,900AACI4F +900 +FJOIN +# +1682846956 ++Cnt +o,000AAAAAC o,900AACI4F +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA # maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +# +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA # mlock :ntlk +900 +METADATA +# +mlock +ntlk +WARNING: Command is unknown, ignoring... + +Recvd: :900 FJOIN #evosaur-internal 1663661018 +CPint :qo,900AACQ8I ,900AAAAZV +900 +FJOIN +#evosaur-internal +1663661018 ++CPint +qo,900AACQ8I ,900AAAAZV +WARNING: Command is unknown, ignoring... + +Recvd: :900 FTOPIC #evosaur-internal 1661616956 Andrew :Internal Channel for Evosaur Developers +900 +FTOPIC +#evosaur-internal +1661616956 +Andrew +Internal Channel for Evosaur Developers +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #evosaur-internal maxlist :b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +900 +METADATA +#evosaur-internal +maxlist +b 1000 w 1000 e 1000 g 1000 X 1000 I 1000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 FMODE #evosaur-internal 1663661018 +II R:Andrew R:*!*@* +900 +FMODE +#evosaur-internal +1663661018 ++II +R:Andrew +R:*!*@* +WARNING: Command is unknown, ignoring... + +Recvd: :900 METADATA #evosaur-internal mlock :intCP +900 +METADATA +#evosaur-internal +mlock +intCP +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE E *@*.noisytoot.org Noisytoot 1649728931 0 : +900 +ADDLINE +E +*@*.noisytoot.org +Noisytoot +1649728931 +0 + +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE E *@/tmp/inspircd.sock Noisytoot 1655054525 0 :localhost +900 +ADDLINE +E +*@/tmp/inspircd.sock +Noisytoot +1655054525 +0 +localhost +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE E *@0::1 Noisytoot 1653750410 0 :localhost +900 +ADDLINE +E +*@0::1 +Noisytoot +1653750410 +0 +localhost +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE E *@2a02:c207:2078:7509::1 Noisytoot 1653748587 0 :andrewyu.org +900 +ADDLINE +E +*@2a02:c207:2078:7509::1 +Noisytoot +1653748587 +0 +andrewyu.org +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE E *@66.26.6.176 eggman 1658954211 0 :yes +900 +ADDLINE +E +*@66.26.6.176 +eggman +1658954211 +0 +yes +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE E *@82.17.135.195 Noisytoot 1658954293 0 : +900 +ADDLINE +E +*@82.17.135.195 +Noisytoot +1658954293 +0 + +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE Q #* Noisytoot 1668541568 0 :Channel names are not valid nicks. +900 +ADDLINE +Q +#* +Noisytoot +1668541568 +0 +Channel names are not valid nicks. +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE Q *S3rv TronaldDump 1657293178 0 :Impostor +900 +ADDLINE +Q +*S3rv +TronaldDump +1657293178 +0 +Impostor +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE Q *Serv Andrew_ 1649921657 0 :Nickname reserved for services +900 +ADDLINE +Q +*Serv +Andrew_ +1649921657 +0 +Nickname reserved for services +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE Q ? Andrew_ 1649850818 0 :Single letter nicknames are not allowed +900 +ADDLINE +Q +? +Andrew_ +1649850818 +0 +Single letter nicknames are not allowed +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE SHUN ReplIRC!*@* Noisytoot 1666714980 0 :Spam +900 +ADDLINE +SHUN +ReplIRC!*@* +Noisytoot +1666714980 +0 +Spam +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE Z 106.75.173.138 Noisytoot 1666367066 0 :Server link spam. Probably a port scanner. +900 +ADDLINE +Z +106.75.173.138 +Noisytoot +1666367066 +0 +Server link spam. Probably a port scanner. +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE Z 128.14.233.62 Noisytoot 1665533200 0 :Server link spam. Probably a port scanner. +900 +ADDLINE +Z +128.14.233.62 +Noisytoot +1665533200 +0 +Server link spam. Probably a port scanner. +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE Z 152.89.196.211 Noisytoot 1665788124 0 :Server link spam. Probably a port scanner. +900 +ADDLINE +Z +152.89.196.211 +Noisytoot +1665788124 +0 +Server link spam. Probably a port scanner. +WARNING: Command is unknown, ignoring... + +Recvd: :900 ADDLINE Z 80.85.85.235 Noisytoot 1665788097 0 :Port scanner. +900 +ADDLINE +Z +80.85.85.235 +Noisytoot +1665788097 +0 +Port scanner. +WARNING: Command is unknown, ignoring... + +Recvd: :900 ENDBURST +900 +ENDBURST +WARNING: Command is unknown, ignoring... + +Recvd: :000AAAAAJ PRIVMSG #LibreIRC-logs :OPER: HaxServ (hax.irc.andrewyu.org) +000AAAAAJ +PRIVMSG +#LibreIRC-logs +OPER: HaxServ (hax.irc.andrewyu.org) +WARNING: Command is unknown, ignoring... + +Recvd: :900 PRIVMSG #LibreIRC-logs :GLOBOPS: From services.irc.andrewyu.org: OPER: HaxServ (hax.irc.andrewyu.org) +900 +PRIVMSG +#LibreIRC-logs +GLOBOPS: From services.irc.andrewyu.org: OPER: HaxServ (hax.irc.andrewyu.org) +WARNING: Command is unknown, ignoring... + +Recvd: :000 SNONOTICE g :OPER: HaxServ (hax.irc.andrewyu.org) +000 +SNONOTICE +g +OPER: HaxServ (hax.irc.andrewyu.org) +WARNING: Command is unknown, ignoring... + +Recvd: :000AAAAAC FMODE #librespeech 1653494594 +o :1HC000000 +000AAAAAC +FMODE +#librespeech +1653494594 ++o +1HC000000 +WARNING: Command is unknown, ignoring... + +Recvd: :000AAAAAC FMODE #IDC 1649730748 +o :1HC000000 +000AAAAAC +FMODE +#IDC +1649730748 ++o +1HC000000 +WARNING: Command is unknown, ignoring... + +Recvd: :000AAAAAC FMODE #LibreIRC 1649353732 +o :1HC000000 +000AAAAAC +FMODE +#LibreIRC +1649353732 ++o +1HC000000 +WARNING: Command is unknown, ignoring... + +Recvd: :000 FJOIN #ykpao 1652768120 +CPint :o,000AAAAAC +000 +FJOIN +#ykpao +1652768120 ++CPint +o,000AAAAAC +WARNING: Command is unknown, ignoring... + +Recvd: :000AAAAAC FMODE #ykpao 1652768120 +o :1HC000000 +000AAAAAC +FMODE +#ykpao +1652768120 ++o +1HC000000 +WARNING: Command is unknown, ignoring... + +Recvd: :900 PRIVMSG #LibreIRC-logs :LINK: Received end of netburst from hax.irc.andrewyu.org (burst time: 198 msecs) +900 +PRIVMSG +#LibreIRC-logs +LINK: Received end of netburst from hax.irc.andrewyu.org (burst time: 198 msecs) +WARNING: Command is unknown, ignoring... + +Recvd: :000 PING 000 :1HC +000 +PING +000 +1HC + + +Recvd: :000 METADATA * saslmechlist :PLAIN,AUTHCOOKIE,EXTERNAL,ECDSA-NIST256P-CHALLENGE +000 +METADATA +* +saslmechlist +PLAIN,AUTHCOOKIE,EXTERNAL,ECDSA-NIST256P-CHALLENGE +WARNING: Command is unknown, ignoring... + diff --git a/table.c b/table.c new file mode 100644 index 0000000..f663139 --- /dev/null +++ b/table.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include + +#include "types.h" +#include "table.h" + +// currently going with a binary lookup... + +static inline int compare(struct string a, struct string b) { + size_t len; + if (a.len > b.len) + len = b.len; + else + len = a.len; + + int val = memcmp(a.data, b.data, len); + + if (val == 0 && a.len != b.len) + return 1; + else + return val; +} + +static inline uint64_t search(struct table tbl, struct string name, uint8_t *exists) { + if (tbl.len == 0) + return 0; + + size_t low = 0, high = tbl.len - 1; + + size_t mid = high/2; + + while (low != high) { + int val = compare(tbl.array[mid].name, name); + + if (val == 0) { + *exists = 1; + return mid; + } else if (val > 0) { + low = mid + 1; + if (mid > low) + break; + if (low > high) + low = high; + } else { + high = mid - 1; + if (mid < high) + break; + if (high < low) + high = low; + } + + mid = low + ((high-low)/2); + } + + int val = compare(tbl.array[mid].name, name); + if (val > 0) { + *exists = 0; + return mid+1; + } else if (val == 0) { + *exists = 1; + return mid; + } else { + *exists = 0; + return mid; + } +} + +int set_table_index(struct table *tbl, struct string name, void *ptr) { + uint8_t exists, err; + uint64_t index = search(*tbl, name, &exists); + + if (index == tbl->len) { + void *tmp = realloc(tbl->array, sizeof(*(tbl->array)) * (tbl->len+1)); + if (tmp == 0) + return 1; + + tbl->array = tmp; + + tbl->len++; + } else if (!exists) { + void *tmp = realloc(tbl->array, sizeof(*(tbl->array)) * (tbl->len+1)); + if (tmp == 0) + return 1; + + tbl->array = tmp; + + memmove(&(tbl->array[index+1]), &(tbl->array[index]), (tbl->len - index) * sizeof(*(tbl->array))); + tbl->len++; + } else { + tbl->array[index].ptr = ptr; + + return 0; // don't overwrite old allocated name + } + + char *data = malloc(name.len); + if (data == 0) + return 1; + + memcpy(data, name.data, name.len); + + tbl->array[index] = (struct table_index){{data, name.len}, ptr}; + + return 0; +} + +void * get_table_index(struct table tbl, struct string name) { + if (tbl.len == 0) + return 0; + + size_t low = 0, high = tbl.len - 1; + + size_t mid = high/2; + + while (low != high) { + int val = compare(tbl.array[mid].name, name); + if (val == 0) { + return tbl.array[mid].ptr; + } else if (val > 0) { + low = mid + 1; + if (mid > low) + return 0; + if (low > high) + low = high; + } else { + high = mid - 1; + if (mid < high) + return 0; + if (high < low) + high = low; + } + + mid = low + ((high-low)/2); + } + + if (compare(tbl.array[mid].name, name) == 0) + return tbl.array[mid].ptr; + else + return 0; +} + +void * remove_table_index(struct table *tbl, struct string name) { + uint8_t exists, err; + uint64_t index = search(*tbl, name, &exists); + + if (!exists) + return 0; + + void *ptr = tbl->array[index].ptr; + free(tbl->array[index].name.data); + + memmove(&(tbl->array[index]), &(tbl->array[index+1]), (tbl->len - index) * sizeof(*(tbl->array))); + tbl->len--; + + void *tmp = realloc(tbl->array, sizeof(*(tbl->array)) * tbl->len); + if (tmp) + tbl->array = tmp; + // else: realloc failed on shrinking... so now we have a table that's allocated a bit too big, not much of an issue + + return ptr; +} diff --git a/table.h b/table.h new file mode 100644 index 0000000..af37c7e --- /dev/null +++ b/table.h @@ -0,0 +1,17 @@ +#pragma once + +#include "types.h" + +struct table_index { + struct string name; + void *ptr; +}; + +struct table { + struct table_index *array; + size_t len; +}; + +extern int set_table_index(struct table *tbl, struct string name, void *ptr); +extern void * get_table_index(struct table tbl, struct string name); +extern void * remove_table_index(struct table *tbl, struct string name); // returns same as get_table_index diff --git a/tls.c b/tls.c new file mode 100644 index 0000000..aeb83fb --- /dev/null +++ b/tls.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + +#include "network.h" +#include "config.h" +#include "types.h" + +SSL *ssl; +SSL_CTX *ctx; +int fd; + +int connect_tls(void) { + // TODO: free used things on failure + + SSL_library_init(); + SSL_load_error_strings(); + + const SSL_METHOD *method = TLS_client_method(); + if (method == NULL) + return 1; + + ctx = SSL_CTX_new(method); + if (ctx == NULL) + return 2; + + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); + + int success = SSL_CTX_load_verify_locations(ctx, X509_get_default_cert_file(), NULL); + success |= SSL_CTX_load_verify_locations(ctx, NULL, X509_get_default_cert_dir()); + if (!success) + return 3; + + fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (fd == -1) + return 4; + + ssl = SSL_new(ctx); + if (ssl == NULL) + return 5; + + X509_VERIFY_PARAM *param = SSL_get0_param(ssl); + X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_WILDCARDS); + if (!X509_VERIFY_PARAM_set1_host(param, address.data, address.len)) + return 6; + + SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); + + struct sockaddr sockaddr; + resolve(address.data, port.data, &sockaddr); + int ret = connect(fd, &sockaddr, sizeof(sockaddr)); + if (ret != 0) + return 7; + + if (SSL_set_fd(ssl, fd) != 1) + return 8; + + ret = SSL_connect(ssl); + if (ret != 1) + return 9; + + return 0; +} diff --git a/tls.h b/tls.h new file mode 100644 index 0000000..d59ad00 --- /dev/null +++ b/tls.h @@ -0,0 +1,7 @@ +#include + +#define SEND(x) SSL_write(ssl, x.data, x.len) + +extern SSL *ssl; + +extern int connect_tls(void); diff --git a/types.h b/types.h new file mode 100644 index 0000000..0a7e592 --- /dev/null +++ b/types.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +struct string { + char *data; + size_t len; +}; + +#define STRING(x) (struct string){x, sizeof(x)-1} +#define WRITES(x, y) write(x, y.data, y.len); diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..fa97087 --- /dev/null +++ b/utils.c @@ -0,0 +1,38 @@ +#include + +#include "types.h" + +uint64_t str_to_unsigned(struct string str, uint8_t *err) { + if (str.len == 0) { + *err = 1; + return 0; + } + + uint64_t val = 0; + while (str.len > 0) { + switch(str.data[0]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + val *= 10; + val += str.data[0] - 0x30; + break; + default: + *err = 1; + return 0; + } + + str.data++; + str.len--; + } + + *err = 0; + return val; +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..8451ada --- /dev/null +++ b/utils.h @@ -0,0 +1,4 @@ +#include +#include "types.h" + +uint64_t str_to_unsigned(struct string str, uint8_t *err); -- cgit v1.2.3