53 lines
1.3 KiB
Go
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) }
|