diff options
Diffstat (limited to '')
-rw-r--r-- | .gitignore | 7 | ||||
-rwxr-xr-x | CoupServ.lua | 200 | ||||
-rw-r--r-- | Makefile | 33 | ||||
-rw-r--r-- | commands.c | 65 | ||||
-rw-r--r-- | commands.h | 14 | ||||
-rw-r--r-- | commands.lua | 363 | ||||
-rw-r--r-- | config.h | 17 | ||||
-rw-r--r-- | main.c | 189 | ||||
-rw-r--r-- | network.c | 463 | ||||
-rw-r--r-- | network.h | 39 | ||||
-rw-r--r-- | network.lua | 310 | ||||
-rw-r--r-- | stdin.lua | 132 | ||||
-rw-r--r-- | stdout | 2049 | ||||
-rw-r--r-- | table.c | 163 | ||||
-rw-r--r-- | table.h | 17 | ||||
-rw-r--r-- | tls.c | 66 | ||||
-rw-r--r-- | tls.h | 7 | ||||
-rw-r--r-- | types.h | 12 | ||||
-rw-r--r-- | utils.c | 38 | ||||
-rw-r--r-- | utils.h | 4 |
20 files changed, 3179 insertions, 1009 deletions
@@ -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 <hax@andrewyu.org> - -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 <stdint.h> +#include <stdlib.h> + +#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 <stdint.h> + +#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 <hax@andrewyu.org> - -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 = "<target> <new nick>", - }, - - ["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 = "[<section>]", - }, - - ["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 = "<raw IRC message>", - }, - - ["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 = "<target> <count> <message>", - }, - - ["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 = "[<target>]", - }, - - ["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 = "[<nick>]", - }, - - ["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 = "<list>", - }, - - ["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 = "[<UID>]", - }, - - ["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 = "[<UID>]", - }, - - ["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 = "<server>", - }, - - ["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 = "<user>", - }, - - ["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 = "<user>", - }, - - ["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 = "<command>", - }, - - ["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 <stdint.h> + +#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; @@ -0,0 +1,189 @@ +#include <openssl/ssl.h> +#include <string.h> + +#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 <openssl/ssl.h> +#include <netdb.h> +#include <string.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <stdlib.h> +#include <stdio.h> + +#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 <netinet/in.h> + +#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 <hax@andrewyu.org> - -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 <hax@andrewyu.org> - -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, -} @@ -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 <https://directory.fsf.org/wiki/Fases> -- latest POSIX specification <https://pubs.opengroup.org/onlinepubs/9699919799/> -- 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 <https://directory.fsf.org/wiki/Fases> -- latest POSIX specification <https://pubs.opengroup.org/onlinepubs/9699919799/> -- 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... + @@ -0,0 +1,163 @@ +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +#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; +} @@ -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 @@ -0,0 +1,66 @@ +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/x509v3.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <arpa/inet.h> + +#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; +} @@ -0,0 +1,7 @@ +#include <openssl/ssl.h> + +#define SEND(x) SSL_write(ssl, x.data, x.len) + +extern SSL *ssl; + +extern int connect_tls(void); @@ -0,0 +1,12 @@ +#pragma once + +#include <stddef.h> +#include <unistd.h> + +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); @@ -0,0 +1,38 @@ +#include <stdint.h> + +#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; +} @@ -0,0 +1,4 @@ +#include <stdint.h> +#include "types.h" + +uint64_t str_to_unsigned(struct string str, uint8_t *err); |