diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..d24aa628 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/docker/docker-credential-helpers + +go 1.13 + +require github.com/danieljoos/wincred v1.0.2 diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..c531bc48 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= +github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= diff --git a/vendor/github.com/danieljoos/wincred/.gitattributes b/vendor/github.com/danieljoos/wincred/.gitattributes new file mode 100644 index 00000000..d207b180 --- /dev/null +++ b/vendor/github.com/danieljoos/wincred/.gitattributes @@ -0,0 +1 @@ +*.go text eol=lf diff --git a/vendor/github.com/danieljoos/wincred/.gitignore b/vendor/github.com/danieljoos/wincred/.gitignore new file mode 100644 index 00000000..83656241 --- /dev/null +++ b/vendor/github.com/danieljoos/wincred/.gitignore @@ -0,0 +1,23 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test diff --git a/vendor/github.com/danieljoos/wincred/README.md b/vendor/github.com/danieljoos/wincred/README.md new file mode 100644 index 00000000..1b523f9a --- /dev/null +++ b/vendor/github.com/danieljoos/wincred/README.md @@ -0,0 +1,98 @@ +wincred +======= + +Go wrapper around the Windows Credential Manager API functions. + +[![Build status](https://ci.appveyor.com/api/projects/status/eclecjwniu2n4u3w/branch/master?svg=true)](https://ci.appveyor.com/project/danieljoos/wincred/branch/master) +[![GoDoc](https://godoc.org/github.com/danieljoos/wincred?status.svg)](https://godoc.org/github.com/danieljoos/wincred) + + +Installation +------------ + +```Go +go get github.com/danieljoos/wincred +``` + + +Usage +----- + +See the following examples: + +### Create and store a new generic credential object +```Go +package main + +import ( + "fmt" + "github.com/danieljoos/wincred" +) + +func main() { + cred := wincred.NewGenericCredential("myGoApplication") + cred.CredentialBlob = []byte("my secret") + err := cred.Write() + + if err != nil { + fmt.Println(err) + } +} +``` + +### Retrieve a credential object +```Go +package main + +import ( + "fmt" + "github.com/danieljoos/wincred" +) + +func main() { + cred, err := wincred.GetGenericCredential("myGoApplication") + if err == nil { + fmt.Println(string(cred.CredentialBlob)) + } +} +``` + +### Remove a credential object +```Go +package main + +import ( + "fmt" + "github.com/danieljoos/wincred" +) + +func main() { + cred, err := wincred.GetGenericCredential("myGoApplication") + if err != nil { + fmt.Println(err) + return + } + cred.Delete() +} +``` + +### List all available credentials +```Go +package main + +import ( + "fmt" + "github.com/danieljoos/wincred" +) + +func main() { + creds, err := wincred.List() + if err != nil { + fmt.Println(err) + return + } + for i := range(creds) { + fmt.Println(creds[i].TargetName) + } +} +``` diff --git a/vendor/github.com/danieljoos/wincred/appveyor.yml b/vendor/github.com/danieljoos/wincred/appveyor.yml new file mode 100644 index 00000000..cda4bb3c --- /dev/null +++ b/vendor/github.com/danieljoos/wincred/appveyor.yml @@ -0,0 +1,24 @@ +version: '{build}' +clone_folder: c:\gopath\src\github.com\danieljoos\wincred +environment: + GOPATH: c:\gopath +install: +- cmd: >- + rmdir c:\go /s /q + + appveyor DownloadFile https://storage.googleapis.com/golang/go1.6.1.windows-amd64.msi + + msiexec /i go1.6.1.windows-amd64.msi /q + + go version + + go env + + go get -t +build_script: +- cmd: go install +test_script: +- cmd: >- + cd %GOPATH%/src/github.com/danieljoos/wincred + + go test -v -cover diff --git a/vendor/github.com/danieljoos/wincred/conversion.go b/vendor/github.com/danieljoos/wincred/conversion.go index e36f876f..685f90a8 100644 --- a/vendor/github.com/danieljoos/wincred/conversion.go +++ b/vendor/github.com/danieljoos/wincred/conversion.go @@ -1,3 +1,5 @@ +// +build windows + package wincred import ( @@ -9,48 +11,57 @@ import ( "unsafe" ) -var nullPointer = unsafe.Pointer(uintptr(0)) - -// Create a Go string using a pointer to a zero-terminated UTF 16 encoded string. -// See github.com/AllenDang/w32 +// uf16PtrToString creates a Go string from a pointer to a UTF16 encoded zero-terminated string. +// Such pointers are returned from the Windows API calls. +// The function creates a copy of the string. func utf16PtrToString(wstr *uint16) string { if wstr != nil { - buf := make([]uint16, 0, 256) - for ptr := uintptr(unsafe.Pointer(wstr)); ; ptr += 2 { - rune := *(*uint16)(unsafe.Pointer(ptr)) - if rune == 0 { - return string(utf16.Decode(buf)) + for len := 0; ; len++ { + ptr := unsafe.Pointer(uintptr(unsafe.Pointer(wstr)) + uintptr(len)*unsafe.Sizeof(*wstr)) // see https://golang.org/pkg/unsafe/#Pointer (3) + if *(*uint16)(ptr) == 0 { + return string(utf16.Decode(*(*[]uint16)(unsafe.Pointer(&reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(wstr)), + Len: len, + Cap: len, + })))) } - buf = append(buf, rune) } } - return "" } -// Create a byte array from a given UTF 16 char array +// utf16ToByte creates a byte array from a given UTF 16 char array. func utf16ToByte(wstr []uint16) (result []byte) { result = make([]byte, len(wstr)*2) - for i, _ := range wstr { + for i := range wstr { binary.LittleEndian.PutUint16(result[(i*2):(i*2)+2], wstr[i]) } return } -// Copies the given C byte array to a Go byte array (see `C.GoBytes`) -func goBytes(src unsafe.Pointer, len uint32) []byte { - if src == nullPointer { +// utf16FromString creates a UTF16 char array from a string. +func utf16FromString(str string) []uint16 { + return syscall.StringToUTF16(str) +} + +// goBytes copies the given C byte array to a Go byte array (see `C.GoBytes`). +// This function avoids having cgo as dependency. +func goBytes(src uintptr, len uint32) []byte { + if src == uintptr(0) { return []byte{} } - slice := (*[1 << 30]byte)(src)[0:len] rv := make([]byte, len) - copy(rv, slice) - return rv[:] + copy(rv, *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ + Data: src, + Len: int(len), + Cap: int(len), + }))) + return rv } // Convert the given CREDENTIAL struct to a more usable structure -func nativeToCredential(cred *nativeCREDENTIAL) (result *Credential) { - if unsafe.Pointer(cred) == nullPointer { +func sysToCredential(cred *sysCREDENTIAL) (result *Credential) { + if cred == nil { return nil } result = new(Credential) @@ -60,29 +71,28 @@ func nativeToCredential(cred *nativeCREDENTIAL) (result *Credential) { result.UserName = utf16PtrToString(cred.UserName) result.LastWritten = time.Unix(0, cred.LastWritten.Nanoseconds()) result.Persist = CredentialPersistence(cred.Persist) - result.CredentialBlob = goBytes(unsafe.Pointer(cred.CredentialBlob), cred.CredentialBlobSize) + result.CredentialBlob = goBytes(cred.CredentialBlob, cred.CredentialBlobSize) result.Attributes = make([]CredentialAttribute, cred.AttributeCount) - attrSliceHeader := reflect.SliceHeader{ + attrSlice := *(*[]sysCREDENTIAL_ATTRIBUTE)(unsafe.Pointer(&reflect.SliceHeader{ Data: cred.Attributes, Len: int(cred.AttributeCount), Cap: int(cred.AttributeCount), - } - attrSlice := *(*[]nativeCREDENTIAL_ATTRIBUTE)(unsafe.Pointer(&attrSliceHeader)) + })) for i, attr := range attrSlice { resultAttr := &result.Attributes[i] resultAttr.Keyword = utf16PtrToString(attr.Keyword) - resultAttr.Value = goBytes(unsafe.Pointer(attr.Value), attr.ValueSize) + resultAttr.Value = goBytes(attr.Value, attr.ValueSize) } return result } // Convert the given Credential object back to a CREDENTIAL struct, which can be used for calling the // Windows APIs -func nativeFromCredential(cred *Credential) (result *nativeCREDENTIAL) { +func sysFromCredential(cred *Credential) (result *sysCREDENTIAL) { if cred == nil { return nil } - result = new(nativeCREDENTIAL) + result = new(sysCREDENTIAL) result.Flags = 0 result.Type = 0 result.TargetName, _ = syscall.UTF16PtrFromString(cred.TargetName) @@ -96,13 +106,13 @@ func nativeFromCredential(cred *Credential) (result *nativeCREDENTIAL) { } result.Persist = uint32(cred.Persist) result.AttributeCount = uint32(len(cred.Attributes)) - attributes := make([]nativeCREDENTIAL_ATTRIBUTE, len(cred.Attributes)) + attributes := make([]sysCREDENTIAL_ATTRIBUTE, len(cred.Attributes)) if len(attributes) > 0 { result.Attributes = uintptr(unsafe.Pointer(&attributes[0])) } else { result.Attributes = 0 } - for i, _ := range cred.Attributes { + for i := range cred.Attributes { inAttr := &cred.Attributes[i] outAttr := &attributes[i] outAttr.Keyword, _ = syscall.UTF16PtrFromString(inAttr.Keyword) diff --git a/vendor/github.com/danieljoos/wincred/conversion_unsupported.go b/vendor/github.com/danieljoos/wincred/conversion_unsupported.go new file mode 100644 index 00000000..a1ea7207 --- /dev/null +++ b/vendor/github.com/danieljoos/wincred/conversion_unsupported.go @@ -0,0 +1,11 @@ +// +build !windows + +package wincred + +func utf16ToByte(...interface{}) []byte { + return nil +} + +func utf16FromString(...interface{}) []uint16 { + return nil +} diff --git a/vendor/github.com/danieljoos/wincred/native.go b/vendor/github.com/danieljoos/wincred/sys.go similarity index 68% rename from vendor/github.com/danieljoos/wincred/native.go rename to vendor/github.com/danieljoos/wincred/sys.go index 55926c87..70aaa002 100644 --- a/vendor/github.com/danieljoos/wincred/native.go +++ b/vendor/github.com/danieljoos/wincred/sys.go @@ -1,6 +1,9 @@ +// +build windows + package wincred import ( + "reflect" "syscall" "unsafe" ) @@ -21,7 +24,7 @@ type proc interface { } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx -type nativeCREDENTIAL struct { +type sysCREDENTIAL struct { Flags uint32 Type uint32 TargetName *uint16 @@ -37,7 +40,7 @@ type nativeCREDENTIAL struct { } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa374790(v=vs.85).aspx -type nativeCREDENTIAL_ATTRIBUTE struct { +type sysCREDENTIAL_ATTRIBUTE struct { Keyword *uint16 Flags uint32 ValueSize uint32 @@ -45,22 +48,22 @@ type nativeCREDENTIAL_ATTRIBUTE struct { } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx -type nativeCRED_TYPE uint32 +type sysCRED_TYPE uint32 const ( - naCRED_TYPE_GENERIC nativeCRED_TYPE = 0x1 - naCRED_TYPE_DOMAIN_PASSWORD nativeCRED_TYPE = 0x2 - naCRED_TYPE_DOMAIN_CERTIFICATE nativeCRED_TYPE = 0x3 - naCRED_TYPE_DOMAIN_VISIBLE_PASSWORD nativeCRED_TYPE = 0x4 - naCRED_TYPE_GENERIC_CERTIFICATE nativeCRED_TYPE = 0x5 - naCRED_TYPE_DOMAIN_EXTENDED nativeCRED_TYPE = 0x6 - - naERROR_NOT_FOUND = "Element not found." + 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 + + sysERROR_NOT_FOUND = "Element not found." ) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa374804(v=vs.85).aspx -func nativeCredRead(targetName string, typ nativeCRED_TYPE) (*Credential, error) { - var pcred uintptr +func sysCredRead(targetName string, typ sysCRED_TYPE) (*Credential, error) { + var pcred *sysCREDENTIAL targetNamePtr, _ := syscall.UTF16PtrFromString(targetName) ret, _, err := procCredRead.Call( uintptr(unsafe.Pointer(targetNamePtr)), @@ -71,14 +74,14 @@ func nativeCredRead(targetName string, typ nativeCRED_TYPE) (*Credential, error) if ret == 0 { return nil, err } - defer procCredFree.Call(pcred) + defer procCredFree.Call(uintptr(unsafe.Pointer(pcred))) - return nativeToCredential((*nativeCREDENTIAL)(unsafe.Pointer(pcred))), nil + return sysToCredential(pcred), nil } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa375187(v=vs.85).aspx -func nativeCredWrite(cred *Credential, typ nativeCRED_TYPE) error { - ncred := nativeFromCredential(cred) +func sysCredWrite(cred *Credential, typ sysCRED_TYPE) error { + ncred := sysFromCredential(cred) ncred.Type = uint32(typ) ret, _, err := procCredWrite.Call( uintptr(unsafe.Pointer(ncred)), @@ -92,7 +95,7 @@ func nativeCredWrite(cred *Credential, typ nativeCRED_TYPE) error { } // http://msdn.microsoft.com/en-us/library/windows/desktop/aa374787(v=vs.85).aspx -func nativeCredDelete(cred *Credential, typ nativeCRED_TYPE) error { +func sysCredDelete(cred *Credential, typ sysCRED_TYPE) error { targetNamePtr, _ := syscall.UTF16PtrFromString(cred.TargetName) ret, _, err := procCredDelete.Call( uintptr(unsafe.Pointer(targetNamePtr)), @@ -107,7 +110,7 @@ func nativeCredDelete(cred *Credential, typ nativeCRED_TYPE) error { } // https://msdn.microsoft.com/en-us/library/windows/desktop/aa374794(v=vs.85).aspx -func nativeCredEnumerate(filter string, all bool) ([]*Credential, error) { +func sysCredEnumerate(filter string, all bool) ([]*Credential, error) { var count int var pcreds uintptr var filterPtr uintptr @@ -127,10 +130,14 @@ func nativeCredEnumerate(filter string, all bool) ([]*Credential, error) { 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]))) + 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 diff --git a/vendor/github.com/danieljoos/wincred/sys_unsupported.go b/vendor/github.com/danieljoos/wincred/sys_unsupported.go new file mode 100644 index 00000000..dd9e135a --- /dev/null +++ b/vendor/github.com/danieljoos/wincred/sys_unsupported.go @@ -0,0 +1,32 @@ +// +build !windows + +package wincred + +import "errors" + +const ( + sysCRED_TYPE_GENERIC = 0 + sysCRED_TYPE_DOMAIN_PASSWORD = 0 + sysCRED_TYPE_DOMAIN_CERTIFICATE = 0 + sysCRED_TYPE_DOMAIN_VISIBLE_PASSWORD = 0 + sysCRED_TYPE_GENERIC_CERTIFICATE = 0 + sysCRED_TYPE_DOMAIN_EXTENDED = 0 + + sysERROR_NOT_FOUND = "" +) + +func sysCredRead(...interface{}) (*Credential, error) { + return nil, errors.New("Operation not supported") +} + +func sysCredWrite(...interface{}) error { + return errors.New("Operation not supported") +} + +func sysCredDelete(...interface{}) error { + return errors.New("Operation not supported") +} + +func sysCredEnumerate(...interface{}) ([]*Credential, error) { + return nil, errors.New("Operation not supported") +} diff --git a/vendor/github.com/danieljoos/wincred/types.go b/vendor/github.com/danieljoos/wincred/types.go index a0679921..42e24a2f 100644 --- a/vendor/github.com/danieljoos/wincred/types.go +++ b/vendor/github.com/danieljoos/wincred/types.go @@ -4,19 +4,38 @@ import ( "time" ) +// CredentialPersistence describes one of three persistence modes of a credential. +// A detailed description of the available modes can be found on +// MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx type CredentialPersistence uint32 const ( - PersistSession CredentialPersistence = 0x1 + // PersistSession indicates that the credential only persists for the life + // of the current Windows login session. Such a credential is not visible in + // any other logon session, even from the same user. + PersistSession CredentialPersistence = 0x1 + + // PersistLocalMachine indicates that the credential persists for this and + // all subsequent logon sessions on this local machine/computer. It is + // however not visible for logon sessions of this user on a different + // machine. PersistLocalMachine CredentialPersistence = 0x2 - PersistEnterprise CredentialPersistence = 0x3 + + // PersistEnterprise indicates that the credential persists for this and all + // subsequent logon sessions for this user. It is also visible for logon + // sessions on different computers. + PersistEnterprise CredentialPersistence = 0x3 ) +// CredentialAttribute represents an application-specific attribute of a credential. type CredentialAttribute struct { Keyword string Value []byte } +// Credential is the basic credential structure. +// A credential is identified by its target name. +// The actual credential secret is available in the CredentialBlob field. type Credential struct { TargetName string Comment string @@ -28,10 +47,23 @@ type Credential struct { Persist CredentialPersistence } +// GenericCredential holds a credential for generic usage. +// It is typically defined and used by applications that need to manage user +// secrets. +// +// More information about the available kinds of credentials of the Windows +// Credential Management API can be found on MSDN: +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa380517(v=vs.85).aspx type GenericCredential struct { Credential } +// DomainPassword holds a domain credential that is typically used by the +// operating system for user logon. +// +// More information about the available kinds of credentials of the Windows +// Credential Management API can be found on MSDN: +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa380517(v=vs.85).aspx type DomainPassword struct { Credential } diff --git a/vendor/github.com/danieljoos/wincred/wincred.go b/vendor/github.com/danieljoos/wincred/wincred.go index ac5d4a70..ff79d8e8 100644 --- a/vendor/github.com/danieljoos/wincred/wincred.go +++ b/vendor/github.com/danieljoos/wincred/wincred.go @@ -1,19 +1,23 @@ +// Package wincred provides primitives for accessing the Windows Credentials Management API. +// This includes functions for retrieval, listing and storage of credentials as well as Go structures for convenient access to the credential data. +// +// A more detailed description of Windows Credentials Management can be found on +// MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/aa374789(v=vs.85).aspx package wincred -import ( - "syscall" -) - -// Get the generic credential with the given name from Windows credential manager +// GetGenericCredential fetches the generic credential with the given name from Windows credential manager. +// It returns nil and an error if the credential could not be found or an error occurred. func GetGenericCredential(targetName string) (*GenericCredential, error) { - cred, err := nativeCredRead(targetName, naCRED_TYPE_GENERIC) + cred, err := sysCredRead(targetName, sysCRED_TYPE_GENERIC) if cred != nil { return &GenericCredential{*cred}, err } return nil, err } -// Create a new generic credential with the given name +// NewGenericCredential creates a new generic credential object with the given name. +// The persist mode of the newly created object is set to a default value that indicates local-machine-wide storage. +// The credential object is NOT yet persisted to the Windows credential vault. func NewGenericCredential(targetName string) (result *GenericCredential) { result = new(GenericCredential) result.TargetName = targetName @@ -21,28 +25,31 @@ func NewGenericCredential(targetName string) (result *GenericCredential) { return } -// Persist the credential to Windows credential manager +// Write persists the generic credential object to Windows credential manager. func (t *GenericCredential) Write() (err error) { - err = nativeCredWrite(&t.Credential, naCRED_TYPE_GENERIC) + err = sysCredWrite(&t.Credential, sysCRED_TYPE_GENERIC) return } -// Delete the credential from Windows credential manager +// Delete removes the credential object from Windows credential manager. func (t *GenericCredential) Delete() (err error) { - err = nativeCredDelete(&t.Credential, naCRED_TYPE_GENERIC) + err = sysCredDelete(&t.Credential, sysCRED_TYPE_GENERIC) return } -// Get the domain password credential with the given target host name +// GetDomainPassword fetches the domain-password credential with the given target host name from Windows credential manager. +// It returns nil and an error if the credential could not be found or an error occurred. func GetDomainPassword(targetName string) (*DomainPassword, error) { - cred, err := nativeCredRead(targetName, naCRED_TYPE_DOMAIN_PASSWORD) + cred, err := sysCredRead(targetName, sysCRED_TYPE_DOMAIN_PASSWORD) if cred != nil { return &DomainPassword{*cred}, err } return nil, err } -// Create a new domain password credential used for login to the given target host name +// NewDomainPassword creates a new domain-password credential used for login to the given target host name. +// The persist mode of the newly created object is set to a default value that indicates local-machine-wide storage. +// The credential object is NOT yet persisted to the Windows credential vault. func NewDomainPassword(targetName string) (result *DomainPassword) { result = new(DomainPassword) result.TargetName = targetName @@ -50,28 +57,27 @@ func NewDomainPassword(targetName string) (result *DomainPassword) { return } -// Persist the domain password credential to Windows credential manager +// Write persists the domain-password credential to Windows credential manager. func (t *DomainPassword) Write() (err error) { - err = nativeCredWrite(&t.Credential, naCRED_TYPE_DOMAIN_PASSWORD) + err = sysCredWrite(&t.Credential, sysCRED_TYPE_DOMAIN_PASSWORD) return } -// Delete the domain password credential from Windows credential manager +// Delete removes the domain-password credential from Windows credential manager. func (t *DomainPassword) Delete() (err error) { - err = nativeCredDelete(&t.Credential, naCRED_TYPE_DOMAIN_PASSWORD) + err = sysCredDelete(&t.Credential, sysCRED_TYPE_DOMAIN_PASSWORD) return } -// Set the CredentialBlob field of a domain password credential -// using an UTF16 encoded password string +// SetPassword sets the CredentialBlob field of a domain password credential to the given string. func (t *DomainPassword) SetPassword(pw string) { - t.CredentialBlob = utf16ToByte(syscall.StringToUTF16(pw)) + t.CredentialBlob = utf16ToByte(utf16FromString(pw)) } -// List the contents of the Credentials store +// List retrieves all credentials of the Credentials store. func List() ([]*Credential, error) { - creds, err := nativeCredEnumerate("", true) - if err != nil && err.Error() == naERROR_NOT_FOUND { + creds, err := sysCredEnumerate("", true) + if err != nil && err.Error() == sysERROR_NOT_FOUND { // Ignore ERROR_NOT_FOUND and return an empty list instead creds = []*Credential{} err = nil diff --git a/vendor/modules.txt b/vendor/modules.txt new file mode 100644 index 00000000..9f8a1a41 --- /dev/null +++ b/vendor/modules.txt @@ -0,0 +1,2 @@ +# github.com/danieljoos/wincred v1.0.2 +github.com/danieljoos/wincred