new security enhancements for toontown client and server
This commit is contained in:
parent
a0ccebc539
commit
577c5ac28c
|
|
@ -6,8 +6,7 @@
|
|||
#begin lib_target
|
||||
#define TARGET downloader
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx \
|
||||
$[if $[HAVE_ZLIB], $[TARGET]_composite4.cxx] \
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
config_downloader.h \
|
||||
|
|
@ -16,8 +15,10 @@
|
|||
bioStreamPtr.I bioStreamPtr.h \
|
||||
bioStream.I bioStream.h bioStreamBuf.h \
|
||||
chunkedStream.I chunkedStream.h chunkedStreamBuf.h \
|
||||
decompressor.h \
|
||||
documentSpec.I documentSpec.h \
|
||||
downloadDb.I downloadDb.h \
|
||||
download_utils.h \
|
||||
extractor.h \
|
||||
httpAuthorization.I httpAuthorization.h \
|
||||
httpBasicAuthorization.I httpBasicAuthorization.h \
|
||||
|
|
@ -30,10 +31,9 @@
|
|||
identityStream.I identityStream.h identityStreamBuf.h \
|
||||
multiplexStream.I multiplexStream.h \
|
||||
multiplexStreamBuf.I multiplexStreamBuf.h \
|
||||
patcher.h patcher.I \
|
||||
socketStream.h socketStream.I \
|
||||
urlSpec.I urlSpec.h \
|
||||
$[if $[HAVE_ZLIB], decompressor.h download_utils.h] \
|
||||
$[if $[HAVE_CRYPTO], patcher.cxx patcher.h patcher.I]
|
||||
urlSpec.I urlSpec.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
config_downloader.cxx \
|
||||
|
|
@ -42,8 +42,10 @@
|
|||
bioStreamPtr.cxx \
|
||||
bioStream.cxx bioStreamBuf.cxx \
|
||||
chunkedStream.cxx chunkedStreamBuf.cxx \
|
||||
decompressor.cxx \
|
||||
documentSpec.cxx \
|
||||
downloadDb.cxx \
|
||||
download_utils.cxx \
|
||||
extractor.cxx \
|
||||
httpAuthorization.cxx \
|
||||
httpBasicAuthorization.cxx \
|
||||
|
|
@ -55,9 +57,9 @@
|
|||
httpEnum.cxx \
|
||||
identityStream.cxx identityStreamBuf.cxx \
|
||||
multiplexStream.cxx multiplexStreamBuf.cxx \
|
||||
patcher.cxx \
|
||||
socketStream.cxx \
|
||||
urlSpec.cxx \
|
||||
$[if $[HAVE_ZLIB], decompressor.cxx download_utils.cxx]
|
||||
urlSpec.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
asyncUtility.h asyncUtility.I \
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "bioPtr.h"
|
||||
#include "urlSpec.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "bioPtr.h"
|
||||
#include "bioStreamPtr.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,17 @@ config_downloader.GetDouble("http-timeout", 20.0);
|
|||
const int http_max_connect_count =
|
||||
config_downloader.GetInt("http-max-connect-count", 10);
|
||||
|
||||
// These provide a default client certificate to offer up should an
|
||||
// SSL server demand one. The files references a PEM-formatted file
|
||||
// that includes a public and private key specification. A
|
||||
// connection-specific certificate may also be specified at runtime on
|
||||
// the HTTPClient object, but this will require having a different
|
||||
// HTTPClient object for each differently-certificated connection.
|
||||
const string http_client_certificate_filename =
|
||||
config_downloader.GetString("http-client-certificate-filename", "");
|
||||
const string http_client_certificate_passphrase =
|
||||
config_downloader.GetString("http-client-certificate-passphrase", "");
|
||||
|
||||
ConfigureFn(config_downloader) {
|
||||
#ifdef HAVE_SSL
|
||||
HTTPChannel::init_type();
|
||||
|
|
|
|||
|
|
@ -51,5 +51,7 @@ extern const bool http_proxy_tunnel;
|
|||
extern const double connect_timeout;
|
||||
extern const double http_timeout;
|
||||
extern const int http_max_connect_count;
|
||||
extern const string http_client_certificate_filename;
|
||||
extern const string http_client_certificate_passphrase;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,13 +16,15 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is compiled only if we have zlib installed.
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
#include "config_downloader.h"
|
||||
|
||||
#include "error_utils.h"
|
||||
#include "filename.h"
|
||||
#include "buffer.h"
|
||||
#include "ramfile.h"
|
||||
#include "zStream.h"
|
||||
#include "config_express.h"
|
||||
|
||||
|
|
@ -273,3 +275,5 @@ cleanup() {
|
|||
_decompress = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_ZLIB
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
#define DECOMPRESSOR_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
#include "filename.h"
|
||||
|
||||
class Ramfile;
|
||||
|
|
@ -58,4 +61,6 @@ private:
|
|||
|
||||
#include "decompressor.I"
|
||||
|
||||
#endif // HAVE_ZLIB
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "downloadDb.h"
|
||||
#include "streamReader.h"
|
||||
#include "streamWriter.h"
|
||||
#include "ramfile.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
|
@ -481,11 +482,7 @@ write(ostream &out) const {
|
|||
<< " phase: " << _phase << endl
|
||||
<< " size: " << _size << endl
|
||||
<< " status: " << _status << endl
|
||||
<< " hash: [" << _hash.get_value(0)
|
||||
<< " " << _hash.get_value(1)
|
||||
<< " " << _hash.get_value(2)
|
||||
<< " " << _hash.get_value(3)
|
||||
<< "]" << endl;
|
||||
<< " hash: " << _hash << endl;
|
||||
out << "--------------------------------------------------" << endl;
|
||||
pvector< PT(FileRecord) >::const_iterator i = _file_records.begin();
|
||||
for(; i != _file_records.end(); ++i) {
|
||||
|
|
@ -753,12 +750,7 @@ parse_mfr(const string &data) {
|
|||
mfr->_name = back_to_front_slash(mfr->_name);
|
||||
|
||||
// Read the hash value
|
||||
HashVal hash;
|
||||
hash.set_value(0, di.get_uint32());
|
||||
hash.set_value(1, di.get_uint32());
|
||||
hash.set_value(2, di.get_uint32());
|
||||
hash.set_value(3, di.get_uint32());
|
||||
mfr->_hash = hash;
|
||||
mfr->_hash.read_datagram(di);
|
||||
|
||||
downloader_cat.debug()
|
||||
<< "Parsed multifile record: " << mfr->_name << " phase: " << mfr->_phase
|
||||
|
|
@ -812,7 +804,7 @@ read(StreamReader &sr, bool want_server_info) {
|
|||
// Read the header
|
||||
string header;
|
||||
header = sr.extract_bytes(_header_length);
|
||||
if (header.size() != _header_length) {
|
||||
if (header.size() != (size_t)_header_length) {
|
||||
downloader_cat.error() << "truncated db file" << endl;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -832,7 +824,7 @@ read(StreamReader &sr, bool want_server_info) {
|
|||
int mfr_header_length = sizeof(PN_int32);
|
||||
|
||||
string mfr_header = sr.extract_bytes(mfr_header_length);
|
||||
if (mfr_header.size() != mfr_header_length) {
|
||||
if (mfr_header.size() != (size_t)mfr_header_length) {
|
||||
downloader_cat.error() << "invalid mfr header" << endl;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -845,7 +837,7 @@ read(StreamReader &sr, bool want_server_info) {
|
|||
// do not count the header length twice
|
||||
int read_length = (mfr_length - mfr_header_length);
|
||||
string mfr_record = sr.extract_bytes(read_length);
|
||||
if (mfr_record.size() != read_length) {
|
||||
if (mfr_record.size() != (size_t)read_length) {
|
||||
downloader_cat.error() << "invalid mfr record" << endl;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -864,7 +856,7 @@ read(StreamReader &sr, bool want_server_info) {
|
|||
|
||||
// Read the header
|
||||
string fr_header = sr.extract_bytes(fr_header_length);
|
||||
if (fr_header.size() != fr_header_length) {
|
||||
if (fr_header.size() != (size_t)fr_header_length) {
|
||||
downloader_cat.error() << "invalid fr header" << endl;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -877,7 +869,7 @@ read(StreamReader &sr, bool want_server_info) {
|
|||
int read_length = (fr_length - fr_header_length);
|
||||
|
||||
string fr_record = sr.extract_bytes(read_length);
|
||||
if (fr_record.size() != read_length) {
|
||||
if (fr_record.size() != (size_t)read_length) {
|
||||
downloader_cat.error() << "invalid fr record" << endl;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -914,7 +906,6 @@ write(StreamWriter &sw, bool want_server_info) {
|
|||
PN_int32 num_files;
|
||||
PN_int32 name_length;
|
||||
PN_int32 header_length;
|
||||
HashVal hash;
|
||||
|
||||
// Iterate over the multifiles writing them to the stream
|
||||
pvector< PT(MultifileRecord) >::const_iterator i = _mfile_records.begin();
|
||||
|
|
@ -949,11 +940,7 @@ write(StreamWriter &sw, bool want_server_info) {
|
|||
sw.add_int32(status);
|
||||
sw.add_int32(num_files);
|
||||
|
||||
hash = (*i)->_hash;
|
||||
sw.add_uint32(hash.get_value(0));
|
||||
sw.add_uint32(hash.get_value(1));
|
||||
sw.add_uint32(hash.get_value(2));
|
||||
sw.add_uint32(hash.get_value(3));
|
||||
(*i)->_hash.write_stream(sw);
|
||||
|
||||
// Only write out the file information if you are the server
|
||||
if (want_server_info) {
|
||||
|
|
@ -1217,7 +1204,6 @@ write_version_map(StreamWriter &sw) {
|
|||
VersionMap::iterator vmi;
|
||||
VectorHash::iterator i;
|
||||
string name;
|
||||
HashVal hash;
|
||||
|
||||
sw.add_int32(_versions.size());
|
||||
for (vmi = _versions.begin(); vmi != _versions.end(); ++vmi) {
|
||||
|
|
@ -1230,12 +1216,7 @@ write_version_map(StreamWriter &sw) {
|
|||
sw.add_int32((*vmi).second.size());
|
||||
for (i = (*vmi).second.begin(); i != (*vmi).second.end(); ++i) {
|
||||
// *i will point to a HashVal
|
||||
hash = *i;
|
||||
// Write out each uint separately
|
||||
sw.add_uint32(hash.get_value(0));
|
||||
sw.add_uint32(hash.get_value(1));
|
||||
sw.add_uint32(hash.get_value(2));
|
||||
sw.add_uint32(hash.get_value(3));
|
||||
(*i).write_stream(sw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1279,10 +1260,7 @@ read_version_map(StreamReader &sr) {
|
|||
|
||||
for (int j = 0; j < length; j++) {
|
||||
HashVal hash;
|
||||
hash.set_value(0, sr.get_uint32());
|
||||
hash.set_value(1, sr.get_uint32());
|
||||
hash.set_value(2, sr.get_uint32());
|
||||
hash.set_value(3, sr.get_uint32());
|
||||
hash.read_stream(sr);
|
||||
if (sr.get_istream()->fail()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1306,7 +1284,7 @@ write_version_map(ostream &out) const {
|
|||
out << " " << (*vmi).first << endl;
|
||||
for (i = (*vmi).second.begin(); i != (*vmi).second.end(); ++i) {
|
||||
HashVal hash = *i;
|
||||
out << " " << hash << endl;
|
||||
out << " " << hash.as_dec() << endl;
|
||||
}
|
||||
}
|
||||
out << endl;
|
||||
|
|
|
|||
|
|
@ -30,11 +30,11 @@
|
|||
#include "pmap.h"
|
||||
|
||||
#include "hashVal.h"
|
||||
#include "buffer.h"
|
||||
|
||||
class StreamReader;
|
||||
class StreamWriter;
|
||||
typedef float Phase;
|
||||
class Ramfile;
|
||||
|
||||
/*
|
||||
//////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -16,13 +16,15 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is compiled only if we have zlib installed.
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
#include "download_utils.h"
|
||||
#include "config_downloader.h"
|
||||
#include <zlib.h>
|
||||
|
||||
ulong
|
||||
unsigned long
|
||||
check_crc(Filename name) {
|
||||
ifstream read_stream;
|
||||
name.set_binary();
|
||||
|
|
@ -40,7 +42,7 @@ check_crc(Filename name) {
|
|||
read_stream.read(buffer, buffer_length);
|
||||
|
||||
// Compute the crc
|
||||
ulong crc = crc32(0L, Z_NULL, 0);
|
||||
unsigned long crc = crc32(0L, Z_NULL, 0);
|
||||
crc = crc32(crc, (uchar *)buffer, buffer_length);
|
||||
|
||||
delete buffer;
|
||||
|
|
@ -48,7 +50,7 @@ check_crc(Filename name) {
|
|||
return crc;
|
||||
}
|
||||
|
||||
ulong
|
||||
unsigned long
|
||||
check_adler(Filename name) {
|
||||
ifstream read_stream;
|
||||
name.set_binary();
|
||||
|
|
@ -66,10 +68,12 @@ check_adler(Filename name) {
|
|||
read_stream.read(buffer, buffer_length);
|
||||
|
||||
// Compute the adler checksum
|
||||
ulong adler = adler32(0L, Z_NULL, 0);
|
||||
unsigned long adler = adler32(0L, Z_NULL, 0);
|
||||
adler = adler32(adler, (uchar *)buffer, buffer_length);
|
||||
|
||||
delete buffer;
|
||||
|
||||
return adler;
|
||||
}
|
||||
|
||||
#endif // HAVE_ZLIB
|
||||
|
|
|
|||
|
|
@ -19,16 +19,20 @@
|
|||
#ifndef DOWNLOAD_UTILS_H
|
||||
#define DOWNLOAD_UTILS_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include <filename.h>
|
||||
#include <typedef.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
#include "filename.h"
|
||||
|
||||
BEGIN_PUBLISH
|
||||
|
||||
EXPCL_PANDAEXPRESS ulong check_crc(Filename name);
|
||||
EXPCL_PANDAEXPRESS ulong check_adler(Filename name);
|
||||
EXPCL_PANDAEXPRESS unsigned long check_crc(Filename name);
|
||||
EXPCL_PANDAEXPRESS unsigned long check_adler(Filename name);
|
||||
|
||||
END_PUBLISH
|
||||
|
||||
#endif // HAVE_ZLIB
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
#include "config_downloader.cxx"
|
||||
#include "asyncUtility.cxx"
|
||||
#include "bioPtr.cxx"
|
||||
#include "bioStreamPtr.cxx"
|
||||
#include "bioStream.cxx"
|
||||
#include "bioStreamBuf.cxx"
|
||||
#include "bioStreamPtr.cxx"
|
||||
#include "chunkedStream.cxx"
|
||||
#include "chunkedStreamBuf.cxx"
|
||||
#include "downloadDb.cxx"
|
||||
#include "extractor.cxx"
|
||||
#include "httpDate.cxx"
|
||||
#include "httpEntityTag.cxx"
|
||||
#include "config_downloader.cxx"
|
||||
#include "decompressor.cxx"
|
||||
#include "documentSpec.cxx"
|
||||
|
||||
#include "downloadDb.cxx"
|
||||
#include "download_utils.cxx"
|
||||
#include "extractor.cxx"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
#include "httpAuthorization.cxx"
|
||||
#include "httpBasicAuthorization.cxx"
|
||||
#include "httpClient.cxx"
|
||||
#include "httpChannel.cxx"
|
||||
#include "httpClient.cxx"
|
||||
#include "httpDate.cxx"
|
||||
#include "httpDigestAuthorization.cxx"
|
||||
#include "httpEntityTag.cxx"
|
||||
#include "httpEnum.cxx"
|
||||
#include "identityStream.cxx"
|
||||
#include "identityStreamBuf.cxx"
|
||||
#include "multiplexStream.cxx"
|
||||
#include "multiplexStreamBuf.cxx"
|
||||
#include "patcher.cxx"
|
||||
#include "socketStream.cxx"
|
||||
#include "urlSpec.cxx"
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
#include "download_utils.cxx"
|
||||
#include "decompressor.cxx"
|
||||
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#include "identityStream.h"
|
||||
#include "config_downloader.h"
|
||||
#include "clockObject.h"
|
||||
#include "buffer.h" // for Ramfile
|
||||
#include "ramfile.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef REPORT_OPENSSL_ERRORS
|
||||
|
|
@ -54,6 +54,7 @@ HTTPChannel(HTTPClient *client) :
|
|||
_max_updates_per_second = 1.0f / _seconds_per_update;
|
||||
_bytes_per_update = int(_max_bytes_per_second * _seconds_per_update);
|
||||
_nonblocking = false;
|
||||
|
||||
_want_ssl = false;
|
||||
_proxy_serves_document = false;
|
||||
_proxy_tunnel_now = false;
|
||||
|
|
@ -646,6 +647,7 @@ downcase(const string &s) {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPChannel::reached_done_state
|
||||
// Access: Private
|
||||
|
|
@ -1191,6 +1193,24 @@ run_setup_ssl() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// It would be nice to use something like SSL_set_client_cert_cb()
|
||||
// here to set a callback to provide the certificate should it be
|
||||
// requested, or even to potentially provide any of a number of
|
||||
// certificates according to the server's CA presented, but that
|
||||
// interface as provided by OpenSSL is broken since there's no way
|
||||
// to pass additional data to the callback function (and hence no
|
||||
// way to tie it back to the HTTPChannel object, other than by
|
||||
// building a messy mapping of SSL pointers back to HTTPChannel
|
||||
// pointers).
|
||||
if (_client->load_client_certificate()) {
|
||||
SSL_use_certificate(ssl, _client->_client_certificate_pub);
|
||||
SSL_use_PrivateKey(ssl, _client->_client_certificate_priv);
|
||||
if (!SSL_check_private_key(ssl)) {
|
||||
downloader_cat.warning()
|
||||
<< "Client private key does not match public key!\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (downloader_cat.is_spam()) {
|
||||
downloader_cat.spam()
|
||||
<< "SSL Ciphers available:\n";
|
||||
|
|
|
|||
|
|
@ -44,6 +44,52 @@ get_try_all_direct() const {
|
|||
return _try_all_direct;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::set_client_certificate_filename
|
||||
// Access: Published
|
||||
// Description: Sets the filename of the pem-formatted file that will
|
||||
// be read for the client public and private keys if an
|
||||
// SSL server requests a certificate. Either this or
|
||||
// set_client_certificate_pem() may be used to specify a
|
||||
// client certificate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPClient::
|
||||
set_client_certificate_filename(const Filename &filename) {
|
||||
_client_certificate_filename = filename;
|
||||
_client_certificate_pem = string();
|
||||
unload_client_certificate();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::set_client_certificate_pem
|
||||
// Access: Published
|
||||
// Description: Sets the pem-formatted contents of the certificate
|
||||
// that will be parsed for the client public and private
|
||||
// keys if an SSL server requests a certificate. Either
|
||||
// this or set_client_certificate_filename() may be used
|
||||
// to specify a client certificate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPClient::
|
||||
set_client_certificate_pem(const string &pem) {
|
||||
_client_certificate_pem = pem;
|
||||
_client_certificate_filename = Filename();
|
||||
unload_client_certificate();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::set_client_certificate_passphrase
|
||||
// Access: Published
|
||||
// Description: Sets the passphrase used to decrypt the private key
|
||||
// in the certificate named by
|
||||
// set_client_certificate_filename() or
|
||||
// set_client_certificate_pem().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPClient::
|
||||
set_client_certificate_passphrase(const string &passphrase) {
|
||||
_client_certificate_passphrase = passphrase;
|
||||
unload_client_certificate();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::set_http_version
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -128,6 +128,13 @@ HTTPClient() {
|
|||
}
|
||||
}
|
||||
|
||||
_client_certificate_filename = http_client_certificate_filename;
|
||||
_client_certificate_passphrase = http_client_certificate_passphrase;
|
||||
|
||||
_client_certificate_loaded = false;
|
||||
_client_certificate_pub = NULL;
|
||||
_client_certificate_priv = NULL;
|
||||
|
||||
// The first time we create an HTTPClient, we must initialize the
|
||||
// OpenSSL library.
|
||||
if (!_ssl_initialized) {
|
||||
|
|
@ -190,6 +197,8 @@ HTTPClient::
|
|||
|
||||
// Free all of the expected server definitions.
|
||||
clear_expected_servers();
|
||||
|
||||
unload_client_certificate();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -599,6 +608,93 @@ get_username(const string &server, const string &realm) const {
|
|||
return string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::load_client_certificate
|
||||
// Access: Published
|
||||
// Description: Attempts to load the certificate named by
|
||||
// set_client_certificate_filename() immediately, and
|
||||
// returns true if successful, false otherwise.
|
||||
//
|
||||
// Normally this need not be explicitly called, since it
|
||||
// will be called automatically if the server requests a
|
||||
// certificate, but it may be useful to determine ahead
|
||||
// of time if the certificate can be loaded correctly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPClient::
|
||||
load_client_certificate() {
|
||||
if (!_client_certificate_loaded) {
|
||||
_client_certificate_loaded = true;
|
||||
|
||||
if (!_client_certificate_filename.empty()) {
|
||||
_client_certificate_filename.set_text();
|
||||
|
||||
// First, read the complete file into memory.
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
||||
if (!vfs->read_file(_client_certificate_filename,
|
||||
_client_certificate_pem)) {
|
||||
// Could not find or read file.
|
||||
downloader_cat.warning()
|
||||
<< "Could not read " << _client_certificate_filename << ".\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create an in-memory BIO to read the "file" from the memory
|
||||
// buffer, and call the low-level routines to read the
|
||||
// keys from the BIO.
|
||||
BIO *mbio = BIO_new_mem_buf((void *)_client_certificate_pem.data(),
|
||||
_client_certificate_pem.length());
|
||||
|
||||
ERR_clear_error();
|
||||
_client_certificate_priv =
|
||||
PEM_read_bio_PrivateKey(mbio, NULL, NULL,
|
||||
(char *)_client_certificate_passphrase.c_str());
|
||||
|
||||
// Rewind the "file" to the beginning in order to read the public
|
||||
// key (which might appear first in the file).
|
||||
BIO_reset(mbio);
|
||||
|
||||
ERR_clear_error();
|
||||
_client_certificate_pub =
|
||||
PEM_read_bio_X509(mbio, NULL, NULL, NULL);
|
||||
|
||||
BIO_free(mbio);
|
||||
|
||||
|
||||
NotifySeverity sev = NS_debug;
|
||||
string source = "memory";
|
||||
if (!_client_certificate_filename.empty()) {
|
||||
// Only report status to "info" severity if we have read the
|
||||
// certificate from a file. If it came from an in-memory image,
|
||||
// a failure will presumably be handled by whoever set the
|
||||
// image.
|
||||
sev = NS_info;
|
||||
source = _client_certificate_filename;
|
||||
}
|
||||
|
||||
if (_client_certificate_priv != (EVP_PKEY *)NULL &&
|
||||
_client_certificate_pub != (X509 *)NULL) {
|
||||
downloader_cat.out(sev)
|
||||
<< "Read client certificate from " << source << "\n";
|
||||
|
||||
} else {
|
||||
if (_client_certificate_priv == (EVP_PKEY *)NULL) {
|
||||
downloader_cat.out(sev)
|
||||
<< "Could not read private key from " << source << "\n";
|
||||
}
|
||||
|
||||
if (_client_certificate_pub == (X509 *)NULL) {
|
||||
downloader_cat.out(sev)
|
||||
<< "Could not read public key from " << source << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (_client_certificate_priv != (EVP_PKEY *)NULL &&
|
||||
_client_certificate_pub != (X509 *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::get_http_version_string
|
||||
// Access: Published
|
||||
|
|
@ -1108,6 +1204,28 @@ generate_auth(const URLSpec &url, bool is_proxy, const string &challenge) {
|
|||
return auth;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::unload_client_certificate
|
||||
// Access: Private
|
||||
// Description: Frees the resources allocated by a previous call to
|
||||
// load_client_certificate(), and marks the certificate
|
||||
// unloaded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPClient::
|
||||
unload_client_certificate() {
|
||||
if (_client_certificate_priv != (EVP_PKEY *)NULL) {
|
||||
EVP_PKEY_free(_client_certificate_priv);
|
||||
_client_certificate_priv = NULL;
|
||||
}
|
||||
|
||||
if (_client_certificate_pub != (X509 *)NULL) {
|
||||
X509_free(_client_certificate_pub);
|
||||
_client_certificate_pub = NULL;
|
||||
}
|
||||
|
||||
_client_certificate_loaded = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::initialize_ssl
|
||||
// Access: Private, Static
|
||||
|
|
@ -1209,6 +1327,14 @@ load_verify_locations(SSL_CTX *ctx, const Filename &ca_file) {
|
|||
<< "Entry " << i << " is crl\n";
|
||||
}
|
||||
|
||||
} else if (itmp->x_pkey) {
|
||||
// X509_STORE_add_crl(store, itmp->x_pkey);
|
||||
// count++;
|
||||
if (downloader_cat.is_spam()) {
|
||||
downloader_cat.spam()
|
||||
<< "Entry " << i << " is pkey\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
if (downloader_cat.is_spam()) {
|
||||
downloader_cat.spam()
|
||||
|
|
|
|||
|
|
@ -82,6 +82,11 @@ PUBLISHED:
|
|||
void set_username(const string &server, const string &realm, const string &username);
|
||||
string get_username(const string &server, const string &realm) const;
|
||||
|
||||
INLINE void set_client_certificate_filename(const Filename &filename);
|
||||
INLINE void set_client_certificate_pem(const string &pem);
|
||||
INLINE void set_client_certificate_passphrase(const string &passphrase);
|
||||
bool load_client_certificate();
|
||||
|
||||
INLINE void set_http_version(HTTPEnum::HTTPVersion version);
|
||||
INLINE HTTPEnum::HTTPVersion get_http_version() const;
|
||||
string get_http_version_string() const;
|
||||
|
|
@ -125,6 +130,8 @@ private:
|
|||
PT(HTTPAuthorization) generate_auth(const URLSpec &url, bool is_proxy,
|
||||
const string &challenge);
|
||||
|
||||
void unload_client_certificate();
|
||||
|
||||
static void initialize_ssl();
|
||||
static int load_verify_locations(SSL_CTX *ctx, const Filename &ca_file);
|
||||
|
||||
|
|
@ -158,12 +165,19 @@ private:
|
|||
typedef pmap<string, Domain> Domains;
|
||||
Domains _proxy_domains, _www_domains;
|
||||
|
||||
Filename _client_certificate_filename;
|
||||
string _client_certificate_pem;
|
||||
string _client_certificate_passphrase;
|
||||
|
||||
// List of allowable SSL servers to connect to. If the list is
|
||||
// empty, any server is acceptable.
|
||||
typedef pvector<X509_NAME *> ExpectedServers;
|
||||
ExpectedServers _expected_servers;
|
||||
|
||||
SSL_CTX *_ssl_ctx;
|
||||
bool _client_certificate_loaded;
|
||||
X509 *_client_certificate_pub;
|
||||
EVP_PKEY *_client_certificate_priv;
|
||||
|
||||
static bool _ssl_initialized;
|
||||
static X509_STORE *_x509_store;
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_downloader.h"
|
||||
#include <filename.h>
|
||||
#include "patcher.h"
|
||||
#include "pandabase.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Defines
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
#include "config_downloader.h"
|
||||
#include "patcher.h"
|
||||
#include "filename.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Patcher::Constructor
|
||||
|
|
@ -88,3 +88,5 @@ int Patcher::
|
|||
run(void) {
|
||||
return _patchfile->run();
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
|
|
|
|||
|
|
@ -15,16 +15,17 @@
|
|||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PATCHER_H
|
||||
#define PATCHER_H
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include <pandabase.h>
|
||||
#include <filename.h>
|
||||
#include <buffer.h>
|
||||
#include <patchfile.h>
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
#include "filename.h"
|
||||
#include "buffer.h"
|
||||
#include "patchfile.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Patcher
|
||||
|
|
@ -49,4 +50,6 @@ private:
|
|||
|
||||
#include "patcher.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET apply_patch
|
||||
#define BUILD_TARGET $[HAVE_CRYPTO]
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
|
||||
#define SOURCES \
|
||||
apply_patch.cxx
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET build_patch
|
||||
#define BUILD_TARGET $[HAVE_CRYPTO]
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
|
||||
#define SOURCES \
|
||||
build_patch.cxx
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET show_ddb
|
||||
#define BUILD_TARGET $[HAVE_CRYPTO]
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
|
||||
#define SOURCES \
|
||||
show_ddb.cxx
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
#begin bin_target
|
||||
#define TARGET check_md5
|
||||
#define BUILD_TARGET $[HAVE_CRYPTO]
|
||||
#define BUILD_TARGET $[HAVE_SSL]
|
||||
#define USE_PACKAGES $[USE_PACKAGES] crypto
|
||||
|
||||
#define SOURCES \
|
||||
|
|
|
|||
|
|
@ -16,34 +16,121 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "crypto_utils.h"
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "hashVal.h"
|
||||
#include "filename.h"
|
||||
|
||||
#ifndef HAVE_GETOPT
|
||||
#include <gnu_getopt.h>
|
||||
#else
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
usage() {
|
||||
cerr <<
|
||||
"\n"
|
||||
"Usage:\n\n"
|
||||
"check_md5 [-d] [-i \"input string\"] [file1 file2 ...]\n"
|
||||
"check_md5 -h\n\n";
|
||||
}
|
||||
|
||||
void
|
||||
help() {
|
||||
usage();
|
||||
cerr <<
|
||||
"This program outputs the MD5 hash of one or more files (or of a string\n"
|
||||
"passed on the command line with -i).\n\n"
|
||||
|
||||
"An MD5 hash is a 128-bit value. The output is presented as a 32-digit\n"
|
||||
"hexadecimal string by default, but with -d, it is presented as four\n"
|
||||
"big-endian unsigned 32-bit decimal integers.\n\n";
|
||||
}
|
||||
|
||||
void
|
||||
output_hash(const string &filename, const HashVal &hash, bool output_decimal) {
|
||||
if (!filename.empty()) {
|
||||
cout << filename << " ";
|
||||
}
|
||||
if (output_decimal) {
|
||||
hash.output_dec(cout);
|
||||
} else {
|
||||
hash.output_hex(cout);
|
||||
}
|
||||
cout << "\n";
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
const char *usagestr = "Usage: check_md5 <file>";
|
||||
if (argc < 2) {
|
||||
cerr << usagestr << endl;
|
||||
return 1;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
const char *optstr = "i:dh";
|
||||
|
||||
bool got_input_string = false;
|
||||
string input_string;
|
||||
bool output_decimal = false;
|
||||
|
||||
int flag = getopt(argc, argv, optstr);
|
||||
|
||||
while (flag != EOF) {
|
||||
switch (flag) {
|
||||
case 'i':
|
||||
got_input_string = true;
|
||||
input_string = optarg;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
output_decimal = true;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
help();
|
||||
exit(1);
|
||||
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
flag = getopt(argc, argv, optstr);
|
||||
}
|
||||
|
||||
Filename source_file;
|
||||
source_file = Filename::from_os_specific(argv[1]);
|
||||
argc -= (optind-1);
|
||||
argv += (optind-1);
|
||||
|
||||
if(!source_file.exists()) {
|
||||
cerr << usagestr << endl;
|
||||
cerr << source_file << " not found!\n";
|
||||
return 2;
|
||||
if (argc < 2 && !got_input_string) {
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
HashVal hash;
|
||||
md5_a_file(source_file, hash);
|
||||
if (got_input_string) {
|
||||
HashVal hash;
|
||||
hash.hash_string(input_string);
|
||||
output_hash("", hash, output_decimal);
|
||||
}
|
||||
|
||||
bool okflag = true;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
Filename source_file = Filename::from_os_specific(argv[i]);
|
||||
|
||||
if (!source_file.exists()) {
|
||||
cerr << source_file << " not found!\n";
|
||||
okflag = false;
|
||||
} else {
|
||||
HashVal hash;
|
||||
if (!hash.hash_file(source_file)) {
|
||||
cerr << "Unable to read " << source_file << "\n";
|
||||
okflag = false;
|
||||
} else {
|
||||
output_hash(source_file.get_basename(), hash, output_decimal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!okflag) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// output base of Filename along w/md5
|
||||
cout << source_file.get_basename() << " ";
|
||||
hash.output(cout);
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#begin lib_target
|
||||
#define TARGET express
|
||||
#define USE_PACKAGES nspr crypto net zlib
|
||||
#define USE_PACKAGES nspr crypto net zlib ssl
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
|
|
@ -41,10 +41,13 @@
|
|||
namable.h nativeNumericData.I nativeNumericData.h \
|
||||
numeric_types.h \
|
||||
ordered_vector.h ordered_vector.I ordered_vector.T \
|
||||
patchfile.I patchfile.h \
|
||||
pointerTo.I pointerTo.h \
|
||||
pointerToArray.I pointerToArray.h \
|
||||
profileTimer.I profileTimer.h \
|
||||
pta_uchar.h referenceCount.I referenceCount.h \
|
||||
pta_uchar.h \
|
||||
ramfile.I ramfile.h \
|
||||
referenceCount.I referenceCount.h \
|
||||
register_type.I register_type.h \
|
||||
reversedNumericData.I reversedNumericData.h \
|
||||
selectThreadImpl.h \
|
||||
|
|
@ -69,10 +72,7 @@
|
|||
virtualFileMountSystem.I virtualFileSimple.h virtualFileSimple.I \
|
||||
virtualFileSystem.h virtualFileSystem.I \
|
||||
windowsRegistry.h \
|
||||
zStream.I zStream.h zStreamBuf.h \
|
||||
$[if $[HAVE_CRYPTO], \
|
||||
crypto_utils.cxx crypto_utils.h patchfile.I \
|
||||
patchfile.cxx patchfile.h ]
|
||||
zStream.I zStream.h zStreamBuf.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
atomicAdjust.cxx atomicAdjustDummyImpl.cxx atomicAdjustNsprImpl.cxx \
|
||||
|
|
@ -90,8 +90,11 @@
|
|||
namable.cxx \
|
||||
nativeNumericData.cxx \
|
||||
ordered_vector.cxx \
|
||||
patchfile.cxx \
|
||||
profileTimer.cxx \
|
||||
pta_uchar.cxx referenceCount.cxx register_type.cxx \
|
||||
pta_uchar.cxx \
|
||||
ramfile.cxx \
|
||||
referenceCount.cxx register_type.cxx \
|
||||
reversedNumericData.cxx \
|
||||
streamReader.cxx streamWriter.cxx \
|
||||
stringDecoder.cxx \
|
||||
|
|
@ -141,7 +144,9 @@
|
|||
ordered_vector.h ordered_vector.I ordered_vector.T \
|
||||
patchfile.I patchfile.h pointerTo.I pointerTo.h \
|
||||
pointerToArray.I pointerToArray.h profileTimer.I \
|
||||
profileTimer.h pta_uchar.h referenceCount.I referenceCount.h \
|
||||
profileTimer.h pta_uchar.h \
|
||||
ramfile.I ramfile.h \
|
||||
referenceCount.I referenceCount.h \
|
||||
register_type.I register_type.h \
|
||||
reversedNumericData.I reversedNumericData.h \
|
||||
selectThreadImpl.h \
|
||||
|
|
|
|||
|
|
@ -25,13 +25,3 @@ INLINE int Buffer::
|
|||
get_length(void) const {
|
||||
return _length;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Ramfile::constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Ramfile::
|
||||
Ramfile(void) {
|
||||
_pos = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@
|
|||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include "buffer.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Defines
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include "buffer.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Buffer::Constructor
|
||||
|
|
@ -42,31 +39,3 @@ Buffer::
|
|||
delete _buffer;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Ramfile::readline
|
||||
// Access: Published
|
||||
// Description: Assumes the stream represents a text file, and
|
||||
// extracts one line up to and including the trailing
|
||||
// newline character. Returns empty string when the end
|
||||
// of file is reached.
|
||||
//
|
||||
// The interface here is intentionally designed to be
|
||||
// similar to that for Python's File.readline()
|
||||
// function.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string Ramfile::
|
||||
readline() {
|
||||
size_t start = _pos;
|
||||
while (_pos < _data.length() && _data[_pos] != '\n') {
|
||||
++_pos;
|
||||
}
|
||||
|
||||
if (_pos < _data.length() && _data[_pos] == '\n') {
|
||||
// Include the newline character also.
|
||||
++_pos;
|
||||
}
|
||||
|
||||
return _data.substr(start, _pos - start);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,11 @@
|
|||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BUFFER_H
|
||||
#define BUFFER_H
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include <pandabase.h>
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedef.h"
|
||||
#include "referenceCount.h"
|
||||
|
||||
|
|
@ -46,21 +44,6 @@ private:
|
|||
int _length;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Ramfile
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS Ramfile {
|
||||
PUBLISHED:
|
||||
INLINE Ramfile();
|
||||
|
||||
string readline();
|
||||
|
||||
public:
|
||||
size_t _pos;
|
||||
string _data;
|
||||
};
|
||||
|
||||
#include "buffer.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,134 +0,0 @@
|
|||
// Filename: crypto_utils.cxx
|
||||
// Created by: drose (07Nov00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is compiled only if we have crypto++ installed.
|
||||
|
||||
|
||||
#include "hashVal.h"
|
||||
#include "config_express.h"
|
||||
#include "crypto_utils.h"
|
||||
|
||||
#include <md5.h>
|
||||
#include <hex.h>
|
||||
#include <files.h>
|
||||
|
||||
// md5 defines this, but we'd rather do without it, because it
|
||||
// conflicts with a similar macro defined in NSPR.
|
||||
#undef IS_LITTLE_ENDIAN
|
||||
|
||||
USING_NAMESPACE(CryptoPP);
|
||||
USING_NAMESPACE(std);
|
||||
|
||||
static uint
|
||||
read32(istream& is) {
|
||||
unsigned int ret = 0x0;
|
||||
for (int i=0; i<8; ++i) {
|
||||
char b;
|
||||
int n = 0;
|
||||
is >> b;
|
||||
switch (b) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
n = b - '0';
|
||||
break;
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
n = b - 'A' + 10;
|
||||
break;
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
n = b - 'a' + 10;
|
||||
break;
|
||||
default:
|
||||
cerr << "illegal hex nibble '" << b << "'" << endl;
|
||||
}
|
||||
ret = (ret << 4) | (n & 0x0f);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
md5_a_file(const Filename &name, HashVal &ret) {
|
||||
ostringstream os;
|
||||
MD5 md5;
|
||||
|
||||
string fs = name.to_os_specific();
|
||||
|
||||
try {
|
||||
FileSource f(fs.c_str(), true,
|
||||
new HashFilter(md5, new HexEncoder(new FileSink(os))));
|
||||
} catch (...) {
|
||||
express_cat.warning()
|
||||
<< "Unable to read " << name << " to compute md5 hash.\n";
|
||||
if (!name.exists()) {
|
||||
express_cat.warning()
|
||||
<< "(file does not exist.)\n";
|
||||
} else {
|
||||
express_cat.warning()
|
||||
<< "(file exists but cannot be read.)\n";
|
||||
}
|
||||
ret.hv[0] = 0;
|
||||
ret.hv[1] = 0;
|
||||
ret.hv[2] = 0;
|
||||
ret.hv[3] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
istringstream is(os.str());
|
||||
|
||||
ret.hv[0] = read32(is);
|
||||
ret.hv[1] = read32(is);
|
||||
ret.hv[2] = read32(is);
|
||||
ret.hv[3] = read32(is);
|
||||
}
|
||||
|
||||
void
|
||||
md5_a_buffer(const unsigned char* buf, unsigned long len, HashVal& ret) {
|
||||
MD5 md5;
|
||||
|
||||
HashFilter hash(md5);
|
||||
hash.Put((byte*)buf, len);
|
||||
hash.Close();
|
||||
|
||||
unsigned char* outb;
|
||||
unsigned long outl = hash.MaxRetrieveable();
|
||||
outb = new uchar[outl];
|
||||
hash.Get((byte*)outb, outl);
|
||||
ret.hv[0] = (outb[0] << 24) | (outb[1] << 16) | (outb[2] << 8) | outb[3];
|
||||
ret.hv[1] = (outb[4] << 24) | (outb[5] << 16) | (outb[6] << 8) | outb[7];
|
||||
ret.hv[2] = (outb[8] << 24) | (outb[9] << 16) | (outb[10] << 8) | outb[11];
|
||||
ret.hv[3] = (outb[12] << 24) | (outb[13] << 16) | (outb[14] << 8) | outb[15];
|
||||
delete[] outb;
|
||||
}
|
||||
|
||||
|
|
@ -24,13 +24,9 @@
|
|||
#include "memoryUsagePointerCounts.cxx"
|
||||
#include "memoryUsagePointers.cxx"
|
||||
#include "multifile.cxx"
|
||||
#include "pmutex.cxx"
|
||||
#include "mutexHolder.cxx"
|
||||
#include "mutexDummyImpl.cxx"
|
||||
#include "mutexNsprImpl.cxx"
|
||||
#include "namable.cxx"
|
||||
#include "nativeNumericData.cxx"
|
||||
#include "ordered_vector.cxx"
|
||||
#include "profileTimer.cxx"
|
||||
#include "pta_uchar.cxx"
|
||||
#include "referenceCount.cxx"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
#include "patchfile.cxx"
|
||||
#include "pmutex.cxx"
|
||||
#include "profileTimer.cxx"
|
||||
#include "pta_uchar.cxx"
|
||||
#include "ramfile.cxx"
|
||||
#include "referenceCount.cxx"
|
||||
#include "register_type.cxx"
|
||||
#include "reversedNumericData.cxx"
|
||||
#include "streamReader.cxx"
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE HashVal::
|
||||
HashVal() {
|
||||
hv[0] = hv[1] = hv[2] = hv[3] = 0;
|
||||
_hv[0] = _hv[1] = _hv[2] = _hv[3] = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -34,10 +34,23 @@ HashVal() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE HashVal::
|
||||
HashVal(const HashVal ©) {
|
||||
hv[0] = copy.hv[0];
|
||||
hv[1] = copy.hv[1];
|
||||
hv[2] = copy.hv[2];
|
||||
hv[3] = copy.hv[3];
|
||||
_hv[0] = copy._hv[0];
|
||||
_hv[1] = copy._hv[1];
|
||||
_hv[2] = copy._hv[2];
|
||||
_hv[3] = copy._hv[3];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
operator = (const HashVal ©) {
|
||||
_hv[0] = copy._hv[0];
|
||||
_hv[1] = copy._hv[1];
|
||||
_hv[2] = copy._hv[2];
|
||||
_hv[3] = copy._hv[3];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -47,10 +60,10 @@ HashVal(const HashVal ©) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool HashVal::
|
||||
operator == (const HashVal &other) const {
|
||||
return (hv[0] == other.hv[0] &&
|
||||
hv[1] == other.hv[1] &&
|
||||
hv[2] == other.hv[2] &&
|
||||
hv[3] == other.hv[3]);
|
||||
return (_hv[0] == other._hv[0] &&
|
||||
_hv[1] == other._hv[1] &&
|
||||
_hv[2] == other._hv[2] &&
|
||||
_hv[3] == other._hv[3]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -64,36 +77,189 @@ operator != (const HashVal &other) const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::get_value
|
||||
// Function: HashVal::operator <
|
||||
// Access: Published
|
||||
// Description: Returns the integer value of the indicated component.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE uint HashVal::
|
||||
get_value(int val) const {
|
||||
nassertr(val >= 0 && val < 4, 0);
|
||||
return hv[val];
|
||||
INLINE bool HashVal::
|
||||
operator < (const HashVal &other) const {
|
||||
return compare_to(other) < 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::compare_to
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int HashVal::
|
||||
compare_to(const HashVal &other) const {
|
||||
if (_hv[0] != other._hv[0]) {
|
||||
return (int)_hv[0] - (int)other._hv[0];
|
||||
}
|
||||
if (_hv[1] != other._hv[1]) {
|
||||
return (int)_hv[1] - (int)other._hv[1];
|
||||
}
|
||||
if (_hv[2] != other._hv[2]) {
|
||||
return (int)_hv[2] - (int)other._hv[2];
|
||||
}
|
||||
return (int)_hv[3] - (int)other._hv[3];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::set_value
|
||||
// Function: HashVal::merge_with
|
||||
// Access: Published
|
||||
// Description: Sets the hash value at index val
|
||||
// Description: Generates a new HashVal representing the xor of this
|
||||
// one and the other one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
set_value(int val, uint hashval) {
|
||||
nassertv(val >= 0 && val < 4);
|
||||
hv[val] = hashval;
|
||||
merge_with(const HashVal &other) {
|
||||
_hv[0] ^= other._hv[0];
|
||||
_hv[1] ^= other._hv[1];
|
||||
_hv[2] ^= other._hv[2];
|
||||
_hv[3] ^= other._hv[3];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::output_dec
|
||||
// Access: Published
|
||||
// Description: Outputs the HashVal as four unsigned decimal
|
||||
// integers.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
output_dec(ostream &out) const {
|
||||
out << _hv[0] << " " << _hv[1] << " " << _hv[2] << " " << _hv[3];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::input
|
||||
// Access: Published
|
||||
// Description: Inputs the HashVal as four unsigned decimal integers.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
input_dec(istream &in) {
|
||||
in >> _hv[0] >> _hv[1] >> _hv[2] >> _hv[3];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::output
|
||||
// Access: Published
|
||||
// Description: The output method does not itself output enclosing
|
||||
// brackets, but the ostream operator << does.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
output(ostream &out) const {
|
||||
out << hv[0] << " " << hv[1] << " " << hv[2] << " " << hv[3];
|
||||
output_hex(out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::write_datagram
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
write_datagram(Datagram &destination) const {
|
||||
destination.add_uint32(_hv[0]);
|
||||
destination.add_uint32(_hv[1]);
|
||||
destination.add_uint32(_hv[2]);
|
||||
destination.add_uint32(_hv[3]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::read_datagram
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
read_datagram(DatagramIterator &source) {
|
||||
_hv[0] = source.get_uint32();
|
||||
_hv[1] = source.get_uint32();
|
||||
_hv[2] = source.get_uint32();
|
||||
_hv[3] = source.get_uint32();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::write_stream
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
write_stream(StreamWriter &destination) const {
|
||||
destination.add_uint32(_hv[0]);
|
||||
destination.add_uint32(_hv[1]);
|
||||
destination.add_uint32(_hv[2]);
|
||||
destination.add_uint32(_hv[3]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::read_stream
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
read_stream(StreamReader &source) {
|
||||
_hv[0] = source.get_uint32();
|
||||
_hv[1] = source.get_uint32();
|
||||
_hv[2] = source.get_uint32();
|
||||
_hv[3] = source.get_uint32();
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::hash_ramfile
|
||||
// Access: Published
|
||||
// Description: Generates the hash value by hashing the indicated
|
||||
// data. This method is only defined if we have the
|
||||
// OpenSSL library (which provides md5 functionality)
|
||||
// available.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
hash_ramfile(const Ramfile &ramfile) {
|
||||
return hash_buffer(ramfile._data.data(), ramfile._data.length());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::hash_string
|
||||
// Access: Published
|
||||
// Description: Generates the hash value by hashing the indicated
|
||||
// data. This method is only defined if we have the
|
||||
// OpenSSL library (which provides md5 functionality)
|
||||
// available.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HashVal::
|
||||
hash_string(const string &data) {
|
||||
return hash_buffer(data.data(), data.length());
|
||||
}
|
||||
#endif // HAVE_SSL
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::tohex
|
||||
// Access: Private, Static
|
||||
// Description: Converts a single nibble to a hex digit.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE char HashVal::
|
||||
tohex(unsigned int nibble) {
|
||||
nibble &= 0xf;
|
||||
if (nibble < 10) {
|
||||
return nibble + '0';
|
||||
}
|
||||
return nibble - 10 + 'a';
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::fromhex
|
||||
// Access: Private, Static
|
||||
// Description: Converts a single hex digit to a numerical value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE unsigned int HashVal::
|
||||
fromhex(char digit) {
|
||||
if (isdigit(digit)) {
|
||||
return digit - '0';
|
||||
} else {
|
||||
return tolower(digit) - 'a' + 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const HashVal &hv) {
|
||||
hv.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,17 +16,233 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "hashVal.h"
|
||||
#include "ctype.h"
|
||||
#include "virtualFileSystem.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/md5.h>
|
||||
#endif // HAVE_SSL
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::as_string
|
||||
// Function: HashVal::output_hex
|
||||
// Access: Published
|
||||
// Description: Returns the HashVal as a string with four numbers.
|
||||
// Description: Outputs the HashVal as a 32-digit hexadecimal number.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HashVal::
|
||||
output_hex(ostream &out) const {
|
||||
char buffer[32];
|
||||
encode_hex(_hv[0], buffer);
|
||||
encode_hex(_hv[1], buffer + 8);
|
||||
encode_hex(_hv[2], buffer + 16);
|
||||
encode_hex(_hv[3], buffer + 24);
|
||||
out.write(buffer, 32);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::input
|
||||
// Access: Published
|
||||
// Description: Inputs the HashVal as a 32-digit hexadecimal number.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HashVal::
|
||||
input_hex(istream &in) {
|
||||
in >> ws;
|
||||
char buffer[32];
|
||||
size_t i = 0;
|
||||
int ch = in.get();
|
||||
|
||||
while (!in.eof() && !in.fail() && isxdigit(ch)) {
|
||||
if (i < 32) {
|
||||
buffer[i] = ch;
|
||||
}
|
||||
i++;
|
||||
ch = in.get();
|
||||
}
|
||||
|
||||
if (i != 32) {
|
||||
in.setstate(ios::failbit);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in.eof()) {
|
||||
in.unget();
|
||||
} else {
|
||||
in.clear();
|
||||
}
|
||||
|
||||
decode_hex(buffer, _hv[0]);
|
||||
decode_hex(buffer + 8, _hv[1]);
|
||||
decode_hex(buffer + 16, _hv[2]);
|
||||
decode_hex(buffer + 24, _hv[3]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::as_dec
|
||||
// Access: Published
|
||||
// Description: Returns the HashVal as a string with four decimal
|
||||
// numbers.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string HashVal::
|
||||
as_string() const {
|
||||
as_dec() const {
|
||||
ostringstream strm;
|
||||
output(strm);
|
||||
output_dec(strm);
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::set_from_dec
|
||||
// Access: Published
|
||||
// Description: Sets the HashVal from a string with four decimal
|
||||
// numbers. Returns true if valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HashVal::
|
||||
set_from_dec(const string &text) {
|
||||
istringstream strm(text);
|
||||
input_dec(strm);
|
||||
return !strm.fail();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::as_hex
|
||||
// Access: Published
|
||||
// Description: Returns the HashVal as a 32-byte hexadecimal string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string HashVal::
|
||||
as_hex() const {
|
||||
char buffer[32];
|
||||
encode_hex(_hv[0], buffer);
|
||||
encode_hex(_hv[1], buffer + 8);
|
||||
encode_hex(_hv[2], buffer + 16);
|
||||
encode_hex(_hv[3], buffer + 24);
|
||||
return string(buffer, 32);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::set_from_hex
|
||||
// Access: Published
|
||||
// Description: Sets the HashVal from a 32-byte hexademical string.
|
||||
// Returns true if successful, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HashVal::
|
||||
set_from_hex(const string &text) {
|
||||
istringstream strm(text);
|
||||
input_hex(strm);
|
||||
return !strm.fail();
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::hash_file
|
||||
// Access: Published
|
||||
// Description: Generates the hash value from the indicated file.
|
||||
// Returns true on success, false if the file cannot be
|
||||
// read. This method is only defined if we have the
|
||||
// OpenSSL library (which provides md5 functionality)
|
||||
// available.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HashVal::
|
||||
hash_file(const Filename &filename) {
|
||||
Filename bin_filename = Filename::binary_filename(filename);
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
istream *istr = vfs->open_read_file(bin_filename);
|
||||
if (istr == (istream *)NULL) {
|
||||
(*this) = HashVal();
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char md[16];
|
||||
|
||||
MD5_CTX ctx;
|
||||
MD5_Init(&ctx);
|
||||
|
||||
static const int buffer_size = 1024;
|
||||
char buffer[buffer_size];
|
||||
|
||||
istr->read(buffer, buffer_size);
|
||||
size_t count = istr->gcount();
|
||||
while (count != 0) {
|
||||
MD5_Update(&ctx, buffer, count);
|
||||
istr->read(buffer, buffer_size);
|
||||
count = istr->gcount();
|
||||
}
|
||||
|
||||
delete istr;
|
||||
MD5_Final(md, &ctx);
|
||||
|
||||
// Store the individual bytes as big-endian ints, from historical
|
||||
// convention.
|
||||
_hv[0] = (md[0] << 24) | (md[1] << 16) | (md[2] << 8) | (md[3]);
|
||||
_hv[1] = (md[4] << 24) | (md[5] << 16) | (md[6] << 8) | (md[7]);
|
||||
_hv[2] = (md[8] << 24) | (md[9] << 16) | (md[10] << 8) | (md[11]);
|
||||
_hv[3] = (md[12] << 24) | (md[13] << 16) | (md[14] << 8) | (md[15]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::hash_buffer
|
||||
// Access: Published
|
||||
// Description: Generates the hash value by hashing the indicated
|
||||
// data. This method is only defined if we have the
|
||||
// OpenSSL library (which provides md5 functionality)
|
||||
// available.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HashVal::
|
||||
hash_buffer(const char *buffer, int length) {
|
||||
unsigned char md[16];
|
||||
MD5((const unsigned char *)buffer, length, md);
|
||||
|
||||
// Store the individual bytes as big-endian ints, from historical
|
||||
// convention.
|
||||
_hv[0] = (md[0] << 24) | (md[1] << 16) | (md[2] << 8) | (md[3]);
|
||||
_hv[1] = (md[4] << 24) | (md[5] << 16) | (md[6] << 8) | (md[7]);
|
||||
_hv[2] = (md[8] << 24) | (md[9] << 16) | (md[10] << 8) | (md[11]);
|
||||
_hv[3] = (md[12] << 24) | (md[13] << 16) | (md[14] << 8) | (md[15]);
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::encode_hex
|
||||
// Access: Private, Static
|
||||
// Description: Encodes the indicated unsigned int into an
|
||||
// eight-digit hex string, stored at the indicated
|
||||
// buffer and the following 8 positions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HashVal::
|
||||
encode_hex(unsigned int val, char *buffer) {
|
||||
buffer[0] = tohex(val >> 28);
|
||||
buffer[1] = tohex(val >> 24);
|
||||
buffer[2] = tohex(val >> 20);
|
||||
buffer[3] = tohex(val >> 16);
|
||||
buffer[4] = tohex(val >> 12);
|
||||
buffer[5] = tohex(val >> 8);
|
||||
buffer[6] = tohex(val >> 4);
|
||||
buffer[7] = tohex(val);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HashVal::decode_hex
|
||||
// Access: Private, Static
|
||||
// Description: Decodes the indicated eight-digit hex string into an
|
||||
// unsigned integer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HashVal::
|
||||
decode_hex(const char *buffer, unsigned int &val) {
|
||||
unsigned int bytes[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
bytes[i] = fromhex(buffer[i]);
|
||||
}
|
||||
|
||||
val = ((bytes[0] << 28) |
|
||||
(bytes[1] << 24) |
|
||||
(bytes[2] << 20) |
|
||||
(bytes[3] << 16) |
|
||||
(bytes[4] << 12) |
|
||||
(bytes[5] << 8) |
|
||||
(bytes[6] << 4) |
|
||||
(bytes[7]));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,36 +19,68 @@
|
|||
#ifndef HASHVAL_H
|
||||
#define HASHVAL_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
#include "typedef.h"
|
||||
#include <notify.h>
|
||||
#include "notify.h"
|
||||
#include "ramfile.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "streamWriter.h"
|
||||
#include "streamReader.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : HashVal
|
||||
// Description : A sixteen-byte hash value sent to the crypt library.
|
||||
// Description : Stores a 128-bit value that represents the hashed
|
||||
// contents (typically MD5) of a file or buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS HashVal {
|
||||
PUBLISHED:
|
||||
INLINE HashVal();
|
||||
INLINE HashVal(const HashVal ©);
|
||||
INLINE void operator = (const HashVal ©);
|
||||
|
||||
INLINE bool operator == (const HashVal &other) const;
|
||||
INLINE bool operator != (const HashVal &other) const;
|
||||
INLINE uint get_value(int val) const;
|
||||
INLINE void set_value(int val, uint hash);
|
||||
INLINE void output(ostream &out) const;
|
||||
string as_string() const;
|
||||
INLINE bool operator < (const HashVal &other) const;
|
||||
INLINE int compare_to(const HashVal &other) const;
|
||||
|
||||
public:
|
||||
uint hv[4];
|
||||
INLINE void merge_with(const HashVal &other);
|
||||
|
||||
INLINE void output_dec(ostream &out) const;
|
||||
INLINE void input_dec(istream &in);
|
||||
void output_hex(ostream &out) const;
|
||||
void input_hex(istream &in);
|
||||
|
||||
INLINE void output(ostream &out) const;
|
||||
|
||||
string as_dec() const;
|
||||
bool set_from_dec(const string &text);
|
||||
|
||||
string as_hex() const;
|
||||
bool set_from_hex(const string &text);
|
||||
|
||||
INLINE void write_datagram(Datagram &destination) const;
|
||||
INLINE void read_datagram(DatagramIterator &source);
|
||||
INLINE void write_stream(StreamWriter &destination) const;
|
||||
INLINE void read_stream(StreamReader &source);
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
bool hash_file(const Filename &filename);
|
||||
INLINE void hash_ramfile(const Ramfile &ramfile);
|
||||
INLINE void hash_string(const string &data);
|
||||
void hash_buffer(const char *buffer, int length);
|
||||
#endif // HAVE_SSL
|
||||
|
||||
private:
|
||||
static void encode_hex(unsigned int val, char *buffer);
|
||||
static void decode_hex(const char *buffer, unsigned int &val);
|
||||
INLINE static char tohex(unsigned int nibble);
|
||||
INLINE static unsigned int fromhex(char digit);
|
||||
|
||||
PN_uint32 _hv[4];
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const HashVal &hv) {
|
||||
out << "[";
|
||||
hv.output(out);
|
||||
out << "]";
|
||||
return out;
|
||||
}
|
||||
INLINE ostream &operator << (ostream &out, const HashVal &hv);
|
||||
|
||||
#include "hashVal.I"
|
||||
|
||||
|
|
|
|||
|
|
@ -16,15 +16,22 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
#include "config_express.h"
|
||||
#include "error_utils.h"
|
||||
#include "patchfile.h"
|
||||
#include "crypto_utils.h" // MD5 stuff
|
||||
#include "streamReader.h"
|
||||
#include "streamWriter.h"
|
||||
|
||||
#include <stdio.h> // for tempnam
|
||||
|
||||
#ifdef WIN32_VC
|
||||
#define tempnam _tempnam
|
||||
#endif
|
||||
|
||||
// PROFILING ///////////////////////////////////////////////////////
|
||||
//#define PROFILE_PATCH_BUILD
|
||||
#ifdef PROFILE_PATCH_BUILD
|
||||
|
|
@ -200,7 +207,7 @@ initiate(const Filename &patch_file, const Filename &file) {
|
|||
|
||||
// Open the temp file for write
|
||||
{
|
||||
char *tempfilename = _tempnam(".", "pf");
|
||||
char *tempfilename = tempnam(".", "pf");
|
||||
if (NULL == tempfilename) {
|
||||
express_cat.error()
|
||||
<< "Patchfile::initiate() - Failed to create temp file name, using default" << endl;
|
||||
|
|
@ -356,7 +363,7 @@ run(void) {
|
|||
// check the MD5 from the patch file against the newly patched file
|
||||
{
|
||||
HashVal MD5_actual;
|
||||
md5_a_file(_temp_file, MD5_actual);
|
||||
MD5_actual.hash_file(_temp_file);
|
||||
if (_MD5_ofResult != MD5_actual) {
|
||||
// Whoops, patching screwed up somehow.
|
||||
_origfile_stream.close();
|
||||
|
|
@ -376,7 +383,7 @@ run(void) {
|
|||
<< "No source hash in patch file to verify.\n";
|
||||
} else {
|
||||
HashVal MD5_orig;
|
||||
md5_a_file(_orig_file, MD5_orig);
|
||||
MD5_orig.hash_file(_orig_file);
|
||||
if (MD5_orig != get_source_hash()) {
|
||||
express_cat.info()
|
||||
<< "Started from incorrect source file. Got:\n"
|
||||
|
|
@ -496,20 +503,14 @@ internal_read_header(const Filename &patch_file) {
|
|||
_source_file_length = patch_reader.get_uint32();
|
||||
|
||||
// get the MD5 of the source file.
|
||||
_MD5_ofSource.set_value(0, patch_reader.get_uint32());
|
||||
_MD5_ofSource.set_value(1, patch_reader.get_uint32());
|
||||
_MD5_ofSource.set_value(2, patch_reader.get_uint32());
|
||||
_MD5_ofSource.set_value(3, patch_reader.get_uint32());
|
||||
_MD5_ofSource.read_stream(patch_reader);
|
||||
}
|
||||
|
||||
// get the length of the patched result file
|
||||
_result_file_length = patch_reader.get_uint32();
|
||||
|
||||
// get the MD5 of the resultant patched file
|
||||
_MD5_ofResult.set_value(0, patch_reader.get_uint32());
|
||||
_MD5_ofResult.set_value(1, patch_reader.get_uint32());
|
||||
_MD5_ofResult.set_value(2, patch_reader.get_uint32());
|
||||
_MD5_ofResult.set_value(3, patch_reader.get_uint32());
|
||||
_MD5_ofResult.read_stream(patch_reader);
|
||||
|
||||
express_cat.debug()
|
||||
<< "Patchfile::initiate() - valid patchfile" << endl;
|
||||
|
|
@ -530,8 +531,7 @@ PN_uint16 Patchfile::
|
|||
calc_hash(const char *buffer) {
|
||||
#ifdef USE_MD5_FOR_HASHTABLE_INDEX_VALUES
|
||||
HashVal hash;
|
||||
|
||||
md5_a_buffer((const unsigned char*)buffer, (int)_footprint_length, hash);
|
||||
hash.hash_buffer(buffer, _footprint_length);
|
||||
|
||||
//cout << PN_uint16(hash.get_value(0)) << " ";
|
||||
|
||||
|
|
@ -869,22 +869,16 @@ build(Filename file_orig, Filename file_new, Filename patch_name) {
|
|||
patch_writer.add_uint32(_source_file_length);
|
||||
{
|
||||
// calc MD5 of original file
|
||||
md5_a_buffer((const unsigned char*)buffer_orig, (int)_source_file_length, _MD5_ofSource);
|
||||
_MD5_ofSource.hash_buffer(buffer_orig, _source_file_length);
|
||||
// add it to the header
|
||||
patch_writer.add_uint32(_MD5_ofSource.get_value(0));
|
||||
patch_writer.add_uint32(_MD5_ofSource.get_value(1));
|
||||
patch_writer.add_uint32(_MD5_ofSource.get_value(2));
|
||||
patch_writer.add_uint32(_MD5_ofSource.get_value(3));
|
||||
_MD5_ofSource.write_stream(patch_writer);
|
||||
}
|
||||
patch_writer.add_uint32(_result_file_length);
|
||||
{
|
||||
// calc MD5 of resultant patched file
|
||||
md5_a_buffer((const unsigned char*)buffer_new, (int)_result_file_length, _MD5_ofResult);
|
||||
_MD5_ofResult.hash_buffer(buffer_new, _result_file_length);
|
||||
// add it to the header
|
||||
patch_writer.add_uint32(_MD5_ofResult.get_value(0));
|
||||
patch_writer.add_uint32(_MD5_ofResult.get_value(1));
|
||||
patch_writer.add_uint32(_MD5_ofResult.get_value(2));
|
||||
patch_writer.add_uint32(_MD5_ofResult.get_value(3));
|
||||
_MD5_ofResult.write_stream(patch_writer);
|
||||
}
|
||||
|
||||
END_PROFILE(writeHeader, "writing patch file header");
|
||||
|
|
@ -941,7 +935,7 @@ build(Filename file_orig, Filename file_new, Filename patch_name) {
|
|||
}
|
||||
|
||||
// are there still more bytes left in the new file?
|
||||
if ((int)ADD_pos != _result_file_length) {
|
||||
if (ADD_pos != _result_file_length) {
|
||||
// emit ADD for all remaining bytes
|
||||
emit_ADD(write_stream, _result_file_length - ADD_pos, &buffer_new[ADD_pos],
|
||||
ADD_pos);
|
||||
|
|
@ -961,3 +955,4 @@ build(Filename file_orig, Filename file_new, Filename patch_name) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
||||
|
|
|
|||
|
|
@ -17,15 +17,14 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
#ifndef PATCHFILE_H
|
||||
#define PATCHFILE_H
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include <pandabase.h>
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
#include "typedef.h"
|
||||
#include <notify.h>
|
||||
#include <filename.h>
|
||||
#include "notify.h"
|
||||
#include "filename.h"
|
||||
#include "plist.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
|
@ -133,4 +132,6 @@ protected:
|
|||
|
||||
#include "patchfile.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: crypto_utils.h
|
||||
// Created by: drose (07Nov00)
|
||||
// Filename: ramfile.I
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -16,21 +16,12 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CRYPTO_UTILS_H
|
||||
#define CRYPTO_UTILS_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include <filename.h>
|
||||
#include "typedef.h"
|
||||
|
||||
class HashVal;
|
||||
|
||||
BEGIN_PUBLISH
|
||||
|
||||
EXPCL_PANDAEXPRESS void md5_a_file(const Filename &fname, HashVal &ret);
|
||||
EXPCL_PANDAEXPRESS void md5_a_buffer(const uchar *buf, ulong len, HashVal &ret);
|
||||
|
||||
END_PUBLISH
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Ramfile::constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Ramfile::
|
||||
Ramfile() {
|
||||
_pos = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Filename: ramfile.cxx
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ramfile.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Ramfile::readline
|
||||
// Access: Published
|
||||
// Description: Assumes the stream represents a text file, and
|
||||
// extracts one line up to and including the trailing
|
||||
// newline character. Returns empty string when the end
|
||||
// of file is reached.
|
||||
//
|
||||
// The interface here is intentionally designed to be
|
||||
// similar to that for Python's File.readline()
|
||||
// function.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string Ramfile::
|
||||
readline() {
|
||||
size_t start = _pos;
|
||||
while (_pos < _data.length() && _data[_pos] != '\n') {
|
||||
++_pos;
|
||||
}
|
||||
|
||||
if (_pos < _data.length() && _data[_pos] == '\n') {
|
||||
// Include the newline character also.
|
||||
++_pos;
|
||||
}
|
||||
|
||||
return _data.substr(start, _pos - start);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// Filename: ramfile.h
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef RAMFILE_H
|
||||
#define RAMFILE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedef.h"
|
||||
#include "referenceCount.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Ramfile
|
||||
// Description : An in-memory buffer specifically designed for
|
||||
// downloading files to memory.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS Ramfile {
|
||||
PUBLISHED:
|
||||
INLINE Ramfile();
|
||||
|
||||
string readline();
|
||||
|
||||
public:
|
||||
size_t _pos;
|
||||
string _data;
|
||||
};
|
||||
|
||||
#include "ramfile.I"
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue