getting somewhere
This commit is contained in:
parent
040604f212
commit
54c3e34f6e
|
|
@ -25,6 +25,7 @@
|
|||
p3d_lock.h p3d_plugin.h \
|
||||
p3d_plugin_config.h \
|
||||
p3d_plugin_common.h \
|
||||
p3dAuthSession.h p3dAuthSession.I \
|
||||
p3dBoolObject.h \
|
||||
p3dConcreteSequence.h \
|
||||
p3dConcreteStruct.h \
|
||||
|
|
@ -57,6 +58,7 @@
|
|||
|
||||
#define INCLUDED_SOURCES \
|
||||
p3d_plugin.cxx \
|
||||
p3dAuthSession.cxx \
|
||||
p3dBoolObject.cxx \
|
||||
p3dConcreteSequence.cxx \
|
||||
p3dConcreteStruct.cxx \
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "p3dCert.h"
|
||||
#include "wx/cmdline.h"
|
||||
#include "wx/filename.h"
|
||||
|
||||
#ifdef __WXMAC__
|
||||
#include <Carbon/Carbon.h>
|
||||
|
|
@ -85,6 +86,7 @@ IMPLEMENT_APP(P3DCertApp)
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DCertApp::
|
||||
OnInit() {
|
||||
cerr << "OnInit\n";
|
||||
// call the base class initialization method, currently it only parses a
|
||||
// few common command-line options but it could be do more in the future
|
||||
if (!wxApp::OnInit()) {
|
||||
|
|
@ -103,8 +105,9 @@ OnInit() {
|
|||
SetFrontProcess(&psn);
|
||||
#endif
|
||||
|
||||
AuthDialog *dialog = new AuthDialog(_cert_filename, _ca_filename);
|
||||
AuthDialog *dialog = new AuthDialog(_cert_filename, _cert_dir);
|
||||
SetTopWindow(dialog);
|
||||
cerr << "got dialog " << dialog << "\n";
|
||||
dialog->Show(true);
|
||||
|
||||
// Return true to enter the main loop and wait for user input.
|
||||
|
|
@ -132,7 +135,7 @@ OnInitCmdLine(wxCmdLineParser &parser) {
|
|||
bool P3DCertApp::
|
||||
OnCmdLineParsed(wxCmdLineParser &parser) {
|
||||
_cert_filename = parser.GetParam(0);
|
||||
_ca_filename = parser.GetParam(1);
|
||||
_cert_dir = parser.GetParam(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -151,16 +154,19 @@ END_EVENT_TABLE()
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AuthDialog::
|
||||
AuthDialog(const wxString &cert_filename, const wxString &ca_filename) :
|
||||
wxDialog(NULL, wxID_ANY, _T("New Panda3D Application"), wxDefaultPosition)
|
||||
AuthDialog(const wxString &cert_filename, const wxString &cert_dir) :
|
||||
wxDialog(NULL, wxID_ANY, _T("New Panda3D Application"), wxDefaultPosition),
|
||||
_cert_dir(cert_dir)
|
||||
{
|
||||
_view_cert_dialog = NULL;
|
||||
|
||||
_cert = NULL;
|
||||
_stack = NULL;
|
||||
_verify_result = -1;
|
||||
|
||||
read_cert_file(cert_filename);
|
||||
get_common_name();
|
||||
verify_cert(ca_filename);
|
||||
verify_cert();
|
||||
layout();
|
||||
}
|
||||
|
||||
|
|
@ -171,6 +177,10 @@ AuthDialog(const wxString &cert_filename, const wxString &ca_filename) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
AuthDialog::
|
||||
~AuthDialog() {
|
||||
if (_view_cert_dialog != NULL) {
|
||||
_view_cert_dialog->Destroy();
|
||||
}
|
||||
|
||||
if (_cert != NULL) {
|
||||
X509_free(_cert);
|
||||
_cert = NULL;
|
||||
|
|
@ -189,7 +199,7 @@ AuthDialog::
|
|||
void AuthDialog::
|
||||
run_clicked(wxCommandEvent &event) {
|
||||
cerr << "run\n";
|
||||
Destroy();
|
||||
approve_cert();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -200,6 +210,11 @@ run_clicked(wxCommandEvent &event) {
|
|||
void AuthDialog::
|
||||
view_cert_clicked(wxCommandEvent &event) {
|
||||
cerr << "view cert\n";
|
||||
if (_view_cert_dialog != NULL) {
|
||||
_view_cert_dialog->Destroy();
|
||||
}
|
||||
_view_cert_dialog = new ViewCertDialog(this, _cert);
|
||||
_view_cert_dialog->Show();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -213,6 +228,41 @@ cancel_clicked(wxCommandEvent &event) {
|
|||
Destroy();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AuthDialog::approve_cert
|
||||
// Access: Public
|
||||
// Description: Writes the certificate into the _cert_dir, so
|
||||
// that it will be found by the P3DInstanceManager and
|
||||
// known to be approved.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AuthDialog::
|
||||
approve_cert() {
|
||||
assert(_cert != NULL);
|
||||
|
||||
// Make sure the directory exists.
|
||||
wxFileName::Mkdir(_cert_dir, 0777, wxPATH_MKDIR_FULL);
|
||||
|
||||
// Look for an unused filename.
|
||||
wxString pathname;
|
||||
int i = 1;
|
||||
while (true) {
|
||||
pathname.Printf(wxT("%s/p%d.crt"), _cert_dir.c_str(), i);
|
||||
if (!wxFileName::FileExists(pathname)) {
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
// Sure, there's a slight race condition right now: another process
|
||||
// might attempt to create the same filename. So what.
|
||||
FILE *fp = fopen(pathname.mb_str(), "w");
|
||||
if (fp != NULL) {
|
||||
PEM_write_X509(fp, _cert);
|
||||
fclose(fp);
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AuthDialog::read_cert_file
|
||||
// Access: Private
|
||||
|
|
@ -246,7 +296,7 @@ read_cert_file(const wxString &cert_filename) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AuthDialog::get_common_name
|
||||
// Access: Public
|
||||
// Access: Private
|
||||
// Description: Extracts the common_name from the certificate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AuthDialog::
|
||||
|
|
@ -286,12 +336,12 @@ get_common_name() {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AuthDialog::verify_cert
|
||||
// Access: Public
|
||||
// Access: Private
|
||||
// Description: Checks whether the certificate is valid by the chain
|
||||
// and initializes _verify_status accordingly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AuthDialog::
|
||||
verify_cert(const wxString &ca_filename) {
|
||||
verify_cert() {
|
||||
if (_cert == NULL) {
|
||||
_verify_result = -1;
|
||||
return;
|
||||
|
|
@ -301,17 +351,25 @@ verify_cert(const wxString &ca_filename) {
|
|||
X509_STORE *store = X509_STORE_new();
|
||||
X509_STORE_set_default_paths(store);
|
||||
|
||||
// Read the trusted certificates.
|
||||
FILE *fp = fopen(ca_filename.mb_str(), "r");
|
||||
if (fp == NULL) {
|
||||
cerr << "Couldn't read " << ca_filename << "\n";
|
||||
} else {
|
||||
X509 *c = PEM_read_X509(fp, NULL, NULL, (void *)"");
|
||||
while (c != NULL) {
|
||||
X509_STORE_add_cert(store, c);
|
||||
c = PEM_read_X509(fp, NULL, NULL, (void *)"");
|
||||
// Find the ca-bundle.crt.
|
||||
char *p3dcert_root = getenv("P3DCERT_ROOT");
|
||||
if (p3dcert_root != NULL) {
|
||||
wxString ca_filename = p3dcert_root;
|
||||
ca_filename += "/ca-bundle.crt";
|
||||
|
||||
// Read the trusted certificates.
|
||||
cerr << "Reading " << ca_filename.mb_str() << "\n";;
|
||||
FILE *fp = fopen(ca_filename.mb_str(), "r");
|
||||
if (fp == NULL) {
|
||||
cerr << "Couldn't read " << ca_filename.mb_str() << "\n";
|
||||
} else {
|
||||
X509 *c = PEM_read_X509(fp, NULL, NULL, (void *)"");
|
||||
while (c != NULL) {
|
||||
X509_STORE_add_cert(store, c);
|
||||
c = PEM_read_X509(fp, NULL, NULL, (void *)"");
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// Create the X509_STORE_CTX for verifying the cert and chain.
|
||||
|
|
@ -430,3 +488,102 @@ get_text(wxString &header, wxString &text) {
|
|||
text.Printf(generic_error_cert_text, _verify_result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The event table for ViewCertDialog.
|
||||
BEGIN_EVENT_TABLE(ViewCertDialog, wxDialog)
|
||||
EVT_BUTTON(wxID_OK, ViewCertDialog::run_clicked)
|
||||
EVT_BUTTON(wxID_CANCEL, ViewCertDialog::cancel_clicked)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ViewCertDialog::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ViewCertDialog::
|
||||
ViewCertDialog(AuthDialog *auth_dialog, X509 *cert) :
|
||||
wxDialog(NULL, wxID_ANY, _T("View Certificate"), wxDefaultPosition),
|
||||
_auth_dialog(auth_dialog),
|
||||
_cert(cert)
|
||||
{
|
||||
layout();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ViewCertDialog::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ViewCertDialog::
|
||||
~ViewCertDialog() {
|
||||
if (_auth_dialog != NULL) {
|
||||
_auth_dialog->_view_cert_dialog = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ViewCertDialog::run_clicked
|
||||
// Access: Public
|
||||
// Description: The user clicks the "Run" button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ViewCertDialog::
|
||||
run_clicked(wxCommandEvent &event) {
|
||||
cerr << "run\n";
|
||||
if (_auth_dialog != NULL){
|
||||
_auth_dialog->approve_cert();
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ViewCertDialog::run_clicked
|
||||
// Access: Public
|
||||
// Description: The user clicks the "Cancel" button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ViewCertDialog::
|
||||
cancel_clicked(wxCommandEvent &event) {
|
||||
cerr << "cancel\n";
|
||||
Destroy();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ViewCertDialog::layout
|
||||
// Access: Private
|
||||
// Description: Arranges the text and controls within the dialog.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ViewCertDialog::
|
||||
layout() {
|
||||
// Format the certificate text for display in the dialog.
|
||||
assert(_cert != NULL);
|
||||
|
||||
BIO *mbio = BIO_new(BIO_s_mem());
|
||||
X509_print(mbio, _cert);
|
||||
|
||||
char *pp;
|
||||
long pp_size = BIO_get_mem_data(mbio, &pp);
|
||||
wxString cert_body(pp, wxConvUTF8, pp_size);
|
||||
BIO_free(mbio);
|
||||
|
||||
wxPanel *panel = new wxPanel(this);
|
||||
wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxStaticText *text1 = new wxStaticText
|
||||
(panel, wxID_ANY, cert_body, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
vsizer->Add(text1, 0, wxCENTER | wxALL, 10);
|
||||
|
||||
// Create the run / cancel buttons.
|
||||
wxBoxSizer *bsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxButton *run_button = new wxButton(panel, wxID_OK, _T("Run"));
|
||||
bsizer->Add(run_button, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
wxButton *cancel_button = new wxButton(panel, wxID_CANCEL, _T("Cancel"));
|
||||
bsizer->Add(cancel_button, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
vsizer->Add(bsizer, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
panel->SetSizer(vsizer);
|
||||
panel->SetAutoLayout(true);
|
||||
vsizer->Fit(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include <stdio.h>
|
||||
using namespace std;
|
||||
|
||||
class ViewCertDialog;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : P3DCertApp
|
||||
// Description : This is the wxApp that drives this application.
|
||||
|
|
@ -39,7 +41,7 @@ public:
|
|||
|
||||
private:
|
||||
wxString _cert_filename;
|
||||
wxString _ca_filename;
|
||||
wxString _cert_dir;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -54,25 +56,31 @@ private:
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class AuthDialog : public wxDialog {
|
||||
public:
|
||||
AuthDialog(const wxString &cert_filename, const wxString &ca_filename);
|
||||
AuthDialog(const wxString &cert_filename, const wxString &cert_dir);
|
||||
virtual ~AuthDialog();
|
||||
|
||||
void run_clicked(wxCommandEvent &event);
|
||||
void view_cert_clicked(wxCommandEvent &event);
|
||||
void cancel_clicked(wxCommandEvent &event);
|
||||
|
||||
void approve_cert();
|
||||
|
||||
private:
|
||||
void read_cert_file(const wxString &cert_filename);
|
||||
void get_common_name();
|
||||
void verify_cert(const wxString &ca_filename);
|
||||
void verify_cert();
|
||||
|
||||
void layout();
|
||||
void get_text(wxString &header, wxString &text);
|
||||
|
||||
public:
|
||||
ViewCertDialog *_view_cert_dialog;
|
||||
|
||||
private:
|
||||
// any class wishing to process wxWidgets events must use this macro
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
wxString _cert_dir;
|
||||
X509 *_cert;
|
||||
STACK *_stack;
|
||||
|
||||
|
|
@ -80,4 +88,27 @@ private:
|
|||
int _verify_result;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ViewCertDialog
|
||||
// Description : This is the detailed view of the particular
|
||||
// certificate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class ViewCertDialog : public wxDialog {
|
||||
public:
|
||||
ViewCertDialog(AuthDialog *auth_dialog, X509 *cert);
|
||||
virtual ~ViewCertDialog();
|
||||
|
||||
void run_clicked(wxCommandEvent &event);
|
||||
void cancel_clicked(wxCommandEvent &event);
|
||||
|
||||
private:
|
||||
void layout();
|
||||
|
||||
private:
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
AuthDialog *_auth_dialog;
|
||||
X509 *_cert;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ P3DInstance(P3D_request_ready_func *func,
|
|||
_got_fparams = false;
|
||||
_got_wparams = false;
|
||||
_p3d_trusted = false;
|
||||
_p3dcert_package = NULL;
|
||||
|
||||
_fparams.set_tokens(tokens, num_tokens);
|
||||
_fparams.set_args(argc, argv);
|
||||
|
|
@ -96,6 +97,7 @@ P3DInstance(P3D_request_ready_func *func,
|
|||
_auto_start = false;
|
||||
_auth_button_approved = false;
|
||||
_session = NULL;
|
||||
_auth_session = NULL;
|
||||
_panda3d = NULL;
|
||||
_splash_window = NULL;
|
||||
_instance_window_opened = false;
|
||||
|
|
@ -140,6 +142,12 @@ P3DInstance::
|
|||
~P3DInstance() {
|
||||
assert(_session == NULL);
|
||||
|
||||
if (_auth_session != NULL) {
|
||||
_auth_session->shutdown(false);
|
||||
unref_delete(_auth_session);
|
||||
_auth_session = NULL;
|
||||
}
|
||||
|
||||
P3D_OBJECT_XDECREF(_browser_script_object);
|
||||
|
||||
nout << "panda_script_object ref = "
|
||||
|
|
@ -159,6 +167,11 @@ P3DInstance::
|
|||
_image_package = NULL;
|
||||
}
|
||||
|
||||
if (_p3dcert_package != NULL) {
|
||||
_p3dcert_package->remove_instance(this);
|
||||
_p3dcert_package = NULL;
|
||||
}
|
||||
|
||||
if (_splash_window != NULL) {
|
||||
delete _splash_window;
|
||||
_splash_window = NULL;
|
||||
|
|
@ -929,20 +942,18 @@ splash_button_clicked_main_thread() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
auth_button_clicked() {
|
||||
// Here's where we need to invoke the authorization program.
|
||||
cerr << "auth clicked\n";
|
||||
|
||||
// After the authorization program has returned, check the signature
|
||||
// again.
|
||||
if (check_p3d_signature()) {
|
||||
// Set this flag to indicate that the user has clicked on the red
|
||||
// "auth" button an successfully approved the application. This
|
||||
// eliminates the need to click on the green "start" button.
|
||||
_auth_button_approved = true;
|
||||
mark_p3d_trusted();
|
||||
} else {
|
||||
mark_p3d_untrusted();
|
||||
// Delete the previous session and create a new one.
|
||||
if (_auth_session != NULL) {
|
||||
_auth_session->shutdown(false);
|
||||
unref_delete(_auth_session);
|
||||
_auth_session = NULL;
|
||||
}
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
_auth_session = inst_mgr->authorize_instance(this);
|
||||
_auth_session->ref();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -962,6 +973,49 @@ play_button_clicked() {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::auth_finished_sub_thread
|
||||
// Access: Public
|
||||
// Description: Called by the P3DAuthSession code in a sub-thread
|
||||
// when the auth dialog exits (for instance, because the
|
||||
// user approved the certificate, or cancelled).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
auth_finished_sub_thread() {
|
||||
TiXmlDocument *doc = new TiXmlDocument;
|
||||
TiXmlElement *xrequest = new TiXmlElement("request");
|
||||
xrequest->SetAttribute("rtype", "notify");
|
||||
xrequest->SetAttribute("message", "authfinished");
|
||||
doc->LinkEndChild(xrequest);
|
||||
|
||||
add_raw_request(doc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::auth_finished_main_thread
|
||||
// Access: Public
|
||||
// Description: Called only in the main thread, indirectly from
|
||||
// auth_finished_sub_thread(), as the result of
|
||||
// the user closing the auth dialog.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
auth_finished_main_thread() {
|
||||
// After the authorization program has returned, check the signature
|
||||
// again.
|
||||
if (check_p3d_signature()) {
|
||||
// Set this flag to indicate that the user has clicked on the red
|
||||
// "auth" button and successfully approved the application's
|
||||
// certificate. This eliminates the need to click on the green
|
||||
// "start" button.
|
||||
_auth_button_approved = true;
|
||||
mark_p3d_trusted();
|
||||
|
||||
} else {
|
||||
// Still untrusted.
|
||||
mark_p3d_untrusted();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::check_p3d_signature
|
||||
// Access: Private
|
||||
|
|
@ -984,10 +1038,7 @@ check_p3d_signature() {
|
|||
// is complete.
|
||||
return true;
|
||||
|
||||
nout << "check_p3d_signature\n";
|
||||
int num_signatures = _mf_reader.get_num_signatures();
|
||||
nout << "file has " << num_signatures << " signatures\n";
|
||||
|
||||
for (int i = 0; i < num_signatures; ++i) {
|
||||
const P3DMultifileReader::CertChain &chain = _mf_reader.get_signature(i);
|
||||
|
||||
|
|
@ -1019,6 +1070,27 @@ void P3DInstance::
|
|||
mark_p3d_untrusted() {
|
||||
// Failed test.
|
||||
nout << "p3d untrusted\n";
|
||||
|
||||
if (_p3dcert_package == NULL) {
|
||||
// We have to go download this package.
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
P3DHost *host = inst_mgr->get_host(PANDA_PACKAGE_HOST_URL);
|
||||
_p3dcert_package = host->get_package("p3dcert", "");
|
||||
if (_p3dcert_package != NULL) {
|
||||
_p3dcert_package->add_instance(this);
|
||||
}
|
||||
|
||||
// When the package finishes downloading, we will come back here.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_p3dcert_package->get_ready()) {
|
||||
// Wait for it to finish downloading.
|
||||
return;
|
||||
}
|
||||
|
||||
// OK, we've got the authorization program; we can put up the red
|
||||
// button now.
|
||||
set_background_image(IT_unauth);
|
||||
set_button_image(IT_auth_ready);
|
||||
make_splash_window();
|
||||
|
|
@ -1332,6 +1404,10 @@ handle_notify_request(const string &message) {
|
|||
// started Python yet). We use this as a sneaky way to forward
|
||||
// the event from the sub-thread to the main thread.
|
||||
splash_button_clicked_main_thread();
|
||||
|
||||
} else if (message == "authfinished") {
|
||||
// Similarly for the "auth finished" message.
|
||||
auth_finished_main_thread();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1506,7 +1582,9 @@ make_splash_window() {
|
|||
if (_image_package == NULL) {
|
||||
P3DHost *host = inst_mgr->get_host(PANDA_PACKAGE_HOST_URL);
|
||||
_image_package = host->get_package("images", "");
|
||||
_image_package->add_instance(this);
|
||||
if (_image_package != NULL) {
|
||||
_image_package->add_instance(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1607,9 +1685,18 @@ set_button_image(ImageType image_type) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
report_package_info_ready(P3DPackage *package) {
|
||||
if (package == _image_package) {
|
||||
// A special case: the image package gets immediately downloaded,
|
||||
// without waiting for anything else.
|
||||
if (package == _image_package || package == _p3dcert_package) {
|
||||
// A special case: the image package and the p3dcert package get
|
||||
// immediately downloaded, without waiting for anything else.
|
||||
if (package == _p3dcert_package) {
|
||||
// If we're downloading p3dcert, though, put up a progress bar.
|
||||
make_splash_window();
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(0.0);
|
||||
_splash_window->set_install_label("Getting Authorization Dialog");
|
||||
}
|
||||
}
|
||||
|
||||
package->activate_download();
|
||||
return;
|
||||
}
|
||||
|
|
@ -1785,6 +1872,18 @@ report_instance_progress(double progress) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
report_package_progress(P3DPackage *package, double progress) {
|
||||
if (package == _image_package) {
|
||||
// Ignore this.
|
||||
return;
|
||||
}
|
||||
if (package == _p3dcert_package) {
|
||||
// This gets its own progress bar.
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(progress);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_download_package_index >= (int)_downloading_packages.size() ||
|
||||
package != _downloading_packages[_download_package_index]) {
|
||||
// Quietly ignore a download progress report from an unexpected
|
||||
|
|
@ -1822,6 +1921,7 @@ report_package_done(P3DPackage *package, bool success) {
|
|||
nout << "No <config> entry in image package\n";
|
||||
return;
|
||||
}
|
||||
cerr << "downloaded image_package\n";
|
||||
for (int i = 0; i < (int)IT_none; ++i) {
|
||||
if (_image_files[i]._use_standard_image) {
|
||||
// This image indexes into the package. Go get the standard
|
||||
|
|
@ -1838,6 +1938,7 @@ report_package_done(P3DPackage *package, bool success) {
|
|||
// still exists, put it up.
|
||||
if (_splash_window != NULL &&
|
||||
_image_files[i]._image_placement != P3DSplashWindow::IP_none) {
|
||||
cerr << "putting up image " << i << "\n";
|
||||
P3DSplashWindow::ImagePlacement image_placement = _image_files[i]._image_placement;
|
||||
_splash_window->set_image_filename(image_filename, image_placement);
|
||||
}
|
||||
|
|
@ -1847,6 +1948,22 @@ report_package_done(P3DPackage *package, bool success) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (package == _p3dcert_package) {
|
||||
// Another special case: successfully downloading p3dcert means we
|
||||
// can enable the auth button.
|
||||
|
||||
// Take down the download progress.
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(0.0);
|
||||
_splash_window->set_install_label("");
|
||||
}
|
||||
|
||||
if (success) {
|
||||
mark_p3d_untrusted();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
report_package_progress(package, 1.0);
|
||||
start_next_download();
|
||||
|
|
|
|||
|
|
@ -106,6 +106,9 @@ public:
|
|||
void auth_button_clicked();
|
||||
void play_button_clicked();
|
||||
|
||||
void auth_finished_sub_thread();
|
||||
void auth_finished_main_thread();
|
||||
|
||||
private:
|
||||
class ImageDownload : public P3DFileDownload {
|
||||
public:
|
||||
|
|
@ -209,6 +212,9 @@ private:
|
|||
P3DWindowParams _wparams;
|
||||
|
||||
bool _p3d_trusted;
|
||||
|
||||
// For downloading the p3dcert authorization program.
|
||||
P3DPackage *_p3dcert_package;
|
||||
|
||||
int _instance_id;
|
||||
string _session_key;
|
||||
|
|
@ -219,6 +225,7 @@ private:
|
|||
bool _auth_button_approved;
|
||||
|
||||
P3DSession *_session;
|
||||
P3DAuthSession *_auth_session;
|
||||
|
||||
#ifdef __APPLE__
|
||||
// On OSX, we have to get a copy of the framebuffer data back from
|
||||
|
|
@ -275,6 +282,7 @@ private:
|
|||
BakedRequests _baked_requests;
|
||||
|
||||
friend class P3DSession;
|
||||
friend class P3DAuthSession;
|
||||
friend class ImageDownload;
|
||||
friend class P3DWindowParams;
|
||||
friend class P3DPackage;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "p3dInstanceManager.h"
|
||||
#include "p3dInstance.h"
|
||||
#include "p3dSession.h"
|
||||
#include "p3dAuthSession.h"
|
||||
#include "p3dHost.h"
|
||||
#include "p3d_plugin_config.h"
|
||||
#include "p3dWinSplashWindow.h"
|
||||
|
|
@ -67,6 +68,8 @@ P3DInstanceManager() {
|
|||
_true_object = new P3DBoolObject(true);
|
||||
_false_object = new P3DBoolObject(false);
|
||||
|
||||
_auth_session = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Ensure the appropriate Windows common controls are available to
|
||||
// this application.
|
||||
|
|
@ -110,6 +113,11 @@ P3DInstanceManager::
|
|||
assert(_instances.empty());
|
||||
assert(_sessions.empty());
|
||||
|
||||
if (_auth_session != NULL) {
|
||||
unref_delete(_auth_session);
|
||||
_auth_session = NULL;
|
||||
}
|
||||
|
||||
Hosts::iterator hi;
|
||||
for (hi = _hosts.begin(); hi != _hosts.end(); ++hi) {
|
||||
delete (*hi).second;
|
||||
|
|
@ -381,6 +389,29 @@ finish_instance(P3DInstance *inst) {
|
|||
unref_delete(inst);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::authorize_instance
|
||||
// Access: Public
|
||||
// Description: Creates a new P3DAuthSession object, to pop up a
|
||||
// window for the user to authorize the certificate on
|
||||
// this instance. Automatically terminates any
|
||||
// previously-created P3DAuthSession.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3DAuthSession *P3DInstanceManager::
|
||||
authorize_instance(P3DInstance *inst) {
|
||||
if (_auth_session != NULL) {
|
||||
// We only want one auth_session window open at a time, to
|
||||
// minimize user confusion, so close any previous window.
|
||||
_auth_session->shutdown(true);
|
||||
unref_delete(_auth_session);
|
||||
_auth_session = NULL;
|
||||
}
|
||||
|
||||
_auth_session = new P3DAuthSession(inst);
|
||||
_auth_session->ref();
|
||||
return _auth_session;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::validate_instance
|
||||
// Access: Public
|
||||
|
|
@ -678,25 +709,7 @@ find_cert(X509 *cert) {
|
|||
// OpenSSL's get_by_subject() approach, except we hash the whole
|
||||
// cert, not just the subject. (Since we also store self-signed
|
||||
// certs in this list, we can't trust the subject name alone.)
|
||||
|
||||
static const size_t hash_size = 16;
|
||||
unsigned char md[hash_size];
|
||||
|
||||
MD5_CTX ctx;
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, der.data(), der.size());
|
||||
MD5_Final(md, &ctx);
|
||||
|
||||
string basename;
|
||||
static const size_t keep_hash = 6;
|
||||
for (size_t i = 0; i < keep_hash; ++i) {
|
||||
int high = (md[i] >> 4) & 0xf;
|
||||
int low = md[i] & 0xf;
|
||||
basename += P3DInstanceManager::encode_hexdigit(high);
|
||||
basename += P3DInstanceManager::encode_hexdigit(low);
|
||||
}
|
||||
|
||||
string this_cert_dir = _certs_dir + "/" + basename;
|
||||
string this_cert_dir = get_cert_dir(cert);
|
||||
nout << "looking in " << this_cert_dir << "\n";
|
||||
|
||||
vector<string> contents;
|
||||
|
|
@ -730,6 +743,36 @@ find_cert(X509 *cert) {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::get_cert_dir
|
||||
// Access: Public
|
||||
// Description: Returns the directory searched for this particular
|
||||
// certificate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string P3DInstanceManager::
|
||||
get_cert_dir(X509 *cert) {
|
||||
string der = cert_to_der(cert);
|
||||
|
||||
static const size_t hash_size = 16;
|
||||
unsigned char md[hash_size];
|
||||
|
||||
MD5_CTX ctx;
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, der.data(), der.size());
|
||||
MD5_Final(md, &ctx);
|
||||
|
||||
string basename;
|
||||
static const size_t keep_hash = 6;
|
||||
for (size_t i = 0; i < keep_hash; ++i) {
|
||||
int high = (md[i] >> 4) & 0xf;
|
||||
int low = md[i] & 0xf;
|
||||
basename += P3DInstanceManager::encode_hexdigit(high);
|
||||
basename += P3DInstanceManager::encode_hexdigit(low);
|
||||
}
|
||||
|
||||
return _certs_dir + "/" + basename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::cert_to_der
|
||||
// Access: Public, Static
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
class P3DInstance;
|
||||
class P3DSession;
|
||||
class P3DAuthSession;
|
||||
class P3DHost;
|
||||
class FileSpec;
|
||||
class TiXmlElement;
|
||||
|
|
@ -75,6 +76,7 @@ public:
|
|||
const string &p3d_filename);
|
||||
bool start_instance(P3DInstance *inst);
|
||||
void finish_instance(P3DInstance *inst);
|
||||
P3DAuthSession *authorize_instance(P3DInstance *inst);
|
||||
|
||||
P3DInstance *validate_instance(P3D_instance *instance);
|
||||
|
||||
|
|
@ -98,6 +100,7 @@ public:
|
|||
void release_temp_filename(const string &filename);
|
||||
|
||||
bool find_cert(X509 *cert);
|
||||
string get_cert_dir(X509 *cert);
|
||||
static string cert_to_der(X509 *cert);
|
||||
|
||||
static P3DInstanceManager *get_global_ptr();
|
||||
|
|
@ -134,6 +137,7 @@ private:
|
|||
|
||||
typedef set<P3DInstance *> Instances;
|
||||
Instances _instances;
|
||||
P3DAuthSession *_auth_session;
|
||||
|
||||
typedef map<string, P3DSession *> Sessions;
|
||||
Sessions _sessions;
|
||||
|
|
|
|||
|
|
@ -816,7 +816,6 @@ start_p3dpython(P3DInstance *inst) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Define some new environment variables.
|
||||
|
|
@ -964,13 +963,6 @@ start_p3dpython(P3DInstance *inst) {
|
|||
_pipe_write.open_write(to_fd[1]);
|
||||
#endif // _WIN32
|
||||
|
||||
// Create the error stream for log output. This means opening the
|
||||
// logfile, if we have one, or keeping the standard error if we
|
||||
// don't.
|
||||
#ifdef _WIN32
|
||||
#else // _WIN32
|
||||
#endif // _WIN32
|
||||
|
||||
// Get the filename of the Panda3D multifile. We need to pass this
|
||||
// to p3dpython.
|
||||
_mf_filename = inst->_panda3d->get_archive_file_pathname();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "p3d_plugin.cxx"
|
||||
#include "p3dAuthSession.cxx"
|
||||
#include "p3dBoolObject.cxx"
|
||||
#include "p3dConcreteSequence.cxx"
|
||||
#include "p3dConcreteStruct.cxx"
|
||||
|
|
|
|||
Loading…
Reference in New Issue