getting somewhere

This commit is contained in:
David Rose 2009-09-17 22:52:52 +00:00
parent 040604f212
commit 54c3e34f6e
9 changed files with 422 additions and 67 deletions

View File

@ -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 \

View File

@ -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);
}

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -1,4 +1,5 @@
#include "p3d_plugin.cxx"
#include "p3dAuthSession.cxx"
#include "p3dBoolObject.cxx"
#include "p3dConcreteSequence.cxx"
#include "p3dConcreteStruct.cxx"