84 lines
2.1 KiB
Go
84 lines
2.1 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package osutil
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
)
|
|
|
|
func IsWriteGroup(mode os.FileMode) bool {
|
|
return mode&0o20 != 0
|
|
}
|
|
|
|
func IsWriteOther(mode os.FileMode) bool {
|
|
return mode&0o02 != 0
|
|
}
|
|
|
|
func checkPathInfo(info fs.FileInfo, path string, uid int, permissions int) error {
|
|
err := FileUidMatch(info, path, uid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = FilePermissionsMatch(info, path, permissions)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func FilePermissionsMatch(info fs.FileInfo, path string, permissions int) error {
|
|
if permissions != 0 && int(info.Mode().Perm()) != permissions {
|
|
return fmt.Errorf("path %q does not have permissions %o", path, permissions)
|
|
}
|
|
if permissions == 0 && (IsWriteOther(info.Mode()) || IsWriteGroup(info.Mode())) {
|
|
return fmt.Errorf("path %q has insecure permissions %o. Vault expects no write permissions for group or others", path, info.Mode().Perm())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// OwnerPermissionsMatch checks if vault user is the owner and permissions are secure for input path
|
|
func OwnerPermissionsMatch(path string, uid int, permissions int) error {
|
|
if path == "" {
|
|
return fmt.Errorf("could not verify permissions for path. No path provided ")
|
|
}
|
|
|
|
info, err := os.Stat(path)
|
|
if err != nil {
|
|
return fmt.Errorf("error stating %q: %w", path, err)
|
|
}
|
|
if info.Mode()&os.ModeSymlink != 0 {
|
|
symLinkInfo, err := os.Lstat(path)
|
|
if err != nil {
|
|
return fmt.Errorf("error stating %q: %w", path, err)
|
|
}
|
|
err = checkPathInfo(symLinkInfo, path, uid, permissions)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
err = checkPathInfo(info, path, uid, permissions)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// OwnerPermissionsMatchFile checks if vault user is the owner and permissions are secure for the input file
|
|
func OwnerPermissionsMatchFile(file *os.File, uid int, permissions int) error {
|
|
info, err := file.Stat()
|
|
if err != nil {
|
|
return fmt.Errorf("file stat error on path %q: %w", file.Name(), err)
|
|
}
|
|
err = checkPathInfo(info, file.Name(), uid, permissions)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|