Beispiel #1
0
/**
 * \brief Checks URL policy files to see if the player is allowed access to the given UR
 *
 * Waits for mutex at start and releases mutex when finished
 * \param url The URL to evaluate
 * \param loadPendingPolicies Whether to load (and thus check) pending policies before evaluating
 * \return \c ALLOWED if allowed or otherwise \c NA_CROSSDOMAIN_POLICY
 */
SecurityManager::EVALUATIONRESULT SecurityManager::evaluatePoliciesURL(const URLInfo& url,
		bool loadPendingPolicies)
{
	//This check doesn't apply to local files
	if(url.getProtocol() == "file" && sys->getOrigin().getProtocol() == "file")
		return ALLOWED;

	LOG(LOG_NO_INFO, _("SECURITY: Evaluating URL for cross domain policies:"));
	LOG(LOG_NO_INFO, _("SECURITY: --> URL:    ") << url);
	LOG(LOG_NO_INFO, _("SECURITY: --> Origin: ") << sys->getOrigin());

	//The URL has exactly the same domain name as the origin, always allowed
	if(url.getProtocol() == sys->getOrigin().getProtocol() &&
			url.getHostname() == sys->getOrigin().getHostname())
	{
		LOG(LOG_NO_INFO, _("SECURITY: Same hostname as origin, allowing"));
		return ALLOWED;
	}

	//Search for the policy files to check
	URLPFileList* files = searchURLPolicyFiles(url, loadPendingPolicies);
	
	sem_wait(&mutex);
	//-- Lock acquired

	//Check the policy files
	if(files != NULL)
	{
		URLPFileListConstIt it = files->begin();
		for(; it != files->end(); ++it)
		{
			if((*it)->allowsAccessFrom(sys->getOrigin(), url))
			{
				LOG(LOG_NO_INFO, _("SECURITY: ALLOWED: A policy file explicitly allowed access"));
				delete files;

				//++ Release lock
				sem_post(&mutex);
				return ALLOWED;
			}
		}
	}

	LOG(LOG_NO_INFO, _("SECURITY: DISALLOWED: No policy file explicitly allowed access"));
	delete files;

	//++ Release lock
	sem_post(&mutex);
	return NA_CROSSDOMAIN_POLICY;
}
Beispiel #2
0
/**
 * \brief Checks URL policy files to see if the player is allowed access to the given UR
 *
 * Waits for mutex at start and releases mutex when finished
 * \param url The URL to evaluate
 * \param loadPendingPolicies Whether to load (and thus check) pending policies before evaluating
 * \return \c ALLOWED if allowed or otherwise \c NA_CROSSDOMAIN_POLICY
 */
SecurityManager::EVALUATIONRESULT SecurityManager::evaluatePoliciesURL(const URLInfo& url,
		bool loadPendingPolicies)
{
	//This check doesn't apply to local files
	if(url.getProtocol() == "file" && getSys()->getOrigin().getProtocol() == "file")
		return ALLOWED;

	//Streaming from RTMP is always allowed (see
	//http://forums.adobe.com/thread/422391)
	if(url.isRTMP())
		return ALLOWED;

	LOG(LOG_INFO, _("SECURITY: Evaluating URL for cross domain policies:"));
	LOG(LOG_INFO, _("SECURITY: --> URL:    ") << url);
	LOG(LOG_INFO, _("SECURITY: --> Origin: ") << getSys()->getOrigin());

	//The URL has exactly the same domain name as the origin, always allowed
	if(url.getProtocol() == getSys()->getOrigin().getProtocol() &&
			url.getHostname() == getSys()->getOrigin().getHostname())
	{
		LOG(LOG_INFO, _("SECURITY: Same hostname as origin, allowing"));
		return ALLOWED;
	}

	//Search for the policy files to check
	URLPFileList* files = searchURLPolicyFiles(url, loadPendingPolicies);

	RecMutex::Lock l(mutex);

	//Check the policy files
	if(files != NULL)
	{
		URLPFileListConstIt it = files->begin();
		for(; it != files->end(); ++it)
		{
			if((*it)->allowsAccessFrom(getSys()->getOrigin(), url))
			{
				LOG(LOG_INFO, _("SECURITY: ALLOWED: A policy file explicitly allowed access"));
				delete files;
				return ALLOWED;
			}
		}
	}

	LOG(LOG_INFO, _("SECURITY: DISALLOWED: No policy file explicitly allowed access"));
	delete files;

	return NA_CROSSDOMAIN_POLICY;
}
Beispiel #3
0
/**
 * \brief Checks URL policy files to see if the player is allowed to send a given request header 
 * as part of a request for the given URL
 *
 * Waits for mutex at start and releases mutex when finished
 * \param url The URL of the request to which the request header belongs
 * \param header The request header to evaluate
 * \param loadPendingPolicies Whether or not to load (and thus check) pending policy files
 * \return \c ALLOWED if allowed or otherwise \c NA_HEADER
 */
SecurityManager::EVALUATIONRESULT SecurityManager::evaluateHeader(const URLInfo& url,
		const tiny_string& header, bool loadPendingPolicies)
{
	//This check doesn't apply to local files
	if(url.getProtocol() == "file" && getSys()->getOrigin().getProtocol() == "file")
		return ALLOWED;

	LOG(LOG_INFO, _("SECURITY: Evaluating header for cross domain policies ('") << header << "'):");
	LOG(LOG_INFO, _("SECURITY: --> URL: ") << url);
	LOG(LOG_INFO, _("SECURITY: --> Origin: ") << getSys()->getOrigin());

	string headerStrLower(header.raw_buf());
	transform(headerStrLower.begin(), headerStrLower.end(), headerStrLower.begin(), ::tolower);
	string headerStr = headerStrLower;
	if(headerStr.find("_") != string::npos)
		headerStr.replace(headerStr.find("_"), 1, "-");

	//Disallowed headers, in any case
	if(headerStr == "accept-charset" &&	headerStr == "accept-encoding" &&	headerStr == "accept-ranges" &&
			headerStr == "age" &&	headerStr == "allow" && headerStr == "allowed" && headerStr == "authorization" &&
			headerStr == "charge-to" && headerStr == "connect" && headerStr == "connection" &&
			headerStr == "content-length" && headerStr == "content-location" && headerStr == "content-range" &&
			headerStr == "cookie" && headerStr == "date" && headerStr == "delete" && headerStr == "etag" &&
			headerStr == "expect" && headerStr == "get" && headerStr == "head" && headerStr == "host" &&
			headerStr == "if-modified-since" && headerStr == "keep-alive" && headerStr == "last-modified" &&
			headerStr == "location" && headerStr == "max-forwards" && headerStr == "options" &&
			headerStr == "origin" && headerStr == "post" && headerStr == "proxy-authenticate" &&
			headerStr == "proxy-authorization" && headerStr == "proxy-connection" && headerStr == "public" &&
			headerStr == "put" && headerStr == "range" && headerStr == "referer" && headerStr == "request-range" &&
			headerStr == "retry-after" && headerStr == "server" && headerStr == "te" && headerStr == "trace" &&
			headerStr == "trailer" && headerStr == "transfer-encoding" && headerStr == "upgrade" &&
			headerStr == "uri" && headerStr == "user-agent" && headerStr == "vary" && headerStr == "via" &&
			headerStr == "warning" && headerStr == "www-authenticate" && headerStr == "x-flash-version")
	{
		LOG(LOG_INFO, _("SECURITY: DISALLOWED: Header is restricted"));
		return NA_HEADER;
	}

	//The URL has exactly the same domain name as the origin, always allowed
	if(url.getProtocol() == getSys()->getOrigin().getProtocol() &&
			url.getHostname() == getSys()->getOrigin().getHostname())
	{
		LOG(LOG_INFO, _("SECURITY: ALLOWED: Same hostname as origin"));
		return ALLOWED;
	}

	//Search for the policy files to check
	URLPFileList* files = searchURLPolicyFiles(url, loadPendingPolicies);

	RecMutex::Lock l(mutex);

	//Check the policy files
	if(files != NULL)
	{
		URLPFileListConstIt it = files->begin();
		for(; it != files->end(); ++it)
		{
			if((*it)->allowsHTTPRequestHeaderFrom(getSys()->getOrigin(), url, headerStrLower))
			{
				LOG(LOG_INFO, _("SECURITY: ALLOWED: A policy file explicitly allowed the header"));
				delete files;
				return ALLOWED;
			}
		}
	}

	LOG(LOG_INFO, _("SECURITY: DISALLOWED: No policy file explicitly allowed the header"));
	delete files;

	return NA_CROSSDOMAIN_POLICY;
}
Beispiel #4
0
/**
 * \brief Search for URL policy files relevant to a given URL
 *
 * Searches the loaded URL policy file list for URL policy files that are relevant to a given URL.
 * If \c loadPendingPolicies is true, it search the pending URL policy files list next, 
 * loading every relative policy file.
 * Waits for mutex at start and releases mutex when finished
 * \param url The URL that will be evaluated using the relevant policy files.
 * \param loadPendingPolicies Whether or not to load (and thus check) pending URL policy files.
 * \return An pointer to a newly created URLPFileList containing the relevant policy files.
 *         This list needs to be deleted after use.
 */
URLPFileList* SecurityManager::searchURLPolicyFiles(const URLInfo& url, bool loadPendingPolicies)
{
	URLPFileList* result = new URLPFileList;

	//Get or create the master policy file object
	URLInfo masterURL = url.goToURL("/crossdomain.xml");
	URLPolicyFile* master = getURLPolicyFileByURL(masterURL);

	if(master == NULL)
		master = addURLPolicyFile(masterURL);

	if(loadPendingPolicies)
		getSys()->securityManager->loadPolicyFile(master);

	RecMutex::Lock l(mutex);
	//Check if the master policy file is loaded.
	//If another user-added relevant policy file is already loaded, 
	//it's master will have already been loaded too (to check if it is allowed).
	//So IF any relevant policy file is loaded already, then the master will be too.
	if(master->isLoaded() && master->isValid())
	{
		LOG(LOG_INFO, _("SECURITY: Master policy file is loaded and valid (") << url << ")");

		PolicySiteControl::METAPOLICY siteControl = master->getSiteControl()->getPermittedPolicies();
		//Master defines no policy files are allowed at all
		if(siteControl == PolicySiteControl::NONE)
		{
			LOG(LOG_INFO, _("SECURITY: DISALLOWED: Master policy file disallows policy files"));
			return NULL;
		}

		result->push_back(master);

		//Non-master policy files are allowed
		if(siteControl != PolicySiteControl::MASTER_ONLY)
		{
			LOG(LOG_INFO, _("SECURITY: Searching for loaded non-master policy files (") <<
					loadedURLPFiles.count(url.getHostname()) << ")");

			URLPFileMapConstItPair range = loadedURLPFiles.equal_range(url.getHostname());
			URLPFileMapConstIt i = range.first;
			for(;i != range.second; ++i)
			{
				if((*i).second == master)
					continue;
				result->push_back((*i).second);
			}

			//And check the pending policy files next (if we are allowed to)
			if(loadPendingPolicies)
			{
				LOG(LOG_INFO, _("SECURITY: Searching for and loading pending non-master policy files (") <<
						pendingURLPFiles.count(url.getHostname()) << ")");

				while(true)
				{
					i=pendingURLPFiles.find(url.getHostname());
					if(i==pendingURLPFiles.end())
						break;

					result->push_back((*i).second);

					l.release();
					getSys()->securityManager->loadPolicyFile((*i).second);
					//NOTE: loadPolicyFile() will change pendingURLPFiles,
					//erasing & moving to loadURLPFiles. Therefore, the
					//iterator i is now invalid.
					l.acquire();
				}
			}
		}
	}
	return result;
}