diff --git a/droppriv_unix.go b/droppriv_unix.go new file mode 100644 index 000000000000..8af2efd1175c --- /dev/null +++ b/droppriv_unix.go @@ -0,0 +1,30 @@ +package main + +import ( + "syscall" +) + +func DropPrivileges() error { + var err error + + if !_ConfigMeta.IsDefined("runoptions", "uid") { + // not found, no dropping privileges but no err + return nil + } + + if !_ConfigMeta.IsDefined("runoptions", "gid") { + return MsgError("GID must be specified for dropping privileges") + } + + INFO("Switching to user: %d.%d", _Config.RunOptions.Uid, _Config.RunOptions.Gid) + + if err = syscall.Setgid(_Config.RunOptions.Gid); err != nil { + return MsgError("setgid: %s", err.Error()) + } + + if err = syscall.Setuid(_Config.RunOptions.Uid); err != nil { + return MsgError("setuid: %s", err.Error()) + } + + return nil +} diff --git a/droppriv_windows.go b/droppriv_windows.go new file mode 100644 index 000000000000..84ff27a7ba92 --- /dev/null +++ b/droppriv_windows.go @@ -0,0 +1,16 @@ +package main + +import ( + "syscall" +) + +func DropPrivileges() error { + var err error + + if !_ConfigMeta.IsDefined("runoptions", "uid") { + // not found, no dropping privileges but no err + return nil + } + + return MsgError("Dropping privileges is not supported on Windows") +} diff --git a/http_test.go b/http_test.go index d8dd5834ee3e..e559d4ad81d0 100644 --- a/http_test.go +++ b/http_test.go @@ -2,7 +2,6 @@ package main import ( "bytes" - "log/syslog" "testing" "time" //"fmt" @@ -382,7 +381,7 @@ func TestHttpParser_splitResponse_midBody(t *testing.T) { } func TestHttpParser_RequestResponse(t *testing.T) { - LogInit(syslog.LOG_CRIT, "" /*toSyslog*/, false, []string{}) + LogInit(LOG_CRIT, "" /*toSyslog*/, false, []string{}) data := []byte( "GET / HTTP/1.1\r\n" + diff --git a/log.go b/log_unix.go similarity index 89% rename from log.go rename to log_unix.go index 3f74147888e5..27d17c1ac290 100644 --- a/log.go +++ b/log_unix.go @@ -8,6 +8,21 @@ import ( "runtime/debug" ) +type Priority int +const ( + // Severity. + + // From /usr/include/sys/syslog.h. + // These are the same on Linux, BSD, and OS X. + LOG_EMERG Priority = iota + LOG_ALERT + LOG_CRIT + LOG_ERR + LOG_WARNING + LOG_NOTICE + LOG_INFO + LOG_DEBUG +) type Logger struct { toSyslog bool level syslog.Priority @@ -107,9 +122,9 @@ func openSyslog(level syslog.Priority, prefix string) *log.Logger { return logger } -func LogInit(level syslog.Priority, prefix string, toSyslog bool, debugSelectors []string) { +func LogInit(level Priority, prefix string, toSyslog bool, debugSelectors []string) { _log.toSyslog = toSyslog - _log.level = level + _log.level = syslog.Priority(level) _log.selectors = make(map[string]bool) for _, selector := range debugSelectors { diff --git a/log_windows.go b/log_windows.go new file mode 100644 index 000000000000..e19ea3c60c34 --- /dev/null +++ b/log_windows.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "log" + "os" + "runtime/debug" +) +type Logger struct { + toSyslog bool + level Priority + selectors map[string]bool + + logger *log.Logger +} + +type Priority int +const ( + // Severity. + + // From /usr/include/sys/syslog.h. + // These are the same on Linux, BSD, and OS X. + LOG_EMERG Priority = iota + LOG_ALERT + LOG_CRIT + LOG_ERR + LOG_WARNING + LOG_NOTICE + LOG_INFO + LOG_DEBUG +) + +var _log Logger + +func DEBUG(selector string, format string, v ...interface{}) { + if _log.level >= LOG_DEBUG { + selected := _log.selectors[selector] + if !selected { + return + } + _log.logger.Output(2, fmt.Sprintf("DBG "+format, v...)) + } +} + +func IS_DEBUG(selector string) bool { + return _log.selectors[selector] +} + +func INFO(format string, v ...interface{}) { + if _log.level >= LOG_INFO { + _log.logger.Output(2, fmt.Sprintf("INFO "+format, v...)) + } +} + +func WARN(format string, v ...interface{}) { + if _log.level >= LOG_WARNING { + _log.logger.Output(2, fmt.Sprintf("WARN "+format, v...)) + } +} + +func ERR(format string, v ...interface{}) { + if _log.level >= LOG_ERR { + _log.logger.Output(2, fmt.Sprintf("ERR "+format, v...)) + } +} + +func CRIT(format string, v ...interface{}) { + if _log.level >= LOG_CRIT { + _log.logger.Output(2, fmt.Sprintf("CRIT "+format, v...)) + } +} + +func WTF(format string, v ...interface{}) { + if _log.level >= LOG_CRIT { + _log.logger.Output(2, fmt.Sprintf("CRIT "+format, v...)) + } + + // TODO: assert here when not in production mode +} + +func RECOVER(msg string) { + if r := recover(); r != nil { + ERR("%s. Recovering, but please report this: %s.", msg, r) + ERR("Stacktrace: %s", debug.Stack()) + } +} + +func LogInit(level Priority, prefix string, toSyslog bool, debugSelectors []string) { + _log.level = level + + _log.selectors = make(map[string]bool) + for _, selector := range debugSelectors { + _log.selectors[selector] = true + } + + _log.logger = log.New(os.Stdout, prefix, log.Lshortfile) +} diff --git a/main.go b/main.go index 8951648e5c49..86fc4ee22b1b 100644 --- a/main.go +++ b/main.go @@ -3,10 +3,8 @@ package main import ( "flag" "fmt" - "log/syslog" "strconv" "strings" - "syscall" "time" "github.com/BurntSushi/toml" @@ -150,30 +148,6 @@ func decodePktEth(datalink int, pkt *pcap.Packet) { FollowTcp(tcphdr, packet) } -func DropPrivileges() error { - var err error - - if !_ConfigMeta.IsDefined("runoptions", "uid") { - // not found, no dropping privileges but no err - return nil - } - - if !_ConfigMeta.IsDefined("runoptions", "gid") { - return MsgError("GID must be specified for dropping privileges") - } - - INFO("Switching to user: %d.%d", _Config.RunOptions.Uid, _Config.RunOptions.Gid) - - if err = syscall.Setgid(_Config.RunOptions.Gid); err != nil { - return MsgError("setgid: %s", err.Error()) - } - - if err = syscall.Setuid(_Config.RunOptions.Uid); err != nil { - return MsgError("setuid: %s", err.Error()) - } - - return nil -} func main() { @@ -189,7 +163,7 @@ func main() { flag.Parse() debugSelectors := []string{} - logLevel := syslog.LOG_DEBUG + logLevel := LOG_DEBUG if len(*debugSelectorsStr) > 0 { debugSelectors = strings.Split(*debugSelectorsStr, ",") } diff --git a/procs_test.go b/procs_test.go index ae0b2e2f4622..c8746c34f358 100644 --- a/procs_test.go +++ b/procs_test.go @@ -3,7 +3,6 @@ package main import ( "fmt" "io/ioutil" - "log/syslog" "os" "path/filepath" "testing" @@ -78,7 +77,7 @@ func AssertInt64ArraysAreEqual(t *testing.T, expected []int64, result []int64) b } func TestFindPidsByCmdlineGrep(t *testing.T) { - LogInit(syslog.LOG_DEBUG, "" /*toSyslog*/, false, []string{}) + LogInit(LOG_DEBUG, "" /*toSyslog*/, false, []string{}) proc := []TestProcFile{ {Path: "/proc/1/cmdline", Contents: "/sbin/init"}, {Path: "/proc/1/cgroup", Contents: ""}, @@ -167,7 +166,7 @@ func TestRefreshPids(t *testing.T) { } func TestFindSocketsOfPid(t *testing.T) { - LogInit(syslog.LOG_DEBUG, "" /*toSyslog*/, false, []string{}) + LogInit(LOG_DEBUG, "" /*toSyslog*/, false, []string{}) proc := []TestProcFile{ {Path: "/proc/766/fd/0", IsLink: true, Contents: "/dev/null"}, diff --git a/publish_test.go b/publish_test.go index 098706477d43..db0943882cad 100644 --- a/publish_test.go +++ b/publish_test.go @@ -3,7 +3,6 @@ package main import ( "github.com/mattbaird/elastigo/api" "github.com/mattbaird/elastigo/core" - "log/syslog" "testing" "time" ) @@ -75,7 +74,7 @@ func TestGetServerName(t *testing.T) { t.Skip("Skipping topology tests in short mode, because they require Elasticsearch") } - LogInit(syslog.LOG_DEBUG, "" /*!toSyslog*/, true, []string{}) + LogInit(LOG_DEBUG, "" /*!toSyslog*/, true, []string{}) // TODO: delete old topology api.Domain = "localhost" api.Port = "9200"