source: code/trunk/vendor/github.com/lib/pq/ssl_permissions.go@ 822

Last change on this file since 822 was 822, checked in by yakumo.izuru, 22 months ago

Prefer immortal.run over runit and rc.d, use vendored modules
for convenience.

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 2.9 KB
Line 
1//go:build !windows
2// +build !windows
3
4package pq
5
6import (
7 "errors"
8 "os"
9 "syscall"
10)
11
12const (
13 rootUserID = uint32(0)
14
15 // The maximum permissions that a private key file owned by a regular user
16 // is allowed to have. This translates to u=rw.
17 maxUserOwnedKeyPermissions os.FileMode = 0600
18
19 // The maximum permissions that a private key file owned by root is allowed
20 // to have. This translates to u=rw,g=r.
21 maxRootOwnedKeyPermissions os.FileMode = 0640
22)
23
24var (
25 errSSLKeyHasUnacceptableUserPermissions = errors.New("permissions for files not owned by root should be u=rw (0600) or less")
26 errSSLKeyHasUnacceptableRootPermissions = errors.New("permissions for root owned files should be u=rw,g=r (0640) or less")
27)
28
29// sslKeyPermissions checks the permissions on user-supplied ssl key files.
30// The key file should have very little access.
31//
32// libpq does not check key file permissions on Windows.
33func sslKeyPermissions(sslkey string) error {
34 info, err := os.Stat(sslkey)
35 if err != nil {
36 return err
37 }
38
39 err = hasCorrectPermissions(info)
40
41 // return ErrSSLKeyHasWorldPermissions for backwards compatability with
42 // existing code.
43 if err == errSSLKeyHasUnacceptableUserPermissions || err == errSSLKeyHasUnacceptableRootPermissions {
44 err = ErrSSLKeyHasWorldPermissions
45 }
46 return err
47}
48
49// hasCorrectPermissions checks the file info (and the unix-specific stat_t
50// output) to verify that the permissions on the file are correct.
51//
52// If the file is owned by the same user the process is running as,
53// the file should only have 0600 (u=rw). If the file is owned by root,
54// and the group matches the group that the process is running in, the
55// permissions cannot be more than 0640 (u=rw,g=r). The file should
56// never have world permissions.
57//
58// Returns an error when the permission check fails.
59func hasCorrectPermissions(info os.FileInfo) error {
60 // if file's permission matches 0600, allow access.
61 userPermissionMask := (os.FileMode(0777) ^ maxUserOwnedKeyPermissions)
62
63 // regardless of if we're running as root or not, 0600 is acceptable,
64 // so we return if we match the regular user permission mask.
65 if info.Mode().Perm()&userPermissionMask == 0 {
66 return nil
67 }
68
69 // We need to pull the Unix file information to get the file's owner.
70 // If we can't access it, there's some sort of operating system level error
71 // and we should fail rather than attempting to use faulty information.
72 sysInfo := info.Sys()
73 if sysInfo == nil {
74 return ErrSSLKeyUnknownOwnership
75 }
76
77 unixStat, ok := sysInfo.(*syscall.Stat_t)
78 if !ok {
79 return ErrSSLKeyUnknownOwnership
80 }
81
82 // if the file is owned by root, we allow 0640 (u=rw,g=r) to match what
83 // Postgres does.
84 if unixStat.Uid == rootUserID {
85 rootPermissionMask := (os.FileMode(0777) ^ maxRootOwnedKeyPermissions)
86 if info.Mode().Perm()&rootPermissionMask != 0 {
87 return errSSLKeyHasUnacceptableRootPermissions
88 }
89 return nil
90 }
91
92 return errSSLKeyHasUnacceptableUserPermissions
93}
Note: See TracBrowser for help on using the repository browser.