From 14aa76750e982ff87a1642f5147e11c567c22251 Mon Sep 17 00:00:00 2001 From: Dominik Richter Date: Sat, 23 Sep 2023 20:38:56 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20support=20sudo=20over=20ssh=20on?= =?UTF-8?q?=20alpine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stat does not support all the flags, especially printf. We can skip newline escapes, since we only grab simple fields. The only limitation here is the SElinux context, which we do not return yet (so we can revisit that then). Even so, it is the last value returned, so we can stick with `-c` Signed-off-by: Dominik Richter --- providers/os/connection/local/statutil/stat.go | 18 ++++++------------ .../local/statutil/testdata/linux.toml | 18 ++++-------------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/providers/os/connection/local/statutil/stat.go b/providers/os/connection/local/statutil/stat.go index 1d9285118d..473c3fb2a0 100644 --- a/providers/os/connection/local/statutil/stat.go +++ b/providers/os/connection/local/statutil/stat.go @@ -99,19 +99,10 @@ func (s *statHelper) linux(name string) (os.FileInfo, error) { return nil, os.ErrNotExist } - // run stat - lstat := "-L" - format := "--printf" - var sb strings.Builder - - sb.WriteString("stat ") - sb.WriteString(lstat) - sb.WriteString(" ") + sb.WriteString("stat -L ") sb.WriteString(path) - sb.WriteString(" ") - sb.WriteString(format) - sb.WriteString(" '%s\n%f\n%u\n%g\n%X\n%Y\n%C'") + sb.WriteString(" -c '%s.%f.%u.%g.%X.%Y.%C'") // NOTE: handling the exit code here does not work for all cases // sometimes stat returns something like: failed to get security context of '/etc/ssh/sshd_config': No data available @@ -134,7 +125,7 @@ func (s *statHelper) linux(name string) (os.FileInfo, error) { return nil, err } - statsData := strings.Split(string(data), "\n") + statsData := strings.Split(strings.TrimSpace(string(data)), ".") if len(statsData) != 7 { log.Debug().Str("path", path).Msg("could not parse file stat information") // TODO: we may need to parse the returning error to better distinguish between a real error and file not found @@ -143,6 +134,9 @@ func (s *statHelper) linux(name string) (os.FileInfo, error) { return nil, errors.New("could not parse file stat: " + path) } + // Note: The SElinux context may not be supported by stats on all OSs. + // For example: Alpine does not support it, resulting in statsData[6] == "C" + size, err := strconv.Atoi(statsData[0]) if err != nil { return nil, errors.Wrap(err, "could not stat "+name) diff --git a/providers/os/connection/local/statutil/testdata/linux.toml b/providers/os/connection/local/statutil/testdata/linux.toml index 0825e6244e..3949828b4a 100644 --- a/providers/os/connection/local/statutil/testdata/linux.toml +++ b/providers/os/connection/local/statutil/testdata/linux.toml @@ -4,22 +4,12 @@ stdout = "x86_64" [commands."uname -s"] stdout = "Linux" -[commands."stat -L /etc/ssh/sshd_config --printf '%s\n%f\n%u\n%g\n%X\n%Y\n%C'"] -stdout = """4317 -8180 -0 -0 -1590420240 -1590418792 +[commands."stat -L /etc/ssh/sshd_config -c '%s.%f.%u.%g.%X.%Y.%C'"] +stdout = """4317.8180.0.0.1590420240.1590418792.? """ -[commands."stat -L /usr/bin/su --printf '%s\n%f\n%u\n%g\n%X\n%Y\n%C'"] -stdout = """71728 -89ed -0 -0 -1634057181 -1629123001 +[commands."stat -L /usr/bin/su -c '%s.%f.%u.%g.%X.%Y.%C'"] +stdout = """71728.89ed.0.0.1634057181.1629123001.? """