diff --git a/vendor/github.com/danieljoos/wincred/conversion.go b/vendor/github.com/danieljoos/wincred/conversion.go index 36e67b1..dc64718 100644 --- a/vendor/github.com/danieljoos/wincred/conversion.go +++ b/vendor/github.com/danieljoos/wincred/conversion.go @@ -58,7 +58,6 @@ func nativeToCredential(cred *nativeCREDENTIAL) (result *Credential) { resultAttr.Keyword = utf16PtrToString(attr.Keyword) resultAttr.Value = C.GoBytes(unsafe.Pointer(attr.Value), C.int(attr.ValueSize)) } - return result } diff --git a/vendor/github.com/danieljoos/wincred/native.go b/vendor/github.com/danieljoos/wincred/native.go index 16e91ad..5fb8bb4 100644 --- a/vendor/github.com/danieljoos/wincred/native.go +++ b/vendor/github.com/danieljoos/wincred/native.go @@ -1,6 +1,7 @@ package wincred import ( + "C" "syscall" "unsafe" ) @@ -8,10 +9,11 @@ import ( var ( modadvapi32 = syscall.NewLazyDLL("advapi32.dll") - procCredRead = modadvapi32.NewProc("CredReadW") - procCredWrite = modadvapi32.NewProc("CredWriteW") - procCredDelete = modadvapi32.NewProc("CredDeleteW") - procCredFree = modadvapi32.NewProc("CredFree") + procCredRead = modadvapi32.NewProc("CredReadW") + procCredWrite = modadvapi32.NewProc("CredWriteW") + procCredDelete = modadvapi32.NewProc("CredDeleteW") + procCredFree = modadvapi32.NewProc("CredFree") + procCredEnumerate = modadvapi32.NewProc("CredEnumerateW") ) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx @@ -97,3 +99,33 @@ func nativeCredDelete(cred *Credential, typ nativeCRED_TYPE) error { return nil } + +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa374794(v=vs.85).aspx +func nativeCredEnumerate(filter string, all bool) ([]*Credential, error) { + var count int + var pcreds uintptr + var filterPtr uintptr + if !all { + filterUtf16Ptr, _ := syscall.UTF16PtrFromString(filter) + filterPtr = uintptr(unsafe.Pointer(filterUtf16Ptr)) + } else { + filterPtr = 0 + } + ret, _, err := procCredEnumerate.Call( + filterPtr, + 0, + uintptr(unsafe.Pointer(&count)), + uintptr(unsafe.Pointer(&pcreds)), + ) + if ret == 0 { + return nil, err + } + defer procCredFree.Call(pcreds) + pcredsSlice := (*[1 << 30]uintptr)(unsafe.Pointer(pcreds))[:count:count] + creds := make([]*Credential, count) + for i := range creds { + creds[i] = nativeToCredential((*nativeCREDENTIAL)(unsafe.Pointer(pcredsSlice[i]))) + } + + return creds, nil +} diff --git a/vendor/github.com/danieljoos/wincred/wincred.go b/vendor/github.com/danieljoos/wincred/wincred.go index bdcf609..5044520 100644 --- a/vendor/github.com/danieljoos/wincred/wincred.go +++ b/vendor/github.com/danieljoos/wincred/wincred.go @@ -67,3 +67,8 @@ func (t *DomainPassword) Delete() (err error) { func (t *DomainPassword) SetPassword(pw string) { t.CredentialBlob = utf16ToByte(syscall.StringToUTF16(pw)) } + +// List the contents of the Credentials store +func List() ([]*Credential, error) { + return nativeCredEnumerate("", true) +} diff --git a/wincred/wincred_windows.go b/wincred/wincred_windows.go index 134883c..e79b2e9 100644 --- a/wincred/wincred_windows.go +++ b/wincred/wincred_windows.go @@ -39,9 +39,15 @@ func (h Wincred) Get(serverURL string) (string, string, error) { } func (h Wincred) List() ([]string, []string, error) { - accts, paths, err := winc.List() + creds, err := winc.List() + paths := make([]string, len(creds)) + accts := make([]string, len(creds)) if err != nil { return err } + for i := range(creds) { + paths[i] = creds[i].TargetName + accts[i] = creds[i].UserName + } return paths, accts, nil } diff --git a/wincred/wincred_windows_test.go b/wincred/wincred_windows_test.go index b2ff86f..a37ec04 100644 --- a/wincred/wincred_windows_test.go +++ b/wincred/wincred_windows_test.go @@ -31,6 +31,21 @@ func TestWinCredHelper(t *testing.T) { t.Fatalf("expected %s, got %s\n", "foobarbaz", secret) } + paths, accts, err := helper.List() + if err != nil || len(paths) == 0 || len(accts) == 0 { + t.Fatal(err) + } + + helper.Add(creds1) + defer helper.Delete(creds1.ServerURL) + newpaths, newaccts, err := helper.List() + if len(newpaths)-len(paths) != 1 || len(newaccts)-len(accts) != 1 { + if(err == nil) { + t.Fatalf("Error: len(newpaths): %d, len(paths): %d\n len(newaccts): %d, len(accts): %d\n Error= %s", len(newpaths), len(paths), len(newaccts), len(accts), "") + } + t.Fatalf("Error: len(newpaths): %d, len(paths): %d\n len(newaccts): %d, len(accts): %d\n Error= %s", len(newpaths), len(paths), len(newaccts), len(accts), err.Error()) + } + if err := helper.Delete(creds.ServerURL); err != nil { t.Fatal(err) }