func FindInternetPassword(pass *InternetPassword) (*InternetPassword, error) {
	if err := pass.CheckValidity(); err != nil {
		return nil, err
	}
	serverName := C.CString(pass.ServerName)
	defer C.free(unsafe.Pointer(serverName))
	var securityDomain *C.char
	if pass.SecurityDomain != "" {
		securityDomain = C.CString(pass.SecurityDomain)
		defer C.free(unsafe.Pointer(securityDomain))
	}
	accountName := C.CString(pass.AccountName)
	defer C.free(unsafe.Pointer(accountName))
	path := C.CString(pass.Path)
	defer C.free(unsafe.Pointer(path))
	var passwordLength C.UInt32
	var password unsafe.Pointer
	var itemRef C.SecKeychainItemRef
	errCode := C.SecKeychainFindInternetPassword(
		nil,  
		C.UInt32(len(pass.ServerName)),
		serverName,
		C.UInt32(len(pass.SecurityDomain)),
		securityDomain,
		C.UInt32(len(pass.AccountName)),
		accountName,
		C.UInt32(len(pass.Path)),
		path,
		C.UInt16(pass.Port),
		C.SecProtocolType(pass.Protocol),
		C.SecAuthenticationType(pass.AuthType),
		&passwordLength,
		&password,
		&itemRef,
	)
	if err := newKeychainError(errCode); err != nil {
		return nil, err
	}
	defer C.CFRelease(C.CFTypeRef(itemRef))
	defer C.SecKeychainItemFreeContent(nil, password)
	resp := InternetPassword{}
	resp.Password = C.GoStringN((*C.char)(password), C.int(passwordLength))
	items := C.CFArrayCreateMutable(nil, 1, nil)
	defer C.CFRelease(C.CFTypeRef(items))
	C.CFArrayAppendValue(items, unsafe.Pointer(itemRef))
	dict := C.CFDictionaryCreateMutable(nil, 0, nil, nil)
	defer C.CFRelease(C.CFTypeRef(dict))
	C.CFDictionaryAddValue(dict, unsafe.Pointer(C.kSecClass), unsafe.Pointer(C.kSecClassInternetPassword))
	C.CFDictionaryAddValue(dict, unsafe.Pointer(C.kSecMatchItemList), unsafe.Pointer(items))
	C.CFDictionaryAddValue(dict, unsafe.Pointer(C.kSecReturnAttributes), unsafe.Pointer(C.kCFBooleanTrue))
	var result C.CFTypeRef = nil
	errCode = C.SecItemCopyMatching(dict, &result)
	if err := newKeychainError(errCode); err != nil {
		return nil, err
	}
	defer C.CFRelease(result)
	resultdict := (C.CFDictionaryRef)(result)  
	resp.ServerName = getCFDictValueUTF8String(resultdict, C.kSecAttrServer)
	resp.SecurityDomain = getCFDictValueUTF8String(resultdict, C.kSecAttrSecurityDomain)
	resp.AccountName = getCFDictValueUTF8String(resultdict, C.kSecAttrAccount)
	resp.Path = getCFDictValueUTF8String(resultdict, C.kSecAttrPath)
	resp.Port = (int)(getCFDictValueInt32(resultdict, C.kSecAttrPort))
	resp.Protocol = protocolTypeFromRef(getCFDictValueRef(resultdict, C.kSecAttrProtocol))
	resp.AuthType = authenticationTypeFromRef(getCFDictValueRef(resultdict, C.kSecAttrAuthenticationType))
	return &resp, nil
}
Finds the first Internet password item that matches the attributes you
provide in pass. Some attributes, such as ServerName and AccountName may be
left blank, in which case they will be ignored in the search.

