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
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"`
}

// JSONAuditLogHandler 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