Basic implementation of certificate zones - only one authorised cert per zone.
This commit is contained in:
parent
5377c2941f
commit
a0dacf4bbd
3 changed files with 35 additions and 3 deletions
|
@ -20,6 +20,7 @@ type Config struct {
|
|||
MimeOverrides map[string]string
|
||||
CGIPaths []string
|
||||
SCGIPaths map[string]string
|
||||
CertificateZones map[string]string
|
||||
DirectorySort string
|
||||
DirectoryReverse bool
|
||||
DirectoryTitles bool
|
||||
|
|
11
dynamic.go
11
dynamic.go
|
@ -5,6 +5,7 @@ import (
|
|||
"context"
|
||||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"net"
|
||||
|
@ -145,13 +146,17 @@ func prepareGatewayVariables(config Config, URL *url.URL, conn net.Conn) map[str
|
|||
clientCerts := connState.PeerCertificates
|
||||
if len(clientCerts) > 0 {
|
||||
cert := clientCerts[0]
|
||||
fingerprint := sha256.Sum256(cert.Raw)
|
||||
vars["TLS_CLIENT_HASH"] = hex.EncodeToString(fingerprint[:])
|
||||
vars["TLS_CLIENT_HASH"] = getCertFingerprint(cert)
|
||||
vars["TLS_CLIENT_ISSUER"] = cert.Issuer.String()
|
||||
vars["TLS_CLIENT_ISSUER_CN"] = cert.Issuer.CommonName
|
||||
vars["TLS_CLIENT_SUBJECT"] = cert.Subject.String()
|
||||
vars["TLS_CLIENT_SUBJECT_CN"] = cert.Subject.CommonName
|
||||
}
|
||||
|
||||
return vars
|
||||
}
|
||||
|
||||
func getCertFingerprint(cert *x509.Certificate) string {
|
||||
hash := sha256.Sum256(cert.Raw)
|
||||
fingerprint := hex.EncodeToString(hash[:])
|
||||
return fingerprint
|
||||
}
|
||||
|
|
26
handler.go
26
handler.go
|
@ -92,6 +92,32 @@ func handleGeminiRequest(conn net.Conn, config Config, logEntries chan LogEntry)
|
|||
}
|
||||
}
|
||||
|
||||
// Check whether this URL is in a certificate zone
|
||||
authorised := true
|
||||
for zone, allowed_fingerprint := range config.CertificateZones {
|
||||
matched, err := regexp.Match(zone, []byte(URL.Path))
|
||||
if !matched || err != nil {
|
||||
continue
|
||||
}
|
||||
authorised = false
|
||||
for _, cert := range clientCerts {
|
||||
if getCertFingerprint(cert) == allowed_fingerprint {
|
||||
authorised = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !authorised {
|
||||
if len(clientCerts) > 0 {
|
||||
conn.Write([]byte("61 Provided certificate not authorised for this resource\r\n"))
|
||||
log.Status = 61
|
||||
} else {
|
||||
conn.Write([]byte("60 A pre-authorised certificate is required to access this resource\r\n"))
|
||||
log.Status = 60
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Check whether this URL is mapped to an SCGI app
|
||||
for scgi_url, scgi_socket := range config.SCGIPaths {
|
||||
matched, err := regexp.Match(scgi_url, []byte(URL.Path))
|
||||
|
|
Loading…
Add table
Reference in a new issue