Merge hid IRCd from haven as xS

Given that this project already contains a Go binary,
it only makes sense to put the IRCds back together.
This commit is contained in:
Přemysl Eric Janouch 2022-09-26 12:26:49 +02:00
commit f891e5ca63
Signed by: p
GPG Key ID: A0420B94F92B9493
4 changed files with 3800 additions and 0 deletions

3529
xS/main.go Normal file

File diff suppressed because it is too large Load Diff

168
xS/main_test.go Normal file
View File

@ -0,0 +1,168 @@
//
// Copyright (c) 2015 - 2018, Přemysl Eric Janouch <p@janouch.name>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
package main
import (
"crypto/tls"
"net"
"os"
"reflect"
"syscall"
"testing"
)
func TestSplitString(t *testing.T) {
var splitStringTests = []struct {
s, delims string
ignoreEmpty bool
result []string
}{
{",a,,bc", ",", false, []string{"", "a", "", "bc"}},
{",a,,bc", ",", true, []string{"a", "bc"}},
{"a,;bc,", ",;", false, []string{"a", "", "bc", ""}},
{"a,;bc,", ",;", true, []string{"a", "bc"}},
{"", ",", false, []string{""}},
{"", ",", true, nil},
}
for i, d := range splitStringTests {
got := splitString(d.s, d.delims, d.ignoreEmpty)
if !reflect.DeepEqual(got, d.result) {
t.Errorf("case %d: %v should be %v\n", i, got, d.result)
}
}
}
func socketpair() (*os.File, *os.File, error) {
pair, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
if err != nil {
return nil, nil, err
}
// See go #24331, this makes 1.11 use the internal poller
// while there wasn't a way to achieve that before.
if err := syscall.SetNonblock(int(pair[0]), true); err != nil {
return nil, nil, err
}
if err := syscall.SetNonblock(int(pair[1]), true); err != nil {
return nil, nil, err
}
fa := os.NewFile(uintptr(pair[0]), "a")
if fa == nil {
return nil, nil, os.ErrInvalid
}
fb := os.NewFile(uintptr(pair[1]), "b")
if fb == nil {
fa.Close()
return nil, nil, os.ErrInvalid
}
return fa, fb, nil
}
func TestDetectTLS(t *testing.T) {
detectTLSFromFunc := func(t *testing.T, writer func(net.Conn)) bool {
// net.Pipe doesn't use file descriptors, we need a socketpair.
sockA, sockB, err := socketpair()
if err != nil {
t.Fatal(err)
}
defer sockA.Close()
defer sockB.Close()
fcB, err := net.FileConn(sockB)
if err != nil {
t.Fatal(err)
}
go writer(fcB)
fcA, err := net.FileConn(sockA)
if err != nil {
t.Fatal(err)
}
sc, err := fcA.(syscall.Conn).SyscallConn()
if err != nil {
t.Fatal(err)
}
return detectTLS(sc)
}
t.Run("SSL_2.0", func(t *testing.T) {
if !detectTLSFromFunc(t, func(fc net.Conn) {
// The obsolete, useless, unsupported SSL 2.0 record format.
_, _ = fc.Write([]byte{0x80, 0x01, 0x01})
}) {
t.Error("could not detect SSL")
}
})
t.Run("crypto_tls", func(t *testing.T) {
if !detectTLSFromFunc(t, func(fc net.Conn) {
conn := tls.Client(fc, &tls.Config{InsecureSkipVerify: true})
_ = conn.Handshake()
}) {
t.Error("could not detect TLS")
}
})
t.Run("text", func(t *testing.T) {
if detectTLSFromFunc(t, func(fc net.Conn) {
_, _ = fc.Write([]byte("ПРЕВЕД"))
}) {
t.Error("detected UTF-8 as TLS")
}
})
t.Run("EOF", func(t *testing.T) {
type connCloseWriter interface {
net.Conn
CloseWrite() error
}
if detectTLSFromFunc(t, func(fc net.Conn) {
_ = fc.(connCloseWriter).CloseWrite()
}) {
t.Error("detected EOF as TLS")
}
})
}
func TestIRC(t *testing.T) {
msg := ircParseMessage(
`@first=a\:\s\r\n\\;2nd :srv hi there :good m8 :how are you?`)
if !reflect.DeepEqual(msg.tags, map[string]string{
"first": "a; \r\n\\",
"2nd": "",
}) {
t.Error("tags parsed incorrectly")
}
if msg.nick != "srv" || msg.user != "" || msg.host != "" {
t.Error("server name parsed incorrectly")
}
if msg.command != "hi" {
t.Error("command name parsed incorrectly")
}
if !reflect.DeepEqual(msg.params,
[]string{"there", "good m8 :how are you?"}) {
t.Error("params parsed incorrectly")
}
if !ircEqual("[fag]^", "{FAG}~") {
t.Error("string case comparison not according to RFC 2812")
}
// TODO: More tests.
}

16
xS/xS-gen-replies.awk Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/awk -f
/^[0-9]+ *(ERR|RPL)_[A-Z]+ *".*"$/ {
match($0, /".*"/);
ids[$1] = $2;
texts[$2] = substr($0, RSTART, RLENGTH);
}
END {
print "package " ENVIRON["GOPACKAGE"] "\n\nconst ("
for (i in ids)
printf("\t%s = %s\n", ids[i], i)
print ")\n\nvar defaultReplies = map[int]string{"
for (i in ids)
print "\t" ids[i] ": " texts[ids[i]] ","
print "}"
}

87
xS/xS-replies Normal file
View File

