diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-19 21:51:44 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-19 21:51:44 +0200 |
| commit | 2ab8a24c188a2ba39424eb7925bc7ff3fb767bfb (patch) | |
| tree | 0867a5d189d61a6e7f6ce4accea9868014a0fe7d /internal/server | |
| parent | 91296d85e8a6f1aca5beaeeecf648683c83c75bc (diff) | |
task 261: harden server reads with OpenRoot
Diffstat (limited to 'internal/server')
| -rw-r--r-- | internal/server/handlers/readcommand.go | 27 | ||||
| -rw-r--r-- | internal/server/handlers/readcommand_server.go | 9 |
2 files changed, 24 insertions, 12 deletions
diff --git a/internal/server/handlers/readcommand.go b/internal/server/handlers/readcommand.go index d4c9c30..7f17b14 100644 --- a/internal/server/handlers/readcommand.go +++ b/internal/server/handlers/readcommand.go @@ -71,7 +71,7 @@ func (r *readCommand) Start(ctx context.Context, ltx lcontext.LContext, if isPipe { dlog.Server.Debug("Reading data from stdin pipe") // Empty file path and globID "-" represents reading from the stdin pipe. - r.read(ctx, ltx, "", "-", re) + r.read(ctx, ltx, "", nil, "-", re) return } @@ -200,17 +200,18 @@ func (r *readCommand) readFileIfPermissions(ctx context.Context, ltx lcontext.LC }() globID := r.makeGlobID(path, glob) - if !r.server.CanReadFile(path) { + target, ok := r.server.PrepareReadTarget(path) + if !ok { dlog.Server.Error(r.server.LogContext(), "No permission to read file", path, globID) r.sendServerMessage(dlog.Server.Warn(r.server.LogContext(), "Unable to read file(s), check server logs")) return } - r.read(ctx, ltx, path, globID, re) + r.read(ctx, ltx, path, &target, globID, re) } func (r *readCommand) read(ctx context.Context, ltx lcontext.LContext, - path, globID string, re regex.Regex) { + path string, target *fs.ValidatedReadTarget, globID string, re regex.Regex) { dlog.Server.Info(r.server.LogContext(), "Start reading", path, globID) r.logRegexMode(re) @@ -222,14 +223,24 @@ func (r *readCommand) read(ctx context.Context, ltx lcontext.LContext, switch r.mode { case omode.GrepClient, omode.CatClient: - catFile := fs.NewCatFile(path, globID, serverMessages, r.server.MaxLineLength()) - reader = &catFile + if target != nil { + catFile := fs.NewValidatedCatFile(path, *target, globID, serverMessages, r.server.MaxLineLength()) + reader = &catFile + } else { + catFile := fs.NewCatFile(path, globID, serverMessages, r.server.MaxLineLength()) + reader = &catFile + } limiter = r.server.CatLimiter() case omode.TailClient: fallthrough default: - tailFile := fs.NewTailFile(path, globID, serverMessages, r.server.MaxLineLength()) - reader = &tailFile + if target != nil { + tailFile := fs.NewValidatedTailFile(path, *target, globID, serverMessages, r.server.MaxLineLength()) + reader = &tailFile + } else { + tailFile := fs.NewTailFile(path, globID, serverMessages, r.server.MaxLineLength()) + reader = &tailFile + } limiter = r.server.TailLimiter() } diff --git a/internal/server/handlers/readcommand_server.go b/internal/server/handlers/readcommand_server.go index 8c3cb96..0f98a58 100644 --- a/internal/server/handlers/readcommand_server.go +++ b/internal/server/handlers/readcommand_server.go @@ -4,6 +4,7 @@ import ( "sync/atomic" "time" + "github.com/mimecast/dtail/internal/io/fs" "github.com/mimecast/dtail/internal/io/line" "github.com/mimecast/dtail/internal/mapr/server" ) @@ -13,7 +14,7 @@ type readCommandContext interface { } type readCommandFiles interface { - CanReadFile(path string) bool + PrepareReadTarget(path string) (fs.ValidatedReadTarget, bool) CatLimiter() chan struct{} TailLimiter() chan struct{} } @@ -87,9 +88,9 @@ func (h *ServerHandler) SendServerMessage(message string) { h.sendln(h.serverMessages, message) } -// CanReadFile reports whether the current user can read the given path. -func (h *ServerHandler) CanReadFile(path string) bool { - return h.user.HasFilePermission(path, "readfiles") +// PrepareReadTarget validates the current user's access to the given path. +func (h *ServerHandler) PrepareReadTarget(path string) (fs.ValidatedReadTarget, bool) { + return h.user.ValidateReadTarget(path, "readfiles") } // ServerMessagesChannel returns the server message channel. |
