User dir is now not customizeable, improve gemini request parsing

Signed-off-by: kim (grufwub) <grufwub@gmail.com>
development
kim (grufwub) 4 years ago
parent 797ad97e1c
commit ba2bc9f033

@ -6,9 +6,7 @@ import (
"log"
"os"
"os/signal"
"path"
"strconv"
"strings"
"syscall"
"time"
@ -25,7 +23,7 @@ func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Lis
// in `string_constants.go` to allow for later localization
sysLog := flag.String(sysLogFlagStr, "stdout", sysLogDescStr)
accLog := flag.String(accLogFlagStr, "stdout", accLogDescStr)
flag.StringVar(&Root, rootFlagStr, "/var/gopher", rootDescStr)
flag.StringVar(&Root, rootFlagStr, "/var/"+proto, rootDescStr)
flag.StringVar(&Bind, bindFlagStr, "", bindDescStr)
flag.StringVar(&Hostname, hostnameFlagStr, "localhost", hostnameDescStr)
port := flag.Uint(portFlagStr, defaultPort, portDescStr)
@ -46,7 +44,7 @@ func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Lis
cgiDir := flag.String(cgiDirFlagStr, "", cgiDirDescStr)
flag.DurationVar(&maxCGIRunTime, maxCGITimeFlagStr, time.Duration(time.Second*3), maxCGITimeDescStr)
safePath := flag.String(safePathFlagStr, "/bin:/usr/bin", safePathDescStr)
flag.StringVar(&userDir, userDirFlagStr, "", userDirDescStr)
userSpacesEnabled := flag.Bool(userSpacesFlagStr, false, userSpacesDescStr)
printVersion := flag.Bool(versionFlagStr, false, versionDescStr)
// Parse flags! (including any set by outer calling function)
@ -152,20 +150,14 @@ func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Lis
}
// If no user dir supplied, set to disabled function. Else, set user dir and enable
if userDir == "" {
SystemLog.Info(userDirDisabledStr)
getRequestPath = getRequestPathUserDirDisabled
if *userSpacesEnabled {
SystemLog.Info(userSpacesDisabledStr)
getRequestPath = getRequestPathUserSpacesDisabled
} else {
SystemLog.Info(userDirEnabledStr)
getRequestPath = getRequestPathUserDirEnabled
// Clean the user dir to be safe
userDir = path.Clean(userDir)
if strings.HasPrefix(userDir, "..") {
SystemLog.Fatalf(userDirBackTraverseErrStr, userDir)
} else {
SystemLog.Infof(userDirStr, userDir)
}
SystemLog.Info(userSpacesEnabledStr)
getRequestPath = getRequestPathUserSpacesEnabled
userSpace = "public_" + proto
SystemLog.Infof(userSpacesStr, userSpace)
}
// Set provided client filesystem handler functions

@ -117,7 +117,7 @@ func sanitizeRawPath(root, rel string) string {
// sanitizerUserRoot takes a generated user root directory and sanitizes it, returning a bool as to whether it's safe
func sanitizeUserRoot(root string) (string, bool) {
root = path.Clean(root)
if !strings.HasPrefix(root, "/home/") && strings.HasSuffix(root, "/"+userDir) {
if !strings.HasPrefix(root, "/home/") && strings.HasSuffix(root, "/"+userSpace) {
return "", false
}
return root, true

@ -44,7 +44,7 @@ var (
// File system related globals
monitorSleepTime time.Duration
fileSizeMax int64
userDir string
userSpace string
// Global listener
serverListener *Listener

@ -71,8 +71,8 @@ const (
safePathFlagStr = "safe-path"
safePathDescStr = "CGI environment safe PATH variable"
userDirFlagStr = "user-dir"
userDirDescStr = "User subdir for personal server space"
userSpacesFlagStr = "user-spaces"
userSpacesDescStr = "Enable user sub-dirs for personal server space"
versionFlagStr = "version"
versionDescStr = "Print version string"
@ -115,10 +115,9 @@ const (
cgiDirStr = "CGI directory: %s"
cgiExecuteErrStr = "Exit executing: %s [%d]"
userDirEnabledStr = "User directory support enabled"
userDirDisabledStr = "User directory support disabled"
userDirBackTraverseErrStr = "User directory with back-traversal not supported: %s"
userDirStr = "User directory: %s"
userSpacesEnabledStr = "User spaces support enabled"
userSpacesDisabledStr = "User spaces support disabled"
userSpacesStr = "User space directory: %s"
signalReceivedStr = "Signal received: %v. Shutting down..."
@ -127,23 +126,22 @@ const (
pgidNotFoundErrStr = "Process unfinished, PGID not found!"
pgidStopErrStr = "Error stopping process group %d: %s"
connWriteErrStr = "Conn write error"
connReadErrStr = "Conn read error"
connCloseErrStr = "Conn close error"
listenerResolveErrStr = "Listener resolve error"
listenerBeginErrStr = "Listener begin error"
listenerAcceptErrStr = "Listener accept error"
invalidIPErrStr = "Invalid IP"
invalidPortErrStr = "Invalid port"
mutexUpgradeErrStr = "Mutex upgrade fail"
mutexDowngradeErrStr = "Mutex downgrade fail"
fileOpenErrStr = "File open error"
fileStatErrStr = "File stat error"
fileReadErrStr = "File read error"
fileTypeErrStr = "Unsupported file type"
directoryReadErrStr = "Directory read error"
restrictedPathErrStr = "Restricted path"
invalidRequestErrStr = "Invalid request"
cgiStartErrStr = "CGI start error"
cgiExitCodeErrStr = "CGI non-zero exit code"
connWriteErrStr = "Conn write error"
connReadErrStr = "Conn read error"
connCloseErrStr = "Conn close error"
listenerBeginErrStr = "Listener begin error"
listenerAcceptErrStr = "Listener accept error"
invalidIPErrStr = "Invalid IP"
invalidPortErrStr = "Invalid port"
mutexUpgradeErrStr = "Mutex upgrade fail"
mutexDowngradeErrStr = "Mutex downgrade fail"
fileOpenErrStr = "File open error"
fileStatErrStr = "File stat error"
fileReadErrStr = "File read error"
fileTypeErrStr = "Unsupported file type"
directoryReadErrStr = "Directory read error"
restrictedPathErrStr = "Restricted path"
invalidRequestErrStr = "Invalid request"
cgiStartErrStr = "CGI start error"
cgiExitCodeErrStr = "CGI non-zero exit code"
)

@ -42,8 +42,8 @@ func ParseInternalRequest(p *Path, line string) *Request {
return &Request{newSanitizedPath(p.Root(), rawPath), query}
}
// getRequestPathUserDirEnabled creates a Path object from raw path, converting ~USER to user subdirectory roots, else at server root
func getRequestPathUserDirEnabled(rawPath string) *Path {
// getRequestPathUserSpacesEnabled creates a Path object from raw path, converting ~USER to user subdirectory roots, else at server root
func getRequestPathUserSpacesEnabled(rawPath string) *Path {
if userPath := strings.TrimPrefix(rawPath, "/"); strings.HasPrefix(userPath, "~") {
// We found a user path! Split into the user part, and remaining path
user, remaining := SplitBy(userPath, "/")
@ -54,7 +54,7 @@ func getRequestPathUserDirEnabled(rawPath string) *Path {
}
// Get sanitized user root, else return server root
root, ok := sanitizeUserRoot(path.Join("/home", user[1:], userDir))
root, ok := sanitizeUserRoot(path.Join("/home", user[1:], userSpace))
if !ok {
return &Path{Root, "", "/"}
}
@ -69,7 +69,7 @@ func getRequestPathUserDirEnabled(rawPath string) *Path {
return newSanitizedPath(Root, rawPath)
}
// getRequestPathUserDirDisabled creates a Path object from raw path, always at server root
func getRequestPathUserDirDisabled(rawPath string) *Path {
// getRequestPathUserSpacesDisabled creates a Path object from raw path, always at server root
func getRequestPathUserSpacesDisabled(rawPath string) *Path {
return newSanitizedPath(Root, rawPath)
}

@ -3,6 +3,7 @@ package gemini
import (
"gophi/core"
"os"
"strings"
"github.com/grufwub/go-errors"
)
@ -25,19 +26,22 @@ func serve(client *core.Client) {
if line == "" {
line = proto
} else if proto != "gemini" {
client.LogError(clientRequestParseFailStr)
handleError(client, errors.NewError(core.ConnWriteErr))
client.LogError(clientInvalidRequestStr)
handleError(client, errors.NewError(invalidProtocolErr))
return
}
// Split up to first '/', ensure first part contains expected
// host:port combo
hostPort, line := core.SplitBy(line, "/")
host, port := core.SplitBy(hostPort, ":")
if host != core.Hostname || port != core.Port {
client.LogError(clientRequestParseFailStr)
handleError(client, errors.NewError(core.ConnWriteErr))
return
// If doesn't start with '/', is providing a host(:port) and we need
// to make sure this is equal to our current server
if !strings.HasPrefix(line, "/") {
var hostPort string
hostPort, line = core.SplitBy(line, "/")
host, port := core.SplitBy(hostPort, ":")
if host != core.Hostname || (port != "" && port != core.Port) {
client.LogError(clientInvalidRequestStr)
handleError(client, errors.NewError(invalidHostPortErr))
return
}
}
// Parse new request
@ -49,13 +53,7 @@ func serve(client *core.Client) {
}
// Handle the request!
err = core.HandleClient(
// Current client
client,
// Current request
request,
)
err = core.HandleClient(client, request)
// Final error handling
if err != nil {
@ -102,13 +100,8 @@ func handleDirectory(client *core.Client, fd *os.File, p *core.Path) *errors.Err
// Scan directory and build lines
err = core.ScanDirectory(
// Directory fd
fd,
// Directory path
p,
// Iter function
func(file os.FileInfo, fp *core.Path) {
// Append new formatted file listing
dirContents += "=> " + fp.Selector() + " * " + fp.Selector() + "\n"

@ -54,13 +54,7 @@ func serve(client *core.Client) {
request.AddToQuery(extra)
// Handle the request!
err = core.HandleClient(
// Current client
client,
// Current request
request,
)
err = core.HandleClient(client, request)
// Final error handling
if err != nil {
@ -99,13 +93,8 @@ func handleDirectory(client *core.Client, file *os.File, p *core.Path) *errors.E
// Scan directory and build lines
err = core.ScanDirectory(
// Directory file
file,
// Directory path
p,
// Iter function
func(file os.FileInfo, fp *core.Path) {
// Append new formatted file listing (if correct type)
dirContents = appendFileListing(dirContents, file, fp)

Loading…
Cancel
Save