mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-05 03:15:07 -04:00
matches_run_origin, matches_script_origin
This commit is contained in:
parent
7937aef9e9
commit
e338f35a9e
@ -96,6 +96,19 @@ is_trusted() const {
|
|||||||
return _p3d_trusted;
|
return _p3d_trusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::get_matches_script_origin
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if this instance is allowed to be
|
||||||
|
// scripted by its embedding web page, false otherwise.
|
||||||
|
// This may not be known until the p3d file has been
|
||||||
|
// fully downloaded and opened.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline bool P3DInstance::
|
||||||
|
get_matches_script_origin() const {
|
||||||
|
return _matches_script_origin;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::is_started
|
// Function: P3DInstance::is_started
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -97,6 +97,8 @@ P3DInstance(P3D_request_ready_func *func,
|
|||||||
_instance_id = inst_mgr->get_unique_id();
|
_instance_id = inst_mgr->get_unique_id();
|
||||||
_has_log_basename = false;
|
_has_log_basename = false;
|
||||||
_hidden = (_fparams.lookup_token_int("hidden") != 0);
|
_hidden = (_fparams.lookup_token_int("hidden") != 0);
|
||||||
|
_matches_run_origin = true;
|
||||||
|
_matches_script_origin = false;
|
||||||
_allow_python_dev = false;
|
_allow_python_dev = false;
|
||||||
_keep_user_env = (_fparams.lookup_token_int("keep_user_env") != 0);
|
_keep_user_env = (_fparams.lookup_token_int("keep_user_env") != 0);
|
||||||
_auto_start = (_fparams.lookup_token_int("auto_start") != 0);
|
_auto_start = (_fparams.lookup_token_int("auto_start") != 0);
|
||||||
@ -296,6 +298,10 @@ P3DInstance::
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
set_p3d_url(const string &p3d_url) {
|
set_p3d_url(const string &p3d_url) {
|
||||||
|
// Save the last part of the URL as the p3d_basename, for reporting
|
||||||
|
// purposes or whatever.
|
||||||
|
determine_p3d_basename(p3d_url);
|
||||||
|
|
||||||
// Make a temporary file to receive the instance data.
|
// Make a temporary file to receive the instance data.
|
||||||
assert(_temp_p3d_filename == NULL);
|
assert(_temp_p3d_filename == NULL);
|
||||||
_temp_p3d_filename = new P3DTemporaryFile(".p3d");
|
_temp_p3d_filename = new P3DTemporaryFile(".p3d");
|
||||||
@ -331,6 +337,10 @@ set_p3d_url(const string &p3d_url) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int P3DInstance::
|
int P3DInstance::
|
||||||
make_p3d_stream(const string &p3d_url) {
|
make_p3d_stream(const string &p3d_url) {
|
||||||
|
// Save the last part of the URL as the p3d_basename, for reporting
|
||||||
|
// purposes or whatever.
|
||||||
|
determine_p3d_basename(p3d_url);
|
||||||
|
|
||||||
// Make a temporary file to receive the instance data.
|
// Make a temporary file to receive the instance data.
|
||||||
assert(_temp_p3d_filename == NULL);
|
assert(_temp_p3d_filename == NULL);
|
||||||
_temp_p3d_filename = new P3DTemporaryFile(".p3d");
|
_temp_p3d_filename = new P3DTemporaryFile(".p3d");
|
||||||
@ -365,33 +375,8 @@ make_p3d_stream(const string &p3d_url) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
set_p3d_filename(const string &p3d_filename) {
|
set_p3d_filename(const string &p3d_filename) {
|
||||||
if (!_fparams.get_p3d_filename().empty()) {
|
determine_p3d_basename(p3d_filename);
|
||||||
nout << "p3d_filename already set to: " << _fparams.get_p3d_filename()
|
priv_set_p3d_filename(p3d_filename);
|
||||||
<< ", trying to set to " << p3d_filename << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fparams.set_p3d_filename(p3d_filename);
|
|
||||||
_got_fparams = true;
|
|
||||||
|
|
||||||
_panda_script_object->set_float_property("instanceDownloadProgress", 1.0);
|
|
||||||
|
|
||||||
// Generate a special notification: onpluginload, indicating the
|
|
||||||
// plugin has read its parameters and is ready to be queried (even
|
|
||||||
// if Python has not yet started).
|
|
||||||
send_notify("onpluginload");
|
|
||||||
|
|
||||||
if (!_mf_reader.open_read(_fparams.get_p3d_filename())) {
|
|
||||||
nout << "Couldn't read " << _fparams.get_p3d_filename() << "\n";
|
|
||||||
set_failed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_p3d_signature()) {
|
|
||||||
mark_p3d_trusted();
|
|
||||||
} else {
|
|
||||||
mark_p3d_untrusted();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -515,40 +500,61 @@ set_browser_script_object(P3D_object *browser_script_object) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query the location hostname. We'll use this to limit access to
|
// Query the origin: protocol, hostname, and port. We'll use this to
|
||||||
// the scripting interfaces for a particular p3d file.
|
// limit access to the scripting interfaces for a particular p3d
|
||||||
_web_hostname = "";
|
// file.
|
||||||
|
_origin_protocol.clear();
|
||||||
|
_origin_hostname.clear();
|
||||||
|
_origin_port.clear();
|
||||||
if (_browser_script_object != NULL) {
|
if (_browser_script_object != NULL) {
|
||||||
P3D_object *location = P3D_OBJECT_GET_PROPERTY(_browser_script_object, "location");
|
P3D_object *location = P3D_OBJECT_GET_PROPERTY(_browser_script_object, "location");
|
||||||
if (location != NULL) {
|
if (location != NULL) {
|
||||||
P3D_object *hostname = P3D_OBJECT_GET_PROPERTY(location, "hostname");
|
|
||||||
if (hostname != NULL) {
|
|
||||||
int size = P3D_OBJECT_GET_STRING(hostname, NULL, 0);
|
|
||||||
char *buffer = new char[size];
|
|
||||||
P3D_OBJECT_GET_STRING(hostname, buffer, size);
|
|
||||||
_web_hostname = string(buffer, size);
|
|
||||||
delete [] buffer;
|
|
||||||
|
|
||||||
P3D_OBJECT_DECREF(hostname);
|
|
||||||
}
|
|
||||||
|
|
||||||
P3D_object *protocol = P3D_OBJECT_GET_PROPERTY(location, "protocol");
|
P3D_object *protocol = P3D_OBJECT_GET_PROPERTY(location, "protocol");
|
||||||
if (protocol != NULL) {
|
if (protocol != NULL) {
|
||||||
int size = P3D_OBJECT_GET_STRING(protocol, NULL, 0);
|
int size = P3D_OBJECT_GET_STRING(protocol, NULL, 0);
|
||||||
char *buffer = new char[size];
|
char *buffer = new char[size];
|
||||||
P3D_OBJECT_GET_STRING(protocol, buffer, size);
|
P3D_OBJECT_GET_STRING(protocol, buffer, size);
|
||||||
if (string(buffer, size) == "file:") {
|
_origin_protocol = string(buffer, size);
|
||||||
_web_hostname = "local";
|
|
||||||
}
|
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
P3D_OBJECT_DECREF(protocol);
|
P3D_OBJECT_DECREF(protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
P3D_object *hostname = P3D_OBJECT_GET_PROPERTY(location, "hostname");
|
||||||
|
if (hostname != NULL) {
|
||||||
|
int size = P3D_OBJECT_GET_STRING(hostname, NULL, 0);
|
||||||
|
char *buffer = new char[size];
|
||||||
|
P3D_OBJECT_GET_STRING(hostname, buffer, size);
|
||||||
|
_origin_hostname = string(buffer, size);
|
||||||
|
delete [] buffer;
|
||||||
|
P3D_OBJECT_DECREF(hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
P3D_object *port = P3D_OBJECT_GET_PROPERTY(location, "port");
|
||||||
|
if (port != NULL) {
|
||||||
|
int size = P3D_OBJECT_GET_STRING(port, NULL, 0);
|
||||||
|
char *buffer = new char[size];
|
||||||
|
P3D_OBJECT_GET_STRING(port, buffer, size);
|
||||||
|
_origin_port = string(buffer, size);
|
||||||
|
delete [] buffer;
|
||||||
|
P3D_OBJECT_DECREF(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_origin_port.empty()) {
|
||||||
|
// Maybe the actual URL doesn't include the port, in which
|
||||||
|
// case it is implicit.
|
||||||
|
if (_origin_protocol == "http:") {
|
||||||
|
_origin_port = "80";
|
||||||
|
} else if (_origin_protocol == "https:") {
|
||||||
|
_origin_port = "443";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
P3D_OBJECT_DECREF(location);
|
P3D_OBJECT_DECREF(location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nout << "_web_hostname is " << _web_hostname << "\n";
|
nout << "origin is " << _origin_protocol << "//" << _origin_hostname
|
||||||
|
<< ":" << _origin_port << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1254,6 +1260,247 @@ auth_finished_main_thread() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::priv_set_p3d_filename
|
||||||
|
// Access: Private
|
||||||
|
// Description: The private implementation of set_p3d_filename(),
|
||||||
|
// this does all the work except for updating
|
||||||
|
// p3d_basename. It is intended to be called
|
||||||
|
// internally, and might be passed a temporary filename.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
priv_set_p3d_filename(const string &p3d_filename) {
|
||||||
|
if (!_fparams.get_p3d_filename().empty()) {
|
||||||
|
nout << "p3d_filename already set to: " << _fparams.get_p3d_filename()
|
||||||
|
<< ", trying to set to " << p3d_filename << "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_fparams.set_p3d_filename(p3d_filename);
|
||||||
|
_got_fparams = true;
|
||||||
|
|
||||||
|
_panda_script_object->set_float_property("instanceDownloadProgress", 1.0);
|
||||||
|
|
||||||
|
// Generate a special notification: onpluginload, indicating the
|
||||||
|
// plugin has read its parameters and is ready to be queried (even
|
||||||
|
// if Python has not yet started).
|
||||||
|
send_notify("onpluginload");
|
||||||
|
|
||||||
|
if (!_mf_reader.open_read(_fparams.get_p3d_filename())) {
|
||||||
|
nout << "Couldn't read " << _fparams.get_p3d_filename() << "\n";
|
||||||
|
set_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_p3d_signature()) {
|
||||||
|
mark_p3d_trusted();
|
||||||
|
} else {
|
||||||
|
mark_p3d_untrusted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::determine_p3d_basename
|
||||||
|
// Access: Private
|
||||||
|
// Description: Determines _p3d_basename from the indicated URL.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
determine_p3d_basename(const string &p3d_url) {
|
||||||
|
string file_part = p3d_url;
|
||||||
|
size_t question = file_part.find('?');
|
||||||
|
if (question != string::npos) {
|
||||||
|
file_part = file_part.substr(0, question);
|
||||||
|
}
|
||||||
|
size_t slash = file_part.rfind('/');
|
||||||
|
if (slash != string::npos) {
|
||||||
|
file_part = file_part.substr(slash + 1);
|
||||||
|
}
|
||||||
|
_p3d_basename = file_part;
|
||||||
|
|
||||||
|
nout << "p3d_basename = " << _p3d_basename << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::check_matches_origin
|
||||||
|
// Access: Private
|
||||||
|
// Description: Returns true if the indicated origin_match string,
|
||||||
|
// one of either run_origin or script_origin from the
|
||||||
|
// p3d_info.xml file, matches the origin of the page
|
||||||
|
// that embedded the p3d file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstance::
|
||||||
|
check_matches_origin(const string &origin_match) {
|
||||||
|
// First, separate the string up at the semicolons.
|
||||||
|
size_t p = 0;
|
||||||
|
size_t semicolon = origin_match.find(';');
|
||||||
|
while (semicolon != string::npos) {
|
||||||
|
if (check_matches_origin_one(origin_match.substr(p, semicolon - p))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p = semicolon + 1;
|
||||||
|
semicolon = origin_match.find(';', p);
|
||||||
|
}
|
||||||
|
if (check_matches_origin_one(origin_match.substr(p))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It doesn't match any of the semicolon-delimited strings within
|
||||||
|
// origin_match.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::check_matches_origin_one
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called for each semicolon-delimited string within
|
||||||
|
// origin_match passed to check_matches_origin().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstance::
|
||||||
|
check_matches_origin_one(const string &origin_match) {
|
||||||
|
// Do we have a protocol?
|
||||||
|
size_t p = 0;
|
||||||
|
size_t colon = origin_match.find(':');
|
||||||
|
if (colon + 1 < origin_match.length() && origin_match[colon + 1] == '/') {
|
||||||
|
// Yes. It should therefore match the protocol we have in the origin.
|
||||||
|
string protocol = origin_match.substr(0, colon + 1);
|
||||||
|
if (!check_matches_component(_origin_protocol, protocol)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
p = colon + 2;
|
||||||
|
// We'll support both http://hostname and http:/hostname, in case
|
||||||
|
// the user is sloppy.
|
||||||
|
if (p < origin_match.length() && origin_match[p] == '/') {
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
colon = origin_match.find(':', p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we have a port?
|
||||||
|
if (colon < origin_match.length() && isdigit(origin_match[colon + 1])) {
|
||||||
|
// Yes. It should therefore match the port we have in the origin.
|
||||||
|
string port = origin_match.substr(colon + 1);
|
||||||
|
if (!check_matches_component(_origin_port, port)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The hostname should also match what we have in the origin.
|
||||||
|
string hostname = origin_match.substr(p, colon - p);
|
||||||
|
if (!check_matches_hostname(_origin_hostname, hostname)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything matches.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::check_matches_hostname
|
||||||
|
// Access: Private
|
||||||
|
// Description: Matches the hostname of check_matches_origin:
|
||||||
|
// the individual components of the hostname are matched
|
||||||
|
// independently, with '**.' allowed at the beginning to
|
||||||
|
// indicate zero or more prefixes. Returns true on
|
||||||
|
// match, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstance::
|
||||||
|
check_matches_hostname(const string &orig, const string &match) {
|
||||||
|
// First, separate both strings up at the dots.
|
||||||
|
vector<string> orig_components;
|
||||||
|
separate_components(orig_components, orig);
|
||||||
|
|
||||||
|
vector<string> match_components;
|
||||||
|
separate_components(match_components, match);
|
||||||
|
|
||||||
|
// If the first component of match is "**", it means we accept any
|
||||||
|
// number, zero or more, of components at the beginning of the
|
||||||
|
// hostname.
|
||||||
|
if (!match_components.empty() && match_components[0] == "**") {
|
||||||
|
// Remove the leading "**"
|
||||||
|
match_components.erase(match_components.begin());
|
||||||
|
// Then remove any extra components from the beginning of
|
||||||
|
// orig_components; we won't need to check them.
|
||||||
|
if (orig_components.size() > match_components.size()) {
|
||||||
|
size_t num_to_remove = orig_components.size() - match_components.size();
|
||||||
|
orig_components.erase(orig_components.begin(), orig_components.begin() + num_to_remove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now match the remaining components one-to-one.
|
||||||
|
if (match_components.size() != orig_components.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string>::const_iterator p = orig_components.begin();
|
||||||
|
vector<string>::const_iterator p2 = match_components.begin();
|
||||||
|
|
||||||
|
while (p != orig_components.end()) {
|
||||||
|
assert(p2 != match_components.end());
|
||||||
|
if (!check_matches_component(*p, *p2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
++p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(p2 == match_components.end());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::separate_components
|
||||||
|
// Access: Private
|
||||||
|
// Description: Separates the indicated hostname into its components
|
||||||
|
// at the dots.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DInstance::
|
||||||
|
separate_components(vector<string> &components, const string &str) {
|
||||||
|
size_t p = 0;
|
||||||
|
size_t dot = str.find('.');
|
||||||
|
while (dot != string::npos) {
|
||||||
|
components.push_back(str.substr(p, dot - p));
|
||||||
|
p = dot + 1;
|
||||||
|
dot = str.find('.', p);
|
||||||
|
}
|
||||||
|
components.push_back(str.substr(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstance::check_matches_component
|
||||||
|
// Access: Private
|
||||||
|
// Description: Matches a single component of check_matches_origin:
|
||||||
|
// either protocol or port, or a single component of the
|
||||||
|
// hostname. Case-insensitive, and supports the '*'
|
||||||
|
// wildcard operator to match the entire component.
|
||||||
|
// Returns true on match, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstance::
|
||||||
|
check_matches_component(const string &orig, const string &match) {
|
||||||
|
if (match == "*") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case-insensitive compare.
|
||||||
|
if (orig.length() != match.length()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string::const_iterator p = orig.begin();
|
||||||
|
string::const_iterator p2 = match.begin();
|
||||||
|
|
||||||
|
while (p != orig.end()) {
|
||||||
|
assert(p2 != match.end());
|
||||||
|
if (tolower(*p) != tolower(*p2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
++p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(p2 == match.end());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::check_p3d_signature
|
// Function: P3DInstance::check_p3d_signature
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1431,6 +1678,16 @@ scan_app_desc_file(TiXmlDocument *doc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *run_origin = xconfig->Attribute("run_origin");
|
||||||
|
if (run_origin != NULL) {
|
||||||
|
_matches_run_origin = check_matches_origin(run_origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *script_origin = xconfig->Attribute("script_origin");
|
||||||
|
if (script_origin != NULL) {
|
||||||
|
_matches_script_origin = check_matches_origin(script_origin);
|
||||||
|
}
|
||||||
|
|
||||||
int allow_python_dev = 0;
|
int allow_python_dev = 0;
|
||||||
if (xconfig->QueryIntAttribute("allow_python_dev", &allow_python_dev) == TIXML_SUCCESS) {
|
if (xconfig->QueryIntAttribute("allow_python_dev", &allow_python_dev) == TIXML_SUCCESS) {
|
||||||
_allow_python_dev = (allow_python_dev != 0);
|
_allow_python_dev = (allow_python_dev != 0);
|
||||||
@ -1447,6 +1704,16 @@ scan_app_desc_file(TiXmlDocument *doc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nout << "_matches_run_origin = " << _matches_run_origin << "\n";
|
||||||
|
nout << "_matches_script_origin = " << _matches_script_origin << "\n";
|
||||||
|
|
||||||
|
if (inst_mgr->get_trusted_environment()) {
|
||||||
|
// If we're in a trusted environment, it is as if the origin
|
||||||
|
// always matches.
|
||||||
|
_matches_run_origin = true;
|
||||||
|
_matches_script_origin = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_auth_button_approved) {
|
if (_auth_button_approved) {
|
||||||
// But finally, if the user has already clicked through the red
|
// But finally, if the user has already clicked through the red
|
||||||
// "auth" button, no need to present him/her with another green
|
// "auth" button, no need to present him/her with another green
|
||||||
@ -1475,6 +1742,13 @@ scan_app_desc_file(TiXmlDocument *doc) {
|
|||||||
|
|
||||||
xrequires = xrequires->NextSiblingElement("requires");
|
xrequires = xrequires->NextSiblingElement("requires");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_matches_run_origin) {
|
||||||
|
nout << "Cannot run " << _p3d_basename << " from origin "
|
||||||
|
<< _origin_protocol << "//" << _origin_hostname
|
||||||
|
<< ":" << _origin_port << "\n";
|
||||||
|
set_failed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1624,6 +1898,9 @@ handle_notify_request(const string &message) {
|
|||||||
// Once Python is up and running, we can get the actual main
|
// Once Python is up and running, we can get the actual main
|
||||||
// object from the Python side, and merge it with our own.
|
// object from the Python side, and merge it with our own.
|
||||||
|
|
||||||
|
// But only if this web page is allowed to call our scripting
|
||||||
|
// functions.
|
||||||
|
if (_matches_script_origin) {
|
||||||
TiXmlDocument *doc = new TiXmlDocument;
|
TiXmlDocument *doc = new TiXmlDocument;
|
||||||
TiXmlElement *xcommand = new TiXmlElement("command");
|
TiXmlElement *xcommand = new TiXmlElement("command");
|
||||||
xcommand->SetAttribute("cmd", "pyobj");
|
xcommand->SetAttribute("cmd", "pyobj");
|
||||||
@ -1647,6 +1924,7 @@ handle_notify_request(const string &message) {
|
|||||||
_panda_script_object->set_pyobj(result);
|
_panda_script_object->set_pyobj(result);
|
||||||
P3D_OBJECT_DECREF(result);
|
P3D_OBJECT_DECREF(result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_panda_script_object->set_string_property("status", "starting");
|
_panda_script_object->set_string_property("status", "starting");
|
||||||
|
|
||||||
@ -2639,7 +2917,7 @@ download_finished(bool success) {
|
|||||||
P3DFileDownload::download_finished(success);
|
P3DFileDownload::download_finished(success);
|
||||||
if (success) {
|
if (success) {
|
||||||
// We've successfully downloaded the instance data.
|
// We've successfully downloaded the instance data.
|
||||||
_inst->set_p3d_filename(get_filename());
|
_inst->priv_set_p3d_filename(get_filename());
|
||||||
} else {
|
} else {
|
||||||
// Oops, no joy on the instance data.
|
// Oops, no joy on the instance data.
|
||||||
_inst->set_failed();
|
_inst->set_failed();
|
||||||
|
@ -98,6 +98,7 @@ public:
|
|||||||
bool get_packages_failed() const;
|
bool get_packages_failed() const;
|
||||||
|
|
||||||
inline bool is_trusted() const;
|
inline bool is_trusted() const;
|
||||||
|
inline bool get_matches_script_origin() const;
|
||||||
int start_download(P3DDownload *download, bool add_request = true);
|
int start_download(P3DDownload *download, bool add_request = true);
|
||||||
inline bool is_started() const;
|
inline bool is_started() const;
|
||||||
inline bool is_failed() const;
|
inline bool is_failed() const;
|
||||||
@ -155,6 +156,15 @@ private:
|
|||||||
IT_num_image_types, // Not a real value
|
IT_num_image_types, // Not a real value
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void priv_set_p3d_filename(const string &p3d_filename);
|
||||||
|
void determine_p3d_basename(const string &p3d_url);
|
||||||
|
|
||||||
|
bool check_matches_origin(const string &origin_match);
|
||||||
|
bool check_matches_origin_one(const string &origin_match);
|
||||||
|
bool check_matches_hostname(const string &orig, const string &match);
|
||||||
|
void separate_components(vector<string> &components, const string &str);
|
||||||
|
bool check_matches_component(const string &orig, const string &match);
|
||||||
|
|
||||||
bool check_p3d_signature();
|
bool check_p3d_signature();
|
||||||
void mark_p3d_untrusted();
|
void mark_p3d_untrusted();
|
||||||
void mark_p3d_trusted();
|
void mark_p3d_trusted();
|
||||||
@ -193,7 +203,10 @@ private:
|
|||||||
P3D_request_ready_func *_func;
|
P3D_request_ready_func *_func;
|
||||||
P3D_object *_browser_script_object;
|
P3D_object *_browser_script_object;
|
||||||
P3DMainObject *_panda_script_object;
|
P3DMainObject *_panda_script_object;
|
||||||
string _web_hostname;
|
string _p3d_basename;
|
||||||
|
string _origin_protocol;
|
||||||
|
string _origin_hostname;
|
||||||
|
string _origin_port;
|
||||||
|
|
||||||
P3DTemporaryFile *_temp_p3d_filename;
|
P3DTemporaryFile *_temp_p3d_filename;
|
||||||
|
|
||||||
@ -234,6 +247,8 @@ private:
|
|||||||
string _log_basename;
|
string _log_basename;
|
||||||
bool _has_log_basename;
|
bool _has_log_basename;
|
||||||
bool _hidden;
|
bool _hidden;
|
||||||
|
bool _matches_run_origin;
|
||||||
|
bool _matches_script_origin;
|
||||||
bool _allow_python_dev;
|
bool _allow_python_dev;
|
||||||
bool _keep_user_env;
|
bool _keep_user_env;
|
||||||
bool _auto_start;
|
bool _auto_start;
|
||||||
@ -302,6 +317,7 @@ private:
|
|||||||
friend class P3DSession;
|
friend class P3DSession;
|
||||||
friend class P3DAuthSession;
|
friend class P3DAuthSession;
|
||||||
friend class ImageDownload;
|
friend class ImageDownload;
|
||||||
|
friend class InstanceDownload;
|
||||||
friend class P3DWindowParams;
|
friend class P3DWindowParams;
|
||||||
friend class P3DPackage;
|
friend class P3DPackage;
|
||||||
};
|
};
|
||||||
|
@ -322,6 +322,9 @@ call_play(P3D_object *params[], int num_params) {
|
|||||||
return inst_mgr->new_bool_object(false);
|
return inst_mgr->new_bool_object(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I guess there's no harm in allowing JavaScript to call play(),
|
||||||
|
// with or without explicit scripting authorization.
|
||||||
|
|
||||||
if (!_inst->is_trusted()) {
|
if (!_inst->is_trusted()) {
|
||||||
// Requires authorization. We allow this only once; beyond that,
|
// Requires authorization. We allow this only once; beyond that,
|
||||||
// and you're only annoying the user.
|
// and you're only annoying the user.
|
||||||
@ -352,6 +355,12 @@ call_read_game_log(P3D_object *params[], int num_params) {
|
|||||||
return inst_mgr->new_undefined_object();
|
return inst_mgr->new_undefined_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_inst->get_matches_script_origin()) {
|
||||||
|
// If you're not allowed to be scripting us, you can't query the
|
||||||
|
// game log either. (But you can query the system log.)
|
||||||
|
return inst_mgr->new_undefined_object();
|
||||||
|
}
|
||||||
|
|
||||||
P3DSession *session = _inst->get_session();
|
P3DSession *session = _inst->get_session();
|
||||||
if (session == NULL) {
|
if (session == NULL) {
|
||||||
return inst_mgr->new_undefined_object();
|
return inst_mgr->new_undefined_object();
|
||||||
|
@ -154,6 +154,11 @@ get_property(const string &property) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool P3DPythonObject::
|
bool P3DPythonObject::
|
||||||
set_property(const string &property, bool needs_response, P3D_object *value) {
|
set_property(const string &property, bool needs_response, P3D_object *value) {
|
||||||
|
if (!_session->get_matches_script_origin()) {
|
||||||
|
// If you can't be scripting us, you can't be setting properties either.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool bresult = !needs_response;
|
bool bresult = !needs_response;
|
||||||
|
|
||||||
P3D_object *params[2];
|
P3D_object *params[2];
|
||||||
@ -234,6 +239,11 @@ has_method(const string &method_name) {
|
|||||||
P3D_object *P3DPythonObject::
|
P3D_object *P3DPythonObject::
|
||||||
call(const string &method_name, bool needs_response,
|
call(const string &method_name, bool needs_response,
|
||||||
P3D_object *params[], int num_params) {
|
P3D_object *params[], int num_params) {
|
||||||
|
if (!_session->get_matches_script_origin()) {
|
||||||
|
// If you can't be scripting us, you can't be calling methods.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
TiXmlDocument *doc = new TiXmlDocument;
|
TiXmlDocument *doc = new TiXmlDocument;
|
||||||
TiXmlElement *xcommand = new TiXmlElement("command");
|
TiXmlElement *xcommand = new TiXmlElement("command");
|
||||||
xcommand->SetAttribute("cmd", "pyobj");
|
xcommand->SetAttribute("cmd", "pyobj");
|
||||||
|
@ -37,6 +37,18 @@ get_log_pathname() const {
|
|||||||
return _log_pathname;
|
return _log_pathname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSession::get_matches_script_origin
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if the instances of this session are
|
||||||
|
// allowed to be scripted by its embedding web page,
|
||||||
|
// false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline bool P3DSession::
|
||||||
|
get_matches_script_origin() const {
|
||||||
|
return _matches_script_origin;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DSession::get_num_instances
|
// Function: P3DSession::get_num_instances
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -56,6 +56,7 @@ P3DSession(P3DInstance *inst) {
|
|||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
_session_id = inst_mgr->get_unique_id();
|
_session_id = inst_mgr->get_unique_id();
|
||||||
_session_key = inst->get_session_key();
|
_session_key = inst->get_session_key();
|
||||||
|
_matches_script_origin = inst->get_matches_script_origin();
|
||||||
_keep_user_env = false;
|
_keep_user_env = false;
|
||||||
_failed = false;
|
_failed = false;
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ public:
|
|||||||
|
|
||||||
inline const string &get_session_key() const;
|
inline const string &get_session_key() const;
|
||||||
inline const string &get_log_pathname() const;
|
inline const string &get_log_pathname() const;
|
||||||
|
inline bool get_matches_script_origin() const;
|
||||||
|
|
||||||
void start_instance(P3DInstance *inst);
|
void start_instance(P3DInstance *inst);
|
||||||
void terminate_instance(P3DInstance *inst);
|
void terminate_instance(P3DInstance *inst);
|
||||||
@ -93,6 +94,7 @@ private:
|
|||||||
string _log_pathname;
|
string _log_pathname;
|
||||||
string _python_root_dir;
|
string _python_root_dir;
|
||||||
string _start_dir;
|
string _start_dir;
|
||||||
|
bool _matches_script_origin;
|
||||||
bool _keep_user_env;
|
bool _keep_user_env;
|
||||||
bool _failed;
|
bool _failed;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user