summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.go8
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--main.go87
-rw-r--r--routes.go46
5 files changed, 97 insertions, 50 deletions
diff --git a/config.go b/config.go
index 6af9808..a758903 100644
--- a/config.go
+++ b/config.go
@@ -16,17 +16,18 @@ type config struct {
hostname string
geminiRoot string
+ gopherRoot string
tlsKeyFile string
tlsCertFile string
- uploaderFingerprints []string
+ privilegedUsers []string
fingerResponses map[string]string
}
func configure() config {
- fingerprints := strings.Split(os.Getenv("UPLOADER_FINGERPRINTS"), ",")
+ privileged := strings.Split(os.Getenv("PRIVILEGED_FINGERPRINTS"), ",")
fingers := map[string]string{}
for _, pair := range os.Environ() {
@@ -40,10 +41,11 @@ func configure() config {
return config{
hostname: os.Getenv("HOST_NAME"),
geminiRoot: os.Getenv("GEMINI_ROOT"),
+ gopherRoot: os.Getenv("GOPHER_ROOT"),
tlsKeyFile: os.Getenv("TLS_KEY_FILE"),
tlsCertFile: os.Getenv("TLS_CERT_FILE"),
- uploaderFingerprints: fingerprints,
+ privilegedUsers: privileged,
fingerResponses: fingers,
}
diff --git a/go.mod b/go.mod
index 07ea11d..7ac0c84 100644
--- a/go.mod
+++ b/go.mod
@@ -2,7 +2,7 @@ module tildegit.org/tjp/sr-71
go 1.19
-require tildegit.org/tjp/sliderule v1.0.1-0.20230504031331-11b693e72fc5
+require tildegit.org/tjp/sliderule v1.0.1-0.20230509182153-a97f6f500f4e
require (
github.com/go-kit/log v0.2.1 // indirect
diff --git a/go.sum b/go.sum
index 71cf7c3..6f9d682 100644
--- a/go.sum
+++ b/go.sum
@@ -6,5 +6,5 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-tildegit.org/tjp/sliderule v1.0.1-0.20230504031331-11b693e72fc5 h1:psd8MmCrj3/LreDmXGnr1/heRbtyKdzatmx5PsK0Q70=
-tildegit.org/tjp/sliderule v1.0.1-0.20230504031331-11b693e72fc5/go.mod h1:opdo8E25iS9X9pNismM8U7pCH8XO0PdRIIhdADn8Uik=
+tildegit.org/tjp/sliderule v1.0.1-0.20230509182153-a97f6f500f4e h1:FnTEB2M257SRIgj5WgqSc13/4/3eVs2HVfCQpcuqWMg=
+tildegit.org/tjp/sliderule v1.0.1-0.20230509182153-a97f6f500f4e/go.mod h1:opdo8E25iS9X9pNismM8U7pCH8XO0PdRIIhdADn8Uik=
diff --git a/main.go b/main.go
index 1d6efc0..69ec021 100644
--- a/main.go
+++ b/main.go
@@ -4,11 +4,12 @@ import (
"context"
"crypto/tls"
"log"
- "os"
"sync"
+ sr "tildegit.org/tjp/sliderule"
"tildegit.org/tjp/sliderule/finger"
"tildegit.org/tjp/sliderule/gemini"
+ "tildegit.org/tjp/sliderule/gopher"
"tildegit.org/tjp/sliderule/logging"
)
@@ -19,75 +20,77 @@ func main() {
log.Fatal(err)
}
- dropped, err := dropPrivileges()
+ ctx, _, info, warn, errlog := serverContext()
+
+ gopherSrv, err := buildGopher(ctx, conf, info, errlog)
if err != nil {
log.Fatal(err)
}
- ctx, _, info, warn, errlog := serverContext()
+ fingerSrv, err := buildFinger(ctx, conf, info, errlog)
+ if err != nil {
+ log.Fatal(err)
+ }
+ dropped, err := dropPrivileges()
+ if err != nil {
+ log.Fatal(err)
+ }
if !dropped {
_ = warn.Log("msg", "dropping privileges to 'nobody' failed")
}
+ gemSrv, err := buildGemini(ctx, conf, gemTLS, info, errlog)
+ if err != nil {
+ log.Fatal(err)
+ }
+
wg := &sync.WaitGroup{}
- go startGemini(ctx, conf, wg, gemTLS, info, errlog)
- go startFinger(ctx, conf, wg, info, errlog)
- wg.Add(2)
+
+ wg.Add(3)
+ go runServer(gemSrv, wg)
+ go runServer(gopherSrv, wg)
+ go runServer(fingerSrv, wg)
wg.Wait()
}
-func startGemini(
+func buildGemini(
ctx context.Context,
conf config,
- wg *sync.WaitGroup,
gemTLS *tls.Config,
infolog logging.Logger,
errlog logging.Logger,
-) {
- defer wg.Done()
-
+) (sr.Server, error) {
handler := logging.LogRequests(infolog)(geminiRouter(conf))
- server, err := gemini.NewServer(
- ctx,
- conf.hostname,
- "tcp",
- "",
- handler,
- errlog,
- gemTLS,
- )
- if err != nil {
- _ = errlog.Log("msg", "error building server", "error", err)
- os.Exit(1)
- }
-
- if err := server.Serve(); err != nil {
- _ = errlog.Log("msg", "error serving gemini", "error", err)
- os.Exit(1)
- }
+ infolog.Log("msg", "starting gemini server", "gemini_root", conf.geminiRoot)
+ return gemini.NewServer(ctx, conf.hostname, "tcp", "", handler, errlog, gemTLS)
}
-func startFinger(
+func buildGopher(
ctx context.Context,
conf config,
- wg *sync.WaitGroup,
infolog logging.Logger,
errlog logging.Logger,
-) {
- defer wg.Done()
+) (sr.Server, error) {
+ handler := logging.LogRequests(infolog)(gopherRouter(conf))
+ infolog.Log("msg", "starting gopher server", "gopher_root", conf.gopherRoot)
+ return gopher.NewServer(ctx, conf.hostname, "tcp", "", handler, errlog)
+}
+func buildFinger(
+ ctx context.Context,
+ conf config,
+ infolog logging.Logger,
+ errlog logging.Logger,
+) (sr.Server, error) {
handler := logging.LogRequests(infolog)(fingerHandler(conf))
- server, err := finger.NewServer(ctx, conf.hostname, "tcp", "", handler, errlog)
- if err != nil {
- _ = errlog.Log("msg", "error building server", "error", err)
- os.Exit(1)
- }
+ infolog.Log("msg", "starting finger server", "finger_users", len(conf.fingerResponses))
+ return finger.NewServer(ctx, conf.hostname, "tcp", "", handler, errlog)
+}
- if err := server.Serve(); err != nil {
- _ = errlog.Log("msg", "error serving finger", "error", err)
- os.Exit(1)
- }
+func runServer(server sr.Server, wg *sync.WaitGroup) error {
+ defer wg.Done()
+ return server.Serve()
}
diff --git a/routes.go b/routes.go
index 35bdfc1..c4c9df0 100644
--- a/routes.go
+++ b/routes.go
@@ -21,12 +21,14 @@ import (
func geminiRouter(conf config) sr.Handler {
fsys := os.DirFS(conf.geminiRoot)
+ privileged := tlsAuth(conf.privilegedUsers)
+
router := &sr.Router{}
router.Route(
"/*",
gemini.GeminiOnly(true)(sr.FallthroughHandler(
- fs.TitanUpload(tlsAuth(conf.uploaderFingerprints), conf.geminiRoot)(postUploadRedirect),
+ fs.TitanUpload(privileged, conf.geminiRoot)(postUploadRedirect),
fs.GeminiFileHandler(fsys),
fs.GeminiDirectoryDefault(fsys, "index.gmi"),
fs.GeminiDirectoryListing(fsys, nil),
@@ -35,7 +37,47 @@ func geminiRouter(conf config) sr.Handler {
router.Route(
"/cgi-bin/*",
- gemini.GeminiOnly(false)(cgi.GeminiCGIDirectory("/cgi-bin/", "./cgi-bin/")),
+ gemini.GeminiOnly(false)(cgi.GeminiCGIDirectory(
+ "/cgi-bin/",
+ strings.Join([]string{".", strings.Trim(conf.geminiRoot, "/"), "cgi-bin"}, "/"),
+ )),
+ )
+
+ router.Route(
+ "/cgi-bin/private/*",
+ gemini.GeminiOnly(false)(tlsauth.GeminiAuth(privileged)(
+ cgi.GeminiCGIDirectory("/cgi-bin/private/", strings.Join([]string{
+ ".",
+ strings.Trim(conf.geminiRoot, "/"),
+ "cgi-bin",
+ "private",
+ }, "/")),
+ )),
+ )
+
+ return router.Handler()
+}
+
+func gopherRouter(conf config) sr.Handler {
+ fsys := os.DirFS(conf.gopherRoot)
+
+ router := &sr.Router{}
+
+ router.Route(
+ "/*",
+ sr.FallthroughHandler(
+ fs.GopherFileHandler(fsys),
+ fs.GopherDirectoryDefault(fsys, "index.gophermap"),
+ fs.GopherDirectoryListing(fsys, nil),
+ ),
+ )
+
+ router.Route(
+ "/cgi-bin/*",
+ cgi.GopherCGIDirectory(
+ "/cgi-bin/",
+ strings.Join([]string{".", strings.Trim(conf.gopherRoot, "/"), "cgi-bin"}, "/"),
+ ),
)
return router.Handler()