summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example.conf9
-rw-r--r--finger.go7
-rw-r--r--gemini.go4
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--gopher.go4
-rw-r--r--parse.go19
-rw-r--r--types.go1
8 files changed, 41 insertions, 9 deletions
diff --git a/example.conf b/example.conf
index 6181fcf..18f58f7 100644
--- a/example.conf
+++ b/example.conf
@@ -86,7 +86,14 @@ gemini 0.0.0.0:1965 {
# "static" and "cgi" directives work much like in gopher servers.
# There is no "extendedgophermap" modifier in gemini, however.
static /var/gemini/docs at / with dirdefault index.gmi, dirlist, exec
- cgi /var/gemini/cgi at /cgi-bin
+
+ # The "cmd" directive modifier can apply to any "cgi" or "static ... with exec" directives.
+ # It specifies a filesystem path to an executable file, which will be executed in place of the CGI script.
+ # Even with "cmd" in use, it will only be invoked if the request path points to a world-executable file
+ # and with the working directory and environment variables of the requested script.
+ # So generally "cmd" scripts can end with something like "exec $SCRIPT_PATH", perhaps after imposing
+ # resource limits or some other security sandbox around it first.
+ cgi /var/gemini/cgi at /cgi-bin with cmd /var/runcgi
# The "autoatom" modifier is allowed on directives in a gemini server.
# It causes any text/gemini responses to be available as atom at <path>.atom.
diff --git a/finger.go b/finger.go
index 941e705..75d8160 100644
--- a/finger.go
+++ b/finger.go
@@ -61,7 +61,12 @@ func fingerHandler(route RouteDirective) sr.Handler {
}
if st.Mode()&5 == 5 && (route.Modifiers.Exec || route.Type == "cgi") {
- buf, code, err := cgi.RunCGI(ctx, request, fpath, "/", nil)
+ workdir := filepath.Dir(fpath)
+ if route.Modifiers.ExecCmd != "" {
+ fpath = route.Modifiers.ExecCmd
+ }
+
+ buf, code, err := cgi.RunCGI(ctx, request, fpath, "/", workdir, nil)
if err != nil {
return finger.Error("execution error")
}
diff --git a/gemini.go b/gemini.go
index 3fb7a46..87af01f 100644
--- a/gemini.go
+++ b/gemini.go
@@ -94,7 +94,7 @@ func addGeminiRoute(router *sr.Router, route RouteDirective) {
addGeminiStaticRoute(router, route)
case "cgi":
buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler {
- handler := cgi.GeminiCGIDirectory(route.FsPath, route.URLPath)
+ handler := cgi.GeminiCGIDirectory(route.FsPath, route.URLPath, route.Modifiers.ExecCmd)
if route.Modifiers.AutoAtom {
handler = atomconv.Auto(handler)
}
@@ -110,7 +110,7 @@ func addGeminiStaticRoute(router *sr.Router, route RouteDirective) {
handlers := []sr.Handler{}
if route.Modifiers.Exec {
- handlers = append(handlers, cgi.GeminiCGIDirectory(route.FsPath, route.URLPath))
+ handlers = append(handlers, cgi.GeminiCGIDirectory(route.FsPath, route.URLPath, route.Modifiers.ExecCmd))
}
handlers = append(handlers, fs.GeminiFileHandler(route.FsPath, route.URLPath))
diff --git a/go.mod b/go.mod
index 09affeb..6c67c53 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.21.0
require (
github.com/go-kit/log v0.2.1
- tildegit.org/tjp/sliderule v1.4.1
+ tildegit.org/tjp/sliderule v1.4.2-0.20231010204754-04449ed66e42
tildegit.org/tjp/syw v0.9.2
)
diff --git a/go.sum b/go.sum
index 7c0c074..d0231f4 100644
--- a/go.sum
+++ b/go.sum
@@ -10,7 +10,7 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-tildegit.org/tjp/sliderule v1.4.1 h1:L1evSiVqhiHSVgWBCFgDXhT30OZdWUHRq8CahCDkd+I=
-tildegit.org/tjp/sliderule v1.4.1/go.mod h1:opdo8E25iS9X9pNismM8U7pCH8XO0PdRIIhdADn8Uik=
+tildegit.org/tjp/sliderule v1.4.2-0.20231010204754-04449ed66e42 h1:KkbiQO/kIxwABGqhocShHvehchDuGyQzvhV61SKfhO8=
+tildegit.org/tjp/sliderule v1.4.2-0.20231010204754-04449ed66e42/go.mod h1:opdo8E25iS9X9pNismM8U7pCH8XO0PdRIIhdADn8Uik=
tildegit.org/tjp/syw v0.9.2 h1:bwLRXJqC5RHes2dfntgePHYnh6iIQC9FZpFBTReemQ0=
tildegit.org/tjp/syw v0.9.2/go.mod h1:Oo05KA7QibiXxoPh5jzpKUq/RG4U3nz7qs6QVitZw8I=
diff --git a/gopher.go b/gopher.go
index 3030bac..1c13886 100644
--- a/gopher.go
+++ b/gopher.go
@@ -57,7 +57,7 @@ func addGopherStaticRoute(router *sr.Router, route RouteDirective) {
handlers := []sr.Handler{}
if route.Modifiers.Exec {
- handlers = append(handlers, cgi.ExecGopherMaps(route.FsPath, route.URLPath, settings))
+ handlers = append(handlers, cgi.ExecGopherMaps(route.FsPath, route.URLPath, route.Modifiers.ExecCmd, settings))
}
handlers = append(handlers, fs.GopherFileHandler(route.FsPath, route.URLPath, settings))
@@ -90,7 +90,7 @@ func addGopherCGIRoute(router *sr.Router, route RouteDirective) {
}
buildAndAddRoute(router, route, func(route RouteDirective) sr.Handler {
- return cgi.GopherCGIDirectory(route.FsPath, route.URLPath, settings)
+ return cgi.GopherCGIDirectory(route.FsPath, route.URLPath, route.Modifiers.ExecCmd, settings)
})
}
diff --git a/parse.go b/parse.go
index 0fe3f30..d087e95 100644
--- a/parse.go
+++ b/parse.go
@@ -293,6 +293,10 @@ func validateRoute(serverType string, dir *RouteDirective) error {
return fmt.Errorf("titan modifier only allowed on gemini{static}")
}
+ if dir.Modifiers.ExecCmd != "" && !(dir.Type == "cgi" || (dir.Type == "static" && dir.Modifiers.Exec)) {
+ return fmt.Errorf("'cmd' modifier only valid on 'cgi' and 'static...with exec' directives")
+ }
+
return nil
}
@@ -410,6 +414,21 @@ func parseModifiers(text string) (Modifiers, string, error) {
mod.DirList = true
case "exec":
mod.Exec = true
+ case "cmd":
+ if sep != " " {
+ return mod, "", errors.New("invalid 'cmd' clause")
+ }
+ text = strings.TrimLeft(text, " \t")
+ idx = strings.IndexAny(text, " \t,")
+ if idx == 0 {
+ return mod, "", errors.New("invalid 'cmd' clause")
+ } else if idx < 0 {
+ mod.ExecCmd = text
+ text = ""
+ } else {
+ mod.ExecCmd = text[0:idx]
+ text = text[idx+1:]
+ }
case "extendedgophermap":
mod.ExtendedGophermap = true
case "autoatom":
diff --git a/types.go b/types.go
index 8d010b2..3dd3935 100644
--- a/types.go
+++ b/types.go
@@ -14,6 +14,7 @@ type Modifiers struct {
DirDefault string
DirList bool
Exec bool
+ ExecCmd string
ExtendedGophermap bool
AutoAtom bool
Titan *Auth