feat(auth): add local and OIDC management to tht
This commit is contained in:
@@ -14,6 +14,21 @@ import (
|
||||
|
||||
var ErrUnsafeFile = errors.New("unsafe file")
|
||||
|
||||
// EnsurePrivateDirectory creates only the final canonical directory with the platform's
|
||||
// owner-only protection, or validates an existing directory has that protection.
|
||||
func EnsurePrivateDirectory(path string) error {
|
||||
if err := ValidateCanonicalPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := requireCanonicalDirectory(filepath.Dir(path)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createPrivateDirectory(path); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
return ErrUnsafeFile
|
||||
}
|
||||
return ValidatePrivateDirectory(path)
|
||||
}
|
||||
|
||||
// ValidateCanonicalPath rejects relative or lexically non-canonical paths before they are opened.
|
||||
func ValidateCanonicalPath(path string) error {
|
||||
if !filepath.IsAbs(path) || filepath.Clean(path) != path || strings.Contains(path, string(filepath.Separator)+".."+string(filepath.Separator)) {
|
||||
|
||||
@@ -3,10 +3,21 @@
|
||||
package safeio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func createPrivateDirectory(path string) error {
|
||||
if err := os.Mkdir(path, 0o700); err != nil {
|
||||
if errors.Is(err, os.ErrExist) {
|
||||
return os.ErrExist
|
||||
}
|
||||
return err
|
||||
}
|
||||
return ProtectPrivateDirectory(path)
|
||||
}
|
||||
|
||||
// ProtectPrivateDirectory sets the private directory mode used for local authentication state.
|
||||
func ProtectPrivateDirectory(path string) error {
|
||||
if err := ValidateCanonicalPath(path); err != nil {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package safeio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -12,6 +13,32 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func createPrivateDirectory(path string) error {
|
||||
parents, target, err := openCanonicalWindowsParent(path)
|
||||
if err != nil {
|
||||
return ErrUnsafeFile
|
||||
}
|
||||
defer parents.Close()
|
||||
security, err := newOwnerOnlySecurityDescriptor()
|
||||
if err != nil {
|
||||
return ErrUnsafeFile
|
||||
}
|
||||
defer security.Close()
|
||||
attributes := &windows.SecurityAttributes{
|
||||
Length: uint32(unsafe.Sizeof(windows.SecurityAttributes{})),
|
||||
SecurityDescriptor: security.descriptor,
|
||||
}
|
||||
err = windows.CreateDirectory(windows.StringToUTF16Ptr(filepath.Join(parents.directory, target)), attributes)
|
||||
runtime.KeepAlive(security)
|
||||
if errors.Is(err, windows.ERROR_ALREADY_EXISTS) {
|
||||
return os.ErrExist
|
||||
}
|
||||
if err != nil {
|
||||
return ErrUnsafeFile
|
||||
}
|
||||
return ValidatePrivateDirectory(path)
|
||||
}
|
||||
|
||||
// ProtectPrivateDirectory sets a protected DACL containing only the current owner.
|
||||
func ProtectPrivateDirectory(path string) error {
|
||||
parents, target, err := openCanonicalWindowsParent(path)
|
||||
|
||||
Reference in New Issue
Block a user