summaryrefslogtreecommitdiff
path: root/vendor/github.com/danieljoos/wincred/sys.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/danieljoos/wincred/sys.go')
-rw-r--r--vendor/github.com/danieljoos/wincred/sys.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/vendor/github.com/danieljoos/wincred/sys.go b/vendor/github.com/danieljoos/wincred/sys.go
new file mode 100644
index 0000000..fb8a6ac
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/sys.go
@@ -0,0 +1,148 @@
+//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
+}