Skip to content

Commit

Permalink
Merge pull request #12073 from spzala/automated-cherry-pick-of-#11798…
Browse files Browse the repository at this point in the history
…-upstream-release-3.3

Automated cherry pick of #11798
  • Loading branch information
gyuho authored Jun 25, 2020
2 parents c511894 + bde76af commit 599beae
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 12 deletions.
13 changes: 10 additions & 3 deletions etcdmain/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,16 @@ func startProxy(cfg *config) error {
}

cfg.ec.Dir = filepath.Join(cfg.ec.Dir, "proxy")
err = os.MkdirAll(cfg.ec.Dir, fileutil.PrivateDirMode)
if err != nil {
return err
if fileutil.Exist(cfg.ec.Dir) {
err := fileutil.CheckDirPermission(cfg.ec.Dir, fileutil.PrivateDirMode)
if err != nil {
return err
}
} else {
err = os.MkdirAll(cfg.ec.Dir, fileutil.PrivateDirMode)
if err != nil {
return err
}
}

var peerURLs []string
Expand Down
41 changes: 34 additions & 7 deletions pkg/fileutil/fileutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,22 @@ func ReadDir(dirpath string) ([]string, error) {
// TouchDirAll is similar to os.MkdirAll. It creates directories with 0700 permission if any directory
// does not exists. TouchDirAll also ensures the given directory is writable.
func TouchDirAll(dir string) error {
// If path is already a directory, MkdirAll does nothing
// and returns nil.
err := os.MkdirAll(dir, PrivateDirMode)
if err != nil {
// if mkdirAll("a/text") and "text" is not
// a directory, this will return syscall.ENOTDIR
return err
// If path is already a directory, MkdirAll does nothing and returns nil, so,
// first check if dir exist with an expected permission mode.
if Exist(dir) {
err := CheckDirPermission(dir, PrivateDirMode)
if err != nil {
return err
}
} else {
err := os.MkdirAll(dir, PrivateDirMode)
if err != nil {
// if mkdirAll("a/text") and "text" is not
// a directory, this will return syscall.ENOTDIR
return err
}
}

return IsDirWriteable(dir)
}

Expand Down Expand Up @@ -120,3 +128,22 @@ func ZeroToEnd(f *os.File) error {
_, err = f.Seek(off, io.SeekStart)
return err
}

// CheckDirPermission checks permission on an existing dir.
// Returns error if dir is empty or exist with a different permission than specified.
func CheckDirPermission(dir string, perm os.FileMode) error {
if !Exist(dir) {
return fmt.Errorf("directory %q empty, cannot check permission.", dir)
}
//check the existing permission on the directory
dirInfo, err := os.Stat(dir)
if err != nil {
return err
}
dirMode := dirInfo.Mode().Perm()
if dirMode != perm {
err = fmt.Errorf("directory %q exist without desired file permission. %q", dir, dirInfo.Mode())
return err
}
return nil
}
18 changes: 18 additions & 0 deletions pkg/fileutil/fileutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,21 @@ func TestZeroToEnd(t *testing.T) {
}
}
}

func TestDirPermission(t *testing.T) {
tmpdir, err := ioutil.TempDir(os.TempDir(), "foo")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)

tmpdir2 := filepath.Join(tmpdir, "testpermission")
// create a new dir with 0700
if err = CreateDirAll(tmpdir2); err != nil {
t.Fatal(err)
}
// check dir permission with mode different than created dir
if err = CheckDirPermission(tmpdir2, 0600); err == nil {
t.Errorf("expected error, got nil")
}
}
12 changes: 10 additions & 2 deletions pkg/transport/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"time"

"github.com/coreos/etcd/pkg/tlsutil"
"go.etcd.io/etcd/pkg/fileutil"
)

func NewListener(addr, scheme string, tlsinfo *TLSInfo) (l net.Listener, err error) {
Expand Down Expand Up @@ -101,8 +102,15 @@ func (info TLSInfo) Empty() bool {
}

func SelfCert(dirpath string, hosts []string, additionalUsages ...x509.ExtKeyUsage) (info TLSInfo, err error) {
if err = os.MkdirAll(dirpath, 0700); err != nil {
return
if fileutil.Exist(dirpath) {
err = fileutil.CheckDirPermission(dirpath, fileutil.PrivateDirMode)
if err != nil {
return
}
} else {
if err = os.MkdirAll(dirpath, fileutil.PrivateDirMode); err != nil {
return
}
}

certPath := filepath.Join(dirpath, "cert.pem")
Expand Down

0 comments on commit 599beae

Please sign in to comment.