mirror of
https://github.com/docker/docker-credential-helpers.git
synced 2026-06-13 16:01:28 +05:30
Updated vendor pkg: github.com/danieljoos/wincred
This includes the following changes: - Removed need for `C` - Added some null checks to avoid possible panics - `List` returns an empty list instead of an error, in case no credentials are installed on the system Signed-off-by: Daniel Joos <daniel@joosweb.de>
This commit is contained in:
+21
-3
@@ -1,7 +1,6 @@
|
||||
package wincred
|
||||
|
||||
import (
|
||||
"C"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"syscall"
|
||||
@@ -10,6 +9,8 @@ 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
|
||||
func utf16PtrToString(wstr *uint16) string {
|
||||
@@ -36,8 +37,22 @@ func utf16ToByte(wstr []uint16) (result []byte) {
|
||||
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 {
|
||||
return []byte{}
|
||||
}
|
||||
slice := (*[1 << 30]byte)(src)[0:len]
|
||||
rv := make([]byte, len)
|
||||
copy(rv, slice)
|
||||
return rv[:]
|
||||
}
|
||||
|
||||
// Convert the given CREDENTIAL struct to a more usable structure
|
||||
func nativeToCredential(cred *nativeCREDENTIAL) (result *Credential) {
|
||||
if unsafe.Pointer(cred) == nullPointer {
|
||||
return nil
|
||||
}
|
||||
result = new(Credential)
|
||||
result.Comment = utf16PtrToString(cred.Comment)
|
||||
result.TargetName = utf16PtrToString(cred.TargetName)
|
||||
@@ -45,7 +60,7 @@ 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 = C.GoBytes(unsafe.Pointer(cred.CredentialBlob), C.int(cred.CredentialBlobSize))
|
||||
result.CredentialBlob = goBytes(unsafe.Pointer(cred.CredentialBlob), cred.CredentialBlobSize)
|
||||
result.Attributes = make([]CredentialAttribute, cred.AttributeCount)
|
||||
attrSliceHeader := reflect.SliceHeader{
|
||||
Data: cred.Attributes,
|
||||
@@ -56,7 +71,7 @@ func nativeToCredential(cred *nativeCREDENTIAL) (result *Credential) {
|
||||
for i, attr := range attrSlice {
|
||||
resultAttr := &result.Attributes[i]
|
||||
resultAttr.Keyword = utf16PtrToString(attr.Keyword)
|
||||
resultAttr.Value = C.GoBytes(unsafe.Pointer(attr.Value), C.int(attr.ValueSize))
|
||||
resultAttr.Value = goBytes(unsafe.Pointer(attr.Value), attr.ValueSize)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -64,6 +79,9 @@ func nativeToCredential(cred *nativeCREDENTIAL) (result *Credential) {
|
||||
// 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) {
|
||||
if cred == nil {
|
||||
return nil
|
||||
}
|
||||
result = new(nativeCREDENTIAL)
|
||||
result.Flags = 0
|
||||
result.Type = 0
|
||||
|
||||
+12
-6
@@ -1,7 +1,6 @@
|
||||
package wincred
|
||||
|
||||
import (
|
||||
"C"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
@@ -9,13 +8,18 @@ import (
|
||||
var (
|
||||
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
||||
|
||||
procCredRead = modadvapi32.NewProc("CredReadW")
|
||||
procCredWrite = modadvapi32.NewProc("CredWriteW")
|
||||
procCredDelete = modadvapi32.NewProc("CredDeleteW")
|
||||
procCredFree = modadvapi32.NewProc("CredFree")
|
||||
procCredEnumerate = modadvapi32.NewProc("CredEnumerateW")
|
||||
procCredRead proc = modadvapi32.NewProc("CredReadW")
|
||||
procCredWrite proc = modadvapi32.NewProc("CredWriteW")
|
||||
procCredDelete proc = modadvapi32.NewProc("CredDeleteW")
|
||||
procCredFree proc = modadvapi32.NewProc("CredFree")
|
||||
procCredEnumerate proc = modadvapi32.NewProc("CredEnumerateW")
|
||||
)
|
||||
|
||||
// Interface for syscall.Proc: helps testing
|
||||
type proc interface {
|
||||
Call(a ...uintptr) (r1, r2 uintptr, lastErr error)
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx
|
||||
type nativeCREDENTIAL struct {
|
||||
Flags uint32
|
||||
@@ -50,6 +54,8 @@ const (
|
||||
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."
|
||||
)
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374804(v=vs.85).aspx
|
||||
|
||||
+7
-1
@@ -70,5 +70,11 @@ func (t *DomainPassword) SetPassword(pw string) {
|
||||
|
||||
// List the contents of the Credentials store
|
||||
func List() ([]*Credential, error) {
|
||||
return nativeCredEnumerate("", true)
|
||||
creds, err := nativeCredEnumerate("", true)
|
||||
if err != nil && err.Error() == naERROR_NOT_FOUND {
|
||||
// Ignore ERROR_NOT_FOUND and return an empty list instead
|
||||
creds = []*Credential{}
|
||||
err = nil
|
||||
}
|
||||
return creds, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user