1
0
Fork 0

Another big refactor, splitting the Config struct in two.

The split reflects that between variables which can and cannot be
overridden by .molly files, and this greatly simplifies the
processing of said files, getting rid of the need for lots of
ugly temporary variable thrashing.
This commit is contained in:
Solderpunk 2023-02-25 11:29:13 +01:00
parent e70ec82594
commit eb85a6e94c
12 changed files with 129 additions and 167 deletions

View file

@ -27,7 +27,7 @@ func enforceCertificateValidity(clientCerts []*x509.Certificate, conn net.Conn,
}
}
func handleCertificateZones(URL *url.URL, clientCerts []*x509.Certificate, config Config, conn net.Conn, logEntry *LogEntry) {
func handleCertificateZones(URL *url.URL, clientCerts []*x509.Certificate, config UserConfig, conn net.Conn, logEntry *LogEntry) {
authorised := true
for zone, allowedFingerprints := range config.CertificateZones {
matched, err := regexp.Match(zone, []byte(URL.Path))

200
config.go
View file

@ -9,195 +9,167 @@ import (
"strings"
)
type Config struct {
type SysConfig struct {
Port int
Hostname string
CertPath string
KeyPath string
DocBase string
HomeDocBase string
GeminiExt string
DefaultLang string
DefaultEncoding string
AccessLog string
ErrorLog string
ReadMollyFiles bool
TempRedirects map[string]string
PermRedirects map[string]string
MimeOverrides map[string]string
DocBase string
HomeDocBase string
CGIPaths []string
SCGIPaths map[string]string
CertificateZones map[string][]string
ReadMollyFiles bool
AllowTLS12 bool
DirectorySort string
DirectorySubdirsFirst bool
DirectoryReverse bool
DirectoryTitles bool
}
type MollyFile struct {
type UserConfig struct {
GeminiExt string
DefaultLang string
DefaultEncoding string
TempRedirects map[string]string
PermRedirects map[string]string
MimeOverrides map[string]string
CertificateZones map[string][]string
DefaultLang string
DefaultEncoding string
DirectorySort string
DirectorySubdirsFirst bool
DirectoryReverse bool
DirectoryTitles bool
}
func getConfig(filename string) (Config, error) {
func getConfig(filename string) (SysConfig, UserConfig, error) {
var config Config
var sysConfig SysConfig
var userConfig UserConfig
// Defaults
config.Port = 1965
config.Hostname = "localhost"
config.CertPath = "cert.pem"
config.KeyPath = "key.pem"
config.DocBase = "/var/gemini/"
config.HomeDocBase = "users"
config.GeminiExt = "gmi"
config.DefaultLang = ""
config.DefaultEncoding = ""
config.AccessLog = "access.log"
config.ErrorLog = ""
config.TempRedirects = make(map[string]string)
config.PermRedirects = make(map[string]string)
config.CGIPaths = make([]string, 0)
config.SCGIPaths = make(map[string]string)
config.AllowTLS12 = true
config.DirectorySort = "Name"
config.DirectorySubdirsFirst = false
sysConfig.Port = 1965
sysConfig.Hostname = "localhost"
sysConfig.CertPath = "cert.pem"
sysConfig.KeyPath = "key.pem"
sysConfig.AccessLog = "access.log"
sysConfig.ErrorLog = ""
sysConfig.DocBase = "/var/gemini/"
sysConfig.HomeDocBase = "users"
sysConfig.CGIPaths = make([]string, 0)
sysConfig.SCGIPaths = make(map[string]string)
sysConfig.ReadMollyFiles = false
sysConfig.AllowTLS12 = true
userConfig.GeminiExt = "gmi"
userConfig.DefaultLang = ""
userConfig.DefaultEncoding = ""
userConfig.TempRedirects = make(map[string]string)
userConfig.PermRedirects = make(map[string]string)
userConfig.DirectorySort = "Name"
userConfig.DirectorySubdirsFirst = false
// Return defaults if no filename given
if filename == "" {
return config, nil
return sysConfig, userConfig, nil
}
// Attempt to overwrite defaults from file
_, err := toml.DecodeFile(filename, &config)
_, err := toml.DecodeFile(filename, &sysConfig)
if err != nil {
return config, err
return sysConfig, userConfig, err
}
_, err = toml.DecodeFile(filename, &userConfig)
if err != nil {
return sysConfig, userConfig, err
}
// Force hostname to lowercase
config.Hostname = strings.ToLower(config.Hostname)
sysConfig.Hostname = strings.ToLower(sysConfig.Hostname)
// Validate pseudo-enums
switch config.DirectorySort {
case "Name", "Size", "Time":
default:
return config, errors.New("Invalid DirectorySort value.")
switch userConfig.DirectorySort {
case "Name", "Size", "Time":
default:
return sysConfig, userConfig, errors.New("Invalid DirectorySort value.")
}
// Absolutise paths
config.DocBase, err = filepath.Abs(config.DocBase)
sysConfig.DocBase, err = filepath.Abs(sysConfig.DocBase)
if err != nil {
return config, err
return sysConfig, userConfig, err
}
config.CertPath, err = filepath.Abs(config.CertPath)
sysConfig.CertPath, err = filepath.Abs(sysConfig.CertPath)
if err != nil {
return config, err
return sysConfig, userConfig, err
}
config.KeyPath, err = filepath.Abs(config.KeyPath)
sysConfig.KeyPath, err = filepath.Abs(sysConfig.KeyPath)
if err != nil {
return config, err
return sysConfig, userConfig, err
}
if config.AccessLog != "" && config.AccessLog != "-" {
config.AccessLog, err = filepath.Abs(config.AccessLog)
if sysConfig.AccessLog != "" && sysConfig.AccessLog != "-" {
sysConfig.AccessLog, err = filepath.Abs(sysConfig.AccessLog)
if err != nil {
return config, err
return sysConfig, userConfig, err
}
}
if config.ErrorLog != "" {
config.ErrorLog, err = filepath.Abs(config.ErrorLog)
if sysConfig.ErrorLog != "" {
sysConfig.ErrorLog, err = filepath.Abs(sysConfig.ErrorLog)
if err != nil {
return config, err
return sysConfig, userConfig, err
}
}
// Absolutise CGI paths
for index, cgiPath := range config.CGIPaths {
for index, cgiPath := range sysConfig.CGIPaths {
if !filepath.IsAbs(cgiPath) {
config.CGIPaths[index] = filepath.Join(config.DocBase, cgiPath)
sysConfig.CGIPaths[index] = filepath.Join(sysConfig.DocBase, cgiPath)
}
}
// Expand CGI paths
var cgiPaths []string
for _, cgiPath := range config.CGIPaths {
for _, cgiPath := range sysConfig.CGIPaths {
expandedPaths, err := filepath.Glob(cgiPath)
if err != nil {
return config, errors.New("Error expanding CGI path glob " + cgiPath + ": " + err.Error())
return sysConfig, userConfig, errors.New("Error expanding CGI path glob " + cgiPath + ": " + err.Error())
}
cgiPaths = append(cgiPaths, expandedPaths...)
}
config.CGIPaths = cgiPaths
sysConfig.CGIPaths = cgiPaths
// Absolutise SCGI paths
for index, scgiPath := range config.SCGIPaths {
config.SCGIPaths[index], err = filepath.Abs( scgiPath)
for index, scgiPath := range sysConfig.SCGIPaths {
sysConfig.SCGIPaths[index], err = filepath.Abs( scgiPath)
if err != nil {
return config, err
return sysConfig, userConfig, err
}
}
// Validate redirects
for _, value := range config.TempRedirects {
for _, value := range userConfig.TempRedirects {
if strings.Contains(value, "://") && !strings.HasPrefix(value, "gemini://") {
return config, errors.New("Invalid cross-protocol redirect to " + value)
return sysConfig, userConfig, errors.New("Invalid cross-protocol redirect to " + value)
}
}
for _, value := range config.PermRedirects {
for _, value := range userConfig.PermRedirects {
if strings.Contains(value, "://") && !strings.HasPrefix(value, "gemini://") {
return config, errors.New("Ignoring cross-protocol redirect to " + value)
return sysConfig, userConfig, errors.New("Ignoring cross-protocol redirect to " + value)
}
}
return config, nil
return sysConfig, userConfig, nil
}
func parseMollyFiles(path string, config *Config) {
func parseMollyFiles(path string, docBase string, config UserConfig) UserConfig {
// Replace config variables which use pointers with new ones,
// so that changes made here aren't reflected everywhere.
newTempRedirects := make(map[string]string)
for key, value := range config.TempRedirects {
newTempRedirects[key] = value
}
config.TempRedirects = newTempRedirects
newPermRedirects := make(map[string]string)
for key, value := range config.PermRedirects {
newPermRedirects[key] = value
}
config.PermRedirects = newPermRedirects
newMimeOverrides := make(map[string]string)
for key, value := range config.MimeOverrides {
newMimeOverrides[key] = value
}
config.MimeOverrides = newMimeOverrides
newCertificateZones := make(map[string][]string)
for key, value := range config.CertificateZones {
newCertificateZones[key] = value
}
config.CertificateZones = newCertificateZones
// Initialise MollyFile using main Config
var mollyFile MollyFile
mollyFile.GeminiExt = config.GeminiExt
mollyFile.DefaultLang = config.DefaultLang
mollyFile.DefaultEncoding = config.DefaultEncoding
mollyFile.DirectorySort = config.DirectorySort
mollyFile.DirectorySubdirsFirst = config.DirectorySubdirsFirst
mollyFile.DirectoryReverse = config.DirectoryReverse
mollyFile.DirectoryTitles = config.DirectoryTitles
config.TempRedirects = make(map[string]string)
config.PermRedirects = make(map[string]string)
config.MimeOverrides = make(map[string]string)
config.CertificateZones = make(map[string][]string)
// Build list of directories to check
var dirs []string
dirs = append(dirs, path)
for {
if path == filepath.Clean(config.DocBase) {
if path == filepath.Clean(docBase) {
break
}
subpath := filepath.Dir(path)
@ -219,38 +191,28 @@ func parseMollyFiles(path string, config *Config) {
continue
}
// If the file exists and we can read it, try to parse it
_, err = toml.DecodeFile(mollyPath, &mollyFile)
_, err = toml.DecodeFile(mollyPath, &config)
if err != nil {
log.Println("Error parsing .molly file " + mollyPath + ": " + err.Error())
continue
}
// Overwrite main Config using MollyFile
config.GeminiExt = mollyFile.GeminiExt
config.DefaultLang = mollyFile.DefaultLang
config.DefaultEncoding = mollyFile.DefaultEncoding
config.DirectorySort = mollyFile.DirectorySort
config.DirectorySubdirsFirst = mollyFile.DirectorySubdirsFirst
config.DirectoryReverse = mollyFile.DirectoryReverse
config.DirectoryTitles = mollyFile.DirectoryTitles
for key, value := range mollyFile.TempRedirects {
for key, value := range config.TempRedirects {
if strings.Contains(value, "://") && !strings.HasPrefix(value, "gemini://") {
log.Println("Ignoring cross-protocol redirect to " + value + " in .molly file " + mollyPath)
continue
}
config.TempRedirects[key] = value
}
for key, value := range mollyFile.PermRedirects {
for key, value := range config.PermRedirects {
if strings.Contains(value, "://") && !strings.HasPrefix(value, "gemini://") {
log.Println("Ignoring cross-protocol redirect to " + value + " in .molly file " + mollyPath)
continue
}
config.PermRedirects[key] = value
}
for key, value := range mollyFile.MimeOverrides {
config.MimeOverrides[key] = value
}
for key, value := range mollyFile.CertificateZones {
config.CertificateZones[key] = value
}
}
return config
}

View file

@ -11,7 +11,7 @@ import (
"strings"
)
func generateDirectoryListing(URL *url.URL, path string, config Config) (string, error) {
func generateDirectoryListing(URL *url.URL, path string, config UserConfig) (string, error) {
var listing string
files, err := ioutil.ReadDir(path)
if err != nil {
@ -82,7 +82,7 @@ func generateDirectoryListing(URL *url.URL, path string, config Config) (string,
return listing, nil
}
func generatePrettyFileLabel(info os.FileInfo, path string, config Config) string {
func generatePrettyFileLabel(info os.FileInfo, path string, config UserConfig) string {
var size string
if info.IsDir() {
size = " "

View file

@ -15,7 +15,7 @@ import (
"time"
)
func handleCGI(config Config, path string, cgiPath string, URL *url.URL, logEntry *LogEntry, conn net.Conn) {
func handleCGI(config SysConfig, path string, cgiPath string, URL *url.URL, logEntry *LogEntry, conn net.Conn) {
// Find the shortest leading part of path which maps to an executable file.
// Call this part scriptPath, and everything after it pathInfo.
components := strings.Split(path, "/")
@ -86,7 +86,7 @@ func handleCGI(config Config, path string, cgiPath string, URL *url.URL, logEntr
conn.Write(response)
}
func handleSCGI(URL *url.URL, scgiPath string, scgiSocket string, config Config, logEntry *LogEntry, conn net.Conn) {
func handleSCGI(URL *url.URL, scgiPath string, scgiSocket string, config SysConfig, logEntry *LogEntry, conn net.Conn) {
// Connect to socket
socket, err := net.Dial("unix", scgiSocket)
@ -148,7 +148,7 @@ func handleSCGI(URL *url.URL, scgiPath string, scgiSocket string, config Config,
}
}
func prepareCGIVariables(config Config, URL *url.URL, conn net.Conn, script_path string, path_info string) map[string]string {
func prepareCGIVariables(config SysConfig, URL *url.URL, conn net.Conn, script_path string, path_info string) map[string]string {
vars := prepareGatewayVariables(config, URL, conn)
vars["GATEWAY_INTERFACE"] = "CGI/1.1"
vars["SCRIPT_PATH"] = script_path
@ -156,7 +156,7 @@ func prepareCGIVariables(config Config, URL *url.URL, conn net.Conn, script_path
return vars
}
func prepareSCGIVariables(config Config, URL *url.URL, scgiPath string, conn net.Conn) map[string]string {
func prepareSCGIVariables(config SysConfig, URL *url.URL, scgiPath string, conn net.Conn) map[string]string {
vars := prepareGatewayVariables(config, URL, conn)
vars["SCGI"] = "1"
vars["CONTENT_LENGTH"] = "0"
@ -165,7 +165,7 @@ func prepareSCGIVariables(config Config, URL *url.URL, scgiPath string, conn net
return vars
}
func prepareGatewayVariables(config Config, URL *url.URL, conn net.Conn) map[string]string {
func prepareGatewayVariables(config SysConfig, URL *url.URL, conn net.Conn) map[string]string {
vars := make(map[string]string)
vars["QUERY_STRING"] = URL.RawQuery
vars["REQUEST_METHOD"] = ""

View file

@ -36,7 +36,7 @@ func isSubdir(subdir, superdir string) (bool, error) {
return false, nil
}
func handleGeminiRequest(conn net.Conn, config Config, accessLogEntries chan LogEntry, wg *sync.WaitGroup) {
func handleGeminiRequest(conn net.Conn, sysConfig SysConfig, config UserConfig, accessLogEntries chan LogEntry, wg *sync.WaitGroup) {
defer conn.Close()
defer wg.Done()
var tlsConn (*tls.Conn) = conn.(*tls.Conn)
@ -75,7 +75,7 @@ func handleGeminiRequest(conn net.Conn, config Config, accessLogEntries chan Log
if strings.HasSuffix(requestedHost, ".") {
requestedHost = requestedHost[:len(requestedHost)-1]
}
if requestedHost != config.Hostname || (URL.Port() != "" && URL.Port() != strconv.Itoa(config.Port)) {
if requestedHost != sysConfig.Hostname || (URL.Port() != "" && URL.Port() != strconv.Itoa(sysConfig.Port)) {
conn.Write([]byte("53 No proxying to other hosts or ports!\r\n"))
logEntry.Status = 53
return
@ -89,7 +89,7 @@ func handleGeminiRequest(conn net.Conn, config Config, accessLogEntries chan Log
}
// Resolve URI path to actual filesystem path, including following symlinks
raw_path := resolvePath(URL.Path, config)
raw_path := resolvePath(URL.Path, sysConfig)
path, err := filepath.EvalSymlinks(raw_path)
if err!= nil {
log.Println("Error evaluating path " + raw_path + " for symlinks: " + err.Error())
@ -99,7 +99,7 @@ func handleGeminiRequest(conn net.Conn, config Config, accessLogEntries chan Log
// If symbolic links have been used to escape the intended document directory,
// deny all knowledge
isSub, err := isSubdir(path, config.DocBase)
isSub, err := isSubdir(path, sysConfig.DocBase)
if err != nil {
log.Println("Error testing whether path " + path + " is below DocBase: " + err.Error())
}
@ -114,15 +114,15 @@ func handleGeminiRequest(conn net.Conn, config Config, accessLogEntries chan Log
// Paranoid security measures:
// Fail ASAP if the URL has mapped to a sensitive file
if path == config.CertPath || path == config.KeyPath || path == config.AccessLog || path == config.ErrorLog || filepath.Base(path) == ".molly" {
if path == sysConfig.CertPath || path == sysConfig.KeyPath || path == sysConfig.AccessLog || path == sysConfig.ErrorLog || filepath.Base(path) == ".molly" {
conn.Write([]byte("51 Not found!\r\n"))
logEntry.Status = 51
return
}
// Read Molly files
if config.ReadMollyFiles {
parseMollyFiles(path, &config)
if sysConfig.ReadMollyFiles {
config = parseMollyFiles(path, sysConfig.DocBase, config)
}
// Check whether this URL is in a certificate zone
@ -138,17 +138,17 @@ func handleGeminiRequest(conn net.Conn, config Config, accessLogEntries chan Log
}
// Check whether this URL is mapped to an SCGI app
for scgiPath, scgiSocket := range config.SCGIPaths {
for scgiPath, scgiSocket := range sysConfig.SCGIPaths {
if strings.HasPrefix(URL.Path, scgiPath) {
handleSCGI(URL, scgiPath, scgiSocket, config, &logEntry, conn)
handleSCGI(URL, scgiPath, scgiSocket, sysConfig, &logEntry, conn)
return
}
}
// Check whether this URL is in a configured CGI path
for _, cgiPath := range config.CGIPaths {
for _, cgiPath := range sysConfig.CGIPaths {
if strings.HasPrefix(path, cgiPath) {
handleCGI(config, path, cgiPath, URL, &logEntry, conn)
handleCGI(sysConfig, path, cgiPath, URL, &logEntry, conn)
if logEntry.Status != 0 {
return
}
@ -212,7 +212,7 @@ func readRequest(conn net.Conn, logEntry *LogEntry) (*url.URL, error) {
return URL, nil
}
func resolvePath(path string, config Config) string {
func resolvePath(path string, config SysConfig) string {
// Handle tildes
if strings.HasPrefix(path, "/~") {
bits := strings.Split(path, "/")
@ -226,7 +226,7 @@ func resolvePath(path string, config Config) string {
return path
}
func handleRedirects(URL *url.URL, config Config, conn net.Conn, logEntry *LogEntry) {
func handleRedirects(URL *url.URL, config UserConfig, conn net.Conn, logEntry *LogEntry) {
handleRedirectsInner(URL, config.TempRedirects, 30, conn, logEntry)
handleRedirectsInner(URL, config.PermRedirects, 31, conn, logEntry)
}
@ -252,7 +252,7 @@ func handleRedirectsInner(URL *url.URL, redirects map[string]string, status int,
}
}
func serveDirectory(URL *url.URL, path string, logEntry *LogEntry, conn net.Conn, config Config) {
func serveDirectory(URL *url.URL, path string, logEntry *LogEntry, conn net.Conn, config UserConfig) {
// Redirect to add trailing slash if missing
// (otherwise relative links don't work properly)
if !strings.HasSuffix(URL.Path, "/") {
@ -281,7 +281,7 @@ func serveDirectory(URL *url.URL, path string, logEntry *LogEntry, conn net.Conn
}
}
func serveFile(path string, logEntry *LogEntry, conn net.Conn, config Config) {
func serveFile(path string, logEntry *LogEntry, conn net.Conn, config UserConfig) {
// Get MIME type of files
ext := filepath.Ext(path)
var mimeType string

View file

@ -16,12 +16,12 @@ import (
var VERSION = "0.0.0"
func launch(config Config, privInfo userInfo) int {
func launch(sysConfig SysConfig, userConfig UserConfig, privInfo userInfo) int {
var err error
// Open log files
if config.ErrorLog != "" {
errorLogFile, err := os.OpenFile(config.ErrorLog, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if sysConfig.ErrorLog != "" {
errorLogFile, err := os.OpenFile(sysConfig.ErrorLog, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Println("Error opening error log file: " + err.Error())
return 1
@ -32,10 +32,10 @@ func launch(config Config, privInfo userInfo) int {
log.SetFlags(log.Ldate|log.Ltime)
var accessLogFile *os.File
if config.AccessLog == "-" {
if sysConfig.AccessLog == "-" {
accessLogFile = os.Stdout
} else if config.AccessLog != "" {
accessLogFile, err = os.OpenFile(config.AccessLog, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
} else if sysConfig.AccessLog != "" {
accessLogFile, err = os.OpenFile(sysConfig.AccessLog, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Println("Error opening access log file: " + err.Error())
return 1
@ -45,22 +45,22 @@ func launch(config Config, privInfo userInfo) int {
// Read TLS files, create TLS config
// Check key file permissions first
info, err := os.Stat(config.KeyPath)
info, err := os.Stat(sysConfig.KeyPath)
if err != nil {
log.Println("Error opening TLS key file: " + err.Error())
return 1
}
if uint64(info.Mode().Perm())&0444 == 0444 {
log.Println("Refusing to use world-readable TLS key file " + config.KeyPath)
log.Println("Refusing to use world-readable TLS key file " + sysConfig.KeyPath)
return 1
}
// Check certificate hostname matches server hostname
info, err = os.Stat(config.CertPath)
info, err = os.Stat(sysConfig.CertPath)
if err != nil {
log.Println("Error opening TLS certificate file: " + err.Error())
return 1
}
certFile, err := os.Open(config.CertPath)
certFile, err := os.Open(sysConfig.CertPath)
if err != nil {
log.Println("Error opening TLS certificate file: " + err.Error())
return 1
@ -76,7 +76,7 @@ func launch(config Config, privInfo userInfo) int {
return 1
}
certx509, err := x509.ParseCertificate(certDer.Bytes)
err = certx509.VerifyHostname(config.Hostname)
err = certx509.VerifyHostname(sysConfig.Hostname)
if err != nil {
log.Println("Invalid TLS certificate: " + err.Error())
return 1
@ -88,7 +88,7 @@ func launch(config Config, privInfo userInfo) int {
}
// Load certificate and private key
cert, err := tls.LoadX509KeyPair(config.CertPath, config.KeyPath)
cert, err := tls.LoadX509KeyPair(sysConfig.CertPath, sysConfig.KeyPath)
if err != nil {
log.Println("Error loading TLS keypair: " + err.Error())
return 1
@ -96,7 +96,7 @@ func launch(config Config, privInfo userInfo) int {
var tlscfg tls.Config
tlscfg.Certificates = []tls.Certificate{cert}
tlscfg.ClientAuth = tls.RequestClientCert
if config.AllowTLS12 {
if sysConfig.AllowTLS12 {
tlscfg.MinVersion = tls.VersionTLS12
} else {
tlscfg.MinVersion = tls.VersionTLS13
@ -110,14 +110,14 @@ func launch(config Config, privInfo userInfo) int {
}
// Apply security restrictions
err = enableSecurityRestrictions(config, privInfo)
err = enableSecurityRestrictions(sysConfig, privInfo)
if err != nil {
log.Println("Exiting due to failure to apply security restrictions.")
return 1
}
// Create TLS listener
listener, err := tls.Listen("tcp", ":"+strconv.Itoa(config.Port), &tlscfg)
listener, err := tls.Listen("tcp", ":"+strconv.Itoa(sysConfig.Port), &tlscfg)
if err != nil {
log.Println("Error creating TLS listener: " + err.Error())
return 1
@ -126,7 +126,7 @@ func launch(config Config, privInfo userInfo) int {
// Start log handling routines
var accessLogEntries chan LogEntry
if config.AccessLog == "" {
if sysConfig.AccessLog == "" {
accessLogEntries = nil
} else {
accessLogEntries = make(chan LogEntry, 10)
@ -156,7 +156,7 @@ func launch(config Config, privInfo userInfo) int {
conn, err := listener.Accept()
if err == nil {
wg.Add(1)
go handleGeminiRequest(conn, config, accessLogEntries, &wg)
go handleGeminiRequest(conn, sysConfig, userConfig, accessLogEntries, &wg)
} else {
select {
case <-shutdown:

View file

@ -25,12 +25,12 @@ func main() {
}
// Read config
config, err := getConfig(conf_file)
sysConfig, userConfig, err := getConfig(conf_file)
if err != nil {
log.Fatal(err)
}
// Run server and exit
var dummy userInfo
os.Exit(launch(config, dummy))
os.Exit(launch(sysConfig, userConfig, dummy))
}

View file

@ -30,7 +30,7 @@ func main() {
}
// Read config
config, err := getConfig(conf_file)
sysConfig, userConfig, err := getConfig(conf_file)
if err != nil {
log.Fatal(err)
}
@ -51,5 +51,5 @@ func main() {
}
// Run server and exit
os.Exit(launch(config, privInfo))
os.Exit(launch(sysConfig, userConfig, privInfo))
}

View file

@ -9,6 +9,6 @@ type userInfo struct {
// This is intended to be called immediately prior to accepting client
// connections and may be used to establish a security "jail" for the molly
// brown executable.
func enableSecurityRestrictions(config Config, ui userInfo) error {
func enableSecurityRestrictions(config SysConfig, ui userInfo) error {
return nil
}

View file

@ -7,7 +7,7 @@ import (
"os"
)
func enableSecurityRestrictions(config Config, ui userInfo) error {
func enableSecurityRestrictions(config SysConfig, ui userInfo) error {
// Prior to Go 1.6, setuid did not work reliably on Linux
// So, absolutely refuse to run as root

View file

@ -11,7 +11,7 @@ import (
// operations available to the molly brown executable. Please note that (S)CGI
// processes that molly brown spawns or communicates with are unrestricted
// and should pledge their own restrictions and unveil their own files.
func enableSecurityRestrictions(config Config, ui userInfo) error {
func enableSecurityRestrictions(config SysConfig, ui userInfo) error {
// Setuid to an unprivileged user
err := DropPrivs(ui)

View file

@ -2,7 +2,7 @@
package main
func enableSecurityRestrictions(config Config, ui userInfo) error {
func enableSecurityRestrictions(config SysConfig, ui userInfo) error {
// Setuid to an unprivileged user
return DropPrivs(ui)