Returns an error if the lookup was unsuccessful.
package osxkeychain
import "C"
import (
	"errors"
	"fmt"
	"math"
	"unicode/utf8"
	"unsafe"
)
type ProtocolType C.SecProtocolType
const (
	ProtocolHTTP  ProtocolType = C.kSecProtocolTypeHTTP
	ProtocolHTTPS              = C.kSecProtocolTypeHTTPS
	ProtocolAny                = C.kSecProtocolTypeAny
)
type AuthenticationType C.SecAuthenticationType
const (
	AuthenticationHTTPBasic AuthenticationType = C.kSecAuthenticationTypeHTTPBasic
	AuthenticationDefault                      = C.kSecAuthenticationTypeDefault
	AuthenticationAny                          = C.kSecAuthenticationTypeAny
)
type InternetPassword struct {
	ServerName     string
	SecurityDomain string
	AccountName    string
	Path           string
	Port           int  
	Password       string
	Protocol       ProtocolType
	AuthType       AuthenticationType
}
func check32Bit(paramName, paramValue string) error {
	if uint64(len(paramValue)) > math.MaxUint32 {
		return errors.New(paramName + " has size overflowing 32 bits")
	}
	return nil
}
func check32BitUTF8(paramName, paramValue string) error {
	if err := check32Bit(paramName, paramValue); err != nil {
		return err
	}
	if !utf8.ValidString(paramValue) {
		return errors.New(paramName + " is not a valid UTF-8 string")
	}
	return nil
}
func (pass *InternetPassword) CheckValidity() error {
	if err := check32BitUTF8("ServerName", pass.ServerName); err != nil {
		return err
	}
	if err := check32BitUTF8("SecurityDomain", pass.SecurityDomain); err != nil {
		return err
	}
	if err := check32BitUTF8("AccountName", pass.AccountName); err != nil {
		return err
	}
	if err := check32BitUTF8("Path", pass.Path); err != nil {
		return err
	}
	if err := check32Bit("Password", pass.Password); err != nil {
		return err
	}
	return nil
}
type keychainError C.OSStatus
const (
	ErrUnimplemented     keychainError = C.errSecUnimplemented
	ErrParam             keychainError = C.errSecParam
	ErrAllocate          keychainError = C.errSecAllocate
	ErrNotAvailable      keychainError = C.errSecNotAvailable
	ErrReadOnly          keychainError = C.errSecReadOnly
	ErrAuthFailed        keychainError = C.errSecAuthFailed
	ErrNoSuchKeychain    keychainError = C.errSecNoSuchKeychain
	ErrInvalidKeychain   keychainError = C.errSecInvalidKeychain
	ErrDuplicateKeychain keychainError = C.errSecDuplicateKeychain
	ErrDuplicateCallback keychainError = C.errSecDuplicateCallback
	ErrInvalidCallback   keychainError = C.errSecInvalidCallback
	ErrDuplicateItem     keychainError = C.errSecDuplicateItem
	ErrItemNotFound      keychainError = C.errSecItemNotFound
	ErrBufferTooSmall    keychainError = C.errSecBufferTooSmall
	ErrDataTooLarge      keychainError = C.errSecDataTooLarge
	ErrNoSuchAttr        keychainError = C.errSecNoSuchAttr
	ErrInvalidItemRef    keychainError = C.errSecInvalidItemRef
	ErrInvalidSearchRef  keychainError = C.errSecInvalidSearchRef
	ErrNoSuchClass       keychainError = C.errSecNoSuchClass
	ErrNoDefaultKeychain keychainError = C.errSecNoDefaultKeychain
	ErrReadOnlyAttr      keychainError = C.errSecReadOnlyAttr
)
func newKeychainError(errCode C.OSStatus) error {
	if errCode == C.noErr {
		return nil
	}
	return keychainError(errCode)
}
func (ke keychainError) Error() string {
	errorMessageCFString := C.SecCopyErrorMessageString(C.OSStatus(ke), nil)
	defer C.CFRelease(C.CFTypeRef(errorMessageCFString))
	errorMessageCString := C.CFStringGetCStringPtr(errorMessageCFString, C.kCFStringEncodingASCII)
	if errorMessageCString != nil {
		return C.GoString(errorMessageCString)
	}
	return fmt.Sprintf("keychainError with unknown error code %d", C.OSStatus(ke))
}
func protocolTypeFromRef(proto C.CFTypeRef) ProtocolType {
	switch proto {
	case C.kSecAttrProtocolHTTP:
		return ProtocolHTTP
	case C.kSecAttrProtocolHTTPS:
		return ProtocolHTTPS
	}
	panic(fmt.Sprintf("unknown proto in protocolTypeToGo: %v", proto))
}
func authenticationTypeFromRef(authType C.CFTypeRef) AuthenticationType {
	switch authType {
	case C.kSecAttrAuthenticationTypeHTTPBasic:
		return AuthenticationHTTPBasic
	case C.kSecAttrAuthenticationTypeDefault:
		return AuthenticationDefault
	}
	panic(fmt.Sprintf("unknown authType in authenticationTypeFromStringRef: %v", authType))
}
func AddInternetPassword(pass *InternetPassword) error {
	if err := pass.CheckValidity(); err != nil {
		return err
	}
	serverName := C.CString(pass.ServerName)
	defer C.free(unsafe.Pointer(serverName))
	var securityDomain *C.char
	if pass.SecurityDomain != "" {
		securityDomain = C.CString(pass.SecurityDomain)
		defer C.free(unsafe.Pointer(securityDomain))
	}
	accountName := C.CString(pass.AccountName)
	defer C.free(unsafe.Pointer(accountName))
	path := C.CString(pass.Path)
	defer C.free(unsafe.Pointer(path))
	password := unsafe.Pointer(C.CString(pass.Password))
	defer C.free(password)
	errCode := C.SecKeychainAddInternetPassword(
		nil,  
		C.UInt32(len(pass.ServerName)),
		serverName,
		C.UInt32(len(pass.SecurityDomain)),
		securityDomain,
		C.UInt32(len(pass.AccountName)),
		accountName,
		C.UInt32(len(pass.Path)),
		path,
		C.UInt16(pass.Port),
		C.SecProtocolType(pass.Protocol),
		C.SecAuthenticationType(pass.AuthType),
		C.UInt32(len(pass.Password)),
		password,
		nil,
	)
	return newKeychainError(errCode)
}