// 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 }
// 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 }
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 }