Pārlūkot izejas kodu

fix #696

tags/v2.0.0-rc1
Shivaram Lingamneni 4 gadus atpakaļ
vecāks
revīzija
e143aaa83f
7 mainītis faili ar 47 papildinājumiem un 6 dzēšanām
  1. 1
    1
      irc/commands.go
  2. 3
    0
      irc/config.go
  3. 7
    3
      irc/handlers.go
  4. 1
    1
      irc/help.go
  5. 13
    0
      irc/utils/crypto.go
  6. 18
    0
      irc/utils/crypto_test.go
  7. 4
    1
      oragono.yaml

+ 1
- 1
irc/commands.go Parādīt failu

@@ -206,7 +206,7 @@ func init() {
206 206
 		},
207 207
 		"OPER": {
208 208
 			handler:   operHandler,
209
-			minParams: 2,
209
+			minParams: 1,
210 210
 		},
211 211
 		"PART": {
212 212
 			handler:   partHandler,

+ 3
- 0
irc/config.go Parādīt failu

@@ -211,6 +211,7 @@ type OperConfig struct {
211 211
 	Vhost     string
212 212
 	WhoisLine string `yaml:"whois-line"`
213 213
 	Password  string
214
+	Certfp    string
214 215
 	Modes     string
215 216
 }
216 217
 
@@ -459,6 +460,7 @@ type Oper struct {
459 460
 	WhoisLine string
460 461
 	Vhost     string
461 462
 	Pass      []byte
463
+	Certfp    string
462 464
 	Modes     []modes.ModeChange
463 465
 }
464 466
 
@@ -479,6 +481,7 @@ func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error
479 481
 		if err != nil {
480 482
 			return nil, err
481 483
 		}
484
+		oper.Certfp = opConf.Certfp
482 485
 
483 486
 		oper.Vhost = opConf.Vhost
484 487
 		class, exists := oc[opConf.Class]

+ 7
- 3
irc/handlers.go Parādīt failu

@@ -2170,7 +2170,7 @@ func npcaHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
2170 2170
 	return false
2171 2171
 }
2172 2172
 
2173
-// OPER <name> <password>
2173
+// OPER <name> [password]
2174 2174
 func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2175 2175
 	if client.HasMode(modes.Operator) {
2176 2176
 		rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.Nick(), "OPER", client.t("You're already opered-up!"))
@@ -2180,8 +2180,12 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
2180 2180
 	authorized := false
2181 2181
 	oper := server.GetOperator(msg.Params[0])
2182 2182
 	if oper != nil {
2183
-		password := []byte(msg.Params[1])
2184
-		authorized = (bcrypt.CompareHashAndPassword(oper.Pass, password) == nil)
2183
+		if utils.CertfpsMatch(oper.Certfp, client.certfp) {
2184
+			authorized = true
2185
+		} else if 1 < len(msg.Params) {
2186
+			password := []byte(msg.Params[1])
2187
+			authorized = (bcrypt.CompareHashAndPassword(oper.Pass, password) == nil)
2188
+		}
2185 2189
 	}
2186 2190
 	if !authorized {
2187 2191
 		rb.Add(nil, server.name, ERR_PASSWDMISMATCH, client.Nick(), client.t("Password incorrect"))

+ 1
- 1
irc/help.go Parādīt failu

@@ -349,7 +349,7 @@ The NPC command is used to send an action to the target as the source.
349 349
 Requires the roleplay mode (+E) to be set on the target.`,
350 350
 	},
351 351
 	"oper": {
352
-		text: `OPER <name> <password>
352
+		text: `OPER <name> [password]
353 353
 
354 354
 If the correct details are given, gives you IRCop privs.`,
355 355
 	},

+ 13
- 0
irc/utils/crypto.go Parādīt failu

@@ -8,6 +8,7 @@ import (
8 8
 	"crypto/subtle"
9 9
 	"encoding/base32"
10 10
 	"encoding/base64"
11
+	"strings"
11 12
 )
12 13
 
13 14
 var (
@@ -68,3 +69,15 @@ func GenerateSecretKey() string {
68 69
 	rand.Read(buf[:])
69 70
 	return base64.RawURLEncoding.EncodeToString(buf[:])
70 71
 }
72
+
73
+func normalizeCertfp(certfp string) string {
74
+	return strings.ToLower(strings.Replace(certfp, ":", "", -1))
75
+}
76
+
77
+// Convenience to compare certfps as returned by different tools, e.g., openssl vs. oragono
78
+func CertfpsMatch(storedCertfp, suppliedCertfp string) bool {
79
+	if storedCertfp == "" {
80
+		return false
81
+	}
82
+	return normalizeCertfp(storedCertfp) == normalizeCertfp(suppliedCertfp)
83
+}

+ 18
- 0
irc/utils/crypto_test.go Parādīt failu

@@ -81,3 +81,21 @@ func BenchmarkMungeSecretToken(b *testing.B) {
81 81
 		t = MungeSecretToken(t)
82 82
 	}
83 83
 }
84
+
85
+func TestCertfpComparisons(t *testing.T) {
86
+	opensslFP := "3D:6B:11:BF:B4:05:C3:F8:4B:38:CD:30:38:FB:EC:01:71:D5:03:54:79:04:07:88:4C:A5:5D:23:41:85:66:C9"
87
+	oragonoFP := "3d6b11bfb405c3f84b38cd3038fbec0171d50354790407884ca55d23418566c9"
88
+	badFP := "3d6b11bfb405c3f84b38cd3038fbec0171d50354790407884ca55d23418566c8"
89
+	if !CertfpsMatch(opensslFP, oragonoFP) {
90
+		t.Error("these certs should match")
91
+	}
92
+	if !CertfpsMatch(oragonoFP, opensslFP) {
93
+		t.Error("these certs should match")
94
+	}
95
+	if CertfpsMatch("", "") {
96
+		t.Error("empty stored certfp should not match empty provided certfp")
97
+	}
98
+	if CertfpsMatch(opensslFP, badFP) {
99
+		t.Error("these certs should not match")
100
+	}
101
+}

+ 4
- 1
oragono.yaml Parādīt failu

@@ -121,7 +121,7 @@ server:
121 121
         # one webirc block -- should correspond to one set of gateways
122 122
         -
123 123
             # tls fingerprint the gateway must connect with to use this webirc block
124
-            fingerprint: 938dd33f4b76dcaf7ce5eb25c852369cb4b8fb47ba22fc235aa29c6623a5f182
124
+            fingerprint: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
125 125
 
126 126
             # password the gateway uses to connect, made with  oragono genpasswd
127 127
             password: "$2a$04$sLEFDpIOyUp55e6gTMKbOeroT6tMXTjPFvA0eGvwvImVR9pkwv7ee"
@@ -449,6 +449,9 @@ opers:
449 449
         # generated using  "oragono genpasswd"
450 450
         password: "$2a$04$LiytCxaY0lI.guDj2pBN4eLRD5cdM2OLDwqmGAgB6M2OPirbF5Jcu"
451 451
 
452
+        # being logged in with this client cert will let you /OPER without a password
453
+        certfp: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
454
+
452 455
 # logging, takes inspiration from Insp
453 456
 logging:
454 457
     -

Notiek ielāde…
Atcelt
Saglabāt