Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions api/authenticators/saml.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (self *SamlAuthenticator) AuthRedirectTemplate() string {
}

func (self *SamlAuthenticator) AddHandlers(mux *api_utils.ServeMux) error {
logger := logging.Manager.GetLogger(self.config_obj, &logging.GUIComponent)
logger := logging.GetLogger(self.config_obj, &logging.GUIComponent)
key, err := crypto_utils.ParseRsaPrivateKeyFromPemStr([]byte(
self.authenticator.SamlPrivateKey))
if err != nil {
Expand Down Expand Up @@ -148,7 +148,7 @@ func (self *SamlAuthenticator) AuthenticateUserHandler(
Set("roles", self.user_roles).
Set("remote", r.RemoteAddr))
if err != nil {
logger := logging.Manager.GetLogger(self.config_obj, &logging.GUIComponent)
logger := logging.GetLogger(self.config_obj, &logging.GUIComponent)
logger.Error("<red>Authorization failed</> %v %v %v",
username, err, r.RemoteAddr)
}
Expand All @@ -167,7 +167,7 @@ func (self *SamlAuthenticator) AuthenticateUserHandler(
Set("roles", self.user_roles).
Set("remote", r.RemoteAddr))
if err != nil {
logger := logging.Manager.GetLogger(self.config_obj, &logging.GUIComponent)
logger := logging.GetLogger(self.config_obj, &logging.GUIComponent)
logger.Error("<red>Role Assignment Failed</> %v %v",
username, r.RemoteAddr)
}
Expand All @@ -189,7 +189,7 @@ func (self *SamlAuthenticator) AuthenticateUserHandler(
Set("remote", r.RemoteAddr).
Set("status", http.StatusUnauthorized))
if err != nil {
logger := logging.Manager.GetLogger(self.config_obj, &logging.GUIComponent)
logger := logging.GetLogger(self.config_obj, &logging.GUIComponent)
logger.Error("<red>no saml_user_roles set</> %v %v",
username, r.RemoteAddr)
}
Expand Down
8 changes: 4 additions & 4 deletions api/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ func StartFrontendWithAutocert(
return errors.New("Frontend server not configured")
}

logger := logging.Manager.GetLogger(config_obj, &logging.GUIComponent)
logger := logging.GetLogger(config_obj, &logging.GUIComponent)

// Autocert directory must be unique since it is usually kept in
// shared storage.
Expand Down Expand Up @@ -550,7 +550,7 @@ func StartFrontendWithAutocert(
go func() {
err := http.ListenAndServe(":http", certManager.HTTPHandler(nil))
if err != nil {
logger := logging.Manager.GetLogger(config_obj, &logging.GUIComponent)
logger := logging.GetLogger(config_obj, &logging.GUIComponent)
logger.Error("Failed to bind to http server: %v", err)
}
}()
Expand Down Expand Up @@ -616,7 +616,7 @@ func StartHTTPGUI(
return errors.New("GUI server not configured")
}

logger := logging.Manager.GetLogger(config_obj, &logging.GUIComponent)
logger := logging.GetLogger(config_obj, &logging.GUIComponent)

listenAddr := fmt.Sprintf("%s:%d",
config_obj.GUI.BindAddress,
Expand Down Expand Up @@ -672,7 +672,7 @@ func StartSelfSignedGUI(
ctx context.Context,
wg *sync.WaitGroup,
config_obj *config_proto.Config, mux http.Handler) error {
logger := logging.Manager.GetLogger(config_obj, &logging.GUIComponent)
logger := logging.GetLogger(config_obj, &logging.GUIComponent)
if config_obj.GUI == nil {
return errors.New("GUI server not configured")
}
Expand Down
4 changes: 4 additions & 0 deletions bin/admin_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ func checkMutex() error { return nil }
func logArgv(argv []string) error {
return nil
}

func InstallAuditlogger() error {
return nil
}
41 changes: 41 additions & 0 deletions bin/admin_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"fmt"
"syscall"

log "github.com/sirupsen/logrus"
"golang.org/x/sys/windows/svc/eventlog"
"www.velocidex.com/golang/velociraptor/json"
logging "www.velocidex.com/golang/velociraptor/logging"
vql_subsystem "www.velocidex.com/golang/velociraptor/vql"
)

Expand Down Expand Up @@ -47,3 +49,42 @@ func logArgv(argv []string) error {

return logger.Info(1000, msg)
}

type EventlogHook struct {
logger *eventlog.Log
}

func (self *EventlogHook) Fire(entry *log.Entry) error {
msg, err := entry.String()
if err != nil {
fmt.Printf("Eror: %v\n", err)
return nil
}
return self.logger.Info(1000, msg)
}

func (self *EventlogHook) Levels() []log.Level {
return []log.Level{log.InfoLevel, log.WarnLevel, log.ErrorLevel}
}

func InstallAuditlogger() error {
source_name := "Velociraptor"
err := eventlog.InstallAsEventCreate(
source_name, eventlog.Error|eventlog.Warning|eventlog.Info)
if err != nil {
// If we fail to register our own source (maybe due to
// permission errors) we steal the .NET source
source_name = ".NET Runtime"
}

logger, err := eventlog.Open(source_name)
if err != nil {
return err
}
hook := &EventlogHook{
logger: logger,
}

logging.Manager().AddHook(hook, &logging.Audit)
return nil
}
5 changes: 5 additions & 0 deletions bin/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ func doClient() error {
return fmt.Errorf("Unable to load config file: %w", err)
}

err = InstallAuditlogger()
if err != nil {
return err
}

return RunClient(ctx, config_obj)
}

Expand Down
1 change: 0 additions & 1 deletion bin/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ func (self *CollectorTestSuite) TestCollectorPlain() {
"--args", "target=ZIP",
"--args", "opt_admin=N",
"--args", "opt_prompt=N",
"--args", "template=Custom.TestArtifact",
"--output", output_zip,
}

Expand Down
1 change: 1 addition & 0 deletions bin/installer_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ func runOnce(ctx context.Context,
}

maybeWritePanicFile(log_name, config_obj)
_ = InstallAuditlogger()

writeback_service := writeback.GetWritebackService()
writeback, err := writeback_service.GetWriteback(config_obj)
Expand Down
11 changes: 11 additions & 0 deletions http_comms/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"fmt"
"sync"

"github.com/Velocidex/ordereddict"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
crypto_client "www.velocidex.com/golang/velociraptor/crypto/client"
"www.velocidex.com/golang/velociraptor/executor"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/services/writeback"
"www.velocidex.com/golang/velociraptor/utils"
)
Expand Down Expand Up @@ -36,6 +38,15 @@ func StartHttpCommunicatorService(
return nil, err
}

err = services.LogAudit(ctx, config_obj,
utils.GetSuperuserName(config_obj), "client_communicator",
ordereddict.NewDict().
Set("server_urls", config_obj.Client.ServerUrls))
if err != nil {
fmt.Printf("Error: %v\n", err)
return nil, err
}

// Now start the communicator so we can talk with the server.
comm, err := NewHTTPCommunicator(
ctx,
Expand Down
55 changes: 38 additions & 17 deletions logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ var (
Audit = "VelociraptorAudit"

// Lock for log manager.
mu sync.Mutex
Manager *LogManager
mu sync.Mutex
manager *LogManager

disable_log_to_files bool
node_name = ""

Expand All @@ -69,6 +70,13 @@ var (
closing_tag_regex = regexp.MustCompile("</>")
)

func Manager() *LogManager {
mu.Lock()
defer mu.Unlock()

return manager
}

func SetNodeName(name string) {
mu.Lock()
defer mu.Unlock()
Expand All @@ -86,8 +94,7 @@ func DisableLogging() {
}

func InitLogging(config_obj *config_proto.Config) error {
mu.Lock()
Manager = &LogManager{
new_manager := &LogManager{
contexts: make(map[*string]*LogContext),
}

Expand All @@ -102,21 +109,23 @@ func InitLogging(config_obj *config_proto.Config) error {
}

for _, component := range components {
logger, err := Manager.makeNewComponent(config_obj, component)
logger, err := new_manager.makeNewComponent(config_obj, component)
if err != nil {
mu.Unlock()
return err
}
Manager.contexts[component] = logger
new_manager.contexts[component] = logger
}

err := maybeAddRemoteSyslog(config_obj, Manager)
mu.Unlock()

err := maybeAddRemoteSyslog(config_obj, new_manager)
if err != nil {
return err
}

mu.Lock()
manager = new_manager
mu.Unlock()

FlushPrelogs(config_obj)

return nil
Expand Down Expand Up @@ -274,6 +283,16 @@ type LogManager struct {
contexts map[*string]*LogContext
}

func (self *LogManager) AddHook(hook logrus.Hook, component *string) {
self.mu.Lock()
defer self.mu.Unlock()

v, pres := self.contexts[component]
if pres {
v.Logger.Hooks.Add(hook)
}
}

// Get the logger from cache - creating it if it needs to.
func (self *LogManager) GetLogger(
config_obj *config_proto.Config,
Expand Down Expand Up @@ -314,8 +333,11 @@ func (self *LogManager) Reset() {
}

func Reset() {
if Manager != nil {
Manager.Reset()
mu.Lock()
defer mu.Unlock()

if manager != nil {
manager.Reset()
}
}

Expand Down Expand Up @@ -469,7 +491,7 @@ func AddLogFile(filename string) error {
logrus.WarnLevel: fd,
}

for _, log := range Manager.contexts {
for _, log := range Manager().contexts {
log.Hooks.Add(lfshook.NewHook(
writer_map, &JSONFormatter{&logrus.JSONFormatter{
DisableHTMLEscape: true,
Expand Down Expand Up @@ -515,17 +537,16 @@ func NewPlainLogger(
}

func GetLogger(config_obj *config_proto.Config, component *string) *LogContext {
mu.Lock()
lManager := Manager
mu.Unlock()

lManager := Manager()
if lManager == nil {
err := InitLogging(config_obj)
if err != nil {
panic(err)
}
lManager = Manager()

}
return Manager.GetLogger(config_obj, component)
return lManager.GetLogger(config_obj, component)
}

type stackTracer interface {
Expand Down
8 changes: 3 additions & 5 deletions logging/syslog_nonwindows.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows

package logging
Expand Down Expand Up @@ -64,11 +65,8 @@ func maybeAddRemoteSyslog(
return err
}

for k, v := range manager.contexts {
_, pres := components[k]
if pres {
v.Logger.Hooks.Add(hook)
}
for k := range components {
manager.AddHook(hook, k)
}

return nil
Expand Down
6 changes: 6 additions & 0 deletions services/audit_manager/audit_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
"www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/utils"
)

type AuditManager struct{}
Expand All @@ -26,6 +27,11 @@ func (self *AuditManager) LogAudit(
logger := logging.GetLogger(config_obj, &logging.Audit)
logger.WithFields(logrus.Fields(record.ToMap())).Info(operation)

// Only forward the event if running on the server.
if utils.RunningOnClient(config_obj) {
return nil
}

journal, err := services.GetJournal(config_obj)
if err != nil {
return err
Expand Down
25 changes: 25 additions & 0 deletions utils/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package utils

import config_proto "www.velocidex.com/golang/velociraptor/config/proto"

// True when we are running on the client.
func RunningOnClient(config_obj *config_proto.Config) bool {
// Pure clients do not have any frontend configs.
if config_obj.Frontend == nil || config_obj.Datastore == nil {
return true
}

// Clients also run the event table service.
if config_obj.Services != nil {
if config_obj.Services.ClientEventTable {
return true
}

// Server only run the hunt dispatcher.
if config_obj.Services.HuntDispatcher {
return false
}
}

return false
}
Loading