Files
rvbox/internal/client/spool/private_unix.go
T

53 lines
1.3 KiB
Go

//go:build !windows
package spool
import (
"errors"
"fmt"
"os"
)
func ensurePrivateFile(path string) error {
file, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0o600)
if err == nil {
return file.Close()
}
if !errors.Is(err, os.ErrExist) {
return err
}
info, err := os.Lstat(path)
if err != nil {
return err
}
if !info.Mode().IsRegular() || info.Mode()&os.ModeSymlink != 0 {
return fmt.Errorf("%w: %s is not a regular file", ErrUnsafeDataDirectory, path)
}
if info.Mode().Perm()&0o077 != 0 {
return fmt.Errorf("%w: %s permissions %04o expose private state", ErrUnsafeDataDirectory, path, info.Mode().Perm())
}
return nil
}
func ensurePrivateDirectory(path string) error {
info, err := os.Lstat(path)
if os.IsNotExist(err) {
if err := os.MkdirAll(path, 0o700); err != nil {
return err
}
info, err = os.Lstat(path)
}
if err != nil {
return err
}
if info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {
return fmt.Errorf("%w: %s is not a real directory", ErrUnsafeDataDirectory, path)
}
if info.Mode().Perm()&0o077 != 0 {
return fmt.Errorf("%w: %s permissions %04o expose private state", ErrUnsafeDataDirectory, path, info.Mode().Perm())
}
return nil
}
func securePrivateFile(path string) error { return os.Chmod(path, 0o600) }