Exemple #1
0
// AddItem adds a Item
func AddItem(item Item) error {
	cfDict, err := ConvertMapToCFDictionary(item.attr)
	if err != nil {
		return err
	}
	defer Release(C.CFTypeRef(cfDict))

	errCode := C.SecItemAdd(cfDict, nil)
	err = checkError(errCode)
	return err
}
Exemple #2
0
// AddItem adds a Item
func AddItem(item Item) error {
	cfDict, err := convertAttr(item.attr)
	if err != nil {
		return err
	}
	defer C.CFRelease(C.CFTypeRef(cfDict))

	errCode := C.SecItemAdd(cfDict, nil)
	err = checkError(errCode)
	return err
}
// AddGenericPassword adds a generic password with the given
// attributes to the default keychain.
func AddGenericPassword(attributes *GenericPasswordAttributes) (err error) {
	if err = attributes.CheckValidity(); err != nil {
		return
	}

	var serviceNameString C.CFStringRef
	if serviceNameString, err = _UTF8StringToCFString(attributes.ServiceName); err != nil {
		return
	}
	defer C.CFRelease(C.CFTypeRef(serviceNameString))

	var accountNameString C.CFStringRef
	if accountNameString, err = _UTF8StringToCFString(attributes.AccountName); err != nil {
		return
	}
	defer C.CFRelease(C.CFTypeRef(accountNameString))

	dataBytes := bytesToCFData(attributes.Password)
	defer C.CFRelease(C.CFTypeRef(dataBytes))

	query := map[C.CFTypeRef]C.CFTypeRef{
		secClass:       secClassGenericPassword,
		secAttrService: C.CFTypeRef(serviceNameString),
		secAttrAccount: C.CFTypeRef(accountNameString),
		secValueData:   C.CFTypeRef(dataBytes),
	}

	access, err := createAccess(attributes.ServiceName, attributes.TrustedApplications)
	if err != nil {
		return
	}

	if access != nil {
		defer C.CFRelease(C.CFTypeRef(access))
		query[secAttrAccess] = C.CFTypeRef(access)
	}

	queryDict := mapToCFDictionary(query)
	defer C.CFRelease(C.CFTypeRef(queryDict))

	errCode := C.SecItemAdd(queryDict, nil)

	err = newKeychainError(errCode)
	return
}
Exemple #4
0
func (k *keychain) Set(item Item) error {
	var kref C.SecKeychainRef
	var err error

	if _, err := os.Stat(k.Path); os.IsNotExist(err) {
		var prompt = true
		if k.Passphrase != "" {
			prompt = false
		}
		log.Printf("Creating keychain %s (prompt %#v)", k.Path, prompt)
		kref, err = createKeychain(k.Path, prompt, k.Passphrase)
		if err != nil {
			return err
		}
		defer C.CFRelease(C.CFTypeRef(kref))
	} else {
		kref, err = openKeychain(k.Path)
		if err != nil {
			return err
		}
		defer C.CFRelease(C.CFTypeRef(kref))
	}

	var serviceRef C.CFStringRef
	if serviceRef, err = _UTF8StringToCFString(k.Service); err != nil {
		return err
	}
	defer C.CFRelease(C.CFTypeRef(serviceRef))

	var accountRef C.CFStringRef
	if accountRef, err = _UTF8StringToCFString(item.Key); err != nil {
		return err
	}
	defer C.CFRelease(C.CFTypeRef(accountRef))

	var descr C.CFStringRef
	if descr, err = _UTF8StringToCFString(item.Description); err != nil {
		return err
	}
	defer C.CFRelease(C.CFTypeRef(descr))

	if item.Label == "" {
		item.Label = fmt.Sprintf("%s (%s)", k.Service, item.Key)
	}

	var label C.CFStringRef
	if label, err = _UTF8StringToCFString(item.Label); err != nil {
		return err
	}
	defer C.CFRelease(C.CFTypeRef(label))

	dataBytes := bytesToCFData(item.Data)
	defer C.CFRelease(C.CFTypeRef(dataBytes))

	query := map[C.CFTypeRef]C.CFTypeRef{
		C.CFTypeRef(C.kSecClass):           C.CFTypeRef(C.kSecClassGenericPassword),
		C.CFTypeRef(C.kSecAttrService):     C.CFTypeRef(serviceRef),
		C.CFTypeRef(C.kSecAttrAccount):     C.CFTypeRef(accountRef),
		C.CFTypeRef(C.kSecValueData):       C.CFTypeRef(dataBytes),
		C.CFTypeRef(C.kSecAttrDescription): C.CFTypeRef(descr),
		C.CFTypeRef(C.kSecAttrLabel):       C.CFTypeRef(label),
		C.CFTypeRef(C.kSecUseKeychain):     C.CFTypeRef(kref),
	}

	if !item.TrustSelf {
		access, err := createEmptyAccess(fmt.Sprintf("%s (%s)", k.Service, item.Key))
		if err != nil {
			return err
		}
		defer C.CFRelease(C.CFTypeRef(access))
		query[C.CFTypeRef(C.kSecAttrAccess)] = C.CFTypeRef(access)
	}

	queryDict := mapToCFDictionary(query)
	defer C.CFRelease(C.CFTypeRef(queryDict))

	log.Printf("Adding service=%q, account=%q to osx keychain %s", k.Service, item.Key, k.Path)
	err = newKeychainError(C.SecItemAdd(queryDict, nil))

	if err == errDuplicateItem {
		if err = k.Remove(item.Key); err != nil {
			return err
		}
		err = newKeychainError(C.SecItemAdd(queryDict, nil))
	}

	return err
}