fix(auth): add Windows session storage bridge

This commit is contained in:
2026-08-16 21:43:03 +02:00
parent 6bf8218fea
commit c9b02fc57e
14 changed files with 1630 additions and 8 deletions
+80
View File
@@ -71,6 +71,50 @@ func ReadCanonicalUTF8(path string, maximum int64) (string, error) {
return string(contents), nil
}
// ReadCanonicalPrivateRegular reads one owner-only private record and revalidates its metadata
// after the bounded read. It intentionally rejects ordinary hard links; OIDC's explicitly named
// atomic claim pair uses ReadCanonicalPrivateClaim instead.
func ReadCanonicalPrivateRegular(path string, maximum int64) ([]byte, error) {
return readCanonicalPrivateRegular(path, maximum)
}
// PrivateDirectoryEntry is a bounded, untrusted directory listing item. Callers must still
// validate each filename and record before using it.
type PrivateDirectoryEntry struct {
Name string
ModifiedUnixMs int64
}
// ListCanonicalPrivateDirectory lists regular, non-symlinked direct children from an owner-only
// directory. It returns no content and bounds the number of entries before allocating output.
func ListCanonicalPrivateDirectory(path string, maximumEntries int) ([]PrivateDirectoryEntry, error) {
if maximumEntries < 1 || maximumEntries > 4096 {
return nil, ErrUnsafeFile
}
if err := ValidatePrivateDirectory(path); err != nil {
return nil, ErrUnsafeFile
}
entries, err := os.ReadDir(path)
if err != nil || len(entries) > maximumEntries {
return nil, ErrUnsafeFile
}
result := make([]PrivateDirectoryEntry, 0, len(entries))
for _, entry := range entries {
if entry.Name() == "" || strings.Contains(entry.Name(), string(filepath.Separator)) {
return nil, ErrUnsafeFile
}
info, err := os.Lstat(filepath.Join(path, entry.Name()))
if err != nil || !info.Mode().IsRegular() || info.Mode()&os.ModeSymlink != 0 {
return nil, ErrUnsafeFile
}
result = append(result, PrivateDirectoryEntry{Name: entry.Name(), ModifiedUnixMs: info.ModTime().UnixMilli()})
}
if err := ValidatePrivateDirectory(path); err != nil {
return nil, ErrUnsafeFile
}
return result, nil
}
func WriteCanonicalNewFile(path string, contents []byte, mode os.FileMode) error {
if err := ValidateCanonicalPath(path); err != nil {
return err
@@ -127,6 +171,42 @@ func RemoveCanonicalPrivateRegular(path string) error {
return removeCanonicalPrivateRegular(path)
}
// ClaimCanonicalPrivateRegular atomically creates a second, explicit private hard link to one
// existing record. It is used only for digest-named, single-use OIDC state claims.
func ClaimCanonicalPrivateRegular(source, claim string) (bool, error) {
if err := validateClaimPaths(source, claim); err != nil {
return false, ErrUnsafeFile
}
return claimCanonicalPrivateRegular(source, claim)
}
// ReadCanonicalPrivateClaim reads a verified two-link source/claim pair. found=false means the
// state has already been consumed or a winning process is between its two removal steps.
func ReadCanonicalPrivateClaim(source, claim string, maximum int64) ([]byte, bool, error) {
if maximum < 0 || maximum == int64(^uint64(0)>>1) || validateClaimPaths(source, claim) != nil {
return nil, false, ErrUnsafeFile
}
return readCanonicalPrivateClaim(source, claim, maximum)
}
// RemoveCanonicalPrivateClaim removes exactly a verified two-link source/claim pair.
func RemoveCanonicalPrivateClaim(source, claim string) (bool, error) {
if err := validateClaimPaths(source, claim); err != nil {
return false, ErrUnsafeFile
}
return removeCanonicalPrivateClaim(source, claim)
}
func validateClaimPaths(source, claim string) error {
if ValidateCanonicalPath(source) != nil || ValidateCanonicalPath(claim) != nil || filepath.Dir(source) != filepath.Dir(claim) {
return ErrUnsafeFile
}
if err := ValidatePrivateDirectory(filepath.Dir(source)); err != nil {
return ErrUnsafeFile
}
return nil
}
func randomTemporaryName() (string, error) {
bytes := make([]byte, 16)
if _, err := rand.Read(bytes); err != nil {