/
tls.go
49 lines (42 loc) · 1.46 KB
/
tls.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package styxauth
import (
"crypto/tls"
"errors"
"aqwari.net/net/styx"
)
var (
errTLSConn = errors.New("not a TLS connection")
)
// TLSSubjectCN authenticates a client using the underyling tls
// connection. The client must provide a valid certificate with a
// common name that matches the username field in the authentication
// request. For more control over cert-based authentication, use the
// TLSAuth type.
var TLSSubjectCN = TLSAuth(checkSubjectCN)
// A TLSAuthFunc is called when validating an attach request based on
// the underlying TLS connection.
type TLSAuthFunc func(user, access string, state tls.ConnectionState) error
// TLSAuth returns a styx.AuthFunc value that authenticates a user based
// on the status of the underlying TLS connection. After validating
// the client certificate, the callback function is called with the
// connection state as a parameter. The callback must return nil if
// authentication succeeds, and a non-nil error otherwise.
func TLSAuth(fn TLSAuthFunc) styx.AuthFunc {
return func(rwc *styx.Channel, user, access string) error {
if tlsconn, ok := rwc.Conn().(*tls.Conn); ok {
return fn(user, access, tlsconn.ConnectionState())
}
return errTLSConn
}
}
func checkSubjectCN(user, access string, state tls.ConnectionState) error {
for _, chain := range state.VerifiedChains {
for _, cert := range chain {
if cert.Subject.CommonName == user {
return nil
}
return errAuthFailure
}
}
return errAuthFailure
}