update gophermap + cgi-bin path checks to use regex (should be more reliable)

Signed-off-by: kim (grufwub) <grufwub@gmail.com>
This commit is contained in:
kim (grufwub) 2020-05-14 13:10:31 +01:00
parent 5aa62ebfa7
commit 3ca8450a84
5 changed files with 48 additions and 19 deletions

View File

@ -2,6 +2,7 @@ package main
import (
"time"
"regexp"
)
/* ServerConfig:
@ -12,31 +13,35 @@ import (
*/
type ServerConfig struct {
/* Executable Settings */
Env []string
CgiEnv []string
CgiEnabled bool
MaxExecRunTime time.Duration
Env []string
CgiEnv []string
CgiEnabled bool
MaxExecRunTime time.Duration
/* Content settings */
CharSet string
FooterText []byte
PageWidth int
CharSet string
FooterText []byte
PageWidth int
/* Logging */
SysLog LoggerInterface
AccLog LoggerInterface
SysLog LoggerInterface
AccLog LoggerInterface
/* Filesystem access */
FileSystem *FileSystem
FileSystem *FileSystem
/* Buffer sizes */
SocketWriteBufSize int
SocketReadBufSize int
SocketReadMax int
SkipPrefixBufSize int
FileReadBufSize int
SocketWriteBufSize int
SocketReadBufSize int
SocketReadMax int
SkipPrefixBufSize int
FileReadBufSize int
/* Socket deadlines */
SocketReadDeadline time.Duration
SocketWriteDeadline time.Duration
/* Precompiled regular expressions for performance */
RgxGophermap *regexp.Regexp
RgxCgiBin *regexp.Regexp
}

View File

@ -238,7 +238,7 @@ func readGophermap(path *RequestPath) ([]GophermapSection, *GophorError) {
}
/* Check if we've been supplied subgophermap or regular file */
if subPath.HasAbsSuffix(GophermapFileStr) {
if isGophermap(subPath) {
/* If executable, store as GophermapExecFileSection, else GophermapSubmapSection */
if stat.Mode().Perm() & 0100 != 0 {
sections = append(sections, &GophermapExecFileSection { &Request{ subPath, parameters } })

View File

@ -32,7 +32,7 @@ func (fs *FileSystem) Init(size int, fileSizeMax float64) {
fs.CacheMap = NewFixedMap(size)
fs.CacheMutex = sync.RWMutex{}
fs.CacheFileMax = int64(BytesInMegaByte * fileSizeMax)
/* {,Reverse}Remap map is setup in `gophor.go`, no need to here */
/* .Remaps and .Restricted are handled within gopher.go */
}
func (fs *FileSystem) IsRestricted(path string) bool {
@ -103,7 +103,7 @@ func (fs *FileSystem) HandleRequest(responder *Responder) *GophorError {
/* Directory */
case stat.Mode() & os.ModeDir != 0:
/* Ignore anything under cgi-bin directory */
if responder.Request.Path.HasRelPrefix(CgiBinDirStr) {
if withinCgiBin(responder.Request.Path) {
return &GophorError{ IllegalPathErr, nil }
}
@ -215,7 +215,7 @@ func (fs *FileSystem) FetchFile(responder *Responder) *GophorError {
/* Create new file contents */
var contents FileContents
if responder.Request.Path.HasRelSuffix(GophermapFileStr) {
if isGophermap(responder.Request.Path) {
contents = &GophermapContents{ responder.Request.Path, nil }
} else {
contents = &RegularFileContents{ responder.Request.Path, nil }

View File

@ -229,6 +229,10 @@ func setupServer() []*GophorListener {
Config.FileSystem.Restricted = compileUserRestrictedRegex(*restrictedFiles)
Config.FileSystem.Remaps = compileUserRemapRegex(*fileRemaps)
/* Precompile some helpful regex */
Config.RgxGophermap = compileGophermapCheckRegex()
Config.RgxCgiBin = compileCgiBinCheckRegex()
/* Return the created listeners slice :) */
return listeners
}

View File

@ -15,6 +15,16 @@ type FileRemap struct {
Template string
}
/* Pre-compile gophermap file string regex */
func compileGophermapCheckRegex() *regexp.Regexp {
return regexp.MustCompile(`^(|.+/|.+\.)gophermap$`)
}
/* Pre-compile cgi-bin path string regex */
func compileCgiBinCheckRegex() *regexp.Regexp {
return regexp.MustCompile(`^cgi-bin(|/.*)$`)
}
/* Compile a user supplied new line separated list of regex statements */
func compileUserRestrictedRegex(restrictions string) []*regexp.Regexp {
/* Return slice */
@ -72,3 +82,13 @@ func compileUserRemapRegex(remaps string) []*FileRemap {
return fileRemaps
}
/* Check if file path is gophermap */
func isGophermap(path *RequestPath) bool {
return Config.RgxGophermap.MatchString(path.Relative())
}
/* Check if file path within cgi-bin */
func withinCgiBin(path *RequestPath) bool {
return Config.RgxCgiBin.MatchString(path.Relative())
}