|
|
|
@ -5,6 +5,7 @@ import (
|
|
|
|
|
"log"
|
|
|
|
|
"os"
|
|
|
|
|
"os/signal"
|
|
|
|
|
"os/user"
|
|
|
|
|
"strconv"
|
|
|
|
|
"syscall"
|
|
|
|
|
"time"
|
|
|
|
@ -16,6 +17,10 @@ import (
|
|
|
|
|
"github.com/grufwub/go-logger"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Temporary check to ensure correct Go
|
|
|
|
|
// version being used
|
|
|
|
|
var _ = syscall.AllThreadsSyscall
|
|
|
|
|
|
|
|
|
|
func usage(code int) {
|
|
|
|
|
fmt.Printf("Usage: %s [-v|--version] [-c|--config $file]\n", os.Args[0])
|
|
|
|
|
os.Exit(code)
|
|
|
|
@ -47,6 +52,9 @@ func ParseConfigAndSetup(tree config.Tree, proto string, defaultPort uint, newLi
|
|
|
|
|
tree.StringVar(&Bind, "listen", "")
|
|
|
|
|
tree.StringVar(&Hostname, "hostname", "")
|
|
|
|
|
port := tree.Uint64("port", uint64(defaultPort))
|
|
|
|
|
chroot := tree.String("chroot", "")
|
|
|
|
|
username := tree.String("user", "")
|
|
|
|
|
groupname := tree.String("group", "")
|
|
|
|
|
|
|
|
|
|
// Filesystem configuration
|
|
|
|
|
fReadBuf := tree.Uint64("filesystem.read-buf", 1024)
|
|
|
|
@ -98,11 +106,54 @@ func ParseConfigAndSetup(tree config.Tree, proto string, defaultPort uint, newLi
|
|
|
|
|
Hostname = Bind
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Change to server directory
|
|
|
|
|
if osErr := os.Chdir(Root); osErr != nil {
|
|
|
|
|
SystemLog.Fatalf(chDirErrStr, osErr)
|
|
|
|
|
// - username supplied, lookup and set uid.
|
|
|
|
|
// - groupname supplied, lookup and set gid.
|
|
|
|
|
// - username but no groupname, we use the user primary gid
|
|
|
|
|
var uid, gid int
|
|
|
|
|
if *username != "" {
|
|
|
|
|
u, osErr := user.Lookup(*username)
|
|
|
|
|
if osErr != nil {
|
|
|
|
|
SystemLog.Fatalf(userLookupErrStr, osErr)
|
|
|
|
|
}
|
|
|
|
|
uid, _ = strconv.Atoi(u.Uid)
|
|
|
|
|
gid, _ = strconv.Atoi(u.Gid)
|
|
|
|
|
}
|
|
|
|
|
if *groupname != "" {
|
|
|
|
|
g, osErr := user.LookupGroup(*groupname)
|
|
|
|
|
if osErr != nil {
|
|
|
|
|
SystemLog.Fatalf(groupLookupErrStr, osErr)
|
|
|
|
|
}
|
|
|
|
|
gid, _ = strconv.Atoi(g.Gid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If chroot provided, change to this!
|
|
|
|
|
if *chroot != "" {
|
|
|
|
|
osErr := syscall.Chroot(*chroot)
|
|
|
|
|
if osErr != nil {
|
|
|
|
|
SystemLog.Fatalf(chrootErrStr, osErr)
|
|
|
|
|
}
|
|
|
|
|
SystemLog.Infof(chrootStr, *chroot)
|
|
|
|
|
|
|
|
|
|
// Ensure we're at root of chroot
|
|
|
|
|
osErr = os.Chdir("/")
|
|
|
|
|
if osErr != nil {
|
|
|
|
|
SystemLog.Fatalf(chDirErrStr, osErr)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If root is different to chroot, we change to this dir
|
|
|
|
|
if Root != *chroot {
|
|
|
|
|
osErr := os.Chdir(Root)
|
|
|
|
|
if osErr != nil {
|
|
|
|
|
SystemLog.Fatalf(chDirErrStr, osErr)
|
|
|
|
|
}
|
|
|
|
|
SystemLog.Infof(chDirStr, Root)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If chroot disabled, and root empty, this is bad!
|
|
|
|
|
if *chroot == "" && Root == "" {
|
|
|
|
|
SystemLog.Fatalf(rootDirEmptyErrStr)
|
|
|
|
|
}
|
|
|
|
|
SystemLog.Infof(chDirStr, Root)
|
|
|
|
|
|
|
|
|
|
// Set port info
|
|
|
|
|
Port = strconv.Itoa(int(*port))
|
|
|
|
@ -117,6 +168,29 @@ func ParseConfigAndSetup(tree config.Tree, proto string, defaultPort uint, newLi
|
|
|
|
|
SystemLog.Fatalf(listenerBeginFailStr, protocol, Hostname, Port, Bind, Port, err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If been supplied a group, change to requested group
|
|
|
|
|
if *groupname != "" {
|
|
|
|
|
osErr := syscall.Setgid(gid)
|
|
|
|
|
if osErr != nil {
|
|
|
|
|
SystemLog.Fatalf(setgidErrStr, osErr)
|
|
|
|
|
}
|
|
|
|
|
SystemLog.Infof(setgidStr, *groupname)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If been supplied a user, switch to requested user
|
|
|
|
|
if *username != "" {
|
|
|
|
|
osErr := syscall.Setuid(uid)
|
|
|
|
|
if osErr != nil {
|
|
|
|
|
SystemLog.Fatalf(setuidErrStr, osErr)
|
|
|
|
|
}
|
|
|
|
|
SystemLog.Infof(setuidStr, *username)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check not running as root
|
|
|
|
|
if syscall.Geteuid() == 0 || syscall.Getegid() == 0 {
|
|
|
|
|
SystemLog.Fatalf(runningAsRootErrStr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setup the sync pools
|
|
|
|
|
connBufferedReaderPool = bufpools.NewBufferedReaderPool(int(*cReadBuf))
|
|
|
|
|
connBufferedWriterPool = bufpools.NewBufferedWriterPool(int(*cWriteBuf))
|
|
|
|
@ -171,8 +245,9 @@ func ParseConfigAndSetup(tree config.Tree, proto string, defaultPort uint, newLi
|
|
|
|
|
WithinCGIDir = withinCGIDirEnabled
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If no user dir supplied, set to disabled function. Else, set user dir and enable
|
|
|
|
|
if *userSpacesEnabled {
|
|
|
|
|
// If no user dir supplied, or chroot enabled, set to disabled function.
|
|
|
|
|
// Else, set user dir and enable
|
|
|
|
|
if *userSpacesEnabled || *chroot != "" {
|
|
|
|
|
SystemLog.Info(userSpacesDisabledStr)
|
|
|
|
|
getRequestPath = getRequestPathUserSpacesDisabled
|
|
|
|
|
} else {
|
|
|
|
|