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