Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions cmd/admin/handlers/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"io"
"net/http"
"os"
"strings"

"github.com/jmpsec/osctrl/cmd/admin/sessions"
"github.com/jmpsec/osctrl/pkg/carves"
Expand Down Expand Up @@ -150,4 +151,6 @@ func (h *HandlersAdmin) CarvesDownloadHandler(w http.ResponseWriter, r *http.Req
fileReader, _ = os.Open(archived.File)
_, _ = io.Copy(w, fileReader)
}
// Audit log visit
h.AuditLog.Visit(ctx[sessions.CtxUser], r.URL.Path, strings.Split(r.RemoteAddr, ":")[0], env.ID)
}
8 changes: 8 additions & 0 deletions cmd/admin/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package handlers

import (
"github.com/jmpsec/osctrl/cmd/admin/sessions"
"github.com/jmpsec/osctrl/pkg/auditlog"
"github.com/jmpsec/osctrl/pkg/backend"
"github.com/jmpsec/osctrl/pkg/cache"
"github.com/jmpsec/osctrl/pkg/carves"
Expand Down Expand Up @@ -43,6 +44,7 @@ type HandlersAdmin struct {
OptimizedUI bool
OsqueryTables []types.OsqueryTable
AdminConfig *config.JSONConfigurationService
AuditLog *auditlog.AuditLogManager
DBLogger *logging.LoggerDB
DebugHTTP *zerolog.Logger
DebugHTTPConfig *config.DebugHTTPConfiguration
Expand Down Expand Up @@ -161,6 +163,12 @@ func WithAdminConfig(config *config.JSONConfigurationService) HandlersOption {
}
}

func WithAuditLog(auditLog *auditlog.AuditLogManager) HandlersOption {
return func(h *HandlersAdmin) {
h.AuditLog = auditLog
}
}

func WithDBLogger(dbfile string, config *backend.JSONConfigurationDB) HandlersOption {
return func(h *HandlersAdmin) {
if dbfile == "" {
Expand Down
79 changes: 79 additions & 0 deletions cmd/admin/handlers/json-audit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package handlers

import (
"fmt"
"net/http"

"github.com/jmpsec/osctrl/cmd/admin/sessions"
"github.com/jmpsec/osctrl/pkg/auditlog"
"github.com/jmpsec/osctrl/pkg/environments"
"github.com/jmpsec/osctrl/pkg/users"
"github.com/jmpsec/osctrl/pkg/utils"
"github.com/rs/zerolog/log"
)

// AuditLogJSON to be used to populate JSON data for audit logs
type AuditLogJSON struct {
Service string `json:"service"`
Username string `json:"username"`
Line string `json:"line"`
SourceIP string `json:"sourceip"`
LogType string `json:"logtype"`
Severity string `json:"severity"`
Env string `json:"environment"`
When CreationTimes `json:"when"`
}

// ReturnedAudit to return a JSON with audit logs
type ReturnedAudit struct {
Data []AuditLogJSON `json:"data"`
}

// JSONTagsHandler for audit logs in JSON
func (h *HandlersAdmin) JSONAuditLogHandler(w http.ResponseWriter, r *http.Request) {
if h.DebugHTTPConfig.Enabled {
utils.DebugHTTPDump(h.DebugHTTP, r, h.DebugHTTPConfig.ShowBody)
}
// Get context data
ctx := r.Context().Value(sessions.ContextKey(sessions.CtxSession)).(sessions.ContextValue)
// Check permissions
if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.AdminLevel, users.NoEnvironment) {
adminErrorResponse(w, fmt.Sprintf("%s has insufficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
return
}
// Get all environments
envs, err := h.Envs.All()
if err != nil {
log.Err(err).Msg("error getting environments")
return
}
// Get audit logs
auditLogs, err := h.AuditLog.GetAll()
if err != nil {
log.Err(err).Msg("error getting audit logs")
return
}
// Prepare data to be returned
var auditLogsJSON []AuditLogJSON
for _, logEntry := range auditLogs {
auditLogsJSON = append(auditLogsJSON, AuditLogJSON{
Service: logEntry.Service,
Username: logEntry.Username,
Line: logEntry.Line,
SourceIP: logEntry.SourceIP,
LogType: auditlog.LogTypeToString(logEntry.LogType),
Severity: auditlog.SeverityToString(logEntry.Severity),
Env: environments.EnvironmentFinderID(logEntry.EnvironmentID, envs, false),
When: CreationTimes{
Display: utils.PastFutureTimes(logEntry.CreatedAt),
// Use Unix timestamp in seconds
Timestamp: utils.TimeTimestamp(logEntry.CreatedAt),
},
})
}
returned := ReturnedAudit{
Data: auditLogsJSON,
}
// Serve JSON
utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, returned)
}
59 changes: 25 additions & 34 deletions cmd/admin/handlers/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net/http"

"github.com/jmpsec/osctrl/cmd/admin/sessions"
"github.com/jmpsec/osctrl/pkg/auditlog"
"github.com/jmpsec/osctrl/pkg/handlers"
"github.com/jmpsec/osctrl/pkg/nodes"
"github.com/jmpsec/osctrl/pkg/queries"
Expand Down Expand Up @@ -45,7 +46,7 @@ func (h *HandlersAdmin) LoginPOSTHandler(w http.ResponseWriter, r *http.Request)
return
}
// Serialize and send response
log.Debug().Msg("Login response sent")
h.AuditLog.NewLogin(user.Username, strings.Split(r.RemoteAddr, ":")[0])
adminOKResponse(w, "/dashboard")
}

Expand Down Expand Up @@ -74,7 +75,7 @@ func (h *HandlersAdmin) LogoutPOSTHandler(w http.ResponseWriter, r *http.Request
return
}
// Serialize and send response
log.Debug().Msg("Logout response sent")
h.AuditLog.NewLogout(ctx[sessions.CtxUser], strings.Split(r.RemoteAddr, ":")[0])
adminOKResponse(w, "OK")
}

Expand Down Expand Up @@ -172,7 +173,7 @@ func (h *HandlersAdmin) QueryRunPOSTHandler(w http.ResponseWriter, r *http.Reque
}
}
// Serialize and send response
log.Debug().Msg("Query run response sent")
h.AuditLog.NewQuery(ctx[sessions.CtxUser], q.Query, strings.Split(r.RemoteAddr, ":")[0], env.ID)
adminOKResponse(w, "OK")
}

