Warn about permissions when creating identity (#1384)
* Warn about permissions when creating identity * Function to determine if directory is writeable * Check if writable before authorizing * Remove redeclatarion * remove windows specific utils * Nat nits * Actually test if directory is writeable with file creation
This commit is contained in:
parent
56ace481c1
commit
bb77d9b4a6
@ -55,7 +55,11 @@ func cmdSetup(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if config.Identity.Status() != identity.CertKey {
|
||||
status, err := config.Identity.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status != identity.CertKey {
|
||||
return errors.New("identity is missing")
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,10 @@ func cmdNewID(cmd *cobra.Command, args []string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
s := newIDCfg.Identity.Status()
|
||||
s, err := newIDCfg.Identity.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if s == identity.NoCertNoKey || newIDCfg.Identity.Overwrite {
|
||||
_, err := newIDCfg.Identity.Create(ca)
|
||||
return err
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"storj.io/storj/pkg/peertls"
|
||||
"storj.io/storj/pkg/pkcrypto"
|
||||
"storj.io/storj/pkg/process"
|
||||
"storj.io/storj/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -71,6 +72,11 @@ func init() {
|
||||
}
|
||||
|
||||
func main() {
|
||||
if writable, err := utils.IsWritable(identityDir); !writable || err != nil {
|
||||
fmt.Printf("%s is not a writeable directory: %s\n", identityDir, err)
|
||||
return
|
||||
}
|
||||
|
||||
process.Exec(rootCmd)
|
||||
}
|
||||
|
||||
@ -95,8 +101,12 @@ func cmdNewService(cmd *cobra.Command, args []string) error {
|
||||
ParentKeyPath: config.ParentKeyPath,
|
||||
}
|
||||
|
||||
if caConfig.Status() != identity.NoCertNoKey {
|
||||
return errs.New("CA certificate and/or key already exits, NOT overwriting!")
|
||||
status, err := caConfig.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status != identity.NoCertNoKey {
|
||||
return errs.New("CA certificate and/or key already exists, NOT overwriting!")
|
||||
}
|
||||
|
||||
identConfig := identity.SetupConfig{
|
||||
@ -104,8 +114,12 @@ func cmdNewService(cmd *cobra.Command, args []string) error {
|
||||
KeyPath: identKeyPath,
|
||||
}
|
||||
|
||||
if identConfig.Status() != identity.NoCertNoKey {
|
||||
return errs.New("Identity certificate and/or key already exits, NOT overwriting!")
|
||||
status, err = identConfig.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status != identity.NoCertNoKey {
|
||||
return errs.New("Identity certificate and/or key already exists, NOT overwriting!")
|
||||
}
|
||||
|
||||
ca, caerr := caConfig.Create(process.Ctx(cmd), os.Stdout)
|
||||
@ -128,6 +142,7 @@ func cmdAuthorize(cmd *cobra.Command, args []string) error {
|
||||
ctx := process.Ctx(cmd)
|
||||
|
||||
serviceDir := serviceDirectory(args[0])
|
||||
|
||||
authToken := args[1]
|
||||
|
||||
caCertPath := filepath.Join(serviceDir, "ca.cert")
|
||||
|
@ -176,7 +176,7 @@ func NewCA(ctx context.Context, opts NewCAOptions) (_ *FullCertificateAuthority,
|
||||
}
|
||||
|
||||
// Status returns the status of the CA cert/key files for the config
|
||||
func (caS CASetupConfig) Status() TLSFilesStatus {
|
||||
func (caS CASetupConfig) Status() (TLSFilesStatus, error) {
|
||||
return statTLSFiles(caS.CertPath, caS.KeyPath)
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ func ToChains(chains ...[]*x509.Certificate) [][]*x509.Certificate {
|
||||
}
|
||||
|
||||
// Status returns the status of the identity cert/key files for the config
|
||||
func (is SetupConfig) Status() TLSFilesStatus {
|
||||
func (is SetupConfig) Status() (TLSFilesStatus, error) {
|
||||
return statTLSFiles(is.CertPath, is.KeyPath)
|
||||
}
|
||||
|
||||
|
@ -58,22 +58,37 @@ func writeFile(path string, dirmode, filemode os.FileMode, data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func statTLSFiles(certPath, keyPath string) TLSFilesStatus {
|
||||
_, err := os.Stat(certPath)
|
||||
hasCert := !os.IsNotExist(err)
|
||||
func statTLSFiles(certPath, keyPath string) (status TLSFilesStatus, err error) {
|
||||
hasKey := true
|
||||
hasCert := true
|
||||
|
||||
_, err = os.Stat(keyPath)
|
||||
hasKey := !os.IsNotExist(err)
|
||||
|
||||
if hasCert && hasKey {
|
||||
return CertKey
|
||||
} else if hasCert {
|
||||
return CertNoKey
|
||||
} else if hasKey {
|
||||
return NoCertKey
|
||||
_, err = os.Stat(certPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
hasCert = false
|
||||
} else {
|
||||
return NoCertNoKey, err
|
||||
}
|
||||
}
|
||||
|
||||
return NoCertNoKey
|
||||
_, err = os.Stat(keyPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
hasKey = false
|
||||
} else {
|
||||
return NoCertNoKey, err
|
||||
}
|
||||
}
|
||||
|
||||
if hasCert && hasKey {
|
||||
return CertKey, nil
|
||||
} else if hasCert {
|
||||
return CertNoKey, nil
|
||||
} else if hasKey {
|
||||
return NoCertKey, nil
|
||||
}
|
||||
|
||||
return NoCertNoKey, nil
|
||||
}
|
||||
|
||||
func (t TLSFilesStatus) String() string {
|
||||
|
@ -4,6 +4,8 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/zeebo/errs"
|
||||
@ -84,3 +86,35 @@ func discardNil(ch chan error) chan error {
|
||||
}()
|
||||
return r
|
||||
}
|
||||
|
||||
// IsWritable determines if a directory is writeable
|
||||
func IsWritable(filepath string) (bool, error) {
|
||||
info, err := os.Stat(filepath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
return false, errs.New("Path %s is not a directory", filepath)
|
||||
}
|
||||
|
||||
// Check if the user bit is enabled in file permission
|
||||
if info.Mode().Perm()&0200 == 0 {
|
||||
return false, errs.New("Write permission bit is not set on this file for user")
|
||||
}
|
||||
|
||||
// Test if user can create file
|
||||
// There is no OS cross-compatible method for
|
||||
// determining if a user has write permissions on a folder.
|
||||
// We can test by attempting to create a file in the folder.
|
||||
testFile := path.Join(filepath, ".perm")
|
||||
file, err := os.Create(testFile) // For read access.
|
||||
if err != nil {
|
||||
return false, errs.New("Write permission bit is not set on this file for user")
|
||||
}
|
||||
|
||||
_ = file.Close()
|
||||
_ = os.Remove(testFile)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user