mirror of
https://github.com/certbot/certbot.git
synced 2026-01-26 07:41:33 +03:00
This PR adds the functionality to enhance Apache configuration to include HTTP Strict Transport Security header with a low initial max-age value. The max-age value will get increased on every (scheduled) run of certbot renew regardless of the certificate actually getting renewed, if the last increase took place longer than ten hours ago. The increase steps are visible in constants.AUTOHSTS_STEPS. Upon the first actual renewal after reaching the maximum increase step, the max-age value will be made "permanent" and will get value of one year. To achieve accurate VirtualHost discovery on subsequent runs, a comment with unique id string will be added to each enhanced VirtualHost. * AutoHSTS code rebased on master * Fixes to match the changes in master * Make linter happy with metaclass registration * Address small review comments * Use new enhancement interfaces * New style enhancement changes * Do not allow --hsts and --auto-hsts simultaneuously * MyPy annotation fixes and added test * Change oldest requrements to point to local certbot core version * Enable new style enhancements for run and install verbs * Test refactor * New test class for main.install tests * Move a test to a correct test class
107 lines
3.1 KiB
Python
107 lines
3.1 KiB
Python
""" Utility functions for certbot-apache plugin """
|
|
import binascii
|
|
import os
|
|
|
|
from certbot import util
|
|
|
|
def get_mod_deps(mod_name):
|
|
"""Get known module dependencies.
|
|
|
|
.. note:: This does not need to be accurate in order for the client to
|
|
run. This simply keeps things clean if the user decides to revert
|
|
changes.
|
|
.. warning:: If all deps are not included, it may cause incorrect parsing
|
|
behavior, due to enable_mod's shortcut for updating the parser's
|
|
currently defined modules (`.ApacheParser.add_mod`)
|
|
This would only present a major problem in extremely atypical
|
|
configs that use ifmod for the missing deps.
|
|
|
|
"""
|
|
deps = {
|
|
"ssl": ["setenvif", "mime"]
|
|
}
|
|
return deps.get(mod_name, [])
|
|
|
|
|
|
def get_file_path(vhost_path):
|
|
"""Get file path from augeas_vhost_path.
|
|
|
|
Takes in Augeas path and returns the file name
|
|
|
|
:param str vhost_path: Augeas virtual host path
|
|
|
|
:returns: filename of vhost
|
|
:rtype: str
|
|
|
|
"""
|
|
if not vhost_path or not vhost_path.startswith("/files/"):
|
|
return None
|
|
|
|
return _split_aug_path(vhost_path)[0]
|
|
|
|
|
|
def get_internal_aug_path(vhost_path):
|
|
"""Get the Augeas path for a vhost with the file path removed.
|
|
|
|
:param str vhost_path: Augeas virtual host path
|
|
|
|
:returns: Augeas path to vhost relative to the containing file
|
|
:rtype: str
|
|
|
|
"""
|
|
return _split_aug_path(vhost_path)[1]
|
|
|
|
|
|
def _split_aug_path(vhost_path):
|
|
"""Splits an Augeas path into a file path and an internal path.
|
|
|
|
After removing "/files", this function splits vhost_path into the
|
|
file path and the remaining Augeas path.
|
|
|
|
:param str vhost_path: Augeas virtual host path
|
|
|
|
:returns: file path and internal Augeas path
|
|
:rtype: `tuple` of `str`
|
|
|
|
"""
|
|
# Strip off /files
|
|
file_path = vhost_path[6:]
|
|
internal_path = []
|
|
|
|
# Remove components from the end of file_path until it becomes valid
|
|
while not os.path.exists(file_path):
|
|
file_path, _, internal_path_part = file_path.rpartition("/")
|
|
internal_path.append(internal_path_part)
|
|
|
|
return file_path, "/".join(reversed(internal_path))
|
|
|
|
|
|
def parse_define_file(filepath, varname):
|
|
""" Parses Defines from a variable in configuration file
|
|
|
|
:param str filepath: Path of file to parse
|
|
:param str varname: Name of the variable
|
|
|
|
:returns: Dict of Define:Value pairs
|
|
:rtype: `dict`
|
|
|
|
"""
|
|
return_vars = {}
|
|
# Get list of words in the variable
|
|
a_opts = util.get_var_from_file(varname, filepath).split()
|
|
for i, v in enumerate(a_opts):
|
|
# Handle Define statements and make sure it has an argument
|
|
if v == "-D" and len(a_opts) >= i+2:
|
|
var_parts = a_opts[i+1].partition("=")
|
|
return_vars[var_parts[0]] = var_parts[2]
|
|
elif len(v) > 2 and v.startswith("-D"):
|
|
# Found var with no whitespace separator
|
|
var_parts = v[2:].partition("=")
|
|
return_vars[var_parts[0]] = var_parts[2]
|
|
return return_vars
|
|
|
|
|
|
def unique_id():
|
|
""" Returns an unique id to be used as a VirtualHost identifier"""
|
|
return binascii.hexlify(os.urandom(16)).decode("utf-8")
|