1
0
mirror of https://github.com/docker/docker-credential-helpers.git synced 2026-06-14 00:11:28 +05:30
Files
docker-credential-helpers/vendor/github.com/danieljoos/wincred/sys.go
T
Sebastiaan van Stijn 218f1787ac vendor: github.com/danieljoos/wincred v1.2.1
- Credential Helpers [v0.8.0](https://github.com/docker/docker-credential-helpers/releases/tag/v0.8.0)

full diff: https://github.com/danieljoos/wincred/compare/v1.2.0...v1.2.1

- Updated dependency golang.org/x/sys to version 0.15.0
- Updated dependency github.com/stretchr/testify to version 1.8.4
- Added error constant ErrBadUsername that can be used when dealing with domain password credentials.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-09 16:42:24 +01:00

149 lines
3.9 KiB
Go

//go:build windows
// +build windows
package wincred
import (
"reflect"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
var (
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
procCredRead = modadvapi32.NewProc("CredReadW")
procCredWrite proc = modadvapi32.NewProc("CredWriteW")
procCredDelete proc = modadvapi32.NewProc("CredDeleteW")
procCredFree proc = modadvapi32.NewProc("CredFree")
procCredEnumerate = modadvapi32.NewProc("CredEnumerateW")
)
// Interface for syscall.Proc: helps testing
type proc interface {
Call(a ...uintptr) (r1, r2 uintptr, lastErr error)
}
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw
type sysCREDENTIAL struct {
Flags uint32
Type uint32
TargetName *uint16
Comment *uint16
LastWritten windows.Filetime
CredentialBlobSize uint32
CredentialBlob uintptr
Persist uint32
AttributeCount uint32
Attributes uintptr
TargetAlias *uint16
UserName *uint16
}
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credential_attributew
type sysCREDENTIAL_ATTRIBUTE struct {
Keyword *uint16
Flags uint32
ValueSize uint32
Value uintptr
}
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw
type sysCRED_TYPE uint32
const (
sysCRED_TYPE_GENERIC sysCRED_TYPE = 0x1
sysCRED_TYPE_DOMAIN_PASSWORD sysCRED_TYPE = 0x2
sysCRED_TYPE_DOMAIN_CERTIFICATE sysCRED_TYPE = 0x3
sysCRED_TYPE_DOMAIN_VISIBLE_PASSWORD sysCRED_TYPE = 0x4
sysCRED_TYPE_GENERIC_CERTIFICATE sysCRED_TYPE = 0x5
sysCRED_TYPE_DOMAIN_EXTENDED sysCRED_TYPE = 0x6
// https://docs.microsoft.com/en-us/windows/desktop/Debug/system-error-codes
sysERROR_NOT_FOUND = windows.Errno(1168)
sysERROR_INVALID_PARAMETER = windows.Errno(87)
sysERROR_BAD_USERNAME = windows.Errno(2202)
)
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreadw
func sysCredRead(targetName string, typ sysCRED_TYPE) (*Credential, error) {
var pcred *sysCREDENTIAL
targetNamePtr, _ := windows.UTF16PtrFromString(targetName)
ret, _, err := syscall.SyscallN(
procCredRead.Addr(),
uintptr(unsafe.Pointer(targetNamePtr)),
uintptr(typ),
0,
uintptr(unsafe.Pointer(&pcred)),
)
if ret == 0 {
return nil, err
}
defer procCredFree.Call(uintptr(unsafe.Pointer(pcred)))
return sysToCredential(pcred), nil
}
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritew
func sysCredWrite(cred *Credential, typ sysCRED_TYPE) error {
ncred := sysFromCredential(cred)
ncred.Type = uint32(typ)
ret, _, err := procCredWrite.Call(
uintptr(unsafe.Pointer(ncred)),
0,
)
if ret == 0 {
return err
}
return nil
}
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletew
func sysCredDelete(cred *Credential, typ sysCRED_TYPE) error {
targetNamePtr, _ := windows.UTF16PtrFromString(cred.TargetName)
ret, _, err := procCredDelete.Call(
uintptr(unsafe.Pointer(targetNamePtr)),
uintptr(typ),
0,
)
if ret == 0 {
return err
}
return nil
}
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credenumeratew
func sysCredEnumerate(filter string, all bool) ([]*Credential, error) {
var count int
var pcreds uintptr
var filterPtr *uint16
if !all {
filterPtr, _ = windows.UTF16PtrFromString(filter)
}
ret, _, err := syscall.SyscallN(
procCredEnumerate.Addr(),
uintptr(unsafe.Pointer(filterPtr)),
0,
uintptr(unsafe.Pointer(&count)),
uintptr(unsafe.Pointer(&pcreds)),
)
if ret == 0 {
return nil, err
}
defer procCredFree.Call(pcreds)
credsSlice := *(*[]*sysCREDENTIAL)(unsafe.Pointer(&reflect.SliceHeader{
Data: pcreds,
Len: count,
Cap: count,
}))
creds := make([]*Credential, count, count)
for i, cred := range credsSlice {
creds[i] = sysToCredential(cred)
}
return creds, nil
}