- agent reports the OS user it runs as (enroll + poll header) - per-machine terminal user on the edit page; defaults to the agent's own user (root on Linux) - create a new user from the panel: name, password, optional sudo group - show the reason in the terminal when a shell fails to start - bump version to 0.0.2
64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
// authenticateAgent resolves the agent identified by the Bearer token on the
|
|
// request, verifying the token against the stored hash in constant time.
|
|
// Returns nil if authentication fails.
|
|
func (s *Server) authenticateAgent(r *http.Request) *Agent {
|
|
id := r.Header.Get("X-Agent-Id")
|
|
token := bearerToken(r)
|
|
if id == "" || token == "" {
|
|
return nil
|
|
}
|
|
a, err := s.db.GetAgent(id)
|
|
if err != nil || a == nil {
|
|
return nil
|
|
}
|
|
if !constantTimeEqual(a.TokenHash, hashToken(token)) {
|
|
return nil
|
|
}
|
|
return a
|
|
}
|
|
|
|
func bearerToken(r *http.Request) string {
|
|
h := r.Header.Get("Authorization")
|
|
if strings.HasPrefix(h, "Bearer ") {
|
|
return strings.TrimPrefix(h, "Bearer ")
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// enroll creates a new agent record for a valid enroll secret and returns the
|
|
// generated id plus a one-time plaintext token (only the hash is stored).
|
|
func (s *Server) enroll(name, hostname, os, arch, version, runUser string) (id, token string, err error) {
|
|
id = randToken()[:16]
|
|
token = randToken()
|
|
a := Agent{
|
|
ID: id,
|
|
Name: firstNonEmpty(name, hostname, id),
|
|
Hostname: hostname,
|
|
OS: os,
|
|
Arch: arch,
|
|
Version: version,
|
|
RunUser: runUser,
|
|
TokenHash: hashToken(token),
|
|
}
|
|
if err = s.db.CreateAgent(a); err != nil {
|
|
return "", "", err
|
|
}
|
|
return id, token, nil
|
|
}
|
|
|
|
func firstNonEmpty(vals ...string) string {
|
|
for _, v := range vals {
|
|
if strings.TrimSpace(v) != "" {
|
|
return v
|
|
}
|
|
}
|
|
return ""
|
|
}
|