Skip to content

Commit

Permalink
updating changes from ent PR
Browse files Browse the repository at this point in the history
  • Loading branch information
akshya96 committed Mar 31, 2022
1 parent b470972 commit 903a4f3
Show file tree
Hide file tree
Showing 18 changed files with 440 additions and 12 deletions.
3 changes: 3 additions & 0 deletions command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2500,6 +2500,8 @@ func createCoreConfig(c *ServerCommand, config *server.Config, backend physical.
ClusterName: config.ClusterName,
CacheSize: config.CacheSize,
PluginDirectory: config.PluginDirectory,
PluginFileUid: config.PluginFileUid,
PluginFilePermissions: config.PluginFilePermissions,
EnableUI: config.EnableUI,
EnableRaw: config.EnableRawEndpoint,
DisableSealWrap: config.DisableSealWrap,
Expand All @@ -2517,6 +2519,7 @@ func createCoreConfig(c *ServerCommand, config *server.Config, backend physical.
LicensePath: config.LicensePath,
DisableSSCTokens: config.DisableSSCTokens,
}

if c.flagDev {
coreConfig.EnableRaw = true
coreConfig.DevToken = c.flagDevRootTokenID
Expand Down
57 changes: 56 additions & 1 deletion command/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import (
"github.com/hashicorp/go-secure-stdlib/parseutil"
"github.com/hashicorp/hcl"
"github.com/hashicorp/hcl/hcl/ast"
"github.com/hashicorp/vault/helper/osutil"
"github.com/hashicorp/vault/internalshared/configutil"
"github.com/hashicorp/vault/sdk/helper/consts"
)

var entConfigValidate = func(_ *Config, _ string) []configutil.ConfigError {
Expand Down Expand Up @@ -54,6 +56,11 @@ type Config struct {

PluginDirectory string `hcl:"plugin_directory"`

PluginFileUid int `hcl:"plugin_file_uid"`

PluginFilePermissions int `hcl:"-"`
PluginFilePermissionsRaw interface{} `hcl:"plugin_file_permissions,alias:PluginFilePermissions"`

EnableRawEndpoint bool `hcl:"-"`
EnableRawEndpointRaw interface{} `hcl:"raw_storage_endpoint,alias:EnableRawEndpoint"`

Expand Down Expand Up @@ -127,7 +134,6 @@ telemetry {
prometheus_retention_time = "24h"
disable_hostname = true
}
enable_raw_endpoint = true
storage "%s" {
Expand Down Expand Up @@ -276,6 +282,17 @@ func (c *Config) Merge(c2 *Config) *Config {
result.PluginDirectory = c2.PluginDirectory
}

result.PluginFileUid = c.PluginFileUid
if c2.PluginFileUid != 0 {
result.PluginFileUid = c2.PluginFileUid
}

result.PluginFilePermissions = c.PluginFilePermissions
if c2.PluginFilePermissionsRaw != nil {
result.PluginFilePermissions = c2.PluginFilePermissions
result.PluginFilePermissionsRaw = c2.PluginFilePermissionsRaw
}

result.DisablePerformanceStandby = c.DisablePerformanceStandby
if c2.DisablePerformanceStandby {
result.DisablePerformanceStandby = c2.DisablePerformanceStandby
Expand Down Expand Up @@ -350,6 +367,13 @@ func LoadConfig(path string) (*Config, error) {
}

if fi.IsDir() {
// check permissions on the config directory
if os.Getenv(consts.VaultDisableFilePermissionsCheckEnv) != "true" {
err = osutil.OwnerPermissionsMatch(path, 0, 0)
if err != nil {
return nil, err
}
}
return CheckConfig(LoadConfigDir(path))
}
return CheckConfig(LoadConfigFile(path))
Expand Down Expand Up @@ -385,6 +409,21 @@ func LoadConfigFile(path string) (*Config, error) {
return nil, err
}

if os.Getenv(consts.VaultDisableFilePermissionsCheckEnv) != "true" {
// check permissions of the config file
err = osutil.OwnerPermissionsMatch(path, 0, 0)
if err != nil {
return nil, err
}
// check permissions of the plugin directory
if conf.PluginDirectory != "" {

err = osutil.OwnerPermissionsMatch(conf.PluginDirectory, conf.PluginFileUid, conf.PluginFilePermissions)
if err != nil {
return nil, err
}
}
}
return conf, nil
}

Expand Down Expand Up @@ -459,6 +498,18 @@ func ParseConfig(d, source string) (*Config, error) {
}
}

if result.PluginFilePermissionsRaw != nil {
octalPermissionsString, err := parseutil.ParseString(result.PluginFilePermissionsRaw)
if err != nil {
return nil, err
}
pluginFilePermissions, err := strconv.ParseInt(octalPermissionsString, 8, 64)
if err != nil {
return nil, err
}
result.PluginFilePermissions = int(pluginFilePermissions)
}

if result.DisableSentinelTraceRaw != nil {
if result.DisableSentinelTrace, err = parseutil.ParseBool(result.DisableSentinelTraceRaw); err != nil {
return nil, err
Expand Down Expand Up @@ -838,6 +889,10 @@ func (c *Config) Sanitized() map[string]interface{} {

"plugin_directory": c.PluginDirectory,

"plugin_file_uid": c.PluginFileUid,

"plugin_file_permissions": c.PluginFilePermissions,

"raw_storage_endpoint": c.EnableRawEndpoint,

"api_addr": c.APIAddr,
Expand Down
3 changes: 3 additions & 0 deletions command/server/config_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@ func testConfig_Sanitized(t *testing.T) {
"disable_indexing": false,
"disable_mlock": true,
"disable_performance_standby": false,
"plugin_file_uid": 0,
"plugin_file_permissions": 0,
"disable_printable_check": false,
"disable_sealwrap": true,
"raw_storage_endpoint": true,
Expand Down Expand Up @@ -855,6 +857,7 @@ func testParseSockaddrTemplate(t *testing.T) {
api_addr = <<EOF
{{- GetAllInterfaces | include "flags" "loopback" | include "type" "ipv4" | attr "address" -}}
EOF
listener "tcp" {
address = <<EOF
{{- GetAllInterfaces | include "flags" "loopback" | include "type" "ipv4" | attr "address" -}}:443
Expand Down
66 changes: 66 additions & 0 deletions helper/osutil/fileinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
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 err
}

func FilePermissionsMatch(info fs.FileInfo, path string, permissions int) (err 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 err
}

// OwnerPermissionsMatch checks if vault user is the owner and permissions are secure for input path
func OwnerPermissionsMatch(path string, uid int, permissions int) (err 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 err
}
84 changes: 84 additions & 0 deletions helper/osutil/fileinfo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package osutil

import (
"io/fs"
"os"
"os/user"
"runtime"
"strconv"
"testing"
)

func TestCheckPathInfo(t *testing.T) {
currentUser, err := user.Current()
if err != nil {
t.Errorf("failed to get details of current process owner. The error is: %v", err)
}
uid, err := strconv.ParseInt(currentUser.Uid, 0, 64)
if err != nil {
t.Errorf("failed to convert uid to int64. The error is: %v", err)
}
uid2, err := strconv.ParseInt(currentUser.Uid+"1", 0, 64)
if err != nil {
t.Errorf("failed to convert uid to int64. The error is: %v", err)
}

testCases := []struct {
uid int
filepermissions fs.FileMode
permissions int
expectError bool
}{
{
uid: 0,
filepermissions: 0o700,
permissions: 0,
expectError: false,
},
{
uid: int(uid2),
filepermissions: 0o700,
permissions: 0,
expectError: true,
},
{
uid: int(uid),
filepermissions: 0o700,
permissions: 0,
expectError: false,
},
{
uid: 0,
filepermissions: 0o777,
permissions: 744,
expectError: true,
},
}

for _, tc := range testCases {
err := os.Mkdir("testFile", tc.filepermissions)
if err != nil {
t.Fatal(err)
}
info, err := os.Stat("testFile")
if err != nil {
t.Errorf("error stating %q: %v", "testFile", err)
}
if tc.uid != 0 && runtime.GOOS == "windows" && tc.expectError == true {
t.Skip("Skipping test in windows environment as no error will be returned in this case")
}

err = checkPathInfo(info, "testFile", tc.uid, int(tc.permissions))
if tc.expectError && err == nil {
t.Errorf("invalid result. expected error")
}
if !tc.expectError && err != nil {
t.Errorf(err.Error())
}

err = os.RemoveAll("testFile")
if err != nil {
t.Fatal(err)
}
}
}
53 changes: 53 additions & 0 deletions helper/osutil/fileinfo_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//go:build !windows

package osutil

import (
"fmt"
"io/fs"
"os/user"
"strconv"
"syscall"
)

func FileUIDEqual(info fs.FileInfo, uid int) bool {
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
path_uid := int(stat.Uid)
if path_uid == uid {
return true
}
}
return false
}

func FileGIDEqual(info fs.FileInfo, gid int) bool {
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
path_gid := int(stat.Gid)
if path_gid == gid {
return true
}
}
return false
}

func FileUidMatch(info fs.FileInfo, path string, uid int) (err error) {
currentUser, err := user.Current()
if err != nil {
return fmt.Errorf("failed to get details of current process owner. The error is: %w", err)
}
switch uid {
case 0:
currentUserUid, err := strconv.Atoi(currentUser.Uid)
if err != nil {
return fmt.Errorf("failed to convert uid %q to int. The error is: %w", currentUser.Uid, err)
}
if !FileUIDEqual(info, currentUserUid) {
return fmt.Errorf("path %q is not owned by my uid %s", path, currentUser.Uid)
}
default:
if !FileUIDEqual(info, uid) {
return fmt.Errorf("path %q is not owned by uid %d", path, uid)
}
}
return err
}
Loading

0 comments on commit 903a4f3

Please sign in to comment.