serverless-ircd 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +2 -2
- package/.github/workflows/deploy-aws.yml +1 -3
- package/.github/workflows/deploy-cf-tcp.yml +87 -0
- package/.github/workflows/deploy-cf.yml +1 -1
- package/.node-version +1 -0
- package/.nvmrc +1 -0
- package/CHANGELOG.md +258 -18
- package/README.md +72 -30
- package/apps/aws-stack/README.md +2 -2
- package/apps/aws-stack/bin/aws.ts +7 -0
- package/apps/aws-stack/package.json +4 -4
- package/apps/aws-stack/src/aws-stack.ts +118 -6
- package/apps/aws-stack/tests/stack.test.ts +98 -3
- package/apps/cf-tcp-container/Dockerfile +69 -0
- package/apps/cf-tcp-container/package.json +34 -0
- package/apps/cf-tcp-container/src/config-loader.ts +145 -0
- package/apps/cf-tcp-container/src/container-do.ts +38 -0
- package/apps/cf-tcp-container/src/container-server.ts +363 -0
- package/apps/cf-tcp-container/src/main.ts +77 -0
- package/apps/cf-tcp-container/src/persistence.ts +144 -0
- package/apps/cf-tcp-container/src/worker.ts +41 -0
- package/apps/cf-tcp-container/terraform/provider.tf +24 -0
- package/apps/cf-tcp-container/terraform/spectrum.tf +81 -0
- package/apps/cf-tcp-container/tests/config-loader.test.ts +217 -0
- package/apps/cf-tcp-container/tests/container-server.test.ts +465 -0
- package/apps/cf-tcp-container/tests/persistence.test.ts +227 -0
- package/apps/cf-tcp-container/tests/tls-e2e.test.ts +275 -0
- package/apps/cf-tcp-container/tsconfig.build.json +17 -0
- package/apps/cf-tcp-container/tsconfig.test.json +15 -0
- package/apps/cf-tcp-container/vitest.config.ts +26 -0
- package/apps/cf-tcp-container/wrangler.toml +63 -0
- package/apps/cf-worker/package.json +1 -1
- package/apps/cf-worker/scripts/smoke.mjs +0 -0
- package/apps/cf-worker/src/worker.ts +8 -2
- package/apps/cf-worker/tests/smoke.test.ts +1 -0
- package/apps/cf-worker/wrangler.test.toml +11 -1
- package/apps/cf-worker/wrangler.toml +69 -19
- package/apps/local-cli/package.json +1 -1
- package/apps/local-cli/src/config-loader.ts +11 -0
- package/apps/local-cli/src/main.ts +1 -1
- package/apps/local-cli/src/server.ts +46 -3
- package/apps/local-cli/tests/e2e.test.ts +52 -0
- package/package.json +19 -16
- package/packages/aws-adapter/package.json +3 -3
- package/packages/aws-adapter/src/account-store.ts +121 -0
- package/packages/aws-adapter/src/admission.ts +74 -0
- package/packages/aws-adapter/src/aws-runtime.ts +124 -34
- package/packages/aws-adapter/src/cdk-table-defs.ts +5 -1
- package/packages/aws-adapter/src/config-loader.ts +62 -0
- package/packages/aws-adapter/src/dynamo-account-store.ts +95 -0
- package/packages/aws-adapter/src/handlers/connect.ts +64 -8
- package/packages/aws-adapter/src/handlers/default.ts +43 -2
- package/packages/aws-adapter/src/handlers/disconnect.ts +27 -8
- package/packages/aws-adapter/src/handlers/index.ts +120 -9
- package/packages/aws-adapter/src/handlers/nlb-stream.ts +481 -0
- package/packages/aws-adapter/src/handlers/ping-checker.ts +1 -1
- package/packages/aws-adapter/src/index.ts +13 -0
- package/packages/aws-adapter/tests/account-store-dynamo.test.ts +182 -0
- package/packages/aws-adapter/tests/account-store.test.ts +279 -0
- package/packages/aws-adapter/tests/admission.test.ts +70 -0
- package/packages/aws-adapter/tests/aws-harness.ts +13 -1
- package/packages/aws-adapter/tests/config-loader.test.ts +75 -0
- package/packages/aws-adapter/tests/connect.test.ts +78 -0
- package/packages/aws-adapter/tests/disconnect-fanout.test.ts +343 -0
- package/packages/aws-adapter/tests/gone-exception.test.ts +31 -26
- package/packages/aws-adapter/tests/handlers.test.ts +194 -47
- package/packages/aws-adapter/tests/nlb-stream.test.ts +478 -0
- package/packages/aws-adapter/tests/ping-checker.test.ts +34 -29
- package/packages/aws-adapter/tests/sweeper.test.ts +25 -18
- package/packages/aws-adapter/tests/transactions.test.ts +25 -20
- package/packages/cf-adapter/package.json +1 -1
- package/packages/cf-adapter/src/cf-runtime.ts +40 -22
- package/packages/cf-adapter/src/channel-do.ts +40 -1
- package/packages/cf-adapter/src/channel-registry-do.ts +58 -0
- package/packages/cf-adapter/src/config-loader.ts +62 -0
- package/packages/cf-adapter/src/connection-do.ts +181 -31
- package/packages/cf-adapter/src/d1-account-store.ts +198 -0
- package/packages/cf-adapter/src/env.ts +58 -8
- package/packages/cf-adapter/src/index.ts +11 -9
- package/packages/cf-adapter/tests/cf-harness.ts +11 -1
- package/packages/cf-adapter/tests/cf-integration.test.ts +2 -1
- package/packages/cf-adapter/tests/cf-runtime.test.ts +91 -0
- package/packages/cf-adapter/tests/config-loader.test.ts +22 -0
- package/packages/cf-adapter/tests/connection-do-channel-registration.test.ts +37 -0
- package/packages/cf-adapter/tests/connection-do-no-batching-reservation.test.ts +52 -0
- package/packages/cf-adapter/tests/connection-do-sasl-d1.test.ts +166 -0
- package/packages/cf-adapter/tests/connection-do.test.ts +40 -0
- package/packages/cf-adapter/tests/d1-account-store.test.ts +226 -0
- package/packages/cf-adapter/tests/raw-modules.d.ts +11 -0
- package/packages/cf-adapter/tests/worker/main.ts +9 -1
- package/packages/cf-adapter/tests/worker/stubs/channel-stub.ts +7 -1
- package/packages/cf-adapter/wrangler.test.toml +18 -1
- package/packages/in-memory-runtime/package.json +1 -1
- package/packages/in-memory-runtime/src/in-memory-runtime.ts +14 -28
- package/packages/in-memory-runtime/tests/in-memory-runtime.test.ts +19 -0
- package/packages/irc-core/package.json +8 -2
- package/packages/irc-core/scripts/generate-build-info.mjs +31 -0
- package/packages/irc-core/src/caps/capabilities.ts +23 -2
- package/packages/irc-core/src/case-fold.ts +64 -0
- package/packages/irc-core/src/cloak.ts +1 -1
- package/packages/irc-core/src/commands/cap.ts +8 -1
- package/packages/irc-core/src/commands/index.ts +11 -0
- package/packages/irc-core/src/commands/invite.ts +6 -9
- package/packages/irc-core/src/commands/ison.ts +61 -0
- package/packages/irc-core/src/commands/isupport.ts +1 -1
- package/packages/irc-core/src/commands/join.ts +4 -3
- package/packages/irc-core/src/commands/kick.ts +4 -11
- package/packages/irc-core/src/commands/list.ts +5 -4
- package/packages/irc-core/src/commands/mode.ts +5 -9
- package/packages/irc-core/src/commands/motd-lines.ts +127 -0
- package/packages/irc-core/src/commands/motd.ts +6 -110
- package/packages/irc-core/src/commands/oper.ts +151 -0
- package/packages/irc-core/src/commands/quit.ts +12 -0
- package/packages/irc-core/src/commands/registration.ts +26 -19
- package/packages/irc-core/src/commands/sasl.ts +72 -9
- package/packages/irc-core/src/commands/server-info.ts +129 -0
- package/packages/irc-core/src/commands/tagmsg.ts +205 -0
- package/packages/irc-core/src/commands/userhost.ts +84 -0
- package/packages/irc-core/src/commands/whowas.ts +113 -0
- package/packages/irc-core/src/config.ts +84 -3
- package/packages/irc-core/src/credential-hashing.ts +124 -0
- package/packages/irc-core/src/effects.ts +6 -29
- package/packages/irc-core/src/index.ts +3 -0
- package/packages/irc-core/src/ports.ts +240 -7
- package/packages/irc-core/src/protocol/numerics.ts +14 -8
- package/packages/irc-core/src/types.ts +60 -1
- package/packages/irc-core/tests/account-store.test.ts +131 -0
- package/packages/irc-core/tests/caps/capabilities.test.ts +4 -3
- package/packages/irc-core/tests/case-fold.test.ts +80 -0
- package/packages/irc-core/tests/commands/cap.test.ts +33 -1
- package/packages/irc-core/tests/commands/ison.test.ts +166 -0
- package/packages/irc-core/tests/commands/kick.test.ts +15 -0
- package/packages/irc-core/tests/commands/oper.test.ts +257 -0
- package/packages/irc-core/tests/commands/quit.test.ts +69 -2
- package/packages/irc-core/tests/commands/registration.test.ts +256 -19
- package/packages/irc-core/tests/commands/sasl.test.ts +118 -10
- package/packages/irc-core/tests/commands/server-info.test.ts +274 -0
- package/packages/irc-core/tests/commands/tagmsg.test.ts +662 -0
- package/packages/irc-core/tests/commands/userhost.test.ts +264 -0
- package/packages/irc-core/tests/commands/who.test.ts +22 -4
- package/packages/irc-core/tests/commands/whois.test.ts +8 -1
- package/packages/irc-core/tests/commands/whowas.test.ts +312 -0
- package/packages/irc-core/tests/config.test.ts +170 -1
- package/packages/irc-core/tests/credential-hashing.test.ts +170 -0
- package/packages/irc-core/tests/effects.test.ts +0 -27
- package/packages/irc-core/tests/nick-history-store.test.ts +162 -0
- package/packages/irc-core/tests/numerics.test.ts +12 -0
- package/packages/irc-core/tests/types.test.ts +35 -1
- package/packages/irc-core/tsconfig.build.json +1 -1
- package/packages/irc-core/tsconfig.test.json +1 -1
- package/packages/irc-server/package.json +1 -1
- package/packages/irc-server/src/actor.ts +182 -14
- package/packages/irc-server/src/dispatch.ts +0 -3
- package/packages/irc-server/src/index.ts +10 -2
- package/packages/irc-server/src/routing.ts +21 -0
- package/packages/irc-server/src/transport.ts +101 -0
- package/packages/irc-server/tests/actor.test.ts +617 -1
- package/packages/irc-server/tests/dispatch.test.ts +0 -17
- package/packages/irc-server/tests/routing.test.ts +7 -0
- package/packages/irc-server/tests/transport.test.ts +230 -0
- package/packages/irc-test-support/package.json +1 -1
- package/packages/irc-test-support/src/harness.ts +44 -9
- package/packages/irc-test-support/src/in-memory-harness.ts +78 -13
- package/packages/irc-test-support/src/index.ts +3 -0
- package/packages/irc-test-support/src/scenarios.ts +132 -2
- package/packages/irc-test-support/tests/in-memory-harness.test.ts +2 -1
- package/packages/irc-test-support/tests/in-memory-scenarios.test.ts +23 -9
- package/pnpm-workspace.yaml +9 -0
- package/tools/ci-hardening/package.json +1 -1
- package/tools/package.json +4 -0
- package/tools/seed-aws-accounts.ts +79 -0
- package/tools/seed-cf-accounts.ts +104 -0
- package/tools/tcp-ws-forwarder/package.json +1 -1
- package/AGENTS.md +0 -5
- package/MOTD.txt +0 -3
- package/PLAN-FIXES.md +0 -358
- package/PLAN.md +0 -420
- package/dashboards/cloudwatch-irc.json +0 -139
- package/docs/AWS-Adapter-Architecture.md +0 -494
- package/docs/AWS-Deployment.md +0 -1107
- package/docs/Cloudflare-Deployment-Guide.md +0 -660
- package/docs/Home.md +0 -1
- package/docs/Observability.md +0 -87
- package/docs/PlanIRCv3Websocket.md +0 -489
- package/docs/PlanWebClient.md +0 -451
- package/docs/Release-Process.md +0 -440
- package/progress.md +0 -107
- package/tickets.md +0 -2485
- package/webircgateway/LICENSE +0 -201
- package/webircgateway/Makefile +0 -44
- package/webircgateway/README.md +0 -134
- package/webircgateway/config.conf.example +0 -135
- package/webircgateway/go.mod +0 -16
- package/webircgateway/go.sum +0 -89
- package/webircgateway/main.go +0 -118
- package/webircgateway/pkg/dnsbl/dnsbl.go +0 -121
- package/webircgateway/pkg/identd/identd.go +0 -86
- package/webircgateway/pkg/identd/rpcclient.go +0 -59
- package/webircgateway/pkg/irc/isupport.go +0 -56
- package/webircgateway/pkg/irc/message.go +0 -217
- package/webircgateway/pkg/irc/state.go +0 -79
- package/webircgateway/pkg/proxy/proxy.go +0 -129
- package/webircgateway/pkg/proxy/server.go +0 -237
- package/webircgateway/pkg/recaptcha/recaptcha.go +0 -59
- package/webircgateway/pkg/webircgateway/client.go +0 -741
- package/webircgateway/pkg/webircgateway/client_command_handlers.go +0 -495
- package/webircgateway/pkg/webircgateway/config.go +0 -385
- package/webircgateway/pkg/webircgateway/gateway.go +0 -278
- package/webircgateway/pkg/webircgateway/gateway_utils.go +0 -133
- package/webircgateway/pkg/webircgateway/hooks.go +0 -152
- package/webircgateway/pkg/webircgateway/letsencrypt.go +0 -41
- package/webircgateway/pkg/webircgateway/messagetags.go +0 -103
- package/webircgateway/pkg/webircgateway/transport_kiwiirc.go +0 -206
- package/webircgateway/pkg/webircgateway/transport_sockjs.go +0 -107
- package/webircgateway/pkg/webircgateway/transport_tcp.go +0 -113
- package/webircgateway/pkg/webircgateway/transport_websocket.go +0 -126
- package/webircgateway/pkg/webircgateway/utils.go +0 -147
- package/webircgateway/plugins/example/plugin.go +0 -11
- package/webircgateway/plugins/stats/plugin.go +0 -52
- package/webircgateway/staticcheck.conf +0 -1
- package/webircgateway/webircgateway.svg +0 -3
package/webircgateway/main.go
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
package main
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"flag"
|
|
5
|
-
"fmt"
|
|
6
|
-
"log"
|
|
7
|
-
"os"
|
|
8
|
-
"os/signal"
|
|
9
|
-
"plugin"
|
|
10
|
-
"sync"
|
|
11
|
-
"syscall"
|
|
12
|
-
|
|
13
|
-
"github.com/kiwiirc/webircgateway/pkg/webircgateway"
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
var VERSION = "1.1.0"
|
|
17
|
-
var GITCOMMIT = "-"
|
|
18
|
-
var BUILTWITHGO = "-"
|
|
19
|
-
|
|
20
|
-
func init() {
|
|
21
|
-
webircgateway.Version = VERSION
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
func main() {
|
|
25
|
-
printVersion := flag.Bool("version", false, "Print the version")
|
|
26
|
-
configFile := flag.String("config", "config.conf", "Config file location")
|
|
27
|
-
startSection := flag.String("run", "gateway", "What type of server to run")
|
|
28
|
-
flag.Parse()
|
|
29
|
-
|
|
30
|
-
if *printVersion {
|
|
31
|
-
fmt.Printf("Version: %s\n", webircgateway.Version)
|
|
32
|
-
fmt.Printf("Git commit: %s\n", GITCOMMIT)
|
|
33
|
-
fmt.Printf("Built with Go version: %s\n", BUILTWITHGO)
|
|
34
|
-
os.Exit(0)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if *startSection != "gateway" && *startSection != "proxy" {
|
|
38
|
-
fmt.Println("-run can either be 'gateway' or 'proxy'")
|
|
39
|
-
os.Exit(1)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
runGateway(*configFile, *startSection)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
func runGateway(configFile string, function string) {
|
|
46
|
-
gateway := webircgateway.NewGateway(function)
|
|
47
|
-
|
|
48
|
-
log.SetFlags(log.Flags() | log.Lmicroseconds)
|
|
49
|
-
|
|
50
|
-
// Print any webircgateway logout to STDOUT
|
|
51
|
-
go printLogOutput(gateway)
|
|
52
|
-
|
|
53
|
-
// Listen for process signals
|
|
54
|
-
go watchForSignals(gateway)
|
|
55
|
-
|
|
56
|
-
gateway.Config.SetConfigFile(configFile)
|
|
57
|
-
log.Printf("Using config %s", gateway.Config.CurrentConfigFile())
|
|
58
|
-
|
|
59
|
-
configErr := gateway.Config.Load()
|
|
60
|
-
if configErr != nil {
|
|
61
|
-
log.Printf("Config file error: %s", configErr.Error())
|
|
62
|
-
os.Exit(1)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
pluginsQuit := &sync.WaitGroup{}
|
|
66
|
-
loadPlugins(gateway, pluginsQuit)
|
|
67
|
-
|
|
68
|
-
gateway.Start()
|
|
69
|
-
|
|
70
|
-
pluginsQuit.Wait()
|
|
71
|
-
gateway.WaitClose()
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
func watchForSignals(gateway *webircgateway.Gateway) {
|
|
75
|
-
c := make(chan os.Signal, 1)
|
|
76
|
-
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT)
|
|
77
|
-
|
|
78
|
-
for {
|
|
79
|
-
switch sig := <-c; sig {
|
|
80
|
-
case syscall.SIGINT:
|
|
81
|
-
fmt.Println("Received SIGINT, shutting down webircgateway")
|
|
82
|
-
gateway.Close()
|
|
83
|
-
case syscall.SIGHUP:
|
|
84
|
-
fmt.Println("Recieved SIGHUP, reloading config file")
|
|
85
|
-
gateway.Config.Load()
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
func printLogOutput(gateway *webircgateway.Gateway) {
|
|
91
|
-
for {
|
|
92
|
-
line, _ := <-gateway.LogOutput
|
|
93
|
-
log.Println(line)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
func loadPlugins(gateway *webircgateway.Gateway, pluginsQuit *sync.WaitGroup) {
|
|
98
|
-
for _, pluginPath := range gateway.Config.Plugins {
|
|
99
|
-
pluginFullPath := gateway.Config.ResolvePath(pluginPath)
|
|
100
|
-
|
|
101
|
-
gateway.Log(2, "Loading plugin "+pluginFullPath)
|
|
102
|
-
p, err := plugin.Open(pluginFullPath)
|
|
103
|
-
if err != nil {
|
|
104
|
-
gateway.Log(3, "Error loading plugin: "+err.Error())
|
|
105
|
-
continue
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
startSymbol, err := p.Lookup("Start")
|
|
109
|
-
if err != nil {
|
|
110
|
-
gateway.Log(3, "Plugin does not export a Start function! (%s)", pluginFullPath)
|
|
111
|
-
continue
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
startFunc := startSymbol.(func(*webircgateway.Gateway, *sync.WaitGroup))
|
|
115
|
-
pluginsQuit.Add(1)
|
|
116
|
-
startFunc(gateway, pluginsQuit)
|
|
117
|
-
}
|
|
118
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
package dnsbl
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"encoding/hex"
|
|
5
|
-
"fmt"
|
|
6
|
-
"net"
|
|
7
|
-
"strings"
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
type ResultList struct {
|
|
11
|
-
Listed bool
|
|
12
|
-
Results []Result
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/*
|
|
16
|
-
Result holds the individual IP lookup results for each RBL search
|
|
17
|
-
*/
|
|
18
|
-
type Result struct {
|
|
19
|
-
// Blacklist is the DNSBL server that gave this result
|
|
20
|
-
Blacklist string
|
|
21
|
-
// Address is the IP address that was searched
|
|
22
|
-
Address string
|
|
23
|
-
// Listed indicates whether or not the IP was on the RBL
|
|
24
|
-
Listed bool
|
|
25
|
-
// RBL lists sometimes add extra information as a TXT record
|
|
26
|
-
// if any info is present, it will be stored here.
|
|
27
|
-
Text string
|
|
28
|
-
// Error represents any error that was encountered (DNS timeout, host not
|
|
29
|
-
// found, etc.) if any
|
|
30
|
-
Error bool
|
|
31
|
-
// ErrorType is the type of error encountered if any
|
|
32
|
-
ErrorType error
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/*
|
|
36
|
-
Convert an IP to a hostname ready for a dnsbl lookup
|
|
37
|
-
127.0.0.1 becomes 1.0.0.127
|
|
38
|
-
1234:1234:1234:1234:1234:1234:1234:1234 becomes 4.3.2.1.4.3.2.1.4.3.2.1.4.3.2.1.4.3.2.1.4.3.2.1.4.3.2.1.4.3.2.1
|
|
39
|
-
*/
|
|
40
|
-
func toDnsBlHostname(ip net.IP) string {
|
|
41
|
-
if ip.To4() != nil {
|
|
42
|
-
// IPv4
|
|
43
|
-
// Reverse the complete octects
|
|
44
|
-
splitAddress := strings.Split(ip.String(), ".")
|
|
45
|
-
for i, j := 0, len(splitAddress)-1; i < len(splitAddress)/2; i, j = i+1, j-1 {
|
|
46
|
-
splitAddress[i], splitAddress[j] = splitAddress[j], splitAddress[i]
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return strings.Join(splitAddress, ".")
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// IPv6
|
|
53
|
-
// Remove all : from a full expanded address, then reverse all the hex characters
|
|
54
|
-
ipv6Str := expandIPv6(ip)
|
|
55
|
-
addrHexStr := strings.ReplaceAll(ipv6Str, ":", "")
|
|
56
|
-
chars := []rune(addrHexStr)
|
|
57
|
-
for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
|
|
58
|
-
chars[i], chars[j] = chars[j], chars[i]
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return strings.Join(strings.Split(string(chars), ""), ".")
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
func expandIPv6(ip net.IP) string {
|
|
65
|
-
dst := make([]byte, hex.EncodedLen(len(ip)))
|
|
66
|
-
_ = hex.Encode(dst, ip)
|
|
67
|
-
return string(dst[0:4]) + ":" +
|
|
68
|
-
string(dst[4:8]) + ":" +
|
|
69
|
-
string(dst[8:12]) + ":" +
|
|
70
|
-
string(dst[12:16]) + ":" +
|
|
71
|
-
string(dst[16:20]) + ":" +
|
|
72
|
-
string(dst[20:24]) + ":" +
|
|
73
|
-
string(dst[24:28]) + ":" +
|
|
74
|
-
string(dst[28:])
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
func query(rbl string, host string, r *Result) {
|
|
78
|
-
r.Listed = false
|
|
79
|
-
|
|
80
|
-
lookup := fmt.Sprintf("%s.%s", host, rbl)
|
|
81
|
-
res, err := net.LookupHost(lookup)
|
|
82
|
-
|
|
83
|
-
if len(res) > 0 {
|
|
84
|
-
r.Listed = true
|
|
85
|
-
txt, _ := net.LookupTXT(lookup)
|
|
86
|
-
if len(txt) > 0 {
|
|
87
|
-
r.Text = txt[0]
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
if err != nil {
|
|
91
|
-
r.Error = true
|
|
92
|
-
r.ErrorType = err
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
func Lookup(dnsblList []string, targetHost string) (r ResultList) {
|
|
99
|
-
ip, err := net.LookupIP(targetHost)
|
|
100
|
-
if err != nil {
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
for _, dnsbl := range dnsblList {
|
|
105
|
-
for _, addr := range ip {
|
|
106
|
-
res := Result{}
|
|
107
|
-
res.Blacklist = dnsbl
|
|
108
|
-
res.Address = addr.String()
|
|
109
|
-
|
|
110
|
-
addr := toDnsBlHostname(addr)
|
|
111
|
-
query(dnsbl, addr, &res)
|
|
112
|
-
r.Results = append(r.Results, res)
|
|
113
|
-
|
|
114
|
-
if res.Listed {
|
|
115
|
-
r.Listed = true
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return
|
|
121
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
package identd
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"fmt"
|
|
5
|
-
"net"
|
|
6
|
-
"net/textproto"
|
|
7
|
-
"strings"
|
|
8
|
-
"sync"
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
// Server - An IdentD server
|
|
12
|
-
type Server struct {
|
|
13
|
-
Entries map[string]string
|
|
14
|
-
EntriesLock sync.Mutex
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// NewIdentdServer - Create a new IdentdServer instance
|
|
18
|
-
func NewIdentdServer() Server {
|
|
19
|
-
return Server{
|
|
20
|
-
Entries: make(map[string]string),
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// AddIdent - Add an ident to be looked up
|
|
25
|
-
func (i *Server) AddIdent(localPort, remotePort int, ident string, iface string) {
|
|
26
|
-
i.EntriesLock.Lock()
|
|
27
|
-
i.Entries[fmt.Sprintf("%d-%d", localPort, remotePort)] = ident
|
|
28
|
-
i.EntriesLock.Unlock()
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// RemoveIdent - Remove an ident from being looked up
|
|
32
|
-
func (i *Server) RemoveIdent(localPort, remotePort int, iface string) {
|
|
33
|
-
i.EntriesLock.Lock()
|
|
34
|
-
delete(i.Entries, fmt.Sprintf("%d-%d", localPort, remotePort))
|
|
35
|
-
i.EntriesLock.Unlock()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Run - Start listening for ident lookups
|
|
39
|
-
func (i *Server) Run() error {
|
|
40
|
-
serv, err := net.Listen("tcp", ":113")
|
|
41
|
-
if err != nil {
|
|
42
|
-
return err
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
go i.ListenForRequests(&serv)
|
|
46
|
-
return nil
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// ListenForRequests - Listen on a net.Listener for ident lookups
|
|
50
|
-
func (i *Server) ListenForRequests(serverSocket *net.Listener) {
|
|
51
|
-
for {
|
|
52
|
-
serv := *serverSocket
|
|
53
|
-
client, err := serv.Accept()
|
|
54
|
-
if err != nil {
|
|
55
|
-
break
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
go func(conn net.Conn) {
|
|
59
|
-
tc := textproto.NewConn(conn)
|
|
60
|
-
|
|
61
|
-
line, err := tc.ReadLine()
|
|
62
|
-
if err != nil {
|
|
63
|
-
conn.Close()
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Remove all spaces, some servers like to send "%d , %d" but the spec examples use "%d, %d"
|
|
68
|
-
line = strings.ReplaceAll(line, " ", "")
|
|
69
|
-
|
|
70
|
-
var localPort, remotePort int
|
|
71
|
-
fmt.Sscanf(line, "%d,%d", &localPort, &remotePort)
|
|
72
|
-
if localPort > 0 && remotePort > 0 {
|
|
73
|
-
i.EntriesLock.Lock()
|
|
74
|
-
ident, ok := i.Entries[fmt.Sprintf("%d-%d", localPort, remotePort)]
|
|
75
|
-
i.EntriesLock.Unlock()
|
|
76
|
-
if !ok {
|
|
77
|
-
fmt.Fprintf(conn, "%d, %d : ERROR : NO-USER\r\n", localPort, remotePort)
|
|
78
|
-
} else {
|
|
79
|
-
fmt.Fprintf(conn, "%d, %d : USERID : UNIX : %s\r\n", localPort, remotePort, ident)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
conn.Close()
|
|
84
|
-
}(client)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
package identd
|
|
2
|
-
|
|
3
|
-
import "net"
|
|
4
|
-
import "fmt"
|
|
5
|
-
import "time"
|
|
6
|
-
|
|
7
|
-
func MakeRpcClient(appName string) *RpcClient {
|
|
8
|
-
return &RpcClient{AppName: appName}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type RpcClient struct {
|
|
12
|
-
AppName string
|
|
13
|
-
Conn *net.Conn
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
func (rpc *RpcClient) ConnectAndReconnect(serverAddress string) {
|
|
17
|
-
for {
|
|
18
|
-
if rpc.Conn == nil {
|
|
19
|
-
println("Connecting to identd RPC...")
|
|
20
|
-
rpc.Connect(serverAddress)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
time.Sleep(time.Second * 3)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
func (rpc *RpcClient) Connect(serverAddress string) error {
|
|
28
|
-
conn, err := net.Dial("tcp", serverAddress)
|
|
29
|
-
if err != nil {
|
|
30
|
-
return err
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
rpc.Conn = &conn
|
|
34
|
-
rpc.Write("id " + rpc.AppName)
|
|
35
|
-
|
|
36
|
-
return nil
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
func (rpc *RpcClient) Write(line string) error {
|
|
40
|
-
if rpc.Conn == nil {
|
|
41
|
-
return fmt.Errorf("not connected")
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
conn := *rpc.Conn
|
|
45
|
-
_, err := conn.Write([]byte(line + "\n"))
|
|
46
|
-
if err != nil {
|
|
47
|
-
rpc.Conn = nil
|
|
48
|
-
conn.Close()
|
|
49
|
-
}
|
|
50
|
-
return err
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
func (rpc *RpcClient) AddIdent(lport int, rport int, username string, iface string) {
|
|
54
|
-
rpc.Write(fmt.Sprintf("add %s %d %d %s", username, lport, rport, iface))
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
func (rpc *RpcClient) RemoveIdent(lport int, rport int, username string, iface string) {
|
|
58
|
-
rpc.Write(fmt.Sprintf("del %d %d %s", lport, rport, iface))
|
|
59
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
package irc
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"strings"
|
|
5
|
-
"sync"
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
type ISupport struct {
|
|
9
|
-
Received bool
|
|
10
|
-
Injected bool
|
|
11
|
-
Tags map[string]string
|
|
12
|
-
tokens map[string]string
|
|
13
|
-
tokensMutex sync.RWMutex
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
func (m *ISupport) ClearTokens() {
|
|
17
|
-
m.tokensMutex.Lock()
|
|
18
|
-
m.tokens = make(map[string]string)
|
|
19
|
-
m.tokensMutex.Unlock()
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
func (m *ISupport) AddToken(tokenPair string) {
|
|
23
|
-
m.tokensMutex.Lock()
|
|
24
|
-
m.addToken(tokenPair)
|
|
25
|
-
m.tokensMutex.Unlock()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
func (m *ISupport) AddTokens(tokenPairs []string) {
|
|
29
|
-
m.tokensMutex.Lock()
|
|
30
|
-
for _, tp := range tokenPairs {
|
|
31
|
-
m.addToken(tp)
|
|
32
|
-
}
|
|
33
|
-
m.tokensMutex.Unlock()
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
func (m *ISupport) HasToken(key string) (ok bool) {
|
|
37
|
-
m.tokensMutex.RLock()
|
|
38
|
-
_, ok = m.tokens[strings.ToUpper(key)]
|
|
39
|
-
m.tokensMutex.RUnlock()
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
func (m *ISupport) GetToken(key string) (val string) {
|
|
44
|
-
m.tokensMutex.RLock()
|
|
45
|
-
val = m.tokens[strings.ToUpper(key)]
|
|
46
|
-
m.tokensMutex.RUnlock()
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
func (m *ISupport) addToken(tokenPair string) {
|
|
51
|
-
kv := strings.Split(tokenPair, "=")
|
|
52
|
-
if len(kv) == 1 {
|
|
53
|
-
kv = append(kv, "")
|
|
54
|
-
}
|
|
55
|
-
m.tokens[strings.ToUpper(kv[0])] = kv[1]
|
|
56
|
-
}
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
package irc
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"errors"
|
|
5
|
-
"strings"
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
type Mask struct {
|
|
9
|
-
Nick string
|
|
10
|
-
Username string
|
|
11
|
-
Hostname string
|
|
12
|
-
Mask string
|
|
13
|
-
}
|
|
14
|
-
type Message struct {
|
|
15
|
-
Raw string
|
|
16
|
-
Tags map[string]string
|
|
17
|
-
Prefix *Mask
|
|
18
|
-
Command string
|
|
19
|
-
Params []string
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
func NewMessage() *Message {
|
|
23
|
-
return &Message{
|
|
24
|
-
Tags: make(map[string]string),
|
|
25
|
-
Prefix: &Mask{},
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// GetParam - Get a param value, returning a default value if it doesn't exist
|
|
30
|
-
func (m *Message) GetParam(idx int, def string) string {
|
|
31
|
-
if idx < 0 || idx > len(m.Params)-1 {
|
|
32
|
-
return def
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return m.Params[idx]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// GetParamU - Get a param value in uppercase, returning a default value if it doesn't exist
|
|
39
|
-
func (m *Message) GetParamU(idx int, def string) string {
|
|
40
|
-
return strings.ToUpper(m.GetParam(idx, def))
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ToLine - Convert the Message struct to its raw IRC line
|
|
44
|
-
func (m *Message) ToLine() string {
|
|
45
|
-
line := ""
|
|
46
|
-
|
|
47
|
-
if len(m.Tags) > 0 {
|
|
48
|
-
line += "@"
|
|
49
|
-
tagCount := 0
|
|
50
|
-
for tagName, tagVal := range m.Tags {
|
|
51
|
-
tagCount++
|
|
52
|
-
line += tagName
|
|
53
|
-
if tagVal != "" {
|
|
54
|
-
line += "=" + tagVal
|
|
55
|
-
}
|
|
56
|
-
if tagCount < len(m.Tags) {
|
|
57
|
-
line += ";"
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if m.Prefix != nil && (m.Prefix.Nick != "" || m.Prefix.Username != "" || m.Prefix.Hostname != "") {
|
|
63
|
-
prefix := ""
|
|
64
|
-
|
|
65
|
-
if m.Prefix.Nick != "" {
|
|
66
|
-
prefix += m.Prefix.Nick
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if m.Prefix.Username != "" && m.Prefix.Nick != "" {
|
|
70
|
-
prefix += "!" + m.Prefix.Username
|
|
71
|
-
} else if m.Prefix.Username != "" {
|
|
72
|
-
prefix += m.Prefix.Username
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if m.Prefix.Hostname != "" && prefix != "" {
|
|
76
|
-
prefix += "@" + m.Prefix.Username
|
|
77
|
-
} else if m.Prefix.Hostname != "" {
|
|
78
|
-
prefix += m.Prefix.Hostname
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if line != "" {
|
|
82
|
-
line += " :" + prefix
|
|
83
|
-
} else {
|
|
84
|
-
line += ":" + prefix
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if line != "" {
|
|
89
|
-
line += " " + m.Command
|
|
90
|
-
} else {
|
|
91
|
-
line += m.Command
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
paramLen := len(m.Params)
|
|
95
|
-
for idx, param := range m.Params {
|
|
96
|
-
if idx == paramLen-1 && (strings.Contains(param, " ") || strings.HasPrefix(param, ":")) {
|
|
97
|
-
line += " :" + param
|
|
98
|
-
} else {
|
|
99
|
-
line += " " + param
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return line
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
func createMask(maskStr string) *Mask {
|
|
107
|
-
mask := &Mask{
|
|
108
|
-
Mask: maskStr,
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
usernameStart := strings.Index(maskStr, "!")
|
|
112
|
-
hostStart := strings.Index(maskStr, "@")
|
|
113
|
-
|
|
114
|
-
if usernameStart == -1 && hostStart == -1 {
|
|
115
|
-
mask.Nick = maskStr
|
|
116
|
-
} else if usernameStart > -1 && hostStart > -1 {
|
|
117
|
-
mask.Nick = maskStr[0:usernameStart]
|
|
118
|
-
mask.Username = maskStr[usernameStart+1 : hostStart]
|
|
119
|
-
mask.Hostname = maskStr[hostStart+1:]
|
|
120
|
-
} else if usernameStart > -1 && hostStart == -1 {
|
|
121
|
-
mask.Nick = maskStr[0:usernameStart]
|
|
122
|
-
mask.Username = maskStr[usernameStart+1:]
|
|
123
|
-
} else if usernameStart == -1 && hostStart > -1 {
|
|
124
|
-
mask.Username = maskStr[0:hostStart]
|
|
125
|
-
mask.Hostname = maskStr[hostStart+1:]
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return mask
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// ParseLine - Turn a raw IRC line into a message
|
|
132
|
-
func ParseLine(input string) (*Message, error) {
|
|
133
|
-
line := strings.Trim(input, "\r\n")
|
|
134
|
-
|
|
135
|
-
message := NewMessage()
|
|
136
|
-
message.Raw = line
|
|
137
|
-
|
|
138
|
-
token := ""
|
|
139
|
-
rest := ""
|
|
140
|
-
|
|
141
|
-
token, rest = nextToken(line, false)
|
|
142
|
-
if token == "" {
|
|
143
|
-
return message, errors.New("Empty line")
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Tags. Starts with "@"
|
|
147
|
-
if token[0] == 64 {
|
|
148
|
-
tagsRaw := token[1:]
|
|
149
|
-
tags := strings.Split(tagsRaw, ";")
|
|
150
|
-
for _, tag := range tags {
|
|
151
|
-
parts := strings.Split(tag, "=")
|
|
152
|
-
if len(parts) > 0 && parts[0] == "" {
|
|
153
|
-
continue
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if len(parts) == 1 {
|
|
157
|
-
message.Tags[parts[0]] = ""
|
|
158
|
-
} else {
|
|
159
|
-
message.Tags[parts[0]] = parts[1]
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
token, rest = nextToken(rest, false)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Prefix. Starts with ":"
|
|
167
|
-
if token != "" && token[0] == 58 {
|
|
168
|
-
message.Prefix = createMask(token[1:])
|
|
169
|
-
token, rest = nextToken(rest, false)
|
|
170
|
-
} else {
|
|
171
|
-
message.Prefix = createMask("")
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Command
|
|
175
|
-
if token == "" {
|
|
176
|
-
return message, errors.New("Missing command")
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
message.Command = token
|
|
180
|
-
|
|
181
|
-
// Params
|
|
182
|
-
for {
|
|
183
|
-
token, rest = nextToken(rest, true)
|
|
184
|
-
if token == "" {
|
|
185
|
-
break
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
message.Params = append(message.Params, token)
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return message, nil
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
func nextToken(s string, allowTrailing bool) (string, string) {
|
|
195
|
-
s = strings.TrimLeft(s, " ")
|
|
196
|
-
|
|
197
|
-
if len(s) == 0 {
|
|
198
|
-
return "", ""
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// The last token (trailing) start with :
|
|
202
|
-
if allowTrailing && s[0] == 58 {
|
|
203
|
-
return s[1:], ""
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
token := ""
|
|
207
|
-
spaceIdx := strings.Index(s, " ")
|
|
208
|
-
if spaceIdx > -1 {
|
|
209
|
-
token = s[:spaceIdx]
|
|
210
|
-
s = s[spaceIdx+1:]
|
|
211
|
-
} else {
|
|
212
|
-
token = s
|
|
213
|
-
s = ""
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return token, s
|
|
217
|
-
}
|