Преглед на файлове

WEBIRC: Allow protecting with fingerprint and parse `tls` flag

tags/v0.10.0
Daniel Oaks преди 6 години
родител
ревизия
b0649cb5d3
променени са 4 файла, в които са добавени 68 реда и са изтрити 16 реда
  1. 1
    1
      irc/config.go
  2. 57
    13
      irc/gateways.go
  3. 7
    2
      irc/help.go
  4. 3
    0
      oragono.yaml

+ 1
- 1
irc/config.go Целия файл

@@ -402,7 +402,7 @@ func LoadConfig(filename string) (config *Config, err error) {
402 402
 			continue
403 403
 		}
404 404
 
405
-		err = webirc.ProcessPassword()
405
+		err = webirc.Populate()
406 406
 		if err != nil {
407 407
 			return nil, fmt.Errorf("Could not parse WebIRC config: %s", err.Error())
408 408
 		}

+ 57
- 13
irc/gateways.go Целия файл

@@ -6,8 +6,10 @@
6 6
 package irc
7 7
 
8 8
 import (
9
+	"errors"
9 10
 	"fmt"
10 11
 	"net"
12
+	"strings"
11 13
 
12 14
 	"github.com/oragono/oragono/irc/passwd"
13 15
 
@@ -18,23 +20,51 @@ import (
18 20
 type webircConfig struct {
19 21
 	PasswordString string `yaml:"password"`
20 22
 	Password       []byte `yaml:"password-bytes"`
23
+	Fingerprint    string
21 24
 	Hosts          []string
22 25
 }
23 26
 
24
-// ProcessPassword populates our password.
25
-func (wc *webircConfig) ProcessPassword() error {
26
-	password, error := passwd.DecodePasswordHash(wc.PasswordString)
27
-	wc.Password = password
28
-	return error
27
+// Populate fills out our password or fingerprint.
28
+func (wc *webircConfig) Populate() (err error) {
29
+	if wc.Fingerprint == "" && wc.PasswordString == "" {
30
+		return errors.New("Fingerprint or password needs to be specified")
31
+	}
32
+
33
+	if wc.PasswordString != "" {
34
+		var password []byte
35
+		password, err = passwd.DecodePasswordHash(wc.PasswordString)
36
+		wc.Password = password
37
+	}
38
+	return err
29 39
 }
30 40
 
31
-// WEBIRC password gateway hostname ip
41
+// WEBIRC <password> <gateway> <hostname> <ip> [:flag1 flag2=x flag3]
32 42
 func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
33 43
 	// only allow unregistered clients to use this command
34 44
 	if client.registered {
35 45
 		return false
36 46
 	}
37 47
 
48
+	// process flags
49
+	var secure bool
50
+	if 4 < len(msg.Params) {
51
+		for _, x := range strings.Split(msg.Params[4], " ") {
52
+			// split into key=value
53
+			var key string
54
+			if strings.Contains(x, "=") {
55
+				y := strings.SplitN(x, "=", 2)
56
+				key, _ = y[0], y[1]
57
+			} else {
58
+				key = x
59
+			}
60
+
61
+			// only accept "tls" flag if the gateway's connection to us is secure as well
62
+			if strings.ToLower(key) == "tls" && client.flags[TLS] {
63
+				secure = true
64
+			}
65
+		}
66
+	}
67
+
38 68
 	clientAddress := utils.IPString(client.socket.conn.RemoteAddr())
39 69
 	clientHostname := client.hostname
40 70
 	server.configurableStateMutex.RLock()
@@ -42,13 +72,17 @@ func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
42 72
 	for _, info := range server.webirc {
43 73
 		for _, address := range info.Hosts {
44 74
 			if clientHostname == address || clientAddress == address {
45
-				// confirm password
75
+				// confirm password and/or fingerprint
46 76
 				givenPassword := msg.Params[0]
47
-				if passwd.ComparePasswordString(info.Password, givenPassword) == nil {
48
-					proxiedIP := msg.Params[3]
49
-
50
-					return client.ApplyProxiedIP(proxiedIP)
77
+				if 0 < len(info.Password) && passwd.ComparePasswordString(info.Password, givenPassword) != nil {
78
+					continue
51 79
 				}
80
+				if 0 < len(info.Fingerprint) && client.certfp != info.Fingerprint {
81
+					continue
82
+				}
83
+
84
+				proxiedIP := msg.Params[3]
85
+				return client.ApplyProxiedIP(proxiedIP, secure)
52 86
 			}
53 87
 		}
54 88
 	}
@@ -73,7 +107,8 @@ func proxyHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
73 107
 		if clientHostname == address || clientAddress == address {
74 108
 			proxiedIP := msg.Params[1]
75 109
 
76
-			return client.ApplyProxiedIP(proxiedIP)
110
+			// assume PROXY connections are always secure
111
+			return client.ApplyProxiedIP(proxiedIP, true)
77 112
 		}
78 113
 	}
79 114
 	client.Quit("PROXY command is not usable from your address")
@@ -81,7 +116,7 @@ func proxyHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
81 116
 }
82 117
 
83 118
 // ApplyProxiedIP applies the given IP to the client.
84
-func (client *Client) ApplyProxiedIP(proxiedIP string) (exiting bool) {
119
+func (client *Client) ApplyProxiedIP(proxiedIP string, tls bool) (exiting bool) {
85 120
 	// ensure IP is sane
86 121
 	parsedProxiedIP := net.ParseIP(proxiedIP)
87 122
 	if parsedProxiedIP == nil {
@@ -99,5 +134,14 @@ func (client *Client) ApplyProxiedIP(proxiedIP string) (exiting bool) {
99 134
 	client.proxiedIP = proxiedIP
100 135
 	client.rawHostname = utils.LookupHostname(proxiedIP)
101 136
 	client.hostname = client.rawHostname
137
+
138
+	// set tls info
139
+	client.certfp = ""
140
+	if tls {
141
+		client.flags[TLS] = true
142
+	} else {
143
+		delete(client.flags, TLS)
144
+	}
145
+
102 146
 	return false
103 147
 }

+ 7
- 2
irc/help.go Целия файл

@@ -463,11 +463,16 @@ Views the version of software and the RPL_ISUPPORT tokens for the given server.`
463 463
 	},
464 464
 	"webirc": {
465 465
 		oper: true, // not really, but it's restricted anyways
466
-		text: `WEBIRC <password> <gateway> <hostname> <ip>
466
+		text: `WEBIRC <password> <gateway> <hostname> <ip> [:<flags>]
467 467
 
468 468
 Used by web<->IRC gateways and bouncers, the WEBIRC command allows gateways to
469 469
 pass-through the real IP addresses of clients:
470
-ircv3.net/specs/extensions/webirc.html`,
470
+ircv3.net/specs/extensions/webirc.html
471
+
472
+<flags> is a list of space-separated strings indicating various details about
473
+the connection from the client to the gateway, such as:
474
+
475
+- tls: this flag indicates that the client->gateway connection is secure`,
471 476
 	},
472 477
 	"who": {
473 478
 		text: `WHO <name> [o]

+ 3
- 0
oragono.yaml Целия файл

@@ -69,6 +69,9 @@ server:
69 69
     webirc:
70 70
         # one webirc block -- should correspond to one set of gateways
71 71
         -
72
+            # tls fingerprint the gateway must connect with to use this webirc block
73
+            fingerprint: 938dd33f4b76dcaf7ce5eb25c852369cb4b8fb47ba22fc235aa29c6623a5f182
74
+
72 75
             # password the gateway uses to connect, made with  oragono genpasswd
73 76
             password: JDJhJDA0JG9rTTVERlNRa0hpOEZpNkhjZE95SU9Da1BseFdlcWtOTEQxNEFERVlqbEZNTkdhOVlYUkMu
74 77
 

Loading…
Отказ
Запис