def _mod_config(self): """Modifies Nginx config to include server_names_hash_bucket_size directive and server challenge blocks. :raises .MisconfigurationError: Unable to find a suitable HTTP block in which to include authenticator hosts. """ included = False include_directive = ['\n', 'include', ' ', self.challenge_conf] root = self.configurator.parser.config_root bucket_directive = ['\n', 'server_names_hash_bucket_size', ' ', '128'] main = self.configurator.parser.parsed[root] for line in main: if line[0] == ['http']: body = line[1] found_bucket = False posn = 0 for inner_line in body: if inner_line[0] == bucket_directive[1]: if int(inner_line[1]) < int(bucket_directive[3]): body[posn] = bucket_directive found_bucket = True posn += 1 if not found_bucket: body.insert(0, bucket_directive) if include_directive not in body: body.insert(0, include_directive) included = True break if not included: raise errors.MisconfigurationError( 'Certbot could not find a block to include ' 'challenges in %s.' % root) config = [ self._make_or_mod_server_block(achall) for achall in self.achalls ] config = [x for x in config if x is not None] config = nginxparser.UnspacedList(config) logger.debug("Generated server block:\n%s", str(config)) self.configurator.reverter.register_file_creation( True, self.challenge_conf) with open(self.challenge_conf, "w") as new_conf: nginxparser.dump(config, new_conf)
def test_dump_as_file(self): with open(util.get_data_filename('nginx.conf')) as handle: parsed = load(handle) parsed[-1][-1].append(UnspacedList([['server'], [['listen', ' ', '443', ' ', 'ssl'], ['server_name', ' ', 'localhost'], ['ssl_certificate', ' ', 'cert.pem'], ['ssl_certificate_key', ' ', 'cert.key'], ['ssl_session_cache', ' ', 'shared:SSL:1m'], ['ssl_session_timeout', ' ', '5m'], ['ssl_ciphers', ' ', 'HIGH:!aNULL:!MD5'], [['location', ' ', '/'], [['root', ' ', 'html'], ['index', ' ', 'index.html', ' ', 'index.htm']]]]])) with tempfile.TemporaryFile(mode='w+t') as f: dump(parsed, f) f.seek(0) parsed_new = load(f) self.assertEqual(parsed, parsed_new)
def test_comments(self): with open(util.get_data_filename( 'minimalistic_comments.conf')) as handle: parsed = load(handle) with tempfile.TemporaryFile(mode='w+t') as f: dump(parsed, f) f.seek(0) parsed_new = load(f) self.assertEqual(parsed, parsed_new) self.assertEqual(parsed_new, [ ['#', " Use bar.conf when it's a full moon!"], ['include', 'foo.conf'], ['#', ' Kilroy was here'], ['check_status'], [['server'], [['#', ''], ['#', " Don't forget to open up your firewall!"], ['#', ''], ['listen', '1234'], ['#', ' listen 80;']]], ])
def _mod_config(self) -> None: """Modifies Nginx config to include server_names_hash_bucket_size directive and server challenge blocks. :raises .MisconfigurationError: Unable to find a suitable HTTP block in which to include authenticator hosts. """ included = False include_directive = ['\n', 'include', ' ', self.challenge_conf] root = self.configurator.parser.config_root bucket_directive = ['\n', 'server_names_hash_bucket_size', ' ', '128'] main = self.configurator.parser.parsed[root] # insert include directive for line in main: if line[0] == ['http']: body = line[1] if include_directive not in body: body.insert(0, include_directive) included = True break # insert or update the server_names_hash_bucket_size directive # We have several options here. # 1) Only check nginx.conf # 2) Check included files, assuming they've been included inside http already, # because if they added it outside an http block their config is broken anyway # 3) Add metadata during parsing to note if an include happened inside the http block # # 1 causes bugs; see https://github.com/certbot/certbot/issues/5199 # 3 would require a more extensive rewrite and probably isn't necessary anyway # So this code uses option 2. found_bucket = False for file_contents in self.configurator.parser.parsed.values(): body = file_contents # already inside http in an included file for line in file_contents: if line[0] == ['http']: body = line[1] # enter http because this is nginx.conf break for posn, inner_line in enumerate(body): if inner_line[0] == bucket_directive[1]: if int(inner_line[1]) < int(bucket_directive[3]): body[posn] = bucket_directive found_bucket = True break if found_bucket: break if not found_bucket: for line in main: if line[0] == ['http']: body = line[1] body.insert(0, bucket_directive) break if not included: raise errors.MisconfigurationError( 'Certbot could not find a block to include ' 'challenges in %s.' % root) config = [self._make_or_mod_server_block(achall) for achall in self.achalls] config = [x for x in config if x is not None] config = nginxparser.UnspacedList(config) logger.debug("Generated server block:\n%s", str(config)) self.configurator.reverter.register_file_creation( True, self.challenge_conf) with io.open(self.challenge_conf, "w", encoding="utf-8") as new_conf: nginxparser.dump(config, new_conf)