25 #include <openssl/evp.h>
32 ConfigPage *ConfigPage::_default_page =
nullptr;
40 ConfigPage(
const string &name,
bool implicit_load,
int page_seq) :
42 _implicit_load(implicit_load),
44 _sort(implicit_load ? 10 : 0),
65 if (_default_page ==
nullptr) {
66 _default_page =
new ConfigPage(
"default",
false, 0);
78 if (_local_page ==
nullptr) {
79 _local_page =
new ConfigPage(
"local",
false, 0);
104 Declarations::iterator di;
105 for (di = _declarations.begin(); di != _declarations.end(); ++di) {
109 _declarations.clear();
111 _signature = string();
131 static const size_t buffer_size = 1024;
132 char buffer[buffer_size];
136 _md_ctx = EVP_MD_CTX_create();
137 EVP_VerifyInit((EVP_MD_CTX *)_md_ctx, EVP_sha1());
142 in.read(buffer, buffer_size);
143 size_t count = in.gcount();
145 char *buffer_end = buffer + count;
148 char *newline = (
char *)memchr((
void *)buffer,
'\n', count);
149 if (newline ==
nullptr) {
151 prev_line += string(buffer, count);
155 size_t length = newline - buffer;
156 read_prc_line(prev_line +
string(buffer, length + 1));
159 char *start = newline + 1;
160 newline = (
char *)memchr((
void *)start,
'\n', buffer_end - start);
161 while (newline !=
nullptr) {
162 length = newline - start;
163 read_prc_line(
string(start, length + 1));
165 newline = (
char *)memchr((
void *)start,
'\n', buffer_end - start);
169 length = buffer_end - start;
170 prev_line = string(start, length);
173 if (in.fail() || in.eof()) {
180 in.read(buffer, buffer_size);
185 if (!prev_line.empty()) {
186 read_prc_line(prev_line);
191 if (!_signature.empty()) {
192 PrcKeyRegistry *pkr = PrcKeyRegistry::get_global_ptr();
193 int num_keys = pkr->get_num_keys();
194 for (
int i = 1; i < num_keys && _trust_level == 0; i++) {
195 EVP_PKEY *pkey = pkr->get_key(i);
196 if (pkey !=
nullptr) {
198 EVP_VerifyFinal((EVP_MD_CTX *)_md_ctx,
199 (
unsigned char *)_signature.data(),
200 _signature.size(), pkey);
201 if (verify_result == 1) {
206 if (_trust_level == 0) {
208 <<
"invalid signature found in " <<
get_name() <<
"\n";
211 EVP_MD_CTX_destroy((EVP_MD_CTX *)_md_ctx);
214 bool failed = (in.fail() && !in.eof());
226 IDecryptStream decrypt(&in,
false, password);
248 (
this, variable, value, _next_decl_seq);
251 _declarations.push_back(decl);
264 Declarations::iterator di;
265 for (di = _declarations.begin(); di != _declarations.end(); ++di) {
267 _declarations.erase(di);
282 return _declarations.size();
290 nassertr(n < _declarations.size(),
nullptr);
291 return _declarations[n];
301 nassertr(n < _declarations.size(),
nullptr);
302 return _declarations[n];
310 nassertr(n < _declarations.size(),
string());
311 return _declarations[n]->get_variable()->get_name();
319 nassertr(n < _declarations.size(),
string());
320 return _declarations[n]->get_string_value();
329 nassertr(n < _declarations.size(),
false);
330 return _declarations[n]->get_variable()->is_used();
337 output(ostream &out)
const {
347 size_t num_bytes = std::min(_signature.size(), (
size_t)8);
348 for (
size_t p = 0; p < num_bytes; ++p) {
349 unsigned int byte = _signature[p];
351 unsigned int hi = (
byte >> 4) & 0xf;
353 out << (char)((hi - 10) +
'a');
355 out << (char)(hi +
'0');
358 unsigned int lo =
byte & 0xf;
360 out << (char)((lo - 10) +
'a');
362 out << (char)(lo +
'0');
371 write(ostream &out)
const {
372 Declarations::const_iterator di;
373 for (di = _declarations.begin(); di != _declarations.end(); ++di) {
383 read_prc_line(
const string &line) {
384 if (line.substr(0, 7) ==
"##!sig ") {
387 for (
size_t p = 7; p < line.length() - 1; p += 2) {
388 unsigned char digit = (hex_digit(line[p]) << 4) | hex_digit(line[p + 1]);
397 EVP_VerifyUpdate((EVP_MD_CTX *)_md_ctx, line.data(), line.size());
402 while (p < line.length() && isspace((
unsigned char)line[p])) {
406 if (p == line.length() || line[p] ==
'#') {
411 size_t variable_begin = p;
412 while (p < line.length() && !isspace((
unsigned char)line[p])) {
415 size_t variable_end = p;
417 while (p < line.length() && isspace((
unsigned char)line[p])) {
420 size_t value_begin = p;
423 p = line.find(
" #", value_begin);
424 if (p == string::npos) {
431 while (p > value_begin && isspace((
unsigned char)line[p - 1])) {
434 size_t value_end = p;
436 string variable = line.substr(variable_begin, variable_end - variable_begin);
437 string value = line.substr(value_begin, value_end - value_begin);
445 unsigned int ConfigPage::
446 hex_digit(
unsigned char digit) {
447 if (isalpha(digit)) {
448 return tolower(digit) -
'a' + 10;
449 }
else if (isdigit(digit)) {
A single declaration of a config variable, typically defined as one line in a .prc file,...
void mark_unsorted()
This method is meant to be used internally to this module; there is no need to call it directly.
A page of ConfigDeclarations that may be loaded or unloaded.
std::string get_string_value(size_t n) const
Returns the value assigned by the nth declaration on the page.
bool delete_declaration(ConfigDeclaration *decl)
Removes the indicated declaration from the page and deletes it.
const ConfigDeclaration * get_declaration(size_t n) const
Returns the nth declaration on the page.
ConfigDeclaration * make_declaration(const std::string &variable, const std::string &value)
Adds the indicated variable/value pair as a new declaration on the page.
get_num_declarations
Returns the number of declarations on the page.
bool read_encrypted_prc(std::istream &in, const std::string &password)
Automatically decrypts and reads the stream, given the indicated password.
modify_declaration
Returns a modifiable pointer to the nth declaration on the page.
std::string get_variable_name(size_t n) const
Returns the variable named by the nth declaration on the page.
static ConfigPage * get_default_page()
Returns a pointer to the global "default page".
static ConfigPage * get_local_page()
Returns a pointer to the global "local page".
bool read_prc(std::istream &in)
Reads the contents of a complete prc file, as returned by the indicated istream, into the current pag...
set_sort
Changes the explicit sort order of this particular ConfigPage.
void output_brief_signature(std::ostream &out) const
Outputs the first few hex digits of the signature.
void clear()
Removes all of the declarations from the page.
bool is_variable_used(size_t n) const
Returns true if the nth active variable on the page has been used by code, false otherwise.
get_name
Returns the name of the page.
The internal definition of a ConfigVariable.
A global object that maintains the set of ConfigVariables (actually, ConfigVariableCores) everywhere ...
ConfigVariableCore * make_variable(const std::string &name)
Creates and returns a new, undefined ConfigVariableCore with the indicated name; or if a variable wit...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.