summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-09-08 14:54:56 -0600
committertjpcc <tjp@ctrl-c.club>2023-09-08 14:54:56 -0600
commit023838345ddb751e3b7143e87f0c123fc2703eac (patch)
tree3f888af79dd4acc6f2063bc1a9f0ad433c8564b7
parent06ec0efd4f34e9c3b776b94ccc83ddfaf7eb55f6 (diff)
support an env var for allowlisting uploaders by cert fingerprint
-rw-r--r--config.go20
-rw-r--r--routes.go27
2 files changed, 37 insertions, 10 deletions
diff --git a/config.go b/config.go
index 39d59bd..4be0790 100644
--- a/config.go
+++ b/config.go
@@ -6,6 +6,7 @@ import (
"os/signal"
"os/user"
"strconv"
+ "strings"
"syscall"
"tildegit.org/tjp/sliderule/logging"
@@ -18,14 +19,20 @@ type config struct {
tlsKeyFile string
tlsCertFile string
+
+ uploaderFingerprints []string
}
func configure() config {
+ fingerprints := strings.Split(os.Getenv("UPLOADER_FINGERPRINTS"), ",")
+
return config{
hostname: os.Getenv("HOST_NAME"),
geminiRoot: os.Getenv("GEMINI_ROOT"),
tlsKeyFile: os.Getenv("TLS_KEY_FILE"),
tlsCertFile: os.Getenv("TLS_CERT_FILE"),
+
+ uploaderFingerprints: fingerprints,
}
}
@@ -56,16 +63,11 @@ func dropPrivileges() (bool, error) {
func serverContext() (context.Context, logging.Logger, logging.Logger, logging.Logger, logging.Logger) {
debug, info, warn, err := logging.DefaultLoggers()
- ctx := signals(context.Background())
+ ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGHUP)
ctx = context.WithValue(ctx, "debuglog", debug) //nolint:staticcheck
- ctx = context.WithValue(ctx, "infolog", info) //nolint:staticcheck
- ctx = context.WithValue(ctx, "warnlog", warn) //nolint:staticcheck
- ctx = context.WithValue(ctx, "errorlog", err) //nolint:staticcheck
+ ctx = context.WithValue(ctx, "infolog", info) //nolint:staticcheck
+ ctx = context.WithValue(ctx, "warnlog", warn) //nolint:staticcheck
+ ctx = context.WithValue(ctx, "errorlog", err) //nolint:staticcheck
return ctx, debug, info, warn, err
}
-
-func signals(ctx context.Context) context.Context {
- ctx, _ = signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGHUP)
- return ctx
-}
diff --git a/routes.go b/routes.go
index 59e6ff4..0683924 100644
--- a/routes.go
+++ b/routes.go
@@ -2,7 +2,11 @@ package main
import (
"context"
+ "crypto/sha256"
+ "crypto/x509"
+ "encoding/hex"
"os"
+ "sort"
"strings"
sr "tildegit.org/tjp/sliderule"
@@ -20,7 +24,7 @@ func geminiRouter(conf config) sr.Handler {
router.Route(
"/*",
gemini.GeminiOnly(true)(sr.FallthroughHandler(
- fs.TitanUpload(tlsauth.Allow, conf.geminiRoot)(postUploadRedirect),
+ fs.TitanUpload(tlsAuth(conf.uploaderFingerprints), conf.geminiRoot)(postUploadRedirect),
fs.GeminiFileHandler(fsys),
fs.GeminiDirectoryDefault(fsys, "index.gmi"),
fs.GeminiDirectoryListing(fsys, nil),
@@ -41,3 +45,24 @@ var postUploadRedirect = sr.HandlerFunc(func(ctx context.Context, request *sr.Re
u.Scheme = "gemini"
return gemini.Redirect(u.String())
})
+
+func tlsAuth(uploaders []string) tlsauth.Approver {
+ sort.Strings(uploaders)
+
+ return func(cert *x509.Certificate) bool {
+ raw := sha256.Sum256(cert.Raw)
+ user := hex.EncodeToString(raw[:])
+
+ _, found := sort.Find(len(uploaders), func(i int) int {
+ switch {
+ case uploaders[i] < user:
+ return 1
+ case uploaders[i] == user:
+ return 0
+ default:
+ return -1
+ }
+ })
+ return found
+ }
+}