Example #1
0
/**
 * \brief Checks if the current sandbox is allowed access to the given URL.
 * 
 * \param url The URL to evaluate the sandbox against
 * \param allowedSandboxesRemote The sandboxes that are allowed to access remote URLs in this case.
 *                               Can be a bitwise expression of sandboxes.
 * \param allowedSandboxesLocal The sandboxes that are allowed to access local URLs in this case.
 *                              Can be a bitwise expression of sandboxes.
 * \return \c ALLOWED if allowed or otherwise \c NA_REMOTE_SANDBOX/NA_LOCAL_SANDBOX depending on the reason.
 */
SecurityManager::EVALUATIONRESULT SecurityManager::evaluateSandboxURL(const URLInfo& url, 
		int allowedSandboxesRemote, int allowedSandboxesLocal)
{
	//The URL is remote and the current sandbox doesn't match the allowed sandboxes for remote URLs
	if(url.getProtocol() != "file" && (~allowedSandboxesRemote) & sandboxType)
		return NA_REMOTE_SANDBOX;
	//The URL is local and the current sandbox doesn't match the allowed sandboxes for local URLs
	if(url.getProtocol() == "file" && (~allowedSandboxesLocal) & sandboxType)
		return NA_LOCAL_SANDBOX;

	return ALLOWED;
}
Example #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" && 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;
}
Example #3
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;
}
Example #4
0
/**
 * \brief Checks if the URL doesn't point to a resource higher up the directory hierarchy than 
 * the current directory
 *
 * \param url The URL to evaluate
 * \return \c ALLOWED if allowed or otherwise \c NA_RESTRICT_LOCAL_DIRECTORY
 */
SecurityManager::EVALUATIONRESULT SecurityManager::evaluateLocalDirectoryURL(const URLInfo& url)
{
	//The URL is local and points to a directory above the origin
	if(url.getProtocol() == "file" && !url.isSubOf(getSys()->getOrigin()))
		return NA_RESTRICT_LOCAL_DIRECTORY;

	return ALLOWED;
}
Example #5
0
/**
 * \brief Checks if the port in the given URL isn't restricted, depending on the protocol of the URL
 *
 * \param url The URL to evaluate
 * \return \c ALLOWED if allowed or otherwise \c NA_PORT
 */
SecurityManager::EVALUATIONRESULT SecurityManager::evaluatePortURL(const URLInfo& url)
{
	if(url.getProtocol() == "http" || url.getProtocol() == "https")
		if(url.getPort() == 20 || url.getPort() == 21)
			return NA_PORT;

	if(url.getProtocol() == "http" || url.getProtocol() == "https" || url.getProtocol() == "ftp")
	{
		switch(url.getPort())
		{
		case 1:		case 7:		case 9:		case 11: case 13: case 15: case 17: case 19: case 22: case 23:
		case 25: case 37: case 42: case 43: case 53: case 77: case 79: case 87: case 95: case 101:
		case 102: case 103: case 104: case 109: case 110: case 111: case 113: case 115: case 117:
		case 119: case 123: case 135: case 139: case 143: case 179: case 389: case 465: case 512:
		case 513: case 514: case 515: case 526: case 530: case 531: case 532: case 540: case 556:
		case 563: case 587: case 601: case 636: case 993: case 995: case 2049: case 4045: case 6000:
			return NA_PORT;
		}
	}
	return ALLOWED;
}
Example #6
0
/**
 * \brief Checks if the entry allows access from the given URL
 *
 * \param url The URL to check this entry against
 * \return \c true if this entry allows the given URL access, otherwise \c false
 */
bool PolicyAllowAccessFrom::allowsAccessFrom(const URLInfo& url) const
{
	//TODO: resolve domain names using DNS before checking for a match?
	//See section 1.5.9 in specification

	//TODO: add check for to-ports and secure for SOCKET type policy files
	
	//Check if domains match
	if(!URLInfo::matchesDomain(domain, url.getHostname()))
		return false;

	//Check if the requesting URL is secure, if needed
	if(file->getType() == PolicyFile::URL && 
			dynamic_cast<URLPolicyFile*>(file)->getSubtype() == URLPolicyFile::HTTPS && 
			secure && url.getProtocol() != "https")
		return false;

	return true;
}
Example #7
0
/**
 * \brief Checks if the entry allows a given request header from a given URL
 *
 * \param url The URL to check this entry against
 * \param header The header to check this entry against
 * \return \c true if this entry allows the given URL to send the given request header, otherwise \c false
 */
bool PolicyAllowHTTPRequestHeadersFrom::allowsHTTPRequestHeaderFrom(const URLInfo& url,
		const string& header) const
{
	if(file->getSubtype() != URLPolicyFile::HTTP && file->getSubtype() != URLPolicyFile::HTTPS)
		return false;

	//Check if domains match
	if(!URLInfo::matchesDomain(domain, url.getHostname()))
		return false;

	//Check if the requesting URL is secure, if needed
	if(file->getSubtype() == URLPolicyFile::HTTPS && secure && url.getProtocol() != "https")
		return false;


	//Check if the header is explicitly allowed
	bool headerFound = false;
	string expression;
	for(list<string*>::const_iterator i = headers.begin();
			i != headers.end(); ++i)
	{
		expression = (**i);
		transform(expression.begin(), expression.end(), expression.begin(), ::tolower);
		if(expression == header || expression == "*")
		{
			headerFound = true;
			break;
		}
		//Match suffix wildcards
		else if(expression[expression.length()-1] == '*' &&
				header.substr(0, expression.length()-1) == expression.substr(0, expression.length()-1))
		{
			headerFound = true;
			break;
		}
	}
	if(!headerFound)
		return false;

	return true;
}
Example #8
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;
}