void SoundCloudCAPI_DefaultAuthenticationLoad(SoundCloudCAPI *c) { const char *service,*name; OSStatus status; CFStringRef bundleName; void*data; UInt32 datalen; service=c->apiBaseURL; bundleName=CFBundleGetIdentifier(CFBundleGetMainBundle()); name=CFStringGetCStringPtr(bundleName,kCFStringEncodingMacRoman); status=SecKeychainFindGenericPassword(NULL,strlen(name),name,strlen(service),service,&datalen,&data,NULL); if (!status) { char *buffer=(char*)malloc(datalen+1); memcpy(buffer,data,datalen); buffer[datalen]=0; SoundCloudCAPI_SetCredentials(c,buffer); free(buffer); SecKeychainItemFreeContent(NULL,data); } }
void CertificateAttributeCoder::decode(TokenContext *tokenContext, const MetaAttribute &metaAttribute, Record &record) { // Get the SecCertificateAdornment off record using a pointer to ourself as // the key SecCertificateAdornment &sca = record.adornment<SecCertificateAdornment>(this, tokenContext, metaAttribute, record); // Get the keychain item for the certificate from the record's adornment. SecKeychainItemRef certificate = sca.certificateItem(); // Read the attribute with the requested attributeId from the item. SecKeychainAttribute ska = { metaAttribute.attributeId() }; SecKeychainAttributeList skal = { 1, &ska }; OSStatus status = SecKeychainItemCopyContent(certificate, NULL, &skal, NULL, NULL); if (status) MacOSError::throwMe(status); // Add the retrieved attribute as an attribute to the record. record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute(ska.data, ska.length)); // Free the retrieved attribute. status = SecKeychainItemFreeContent(&skal, NULL); if (status) MacOSError::throwMe(status); // @@@ The code above only returns one email address. Fix this. }
OSStatus WBKeychainFindGenericPassword(CFTypeRef keychain, CFStringRef service, CFStringRef account, CFStringRef *password, SecKeychainItemRef *itemRef) { OSStatus status; if (password) *password = NULL; char *serviceStr = (char *)__WBCFStringCopyUTF8Characters(service); char *accountStr = (char *)__WBCFStringCopyUTF8Characters(account); require_action_string(serviceStr != NULL && accountStr != NULL, bail, status = paramErr, "Unable to get service or account characters"); UInt32 length; UTF8Char *passwordStr; status = SecKeychainFindGenericPassword(keychain, (UInt32)strlen(serviceStr), serviceStr, (UInt32)strlen(accountStr), accountStr, password ? &length : NULL, password ? (void **)&passwordStr : NULL, itemRef); if ((noErr == status) && password) { *password = CFStringCreateWithBytes(kCFAllocatorDefault, passwordStr, length, kCFStringEncodingUTF8, FALSE); SecKeychainItemFreeContent(NULL, passwordStr); } bail: if (serviceStr) free(serviceStr); if (accountStr) free(accountStr); return status; }
/* Implementation of OSXKeychain.findGenericPassword(). See the Java docs for * explanations of the parameters. */ JNIEXPORT jstring JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1findGenericPassword(JNIEnv* env, jobject obj, jstring serviceName, jstring accountName) { OSStatus status; jstring_unpacked service_name; jstring_unpacked account_name; jstring result = NULL; /* Buffer for the return from SecKeychainFindGenericPassword. */ void* password; UInt32 password_length; /* Query the keychain. */ status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainUser); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); return NULL; } /* Unpack the params. */ jstring_unpack(env, serviceName, &service_name); jstring_unpack(env, accountName, &account_name); if (service_name.str == NULL || account_name.str == NULL) { jstring_unpacked_free(env, serviceName, &service_name); jstring_unpacked_free(env, accountName, &account_name); return NULL; } status = SecKeychainFindGenericPassword( NULL, service_name.len, service_name.str, account_name.len, account_name.str, &password_length, &password, NULL ); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); } else { // the returned value from keychain is not // null terminated, so a copy is created. char *password_buffer = malloc(password_length+1); memcpy(password_buffer, password, password_length); password_buffer[password_length] = 0; /* Create the return value. */ result = (*env)->NewStringUTF(env, password_buffer); /* Clean up. */ bzero(password_buffer, password_length); free(password_buffer); SecKeychainItemFreeContent(NULL, password); } jstring_unpacked_free(env, serviceName, &service_name); jstring_unpacked_free(env, accountName, &account_name); return result; }
/***************************************************************************** ** pfMacPasswordStore ** *****************************************************************************/ const plString pfMacPasswordStore::GetPassword(const plString& username) { plString service = GetServerDisplayName(); void* passwd = nullptr; uint32_t passwd_len = 0; if (SecKeychainFindGenericPassword(nullptr, service.GetSize(), service.c_str(), username.GetSize(), username.c_str(), &passwd_len, &passwd, nullptr) != errSecSuccess) { return plString::Null; } plString ret(reinterpret_cast<const char*>(passwd), size_t(passwd_len)); SecKeychainItemFreeContent(nullptr, passwd); return ret; }
void SG_password__get( SG_context *pCtx, const char *szRepoSpec, const char *username, SG_string **pPassword) { SG_byte *pwdata = NULL; SG_uint32 pwlen; SG_string *password = NULL; SG_string *path = NULL; SG_string *server = NULL; SecProtocolType proto; SG_uint32 port; SG_bool isValid = SG_FALSE; OSStatus findRes; SG_NULLARGCHECK_RETURN(pPassword); *pPassword = NULL; SG_NULLARGCHECK(username); SG_NULLARGCHECK(szRepoSpec); SG_ERR_CHECK( _sg_password__parse_url(pCtx, szRepoSpec, &isValid, &proto, &server, &path, &port) ); if (! isValid) SG_ERR_THROW(SG_ERR_NOTIMPLEMENTED); findRes = SecKeychainFindInternetPassword( NULL, SG_STRLEN( SG_string__sz(server) ), SG_string__sz(server), 0, NULL, SG_STRLEN(username), username, SG_STRLEN( SG_string__sz(path) ), SG_string__sz(path), port, proto, kSecAuthenticationTypeDefault, (UInt32 *)&pwlen, (void **)&pwdata, NULL); if (findRes == errSecItemNotFound || findRes == errSecInteractionNotAllowed) goto fail; else if (findRes != errSecSuccess) _SG_THROW_MAC_SEC_ERROR(findRes); SG_ERR_CHECK( SG_STRING__ALLOC__BUF_LEN(pCtx, &password, pwdata, pwlen) ); *pPassword = password; password = NULL; fail: if (pwdata) SecKeychainItemFreeContent(NULL, pwdata); SG_STRING_NULLFREE(pCtx, path); SG_STRING_NULLFREE(pCtx, server); SG_STRING_NULLFREE(pCtx, password); }
static int do_keychain_delete_internet_password(CFTypeRef keychainOrArray, FourCharCode itemCreator, FourCharCode itemType, const char *kind, const char *comment, const char *label, const char *serverName, const char *securityDomain, const char *accountName, const char *path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType) { OSStatus result = noErr; SecKeychainItemRef itemRef = NULL; void *passwordData = NULL; itemRef = find_first_internet_password(keychainOrArray, itemCreator, itemType, kind, comment, label, serverName, securityDomain, accountName, path, port, protocol, authenticationType); if (!itemRef) { result = errSecItemNotFound; sec_perror("SecKeychainSearchCopyNext", result); goto cleanup; } print_keychain_item_attributes(stdout, itemRef, FALSE, FALSE, FALSE, FALSE); result = SecKeychainItemDelete(itemRef); fputs("password has been deleted.\n", stderr); cleanup: if (passwordData) SecKeychainItemFreeContent(NULL, passwordData); if (itemRef) CFRelease(itemRef); return result; }
static void find_username_in_item(SecKeychainItemRef item) { SecKeychainAttributeList list; SecKeychainAttribute attr; list.count = 1; list.attr = &attr; attr.tag = kSecAccountItemAttr; if (SecKeychainItemCopyContent(item, NULL, &list, NULL, NULL)) return; write_item("username", attr.data, attr.length); SecKeychainItemFreeContent(&list, NULL); }
static void find_internet_password(void) { void *buf; UInt32 len; SecKeychainItemRef item; if (SecKeychainFindInternetPassword(KEYCHAIN_ARGS, &len, &buf, &item)) return; write_item("password", buf, len); if (!username) find_username_in_item(item); SecKeychainItemFreeContent(NULL, buf); }
static int do_keychain_delete_generic_password(CFTypeRef keychainOrArray, FourCharCode itemCreator, FourCharCode itemType, const char *kind, const char *value, const char *comment, const char *label, const char *serviceName, const char *accountName) { OSStatus result = noErr; SecKeychainItemRef itemRef = NULL; void *passwordData = NULL; itemRef = find_first_generic_password(keychainOrArray, itemCreator, itemType, kind, value, comment, label, serviceName, accountName); if (!itemRef) { result = errSecItemNotFound; sec_perror("SecKeychainSearchCopyNext", result); goto cleanup; } print_keychain_item_attributes(stdout, itemRef, FALSE, FALSE, FALSE, FALSE); result = SecKeychainItemDelete(itemRef); fputs("password has been deleted.\n", stderr); cleanup: if (passwordData) SecKeychainItemFreeContent(NULL, passwordData); if (itemRef) CFRelease(itemRef); return result; }
static SecKeychainItemRef get_password_details(const char *server, const char *username, const char **password, int reportErrors) { if (!strlen(server) || !strlen(username)) return NULL; void *passwordBuf = NULL; UInt32 passwordLength; SecKeychainItemRef keychainItem; OSStatus status = SecKeychainFindGenericPassword ( NULL, //CFTypeRef keychainOrArray, strlen(server), //UInt32 serviceNameLength, server, //const char *serviceName, strlen(username), //UInt32 accountNameLength, username, //const char *accountName, &passwordLength, //UInt32 *passwordLength, &passwordBuf, //void **passwordData, &keychainItem //SecKeychainItemRef *itemRef ); if (status == noErr) { if (password) { char *formattedPassword = malloc(passwordLength + 1); memcpy(formattedPassword, passwordBuf, passwordLength); *(formattedPassword + passwordLength) = '\0'; *password = formattedPassword; } SecKeychainItemFreeContent(NULL, passwordBuf); return keychainItem; } else if (reportErrors) { // look up at: // file://localhost/Developer/ADC%20Reference%20Library/documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898-CH5g-95690 STANDARD_KC_ERR(status); } return NULL; }
bool OsxWallet::getCredentials(const QString &realm, QString &user, QString &password) { const QByteArray realm_data = realm.toUtf8(); const QByteArray user_data = user.toUtf8(); SecKeychainItemRef itemRef = NULL; /* get password */ int rc = SecKeychainFindInternetPassword(keychain, realm_data.size(), realm_data.constData(), 0, NULL, user_data.size(), user_data.constData(), 0, NULL, 0, kSecProtocolTypeAny, kSecAuthenticationTypeAny, 0, NULL, &itemRef); if (rc != errSecSuccess) return false; /* get username */ SecKeychainAttribute attr; SecKeychainAttributeList attrList; attr.tag = kSecAccountItemAttr; attr.length = 0; attr.data = NULL; attrList.count = 1; attrList.attr = &attr; UInt32 password_length = 0; void *password_data = NULL; if (SecKeychainItemCopyContent(itemRef, NULL, &attrList, &password_length, &password_data) != errSecSuccess) { CFRelease(itemRef); return false; } /* store results */ user = QString::fromUtf8(QByteArray((char*)attr.data, attr.length)); password = QString::fromUtf8(QByteArray((char*)password_data, password_length)); SecKeychainItemFreeContent(&attrList, password_data); CFRelease(itemRef); return true; }
static void get_password_from_keychain(Pop3 pc, const char *username, const char *servername, /*@out@ */ char *password, /*@out@ */ unsigned char *password_len) { SecKeychainRef kc; OSStatus rc; char *secpwd; UInt32 pwdlen; rc = SecKeychainCopyDefault(&kc); if (rc != noErr) { DM(pc, DEBUG_ERROR, "passmgr: unable to open keychain, exiting\n"); exit(EXIT_FAILURE); } rc = SecKeychainFindInternetPassword(kc, strlen(servername), servername, 0, NULL, strlen(username), username, 0, NULL, 0, NULL, kSecAuthenticationTypeDefault, &pwdlen, (void **) &secpwd, NULL); if (rc != noErr) { DM(pc, DEBUG_ERROR, "passmgr: keychain password grab for %s at %s failed, exiting\n", username, servername); DM(pc, DEBUG_ERROR, "passmgr: (perhaps you pressed 'deny')\n"); /* this seems like the sanest thing to do, for now */ exit(EXIT_FAILURE); } if (pwdlen < *password_len) { strncpy(password, secpwd, pwdlen); password[pwdlen] = '\0'; *password_len = pwdlen; } else { DM(pc, DEBUG_ERROR, "passmgr: warning: your password appears longer (%lu) than expected (%d)\n", strlen(secpwd), *password_len - 1); } rc = SecKeychainItemFreeContent(NULL, secpwd); return; }
char *keychain_find(char *service, char *account, unsigned int *length, char **password) { if (length == NULL || password == NULL) { return strdup("length == NULL || password == NULL"); } SecKeychainItemRef item; char *tmp; OSStatus status = SecKeychainFindGenericPassword( NULL, strlen(service), service, strlen(account), account, length, (void **)&tmp, NULL ); if (status) { *length = 0; return get_error(status); } *password = strdup(tmp); SecKeychainItemFreeContent(NULL, tmp); return NULL; }
OSStatus WBKeychainFindInternetPassword(CFTypeRef keychain, CFStringRef server, CFStringRef domain, CFStringRef account, CFStringRef path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, CFStringRef *password, SecKeychainItemRef *itemRef) { OSStatus status; if (password) *password = NULL; /* Get server and account characters */ char *pathStr = NULL; char *domainStr = NULL; char *serverStr = (char *)__WBCFStringCopyUTF8Characters(server); char *accountStr = (char *)__WBCFStringCopyUTF8Characters(account); require_action_string(serverStr != NULL && accountStr != NULL, bail, status = paramErr, "Unable to get service or account characters"); /* Get optionals parameters characters */ pathStr = path ? (char *)__WBCFStringCopyUTF8Characters(path) : NULL; domainStr = domain ? (char *)__WBCFStringCopyUTF8Characters(domain) : NULL; UInt32 length; UTF8Char *passwordStr; status = SecKeychainFindInternetPassword(keychain, (UInt32)strlen(serverStr), serverStr, domainStr ? (UInt32)strlen(domainStr) : 0, domainStr ? : NULL, (UInt32)strlen(accountStr), accountStr, pathStr ? (UInt32)strlen(pathStr) : 0, pathStr ? : NULL, port, protocol, authenticationType, password ? &length : NULL, password ? (void **)&passwordStr : NULL, itemRef); if ((noErr == status) && password) { *password = CFStringCreateWithBytes(kCFAllocatorDefault, passwordStr, length, kCFStringEncodingUTF8, FALSE); SecKeychainItemFreeContent(NULL, passwordStr); } bail: if (serverStr) free(serverStr); if (accountStr) free(accountStr); if (pathStr) free(pathStr); if (domainStr) free(domainStr); return status; }
static void checkContent(SecKeychainItemRef itemRef) { SecItemClass itemClass; SecKeychainAttribute attrs[] = { { kSecLabelItemAttr, 0, NULL }, { kSecAccountItemAttr, 0, NULL }, { kSecServiceItemAttr, 0, NULL } }; SecKeychainAttributeList attrList = { sizeof(attrs) / sizeof(*attrs), attrs }; UInt32 length; void *data; #if 1 ok_status(SecKeychainItemCopyContent(itemRef, &itemClass, &attrList, &length, &data), "get item data in callback"); SKIP: { skip("length mismatch", 1, is(length, sizeof(password), "<rdar://problem/3867900> " "SecKeychainItemCopyContent() returns bad data on items " "from notifications")); ok(!memcmp(password, data, length), "password data matches."); } #else if (length != sizeof(password) || memcmp(password, data, length)) { fprintf(stderr, "password '%.*s' not same as '%.*s'\n", (int)sizeof(password), password, (int)length, (char *)data); } #endif ok_status(SecKeychainItemFreeContent(&attrList, data), "free item data in callback"); }
static OSStatus do_password_item_printing( SecKeychainItemRef itemRef, Boolean get_password, Boolean password_stdout) { OSStatus result = noErr; void *passwordData = NULL; UInt32 passwordLength = 0; if(get_password) { result = SecKeychainItemCopyContent(itemRef, NULL, NULL, &passwordLength, &passwordData); if(result != noErr) return result; } if(!password_stdout) { print_keychain_item_attributes(stdout, itemRef, FALSE, FALSE, FALSE, FALSE); if(get_password) { fputs("password: "******"%02x", password[i]); } else { for(int i=0; i<passwordLength; i++) putchar(password[i]); } putchar('\n'); } if (passwordData) SecKeychainItemFreeContent(NULL, passwordData); return noErr; }
/* Implementation of svn_auth__password_get_t that retrieves the password from the OS X KeyChain. */ static svn_error_t * keychain_password_get(svn_boolean_t *done, const char **password, apr_hash_t *creds, const char *realmstring, const char *username, apr_hash_t *parameters, svn_boolean_t non_interactive, apr_pool_t *pool) { OSStatus status; UInt32 length; void *data; *done = FALSE; if (non_interactive) SecKeychainSetUserInteractionAllowed(FALSE); status = SecKeychainFindGenericPassword(NULL, (int) strlen(realmstring), realmstring, username == NULL ? 0 : (int) strlen(username), username, &length, &data, NULL); if (non_interactive) SecKeychainSetUserInteractionAllowed(TRUE); if (status != 0) return SVN_NO_ERROR; *password = apr_pstrmemdup(pool, data, length); SecKeychainItemFreeContent(NULL, data); *done = TRUE; return SVN_NO_ERROR; }
static krb5_error_code get_new_tickets(krb5_context context, krb5_principal principal, krb5_ccache ccache, krb5_deltat ticket_life, int interactive) { krb5_error_code ret; krb5_get_init_creds_opt *opt; krb5_creds cred; char passwd[256]; krb5_deltat start_time = 0; krb5_deltat renew = 0; const char *renewstr = NULL; krb5_enctype *enctype = NULL; krb5_ccache tempccache; krb5_init_creds_context icc; krb5_keytab kt = NULL; int will_use_keytab = (use_keytab || keytab_str); krb5_prompter_fct prompter = NULL; int need_prompt; passwd[0] = '\0'; if (password_file) { FILE *f; if (strcasecmp("STDIN", password_file) == 0) f = stdin; else f = fopen(password_file, "r"); if (f == NULL) krb5_errx(context, 1, "Failed to open the password file %s", password_file); if (fgets(passwd, sizeof(passwd), f) == NULL) krb5_errx(context, 1, N_("Failed to read password from file %s", ""), password_file); if (f != stdin) fclose(f); passwd[strcspn(passwd, "\n")] = '\0'; } #if defined(__APPLE__) && !defined(__APPLE_TARGET_EMBEDDED__) if (passwd[0] == '\0' && !will_use_keytab && home_directory_flag) { const char *realm; OSStatus osret; UInt32 length; void *buffer; char *name; realm = krb5_principal_get_realm(context, principal); ret = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name); if (ret) goto nopassword; osret = SecKeychainFindGenericPassword(NULL, (UInt32)strlen(realm), realm, (UInt32)strlen(name), name, &length, &buffer, &passwordItem); free(name); if (osret != noErr) goto nopassword; if (length < sizeof(passwd) - 1) { memcpy(passwd, buffer, length); passwd[length] = '\0'; } SecKeychainItemFreeContent(NULL, buffer); nopassword: do { } while(0); } #endif need_prompt = !(pk_user_id || ent_user_id || anonymous_flag || will_use_keytab || passwd[0] != '\0') && interactive; if (need_prompt) prompter = krb5_prompter_posix; else prompter = krb5_prompter_print_only; memset(&cred, 0, sizeof(cred)); ret = krb5_get_init_creds_opt_alloc (context, &opt); if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); krb5_get_init_creds_opt_set_default_flags(context, "kinit", krb5_principal_get_realm(context, principal), opt); if(forwardable_flag != -1) krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag); if(proxiable_flag != -1) krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag); if(anonymous_flag) krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag); if (pac_flag != -1) krb5_get_init_creds_opt_set_pac_request(context, opt, pac_flag ? TRUE : FALSE); if (canonicalize_flag) krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE); if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag) krb5_get_init_creds_opt_set_win2k(context, opt, TRUE); if (pk_user_id || ent_user_id || anonymous_flag) { ret = krb5_get_init_creds_opt_set_pkinit(context, opt, principal, pk_user_id, pk_x509_anchors, NULL, NULL, pk_use_enckey ? 2 : 0 | anonymous_flag ? 4 : 0, interactive ? krb5_prompter_posix : krb5_prompter_print_only, NULL, passwd); if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_set_pkinit"); if (ent_user_id) krb5_get_init_creds_opt_set_pkinit_user_cert(context, opt, ent_user_id); } if (addrs_flag != -1) krb5_get_init_creds_opt_set_addressless(context, opt, addrs_flag ? FALSE : TRUE); if (renew_life == NULL && renewable_flag) renewstr = "1 month"; if (renew_life) renewstr = renew_life; if (renewstr) { renew = parse_time (renewstr, "s"); if (renew < 0) errx (1, "unparsable time: %s", renewstr); krb5_get_init_creds_opt_set_renew_life (opt, renew); } if(ticket_life != 0) krb5_get_init_creds_opt_set_tkt_life (opt, ticket_life); if(start_str) { int tmp = parse_time (start_str, "s"); if (tmp < 0) errx (1, N_("unparsable time: %s", ""), start_str); start_time = tmp; } if(etype_str.num_strings) { int i; enctype = malloc(etype_str.num_strings * sizeof(*enctype)); if(enctype == NULL) errx(1, "out of memory"); for(i = 0; i < etype_str.num_strings; i++) { ret = krb5_string_to_enctype(context, etype_str.strings[i], &enctype[i]); if(ret) krb5_err(context, 1, ret, "unrecognized enctype: %s", etype_str.strings[i]); } krb5_get_init_creds_opt_set_etype_list(opt, enctype, etype_str.num_strings); } ret = krb5_init_creds_init(context, principal, prompter, NULL, start_time, opt, &icc); if (ret) krb5_err (context, 1, ret, "krb5_init_creds_init"); if (server_str) { ret = krb5_init_creds_set_service(context, icc, server_str); if (ret) krb5_err (context, 1, ret, "krb5_init_creds_set_service"); } if (kdc_hostname) krb5_init_creds_set_kdc_hostname(context, icc, kdc_hostname); if (fast_armor_cache_string) { krb5_ccache fastid; ret = krb5_cc_resolve(context, fast_armor_cache_string, &fastid); if (ret) krb5_err(context, 1, ret, "krb5_cc_resolve(FAST cache)"); ret = krb5_init_creds_set_fast_ccache(context, icc, fastid); if (ret) krb5_err(context, 1, ret, "krb5_init_creds_set_fast_ccache"); } if(will_use_keytab) { if(keytab_str) ret = krb5_kt_resolve(context, keytab_str, &kt); else ret = krb5_kt_default(context, &kt); if (ret) krb5_err (context, 1, ret, "resolving keytab"); ret = krb5_init_creds_set_keytab(context, icc, kt); if (ret) krb5_err (context, 1, ret, "krb5_init_creds_set_keytab"); } if (passwd[0] == '\0' && need_prompt) { char *p, *prompt; krb5_unparse_name(context, principal, &p); asprintf (&prompt, N_("%s's Password: "******""), p); free(p); if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){ memset(passwd, 0, sizeof(passwd)); errx(1, "failed to read password"); } free (prompt); } if (passwd[0]) { ret = krb5_init_creds_set_password(context, icc, passwd); if (ret) krb5_err(context, 1, ret, "krb5_init_creds_set_password"); } ret = krb5_init_creds_get(context, icc); #ifdef __APPLE__ /* * Save password in Keychain */ if (ret == 0 && keychain_flag && passwordItem == NULL) { krb5_error_code ret2; const char *realm; char *name; realm = krb5_principal_get_realm(context, principal); ret2 = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name); if (ret2 == 0) { (void)SecKeychainAddGenericPassword(NULL, (UInt32)strlen(realm), realm, (UInt32)strlen(name), name, (UInt32)strlen(passwd), passwd, NULL); free(name); } } #endif memset(passwd, 0, sizeof(passwd)); switch(ret){ case 0: break; case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */ exit(1); case KRB5KRB_AP_ERR_BAD_INTEGRITY: case KRB5KRB_AP_ERR_MODIFIED: case KRB5KDC_ERR_PREAUTH_FAILED: case KRB5_GET_IN_TKT_LOOP: #ifdef __APPLE__ if (passwordItem) SecKeychainItemDelete(passwordItem); #endif krb5_errx(context, 1, N_("Password incorrect", "")); case KRB5KRB_AP_ERR_V4_REPLY: krb5_errx(context, 1, N_("Looks like a Kerberos 4 reply", "")); case KRB5KDC_ERR_KEY_EXPIRED: krb5_errx(context, 1, N_("Password expired", "")); default: krb5_err(context, 1, ret, "krb5_get_init_creds"); } ret = krb5_init_creds_get_creds(context, icc, &cred); if (ret) krb5_err(context, 1, ret, "krb5_init_creds_get_creds"); krb5_process_last_request(context, opt, icc); ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache), NULL, &tempccache); if (ret) krb5_err (context, 1, ret, "krb5_cc_new_unique"); ret = krb5_init_creds_store(context, icc, tempccache); if (ret) krb5_err(context, 1, ret, "krb5_init_creds_store"); ret = krb5_init_creds_store_config(context, icc, tempccache); if (ret) krb5_warn(context, ret, "krb5_init_creds_store_config"); ret = krb5_init_creds_warn_user(context, icc); if (ret) krb5_warn(context, ret, "krb5_init_creds_warn_user"); #ifdef __APPLE__ /* * Set for this case, default to * so that all processes can use * this cache. */ { heim_array_t bundleacl = heim_array_create(); heim_string_t ace; if (bundle_acl_strings.num_strings > 0) { int i; for (i = 0; i < bundle_acl_strings.num_strings; i++) { ace = heim_string_create(bundle_acl_strings.strings[i]); heim_array_append_value(bundleacl, ace); heim_release(ace); } } else { ace = heim_string_create("*"); heim_array_append_value(bundleacl, ace); heim_release(ace); } krb5_cc_set_acl(context, tempccache, "kHEIMAttrBundleIdentifierACL", bundleacl); heim_release(bundleacl); } #endif ret = krb5_cc_move(context, tempccache, ccache); if (ret) { (void)krb5_cc_destroy(context, tempccache); krb5_err (context, 1, ret, "krb5_cc_move"); } if (switch_cache_flags) krb5_cc_switch(context, ccache); if (ok_as_delegate_flag || windows_flag || use_referrals_flag) { unsigned char d = 0; krb5_data data; if (ok_as_delegate_flag || windows_flag) d |= 1; if (use_referrals_flag || windows_flag) d |= 2; data.length = 1; data.data = &d; krb5_cc_set_config(context, ccache, NULL, "realm-config", &data); } if (enctype) free(enctype); krb5_init_creds_free(context, icc); krb5_get_init_creds_opt_free(context, opt); if (kt) krb5_kt_close(context, kt); #ifdef __APPLE__ if (passwordItem) CFRelease(passwordItem); #endif return 0; }
gboolean gnc_keyring_get_password ( GtkWidget *parent, const gchar *access_method, const gchar *server, guint32 port, const gchar *service, gchar **user, gchar **password) { gboolean password_found = FALSE; #ifdef HAVE_GNOME_KEYRING GnomeKeyringResult gkr_result; GList *found_list = NULL; GnomeKeyringNetworkPasswordData *found; #endif #ifdef HAVE_OSX_KEYCHAIN void *password_data; UInt32 password_length; OSStatus status; #endif g_return_val_if_fail (user != NULL, FALSE); g_return_val_if_fail (password != NULL, FALSE); *password = NULL; #ifdef HAVE_GNOME_KEYRING gkr_result = gnome_keyring_find_network_password_sync ( *user, NULL, server, service, access_method, NULL, port, &found_list ); if (gkr_result == GNOME_KEYRING_RESULT_OK) { found = (GnomeKeyringNetworkPasswordData *) found_list->data; if (found->password) *password = g_strdup(found->password); password_found = TRUE; } else PWARN ("Gnome-keyring access failed: %s.", gnome_keyring_result_to_message(gkr_result)); gnome_keyring_network_password_list_free(found_list); #endif /* HAVE_GNOME_KEYRING */ #ifdef HAVE_OSX_KEYCHAIN /* mysql and postgres aren't valid protocols on Mac OS X. * So we use the security domain parameter to allow us to * distinguish between these two. */ if (*user != NULL) { status = SecKeychainFindInternetPassword( NULL, strlen(server), server, strlen(access_method), access_method, strlen(*user), *user, strlen(service), service, port, kSecProtocolTypeAny, kSecAuthenticationTypeDefault, &password_length, &password_data, NULL); if ( status == noErr ) { *password = g_strndup(password_data, password_length); password_found = TRUE; SecKeychainItemFreeContent(NULL, password_data); } else { CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL ); const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring, GetApplicationTextEncoding()); PWARN ( "OS X keychain error: %s", resultstring ); CFRelease ( osx_resultstring ); } } #endif /* HAVE_OSX_KEYCHAIN */ if ( !password_found ) { /* If we got here, either no proper password store is * available on this system, or we couldn't retrieve * a password from it. In both cases, just ask the user * to enter one */ gchar *db_path, *heading; if ( port == 0 ) db_path = g_strdup_printf ( "%s://%s/%s", access_method, server, service ); else db_path = g_strdup_printf ( "%s://%s:%d/%s", access_method, server, port, service ); heading = g_strdup_printf ( /* Translators: %s is a path to a database or any other url, like mysql://[email protected]/somedb, http://www.somequotes.com/thequotes */ _("Enter a user name and password to connect to: %s"), db_path ); password_found = gnc_get_username_password ( parent, heading, *user, NULL, user, password ); g_free ( db_path ); g_free ( heading ); if ( password_found ) { /* User entered new user/password information * Let's try to add it to a password store. */ gchar *newuser = g_strdup( *user ); gchar *newpassword = g_strdup( *password ); gnc_keyring_set_password ( access_method, server, port, service, newuser, newpassword ); g_free ( newuser ); g_free ( newpassword ); } } return password_found; }
void tests(void) { SecKeychainRef keychain = NULL; ok_status(SecKeychainCreate("test", 4, "test", FALSE, NULL, &keychain), "create keychain"); ok_status(test_sec_event_register(kSecEveryEventMask), "register for all events"); int item_num; int item_count = 9; for (item_num = 0; item_num < item_count; ++item_num) { char account[64]; sprintf(account, "account-%d", item_num); ok_status(SecKeychainAddGenericPassword(keychain, 7, "service", strlen(account), account, 4, "test", NULL), "add generic password"); } SecKeychainAttribute attrs[] = { { kSecAccountItemAttr } }; SecKeychainAttributeList attrList = { sizeof(attrs) / sizeof(*attrs), attrs }; for (item_num = 0; item_num < item_count - 2; ++item_num) { char account[64]; sprintf(account, "account-%d", item_num); SecKeychainItemRef item = NULL; is_sec_event(kSecAddEvent, NULL, &item, NULL, "got add event"); SKIP: { skip("no item", 3, item != NULL); ok_status(SecKeychainItemCopyContent(item, NULL, &attrList, NULL, NULL), "get content"); eq_stringn(account, strlen(account), attrs[0].data, attrs[0].length, "account name in notification matches"); ok_status(SecKeychainItemFreeContent(&attrList, NULL), "free content"); } } for (; item_num < item_count; ++item_num) { char account[64]; sprintf(account, "account-%d", item_num); SecKeychainItemRef item = NULL; is_sec_event(kSecAddEvent, NULL, &item, NULL, "got add event"); SKIP: { skip("no item", 3, item != NULL); ok_status(SecKeychainItemCopyContent(item, NULL, &attrList, NULL, NULL), "get content"); eq_stringn(account, strlen(account), attrs[0].data, attrs[0].length, "account name in notification matches"); ok_status(SecKeychainItemFreeContent(&attrList, NULL), "free content"); } } ok(tests_end(1), "cleanup"); }
QString Nicookie::chromeDecrypt(const QByteArray &encrypt_data) { QString data; #ifdef Q_OS_WIN DATA_BLOB encrypt_data_blob; encrypt_data_blob.pbData = (BYTE*)(encrypt_data.data()); encrypt_data_blob.cbData = static_cast<DWORD>(encrypt_data.size()); DATA_BLOB plain_data_blob; BOOL result = CryptUnprotectData(&encrypt_data_blob, NULL, NULL, NULL, NULL, 0, &plain_data_blob); if (!result) { setError(Nicookie::FailedDecrytError); return QString(); } data = (QByteArray((char *)(plain_data_blob.pbData), plain_data_blob.cbData)); LocalFree(plain_data_blob.pbData); #else // O_QS_WIN #ifdef Q_OS_OSX // https://developer.apple.com/library/mac/documentation/Security/Reference/keychainservices/index.html#//apple_ref/c/func/SecKeychainFindGenericPassword UInt32 password_size = 0; void *password = NULL; OSStatus os_status; os_status = SecKeychainFindGenericPassword(NULL, 19, "Chrome Safe Storage", 6, "Chrome", &password_size, &password, NULL); if (password_size == 0) { setError(Nicookie::FailedDecrytError); SecKeychainItemFreeContent(NULL, password); return data; } #else // Q_OS_OSX int password_size = 7; void *password = (void *)"peanuts"; #endif // Q_OS_OSX const int enc_key_size = 16; unsigned char enc_key[enc_key_size]; #ifdef Q_OS_OSX int iterations = 1003; #else // Q_OS_OSX int iterations = 1; #endif // Q_OS_OSX const char *salt = "saltysalt"; int pbkdf2_r = PKCS5_PBKDF2_HMAC_SHA1((char *)password, password_size, (unsigned char *)salt, strlen(salt), iterations, enc_key_size, enc_key); if (!pbkdf2_r) { setError(Nicookie::FailedDecrytError); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } const int iv_size = 16; unsigned char iv[iv_size]; for (int i = 0; i < iv_size; i++) iv[i] = ' '; // alwayes enc size >= dec size int plain_value_size = encrypt_data.size(); char *plain_value = (char *)malloc(plain_value_size); if (plain_value == NULL) { setError(Nicookie::FailedDecrytError); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } int result = 1; EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); result = EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, enc_key, iv); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } result = EVP_DecryptUpdate(&ctx, (unsigned char *)plain_value, &plain_value_size, (unsigned char *)(encrypt_data.data() + 3), encrypt_data.size() - 3); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } int fin_size = 0; result = EVP_DecryptFinal_ex(&ctx, (unsigned char *)(plain_value + plain_value_size), &fin_size); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } EVP_CIPHER_CTX_cleanup(&ctx); plain_value[plain_value_size + fin_size] = '\0'; data = plain_value; free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX #endif // O_QS_WIN return data; }
//---------------------------------------------------------------------- // dsauth_set_mppe_keys // get the mppe keys from the password server // if this fails - do nothing. there is no way to // know if the keys are actually going to be needed // at this point. //---------------------------------------------------------------------- static int dsauth_set_mppe_keys(tDirReference dirRef, tDirNodeReference userNode, u_char *remmd, tAttributeValueEntryPtr authAuthorityAttr, const unsigned char *challenge) { tDataNodePtr authKeysDataNodePtr = 0; tDataBufferPtr authDataBufPtr = 0; tDataBufferPtr responseDataBufPtr = 0; tDataBufferPtr chapDataBufPtr = NULL; tDirStatus dsResult = eDSNoErr; char *ptr, *comma, *tagStart; MS_Chap2Response *resp; char *keyaccessPassword = 0; char *keyaccessName = 0; u_int32_t keyaccessNameSize = 0; u_int32_t keyaccessPasswordSize; int len, i; u_int32_t slotIDSize = 0; const char *slotID; tContextData dir_context = 0; int status = 0; mppe_keys_set = 0; // parse authAuthorityAttribute to determine if key agent needs to be used. // auth authority tag will be between 2 semicolons. tagStart = 0; ptr = authAuthorityAttr->fAttributeValueData.fBufferData; // DSAuth_hex_print("authAuth mppe", authAuthorityAttr->fAttributeValueData.fBufferData, authAuthorityAttr->fAttributeValueData.fBufferLength); for (i = 0; i < authAuthorityAttr->fAttributeValueData.fBufferLength; i++) { if (*ptr == ';') { if (tagStart == 0) tagStart = ptr + 1; else break; } ptr++; } if (*ptr != ';') { error("DSAuth plugin: Password Server not available for MPPE key retrieval.\n"); return (status); } if (strncmp(tagStart, kDSTagAuthAuthorityPasswordServer, ptr - tagStart) == 0) { dsauth_get_admin_acct(&keyaccessNameSize, &keyaccessName, &keyaccessPasswordSize, &keyaccessPassword); if (keyaccessName == 0) { error("DSAuth plugin: Could not retrieve key agent account information.\n"); return (status); } // PWS auths expect to receive the PWS ID in the MPPE phase comma = strchr(ptr, ','); if (comma == NULL) { error("DSAuth plugin: Could not retrieve slot ID.\n"); return (status); } slotID = ptr + 1; // skip the ';' as well slotIDSize = comma - slotID; } else { error("DSAuth plugin: unsupported authen authority: recved %s, want %s\n", tagStart, kDSTagAuthAuthorityPasswordServer); return (status); // unsupported authentication authority - don't set the keys } resp = (MS_Chap2Response*)remmd; if ((responseDataBufPtr = dsDataBufferAllocate(dirRef, BUF_LEN)) == 0) { error("DSAuth plugin: Could not allocate data buffer\n"); goto cleanup; } if ((authKeysDataNodePtr = dsDataNodeAllocateString(dirRef, kDSStdAuthMPPEMasterKeys)) == 0) { error("DSAuth plugin: Could not allocate data buffer\n"); goto cleanup; } if ((authDataBufPtr = dsDataBufferAllocate(dirRef, BUF_LEN)) == 0) { error("DSAuth plugin: Could not allocate data buffer\n"); goto cleanup; } /* * phase 1 uses an MSCHAP-style auth for the VPN agent (agent account, server challenge, peer challenge, agent NT response, agent account) * phase 2 retrieves the keys (PWS ID of the user, client NT response, keysize) */ // Phase 1 chapDataBufPtr = dsauth_agent_authbuffer(dirRef, keyaccessName, keyaccessNameSize, keyaccessPassword, keyaccessPasswordSize, challenge); if (chapDataBufPtr == NULL) { error("DSAuth plugin: Could not generate agent auth buffer\n"); goto cleanup; } if ((dsResult = dsDoDirNodeAuth(userNode, authKeysDataNodePtr, TRUE, chapDataBufPtr, responseDataBufPtr, &dir_context)) != eDSNoErr) { error("DSAuth plugin: Could not authenticate key agent for encryption key retrieval, err %d\n", dsResult); goto cleanup; } // Phase 2 ptr = (char*)(authDataBufPtr->fBufferData); // DSAuth_hex_print("PWS ID", slotID, slotIDSize); // DSAuth_hex_print("NTResp", resp->NTResp, NT_RESPONSE_SIZE); // 4 byte length & slotID *((u_int32_t*)ptr) = slotIDSize; ptr += sizeof(u_int32_t); memcpy(ptr, slotID, slotIDSize); ptr += slotIDSize; // 4 byte length & client digest *((u_int32_t*)ptr) = NT_RESPONSE_SIZE; ptr += sizeof(u_int32_t); memcpy(ptr, resp->NTResp, NT_RESPONSE_SIZE); ptr += NT_RESPONSE_SIZE; // 4 byte length and master key len - always 128 *((u_int32_t*)ptr) = 1; ptr += sizeof(u_int32_t); *ptr = MPPE_MAX_KEY_LEN; authDataBufPtr->fBufferLength = slotIDSize + NT_RESPONSE_SIZE + 1 + (3 * sizeof(u_int32_t)); // get the mppe keys if ((dsResult = dsDoDirNodeAuth(userNode, authKeysDataNodePtr, TRUE, authDataBufPtr, responseDataBufPtr, &dir_context)) == eDSNoErr) { if (responseDataBufPtr->fBufferLength == (2 * sizeof(u_int32_t)) + (2 * MPPE_MAX_KEY_LEN)) { ptr = (char*)(responseDataBufPtr->fBufferData); len = *((u_int32_t*)ptr); ptr += sizeof(u_int32_t); if (len == sizeof(mppe_send_key)) memcpy(mppe_send_key, ptr, sizeof(mppe_send_key)); ptr += len; len = *((u_int32_t*)ptr); ptr += sizeof(u_int32_t); if (len == sizeof(mppe_recv_key)) memcpy(mppe_recv_key, ptr, sizeof(mppe_recv_key)); mppe_keys_set = 1; status = 1; } else error("DSAuth plugin: Invalid MPPE data for encryption keys retrieval\n"); } else error("DSAuth plugin: Failed to retrieve MPPE encryption keys from the password server: errno %d, ctxt %x\n", dsResult, dir_context); cleanup: if (dir_context != 0) { dsReleaseContinueData(dirRef, dir_context); } if (keyaccessPassword) { bzero(keyaccessPassword, keyaccessPasswordSize); // clear the admin password from memory #if !TARGET_OS_EMBEDDED // This file is not built for Embedded SecKeychainItemFreeContent(NULL, keyaccessPassword); #endif /* TARGET_OS_EMBEDDED */ } if (keyaccessName) { free(keyaccessName); } if (responseDataBufPtr) dsDataBufferDeAllocate(dirRef, responseDataBufPtr); if (chapDataBufPtr) dsDataNodeDeAllocate(dirRef, chapDataBufPtr); if (authKeysDataNodePtr) dsDataNodeDeAllocate(dirRef, authKeysDataNodePtr); if (authDataBufPtr) dsDataBufferDeAllocate(dirRef, authDataBufPtr); return (status); }
OSStatus OTMacKeychain::ItemFreeContent(SecKeychainAttributeList* attrList, void* data) const { return SecKeychainItemFreeContent(attrList, data); }
VALUE internet_password_for(VALUE self, VALUE data) { VALUE ret = Qnil; CHECK_FETCH_HASH_KEY(account) CHECK_FETCH_HASH_KEY(protocol) CHECK_FETCH_HASH_KEY(server) VALUE sym_auth = rb_eval_string(":auth"); VALUE auth; if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_auth)) { auth = 0; } else { auth = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_auth), rb_intern("to_s"), 0); auth = String2FourChar(StringValuePtr(auth)); } VALUE sym_port = rb_eval_string(":port"); VALUE port; if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_port)) { port = 0; } else { port = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_port), rb_intern("to_i"), 0); port = NUM2INT(port); } VALUE sym_path = rb_eval_string(":path"); VALUE path; if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_path)) { path = rb_str_new2(""); } else { path = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_path), rb_intern("to_s"), 0); } char *passwordData = nil; // will be allocated and filled in by SecKeychainFindGenericPassword UInt32 passwordLength = nil; OSStatus status = SecKeychainFindInternetPassword ( NULL, // default keychain strlen(StringValuePtr(server)), // length of serverName StringValuePtr(server), // serverName 0, // length of domain NULL, // no domain strlen(StringValuePtr(account)), // length of account name StringValuePtr(account), // account name strlen(StringValuePtr(path)), // length of path StringValuePtr(path), // path port, // ignore port String2FourChar(StringValuePtr(protocol)), // protocol auth, &passwordLength, &passwordData, NULL ); if (status == noErr) { ((char*)passwordData)[passwordLength] = '\0'; // Should this be necessary? ret = rb_str_new2(passwordData); SecKeychainItemFreeContent(NULL, passwordData); } else if (status == errSecItemNotFound) { ret = Qnil; } else if (status == errSecAuthFailed) { rb_raise(rb_eSecurityError, "Authorisation failed"); } else { rb_raise(rb_eStandardError, getStatusString(status)); } return ret; }
bool getCredentialsFromKeychain(const URI &uri, ClientRequest::ptr priorRequest, std::string &scheme, std::string &realm, std::string &username, std::string &password, size_t attempts) { if (attempts != 1) return false; bool proxy = priorRequest->response().status.status == PROXY_AUTHENTICATION_REQUIRED; const ChallengeList &challengeList = proxy ? priorRequest->response().response.proxyAuthenticate : priorRequest->response().response.wwwAuthenticate; if (isAcceptable(challengeList, "Basic")) scheme = "Basic"; else if (isAcceptable(challengeList, "Digest")) scheme = "Digest"; else return false; std::vector<SecKeychainAttribute> attrVector; std::string host = uri.authority.host(); attrVector.push_back((SecKeychainAttribute){kSecServerItemAttr, host.size(), (void *)host.c_str()}); UInt32 port = 0; if (uri.authority.portDefined()) { port = uri.authority.port(); attrVector.push_back((SecKeychainAttribute){kSecPortItemAttr, sizeof(UInt32), &port}); } SecProtocolType protocol; if (proxy && priorRequest->request().requestLine.method == CONNECT) protocol = kSecProtocolTypeHTTPSProxy; else if (proxy) protocol = kSecProtocolTypeHTTPProxy; else if (uri.scheme() == "https") protocol = kSecProtocolTypeHTTPS; else if (uri.scheme() == "http") protocol = kSecProtocolTypeHTTP; else MORDOR_NOTREACHED(); attrVector.push_back((SecKeychainAttribute){kSecProtocolItemAttr, sizeof(SecProtocolType), &protocol}); ScopedCFRef<SecKeychainSearchRef> search; SecKeychainAttributeList attrList; attrList.count = (UInt32)attrVector.size(); attrList.attr = &attrVector[0]; OSStatus status = SecKeychainSearchCreateFromAttributes(NULL, kSecInternetPasswordItemClass, &attrList, &search); if (status != 0) return false; ScopedCFRef<SecKeychainItemRef> item; status = SecKeychainSearchCopyNext(search, &item); if (status != 0) return false; SecKeychainAttributeInfo info; SecKeychainAttrType tag = kSecAccountItemAttr; CSSM_DB_ATTRIBUTE_FORMAT format = CSSM_DB_ATTRIBUTE_FORMAT_STRING; info.count = 1; info.tag = (UInt32 *)&tag; info.format = (UInt32 *)&format; SecKeychainAttributeList *attrs; UInt32 passwordLength = 0; void *passwordBytes = NULL; status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attrs, &passwordLength, &passwordBytes); if (status != 0) return false; try { username.assign((const char *)attrs->attr[0].data, attrs->attr[0].length); password.assign((const char *)passwordBytes, passwordLength); } catch (...) { SecKeychainItemFreeContent(attrs, passwordBytes); throw; } SecKeychainItemFreeContent(attrs, passwordBytes); return true; }
/* Implementation of OSXKeychain.findInternetPassword(). See the Java docs for * explanations of the parameters. */ JNIEXPORT jstring JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1findInternetPassword(JNIEnv* env, jobject obj, jstring serverName, jstring securityDomain, jstring accountName, jstring path, jint port) { OSStatus status; jstring_unpacked server_name; jstring_unpacked security_domain; jstring_unpacked account_name; jstring_unpacked server_path; jstring result = NULL; /* This is the password buffer which will be used by * SecKeychainFindInternetPassword */ void* password; UInt32 password_length; /* Query the keychain */ status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainUser); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); return NULL; } /* Unpack all the jstrings into useful structures. */ jstring_unpack(env, serverName, &server_name); jstring_unpack(env, securityDomain, &security_domain); jstring_unpack(env, accountName, &account_name); jstring_unpack(env, path, &server_path); if (server_name.str == NULL || security_domain.str == NULL || account_name.str == NULL || server_path.str == NULL) { jstring_unpacked_free(env, serverName, &server_name); jstring_unpacked_free(env, securityDomain, &security_domain); jstring_unpacked_free(env, accountName, &account_name); jstring_unpacked_free(env, path, &server_path); return NULL; } status = SecKeychainFindInternetPassword( NULL, server_name.len, server_name.str, security_domain.len, security_domain.str, account_name.len, account_name.str, server_path.len, server_path.str, port, kSecProtocolTypeAny, kSecAuthenticationTypeAny, &password_length, &password, NULL ); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); } else { // the returned value from keychain is not // null terminated, so a copy is created. char* password_buffer = (char *) malloc(password_length+1); memcpy(password_buffer, password, password_length); password_buffer[password_length] = 0; /* Create the return value. */ result = (*env)->NewStringUTF(env, password_buffer); /* Clean up. */ bzero(password_buffer, password_length); free(password_buffer); SecKeychainItemFreeContent(NULL, password); } jstring_unpacked_free(env, serverName, &server_name); jstring_unpacked_free(env, securityDomain, &security_domain); jstring_unpacked_free(env, accountName, &account_name); jstring_unpacked_free(env, path, &server_path); return result; }
SEXP find_password(SEXP svc, SEXP usr, SEXP new_pwd, SEXP quiet, SEXP del) { SEXP res; OSStatus status; SecKeychainRef kc = NULL; /* default */ SecKeychainItemRef kci; const char *un, *sn; char *svc_name; void *pwd; UInt32 pwd_len = 0; int l; int silent = Rf_asInteger(quiet) == 1; int do_rm = Rf_asInteger(del) == 1; int modify = 0; if (TYPEOF(svc) != STRSXP || LENGTH(svc) != 1) Rf_error("Invalid service name"); if (new_pwd != R_NilValue && (TYPEOF(new_pwd) != STRSXP || LENGTH(new_pwd) != 1)) Rf_error("Invalid password"); if (new_pwd != R_NilValue || do_rm) modify = 1; if (usr == R_NilValue) { un = getlogin(); if (!un) Rf_error("Unable to get current user name via getlogin()"); } else { if (TYPEOF(usr) != STRSXP || LENGTH(usr) != 1) Rf_error("Invalid user name (must be a character vector of length one)"); un = Rf_translateCharUTF8(STRING_ELT(usr, 0)); } sn = Rf_translateCharUTF8(STRING_ELT(svc, 0)); l = strlen(sn); if (l > sizeof(buf) - 16) { svc_name = (char*) malloc(l + 16); if (!svc_name) Rf_error("Cannot allocate memory for service name"); } else svc_name = buf; /* we are enforcing R.keychain. prefix to avoid abuse to access other system keys */ strcpy(svc_name, SEC_PREFIX); strcat(svc_name, sn); status = SecKeychainFindGenericPassword(kc, strlen(svc_name), svc_name, strlen(un), un, &pwd_len, &pwd, modify ? &kci : NULL); if (svc_name != buf) free(svc_name); if (silent && status == errSecItemNotFound) return R_NilValue; chk_status(status, "find"); res = PROTECT(Rf_ScalarString(Rf_mkCharLenCE(pwd, pwd_len, CE_UTF8))); /* FIXME: we'll leak if the above fails in R */ SecKeychainItemFreeContent(NULL, pwd); if (do_rm) { status = SecKeychainItemDelete(kci); chk_status(status, "delete"); } else if (new_pwd != R_NilValue) { /* set a new one */ const char *np = Rf_translateCharUTF8(STRING_ELT(new_pwd, 0)); status = SecKeychainItemModifyContent(kci, NULL, strlen(np), np); chk_status(status, "modify"); } UNPROTECT(1); return res; }
void tests(int dont_skip) { SecKeychainRef source, dest; ok_status(SecKeychainCreate("source", 4, "test", FALSE, NULL, &source), "create source keychain"); ok_status(SecKeychainCreate("dest", 4, "test", FALSE, NULL, &dest), "create dest keychain"); SecKeychainItemRef original = NULL; ok_status(SecKeychainAddInternetPassword(source, 19, "members.spamcop.net", 0, NULL, 5, "smith", 0, NULL, 80, kSecProtocolTypeHTTP, kSecAuthenticationTypeDefault, 4, "test", &original), "add internet password"); SecKeychainAttribute origAttrs[] = { { kSecCreationDateItemAttr }, { kSecModDateItemAttr } }; SecKeychainAttributeList origAttrList = { sizeof(origAttrs) / sizeof(*origAttrs), origAttrs }; ok_status(SecKeychainItemCopyContent(original, NULL, &origAttrList, NULL, NULL), "SecKeychainItemCopyContent"); /* Must sleep 1 second to trigger mod date bug. */ sleep(1); SecKeychainItemRef copy; ok_status(SecKeychainItemCreateCopy(original, dest, NULL, ©), "copy item"); SecKeychainAttribute copyAttrs[] = { { kSecCreationDateItemAttr }, { kSecModDateItemAttr } }; SecKeychainAttributeList copyAttrList = { sizeof(copyAttrs) / sizeof(*copyAttrs), copyAttrs }; ok_status(SecKeychainItemCopyContent(copy, NULL, ©AttrList, NULL, NULL), "SecKeychainItemCopyContent"); is(origAttrs[0].length, 16, "creation date length 16"); is(origAttrs[1].length, 16, "mod date length 16"); is(origAttrs[0].length, copyAttrs[0].length, "creation date length same"); is(origAttrs[1].length, copyAttrs[1].length, "mod date length same"); TODO: { todo("<rdar://problem/3731664> Moving/copying a keychain item " "between keychains erroneously updates dates"); diag("original creation: %.*s copy creation: %.*s", (int)origAttrs[0].length, (const char *)origAttrs[0].data, (int)copyAttrs[0].length, (const char *)copyAttrs[0].data); ok(!memcmp(origAttrs[0].data, copyAttrs[0].data, origAttrs[0].length), "creation date same"); diag("original mod: %.*s copy mod: %.*s", (int)origAttrs[1].length, (const char *)origAttrs[1].data, (int)copyAttrs[1].length, (const char *)copyAttrs[1].data); ok(!memcmp(origAttrs[1].data, copyAttrs[1].data, origAttrs[1].length), "mod date same"); } ok_status(SecKeychainItemFreeContent(&origAttrList, NULL), "SecKeychainItemCopyContent"); ok_status(SecKeychainItemFreeContent(©AttrList, NULL), "SecKeychainItemCopyContent"); is(CFGetRetainCount(original), 1, "original retaincount is 1"); CFRelease(original); is(CFGetRetainCount(copy), 1, "copy retaincount is 1"); CFRelease(copy); is(CFGetRetainCount(source), 1, "source retaincount is 1"); ok_status(SecKeychainDelete(source), "delete keychain source"); CFRelease(source); ok_status(SecKeychainDelete(dest), "delete keychain dest"); is(CFGetRetainCount(dest), 1, "dest retaincount is 1"); CFRelease(dest); ok(tests_end(1), "cleanup"); }