📄 simple_providers.c
字号:
CRYPTPROTECT_PROMPTSTRUCT*, /* pPromptStruct */ DWORD, /* dwFlags */ DATA_BLOB*); /* pDataOut */ HINSTANCE dll; FARPROC fn; encrypt_fn_t encrypt; DATA_BLOB blobin; DATA_BLOB blobout; svn_boolean_t crypted; if (!get_crypto_function("CryptProtectData", &dll, &fn)) return FALSE; encrypt = (encrypt_fn_t) fn; blobin.cbData = strlen(in); blobin.pbData = (BYTE*) in; crypted = encrypt(&blobin, description, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobout); if (crypted) { char *coded = apr_palloc(pool, apr_base64_encode_len(blobout.cbData)); apr_base64_encode(coded, blobout.pbData, blobout.cbData); crypted = simple_password_set(creds, realmstring, username, coded, non_interactive, pool); LocalFree(blobout.pbData); } FreeLibrary(dll); return crypted;}/* Implementation of password_get_t that decrypts the incoming password using the Windows CryptoAPI and verifies its validity. */static svn_boolean_twindows_password_decrypter(const char **out, apr_hash_t *creds, const char *realmstring, const char *username, svn_boolean_t non_interactive, apr_pool_t *pool){ typedef BOOL (CALLBACK * decrypt_fn_t) (DATA_BLOB *, /* pDataIn */ LPWSTR *, /* ppszDataDescr */ DATA_BLOB *, /* pOptionalEntropy */ PVOID, /* pvReserved */ CRYPTPROTECT_PROMPTSTRUCT*, /* pPromptStruct */ DWORD, /* dwFlags */ DATA_BLOB*); /* pDataOut */ HINSTANCE dll; FARPROC fn; DATA_BLOB blobin; DATA_BLOB blobout; LPWSTR descr; decrypt_fn_t decrypt; svn_boolean_t decrypted; char *in; if (!simple_password_get(&in, creds, realmstring, username, non_interactive, pool)) return FALSE; if (!get_crypto_function("CryptUnprotectData", &dll, &fn)) return FALSE; decrypt = (decrypt_fn_t) fn; blobin.cbData = strlen(in); blobin.pbData = apr_palloc(pool, apr_base64_decode_len(in)); apr_base64_decode(blobin.pbData, in); decrypted = decrypt(&blobin, &descr, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobout); if (decrypted) { if (0 == lstrcmpW(descr, description)) *out = apr_pstrndup(pool, blobout.pbData, blobout.cbData); else decrypted = FALSE; LocalFree(blobout.pbData); } FreeLibrary(dll); return decrypted;}/* Get cached encrypted credentials from the simple provider's cache. */static svn_error_t *windows_simple_first_creds(void **credentials, void **iter_baton, void *provider_baton, apr_hash_t *parameters, const char *realmstring, apr_pool_t *pool){ return simple_first_creds_helper(credentials, iter_baton, provider_baton, parameters, realmstring, windows_password_decrypter, SVN_AUTH__WINCRYPT_PASSWORD_TYPE, pool);}/* Save encrypted credentials to the simple provider's cache. */static svn_error_t *windows_simple_save_creds(svn_boolean_t *saved, void *credentials, void *provider_baton, apr_hash_t *parameters, const char *realmstring, apr_pool_t *pool){ return simple_save_creds_helper(saved, credentials, provider_baton, parameters, realmstring, windows_password_encrypter, SVN_AUTH__WINCRYPT_PASSWORD_TYPE, pool);}static const svn_auth_provider_t windows_simple_provider = { SVN_AUTH_CRED_SIMPLE, windows_simple_first_creds, NULL, windows_simple_save_creds};/* Public API */voidsvn_auth_get_windows_simple_provider(svn_auth_provider_object_t **provider, apr_pool_t *pool){ svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po)); po->vtable = &windows_simple_provider; *provider = po;}#endif /* WIN32 *//*-----------------------------------------------------------------------*//* keychain simple provider, puts passwords in the KeyChain *//*-----------------------------------------------------------------------*/#ifdef SVN_HAVE_KEYCHAIN_SERVICES#include <Security/Security.h>/* * XXX (2005-12-07): If no GUI is available (e.g. over a SSH session), * you won't be prompted for credentials with which to unlock your * keychain. Apple recognizes lack of TTY prompting as a known * problem. * * * XXX (2005-12-07): SecKeychainSetUserInteractionAllowed(FALSE) does * not appear to actually prevent all user interaction. Specifically, * if the executable changes (for example, if it is rebuilt), the * system prompts the user to okay the use of the new executable. * * Worse than that, the interactivity setting is global per app (not * process/thread), meaning that there is a race condition in the * implementation below between calls to * SecKeychainSetUserInteractionAllowed() when multiple instances of * the same Subversion auth provider-based app run concurrently. *//* Implementation of password_set_t that stores the password in the OS X KeyChain. */static svn_boolean_tkeychain_password_set(apr_hash_t *creds, const char *realmstring, const char *username, const char *password, svn_boolean_t non_interactive, apr_pool_t *pool){ OSStatus status; SecKeychainItemRef item; if (non_interactive) SecKeychainSetUserInteractionAllowed(FALSE); status = SecKeychainFindGenericPassword(NULL, strlen(realmstring), realmstring, strlen(username), username, 0, NULL, &item); if (status) { if (status == errSecItemNotFound) status = SecKeychainAddGenericPassword(NULL, strlen(realmstring), realmstring, strlen(username), username, strlen(password), password, NULL); } else { status = SecKeychainItemModifyAttributesAndData(item, NULL, strlen(password), password); CFRelease(item); } if (non_interactive) SecKeychainSetUserInteractionAllowed(TRUE); return status == 0;}/* Implementation of password_get_t that retrieves the password from the OS X KeyChain. */static svn_boolean_tkeychain_password_get(const char **password, apr_hash_t *creds, const char *realmstring, const char *username, svn_boolean_t non_interactive, apr_pool_t *pool){ OSStatus status; UInt32 length; void *data; if (non_interactive) SecKeychainSetUserInteractionAllowed(FALSE); status = SecKeychainFindGenericPassword(NULL, strlen(realmstring), realmstring, strlen(username), username, &length, &data, NULL); if (non_interactive) SecKeychainSetUserInteractionAllowed(TRUE); if (status != 0) return FALSE; *password = apr_pstrmemdup(pool, data, length); SecKeychainItemFreeContent(NULL, data); return TRUE;}/* Get cached encrypted credentials from the simple provider's cache. */static svn_error_t *keychain_simple_first_creds(void **credentials, void **iter_baton, void *provider_baton, apr_hash_t *parameters, const char *realmstring, apr_pool_t *pool){ return simple_first_creds_helper(credentials, iter_baton, provider_baton, parameters, realmstring, keychain_password_get, SVN_AUTH__KEYCHAIN_PASSWORD_TYPE, pool);}/* Save encrypted credentials to the simple provider's cache. */static svn_error_t *keychain_simple_save_creds(svn_boolean_t *saved, void *credentials, void *provider_baton, apr_hash_t *parameters, const char *realmstring, apr_pool_t *pool){ return simple_save_creds_helper(saved, credentials, provider_baton, parameters, realmstring, keychain_password_set, SVN_AUTH__KEYCHAIN_PASSWORD_TYPE, pool);}static const svn_auth_provider_t keychain_simple_provider = { SVN_AUTH_CRED_SIMPLE, keychain_simple_first_creds, NULL, keychain_simple_save_creds};/* Public API */voidsvn_auth_get_keychain_simple_provider(svn_auth_provider_object_t **provider, apr_pool_t *pool){ svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po)); po->vtable = &keychain_simple_provider; *provider = po;}#endif /* SVN_HAVE_KEYCHAIN_SERVICES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -