1
0
mirror of https://github.com/docker/docker-credential-helpers.git synced 2026-06-13 16:01:28 +05:30

Merge pull request #3 from calavera/cleanup

Cleanup imports and vendor dependencies.
This commit is contained in:
David Calavera
2016-02-22 16:20:03 -08:00
10 changed files with 345 additions and 15 deletions
+10 -10
View File
@@ -1,23 +1,23 @@
.PHONY: all deps osxkeychain test .PHONY: all deps osxkeychain test validate wincred
all: test all: test
deps: deps:
go get -t ./...
go get github.com/golang/lint/golint go get github.com/golang/lint/golint
osxkeychain: osxkeychain:
mkdir -p bin mkdir -p bin
go build -o bin/docker-credential-osxkeychain osxkeychain/cmd/main_darwin.go go build -o bin/docker-credential-osxkeychain osxkeychain/cmd/main_darwin.go
test:
# tests all packages except vendor
go test -v `go list ./... | grep -v /vendor/`
validate:
go vet ./credentials ./osxkeychain
golint `go list ./... | grep -v /vendor/`
gofmt -s -l `ls **/*.go | grep -v vendor`
wincred: wincred:
mkdir -p bin mkdir -p bin
go build -o bin/docker-credential-wincred wincred/cmd/main_windows.go go build -o bin/docker-credential-wincred wincred/cmd/main_windows.go
test:
go test -v ./...
validate:
go vet ./...
golint ./...
gofmt -s -l .
+1 -1
View File
@@ -36,9 +36,9 @@ install:
- set Path=c:\mingw64\bin;c:\go\bin;%Path% - set Path=c:\mingw64\bin;c:\go\bin;%Path%
- go version - go version
- go env - go env
- go get -v -t ./...
build_script: build_script:
- go vet ./wincred
- go test -v github.com/docker/docker-credential-helpers/wincred - go test -v github.com/docker/docker-credential-helpers/wincred
# Disable automatic tests # Disable automatic tests
+2 -2
View File
@@ -1,8 +1,8 @@
package main package main
import ( import (
"github.com/calavera/docker-credential-helpers/credentials" "github.com/docker/docker-credential-helpers/credentials"
"github.com/calavera/docker-credential-helpers/osxkeychain" "github.com/docker/docker-credential-helpers/osxkeychain"
) )
func main() { func main() {
+1 -1
View File
@@ -15,7 +15,7 @@ import (
"strings" "strings"
"unsafe" "unsafe"
"github.com/calavera/docker-credential-helpers/credentials" "github.com/docker/docker-credential-helpers/credentials"
) )
// errCredentialsNotFound is the specific error message returned by OS X // errCredentialsNotFound is the specific error message returned by OS X
+1 -1
View File
@@ -3,7 +3,7 @@ package osxkeychain
import ( import (
"testing" "testing"
"github.com/calavera/docker-credential-helpers/credentials" "github.com/docker/docker-credential-helpers/credentials"
) )
func TestOSXKeychainHelper(t *testing.T) { func TestOSXKeychainHelper(t *testing.T) {
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Daniel Joos
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+104
View File
@@ -0,0 +1,104 @@
package wincred
import (
"C"
"encoding/binary"
"reflect"
"syscall"
"time"
"unicode/utf16"
"unsafe"
)
// 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 {
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))
}
buf = append(buf, rune)
}
}
return ""
}
// Create 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 {
binary.LittleEndian.PutUint16(result[(i*2):(i*2)+2], wstr[i])
}
return
}
// Convert the given CREDENTIAL struct to a more usable structure
func nativeToCredential(cred *nativeCREDENTIAL) (result *Credential) {
result = new(Credential)
result.Comment = utf16PtrToString(cred.Comment)
result.TargetName = utf16PtrToString(cred.TargetName)
result.TargetAlias = utf16PtrToString(cred.TargetAlias)
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.Attributes = make([]CredentialAttribute, cred.AttributeCount)
attrSliceHeader := 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 = C.GoBytes(unsafe.Pointer(attr.Value), C.int(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) {
result = new(nativeCREDENTIAL)
result.Flags = 0
result.Type = 0
result.TargetName, _ = syscall.UTF16PtrFromString(cred.TargetName)
result.Comment, _ = syscall.UTF16PtrFromString(cred.Comment)
result.LastWritten = syscall.NsecToFiletime(cred.LastWritten.UnixNano())
result.CredentialBlobSize = uint32(len(cred.CredentialBlob))
if len(cred.CredentialBlob) > 0 {
result.CredentialBlob = uintptr(unsafe.Pointer(&cred.CredentialBlob[0]))
} else {
result.CredentialBlob = 0
}
result.Persist = uint32(cred.Persist)
result.AttributeCount = uint32(len(cred.Attributes))
attributes := make([]nativeCREDENTIAL_ATTRIBUTE, len(cred.Attributes))
if len(attributes) > 0 {
result.Attributes = uintptr(unsafe.Pointer(&attributes[0]))
} else {
result.Attributes = 0
}
for i, _ := range cred.Attributes {
inAttr := &cred.Attributes[i]
outAttr := &attributes[i]
outAttr.Keyword, _ = syscall.UTF16PtrFromString(inAttr.Keyword)
outAttr.Flags = 0
outAttr.ValueSize = uint32(len(inAttr.Value))
if len(inAttr.Value) > 0 {
outAttr.Value = uintptr(unsafe.Pointer(&inAttr.Value[0]))
} else {
outAttr.Value = 0
}
}
result.TargetAlias, _ = syscall.UTF16PtrFromString(cred.TargetAlias)
result.UserName, _ = syscall.UTF16PtrFromString(cred.UserName)
return
}
+99
View File
@@ -0,0 +1,99 @@
package wincred
import (
"syscall"
"unsafe"
)
var (
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
procCredRead = modadvapi32.NewProc("CredReadW")
procCredWrite = modadvapi32.NewProc("CredWriteW")
procCredDelete = modadvapi32.NewProc("CredDeleteW")
procCredFree = modadvapi32.NewProc("CredFree")
)
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx
type nativeCREDENTIAL struct {
Flags uint32
Type uint32
TargetName *uint16
Comment *uint16
LastWritten syscall.Filetime
CredentialBlobSize uint32
CredentialBlob uintptr
Persist uint32
AttributeCount uint32
Attributes uintptr
TargetAlias *uint16
UserName *uint16
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374790(v=vs.85).aspx
type nativeCREDENTIAL_ATTRIBUTE struct {
Keyword *uint16
Flags uint32
ValueSize uint32
Value uintptr
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx
type nativeCRED_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
)
// 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
targetNamePtr, _ := syscall.UTF16PtrFromString(targetName)
ret, _, err := procCredRead.Call(
uintptr(unsafe.Pointer(targetNamePtr)),
uintptr(typ),
0,
uintptr(unsafe.Pointer(&pcred)),
)
if ret == 0 {
return nil, err
}
defer procCredFree.Call(pcred)
return nativeToCredential((*nativeCREDENTIAL)(unsafe.Pointer(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)
ncred.Type = uint32(typ)
ret, _, err := procCredWrite.Call(
uintptr(unsafe.Pointer(ncred)),
0,
)
if ret == 0 {
return err
}
return nil
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374787(v=vs.85).aspx
func nativeCredDelete(cred *Credential, typ nativeCRED_TYPE) error {
targetNamePtr, _ := syscall.UTF16PtrFromString(cred.TargetName)
ret, _, err := procCredDelete.Call(
uintptr(unsafe.Pointer(targetNamePtr)),
uintptr(typ),
0,
)
if ret == 0 {
return err
}
return nil
}
+37
View File
@@ -0,0 +1,37 @@
package wincred
import (
"time"
)
type CredentialPersistence uint32
const (
PersistSession CredentialPersistence = 0x1
PersistLocalMachine CredentialPersistence = 0x2
PersistEnterprise CredentialPersistence = 0x3
)
type CredentialAttribute struct {
Keyword string
Value []byte
}
type Credential struct {
TargetName string
Comment string
LastWritten time.Time
CredentialBlob []byte
Attributes []CredentialAttribute
TargetAlias string
UserName string
Persist CredentialPersistence
}
type GenericCredential struct {
Credential
}
type DomainPassword struct {
Credential
}
+69
View File
@@ -0,0 +1,69 @@
package wincred
import (
"syscall"
)
// Get the generic credential with the given name from Windows credential manager
func GetGenericCredential(targetName string) (*GenericCredential, error) {
cred, err := nativeCredRead(targetName, naCRED_TYPE_GENERIC)
if cred != nil {
return &GenericCredential{*cred}, err
}
return nil, err
}
// Create a new generic credential with the given name
func NewGenericCredential(targetName string) (result *GenericCredential) {
result = new(GenericCredential)
result.TargetName = targetName
result.Persist = PersistLocalMachine
return
}
// Persist the credential to Windows credential manager
func (t *GenericCredential) Write() (err error) {
err = nativeCredWrite(&t.Credential, naCRED_TYPE_GENERIC)
return
}
// Delete the credential from Windows credential manager
func (t *GenericCredential) Delete() (err error) {
err = nativeCredDelete(&t.Credential, naCRED_TYPE_GENERIC)
return
}
// Get the domain password credential with the given target host name
func GetDomainPassword(targetName string) (*DomainPassword, error) {
cred, err := nativeCredRead(targetName, naCRED_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
func NewDomainPassword(targetName string) (result *DomainPassword) {
result = new(DomainPassword)
result.TargetName = targetName
result.Persist = PersistLocalMachine
return
}
// Persist the domain password credential to Windows credential manager
func (t *DomainPassword) Write() (err error) {
err = nativeCredWrite(&t.Credential, naCRED_TYPE_DOMAIN_PASSWORD)
return
}
// Delete the domain password credential from Windows credential manager
func (t *DomainPassword) Delete() (err error) {
err = nativeCredDelete(&t.Credential, naCRED_TYPE_DOMAIN_PASSWORD)
return
}
// Set the CredentialBlob field of a domain password credential
// using an UTF16 encoded password string
func (t *DomainPassword) SetPassword(pw string) {
t.CredentialBlob = utf16ToByte(syscall.StringToUTF16(pw))
}