blob: 9bf07bdf9ed8ead5aea148109664be8a19d52928 (
plain)
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
50
51
52
53
54
55
56
|
package tlsauth
import (
"context"
sr "tildegit.org/tjp/sliderule"
"tildegit.org/tjp/sliderule/gemini"
)
// GeminiAuth builds an authentication middleware from approval criteria.
//
// If a request does not contain a client certificate it will be rejected
// with a "60 certificate required" response. If the client identity does
// not pass the approver it will be rejected with "62 certificate invalid".
func GeminiAuth(approver Approver) sr.Middleware {
return func(inner sr.Handler) sr.Handler {
return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response {
if Identity(request) == nil {
return geminiMissingCert(ctx, request)
}
if !approver(ctx, request) {
return geminiCertNotAuthorized(ctx, request)
}
return inner.Handle(ctx, request)
})
}
}
// GeminiOptionalAuth builds auth middleware which doesn't require an identity.
//
// If there is no client certificate the request will pass through the middleware.
// It will only be rejected with "62 certificate invalid" if there *is* a client
// certificate, but it fails the approval.
func GeminiOptionalAuth(approver Approver) sr.Middleware {
return func(inner sr.Handler) sr.Handler {
return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response {
if Identity(request) != nil && !approver(ctx, request) {
return geminiCertNotAuthorized(ctx, request)
}
return inner.Handle(ctx, request)
})
}
}
// GeminiRequireCertificate is a middleware that only requires a client certificate.
var GeminiRequireCertificate = GeminiAuth(Allow)
func geminiMissingCert(_ context.Context, _ *sr.Request) *sr.Response {
return gemini.RequireCert("A client certificate is required.")
}
func geminiCertNotAuthorized(_ context.Context, _ *sr.Request) *sr.Response {
return gemini.CertAuthFailure("Client certificate not authorized.")
}
|