Expand Down Expand Up @@ -262,7 +263,7 @@ func (h *HandlersAdmin) CarvesRunPOSTHandler(w http.ResponseWriter, r *http.Requ
return
}
// Serialize and send response
log.Debug().Msg("Carve run response sent")
h.AuditLog.NewCarve(ctx[sessions.CtxUser], c.Path, strings.Split(r.RemoteAddr, ":")[0], env.ID)
adminOKResponse(w, "OK")
}

Expand Down Expand Up @@ -345,8 +346,7 @@ func (h *HandlersAdmin) QueryActionsPOSTHandler(w http.ResponseWriter, r *http.R
}
adminOKResponse(w, "queries delete successfully")
}
// Serialize and send response
log.Debug().Msg("Query run response sent")
h.AuditLog.QueryAction(ctx[sessions.CtxUser], q.Action, strings.Split(r.RemoteAddr, ":")[0], env.ID)
}

// CarvesActionsPOSTHandler - Handler for POST requests to carves
Expand Down Expand Up @@ -402,8 +402,7 @@ func (h *HandlersAdmin) CarvesActionsPOSTHandler(w http.ResponseWriter, r *http.
log.Debug().Msg("testing action")
adminOKResponse(w, "test successful")
}
// Serialize and send response
log.Debug().Msg("Carves action response sent")
h.AuditLog.CarveAction(ctx[sessions.CtxUser], q.Action, strings.Split(r.RemoteAddr, ":")[0], env.ID)
}

