diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/JSAPI2_Security.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Winamp/JSAPI2_Security.cpp')
-rw-r--r-- | Src/Winamp/JSAPI2_Security.cpp | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/Src/Winamp/JSAPI2_Security.cpp b/Src/Winamp/JSAPI2_Security.cpp new file mode 100644 index 00000000..3e8706b1 --- /dev/null +++ b/Src/Winamp/JSAPI2_Security.cpp @@ -0,0 +1,255 @@ +#include "api.h" +#include "JSAPI2_Security.h" +#include "JSAPI2_svc_apicreator.h" +#include <bfc/platform/types.h> +#include "main.h" +#include "resource.h" +#include "language.h" +#include <api/service/waservicefactory.h> +#include <shlwapi.h> +#include <strsafe.h> + +JSAPI2::Security::~Security() +{ + for(NameMap::iterator iter = names.begin(); iter != names.end(); iter++) + { + if (NULL != iter->second) + free(iter->second); + } +} + +int JSAPI2::Security::GetActionAuthorization( const wchar_t *group, const wchar_t *action, const wchar_t *authorization_key, JSAPI::ifc_info *info, int default_authorization, AuthorizationData *data ) +{ + // TODO: benski> we should build a cache table, as we may hit this function repeatedly and it incurs a file lock + // but for now it will get the ball rolling + if ( action ) + { + wchar_t group_action[ 256 ] = { 0 }; + StringCbPrintfW( group_action, sizeof( group_action ), L"%s@%s", action, group ); + int authorization = GetPrivateProfileIntW( authorization_key, group_action, api_security::ACTION_UNDEFINED, JSAPI2_INIFILE ); + if ( authorization != api_security::ACTION_UNDEFINED ) + return authorization; + } + if ( group ) + { + int authorization = GetPrivateProfileIntW( authorization_key, group, api_security::ACTION_UNDEFINED, JSAPI2_INIFILE ); + if ( authorization != api_security::ACTION_UNDEFINED ) + return authorization; + } + + int authorization = GetPrivateProfileIntW( authorization_key, authorization_key, default_authorization, JSAPI2_INIFILE ); + + if ( ( ACTION_UNDEFINED == authorization || ACTION_PROMPT == authorization ) && + false != IsAuthorizationBypassed( authorization_key ) ) + { + authorization = ACTION_ALLOWED; + } + + if ( ( authorization == ACTION_UNDEFINED || authorization == ACTION_PROMPT )/* if we have to prompt */ + && default_authorization != ACTION_UNDEFINED /* clients pass ACTION_UNDEFINED, API's don't */ + && group ) + { + waServiceFactory *sf = 0; + int n = 0; + do + { + sf = WASABI_API_SVC->service_enumService( JSAPI2::svc_apicreator::getServiceType(), n++ ); + if ( !sf ) + break; + + if ( sf ) + { + JSAPI2::svc_apicreator *creator = (JSAPI2::svc_apicreator *)sf->getInterface(); + if ( creator ) + { + HWND parent = 0; + if ( info ) + parent = info->GetHWND(); + if ( !parent ) + parent = this->GetAssociation( authorization_key ); + + int prompt = creator->PromptForAuthorization( parent, group, action, authorization_key, data ); + if ( ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_MASK ) != JSAPI2::svc_apicreator::AUTHORIZATION_UNDEFINED ) + { + sf->releaseInterface( creator ); + int new_authorization = 0; + switch ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_MASK ) + { + case JSAPI2::svc_apicreator::AUTHORIZATION_ALLOW: + new_authorization = ACTION_ALLOWED; + break; + case JSAPI2::svc_apicreator::AUTHORIZATION_DENY: + new_authorization = ACTION_DISALLOWED; + break; + default: + return default_authorization; + } + if ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_FLAG_GROUP_ONLY ) + action = 0; + if ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_FLAG_ALWAYS ) + SetActionAuthorization( group, action, authorization_key, new_authorization ); + if ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_FLAG_ALWAYS_FOR_SERVICE ) + SetActionAuthorization( 0, 0, authorization_key, new_authorization ); + + return new_authorization; + } + } + + sf->releaseInterface( creator ); + } + } while ( sf ); + } + + return authorization; +} + +int JSAPI2::Security::SetActionAuthorization(const wchar_t *group, const wchar_t *action, const wchar_t *authorization_key, int authorization) +{ + // TODO: benski> we should build a cache table, as we may hit this function repeatedly and it incurs a file lock + // but for now it will get the ball rolling + wchar_t intval[64] = {0}; + _itow(authorization, intval, 10); + if (action) + { + wchar_t group_action[256] = {0}; + StringCbPrintfW(group_action, sizeof(group_action), L"%s@%s", action, group); + WritePrivateProfileStringW(authorization_key, group_action, intval, JSAPI2_INIFILE); + } + else if (group) + WritePrivateProfileStringW(authorization_key, group, intval, JSAPI2_INIFILE); + else + WritePrivateProfileStringW(authorization_key, authorization_key, intval, JSAPI2_INIFILE); + + return JSAPI2::api_security::SUCCESS; +} + +void JSAPI2::Security::Associate(const wchar_t *authorization_key, HWND hwnd) +{ + unsigned long key; + if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key)) + return; + + associations[key] = (void *)hwnd; +} + +HWND JSAPI2::Security::GetAssociation(const wchar_t *authorization_key) +{ + unsigned long key; + if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key)) + return NULL; + + AssociationMap::iterator iter = associations.find(key); + return (HWND)((iter != associations.end()) ? iter->second : NULL); +} + + +INT_PTR JSAPI2_SecurityPrompt(HWND hParent, LPCWSTR pszCaption, LPCWSTR pszTitle, LPCWSTR pszMessage, UINT flags); + +int JSAPI2::Security::SecurityPrompt(HWND parent, const wchar_t *title_string, const wchar_t *display_string, int flags) +{ + return (INT_PTR)JSAPI2_SecurityPrompt(parent, NULL, title_string, display_string, flags); +} + +void JSAPI2::Security::AssociateName(const wchar_t *authorization_key, const wchar_t *name) +{ + unsigned long key; + if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key)) + return; + + NameMap::iterator iter = names.find(key); + if (NULL != name) + { + if (iter != names.end()) + { + if (NULL != iter->second) free(iter->second); + iter->second = _wcsdup(name); + } + else + { + names.insert({key, _wcsdup(name)}); + } + } + else + { + if (iter != names.end()) + { + if (NULL != iter->second) + { + free(iter->second); + iter->second = NULL; + } + names.erase(iter); + } + } +} + +const wchar_t *JSAPI2::Security::GetAssociatedName(const wchar_t *authorization_key) +{ + unsigned long key; + if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key)) + return NULL; + + NameMap::iterator iter = names.find(key); + return (iter != names.end()) ? iter->second : NULL; +} + +void JSAPI2::Security::ResetAuthorization(const wchar_t *authorization_key) +{ + const wchar_t empty[2] = {0, 0}; + WritePrivateProfileSectionW(authorization_key, empty, JSAPI2_INIFILE); +} + +void JSAPI2::Security::SetBypass(const wchar_t *authorization_key, bool enable_bypass) +{ + size_t index = bypassList.size(); + + unsigned long key; + if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key)) + return; + + while(index--) + { + if (bypassList[index] == key) + { + if (false == enable_bypass) + bypassList.erase(bypassList.begin() + index); + return; + } + } + + if (false != enable_bypass) + bypassList.push_back(key); +} + +bool JSAPI2::Security::IsAuthorizationBypassed(const wchar_t *authorization_key) +{ + size_t index = bypassList.size(); + if (0 == index) return false; + + unsigned long key; + if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key)) + return false; + + while(index--) + { + if (bypassList[index] == key) + return true; + } + return false; +} + +JSAPI2::Security JSAPI2::security; + +#define CBCLASS JSAPI2::Security +START_DISPATCH; +CB(JSAPI2_API_SECURITY_GETACTIONAUTHORIZATION, GetActionAuthorization); +CB(JSAPI2_API_SECURITY_SETACTIONAUTHORIZATION, SetActionAuthorization); +VCB(JSAPI2_API_SECURITY_ASSOCIATE, Associate); +CB(JSAPI2_API_SECURITY_GETASSOCIATION, GetAssociation); +CB(JSAPI2_API_SECURITY_SECURITYPROMPT, SecurityPrompt); +VCB(JSAPI2_API_SECURITY_ASSOCIATENAME, AssociateName); +CB(JSAPI2_API_SECURITY_GETASSOCIATEDNAME, GetAssociatedName); +VCB(JSAPI2_API_SECURITY_RESETAUTHORIZATION, ResetAuthorization); +VCB(JSAPI2_API_SECURITY_SETBYPASS, SetBypass); +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file |