32 #include <nsIConsoleService.h>
33 #include <nsIPermissionManager.h>
34 #include <nsIPrefBranch.h>
35 #include <nsIScriptSecurityManager.h>
36 #include <nsServiceManagerUtils.h>
37 #include <nsStringGlue.h>
43 #define PERM_TYPE_PLAYBACK_CONTROL "rapi.playback_control"
44 #define PERM_TYPE_PLAYBACK_READ "rapi.playback_read"
45 #define PERM_TYPE_LIBRARY_READ "rapi.library_read"
46 #define PERM_TYPE_LIBRARY_WRITE "rapi.library_write"
48 #define PREF_PLAYBACK_CONTROL "playback_control_disable"
49 #define PREF_PLAYBACK_READ "playback_read_disable"
50 #define PREF_LIBRARY_READ "library_read_disable"
51 #define PREF_LIBRARY_WRITE "library_write_disable"
57 static PRLogModuleInfo* gLibraryLog = nsnull;
61 #define LOG(args) PR_LOG(gLibraryLog, PR_LOG_WARN, args)
98 nsIProgrammingLanguage::CPLUSPLUS,
102 sbSecurityMixin::sbSecurityMixin()
105 mPrivileged(PR_FALSE)
109 gLibraryLog = PR_NewLogModule(
"sbSecurityMixin" );
131 const nsIID **aInterfacesArray, PRUint32 aInterfacesArrayLength,
132 const char **aMethodsArray, PRUint32 aMethodsArrayLength,
133 const char **aRPropsArray, PRUint32 aRPropsArrayLength,
134 const char **aWPropsArray, PRUint32 aWPropsArrayLength,
137 NS_ENSURE_ARG_POINTER(aOuter);
148 return NS_ERROR_OUT_OF_MEMORY;
164 sbSecurityMixin::CanCreateWrapper(
const nsIID *aIID,
char **_retval)
166 LOG((
"sbSecurityMixin::CanCreateWrapper()"));
167 NS_ENSURE_ARG_POINTER(aIID);
168 NS_ENSURE_ARG_POINTER(_retval);
171 LOG((
"sbSecurityMixin::CanCreateWrapper() - ERROR, no outer"));
173 return NS_ERROR_FAILURE;
177 PRBool canCreate = PR_FALSE;
180 if ( aIID->Equals(*ifaceIID) ) {
186 LOG((
"sbSecurityMixin::CanCreateWrapper() - DENIED, bad interface" ));
188 return NS_ERROR_FAILURE;
198 nsCOMPtr<nsIURI> codebase;
199 GetCodebase( getter_AddRefs(codebase) );
220 LOG((
"sbSecurityMixin::CanCreateWrapper - Permission GRANTED!!!"));
223 LOG((
"sbSecurityMixin::CanCreateWrapper - Permission DENIED (looser)!!!"));
225 return NS_ERROR_FAILURE;
233 sbSecurityMixin::CanCallMethod(
const nsIID *aIID,
234 const PRUnichar *aMethodName,
239 NS_ENSURE_ARG_POINTER(aIID);
240 NS_ENSURE_ARG_POINTER(aMethodName);
241 NS_ENSURE_ARG_POINTER(_retval);
243 LOG((
"sbSecurityMixin::CanCallMethod(%s)",
244 NS_LossyConvertUTF16toASCII(aMethodName).
get() ));
247 nsDependentString inMethodName(aMethodName);
250 if ( method.IsEmpty() ) {
251 LOG((
"sbSecurityMixin::CanCallMethod(%s) - DENIED, unapproved method",
252 NS_LossyConvertUTF16toASCII(aMethodName).
get() ));
254 return NS_ERROR_FAILURE;
258 LOG((
"sbSecurityMixin::CanCallMethod - Permission GRANTED!!!"));
261 LOG((
"sbSecurityMixin::CanCallMethod - Permission DENIED (looser)!!!"));
263 return NS_ERROR_FAILURE;
269 sbSecurityMixin::CanGetProperty(
const nsIID *aIID,
270 const PRUnichar *aPropertyID,
279 NS_ENSURE_ARG_POINTER(aPropertyID);
280 NS_ENSURE_ARG_POINTER(_retval);
282 LOG((
"sbSecurityMixin::CanGetProperty(%s)",
283 NS_LossyConvertUTF16toASCII(aPropertyID).
get() ));
286 nsDependentString inPropertyID(aPropertyID);
289 if ( prop.IsEmpty() ) {
290 LOG((
"sbSecurityMixin::CanGetProperty(%s) - DENIED, unapproved property",
291 NS_LossyConvertUTF16toASCII(aPropertyID).
get() ));
293 return NS_ERROR_FAILURE;
297 LOG((
"sbSecurityMixin::CanGetProperty - Permission GRANTED!!!"));
300 LOG((
"sbSecurityMixin::CanGetProperty - Permission DENIED (looser)!!!"));
302 return NS_ERROR_FAILURE;
308 sbSecurityMixin::CanSetProperty(
const nsIID *aIID,
309 const PRUnichar *aPropertyID,
318 NS_ENSURE_ARG_POINTER(aPropertyID);
319 NS_ENSURE_ARG_POINTER(_retval);
321 LOG((
"sbSecurityMixin::CanSetProperty(%s)",
322 NS_LossyConvertUTF16toASCII(aPropertyID).
get() ));
325 nsDependentString inPropertyID(aPropertyID);
328 if (prop.IsEmpty()) {
329 LOG((
"sbSecurityMixin::CanSetProperty(%s) - DENIED, unapproved property",
330 NS_LossyConvertUTF16toASCII(aPropertyID).
get() ));
332 return NS_ERROR_FAILURE;
336 LOG((
"sbSecurityMixin::CanSetProperty - Permission GRANTED!!!"));
339 LOG((
"sbSecurityMixin::CanSetProperty - Permission DENIED (looser)!!!"));
341 return NS_ERROR_FAILURE;
353 sbSecurityMixin::GetCodebase(nsIURI **aCodebase) {
354 NS_ENSURE_ARG_POINTER(aCodebase);
358 nsCOMPtr<nsIScriptSecurityManager>
secman( do_GetService( NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv ) );
359 NS_ENSURE_SUCCESS( rv, rv );
360 nsCOMPtr<nsIPrincipal> principal;
361 secman->GetSubjectPrincipal( getter_AddRefs(principal) );
364 LOG((
"sbSecurityMixin::GetCodebase -- Error: No Subject Principal."));
368 LOG((
"sbSecurityMixin::GetCodebase -- Have Subject Principal."));
371 nsCOMPtr<nsIPrincipal> systemPrincipal;
372 secman->GetSystemPrincipal( getter_AddRefs(systemPrincipal) );
374 if (principal == systemPrincipal) {
375 LOG((
"sbSecurityMixin::GetCodebase -- System Principal."));
377 LOG((
"sbSecurityMixin::GetCodebase -- Not System Principal."));
381 nsCOMPtr<nsIURI> codebase;
382 principal->GetDomain( getter_AddRefs(codebase) );
385 LOG((
"sbSecurityMixin::GetCodebase -- no codebase from domain, getting it from URI."));
386 principal->GetURI( getter_AddRefs(codebase) );
389 *aCodebase = codebase;
390 NS_IF_ADDREF(*aCodebase);
396 const nsAString &aMethodName,
397 nsAString &aScopedName)
399 LOG((
"sbSecurityMixin::GetScopedName()"));
400 PRBool approved = PR_FALSE;
404 NS_ENSURE_TRUE( methods, PR_FALSE );
406 while ( NS_SUCCEEDED( methods->GetNext(method) ) ) {
407 LOG((
" -- checking method: %s", NS_ConvertUTF16toUTF8(method).
get() ));
408 if ( StringEndsWith( method, aMethodName ) ) {
409 aScopedName = method;
419 PRBool disableNotificationCheck)
421 LOG((
"sbSecurityMixin::GetPermissionForScopedName()"));
428 PRBool allowed = PR_FALSE;
430 nsCOMPtr<nsIURI> codebase;
431 GetCodebase( getter_AddRefs(codebase) );
433 if ( StringBeginsWith( aScopedName, NS_LITERAL_STRING(
"internal:") ) ) {
441 NS_WARNING(
"sbSecurityMixin::GetPermissionForScopedName() -- AHHH!!! Asked for internal with codebase");
458 else if ( StringBeginsWith( aScopedName, NS_LITERAL_STRING(
"site:") ) ) {
462 else if ( StringBeginsWith( aScopedName, NS_LITERAL_STRING(
"helper:") ) ) {
466 else if ( StringBeginsWith( aScopedName, NS_LITERAL_STRING(
"classinfo:") ) ) {
473 if ( scope && !disableNotificationCheck ) {
474 const char* notification =
476 LOG((
"sbSecurityMixin::GetPermissionsForScopedName() notification=%s",
480 LOG((
"sbSecurityMixin::GetPermissionsForScopedName() - ALERT" ));
485 NS_LITERAL_STRING(
"rapi.media_add.request.title"),
486 NS_LITERAL_STRING(
"rapi.media_add.request.message"),
491 LOG((
"sbSecurityMixin::GetPermissionsForScopedName() - STATUS" ));
494 LOG((
"sbSecurityMixin::GetPermissionsForScopedName() - HAT" ));
501 nsCOMPtr<nsIPrefBranch> prefService =
502 do_GetService(
"@mozilla.org/preferences-service;1", &rv );
503 NS_ENSURE_SUCCESS( rv, allowed );
507 nsCString prefKey(
"songbird.rapi.");
508 prefKey.Append(scope->
name);
509 prefKey.AppendLiteral(
"_notify");
510 rv = prefService->GetBoolPref( prefKey.get(), &
notify );
511 NS_ENSURE_SUCCESS( rv, allowed );
513 LOG((
"sbSecurityMixin::GetPermissionsForScopedName() pref value: %s",
514 notify?
"true":
"false" ));
528 for (
unsigned i=0;
i<NS_ARRAY_LENGTH(sScopes);
i++) {
529 NS_ConvertUTF8toUTF16 prefix( sScopes[
i].
name );
530 prefix.AppendLiteral(
":");
531 if( StringBeginsWith( aScopedName, prefix ) ) {
541 NS_ENSURE_TRUE( aURI, PR_FALSE );
542 NS_ENSURE_TRUE( aScope, PR_FALSE );
543 NS_ENSURE_TRUE( aScope->
name, PR_FALSE );
549 LOG((
"sbSecurityMixin::GetPermission( %s, %s)", spec.get(), aScope->
name ));
554 nsCOMPtr<nsIPrefBranch> prefService =
555 do_GetService(
"@mozilla.org/preferences-service;1", &rv );
556 NS_ENSURE_SUCCESS( rv, PR_FALSE );
559 PRBool prefBlocked = PR_TRUE;
560 nsCString prefKey(
"songbird.rapi.");
561 prefKey.Append(aScope->
name);
562 prefKey.AppendLiteral(
"_disable");
565 LOG((
"sbSecurityMixin::GetPermission() - asking for pref: %s", prefKey.get() ));
566 rv = prefService->GetBoolPref( prefKey.get(), &prefBlocked );
567 NS_ENSURE_SUCCESS( rv, PR_FALSE );
570 nsCString permission_name(
"rapi.");
571 permission_name.Append(aScope->
name);
572 nsCOMPtr<nsIPermissionManager> permMgr( do_GetService( NS_PERMISSIONMANAGER_CONTRACTID, &rv ) );
573 NS_ENSURE_SUCCESS( rv, PR_FALSE );
574 PRUint32 perms = nsIPermissionManager::UNKNOWN_ACTION;
575 rv = permMgr->TestPermission( aURI, permission_name.get(), &perms );
576 NS_ENSURE_SUCCESS( rv, PR_FALSE );
580 LOG((
"sbSecurityMixin::GetPermission() - action is blocked" ));
582 if ( perms == nsIPermissionManager::ALLOW_ACTION ) {
583 LOG((
"sbSecurityMixin::GetPermission - Permission GRANTED!!!"));
587 LOG((
"sbSecurityMixin::GetPermission() - action not blocked" ));
589 if ( perms != nsIPermissionManager::DENY_ACTION ) {
590 LOG((
"sbSecurityMixin::GetPermission - Permission GRANTED!!!"));
596 LOG((
"sbSecurityMixin::GetPermission - Permission DENIED (looooooser)!!!"));
604 NS_ENSURE_TRUE( !aScopedName.IsEmpty(), NS_ERROR_INVALID_ARG );
607 nsCString permission_name(
"rapi.");
608 permission_name.Append(aScopedName);
609 nsCOMPtr<nsIPermissionManager> permMgr =
610 do_GetService( NS_PERMISSIONMANAGER_CONTRACTID, &rv );
611 NS_ENSURE_SUCCESS( rv, rv );
613 rv = permMgr->Add( aURI,
614 permission_name.BeginReading(),
615 nsIPermissionManager::ALLOW_ACTION );
616 NS_ENSURE_SUCCESS( rv, rv );
632 NS_ENSURE_ARG_POINTER(aNotificationType);
633 NS_ENSURE_ARG_POINTER(aScope);
638 LOG((
"sbSecurityMixin::DispatchNotificationEvent(%s)", aNotificationType ));
642 LOG((
"sbSecurityMixin::DispatchNotificationEvent - dispatching event" ));
644 nsCOMPtr<sbIRemotePlayer> remotePlayer;
645 nsresult rv =
mOuter->GetRemotePlayer(getter_AddRefs(remotePlayer));
649 if(NS_SUCCEEDED(rv)) {
655 NS_ConvertASCIItoUTF16(aScope->
name),
662 LOG((
"sbSecurityMixin::DispatchNotificationEvent - not dispatching event" ));
663 NS_WARNING(
"sbSecurityMixin::DispatchNotificationEvent didn't have a notification document to dispatch to" );
670 sbSecurityMixin::GetNotificationDocument(nsIDOMDocument **aNotificationDocument)
672 NS_ENSURE_ARG_POINTER(aNotificationDocument);
678 NS_IMETHODIMP sbSecurityMixin::SetNotificationDocument(nsIDOMDocument * aNotificationDocument)
680 NS_ENSURE_ARG_POINTER(aNotificationDocument);
696 NS_ENSURE_ARG_POINTER(aSourceArray);
697 NS_ENSURE_ARG_POINTER(aDestArray);
699 for ( PRUint32 index = 0; index <
aCount; index++ ) {
700 if ( !aDestArray->AppendElement(aSourceArray[index]))
701 return NS_ERROR_OUT_OF_MEMORY;
709 NS_ENSURE_ARG_POINTER(aSourceArray);
710 NS_ENSURE_ARG_POINTER(aDestArray);
714 nsIID **iids =
static_cast<nsIID**
>( NS_Alloc( aCount *
sizeof(nsIID*) ) );
716 return NS_ERROR_OUT_OF_MEMORY;
719 for (PRUint32 index = 0; index <
aCount; ++index) {
720 iids[index] =
static_cast<nsIID*
>(
SB_CloneMemory( aSourceArray[index],
sizeof(nsIID) ) );
723 for (PRUint32 alloc_index = 0; alloc_index < index; ++alloc_index)
724 NS_Free( iids[alloc_index] );
726 return NS_ERROR_OUT_OF_MEMORY;
736 return ToNewCString( NS_LITERAL_CSTRING(
"AllAccess") );
740 sbSecurityMixin::GetPermissionForScopedNameWrapper(
const nsAString& aRemotePermCategory,
static const char * sNotificationNone
#define SONGBIRD_SECURITYMIXIN_CLASSNAME
sbISecurityMixin SB_IMPL_CLASSINFO(sbSecurityMixin,"@songbirdnest.com/remoteapi/security-mixin;1","Songbird Remote Security Mixin", nsIProgrammingLanguage::CPLUSPLUS, 0, kSecurityMixinCID)
void * SB_CloneMemory(const void *ptr, PRSize size)
Clone a block of contiguous memory.
const char * allowed_notification
static PRBool GetUserApprovalForHost(nsIURI *aURI, const nsAString &aTitleKey, const nsAString &aMessageKey, const char *aScopedName=nsnull)
#define PERM_TYPE_PLAYBACK_CONTROL
nsTArray< nsCString > mMethods
nsTArray< nsCString > mWProperties
static const char * sNotificationStatus
#define PREF_LIBRARY_READ
#define PERM_TYPE_PLAYBACK_READ
virtual ~sbSecurityMixin()
#define SONGBIRD_SECURITYMIXIN_CONTRACTID
PRBool GetScopedName(nsTArray< nsCString > &aStringArray, const nsAString &aMethodName, nsAString &aScopedName)
nsTArray< nsCString > mRProperties
PRUint32 mInterfacesCount
NS_IMPL_ISUPPORTS3(sbSecurityMixin, nsIClassInfo, nsISecurityCheckedComponent, sbISecurityMixin) NS_IMPL_CI_INTERFACE_GETTER2(sbSecurityMixin
An interface for setting up nsISecurityCheckedComponent security checks.
static NS_DEFINE_CID(kSecurityMixinCID,{0xaaae98ec, 0x386e, 0x405e,{0xb1, 0x09, 0xcf, 0x1a, 0x87, 0x2e, 0xf6, 0xdd}})
TimerLoop prototype notify
static const char * sNotificationAlert
A marker interface for objects that aggregate the security mixin.
nsresult CopyIIDArray(PRUint32 aCount, const nsIID **aSourceArray, nsIID ***aDestArray)
#define PREF_PLAYBACK_READ
#define PERM_TYPE_LIBRARY_READ
const char * blocked_notification
const struct Scope * GetScopeForScopedName(const nsAString &aScopedName)
static const Scope sScopes[]
nsresult DispatchNotificationEvent(const char *aNotificationType, const Scope *aScope, PRBool aHasAccess)
static nsresult DispatchSecurityEvent(nsIDOMDocument *aDoc, sbIRemotePlayer *aPlayer, const nsAString &aClass, const nsAString &aType, const nsAString &aCategoryID, PRBool aHasAccess, PRBool aIsTrusted)
sbISecurityAggregator * mOuter
restoreHistoryPrecursor aCount
nsCOMPtr< nsIDOMDocument > mNotificationDocument
NS_IMPL_CI_INTERFACE_GETTER2(sbDataRemoteWrapper, sbIDataRemote, nsIClassInfo) sbDataRemoteWrapper
nsISecurityCheckedComponent
#define PREF_PLAYBACK_CONTROL
nsresult CopyStrArray(PRUint32 aCount, const char **aSourceArray, nsTArray< nsCString > *aDestArray)
char * SB_CloneAllAccess()
PRBool GetPermission(nsIURI *aURI, const struct Scope *aScope)
_getSelectedPageStyle s i
#define SONGBIRD_SECURITYMIXIN_CID
static const char * sNotificationHat
PRBool GetPermissionForScopedName(const nsAString &aScopedName, PRBool disableNotificationCheck=PR_FALSE)
static nsresult SetPermission(nsIURI *aURI, const nsACString &aScopedName)
Set the permission to allow for a scoped name.