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());
138 #endif // HAVE_OPENSSL 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);
212 #endif // HAVE_OPENSSL 214 bool failed = (in.fail() && !in.eof());
226 IDecryptStream decrypt(&in,
false, password);
230 #endif // HAVE_OPENSSL 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);
281 get_num_declarations()
const {
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 {
338 out <<
"ConfigPage " << get_name() <<
", " << get_num_declarations()
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());
398 #endif // HAVE_OPENSSL 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)) {
get_name
Returns the name of the page.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear()
Removes all of the declarations from the page.
The internal definition of a ConfigVariable.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static ConfigPage * get_local_page()
Returns a pointer to the global "local page".
bool read_encrypted_prc(std::istream &in, const std::string &password)
Automatically decrypts and reads the stream, given the indicated password.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static ConfigPage * get_default_page()
Returns a pointer to the global "default page".
ConfigVariableCore * make_variable(const std::string &name)
Creates and returns a new, undefined ConfigVariableCore with the indicated name; or if a variable wit...
bool read_prc(std::istream &in)
Reads the contents of a complete prc file, as returned by the indicated istream, into the current pag...
const ConfigDeclaration * get_declaration(size_t n) const
Returns the nth declaration on the page.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A global object that maintains the set of ConfigVariables (actually, ConfigVariableCores) everywhere ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_string_value(size_t n) const
Returns the value assigned by the nth declaration on the page.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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_variable_name(size_t n) const
Returns the variable named by the nth declaration on 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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A single declaration of a config variable, typically defined as one line in a .prc file,...
modify_declaration
Returns a modifiable pointer to 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.
void output_brief_signature(std::ostream &out) const
Outputs the first few hex digits of the signature.
set_sort
Changes the explicit sort order of this particular ConfigPage.
bool delete_declaration(ConfigDeclaration *decl)
Removes the indicated declaration from the page and deletes it.