serverless-ircd 0.2.0 → 0.3.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/CHANGELOG.md +84 -0
- package/README.md +28 -19
- 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 +5 -1
- package/apps/cf-worker/wrangler.toml +41 -17
- package/apps/local-cli/package.json +1 -1
- package/apps/local-cli/src/config-loader.ts +1 -0
- package/apps/local-cli/src/main.ts +1 -1
- package/apps/local-cli/src/server.ts +28 -2
- package/apps/local-cli/tests/e2e.test.ts +52 -0
- package/docs/ADR-001-pure-reducers-and-effect-system.md +74 -0
- package/docs/ADR-002-location-of-authority.md +82 -0
- package/docs/ADR-003-durable-object-sharding.md +93 -0
- package/docs/ADR-004-dynamodb-schema.md +96 -0
- package/docs/ADR-005-wss-only-transport-v1.md +83 -0
- package/docs/ADR-006-sasl-mechanism-scope.md +86 -0
- package/docs/ADR-007-deterministic-ports.md +82 -0
- package/docs/ADR-008-monorepo-tooling.md +60 -0
- package/docs/AWS-Adapter-Architecture.md +6 -4
- package/docs/AWS-Deployment.md +86 -7
- package/docs/Cloudflare-Deployment-Guide.md +5 -5
- package/docs/Home.md +11 -1
- package/docs/Release-Process.md +9 -6
- package/package.json +14 -15
- package/packages/aws-adapter/package.json +1 -1
- package/packages/aws-adapter/src/account-store.ts +121 -0
- package/packages/aws-adapter/src/aws-runtime.ts +118 -30
- package/packages/aws-adapter/src/cdk-table-defs.ts +5 -1
- package/packages/aws-adapter/src/config-loader.ts +30 -0
- package/packages/aws-adapter/src/dynamo-account-store.ts +156 -0
- package/packages/aws-adapter/src/handlers/default.ts +8 -0
- package/packages/aws-adapter/src/handlers/disconnect.ts +27 -8
- package/packages/aws-adapter/src/handlers/index.ts +51 -6
- package/packages/aws-adapter/src/index.ts +7 -0
- package/packages/aws-adapter/tests/account-store-dynamo.test.ts +171 -0
- package/packages/aws-adapter/tests/account-store.test.ts +280 -0
- package/packages/aws-adapter/tests/config-loader.test.ts +55 -0
- package/packages/aws-adapter/tests/disconnect-fanout.test.ts +336 -0
- package/packages/aws-adapter/tests/handlers.test.ts +46 -0
- package/packages/cf-adapter/package.json +1 -1
- package/packages/cf-adapter/src/cf-runtime.ts +42 -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 +29 -0
- package/packages/cf-adapter/src/connection-do.ts +85 -0
- package/packages/cf-adapter/src/env.ts +27 -1
- package/packages/cf-adapter/src/index.ts +2 -1
- package/packages/cf-adapter/tests/cf-runtime.test.ts +91 -0
- package/packages/cf-adapter/tests/connection-do.test.ts +40 -0
- package/packages/cf-adapter/tests/worker/main.ts +2 -1
- package/packages/cf-adapter/tests/worker/stubs/channel-stub.ts +7 -1
- package/packages/cf-adapter/wrangler.test.toml +10 -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 +3 -2
- package/packages/irc-core/src/case-fold.ts +64 -0
- package/packages/irc-core/src/commands/index.ts +2 -0
- package/packages/irc-core/src/commands/invite.ts +6 -9
- 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/registration.ts +8 -7
- package/packages/irc-core/src/commands/tagmsg.ts +205 -0
- package/packages/irc-core/src/config.ts +26 -3
- package/packages/irc-core/src/index.ts +2 -0
- package/packages/irc-core/src/ports.ts +68 -4
- package/packages/irc-core/src/types.ts +22 -0
- package/packages/irc-core/tests/account-store.test.ts +88 -0
- package/packages/irc-core/tests/case-fold.test.ts +80 -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/registration.test.ts +106 -14
- package/packages/irc-core/tests/commands/tagmsg.test.ts +688 -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/config.test.ts +75 -0
- package/packages/irc-server/package.json +1 -1
- package/packages/irc-server/src/actor.ts +24 -0
- package/packages/irc-server/src/routing.ts +9 -0
- package/packages/irc-server/tests/actor.test.ts +220 -1
- package/packages/irc-server/tests/routing.test.ts +3 -0
- package/packages/irc-test-support/package.json +1 -1
- package/packages/irc-test-support/src/in-memory-harness.ts +5 -4
- package/pnpm-workspace.yaml +1 -0
- package/tools/seed-aws-accounts.ts +80 -0
- 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/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
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
package irc
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"strings"
|
|
5
|
-
"sync"
|
|
6
|
-
"time"
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
type State struct {
|
|
10
|
-
LocalPort int
|
|
11
|
-
RemotePort int
|
|
12
|
-
Username string
|
|
13
|
-
Nick string
|
|
14
|
-
RealName string
|
|
15
|
-
Password string
|
|
16
|
-
Account string
|
|
17
|
-
Modes map[string]string
|
|
18
|
-
|
|
19
|
-
channelsMutex sync.Mutex
|
|
20
|
-
Channels map[string]*StateChannel
|
|
21
|
-
ISupport *ISupport
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
type StateChannel struct {
|
|
25
|
-
Name string
|
|
26
|
-
Modes map[string]string
|
|
27
|
-
Joined time.Time
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
func NewState() *State {
|
|
31
|
-
return &State{
|
|
32
|
-
Channels: make(map[string]*StateChannel),
|
|
33
|
-
ISupport: &ISupport{
|
|
34
|
-
tokens: make(map[string]string),
|
|
35
|
-
},
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
func NewStateChannel(name string) *StateChannel {
|
|
40
|
-
return &StateChannel{
|
|
41
|
-
Name: name,
|
|
42
|
-
Modes: make(map[string]string),
|
|
43
|
-
Joined: time.Now(),
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
func (m *State) HasChannel(name string) (ok bool) {
|
|
48
|
-
m.channelsMutex.Lock()
|
|
49
|
-
_, ok = m.Channels[strings.ToLower(name)]
|
|
50
|
-
m.channelsMutex.Unlock()
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
func (m *State) GetChannel(name string) (channel *StateChannel) {
|
|
55
|
-
m.channelsMutex.Lock()
|
|
56
|
-
channel = m.Channels[strings.ToLower(name)]
|
|
57
|
-
m.channelsMutex.Unlock()
|
|
58
|
-
return
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
func (m *State) SetChannel(channel *StateChannel) {
|
|
62
|
-
m.channelsMutex.Lock()
|
|
63
|
-
m.Channels[strings.ToLower(channel.Name)] = channel
|
|
64
|
-
m.channelsMutex.Unlock()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
func (m *State) RemoveChannel(name string) {
|
|
68
|
-
m.channelsMutex.Lock()
|
|
69
|
-
delete(m.Channels, strings.ToLower(name))
|
|
70
|
-
m.channelsMutex.Unlock()
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
func (m *State) ClearChannels() {
|
|
74
|
-
m.channelsMutex.Lock()
|
|
75
|
-
for i := range m.Channels {
|
|
76
|
-
delete(m.Channels, i)
|
|
77
|
-
}
|
|
78
|
-
m.channelsMutex.Unlock()
|
|
79
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
package proxy
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"encoding/json"
|
|
5
|
-
"errors"
|
|
6
|
-
"io"
|
|
7
|
-
"net"
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
type KiwiProxyState int
|
|
11
|
-
|
|
12
|
-
const KiwiProxyStateClosed KiwiProxyState = 0
|
|
13
|
-
const KiwiProxyStateConnecting KiwiProxyState = 1
|
|
14
|
-
const KiwiProxyStateHandshaking KiwiProxyState = 2
|
|
15
|
-
const KiwiProxyStateConnected KiwiProxyState = 3
|
|
16
|
-
|
|
17
|
-
type ConnError struct {
|
|
18
|
-
Msg string
|
|
19
|
-
Type string
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
func (err *ConnError) Error() string {
|
|
23
|
-
return err.Msg
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
type KiwiProxyConnection struct {
|
|
27
|
-
Username string
|
|
28
|
-
ProxyInterface string
|
|
29
|
-
DestHost string
|
|
30
|
-
DestPort int
|
|
31
|
-
DestTLS bool
|
|
32
|
-
State KiwiProxyState
|
|
33
|
-
Conn *net.Conn
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
func MakeKiwiProxyConnection() *KiwiProxyConnection {
|
|
37
|
-
return &KiwiProxyConnection{
|
|
38
|
-
State: KiwiProxyStateClosed,
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
func (c *KiwiProxyConnection) Close() error {
|
|
43
|
-
if c.State == KiwiProxyStateClosed {
|
|
44
|
-
return errors.New("Connection already closed")
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return (*c.Conn).Close()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
func (c *KiwiProxyConnection) Dial(proxyServerAddr string) error {
|
|
51
|
-
if c.State != KiwiProxyStateClosed {
|
|
52
|
-
return errors.New("Connection in closed state")
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
c.State = KiwiProxyStateConnecting
|
|
56
|
-
|
|
57
|
-
conn, err := net.Dial("tcp", proxyServerAddr)
|
|
58
|
-
if err != nil {
|
|
59
|
-
return err
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
c.Conn = &conn
|
|
63
|
-
c.State = KiwiProxyStateHandshaking
|
|
64
|
-
|
|
65
|
-
meta, _ := json.Marshal(map[string]interface{}{
|
|
66
|
-
"username": c.Username,
|
|
67
|
-
"interface": c.ProxyInterface,
|
|
68
|
-
"host": c.DestHost,
|
|
69
|
-
"port": c.DestPort,
|
|
70
|
-
"ssl": c.DestTLS,
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
(*c.Conn).Write(append(meta, byte('\n')))
|
|
74
|
-
|
|
75
|
-
buf := make([]byte, 1024)
|
|
76
|
-
bufLen, readErr := (*c.Conn).Read(buf)
|
|
77
|
-
if readErr != nil {
|
|
78
|
-
(*c.Conn).Close()
|
|
79
|
-
c.State = KiwiProxyStateClosed
|
|
80
|
-
return readErr
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
response := string(buf)
|
|
84
|
-
if bufLen > 0 && response[0] == '1' {
|
|
85
|
-
c.State = KiwiProxyStateConnected
|
|
86
|
-
} else {
|
|
87
|
-
(*c.Conn).Close()
|
|
88
|
-
c.State = KiwiProxyStateClosed
|
|
89
|
-
|
|
90
|
-
if bufLen == 0 {
|
|
91
|
-
return errors.New("The proxy could not connect to the destination")
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
switch response[0] {
|
|
95
|
-
case '0':
|
|
96
|
-
return errors.New("The proxy could not connect to the destination")
|
|
97
|
-
case '2':
|
|
98
|
-
return &ConnError{Msg: "Connection reset", Type: "conn_reset"}
|
|
99
|
-
case '3':
|
|
100
|
-
return &ConnError{Msg: "Connection refused", Type: "conn_refused"}
|
|
101
|
-
case '4':
|
|
102
|
-
return &ConnError{Msg: "Host not found", Type: "not_found"}
|
|
103
|
-
case '5':
|
|
104
|
-
return &ConnError{Msg: "Connection timed out", Type: "conn_timeout"}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return nil
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
func (c *KiwiProxyConnection) Read(b []byte) (n int, err error) {
|
|
112
|
-
if c.State == KiwiProxyStateConnecting || c.State == KiwiProxyStateHandshaking {
|
|
113
|
-
return 0, nil
|
|
114
|
-
} else if c.State == KiwiProxyStateClosed {
|
|
115
|
-
return 0, io.EOF
|
|
116
|
-
} else {
|
|
117
|
-
return (*c.Conn).Read(b)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
func (c *KiwiProxyConnection) Write(b []byte) (n int, err error) {
|
|
122
|
-
if c.State == KiwiProxyStateConnecting || c.State == KiwiProxyStateHandshaking {
|
|
123
|
-
return 0, nil
|
|
124
|
-
} else if c.State == KiwiProxyStateClosed {
|
|
125
|
-
return 0, io.EOF
|
|
126
|
-
} else {
|
|
127
|
-
return (*c.Conn).Write(b)
|
|
128
|
-
}
|
|
129
|
-
}
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
package proxy
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"bufio"
|
|
5
|
-
"crypto/tls"
|
|
6
|
-
"encoding/json"
|
|
7
|
-
"fmt"
|
|
8
|
-
"io"
|
|
9
|
-
"log"
|
|
10
|
-
"net"
|
|
11
|
-
"strconv"
|
|
12
|
-
"sync"
|
|
13
|
-
"syscall"
|
|
14
|
-
"time"
|
|
15
|
-
|
|
16
|
-
"github.com/kiwiirc/webircgateway/pkg/identd"
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
const (
|
|
20
|
-
ResponseError = "0"
|
|
21
|
-
ResponseOK = "1"
|
|
22
|
-
ResponseReset = "2"
|
|
23
|
-
ResponseRefused = "3"
|
|
24
|
-
ResponseUnknownHost = "4"
|
|
25
|
-
ResponseTimeout = "5"
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
var identdRpc *identd.RpcClient
|
|
29
|
-
var Server net.Listener
|
|
30
|
-
|
|
31
|
-
type HandshakeMeta struct {
|
|
32
|
-
Host string `json:"host"`
|
|
33
|
-
Port int `json:"port"`
|
|
34
|
-
TLS bool `json:"ssl"`
|
|
35
|
-
Username string `json:"username"`
|
|
36
|
-
Interface string `json:"interface"`
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
func MakeClient(conn net.Conn) *Client {
|
|
40
|
-
return &Client{
|
|
41
|
-
Client: conn,
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
type Client struct {
|
|
46
|
-
Client net.Conn
|
|
47
|
-
Upstream net.Conn
|
|
48
|
-
UpstreamAddr *net.TCPAddr
|
|
49
|
-
Username string
|
|
50
|
-
BindAddr *net.TCPAddr
|
|
51
|
-
TLS bool
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
func (c *Client) Run() {
|
|
55
|
-
var err error
|
|
56
|
-
|
|
57
|
-
err = c.Handshake()
|
|
58
|
-
if err != nil {
|
|
59
|
-
log.Println(err.Error())
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
err = c.ConnectUpstream()
|
|
64
|
-
if err != nil {
|
|
65
|
-
log.Println(err.Error())
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
c.Pipe()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
func (c *Client) Handshake() error {
|
|
73
|
-
// Read the first line - it should be JSON
|
|
74
|
-
reader := bufio.NewReader(c.Client)
|
|
75
|
-
line, readErr := reader.ReadBytes('\n')
|
|
76
|
-
if readErr != nil {
|
|
77
|
-
return readErr
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
var meta = HandshakeMeta{
|
|
81
|
-
Username: "user",
|
|
82
|
-
Port: 6667,
|
|
83
|
-
Interface: "0.0.0.0",
|
|
84
|
-
}
|
|
85
|
-
unmarshalErr := json.Unmarshal(line, &meta)
|
|
86
|
-
if unmarshalErr != nil {
|
|
87
|
-
c.Client.Write([]byte(ResponseError))
|
|
88
|
-
return unmarshalErr
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if meta.Host == "" || meta.Port == 0 || meta.Username == "" || meta.Interface == "" {
|
|
92
|
-
c.Client.Write([]byte(ResponseError))
|
|
93
|
-
return fmt.Errorf("missing args")
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
c.Username = meta.Username
|
|
97
|
-
c.TLS = meta.TLS
|
|
98
|
-
|
|
99
|
-
bindAddr, bindAddrErr := net.ResolveTCPAddr("tcp", meta.Interface+":")
|
|
100
|
-
if bindAddrErr != nil {
|
|
101
|
-
c.Client.Write([]byte(ResponseError))
|
|
102
|
-
return fmt.Errorf("interface: " + bindAddrErr.Error())
|
|
103
|
-
}
|
|
104
|
-
c.BindAddr = bindAddr
|
|
105
|
-
|
|
106
|
-
hostStr := net.JoinHostPort(meta.Host, strconv.Itoa(meta.Port))
|
|
107
|
-
addr, addrErr := net.ResolveTCPAddr("tcp", hostStr)
|
|
108
|
-
if addrErr != nil {
|
|
109
|
-
c.Client.Write([]byte(ResponseUnknownHost))
|
|
110
|
-
return fmt.Errorf("remote host: " + addrErr.Error())
|
|
111
|
-
}
|
|
112
|
-
c.UpstreamAddr = addr
|
|
113
|
-
|
|
114
|
-
return nil
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
func (c *Client) ConnectUpstream() error {
|
|
118
|
-
dialer := &net.Dialer{}
|
|
119
|
-
dialer.LocalAddr = c.BindAddr
|
|
120
|
-
dialer.Timeout = time.Second * 10
|
|
121
|
-
|
|
122
|
-
conn, err := dialer.Dial("tcp", c.UpstreamAddr.String())
|
|
123
|
-
if err != nil {
|
|
124
|
-
response := ""
|
|
125
|
-
errType := typeOfErr(err)
|
|
126
|
-
switch errType {
|
|
127
|
-
case "timeout":
|
|
128
|
-
response = ResponseTimeout
|
|
129
|
-
case "unknown_host":
|
|
130
|
-
response = ResponseUnknownHost
|
|
131
|
-
case "refused":
|
|
132
|
-
response = ResponseRefused
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
c.Client.Write([]byte(response))
|
|
136
|
-
return err
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if identdRpc != nil {
|
|
140
|
-
lAddr, lPortStr, _ := net.SplitHostPort(conn.LocalAddr().String())
|
|
141
|
-
lPort, _ := strconv.Atoi(lPortStr)
|
|
142
|
-
identdRpc.AddIdent(lPort, c.UpstreamAddr.Port, c.Username, lAddr)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if c.TLS {
|
|
146
|
-
tlsConfig := &tls.Config{InsecureSkipVerify: true}
|
|
147
|
-
tlsConn := tls.Client(conn, tlsConfig)
|
|
148
|
-
err := tlsConn.Handshake()
|
|
149
|
-
if err != nil {
|
|
150
|
-
conn.Close()
|
|
151
|
-
c.Client.Write([]byte(ResponseReset))
|
|
152
|
-
return err
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
conn = net.Conn(tlsConn)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
c.Upstream = conn
|
|
159
|
-
c.Client.Write([]byte(ResponseOK))
|
|
160
|
-
return nil
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
func (c *Client) Pipe() {
|
|
164
|
-
wg := sync.WaitGroup{}
|
|
165
|
-
wg.Add(2)
|
|
166
|
-
|
|
167
|
-
go func() {
|
|
168
|
-
io.Copy(c.Client, c.Upstream)
|
|
169
|
-
c.Client.Close()
|
|
170
|
-
wg.Done()
|
|
171
|
-
}()
|
|
172
|
-
|
|
173
|
-
go func() {
|
|
174
|
-
io.Copy(c.Upstream, c.Client)
|
|
175
|
-
c.Upstream.Close()
|
|
176
|
-
wg.Done()
|
|
177
|
-
}()
|
|
178
|
-
|
|
179
|
-
wg.Wait()
|
|
180
|
-
|
|
181
|
-
if identdRpc != nil {
|
|
182
|
-
lAddr, lPortStr, _ := net.SplitHostPort(c.Upstream.LocalAddr().String())
|
|
183
|
-
lPort, _ := strconv.Atoi(lPortStr)
|
|
184
|
-
identdRpc.RemoveIdent(lPort, c.UpstreamAddr.Port, c.Username, lAddr)
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
func Start(laddr string) {
|
|
189
|
-
srv, err := net.Listen("tcp", laddr)
|
|
190
|
-
if err != nil {
|
|
191
|
-
log.Fatal(err.Error())
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Expose the server
|
|
195
|
-
Server = srv
|
|
196
|
-
log.Printf("Kiwi proxy listening on %s", srv.Addr().String())
|
|
197
|
-
|
|
198
|
-
identdRpc = identd.MakeRpcClient("kiwiproxy" + laddr)
|
|
199
|
-
go identdRpc.ConnectAndReconnect("127.0.0.1:1133")
|
|
200
|
-
|
|
201
|
-
for {
|
|
202
|
-
conn, err := srv.Accept()
|
|
203
|
-
if err != nil {
|
|
204
|
-
log.Print(err.Error())
|
|
205
|
-
break
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
c := MakeClient(conn)
|
|
209
|
-
go c.Run()
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
func typeOfErr(err error) string {
|
|
214
|
-
if err == nil {
|
|
215
|
-
return ""
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if netError, ok := err.(net.Error); ok && netError.Timeout() {
|
|
219
|
-
return "timeout"
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
switch t := err.(type) {
|
|
223
|
-
case *net.OpError:
|
|
224
|
-
if t.Op == "dial" {
|
|
225
|
-
return "unknown_host"
|
|
226
|
-
} else if t.Op == "read" {
|
|
227
|
-
return "refused"
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
case syscall.Errno:
|
|
231
|
-
if t == syscall.ECONNREFUSED {
|
|
232
|
-
return "refused"
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return ""
|
|
237
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
// Google re-captcha package tweaked from http://github.com/haisum/recaptcha
|
|
2
|
-
|
|
3
|
-
package recaptcha
|
|
4
|
-
|
|
5
|
-
import (
|
|
6
|
-
"encoding/json"
|
|
7
|
-
"io/ioutil"
|
|
8
|
-
"net/http"
|
|
9
|
-
"net/url"
|
|
10
|
-
"time"
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
// R type represents an object of Recaptcha and has public property Secret,
|
|
14
|
-
// which is secret obtained from google recaptcha tool admin interface
|
|
15
|
-
type R struct {
|
|
16
|
-
URL string
|
|
17
|
-
Secret string
|
|
18
|
-
lastError []string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Struct for parsing json in google's response
|
|
22
|
-
type googleResponse struct {
|
|
23
|
-
Success bool
|
|
24
|
-
ErrorCodes []string `json:"error-codes"`
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// VerifyResponse is a method similar to `Verify`; but doesn't parse the form for you. Useful if
|
|
28
|
-
// you're receiving the data as a JSON object from a javascript app or similar.
|
|
29
|
-
func (r *R) VerifyResponse(response string) bool {
|
|
30
|
-
r.lastError = make([]string, 1)
|
|
31
|
-
client := &http.Client{Timeout: 20 * time.Second}
|
|
32
|
-
resp, err := client.PostForm(r.URL,
|
|
33
|
-
url.Values{"secret": {r.Secret}, "response": {response}})
|
|
34
|
-
if err != nil {
|
|
35
|
-
r.lastError = append(r.lastError, err.Error())
|
|
36
|
-
return false
|
|
37
|
-
}
|
|
38
|
-
defer resp.Body.Close()
|
|
39
|
-
body, err := ioutil.ReadAll(resp.Body)
|
|
40
|
-
if err != nil {
|
|
41
|
-
r.lastError = append(r.lastError, err.Error())
|
|
42
|
-
return false
|
|
43
|
-
}
|
|
44
|
-
gr := new(googleResponse)
|
|
45
|
-
err = json.Unmarshal(body, gr)
|
|
46
|
-
if err != nil {
|
|
47
|
-
r.lastError = append(r.lastError, err.Error())
|
|
48
|
-
return false
|
|
49
|
-
}
|
|
50
|
-
if !gr.Success {
|
|
51
|
-
r.lastError = append(r.lastError, gr.ErrorCodes...)
|
|
52
|
-
}
|
|
53
|
-
return gr.Success
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// LastError returns errors occurred in last re-captcha validation attempt
|
|
57
|
-
func (r R) LastError() []string {
|
|
58
|
-
return r.lastError
|
|
59
|
-
}
|