// ConfPOSTHandler for POST requests for saving configuration
Expand Down Expand Up @@ -466,8 +465,8 @@ func (h *HandlersAdmin) ConfPOSTHandler(w http.ResponseWriter, r *http.Request)
adminErrorResponse(w, "error saving configuration parts", http.StatusInternalServerError, err)
return
}
h.AuditLog.ConfAction(ctx[sessions.CtxUser], "update configuration", strings.Split(r.RemoteAddr, ":")[0], env.ID)
// Send response
log.Debug().Msg("Configuration response sent")
adminOKResponse(w, "configuration saved successfully")
return
}
Expand All @@ -489,8 +488,8 @@ func (h *HandlersAdmin) ConfPOSTHandler(w http.ResponseWriter, r *http.Request)
adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
return
}
h.AuditLog.ConfAction(ctx[sessions.CtxUser], "update options", strings.Split(r.RemoteAddr, ":")[0], env.ID)
// Send response
log.Debug().Msg("Options response sent")
adminOKResponse(w, "options saved successfully")
return
}
Expand All @@ -512,8 +511,8 @@ func (h *HandlersAdmin) ConfPOSTHandler(w http.ResponseWriter, r *http.Request)
adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
return
}
h.AuditLog.ConfAction(ctx[sessions.CtxUser], "update schedule", strings.Split(r.RemoteAddr, ":")[0], env.ID)
// Send response
log.Debug().Msg("Schedule response sent")
adminOKResponse(w, "schedule saved successfully")
return
}
Expand All @@ -535,8 +534,8 @@ func (h *HandlersAdmin) ConfPOSTHandler(w http.ResponseWriter, r *http.Request)
adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
return
}
h.AuditLog.ConfAction(ctx[sessions.CtxUser], "update packs", strings.Split(r.RemoteAddr, ":")[0], env.ID)
// Send response
log.Debug().Msg("Packs response sent")
adminOKResponse(w, "packs saved successfully")
return
}
Expand All @@ -558,8 +557,8 @@ func (h *HandlersAdmin) ConfPOSTHandler(w http.ResponseWriter, r *http.Request)
adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
return
}
h.AuditLog.ConfAction(ctx[sessions.CtxUser], "update decorators", strings.Split(r.RemoteAddr, ":")[0], env.ID)
// Send response
log.Debug().Msg("Decorators response sent")
adminOKResponse(w, "decorators saved successfully")
return
}
Expand All @@ -581,8 +580,8 @@ func (h *HandlersAdmin) ConfPOSTHandler(w http.ResponseWriter, r *http.Request)
adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
return
}
h.AuditLog.ConfAction(ctx[sessions.CtxUser], "update ATC", strings.Split(r.RemoteAddr, ":")[0], env.ID)
// Send response
log.Debug().Msg("ATC response sent")
adminOKResponse(w, "ATC saved successfully")
return
}
Expand Down Expand Up @@ -644,8 +643,8 @@ func (h *HandlersAdmin) IntervalsPOSTHandler(w http.ResponseWriter, r *http.Requ
adminErrorResponse(w, "error updating flags", http.StatusInternalServerError, err)
return
}
h.AuditLog.ConfAction(ctx[sessions.CtxUser], "update intervals", strings.Split(r.RemoteAddr, ":")[0], env.ID)
// Serialize and send response
log.Debug().Msg("Intervals response sent")
adminOKResponse(w, "intervals saved successfully")
}

Expand Down Expand Up @@ -741,8 +740,7 @@ func (h *HandlersAdmin) ExpirationPOSTHandler(w http.ResponseWriter, r *http.Req
adminOKResponse(w, "link set to not expire successfully")
}
}
// Serialize and send response
log.Debug().Msg("Expiration response sent")
h.AuditLog.ConfAction(ctx[sessions.CtxUser], fmt.Sprintf("%s:%s", e.Type, e.Action), strings.Split(r.RemoteAddr, ":")[0], env.ID)
}

// NodeActionsPOSTHandler for POST requests for multi node action
Expand Down Expand Up @@ -787,8 +785,7 @@ func (h *HandlersAdmin) NodeActionsPOSTHandler(w http.ResponseWriter, r *http.Re
return
}
}
// Serialize and send response
log.Debug().Msg("Multi-node action response sent")
h.AuditLog.NodeAction(ctx[sessions.CtxUser], m.Action, strings.Split(r.RemoteAddr, ":")[0], auditlog.NoEnvironment)
}

// EnvsPOSTHandler for POST request for /environments
Expand Down Expand Up @@ -878,8 +875,7 @@ func (h *HandlersAdmin) EnvsPOSTHandler(w http.ResponseWriter, r *http.Request)
}
adminOKResponse(w, "debug changed successfully")
}
// Serialize and send response
log.Debug().Msg("Environments response sent")
h.AuditLog.EnvAction(ctx[sessions.CtxUser], fmt.Sprintf("%s - %s", c.Action, c.Name), strings.Split(r.RemoteAddr, ":")[0], auditlog.NoEnvironment)
}

