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
|
MimeOverrides map[string]string
|
||||||
CGIPaths []string
|
CGIPaths []string
|
||||||
SCGIPaths map[string]string
|
SCGIPaths map[string]string
|
||||||
|
CertificateZones map[string]string
|
||||||
DirectorySort string
|
DirectorySort string
|
||||||
DirectoryReverse bool
|
DirectoryReverse bool
|
||||||
DirectoryTitles bool
|
DirectoryTitles bool
|
||||||
|
|
11
dynamic.go
11
dynamic.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
@ -145,13 +146,17 @@ func prepareGatewayVariables(config Config, URL *url.URL, conn net.Conn) map[str
|
||||||
clientCerts := connState.PeerCertificates
|
clientCerts := connState.PeerCertificates
|
||||||
if len(clientCerts) > 0 {
|
if len(clientCerts) > 0 {
|
||||||
cert := clientCerts[0]
|
cert := clientCerts[0]
|
||||||
fingerprint := sha256.Sum256(cert.Raw)
|
vars["TLS_CLIENT_HASH"] = getCertFingerprint(cert)
|
||||||
vars["TLS_CLIENT_HASH"] = hex.EncodeToString(fingerprint[:])
|
|
||||||
vars["TLS_CLIENT_ISSUER"] = cert.Issuer.String()
|
vars["TLS_CLIENT_ISSUER"] = cert.Issuer.String()
|
||||||
vars["TLS_CLIENT_ISSUER_CN"] = cert.Issuer.CommonName
|
vars["TLS_CLIENT_ISSUER_CN"] = cert.Issuer.CommonName
|
||||||
vars["TLS_CLIENT_SUBJECT"] = cert.Subject.String()
|
vars["TLS_CLIENT_SUBJECT"] = cert.Subject.String()
|
||||||
vars["TLS_CLIENT_SUBJECT_CN"] = cert.Subject.CommonName
|
vars["TLS_CLIENT_SUBJECT_CN"] = cert.Subject.CommonName
|
||||||
}
|
}
|
||||||
|
|
||||||
return vars
|
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
|
// Check whether this URL is mapped to an SCGI app
|
||||||
for scgi_url, scgi_socket := range config.SCGIPaths {
|
for scgi_url, scgi_socket := range config.SCGIPaths {
|
||||||
matched, err := regexp.Match(scgi_url, []byte(URL.Path))
|
matched, err := regexp.Match(scgi_url, []byte(URL.Path))
|
||||||
|
|
Loading…
Add table
Reference in a new issue