int main(int argc, char *const *argv) { plan_tests(6); ok(tests_begin(argc, argv), "setup"); UInt32 didGetNotification = 0; ok_status(SecKeychainAddCallback(callbackFunction, kSecAddEventMask, &didGetNotification), "add callback"); SecKeychainRef keychain; ok_status(SecKeychainCreate("test", 4, "test", FALSE, NULL, &keychain), "create keychain"); SecKeychainItemRef itemRef; ok_status(SecKeychainAddGenericPassword(keychain, sizeof(account), account, sizeof(service), service, sizeof(password), password, &itemRef), "add generic password, release and wait for callback"); //checkContent(itemRef); CFRelease(itemRef); CFRelease(keychain); if (argc > 1 && !strcmp(argv[1], "-l")) { printf("pid: %d\n", getpid()); sleep(100); } ok(tests_end(1), "cleanup"); ok_leaks("leaks"); return 0; }
OSStatus OTMacKeychain::AddSecret( SecKeychainRef keychain, uint32_t serviceNameLength, const char* serviceName, uint32_t accountNameLength, const char* accountName, uint32_t passwordLength, const void* passwordData, SecKeychainItemRef* itemRef) const { return SecKeychainAddGenericPassword( keychain, serviceNameLength, serviceName, accountNameLength, accountName, passwordLength, passwordData, itemRef); }
char *keychain_add(char *service, char *account, char *pass) { OSStatus status = SecKeychainAddGenericPassword( NULL, strlen(service), service, strlen(account), account, strlen(pass), pass, NULL ); if (status) return get_error(status); return NULL; }
bool pfMacPasswordStore::SetPassword(const plString& username, const plString& password) { plString service = GetServerDisplayName(); return SecKeychainAddGenericPassword(nullptr, service.GetSize(), service.c_str(), username.GetSize(), username.c_str(), password.GetSize(), password.c_str(), nullptr) == errSecSuccess; }
/* Implementation of svn_auth__password_set_t that stores the password in the OS X KeyChain. */ static svn_error_t * keychain_password_set(svn_boolean_t *done, apr_hash_t *creds, const char *realmstring, const char *username, const char *password, apr_hash_t *parameters, svn_boolean_t non_interactive, apr_pool_t *pool) { OSStatus status; SecKeychainItemRef item; if (non_interactive) SecKeychainSetUserInteractionAllowed(FALSE); status = SecKeychainFindGenericPassword(NULL, (int) strlen(realmstring), realmstring, username == NULL ? 0 : (int) strlen(username), username, 0, NULL, &item); if (status) { if (status == errSecItemNotFound) status = SecKeychainAddGenericPassword(NULL, (int) strlen(realmstring), realmstring, username == NULL ? 0 : (int) strlen(username), username, (int) strlen(password), password, NULL); } else { status = SecKeychainItemModifyAttributesAndData(item, NULL, (int) strlen(password), password); CFRelease(item); } if (non_interactive) SecKeychainSetUserInteractionAllowed(TRUE); *done = (status == 0); return SVN_NO_ERROR; }
void SoundCloudCAPI_DefaultAuthenticationSave(SoundCloudCAPI *api) { SecKeychainItemRef ref; const char *data=SoundCloudCAPI_GetCredentials(api); const char *service=api->apiBaseURL; CFStringRef bundleName=CFBundleGetIdentifier(CFBundleGetMainBundle()); const char *name=CFStringGetCStringPtr(bundleName,kCFStringEncodingMacRoman); OSErr status=SecKeychainFindGenericPassword(NULL,strlen(name),name,strlen(service),service,0,0,&ref); if (status) status=SecKeychainAddGenericPassword(NULL,strlen(name),name,strlen(service),service,strlen(data),data,0); else { status=SecKeychainItemModifyAttributesAndData(ref,NULL,strlen(data),data); CFRelease(ref); } if (status) sc_log(api,SoundCloudCAPI_LogLevel_Errors,"Failed to save token, with err: %d\n",status); }
int main(int argc, char **argv) { if ((argc < 3) || (argc > 4)) { printf("Usage: %s <service> <account> [<password>]\n", argv[0]); return 1; } const char *service = argv[1]; const char *login = argv[2]; const char *password = argc == 4 ? argv[3] : NULL; void *buf; UInt32 len; SecKeychainItemRef item; if (password != NULL) { if (key_exists_p(service, login, &item) == 0) { SecKeychainItemDelete(item); } OSStatus create_key = SecKeychainAddGenericPassword( NULL, strlen(service), service, strlen(login), login, strlen(password), password, &item ); if (create_key != 0) { fprintf(stderr, "Boxen Keychain Helper: Encountered error code: %d\n", create_key); return 1; } } else { OSStatus find_key = SecKeychainFindGenericPassword( NULL, strlen(service), service, strlen(login), login, &len, &buf, &item); if (find_key != 0) { fprintf(stderr, "Boxen Keychain Helper: Encountered error code: %d\n", find_key); return 1; } fwrite(buf, 1, len, stdout); } return 0; }
//Call SecKeychainAddGenericPassword to add a new password to the keychain: OSStatus WBKeychainAddGenericPassword(SecKeychainRef keychain, CFStringRef service, CFStringRef account, CFStringRef password, SecKeychainItemRef *itemRef) { OSStatus status; char *serviceStr = (char *)__WBCFStringCopyUTF8Characters(service); char *accountStr = (char *)__WBCFStringCopyUTF8Characters(account); char *passwordStr = (char *)__WBCFStringCopyUTF8Characters(password); require_action_string(serviceStr != NULL && accountStr != NULL && passwordStr != NULL, bail, status = paramErr, "Unable to get service or account characters"); status = SecKeychainAddGenericPassword(keychain, (UInt32)strlen(serviceStr), serviceStr, (UInt32)strlen(accountStr), accountStr, (UInt32)strlen(passwordStr), passwordStr, itemRef); bail: if (serviceStr) free(serviceStr); if (accountStr) free(accountStr); if (passwordStr) free(passwordStr); return status; }
SEXP store_password(SEXP svc, SEXP usr, SEXP pwd) { OSStatus status; SecKeychainRef kc = NULL; /* default */ const char *un, *sn, *pw; char *svc_name; int l; if (TYPEOF(svc) != STRSXP || LENGTH(svc) != 1) Rf_error("Invalid service name"); if (TYPEOF(pwd) != STRSXP || LENGTH(pwd) != 1) Rf_error("Invalid password"); pw = Rf_translateCharUTF8(STRING_ELT(pwd, 0)); 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 = SecKeychainAddGenericPassword(kc, strlen(svc_name), svc_name, strlen(un), un, strlen(pw), pw, NULL); if (svc_name != buf) free(svc_name); chk_status(status, "add"); return R_NilValue; }
/* Implementation of OSXKeychain.addGenericPassword(). See the Java docs for * explanations of the parameters. */ JNIEXPORT void JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1addGenericPassword(JNIEnv* env, jobject obj, jstring serviceName, jstring accountName, jstring password) { OSStatus status; jstring_unpacked service_name; jstring_unpacked account_name; jstring_unpacked service_password; /* Unpack the params */ jstring_unpack(env, serviceName, &service_name); jstring_unpack(env, accountName, &account_name); jstring_unpack(env, password, &service_password); /* check for allocation failures */ if (service_name.str == NULL || account_name.str == NULL || service_password.str == NULL) { jstring_unpacked_free(env, serviceName, &service_name); jstring_unpacked_free(env, accountName, &account_name); jstring_unpacked_free(env, password, &service_password); return; } /* Add the details to the keychain. */ status = SecKeychainAddGenericPassword( NULL, service_name.len, service_name.str, account_name.len, account_name.str, service_password.len, service_password.str, NULL ); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); } /* Clean up. */ jstring_unpacked_free(env, serviceName, &service_name); jstring_unpacked_free(env, accountName, &account_name); jstring_unpacked_free(env, password, &service_password); }
/* Creates or updates a keychain item to match new details. */ void keychain_update_password(const char *origServer, const char *origUser, const char *server, const char *username, const char *password) { if (!strlen(server) || !strlen(username)) return; void *s1 = NULL; BADGE_HOSTNAME(server); SecKeychainItemRef origItem = NULL; OSStatus status; if (strlen(origServer) && strlen(origUser)) { s1 = (void*)BADGE_HOSTNAME(origServer); origItem = get_password_details(origServer, origUser, NULL, 0); } SecKeychainItemRef newItem = get_password_details(server, username, NULL, 0); if (origItem || newItem) { // Modify the existing password SecKeychainItemRef keychainItem = (origItem) ? origItem : newItem; // use 7 instead of kSecLabelItemAttr because of a Carbon bug // details: http://lists.apple.com/archives/apple-cdsa/2006//May/msg00037.html SecKeychainAttribute attrs[] = { {kSecAccountItemAttr, strlen(username), (void*)username}, {7, strlen(server), (void*)server}, {kSecServiceItemAttr, strlen(server), (void*)server} }; SecKeychainAttributeList list = { sizeof(attrs) / sizeof(attrs[0]), attrs }; status = SecKeychainItemModifyAttributesAndData(keychainItem, &list, strlen(password), password); if (status != noErr) EXTENDED_KC_ERR(status, "editing an existing password"); } else { // Password doesn't exist, create it status = SecKeychainAddGenericPassword ( NULL, // default keychain strlen(server), // length of service name server, // service name strlen(username), // length of account name username, // account name strlen(password), // length of password password, // pointer to password data NULL // the item reference ); if (status != noErr) EXTENDED_KC_ERR(status, "saving a new password"); } free(s1); free((void*)server); }
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"); }
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; }