// SettingsPOSTHandler for POST request for /settings
Expand Down Expand Up @@ -963,8 +959,7 @@ func (h *HandlersAdmin) SettingsPOSTHandler(w http.ResponseWriter, r *http.Reque
}
adminOKResponse(w, "setting deleted successfully")
}
// Serialize and send response
log.Debug().Msg("Settings response sent")
h.AuditLog.SettingsAction(ctx[sessions.CtxUser], fmt.Sprintf("%s - %s", s.Action, s.Name), strings.Split(r.RemoteAddr, ":")[0])
}

// UsersPOSTHandler for POST request for /users
Expand Down Expand Up @@ -1112,8 +1107,7 @@ func (h *HandlersAdmin) UsersPOSTHandler(w http.ResponseWriter, r *http.Request)
adminOKResponse(w, "service changed successfully")
}
}
// Serialize and send response
log.Debug().Msg("Users response sent")
h.AuditLog.UserAction(ctx[sessions.CtxUser], fmt.Sprintf("%s - %s", u.Action, u.Username), strings.Split(r.RemoteAddr, ":")[0])
}

// TagsPOSTHandler for POST request for /tags
Expand Down Expand Up @@ -1205,8 +1199,7 @@ func (h *HandlersAdmin) TagsPOSTHandler(w http.ResponseWriter, r *http.Request)
}
adminOKResponse(w, "tag removed successfully")
}
// Serialize and send response
log.Debug().Msg("Tags response sent")
h.AuditLog.TagAction(ctx[sessions.CtxUser], fmt.Sprintf("%s - %s", t.Action, t.Name), strings.Split(r.RemoteAddr, ":")[0], env.ID)
}

// TagNodesPOSTHandler for POST request for /tags/nodes
Expand Down Expand Up @@ -1263,8 +1256,9 @@ func (h *HandlersAdmin) TagNodesPOSTHandler(w http.ResponseWriter, r *http.Reque
return
}
}
aMsg := fmt.Sprintf("tags processed: add %d, remove %d", len(t.TagsAdd), len(t.TagsRemove))
h.AuditLog.TagAction(ctx[sessions.CtxUser], aMsg, strings.Split(r.RemoteAddr, ":")[0], toBeProcessed[0].EnvironmentID)
// Serialize and send response
log.Debug().Msg("Tags response sent")
adminOKResponse(w, "tags processed successfully")
}

Expand Down Expand Up @@ -1322,8 +1316,8 @@ func (h *HandlersAdmin) PermissionsPOSTHandler(w http.ResponseWriter, r *http.Re
return
}
}
h.AuditLog.UserAction(ctx[sessions.CtxUser], fmt.Sprintf("permissions - %s", usernameVar), strings.Split(r.RemoteAddr, ":")[0])
// Serialize and send response
log.Debug().Msg("Users response sent")
adminOKResponse(w, "permissions updated successfully")
}

Expand Down Expand Up @@ -1423,8 +1417,8 @@ func (h *HandlersAdmin) EnrollPOSTHandler(w http.ResponseWriter, r *http.Request
}
}
}
h.AuditLog.EnvAction(ctx[sessions.CtxUser], fmt.Sprintf("%s - %s", e.Action, env.Name), strings.Split(r.RemoteAddr, ":")[0], env.ID)
// Serialize and send response
log.Debug().Msg("Configuration response sent")
adminOKResponse(w, "enroll data saved")
}

Expand Down Expand Up @@ -1491,8 +1485,7 @@ func (h *HandlersAdmin) EditProfilePOSTHandler(w http.ResponseWriter, r *http.Re
}
adminOKResponse(w, "profiled updated successfully")
}
// Serialize and send response
log.Debug().Msg("Edit profile response sent")
h.AuditLog.UserAction(ctx[sessions.CtxUser], fmt.Sprintf("%s - %s", u.Action, u.Username), strings.Split(r.RemoteAddr, ":")[0])
}

// SavedQueriesPOSTHandler for POST requests to save queries
Expand Down Expand Up @@ -1520,6 +1513,4 @@ func (h *HandlersAdmin) SavedQueriesPOSTHandler(w http.ResponseWriter, r *http.R
case "edit":
adminOKResponse(w, "query saved successfully")
}
// Serialize and send response
log.Debug().Msg("Saved query response sent")
}
Loading
Loading