diff --git a/agent/internal/httpapi/server.go b/agent/internal/httpapi/server.go index aa78fbf..b824aea 100644 --- a/agent/internal/httpapi/server.go +++ b/agent/internal/httpapi/server.go @@ -10,6 +10,7 @@ import ( "mime" "net/http" "os" + "os/exec" "path/filepath" "regexp" "strconv" @@ -156,6 +157,8 @@ func New(agentCfg config.AgentConfig, baseDir string, ms *mediaserver.Client, st mux.HandleFunc("/v1/graphs/", s.handleGraphDetail) mux.HandleFunc("/v1/logs/recent", s.handleLogsRecent) mux.HandleFunc("/v1/metrics", s.handleMetrics) + mux.HandleFunc("/v1/time", s.handleTime) + mux.HandleFunc("/v1/time/set", s.handleTimeSet) mux.HandleFunc("/v1/versions", s.handleVersions) mux.HandleFunc("/v1/assets", s.handleAssets) mux.HandleFunc("/v1/tasks/", s.handleTask) @@ -1110,6 +1113,58 @@ func writeRawJSON(w http.ResponseWriter, status int, raw []byte) { _, _ = w.Write(raw) } +type timeResponse struct { + UnixMS int64 `json:"unix_ms"` + Formatted string `json:"formatted"` +} + +func (s *Server) handleTime(w http.ResponseWriter, r *http.Request) { + if !s.authorize(r, false) { + errorJSON(w, http.StatusUnauthorized, "unauthorized") + return + } + now := time.Now() + writeJSON(w, http.StatusOK, timeResponse{ + UnixMS: now.UnixMilli(), + Formatted: now.Format("2006-01-02 15:04:05"), + }) +} + +func (s *Server) handleTimeSet(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + errorJSON(w, http.StatusMethodNotAllowed, "method not allowed") + return + } + if !s.authorize(r, true) { + errorJSON(w, http.StatusUnauthorized, "unauthorized") + return + } + var req struct { + UnixMS int64 `json:"unix_ms"` + } + if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.UnixMS <= 0 { + errorJSON(w, http.StatusBadRequest, "invalid unix_ms") + return + } + now := time.Now() + diff := time.Duration(req.UnixMS-now.UnixMilli()) * time.Millisecond + if diff < 0 { + diff = -diff + } + if diff < 2*time.Second && diff > -2*time.Second { + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "skipped": true}) + return + } + // Set system time via date command (requires root) + t := time.UnixMilli(req.UnixMS) + dateStr := t.Format("2006-01-02 15:04:05") + if err := exec.Command("date", "-s", dateStr).Run(); err != nil { + errorJSON(w, http.StatusInternalServerError, "failed to set time: "+err.Error()) + return + } + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "set_to": dateStr}) +} + func errorJSON(w http.ResponseWriter, status int, msg string) { writeJSON(w, status, map[string]any{"error": msg}) } diff --git a/agent/safesight-edge-agent b/agent/safesight-edge-agent index d7493fb..13ecc7d 100755 Binary files a/agent/safesight-edge-agent and b/agent/safesight-edge-agent differ