@ -0,0 +1,87 @@
1 RPL_WELCOME ":Welcome to the Internet Relay Network %s!%s@%s"
2 RPL_YOURHOST ":Your host is %s, running version %s"
3 RPL_CREATED ":This server was created %s"
4 RPL_MYINFO "%s %s %s %s"
5 RPL_ISUPPORT "%s :are supported by this server"
211 RPL_STATSLINKINFO "%s %d %d %d %d %d %d"
212 RPL_STATSCOMMANDS "%s %d %d %d"
219 RPL_ENDOFSTATS "%c :End of STATS report"
221 RPL_UMODEIS "+%s"
242 RPL_STATSUPTIME ":Server Up %d days %d:%02d:%02d"
251 RPL_LUSERCLIENT ":There are %d users and %d services on %d servers"
252 RPL_LUSEROP "%d :operator(s) online"
253 RPL_LUSERUNKNOWN "%d :unknown connection(s)"
254 RPL_LUSERCHANNELS "%d :channels formed"
255 RPL_LUSERME ":I have %d clients and %d servers"
301 RPL_AWAY "%s :%s"
302 RPL_USERHOST ":%s"
303 RPL_ISON ":%s"
305 RPL_UNAWAY ":You are no longer marked as being away"
306 RPL_NOWAWAY ":You have been marked as being away"
311 RPL_WHOISUSER "%s %s %s * :%s"
312 RPL_WHOISSERVER "%s %s :%s"
313 RPL_WHOISOPERATOR "%s :is an IRC operator"
314 RPL_WHOWASUSER "%s %s %s * :%s"
315 RPL_ENDOFWHO "%s :End of WHO list"
317 RPL_WHOISIDLE "%s %d :seconds idle"
318 RPL_ENDOFWHOIS "%s :End of WHOIS list"
319 RPL_WHOISCHANNELS "%s :%s"
322 RPL_LIST "%s %d :%s"
323 RPL_LISTEND ":End of LIST"
324 RPL_CHANNELMODEIS "%s +%s"
329 RPL_CREATIONTIME "%s %d"
331 RPL_NOTOPIC "%s :No topic is set"
332 RPL_TOPIC "%s :%s"
333 RPL_TOPICWHOTIME "%s %s %d"
341 RPL_INVITING "%s %s"
346 RPL_INVITELIST "%s %s"
347 RPL_ENDOFINVITELIST "%s :End of channel invite list"
348 RPL_EXCEPTLIST "%s %s"
349 RPL_ENDOFEXCEPTLIST "%s :End of channel exception list"
351 RPL_VERSION "%s.%d %s :%s"
352 RPL_WHOREPLY "%s %s %s %s %s %s :%d %s"
353 RPL_NAMREPLY "%c %s :%s"
364 RPL_LINKS "%s %s :%d %s"
365 RPL_ENDOFLINKS "%s :End of LINKS list"
366 RPL_ENDOFNAMES "%s :End of NAMES list"
367 RPL_BANLIST "%s %s"
368 RPL_ENDOFBANLIST "%s :End of channel ban list"
369 RPL_ENDOFWHOWAS "%s :End of WHOWAS"
372 RPL_MOTD ":- %s"
375 RPL_MOTDSTART ":- %s Message of the day - "
376 RPL_ENDOFMOTD ":End of MOTD command"
391 RPL_TIME "%s :%s"
401 ERR_NOSUCHNICK "%s :No such nick/channel"
402 ERR_NOSUCHSERVER "%s :No such server"
403 ERR_NOSUCHCHANNEL "%s :No such channel"
404 ERR_CANNOTSENDTOCHAN "%s :Cannot send to channel"
406 ERR_WASNOSUCHNICK "%s :There was no such nickname"
409 ERR_NOORIGIN ":No origin specified"
410 ERR_INVALIDCAPCMD "%s :%s"
411 ERR_NORECIPIENT ":No recipient given (%s)"
412 ERR_NOTEXTTOSEND ":No text to send"
421 ERR_UNKNOWNCOMMAND "%s: Unknown command"
422 ERR_NOMOTD ":MOTD File is missing"
423 ERR_NOADMININFO "%s :No administrative info available"
431 ERR_NONICKNAMEGIVEN ":No nickname given"
432 ERR_ERRONEOUSNICKNAME "%s :Erroneous nickname"
433 ERR_NICKNAMEINUSE "%s :Nickname is already in use"
441 ERR_USERNOTINCHANNEL "%s %s :They aren't on that channel"
442 ERR_NOTONCHANNEL "%s :You're not on that channel"
443 ERR_USERONCHANNEL "%s %s :is already on channel"
445 ERR_SUMMONDISABLED ":SUMMON has been disabled"
446 ERR_USERSDISABLED ":USERS has been disabled"
451 ERR_NOTREGISTERED ":You have not registered"
461 ERR_NEEDMOREPARAMS "%s :Not enough parameters"
462 ERR_ALREADYREGISTERED ":Unauthorized command (already registered)"
467 ERR_KEYSET "%s :Channel key already set"
471 ERR_CHANNELISFULL "%s :Cannot join channel (+l)"
472 ERR_UNKNOWNMODE "%c :is unknown mode char to me for %s"
473 ERR_INVITEONLYCHAN "%s :Cannot join channel (+i)"
474 ERR_BANNEDFROMCHAN "%s :Cannot join channel (+b)"
475 ERR_BADCHANNELKEY "%s :Cannot join channel (+k)"
476 ERR_BADCHANMASK "%s :Bad Channel Mask"
481 ERR_NOPRIVILEGES ":Permission Denied- You're not an IRC operator"
482 ERR_CHANOPRIVSNEEDED "%s :You're not channel operator"
501 ERR_UMODEUNKNOWNFLAG ":Unknown MODE flag"
502 ERR_USERSDONTMATCH ":Cannot change mode for other users"