wincred

package module
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2024 License: MIT Imports: 3 Imported by: 74

README

wincred

Go wrapper around the Windows Credential Manager API functions.

GitHub release Test Status Go Report Card Codecov PkgGoDev

Installation

go get github.com/danieljoos/wincred

Usage

See the following examples:

Create and store a new generic credential object
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
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
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
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)
    }
}

Hints

Encoding

The credential objects simply store byte arrays without specific meaning or encoding. For sharing between different applications, it might make sense to apply an explicit string encoding - for example UTF-16 LE (used nearly everywhere in the Win32 API).

package main

import (
	"fmt"
	"os"

	"github.com/danieljoos/wincred"
	"golang.org/x/text/encoding/unicode"
	"golang.org/x/text/transform"
)

func main() {
	cred := wincred.NewGenericCredential("myGoApplication")

	encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
	blob, _, err := transform.Bytes(encoder, []byte("mysecret"))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	cred.CredentialBlob = blob
	err = cred.Write()

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

Limitations

The size of a credential blob is limited to 2560 Bytes by the Windows API.

Documentation

Overview

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 Docs: https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/credentials-management

Index

Examples

Constants

View Source
const (
	// ErrElementNotFound is the error that is returned if a requested element cannot be found.
	// This error constant can be used to check if a credential could not be found.
	ErrElementNotFound = sysERROR_NOT_FOUND

	// ErrInvalidParameter is the error that is returned for invalid parameters.
	// This error constant can be used to check if the given function parameters were invalid.
	// For example when trying to create a new generic credential with an empty target name.
	ErrInvalidParameter = sysERROR_INVALID_PARAMETER

	// ErrBadUsername is returned when the credential's username is invalid.
	ErrBadUsername = sysERROR_BAD_USERNAME
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Credential

type Credential struct {
	TargetName     string
	Comment        string
	LastWritten    time.Time
	CredentialBlob []byte
	Attributes     []CredentialAttribute
	TargetAlias    string
	UserName       string
	Persist        CredentialPersistence
}

Credential is the basic credential structure. A credential is identified by its target name. The actual credential secret is available in the CredentialBlob field.

func FilteredList added in v1.0.3

func FilteredList(filter string) ([]*Credential, error)

FilteredList retrieves the list of credentials from the Credentials store that match the given filter. The filter string defines the prefix followed by an asterisk for the `TargetName` attribute of the credentials.

Example
if creds, err := FilteredList("my*"); err == nil {
	for _, cred := range creds {
		fmt.Println(cred.TargetName)
	}
}
Output:

func List

func List() ([]*Credential, error)

List retrieves all credentials of the Credentials store.

Example
if creds, err := List(); err == nil {
	for _, cred := range creds {
		fmt.Println(cred.TargetName)
	}
}
Output:

type CredentialAttribute

type CredentialAttribute struct {
	Keyword string
	Value   []byte
}

CredentialAttribute represents an application-specific attribute of a credential.

type CredentialPersistence

type CredentialPersistence uint32

CredentialPersistence describes one of three persistence modes of a credential. A detailed description of the available modes can be found on Docs: https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw

const (
	// 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 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
)

type DomainPassword

type DomainPassword 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 Docs: https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/kinds-of-credentials

func GetDomainPassword

func GetDomainPassword(targetName string) (*DomainPassword, error)

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 NewDomainPassword

func NewDomainPassword(targetName string) (result *DomainPassword)

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 (*DomainPassword) Delete

func (t *DomainPassword) Delete() (err error)

Delete removes the domain-password credential from Windows credential manager.

func (*DomainPassword) SetPassword

func (t *DomainPassword) SetPassword(pw string)

SetPassword sets the CredentialBlob field of a domain password credential to the given string.

func (*DomainPassword) Write

func (t *DomainPassword) Write() (err error)

Write persists the domain-password credential to Windows credential manager.

type GenericCredential

type GenericCredential struct {
	Credential
}

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 Docs: https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/kinds-of-credentials

func GetGenericCredential

func GetGenericCredential(targetName string) (*GenericCredential, error)

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.

Example
if cred, err := GetGenericCredential("myGoApplication"); err == nil {
	fmt.Println(cred.TargetName, string(cred.CredentialBlob))
}
Output:

func NewGenericCredential

func NewGenericCredential(targetName string) (result *GenericCredential)

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 (*GenericCredential) Delete

func (t *GenericCredential) Delete() (err error)

Delete removes the credential object from Windows credential manager.

Example
cred, _ := GetGenericCredential("myGoApplication")
if err := cred.Delete(); err == nil {
	fmt.Println("Deleted")
}
Output:

func (*GenericCredential) Write

func (t *GenericCredential) Write() (err error)

Write persists the generic credential object to Windows credential manager.

Example
cred := NewGenericCredential("myGoApplication")
cred.CredentialBlob = []byte("my secret")
if err := cred.Write(); err == nil {
	fmt.Println("Created")
}
Output:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL