瀏覽代碼

fix #414

tags/v2.4.0-rc1
Shivaram Lingamneni 3 年之前
父節點
當前提交
1a9f501383
共有 7 個文件被更改,包括 32 次插入15 次删除
  1. 3
    2
      irc/accounts.go
  2. 15
    3
      irc/authscript.go
  3. 3
    1
      irc/client.go
  4. 1
    0
      irc/gateways.go
  5. 1
    1
      irc/handlers.go
  6. 1
    1
      irc/nickserv.go
  7. 8
    7
      irc/utils/crypto.go

+ 3
- 2
irc/accounts.go 查看文件

@@ -5,6 +5,7 @@ package irc
5 5
 
6 6
 import (
7 7
 	"bytes"
8
+	"crypto/x509"
8 9
 	"encoding/json"
9 10
 	"fmt"
10 11
 	"sort"
@@ -1466,7 +1467,7 @@ func (am *AccountManager) ChannelsForAccount(account string) (channels []string)
1466 1467
 	return unmarshalRegisteredChannels(channelStr)
1467 1468
 }
1468 1469
 
1469
-func (am *AccountManager) AuthenticateByCertFP(client *Client, certfp, authzid string) (err error) {
1470
+func (am *AccountManager) AuthenticateByCertificate(client *Client, certfp string, peerCerts []*x509.Certificate, authzid string) (err error) {
1470 1471
 	if certfp == "" {
1471 1472
 		return errAccountInvalidCredentials
1472 1473
 	}
@@ -1495,7 +1496,7 @@ func (am *AccountManager) AuthenticateByCertFP(client *Client, certfp, authzid s
1495 1496
 	if config.Accounts.AuthScript.Enabled {
1496 1497
 		var output AuthScriptOutput
1497 1498
 		output, err = CheckAuthScript(am.server.semaphores.AuthScript, config.Accounts.AuthScript.ScriptConfig,
1498
-			AuthScriptInput{Certfp: certfp, IP: client.IP().String()})
1499
+			AuthScriptInput{Certfp: certfp, IP: client.IP().String(), peerCerts: peerCerts})
1499 1500
 		if err != nil {
1500 1501
 			am.server.logger.Error("internal", "failed shell auth invocation", err.Error())
1501 1502
 		} else if output.Success && output.AccountName != "" {

+ 15
- 3
irc/authscript.go 查看文件

@@ -4,7 +4,9 @@
4 4
 package irc
5 5
 
6 6
 import (
7
+	"crypto/x509"
7 8
 	"encoding/json"
9
+	"encoding/pem"
8 10
 	"fmt"
9 11
 	"net"
10 12
 
@@ -13,9 +15,11 @@ import (
13 15
 
14 16
 // JSON-serializable input and output types for the script
15 17
 type AuthScriptInput struct {
16
-	AccountName string `json:"accountName,omitempty"`
17
-	Passphrase  string `json:"passphrase,omitempty"`
18
-	Certfp      string `json:"certfp,omitempty"`
18
+	AccountName string   `json:"accountName,omitempty"`
19
+	Passphrase  string   `json:"passphrase,omitempty"`
20
+	Certfp      string   `json:"certfp,omitempty"`
21
+	PeerCerts   []string `json:"peerCerts,omitempty"`
22
+	peerCerts   []*x509.Certificate
19 23
 	IP          string `json:"ip,omitempty"`
20 24
 }
21 25
 
@@ -31,6 +35,14 @@ func CheckAuthScript(sem utils.Semaphore, config ScriptConfig, input AuthScriptI
31 35
 		defer sem.Release()
32 36
 	}
33 37
 
38
+	// PEM-encode the peer certificates before applying JSON
39
+	if len(input.peerCerts) != 0 {
40
+		input.PeerCerts = make([]string, len(input.peerCerts))
41
+		for i, cert := range input.peerCerts {
42
+			input.PeerCerts[i] = string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}))
43
+		}
44
+	}
45
+
34 46
 	inputBytes, err := json.Marshal(input)
35 47
 	if err != nil {
36 48
 		return

+ 3
- 1
irc/client.go 查看文件

@@ -6,6 +6,7 @@
6 6
 package irc
7 7
 
8 8
 import (
9
+	"crypto/x509"
9 10
 	"fmt"
10 11
 	"net"
11 12
 	"runtime/debug"
@@ -163,6 +164,7 @@ type Session struct {
163 164
 	destroyed            uint32
164 165
 
165 166
 	certfp     string
167
+	peerCerts  []*x509.Certificate
166 168
 	sasl       saslStatus
167 169
 	passStatus serverPassStatus
168 170
 
@@ -384,7 +386,7 @@ func (server *Server) RunClient(conn IRCConn) {
384 386
 
385 387
 	if wConn.Config.TLSConfig != nil {
386 388
 		// error is not useful to us here anyways so we can ignore it
387
-		session.certfp, _ = utils.GetCertFP(wConn.Conn, RegisterTimeout)
389
+		session.certfp, session.peerCerts, _ = utils.GetCertFP(wConn.Conn, RegisterTimeout)
388 390
 	}
389 391
 
390 392
 	if session.isTor {

+ 1
- 0
irc/gateways.go 查看文件

@@ -99,6 +99,7 @@ func (client *Client) ApplyProxiedIP(session *Session, proxiedIP net.IP, tls boo
99 99
 	// nickmask will be updated when the client completes registration
100 100
 	// set tls info
101 101
 	session.certfp = ""
102
+	session.peerCerts = nil
102 103
 	client.SetMode(modes.TLS, tls)
103 104
 
104 105
 	return nil, ""

+ 1
- 1
irc/handlers.go 查看文件

@@ -303,7 +303,7 @@ func authExternalHandler(server *Server, client *Client, mechanism string, value
303 303
 				rb.session.deviceID = deviceID
304 304
 			}
305 305
 		}
306
-		err = server.accounts.AuthenticateByCertFP(client, rb.session.certfp, authzid)
306
+		err = server.accounts.AuthenticateByCertificate(client, rb.session.certfp, rb.session.peerCerts, authzid)
307 307
 	}
308 308
 
309 309
 	if err != nil {

+ 1
- 1
irc/nickserv.go 查看文件

@@ -721,7 +721,7 @@ func nsIdentifyHandler(server *Server, client *Client, command string, params []
721 721
 
722 722
 	// try certfp
723 723
 	if !loginSuccessful && rb.session.certfp != "" {
724
-		err = server.accounts.AuthenticateByCertFP(client, rb.session.certfp, "")
724
+		err = server.accounts.AuthenticateByCertificate(client, rb.session.certfp, rb.session.peerCerts, "")
725 725
 		loginSuccessful = (err == nil)
726 726
 	}
727 727
 

+ 8
- 7
irc/utils/crypto.go 查看文件

@@ -8,6 +8,7 @@ import (
8 8
 	"crypto/sha256"
9 9
 	"crypto/subtle"
10 10
 	"crypto/tls"
11
+	"crypto/x509"
11 12
 	"encoding/base32"
12 13
 	"encoding/base64"
13 14
 	"encoding/hex"
@@ -92,10 +93,10 @@ func NormalizeCertfp(certfp string) (result string, err error) {
92 93
 	return
93 94
 }
94 95
 
95
-func GetCertFP(conn net.Conn, handshakeTimeout time.Duration) (result string, err error) {
96
+func GetCertFP(conn net.Conn, handshakeTimeout time.Duration) (fingerprint string, peerCerts []*x509.Certificate, err error) {
96 97
 	tlsConn, isTLS := conn.(*tls.Conn)
97 98
 	if !isTLS {
98
-		return "", ErrNotTLS
99
+		return "", nil, ErrNotTLS
99 100
 	}
100 101
 
101 102
 	// ensure handshake is performed
@@ -104,16 +105,16 @@ func GetCertFP(conn net.Conn, handshakeTimeout time.Duration) (result string, er
104 105
 	tlsConn.SetDeadline(time.Time{})
105 106
 
106 107
 	if err != nil {
107
-		return "", err
108
+		return "", nil, err
108 109
 	}
109 110
 
110
-	peerCerts := tlsConn.ConnectionState().PeerCertificates
111
+	peerCerts = tlsConn.ConnectionState().PeerCertificates
111 112
 	if len(peerCerts) < 1 {
112
-		return "", ErrNoPeerCerts
113
+		return "", nil, ErrNoPeerCerts
113 114
 	}
114 115
 
115 116
 	rawCert := sha256.Sum256(peerCerts[0].Raw)
116
-	fingerprint := hex.EncodeToString(rawCert[:])
117
+	fingerprint = hex.EncodeToString(rawCert[:])
117 118
 
118
-	return fingerprint, nil
119
+	return fingerprint, peerCerts, nil
119 120
 }

Loading…
取消
儲存