JSAPI2_Security.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #include "api.h"
  2. #include "JSAPI2_Security.h"
  3. #include "JSAPI2_svc_apicreator.h"
  4. #include <bfc/platform/types.h>
  5. #include "main.h"
  6. #include "resource.h"
  7. #include "language.h"
  8. #include <api/service/waservicefactory.h>
  9. #include <shlwapi.h>
  10. #include <strsafe.h>
  11. JSAPI2::Security::~Security()
  12. {
  13. for(NameMap::iterator iter = names.begin(); iter != names.end(); iter++)
  14. {
  15. if (NULL != iter->second)
  16. free(iter->second);
  17. }
  18. }
  19. 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 )
  20. {
  21. // TODO: benski> we should build a cache table, as we may hit this function repeatedly and it incurs a file lock
  22. // but for now it will get the ball rolling
  23. if ( action )
  24. {
  25. wchar_t group_action[ 256 ] = { 0 };
  26. StringCbPrintfW( group_action, sizeof( group_action ), L"%s@%s", action, group );
  27. int authorization = GetPrivateProfileIntW( authorization_key, group_action, api_security::ACTION_UNDEFINED, JSAPI2_INIFILE );
  28. if ( authorization != api_security::ACTION_UNDEFINED )
  29. return authorization;
  30. }
  31. if ( group )
  32. {
  33. int authorization = GetPrivateProfileIntW( authorization_key, group, api_security::ACTION_UNDEFINED, JSAPI2_INIFILE );
  34. if ( authorization != api_security::ACTION_UNDEFINED )
  35. return authorization;
  36. }
  37. int authorization = GetPrivateProfileIntW( authorization_key, authorization_key, default_authorization, JSAPI2_INIFILE );
  38. if ( ( ACTION_UNDEFINED == authorization || ACTION_PROMPT == authorization ) &&
  39. false != IsAuthorizationBypassed( authorization_key ) )
  40. {
  41. authorization = ACTION_ALLOWED;
  42. }
  43. if ( ( authorization == ACTION_UNDEFINED || authorization == ACTION_PROMPT )/* if we have to prompt */
  44. && default_authorization != ACTION_UNDEFINED /* clients pass ACTION_UNDEFINED, API's don't */
  45. && group )
  46. {
  47. waServiceFactory *sf = 0;
  48. int n = 0;
  49. do
  50. {
  51. sf = WASABI_API_SVC->service_enumService( JSAPI2::svc_apicreator::getServiceType(), n++ );
  52. if ( !sf )
  53. break;
  54. if ( sf )
  55. {
  56. JSAPI2::svc_apicreator *creator = (JSAPI2::svc_apicreator *)sf->getInterface();
  57. if ( creator )
  58. {
  59. HWND parent = 0;
  60. if ( info )
  61. parent = info->GetHWND();
  62. if ( !parent )
  63. parent = this->GetAssociation( authorization_key );
  64. int prompt = creator->PromptForAuthorization( parent, group, action, authorization_key, data );
  65. if ( ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_MASK ) != JSAPI2::svc_apicreator::AUTHORIZATION_UNDEFINED )
  66. {
  67. sf->releaseInterface( creator );
  68. int new_authorization = 0;
  69. switch ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_MASK )
  70. {
  71. case JSAPI2::svc_apicreator::AUTHORIZATION_ALLOW:
  72. new_authorization = ACTION_ALLOWED;
  73. break;
  74. case JSAPI2::svc_apicreator::AUTHORIZATION_DENY:
  75. new_authorization = ACTION_DISALLOWED;
  76. break;
  77. default:
  78. return default_authorization;
  79. }
  80. if ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_FLAG_GROUP_ONLY )
  81. action = 0;
  82. if ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_FLAG_ALWAYS )
  83. SetActionAuthorization( group, action, authorization_key, new_authorization );
  84. if ( prompt & JSAPI2::svc_apicreator::AUTHORIZATION_FLAG_ALWAYS_FOR_SERVICE )
  85. SetActionAuthorization( 0, 0, authorization_key, new_authorization );
  86. return new_authorization;
  87. }
  88. }
  89. sf->releaseInterface( creator );
  90. }
  91. } while ( sf );
  92. }
  93. return authorization;
  94. }
  95. int JSAPI2::Security::SetActionAuthorization(const wchar_t *group, const wchar_t *action, const wchar_t *authorization_key, int authorization)
  96. {
  97. // TODO: benski> we should build a cache table, as we may hit this function repeatedly and it incurs a file lock
  98. // but for now it will get the ball rolling
  99. wchar_t intval[64] = {0};
  100. _itow(authorization, intval, 10);
  101. if (action)
  102. {
  103. wchar_t group_action[256] = {0};
  104. StringCbPrintfW(group_action, sizeof(group_action), L"%s@%s", action, group);
  105. WritePrivateProfileStringW(authorization_key, group_action, intval, JSAPI2_INIFILE);
  106. }
  107. else if (group)
  108. WritePrivateProfileStringW(authorization_key, group, intval, JSAPI2_INIFILE);
  109. else
  110. WritePrivateProfileStringW(authorization_key, authorization_key, intval, JSAPI2_INIFILE);
  111. return JSAPI2::api_security::SUCCESS;
  112. }
  113. void JSAPI2::Security::Associate(const wchar_t *authorization_key, HWND hwnd)
  114. {
  115. unsigned long key;
  116. if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key))
  117. return;
  118. associations[key] = (void *)hwnd;
  119. }
  120. HWND JSAPI2::Security::GetAssociation(const wchar_t *authorization_key)
  121. {
  122. unsigned long key;
  123. if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key))
  124. return NULL;
  125. AssociationMap::iterator iter = associations.find(key);
  126. return (HWND)((iter != associations.end()) ? iter->second : NULL);
  127. }
  128. INT_PTR JSAPI2_SecurityPrompt(HWND hParent, LPCWSTR pszCaption, LPCWSTR pszTitle, LPCWSTR pszMessage, UINT flags);
  129. int JSAPI2::Security::SecurityPrompt(HWND parent, const wchar_t *title_string, const wchar_t *display_string, int flags)
  130. {
  131. return (INT_PTR)JSAPI2_SecurityPrompt(parent, NULL, title_string, display_string, flags);
  132. }
  133. void JSAPI2::Security::AssociateName(const wchar_t *authorization_key, const wchar_t *name)
  134. {
  135. unsigned long key;
  136. if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key))
  137. return;
  138. NameMap::iterator iter = names.find(key);
  139. if (NULL != name)
  140. {
  141. if (iter != names.end())
  142. {
  143. if (NULL != iter->second) free(iter->second);
  144. iter->second = _wcsdup(name);
  145. }
  146. else
  147. {
  148. names.insert({key, _wcsdup(name)});
  149. }
  150. }
  151. else
  152. {
  153. if (iter != names.end())
  154. {
  155. if (NULL != iter->second)
  156. {
  157. free(iter->second);
  158. iter->second = NULL;
  159. }
  160. names.erase(iter);
  161. }
  162. }
  163. }
  164. const wchar_t *JSAPI2::Security::GetAssociatedName(const wchar_t *authorization_key)
  165. {
  166. unsigned long key;
  167. if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key))
  168. return NULL;
  169. NameMap::iterator iter = names.find(key);
  170. return (iter != names.end()) ? iter->second : NULL;
  171. }
  172. void JSAPI2::Security::ResetAuthorization(const wchar_t *authorization_key)
  173. {
  174. const wchar_t empty[2] = {0, 0};
  175. WritePrivateProfileSectionW(authorization_key, empty, JSAPI2_INIFILE);
  176. }
  177. void JSAPI2::Security::SetBypass(const wchar_t *authorization_key, bool enable_bypass)
  178. {
  179. size_t index = bypassList.size();
  180. unsigned long key;
  181. if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key))
  182. return;
  183. while(index--)
  184. {
  185. if (bypassList[index] == key)
  186. {
  187. if (false == enable_bypass)
  188. bypassList.erase(bypassList.begin() + index);
  189. return;
  190. }
  191. }
  192. if (false != enable_bypass)
  193. bypassList.push_back(key);
  194. }
  195. bool JSAPI2::Security::IsAuthorizationBypassed(const wchar_t *authorization_key)
  196. {
  197. size_t index = bypassList.size();
  198. if (0 == index) return false;
  199. unsigned long key;
  200. if (FALSE == StrToIntExW(authorization_key, STIF_DEFAULT, (int*)&key))
  201. return false;
  202. while(index--)
  203. {
  204. if (bypassList[index] == key)
  205. return true;
  206. }
  207. return false;
  208. }
  209. JSAPI2::Security JSAPI2::security;
  210. #define CBCLASS JSAPI2::Security
  211. START_DISPATCH;
  212. CB(JSAPI2_API_SECURITY_GETACTIONAUTHORIZATION, GetActionAuthorization);
  213. CB(JSAPI2_API_SECURITY_SETACTIONAUTHORIZATION, SetActionAuthorization);
  214. VCB(JSAPI2_API_SECURITY_ASSOCIATE, Associate);
  215. CB(JSAPI2_API_SECURITY_GETASSOCIATION, GetAssociation);
  216. CB(JSAPI2_API_SECURITY_SECURITYPROMPT, SecurityPrompt);
  217. VCB(JSAPI2_API_SECURITY_ASSOCIATENAME, AssociateName);
  218. CB(JSAPI2_API_SECURITY_GETASSOCIATEDNAME, GetAssociatedName);
  219. VCB(JSAPI2_API_SECURITY_RESETAUTHORIZATION, ResetAuthorization);
  220. VCB(JSAPI2_API_SECURITY_SETBYPASS, SetBypass);
  221. END_DISPATCH;
  222. #undef CBCLASS