mirror of
https://tildegit.org/solderpunk/molly-brown.git
synced 2025-04-13 09:29:46 +00:00
Request client certificates, check validity dates of received certs and pass certs to handleCGI.
This commit is contained in:
parent
4e262d634a
commit
6f3887bdc4
2 changed files with 23 additions and 3 deletions
25
handler.go
25
handler.go
|
@ -3,8 +3,9 @@ package main
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"mime"
|
"mime"
|
||||||
|
@ -21,6 +22,7 @@ import (
|
||||||
|
|
||||||
func handleGeminiRequest(conn net.Conn, config Config, logEntries chan LogEntry) {
|
func handleGeminiRequest(conn net.Conn, config Config, logEntries chan LogEntry) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
var tlsConn (*tls.Conn) = conn.(*tls.Conn)
|
||||||
var log LogEntry
|
var log LogEntry
|
||||||
log.Time = time.Now()
|
log.Time = time.Now()
|
||||||
log.RemoteAddr = conn.RemoteAddr()
|
log.RemoteAddr = conn.RemoteAddr()
|
||||||
|
@ -41,6 +43,23 @@ func handleGeminiRequest(conn net.Conn, config Config, logEntries chan LogEntry)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientCerts := tlsConn.ConnectionState().PeerCertificates
|
||||||
|
// Check validity
|
||||||
|
// This will fail if any of multiple certs are invalid
|
||||||
|
// Maybe we should just require one valid?
|
||||||
|
now := time.Now()
|
||||||
|
for _, cert := range clientCerts {
|
||||||
|
if now.Before(cert.NotBefore) {
|
||||||
|
conn.Write([]byte("64 Client certificate not yet valid!\r\n"))
|
||||||
|
log.Status = 64
|
||||||
|
return
|
||||||
|
} else if now.After(cert.NotAfter) {
|
||||||
|
conn.Write([]byte("65 Client certificate has expired!\r\n"))
|
||||||
|
log.Status = 65
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parse request as URL
|
// Parse request as URL
|
||||||
URL, err := url.Parse(string(request))
|
URL, err := url.Parse(string(request))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -140,7 +159,7 @@ func handleGeminiRequest(conn net.Conn, config Config, logEntries chan LogEntry)
|
||||||
// If this file is executable, get dynamic content
|
// If this file is executable, get dynamic content
|
||||||
inCGIPath, err := regexp.Match(config.CGIPath, []byte(path))
|
inCGIPath, err := regexp.Match(config.CGIPath, []byte(path))
|
||||||
if inCGIPath && info.Mode().Perm() & 0111 == 0111 {
|
if inCGIPath && info.Mode().Perm() & 0111 == 0111 {
|
||||||
handleCGI(config, path, URL, log, conn)
|
handleCGI(config, path, URL, clientCerts, log, conn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +232,7 @@ func serveFile(path string, log LogEntry, conn net.Conn) {
|
||||||
conn.Write(contents)
|
conn.Write(contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCGI(config Config, path string, URL *url.URL, log LogEntry, conn net.Conn) {
|
func handleCGI(config Config, path string, URL *url.URL, clientCerts []*x509.Certificate, log LogEntry, conn net.Conn) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
cmd := exec.CommandContext(ctx, path)
|
cmd := exec.CommandContext(ctx, path)
|
||||||
|
|
1
main.go
1
main.go
|
@ -44,6 +44,7 @@ func main() {
|
||||||
tlscfg := &tls.Config{
|
tlscfg := &tls.Config{
|
||||||
Certificates: []tls.Certificate{cert},
|
Certificates: []tls.Certificate{cert},
|
||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
|
ClientAuth: tls.RequestClientCert,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create TLS listener
|
// Create TLS listener
|
||||||
|
|
Loading…
Add table
Reference in a new issue