mirror of
https://github.com/certbot/certbot.git
synced 2026-01-26 07:41:33 +03:00
1
docs/.gitignore
vendored
Normal file
1
docs/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
_build/
|
||||
183
docs/Makefile
Normal file
183
docs/Makefile
Normal file
@@ -0,0 +1,183 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
endif
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/LetsEncrypt.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/LetsEncrypt.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/LetsEncrypt"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/LetsEncrypt"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
coverage:
|
||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||
@echo "Testing of coverage in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/coverage/python.txt."
|
||||
|
||||
xml:
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
||||
5
docs/api/client/CONFIG.rst
Normal file
5
docs/api/client/CONFIG.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.CONFIG`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.CONFIG
|
||||
:members:
|
||||
5
docs/api/client/acme.rst
Normal file
5
docs/api/client/acme.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.acme`
|
||||
------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.acme
|
||||
:members:
|
||||
5
docs/api/client/apache_configurator.rst
Normal file
5
docs/api/client/apache_configurator.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.apache_configurator`
|
||||
---------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.apache_configurator
|
||||
:members:
|
||||
5
docs/api/client/augeas_configurator.rst
Normal file
5
docs/api/client/augeas_configurator.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.augeas_configurator`
|
||||
---------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.augeas_configurator
|
||||
:members:
|
||||
5
docs/api/client/challenge.rst
Normal file
5
docs/api/client/challenge.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.challenge`
|
||||
-----------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.challenge
|
||||
:members:
|
||||
5
docs/api/client/client.rst
Normal file
5
docs/api/client/client.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.client`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.client
|
||||
:members:
|
||||
5
docs/api/client/configurator.rst
Normal file
5
docs/api/client/configurator.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.configurator`
|
||||
--------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.configurator
|
||||
:members:
|
||||
5
docs/api/client/crypto_util.rst
Normal file
5
docs/api/client/crypto_util.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.crypto_util`
|
||||
-------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.crypto_util
|
||||
:members:
|
||||
5
docs/api/client/display.rst
Normal file
5
docs/api/client/display.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.display`
|
||||
---------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.display
|
||||
:members:
|
||||
5
docs/api/client/errors.rst
Normal file
5
docs/api/client/errors.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.errors`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.errors
|
||||
:members:
|
||||
5
docs/api/client/index.rst
Normal file
5
docs/api/client/index.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client`
|
||||
-------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client
|
||||
:members:
|
||||
5
docs/api/client/interactive_challenge.rst
Normal file
5
docs/api/client/interactive_challenge.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.interactive_challenge`
|
||||
-----------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.interactive_challenge
|
||||
:members:
|
||||
5
docs/api/client/le_util.rst
Normal file
5
docs/api/client/le_util.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.le_util`
|
||||
---------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.le_util
|
||||
:members:
|
||||
5
docs/api/client/logger.rst
Normal file
5
docs/api/client/logger.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.logger`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.logger
|
||||
:members:
|
||||
5
docs/api/client/nginx_configurator.rst
Normal file
5
docs/api/client/nginx_configurator.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.nginx_configurator`
|
||||
--------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.nginx_configurator
|
||||
:members:
|
||||
5
docs/api/client/recovery_contact_challenge.rst
Normal file
5
docs/api/client/recovery_contact_challenge.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.recovery_contact_challenge`
|
||||
----------------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.recovery_contact_challenge
|
||||
:members:
|
||||
5
docs/api/client/recovery_token_challenge.rst
Normal file
5
docs/api/client/recovery_token_challenge.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.recovery_token_challenge`
|
||||
--------------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.recovery_token_challenge
|
||||
:members:
|
||||
5
docs/api/client/validator.rst
Normal file
5
docs/api/client/validator.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
:mod:`letsencrypt.client.validator`
|
||||
-----------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.validator
|
||||
:members:
|
||||
289
docs/conf.py
Normal file
289
docs/conf.py
Normal file
@@ -0,0 +1,289 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Let's Encrypt documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Nov 23 20:35:21 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Let\'s Encrypt'
|
||||
copyright = u'2014, Let\'s Encrypt Project'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Language to be used for generating the HTML full-text search index.
|
||||
# Sphinx supports the following languages:
|
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
||||
#html_search_language = 'en'
|
||||
|
||||
# A dictionary with options for the search language support, empty by default.
|
||||
# Now only 'ja' uses this config value
|
||||
#html_search_options = {'type': 'default'}
|
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that
|
||||
# implements a search results scorer. If empty, the default will be used.
|
||||
#html_search_scorer = 'scorer.js'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'LetsEncryptdoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'LetsEncrypt.tex', u'Let\'s Encrypt Documentation',
|
||||
u'Let\'s Encrypt Project', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'letsencrypt', u'Let\'s Encrypt Documentation',
|
||||
[u'Let\'s Encrypt Project'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'LetsEncrypt', u'Let\'s Encrypt Documentation',
|
||||
u'Let\'s Encrypt Project', 'LetsEncrypt', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'http://docs.python.org/': None}
|
||||
|
||||
todo_include_todos = True
|
||||
24
docs/index.rst
Normal file
24
docs/index.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
.. Let's Encrypt documentation master file, created by
|
||||
sphinx-quickstart on Sun Nov 23 20:35:21 2014.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to Let's Encrypt's documentation!
|
||||
=========================================
|
||||
|
||||
API documentation
|
||||
-----------------
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
api/**
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
263
docs/make.bat
Normal file
263
docs/make.bat
Normal file
@@ -0,0 +1,263 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
echo. coverage to run coverage check of the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
REM Check if sphinx-build is available and fallback to Python version if any
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 goto sphinx_python
|
||||
goto sphinx_ok
|
||||
|
||||
:sphinx_python
|
||||
|
||||
set SPHINXBUILD=python -m sphinx.__init__
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:sphinx_ok
|
||||
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\LetsEncrypt.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\LetsEncrypt.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "coverage" (
|
||||
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of coverage in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/coverage/python.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
@@ -1,62 +1,83 @@
|
||||
"""Config for Let's Encrypt."""
|
||||
import os.path
|
||||
|
||||
# CA hostname
|
||||
# If you create your own server... change this line
|
||||
# Note: the server certificate must be trusted in order to avoid
|
||||
# further modifications to the client
|
||||
|
||||
ACME_SERVER = "letsencrypt-demo.org"
|
||||
# Apache server root directory
|
||||
"""CA hostname.
|
||||
|
||||
If you create your own server... change this line
|
||||
|
||||
Note: the server certificate must be trusted in order to avoid
|
||||
further modifications to the client."""
|
||||
|
||||
SERVER_ROOT = "/etc/apache2/"
|
||||
# Configuration file directory for letsencrypt
|
||||
"""Apache server root directory"""
|
||||
|
||||
CONFIG_DIR = "/etc/letsencrypt/"
|
||||
# Working directory for letsencrypt
|
||||
"""Configuration file directory for letsencrypt"""
|
||||
|
||||
WORK_DIR = "/var/lib/letsencrypt/"
|
||||
# Directory where configuration backups are stored
|
||||
"""Working directory for letsencrypt"""
|
||||
|
||||
BACKUP_DIR = os.path.join(WORK_DIR, "backups/")
|
||||
# Replaces MODIFIED_FILES, directory where temp checkpoint is created
|
||||
"""Directory where configuration backups are stored"""
|
||||
|
||||
TEMP_CHECKPOINT_DIR = os.path.join(WORK_DIR, "temp_checkpoint/")
|
||||
# Directory used before a permanent checkpoint is finalized
|
||||
"""Replaces MODIFIED_FILES, directory where temp checkpoint is created"""
|
||||
|
||||
IN_PROGRESS_DIR = os.path.join(BACKUP_DIR, "IN_PROGRESS/")
|
||||
# Directory where all certificates/keys are stored - used for easy revocation
|
||||
"""Directory used before a permanent checkpoint is finalized"""
|
||||
|
||||
CERT_KEY_BACKUP = os.path.join(WORK_DIR, "keys-certs/")
|
||||
# Where all keys should be stored
|
||||
"""Directory where all certificates/keys are stored.
|
||||
|
||||
Used for easy revocation"""
|
||||
|
||||
KEY_DIR = os.path.join(SERVER_ROOT, "ssl/")
|
||||
# Certificate storage
|
||||
"""Where all keys should be stored"""
|
||||
|
||||
CERT_DIR = os.path.join(SERVER_ROOT, "certs/")
|
||||
"""Certificate storage"""
|
||||
|
||||
# Contains standard Apache SSL directives
|
||||
OPTIONS_SSL_CONF = os.path.join(CONFIG_DIR, "options-ssl.conf")
|
||||
# Let's Encrypt SSL vhost configuration extension
|
||||
"""Contains standard Apache SSL directives"""
|
||||
|
||||
LE_VHOST_EXT = "-le-ssl.conf"
|
||||
# Temporary file for challenge virtual hosts
|
||||
"""Let's Encrypt SSL vhost configuration extension"""
|
||||
|
||||
APACHE_CHALLENGE_CONF = os.path.join(CONFIG_DIR, "le_dvsni_cert_challenge.conf")
|
||||
"""Temporary file for challenge virtual hosts"""
|
||||
|
||||
# Byte size of S and Nonce
|
||||
S_SIZE = 32
|
||||
"""Byte size of S"""
|
||||
|
||||
NONCE_SIZE = 16
|
||||
"""byte size of Nonce"""
|
||||
|
||||
# Key Sizes
|
||||
RSA_KEY_SIZE = 2048
|
||||
"""Key size"""
|
||||
|
||||
# bits of hashcash to generate
|
||||
DIFFICULTY = 23
|
||||
"""bits of hashcash to generate"""
|
||||
|
||||
# Let's Encrypt cert and chain files
|
||||
CERT_PATH = CERT_DIR + "cert-letsencrypt.pem"
|
||||
"""Let's Encrypt cert file."""
|
||||
|
||||
CHAIN_PATH = CERT_DIR + "chain-letsencrypt.pem"
|
||||
"""Let's Encrypt chain file."""
|
||||
|
||||
# Invalid Extension
|
||||
INVALID_EXT = ".acme.invalid"
|
||||
"""Invalid Extension"""
|
||||
|
||||
# Challenge Preferences Dict for currently supported challenges
|
||||
CHALLENGE_PREFERENCES = ["dvsni", "recoveryToken"]
|
||||
"""Challenge Preferences Dict for currently supported challenges"""
|
||||
|
||||
# Mutually Exclusive Challenges - only solve 1
|
||||
EXCLUSIVE_CHALLENGES = [frozenset(["dvsni", "simpleHttps"])]
|
||||
"""Mutually Exclusive Challenges - only solve 1"""
|
||||
|
||||
# These are challenges that must be solved by a Configurator object
|
||||
CONFIG_CHALLENGES = frozenset(["dvsni", "simpleHttps"])
|
||||
"""These are challenges that must be solved by a Configurator object"""
|
||||
|
||||
# Rewrite rule arguments used for redirections to https vhost
|
||||
REWRITE_HTTPS_ARGS = [
|
||||
"^.*$", "https://%{SERVER_NAME}%{REQUEST_URI}", "[L,R=permanent]"]
|
||||
"""Rewrite rule arguments used for redirections to https vhost"""
|
||||
|
||||
@@ -29,12 +29,10 @@ SCHEMATA = dict([
|
||||
def acme_object_validate(json_string, schemata=None):
|
||||
"""Validate a JSON string against the ACME protocol using JSON Schema.
|
||||
|
||||
:param json_string: Well-formed input JSON string.
|
||||
:type json_string: str
|
||||
:param str json_string: Well-formed input JSON string.
|
||||
|
||||
:param schemata: Mapping from type name to JSON Schema definition.
|
||||
Useful for testing.
|
||||
:type schemata: dict
|
||||
:param dict schemata: Mapping from type name to JSON Schema
|
||||
definition. Useful for testing.
|
||||
|
||||
:returns: None if validation was successful.
|
||||
|
||||
@@ -66,14 +64,12 @@ def pretty(json_string):
|
||||
def challenge_request(name):
|
||||
"""Create ACME "challengeRequest message.
|
||||
|
||||
:param name: Domain name
|
||||
:type name: unicode
|
||||
:param unicode name: Domain name
|
||||
|
||||
:returns: ACME "challengeRequest" message.
|
||||
:rtype: dict
|
||||
|
||||
"""
|
||||
|
||||
return {
|
||||
"type": "challengeRequest",
|
||||
"identifier": name,
|
||||
@@ -84,19 +80,10 @@ def authorization_request(req_id, name, server_nonce, responses, key_file):
|
||||
"""Create ACME "authorizationRequest" message.
|
||||
|
||||
:param req_id: TODO
|
||||
:type req_id: TODO
|
||||
|
||||
:param name: TODO
|
||||
:type name: TODO
|
||||
|
||||
:param server_nonce: TODO
|
||||
:type server_nonce: TODO
|
||||
|
||||
:param responses: TODO
|
||||
:type response: TODO
|
||||
|
||||
:param key_file: TODO
|
||||
:type key_file: TODO
|
||||
|
||||
:returns: ACME "authorizationRequest" message.
|
||||
:rtype: dict
|
||||
@@ -115,11 +102,8 @@ def authorization_request(req_id, name, server_nonce, responses, key_file):
|
||||
def certificate_request(csr_der, key):
|
||||
"""Create ACME "certificateRequest" message.
|
||||
|
||||
:param csr_der: DER encoded CSR.
|
||||
:type csr_der: str
|
||||
|
||||
:param str csr_der: DER encoded CSR.
|
||||
:param key: TODO
|
||||
:type key: TODO
|
||||
|
||||
:returns: ACME "certificateRequest" message.
|
||||
:rtype: dict
|
||||
@@ -135,12 +119,10 @@ def certificate_request(csr_der, key):
|
||||
def revocation_request(key_file, cert_der):
|
||||
"""Create ACME "revocationRequest" message.
|
||||
|
||||
:param key_file: Path to a file containing RSA key. Accepted formats
|
||||
are the same as for `Crypto.PublicKey.RSA.importKey`.
|
||||
:type key_file: str
|
||||
:param str key_file: Path to a file containing RSA key. Accepted
|
||||
formats are the same as for `Crypto.PublicKey.RSA.importKey`.
|
||||
|
||||
:param cert_der: DER encoded certificate.
|
||||
:type cert_der: str
|
||||
:param str cert_der: DER encoded certificate.
|
||||
|
||||
:returns: ACME "revocationRequest" message.
|
||||
:rtype: dict
|
||||
@@ -156,8 +138,7 @@ def revocation_request(key_file, cert_der):
|
||||
def status_request(token):
|
||||
"""Create ACME "statusRequest" message.
|
||||
|
||||
:param token: Token provided in ACME "defer" message.
|
||||
:type token: str
|
||||
:param str token: Token provided in ACME "defer" message.
|
||||
|
||||
:returns: ACME "statusRequest" message.
|
||||
:rtype: dict
|
||||
|
||||
@@ -44,6 +44,8 @@ from letsencrypt.client import logger
|
||||
# transactional due to the use of register_file_creation()
|
||||
|
||||
class VH(object):
|
||||
"""Virtual host."""
|
||||
|
||||
def __init__(self, filename_path, vh_path, vh_addrs, is_ssl, is_enabled):
|
||||
self.file = filename_path
|
||||
self.path = vh_path
|
||||
@@ -129,25 +131,22 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
"""Deploys certificate to specified virtual host.
|
||||
|
||||
Currently tries to find the last directives to deploy the cert in
|
||||
the given virtualhost. If it can't find the directives, it searches
|
||||
the "included" confs. The function verifies that it has located
|
||||
the given virtualhost. If it can't find the directives, it searches
|
||||
the "included" confs. The function verifies that it has located
|
||||
the three directives and finally modifies them to point to the correct
|
||||
destination
|
||||
TODO: Make sure last directive is changed
|
||||
TODO: Might be nice to remove chain directive if none exists
|
||||
* This shouldn't happen within letsencrypt though
|
||||
|
||||
.. todo:: Make sure last directive is changed
|
||||
|
||||
.. todo:: Might be nice to remove chain directive if none exists
|
||||
This shouldn't happen within letsencrypt though
|
||||
|
||||
:param vhost: ssl vhost to deploy certificate
|
||||
:type vhost: VH
|
||||
:type vhost: :class:`VH`
|
||||
|
||||
:param cert: certificate filename
|
||||
:type cert: str
|
||||
|
||||
:param key: private key filename
|
||||
:type key: str
|
||||
|
||||
:param cert_chain: certificate chain filename
|
||||
:type cert_chain: str
|
||||
:param strcert: certificate filename
|
||||
:param str key: private key filename
|
||||
:param str cert_chain: certificate chain filename
|
||||
|
||||
:returns: Success
|
||||
:rtype: bool
|
||||
@@ -196,13 +195,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
def choose_virtual_host(self, name, ssl=True):
|
||||
""" Chooses a virtual host based on the given domain name.
|
||||
|
||||
TODO: This should maybe return list if no obvious answer is presented
|
||||
.. todo:: This should maybe return list if no obvious answer is presented
|
||||
|
||||
:param name: domain name
|
||||
:type name: str
|
||||
:param str name: domain name
|
||||
|
||||
:returns: ssl vhost associated with name
|
||||
:rtype: VH
|
||||
:rtype: :class:`VH`
|
||||
|
||||
"""
|
||||
# Allows for domain names to be associated with a virtual host
|
||||
@@ -244,11 +242,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
|
||||
Helps to choose an appropriate vhost
|
||||
|
||||
:param domain: domain name to associate
|
||||
:type domain: str
|
||||
:param str domain: domain name to associate
|
||||
|
||||
:param vhost: virtual host to associate with domain
|
||||
:type vhost: VH
|
||||
:type vhost: :class:`VH`
|
||||
|
||||
"""
|
||||
self.assoc[domain] = vhost
|
||||
@@ -257,7 +254,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
"""Returns all names found in the Apache Configuration.
|
||||
|
||||
:returns: All ServerNames, ServerAliases, and reverse DNS entries for
|
||||
virtual host addresses
|
||||
virtual host addresses
|
||||
:rtype: set
|
||||
|
||||
"""
|
||||
@@ -286,10 +283,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
def _set_user_config_file(self, filename=''):
|
||||
"""Set the appropriate user configuration file
|
||||
|
||||
TODO: This will have to be updated for other distros versions
|
||||
.. todo:: This will have to be updated for other distros versions
|
||||
|
||||
:param filename: optional filename that will be used as the user config
|
||||
:type filename: str
|
||||
:param str filename: optional filename that will be used as the user config
|
||||
|
||||
"""
|
||||
if filename:
|
||||
@@ -309,7 +305,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
"""Helper function for get_virtual_hosts().
|
||||
|
||||
:param host: In progress vhost whose names will be added
|
||||
:type host: VH
|
||||
:type host: :class:`VH`
|
||||
|
||||
"""
|
||||
nameMatch = self.aug.match(("%s//*[self::directive=~regexp('%s')] | "
|
||||
@@ -326,11 +322,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
def _create_vhost(self, path):
|
||||
"""Used by get_virtual_hosts to create vhost objects
|
||||
|
||||
:param path: Augeas path to virtual host
|
||||
:type path: str
|
||||
:param str path: Augeas path to virtual host
|
||||
|
||||
:returns: newly created vhost
|
||||
:rtype: VH
|
||||
:rtype: :class:`VH`
|
||||
|
||||
"""
|
||||
addrs = []
|
||||
@@ -353,7 +348,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
def get_virtual_hosts(self):
|
||||
"""Returns list of virtual hosts found in the Apache configuration.
|
||||
|
||||
:returns: List of VH objects found in configuration
|
||||
:returns: List of :class:`VH` objects found in configuration
|
||||
:rtype: list
|
||||
|
||||
"""
|
||||
@@ -372,8 +367,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
|
||||
Checks if addr has a NameVirtualHost directive in the Apache config
|
||||
|
||||
:param addr: vhost address ie. *:443
|
||||
:type addr: str
|
||||
:param str addr: vhost address ie. \*:443
|
||||
|
||||
:returns: Success
|
||||
:rtype: bool
|
||||
@@ -403,8 +397,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
Directive is added to ports.conf unless the file doesn't exist
|
||||
It is added to httpd.conf as a backup
|
||||
|
||||
:param addr: Address that will be added as NameVirtualHost directive
|
||||
:type addr: str
|
||||
:param str addr: Address that will be added as NameVirtualHost directive
|
||||
|
||||
"""
|
||||
aug_file_path = "/files%sports.conf" % self.server_root
|
||||
@@ -429,14 +422,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
an IfMod mod_ssl.c block. If the IfMod block does not exist in
|
||||
the file, it is created.
|
||||
|
||||
:param aug_conf_path: Desired Augeas config path to add directive
|
||||
:type aug_conf_path: str
|
||||
|
||||
:param directive: Directive you would like to add
|
||||
:type directive: str
|
||||
|
||||
:param val: Value of directive ie. Listen 443, 443 is the value
|
||||
:type val: str
|
||||
:param str aug_conf_path: Desired Augeas config path to add directive
|
||||
:param str directive: Directive you would like to add
|
||||
:param str val: Value of directive ie. Listen 443, 443 is the value
|
||||
|
||||
"""
|
||||
# TODO: Add error checking code... does the path given even exist?
|
||||
@@ -451,13 +439,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
def make_server_sni_ready(self, vhost, default_addr="*:443"):
|
||||
"""Checks to see if the server is ready for SNI challenges.
|
||||
|
||||
TODO: This should largely depend on the version of Apache
|
||||
.. todo:: This should largely depend on the version of Apache
|
||||
|
||||
:param vhost: VHost to check SNI compatibility
|
||||
:type vhost: VH
|
||||
:type vhost: :class:`VH`
|
||||
|
||||
:param default_addr: TODO - investigate function further
|
||||
:type default_addr: str
|
||||
:param str default_addr: TODO - investigate function further
|
||||
|
||||
"""
|
||||
# Check if mod_ssl is loaded
|
||||
@@ -498,11 +485,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
def get_ifmod(self, aug_conf_path, mod):
|
||||
"""Returns the path to <IfMod mod> and creates one if it doesn't exist.
|
||||
|
||||
:param aug_conf_path: Augeas configuration path
|
||||
:type aug_conf_path: str
|
||||
|
||||
:param mod: module ie. mod_ssl.c
|
||||
:type mod: str
|
||||
:param str aug_conf_path: Augeas configuration path
|
||||
:param str mod: module ie. mod_ssl.c
|
||||
|
||||
"""
|
||||
ifMods = self.aug.match(("%s/IfModule/*[self::arg='%s']" %
|
||||
@@ -520,14 +504,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
|
||||
Note: Not added to AugeasConfigurator because it may depend on the lens
|
||||
|
||||
:param aug_conf_path: Augeas configuration path to add directive
|
||||
:type aug_conf_path: str
|
||||
:param str aug_conf_path: Augeas configuration path to add directive
|
||||
:param str directive: Directive to add
|
||||
:param str arg: Value of the directive. ie. Listen 443, 443 is arg
|
||||
|
||||
:param directive: Directive to add
|
||||
:type directive: str
|
||||
|
||||
:param arg: Value of the directive. ie. Listen 443, 443 is arg
|
||||
:type arg: str
|
||||
|
||||
"""
|
||||
self.aug.set(aug_conf_path + "/directive[last() + 1]", directive)
|
||||
@@ -544,7 +524,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
|
||||
Recursively searches through config files to find directives
|
||||
Directives should be in the form of a case insensitive regex currently
|
||||
TODO: arg should probably be a list
|
||||
|
||||
.. todo:: arg should probably be a list
|
||||
|
||||
Note: Augeas is inherently case sensitive while Apache is case
|
||||
insensitive. Augeas 1.0 allows case insensitive regexes like
|
||||
@@ -553,15 +534,13 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
transformation by calling case_i() on everything to maintain
|
||||
compatibility.
|
||||
|
||||
:param directive: Directive to look for
|
||||
:type directive: str
|
||||
:param str directive: Directive to look for
|
||||
|
||||
:param arg: Specific value direcitve must have, None if all should
|
||||
be considered
|
||||
:type arg: str or None
|
||||
|
||||
:param start: Beginning Augeas path to begin looking
|
||||
:type start: str
|
||||
:param str start: Beginning Augeas path to begin looking
|
||||
|
||||
"""
|
||||
# Cannot place member variable in the definition of the function so...
|
||||
@@ -606,13 +585,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
|
||||
Converts an Apache Include directive argument into an Augeas
|
||||
searchable path
|
||||
TODO: convert to use os.path.join()
|
||||
|
||||
:param cur_dir: current working directory
|
||||
:type cur_dir: str
|
||||
.. todo:: convert to use os.path.join()
|
||||
|
||||
:param arg: Argument of Include directive
|
||||
:type arg: str
|
||||
:param str cur_dir: current working directory
|
||||
|
||||
:param str arg: Argument of Include directive
|
||||
|
||||
:returns: Augeas path string
|
||||
:rtype: str
|
||||
@@ -676,7 +654,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
"""Checks to see if mod_ssl is loaded
|
||||
|
||||
Currently uses apache2ctl to get loaded module list
|
||||
TODO: This function is likely fragile to versions/distros
|
||||
|
||||
.. todo:: This function is likely fragile to versions/distros
|
||||
|
||||
:returns: If ssl_module is included and active in Apache
|
||||
:rtype: bool
|
||||
@@ -704,10 +683,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
New vhost will reside as (nonssl_vhost.path) + CONFIG.LE_VHOST_EXT
|
||||
|
||||
:param nonssl_vhost: Valid VH that doesn't have SSLEngine on
|
||||
:type nonssl_vhost: VH
|
||||
:type nonssl_vhost: :class:`VH`
|
||||
|
||||
:returns: SSL vhost
|
||||
:rtype: VH
|
||||
:rtype: :class:`VH`
|
||||
|
||||
"""
|
||||
avail_fp = nonssl_vhost.file
|
||||
@@ -809,10 +788,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
The function then adds the directive
|
||||
|
||||
:param ssl_vhost: Destination of traffic, an ssl enabled vhost
|
||||
:type ssl_vhost: VH
|
||||
:type ssl_vhost: :class:`VH`
|
||||
|
||||
:returns: Success, general_vhost (HTTP vhost)
|
||||
:rtype: bool, VH
|
||||
:rtype: (bool, :class:`VH`)
|
||||
|
||||
"""
|
||||
# TODO: Enable check to see if it is already there
|
||||
@@ -858,7 +837,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
-1 is also returned in case of no redirection/rewrite directives
|
||||
|
||||
:param vhost: vhost to check
|
||||
:type vhost: VH
|
||||
:type vhost: :class:`VH`
|
||||
|
||||
:returns: Success, code value... see documentation
|
||||
:rtype: bool, int
|
||||
@@ -889,10 +868,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
"""Creates an http_vhost specifically to redirect for the ssl_vhost.
|
||||
|
||||
:param ssl_vhost: ssl vhost
|
||||
:type ssl_vhost: VH
|
||||
:type ssl_vhost: :class:`VH`
|
||||
|
||||
:returns: Success, vhost
|
||||
:rtype: bool, VH
|
||||
:rtype: (bool, :class:`VH`)
|
||||
|
||||
"""
|
||||
# Consider changing this to a dictionary check
|
||||
@@ -973,7 +952,7 @@ LogLevel warn \n\
|
||||
if not conflict: returns space separated list of new host addrs
|
||||
|
||||
:param ssl_vhost: SSL Vhost to check for possible port 80 redirection
|
||||
:type ssl_vhost: VH
|
||||
:type ssl_vhost: :class:`VH`
|
||||
|
||||
:returns: TODO
|
||||
:rtype: TODO
|
||||
@@ -1012,10 +991,10 @@ LogLevel warn \n\
|
||||
Consider changing this into a dict check
|
||||
|
||||
:param ssl_vhost: ssl vhost to check
|
||||
:type ssl_vhost: VH
|
||||
:type ssl_vhost: :class:`VH`
|
||||
|
||||
:returns: HTTP vhost or None if unsuccessful
|
||||
:rtype: VH or None
|
||||
:rtype: :class:`VH` or None
|
||||
|
||||
"""
|
||||
# _default_:443 check
|
||||
@@ -1090,8 +1069,7 @@ LogLevel warn \n\
|
||||
|
||||
Takes in Augeas path and returns the file name
|
||||
|
||||
:param vhost_path: Augeas virtual host path
|
||||
:type vhost_path: str
|
||||
:param str vhost_path: Augeas virtual host path
|
||||
|
||||
:returns: filename of vhost
|
||||
:rtype: str
|
||||
@@ -1116,10 +1094,9 @@ LogLevel warn \n\
|
||||
def is_site_enabled(self, avail_fp):
|
||||
"""Checks to see if the given site is enabled.
|
||||
|
||||
TODO: fix hardcoded sites-enabled
|
||||
.. todo:: fix hardcoded sites-enabled
|
||||
|
||||
:param avail_fp: Complete file path of available site
|
||||
:type avail_fp: str
|
||||
:param str avail_fp: Complete file path of available site
|
||||
|
||||
:returns: Success
|
||||
:rtype: bool
|
||||
@@ -1135,11 +1112,12 @@ LogLevel warn \n\
|
||||
def enable_site(self, vhost):
|
||||
"""Enables an available site, Apache restart required.
|
||||
|
||||
TODO: This function should number subdomains before the domain vhost
|
||||
TODO: Make sure link is not broken...
|
||||
.. todo:: This function should number subdomains before the domain vhost
|
||||
|
||||
.. todo:: Make sure link is not broken...
|
||||
|
||||
:param vhost: vhost to enable
|
||||
:type vhost: VH
|
||||
:type vhost: :class:`VH`
|
||||
|
||||
:returns: Success
|
||||
:rtype: bool
|
||||
@@ -1164,8 +1142,7 @@ LogLevel warn \n\
|
||||
|
||||
Both enables and restarts Apache so module is active.
|
||||
|
||||
:param mod_name: Name of the module to enable
|
||||
:type mod_name: str
|
||||
:param str mod_name: Name of the module to enable
|
||||
|
||||
"""
|
||||
try:
|
||||
@@ -1185,8 +1162,7 @@ LogLevel warn \n\
|
||||
def fnmatch_to_re(self, clean_fn_match):
|
||||
"""Method converts Apache's basic fnmatch to regular expression.
|
||||
|
||||
:param clean_fn_match: Apache style filename match, similar to globs
|
||||
:type clean_fn_match: str
|
||||
:param str clean_fn_match: Apache style filename match, similar to globs
|
||||
|
||||
:returns: regex suitable for augeas
|
||||
:rtype: str
|
||||
@@ -1212,8 +1188,7 @@ LogLevel warn \n\
|
||||
Checks to see if file_path is parsed by Augeas
|
||||
If file_path isn't parsed, the file is added and Augeas is reloaded
|
||||
|
||||
:param file_path: Apache config file path
|
||||
:type file_path: str
|
||||
:param str file_path: Apache config file path
|
||||
|
||||
"""
|
||||
# Test if augeas included file for Httpd.lens
|
||||
@@ -1313,8 +1288,7 @@ LogLevel warn \n\
|
||||
This function will correctly add a transform to augeas
|
||||
The existing augeas.add_transform in python is broken.
|
||||
|
||||
:param incl: TODO
|
||||
:type incl: str
|
||||
:param str incl: TODO
|
||||
|
||||
"""
|
||||
lastInclude = self.aug.match("/augeas/load/Httpd/incl [last()]")
|
||||
@@ -1354,8 +1328,7 @@ LogLevel warn \n\
|
||||
def perform(self, chall_dict):
|
||||
"""Perform the configuration related challenge.
|
||||
|
||||
:param chall_dict: Dictionary representing a challenge.
|
||||
:type chall_dict: dict
|
||||
:param dict chall_dict: Dictionary representing a challenge.
|
||||
|
||||
"""
|
||||
|
||||
@@ -1366,13 +1339,16 @@ LogLevel warn \n\
|
||||
def dvsni_perform(self, chall_dict):
|
||||
"""Peform a DVSNI challenge.
|
||||
|
||||
Composed of
|
||||
listSNITuple: List of tuples with form (addr, r, nonce)
|
||||
addr (string), r (base64 string), nonce (hex string)
|
||||
dvsni_key: string - File path to key
|
||||
Composed of:
|
||||
|
||||
:param chall_dict: dvsni challenge - see documentation
|
||||
:type chall_dict: dict
|
||||
listSNITuple
|
||||
List of tuples with form (addr, r, nonce)
|
||||
addr (string), r (base64 string), nonce (hex string)
|
||||
|
||||
dvsni_key
|
||||
string - File path to key
|
||||
|
||||
:param dict chall_dict: dvsni challenge - see documentation
|
||||
|
||||
"""
|
||||
# Save any changes to the configuration as a precaution
|
||||
@@ -1437,8 +1413,7 @@ LogLevel warn \n\
|
||||
def dvsni_get_cert_file(self, nonce):
|
||||
"""Returns standardized name for challenge certificate.
|
||||
|
||||
:param nonce: hex form of nonce
|
||||
:type nonce: str
|
||||
:param str nonce: hex form of nonce
|
||||
|
||||
:returns: certificate file name
|
||||
:rtype: str
|
||||
@@ -1449,14 +1424,9 @@ LogLevel warn \n\
|
||||
def _get_config_text(self, nonce, ip_addrs, key):
|
||||
"""Chocolate virtual server configuration text
|
||||
|
||||
:param nonce: hex form of nonce
|
||||
:type nonce: str
|
||||
|
||||
:param ip_addrs: addresses of challenged domain
|
||||
:type ip_addrs: str
|
||||
|
||||
:param key: file path to key
|
||||
:type key: str
|
||||
:param str nonce: hex form of nonce
|
||||
:param str ip_addrs: addresses of challenged domain
|
||||
:param str key: file path to key
|
||||
|
||||
:returns: virtual host configuration text
|
||||
:rtype: str
|
||||
@@ -1483,18 +1453,14 @@ LogLevel warn \n\
|
||||
|
||||
Result: Apache config includes virtual servers for issued challs
|
||||
|
||||
:param mainConfig: file path to Apache user config file
|
||||
:type mainConfig: str
|
||||
:param str mainConfig: file path to Apache user config file
|
||||
|
||||
:param listSNITuple: list of tuples with the form (addr, y, nonce)
|
||||
addr (string), y (byte array), nonce (hex string)
|
||||
:type listSNITuple: lsit
|
||||
:param list listSNITuple: list of tuples with the form (addr, y, nonce)
|
||||
addr (string), y (byte array), nonce (hex string)
|
||||
|
||||
:param dvsni_key: file path to key
|
||||
:type dvsni_key: str
|
||||
:param str dvsni_key: file path to key
|
||||
|
||||
:param listlistAddrs: list of list of addresses to apply
|
||||
:type listlistAddrs: list
|
||||
:param list listlistAddrs: list of list of addresses to apply
|
||||
|
||||
"""
|
||||
# WARNING: THIS IS A POTENTIAL SECURITY VULNERABILITY
|
||||
@@ -1527,8 +1493,7 @@ LogLevel warn \n\
|
||||
Adds DVSNI challenge include file if it does not already exist
|
||||
within mainConfig
|
||||
|
||||
:param mainConfig: file path to main user apache config file
|
||||
:type mainConfig: str
|
||||
:param str mainConfig: file path to main user apache config file
|
||||
|
||||
"""
|
||||
if len(self.find_directive(
|
||||
@@ -1542,11 +1507,8 @@ LogLevel warn \n\
|
||||
|
||||
Certificate created at dvsni_get_cert_file(nonce)
|
||||
|
||||
:param nonce: hex form of nonce
|
||||
:type nonce: str
|
||||
|
||||
:param key_file: absolute path to key file
|
||||
:type key: str
|
||||
:param str nonce: hex form of nonce
|
||||
:param str key_file: absolute path to key file
|
||||
|
||||
"""
|
||||
try:
|
||||
@@ -1567,11 +1529,8 @@ LogLevel warn \n\
|
||||
def dvsni_gen_ext(self, r, s):
|
||||
"""Generates z extension to be placed in certificate extension.
|
||||
|
||||
:param r: DVSNI r value
|
||||
:type r: byte array
|
||||
|
||||
:param s: DVSNI s value
|
||||
:type s: byte array
|
||||
:param bytearray r: DVSNI r value
|
||||
:param bytearray s: DVSNI s value
|
||||
|
||||
result: returns z + CONFIG.INVALID_EXT
|
||||
|
||||
@@ -1592,8 +1551,7 @@ def case_i(string):
|
||||
May be replaced by a more proper /i once augeas 1.0 is widely
|
||||
supported.
|
||||
|
||||
:param string: string to make case i regex
|
||||
:type string: str
|
||||
:param str string: string to make case i regex
|
||||
|
||||
"""
|
||||
return "".join(["["+c.upper()+c.lower()+"]"
|
||||
@@ -1603,10 +1561,10 @@ def case_i(string):
|
||||
def strip_dir(path):
|
||||
"""Returns directory of file path.
|
||||
|
||||
TODO: Replace this with Python standard function
|
||||
.. todo:: Replace this with Python standard function
|
||||
|
||||
:param path: path is a file path. not an augeas section or directive path
|
||||
:type path: str
|
||||
:param str path: path is a file path. not an augeas section or
|
||||
directive path
|
||||
|
||||
:returns: directory
|
||||
:rtype: str
|
||||
|
||||
@@ -12,6 +12,7 @@ from letsencrypt.client import logger
|
||||
|
||||
|
||||
class AugeasConfigurator(configurator.Configurator):
|
||||
"""Augeas configurator."""
|
||||
|
||||
def __init__(self):
|
||||
super(AugeasConfigurator, self).__init__()
|
||||
@@ -24,8 +25,7 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
def check_parsing_errors(self, lens):
|
||||
"""Verify Augeas can parse all of the lens files.
|
||||
|
||||
:param lens: lens to check for errors
|
||||
:type lens: str
|
||||
:param str lens: lens to check for errors
|
||||
|
||||
"""
|
||||
error_files = self.aug.match("/augeas//error")
|
||||
@@ -48,14 +48,12 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
all configuration changes made will be saved. According to the
|
||||
function parameters.
|
||||
|
||||
:param title: The title of the save. If a title is given, the
|
||||
configuration will be saved as a new checkpoint
|
||||
and put in a timestamped directory.
|
||||
:type title: str
|
||||
:param str title: The title of the save. If a title is given, the
|
||||
configuration will be saved as a new checkpoint and put in a
|
||||
timestamped directory.
|
||||
|
||||
:param temporary: Indicates whether the changes made will be quickly
|
||||
reversed in the future (ie. challenges)
|
||||
:type temporary: bool
|
||||
:param bool temporary: Indicates whether the changes made will
|
||||
be quickly reversed in the future (ie. challenges)
|
||||
|
||||
"""
|
||||
save_state = self.aug.get("/augeas/save")
|
||||
@@ -141,8 +139,7 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
def rollback_checkpoints(self, rollback=1):
|
||||
"""Revert 'rollback' number of configuration checkpoints.
|
||||
|
||||
:param rollback: Number of checkpoints to reverse
|
||||
:type rollback: int
|
||||
:param int rollback: Number of checkpoints to reverse
|
||||
|
||||
"""
|
||||
try:
|
||||
@@ -222,8 +219,7 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
Adds title to cp_dir CHANGES_SINCE
|
||||
Move cp_dir to Backups directory and rename with timestamp
|
||||
|
||||
:param cp_dir: "IN PROGRESS" directory
|
||||
:type cp_dir: str
|
||||
:param str cp_dir: "IN PROGRESS" directory
|
||||
|
||||
:returns: Success
|
||||
:rtype: bool
|
||||
@@ -250,11 +246,8 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
def add_to_checkpoint(self, cp_dir, save_files):
|
||||
"""Add save files to checkpoint directory.
|
||||
|
||||
:param cp_dir: Checkpoint directory filepath
|
||||
:type cp_dir: str
|
||||
|
||||
:param save_files: set of files to save
|
||||
:type save_files: set
|
||||
:param str cp_dir: Checkpoint directory filepath
|
||||
:param set save_files: set of files to save
|
||||
|
||||
"""
|
||||
le_util.make_or_verify_dir(cp_dir, 0o755)
|
||||
@@ -289,8 +282,7 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
Recover a specific checkpoint provided by cp_dir
|
||||
Note: this function does not reload augeas.
|
||||
|
||||
:param cp_dir: checkpoint directory file path
|
||||
:type cp_dir: str
|
||||
:param str cp_dir: checkpoint directory file path
|
||||
|
||||
:returns: 0 success, 1 Unable to revert, -1 Unable to delete
|
||||
:rtype: int
|
||||
@@ -322,8 +314,7 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
def check_tempfile_saves(self, save_files):
|
||||
"""Verify save isn't overwriting any temporary files.
|
||||
|
||||
:param save_files: Set of files about to be saved.
|
||||
:type save_files: set
|
||||
:param set save_files: Set of files about to be saved.
|
||||
|
||||
:returns: Success, error message
|
||||
:rtype: bool, str
|
||||
@@ -347,12 +338,10 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
file will be cleaned up if the program exits unexpectedly.
|
||||
(Before a save occurs)
|
||||
|
||||
:param temporary: If the file creation registry is for a temp or
|
||||
permanent save.
|
||||
:type temporary: bool
|
||||
:param bool temporary: If the file creation registry is for
|
||||
a temp or permanent save.
|
||||
|
||||
:param *files: file paths to be registered
|
||||
:type *files: str
|
||||
:param \*files: file paths (str) to be registered
|
||||
|
||||
"""
|
||||
if temporary:
|
||||
@@ -395,8 +384,7 @@ class AugeasConfigurator(configurator.Configurator):
|
||||
def _remove_contained_files(self, file_list):
|
||||
"""Erase all files contained within file_list.
|
||||
|
||||
:param file_list: file containing list of file paths to be deleted
|
||||
:type file_list: str
|
||||
:param str file_list: file containing list of file paths to be deleted
|
||||
|
||||
:returns: Success
|
||||
:rtype: bool
|
||||
|
||||
@@ -23,18 +23,16 @@ class Challenge(object):
|
||||
def gen_challenge_path(challenges, combos=None):
|
||||
"""Generate a plan to get authority over the identity.
|
||||
|
||||
TODO: Make sure that the challenges are feasible...
|
||||
Example: Do you have the recovery key?
|
||||
.. todo:: Make sure that the challenges are feasible...
|
||||
Example: Do you have the recovery key?
|
||||
|
||||
:param challenges: A list of challenges from ACME "challenge"
|
||||
server message to be fulfilled by the client
|
||||
in order to prove possession of the identifier.
|
||||
:type challenges: list
|
||||
:param list challenges: A list of challenges from ACME "challenge"
|
||||
server message to be fulfilled by the client in order to prove
|
||||
possession of the identifier.
|
||||
|
||||
:param combos: A collection of sets of challenges from ACME
|
||||
"challenge" server message ("combinations"),
|
||||
each of which would be sufficient to prove
|
||||
possession of the identifier.
|
||||
"challenge" server message ("combinations"), each of which would
|
||||
be sufficient to prove possession of the identifier.
|
||||
:type combos: list or None
|
||||
|
||||
:returns: List of indices from `challenges`.
|
||||
@@ -49,19 +47,17 @@ def gen_challenge_path(challenges, combos=None):
|
||||
|
||||
def _find_smart_path(challenges, combos):
|
||||
"""
|
||||
Can be called if combinations is included
|
||||
Can be called if combinations is included
|
||||
Function uses a simple ranking system to choose the combo with the
|
||||
lowest cost
|
||||
|
||||
:param challenges: A list of challenges from ACME "challenge"
|
||||
server message to be fulfilled by the client
|
||||
in order to prove possession of the identifier.
|
||||
:type challenges: list
|
||||
:param list challenges: A list of challenges from ACME "challenge"
|
||||
server message to be fulfilled by the client in order to prove
|
||||
possession of the identifier.
|
||||
|
||||
:param combos: A collection of sets of challenges from ACME
|
||||
"challenge" server message ("combinations"),
|
||||
each of which would be sufficient to prove
|
||||
possession of the identifier.
|
||||
"challenge" server message ("combinations"), each of which would
|
||||
be sufficient to prove possession of the identifier.
|
||||
:type combos: list or None
|
||||
|
||||
:returns: List of indices from `challenges`.
|
||||
@@ -102,10 +98,9 @@ def _find_dumb_path(challenges):
|
||||
This function returns the best path that does not contain multiple
|
||||
mutually exclusive challenges
|
||||
|
||||
:param challanges: A list of challenges from ACME "challenge"
|
||||
server message to be fulfilled by the client
|
||||
in order to prove possession of the identifier.
|
||||
:type challenges: list
|
||||
:param list challanges: A list of challenges from ACME "challenge"
|
||||
server message to be fulfilled by the client in order to prove
|
||||
possession of the identifier.
|
||||
|
||||
:returns: List of indices from `challenges`.
|
||||
:rtype: list
|
||||
|
||||
@@ -36,20 +36,11 @@ class Client(object):
|
||||
private_key=None, private_key_file=None, use_curses=True):
|
||||
"""
|
||||
|
||||
:param ca_server: Certificate authority server
|
||||
:type ca_server: str
|
||||
|
||||
:param cert_signing_request: Contents of the CSR
|
||||
:type cert_signing_request: str
|
||||
|
||||
:param private_key: Contents of the private key
|
||||
:type private_key: str
|
||||
|
||||
:param private_key_file: absolute path to private_key
|
||||
:type private_key_file: str
|
||||
|
||||
:param use_curses: Use curses UI
|
||||
:type use_curses: bool
|
||||
:param str ca_server: Certificate authority server
|
||||
:param str cert_signing_request: Contents of the CSR
|
||||
:param str private_key: Contents of the private key
|
||||
:param str private_key_file: absolute path to private_key
|
||||
:param bool use_curses: Use curses UI
|
||||
|
||||
"""
|
||||
self.curses = use_curses
|
||||
@@ -80,14 +71,12 @@ class Client(object):
|
||||
def authenticate(self, domains=None, redirect=None, eula=False):
|
||||
"""
|
||||
|
||||
:param domains: List of domains
|
||||
:type domains: list
|
||||
:param list domains: List of domains
|
||||
|
||||
:param redirect:
|
||||
:type redirect: bool|None
|
||||
:type redirect: bool or None
|
||||
|
||||
:param eula: EULA accepted
|
||||
:type eula: bool
|
||||
:param bool eula: EULA accepted
|
||||
|
||||
:raises errors.LetsEncryptClientError: CSR does not contain one of the
|
||||
specified names.
|
||||
@@ -157,9 +146,12 @@ class Client(object):
|
||||
|
||||
def acme_challenge(self):
|
||||
"""Handle ACME "challenge" phase.
|
||||
TODO: Handle more than one domain name in self.names
|
||||
|
||||
.. todo:: Handle more than one domain name in self.names
|
||||
|
||||
:returns: ACME "challenge" message.
|
||||
:rtype: dict
|
||||
|
||||
"""
|
||||
return self.send_and_receive_expected(
|
||||
acme.challenge_request(self.names[0]), "challenge")
|
||||
@@ -167,14 +159,10 @@ class Client(object):
|
||||
def acme_authorization(self, challenge_msg, chal_objs, responses):
|
||||
"""Handle ACME "authorization" phase.
|
||||
|
||||
:param challenge_msg: ACME "challenge" message.
|
||||
:type challenge_msg: dict
|
||||
:param dict challenge_msg: ACME "challenge" message.
|
||||
|
||||
:param chal_objs: TODO
|
||||
:type chal_objs: TODO
|
||||
|
||||
:param responses: TODO
|
||||
:type responses: TODO
|
||||
|
||||
:returns: ACME "authorization" message.
|
||||
:rtype: dict
|
||||
@@ -196,8 +184,7 @@ class Client(object):
|
||||
def acme_certificate(self, csr_der):
|
||||
"""Handle ACME "certificate" phase.
|
||||
|
||||
:param csr_der: CSR in DER format.
|
||||
:type csr_der: str
|
||||
:param str csr_der: CSR in DER format.
|
||||
|
||||
:returns: ACME "certificate" message.
|
||||
:rtype: dict
|
||||
@@ -210,8 +197,7 @@ class Client(object):
|
||||
def acme_revocation(self, cert):
|
||||
"""Handle ACME "revocation" phase.
|
||||
|
||||
:param cert: TODO
|
||||
:type cert: dict
|
||||
:param dict cert: TODO
|
||||
|
||||
:returns: ACME "revocation" message.
|
||||
:rtype: dict
|
||||
@@ -235,8 +221,7 @@ class Client(object):
|
||||
def send(self, msg):
|
||||
"""Send ACME message to server.
|
||||
|
||||
:param msg: ACME message (JSON serializable).
|
||||
:type msg: dict
|
||||
:param dict msg: ACME message (JSON serializable).
|
||||
|
||||
:returns: Server response message.
|
||||
:rtype: dict
|
||||
@@ -274,11 +259,8 @@ class Client(object):
|
||||
def send_and_receive_expected(self, msg, expected):
|
||||
"""Send ACME message to server and return expected message.
|
||||
|
||||
:param msg: ACME message (JSON serializable).
|
||||
:type msg: dict
|
||||
|
||||
:param expected: Name of the expected response ACME message type.
|
||||
:type expected: str
|
||||
:param dict msg: ACME message (JSON serializable).
|
||||
:param str expected: Name of the expected response ACME message type.
|
||||
|
||||
:returns: ACME response message of expected type.
|
||||
:rtype: dict
|
||||
@@ -296,19 +278,15 @@ class Client(object):
|
||||
def is_expected_msg(self, response, expected, delay=3, rounds=20):
|
||||
"""Is reponse expected ACME message?
|
||||
|
||||
:param response: ACME response message from server.
|
||||
:type response: dict
|
||||
:param dict response: ACME response message from server.
|
||||
|
||||
:param expected: Name of the expected response ACME message type.
|
||||
:type expected: str
|
||||
:param str expected: Name of the expected response ACME message type.
|
||||
|
||||
:param delay: Number of seconds to delay before next round in case
|
||||
of ACME "defer" response message.
|
||||
:type delay: int
|
||||
:param int delay: Number of seconds to delay before next round
|
||||
in case of ACME "defer" response message.
|
||||
|
||||
:param rounds: Number of resend attempts in case of ACME "defer"
|
||||
reponse message.
|
||||
:type rounds: int
|
||||
:param int rounds: Number of resend attempts in case of ACME "defer"
|
||||
reponse message.
|
||||
|
||||
:returns: ACME response message from server.
|
||||
:rtype: dict
|
||||
@@ -387,8 +365,7 @@ class Client(object):
|
||||
def choose_certs(self, certs):
|
||||
"""Display choose certificates menu.
|
||||
|
||||
:param certs: List of cert dicts.
|
||||
:type certs: list
|
||||
:param list certs: List of cert dicts.
|
||||
|
||||
"""
|
||||
code, tag = display.display_certs(certs)
|
||||
@@ -478,8 +455,7 @@ class Client(object):
|
||||
def verify_identity(self, challenge_msg):
|
||||
"""Verify identity.
|
||||
|
||||
:param challenge_msg: ACME "challenge" message.
|
||||
:type challenge_msg: dict
|
||||
:param dict challenge_msg: ACME "challenge" message.
|
||||
|
||||
:returns: TODO
|
||||
:rtype: dict
|
||||
@@ -519,11 +495,9 @@ class Client(object):
|
||||
def store_cert_key(self, cert_file, encrypt=False):
|
||||
"""Store certificate key.
|
||||
|
||||
:param cert_file: Path to a certificate file.
|
||||
:type cert_file: str
|
||||
:param str cert_file: Path to a certificate file.
|
||||
|
||||
:param encrypt: Should the certificate key be encrypted?
|
||||
:type encrypt: bool
|
||||
:param bool encrypt: Should the certificate key be encrypted?
|
||||
|
||||
:returns: True if key file was stored successfully, False otherwise.
|
||||
:rtype: bool
|
||||
@@ -584,15 +558,12 @@ class Client(object):
|
||||
"""
|
||||
|
||||
:param name: TODO
|
||||
:type name: TODO
|
||||
|
||||
:param challenges: A list of challenges from ACME "challenge"
|
||||
server message to be fulfilled by the client
|
||||
in order to prove possession of the identifier.
|
||||
:type challenges: list
|
||||
:param list challenges: A list of challenges from ACME "challenge"
|
||||
server message to be fulfilled by the client in order to prove
|
||||
possession of the identifier.
|
||||
|
||||
:param path: List of indices from `challenges`.
|
||||
:type path: list
|
||||
:param list path: List of indices from `challenges`.
|
||||
|
||||
:returns: A pair of TODO
|
||||
:rtype: tuple
|
||||
@@ -748,8 +719,7 @@ class Client(object):
|
||||
def remove_cert_key(cert):
|
||||
"""Remove certificate key.
|
||||
|
||||
:param cert:
|
||||
:type cert: dict
|
||||
:param dict cert:
|
||||
|
||||
"""
|
||||
list_file = os.path.join(CONFIG.CERT_KEY_BACKUP, "LIST")
|
||||
@@ -776,8 +746,7 @@ def remove_cert_key(cert):
|
||||
def sanity_check_names(names):
|
||||
"""Make sure host names are valid.
|
||||
|
||||
:param names: List of host names
|
||||
:type names: list
|
||||
:param list names: List of host names
|
||||
|
||||
"""
|
||||
for name in names:
|
||||
@@ -792,8 +761,7 @@ def is_hostname_sane(hostname):
|
||||
Do enough to avoid shellcode from the environment. There's
|
||||
no need to do more.
|
||||
|
||||
:param hostname: Host name to validate
|
||||
:type hostname: str
|
||||
:param str hostname: Host name to validate
|
||||
|
||||
:returns: True if hostname is valid, otherwise false.
|
||||
:rtype: bool
|
||||
|
||||
@@ -11,6 +11,13 @@ class Configurator(object):
|
||||
"""
|
||||
|
||||
def deploy_cert(self, vhost, cert, key, cert_chain=None):
|
||||
"""Deploy certificate.
|
||||
|
||||
:param vhost
|
||||
:param str cert: CSR
|
||||
:param str key: Private key
|
||||
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def choose_virtual_host(self, name):
|
||||
@@ -53,12 +60,12 @@ class Configurator(object):
|
||||
intended to be permanent, but the save is not ready to be a full
|
||||
checkpoint
|
||||
|
||||
title: string - The title of the save. If a title is given, the
|
||||
configuration will be saved as a new checkpoint
|
||||
and put in a timestamped directory.
|
||||
`title` has no effect if temporary is true.
|
||||
temporary: boolean - Indicates whether the changes made will be
|
||||
quickly reversed in the future (challenges)
|
||||
:param str title: The title of the save. If a title is given, the
|
||||
configuration will be saved as a new checkpoint and put in a
|
||||
timestamped directory. `title` has no effect if temporary is true.
|
||||
|
||||
:param bool temporary: Indicates whether the changes made will
|
||||
be quickly reversed in the future (challenges)
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@@ -25,23 +25,21 @@ def b64_cert_to_pem(b64_der_cert):
|
||||
def create_sig(msg, key_str, nonce=None, nonce_len=CONFIG.NONCE_SIZE):
|
||||
"""Create signature with nonce prepended to the message.
|
||||
|
||||
TODO: Change this over to M2Crypto... PKey
|
||||
Protect against crypto unicode errors... is this sufficient?
|
||||
Do I need to escape?
|
||||
.. todo:: Change this over to M2Crypto... PKey
|
||||
|
||||
:param msg: Message to be signed
|
||||
:type msg: Anything with __str__ method
|
||||
.. todo::Protect against crypto unicode errors... is this sufficient?
|
||||
Do I need to escape?
|
||||
|
||||
:param key_str: Key in string form. Accepted formats
|
||||
are the same as for `Crypto.PublicKey.RSA.importKey`.
|
||||
:type key_str: str
|
||||
:param str key_str: Key in string form. Accepted formats
|
||||
are the same as for `Crypto.PublicKey.RSA.importKey`.
|
||||
|
||||
:param str msg: Message to be signed
|
||||
|
||||
:param nonce: Nonce to be used. If None, nonce of `nonce_len` size
|
||||
will be randomly genereted.
|
||||
:type nonce: str or None
|
||||
|
||||
:param nonce_len: Size of the automaticaly generated nonce.
|
||||
:type nonce_len: int
|
||||
:param int nonce_len: Size of the automaticaly generated nonce.
|
||||
|
||||
:returns: Signature.
|
||||
:rtype: dict
|
||||
@@ -176,8 +174,7 @@ def make_ss_cert(key_str, domains):
|
||||
def get_cert_info(filename):
|
||||
"""Get certificate info.
|
||||
|
||||
:param filename: Name of file containing certificate in PEM format.
|
||||
:type filename: str
|
||||
:param str filename: Name of file containing certificate in PEM format.
|
||||
|
||||
:rtype: dict
|
||||
|
||||
@@ -213,8 +210,7 @@ def valid_csr(csr):
|
||||
|
||||
Check if `csr` is a valid CSR for the given domains.
|
||||
|
||||
:param csr: CSR file contents
|
||||
:type csr: str
|
||||
:param str csr: CSR file contents
|
||||
|
||||
:returns: Validity of CSR.
|
||||
:rtype: bool
|
||||
@@ -233,11 +229,9 @@ def csr_matches_names(csr, domains):
|
||||
M2Crypto currently does not expose the OpenSSL interface to
|
||||
also check the SAN extension. This is insufficient for full testing
|
||||
|
||||
:param csr: CSR file contents
|
||||
:type csr: str
|
||||
:param str csr: CSR file contents
|
||||
|
||||
:param domains: Domains the CSR should contain.
|
||||
:type domains: list
|
||||
:param list domains: Domains the CSR should contain.
|
||||
|
||||
:returns: If the CSR subject contains one of the domains
|
||||
:rtype: bool
|
||||
@@ -253,8 +247,7 @@ def csr_matches_names(csr, domains):
|
||||
def valid_privkey(privkey):
|
||||
"""Is valid RSA private key?
|
||||
|
||||
:param privkey: Private key file contents
|
||||
:type privkey: str
|
||||
:param str privkey: Private key file contents
|
||||
|
||||
:returns: Validity of private key.
|
||||
:rtype: bool
|
||||
@@ -269,11 +262,8 @@ def valid_privkey(privkey):
|
||||
def csr_matches_pubkey(csr, privkey):
|
||||
"""Does private key correspond to the subject public key in the CSR?
|
||||
|
||||
:param csr: CSR file contents
|
||||
:type csr: str
|
||||
|
||||
:param privkey: Private key file contents
|
||||
:type privkey: str
|
||||
:param str csr: CSR file contents
|
||||
:param str privkey: Private key file contents
|
||||
|
||||
:returns: Correspondence of private key to CSR subject public key.
|
||||
:rtype: bool
|
||||
|
||||
@@ -10,14 +10,9 @@ from letsencrypt.client import errors
|
||||
def make_or_verify_dir(directory, mode=0o755, uid=0):
|
||||
"""Make sure directory exists with proper permissions.
|
||||
|
||||
:param directory: Path to a directry.
|
||||
:type directory: str
|
||||
|
||||
:param mode: Diretory mode.
|
||||
:type mode: int
|
||||
|
||||
:param uid: Directory owner.
|
||||
:type uid: int
|
||||
:param str directory: Path to a directry.
|
||||
:param int mode: Diretory mode.
|
||||
:param int uid: Directory owner.
|
||||
|
||||
:raises LetsEncryptClientError: if a directory already exists,
|
||||
but has wrong permissions or owner
|
||||
@@ -38,16 +33,12 @@ def make_or_verify_dir(directory, mode=0o755, uid=0):
|
||||
def check_permissions(filepath, mode, uid=0):
|
||||
"""Check file or directory permissions.
|
||||
|
||||
:param filepath: Path to the tested file (or directory).
|
||||
:type filepath: str
|
||||
:param str filepath: Path to the tested file (or directory).
|
||||
:param int mode: Expected file mode.
|
||||
:param int uid: Expected file owner.
|
||||
|
||||
:param mode: Expected file mode.
|
||||
:type mode: int
|
||||
|
||||
:param uid: Expected file owner.
|
||||
:type uid: int
|
||||
|
||||
:returns: bool -- True if `mode` and `uid` match, False otherwise.
|
||||
:returns: True if `mode` and `uid` match, False otherwise.
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
file_stat = os.stat(filepath)
|
||||
@@ -57,11 +48,8 @@ def check_permissions(filepath, mode, uid=0):
|
||||
def unique_file(default_name, mode=0o777):
|
||||
"""Safely finds a unique file for writing only (by default).
|
||||
|
||||
:param default_name: Default file name
|
||||
:type default_name: str
|
||||
|
||||
:param mode: File mode
|
||||
:type mode: int
|
||||
:param str default_name: Default file name
|
||||
:param int mode: File mode
|
||||
|
||||
:return: tuple of file object and file name
|
||||
|
||||
@@ -94,11 +82,11 @@ def jose_b64encode(data):
|
||||
:param data: Data to be encoded.
|
||||
:type data: str or bytearray
|
||||
|
||||
:raises TypeError: if input is of incorrect type
|
||||
|
||||
:returns: JOSE Base64 string.
|
||||
:rtype: str
|
||||
|
||||
:raises TypeError: if `data` is of incorrect type
|
||||
|
||||
"""
|
||||
if not isinstance(data, str):
|
||||
raise TypeError('argument should be str or bytearray')
|
||||
@@ -112,11 +100,11 @@ def jose_b64decode(data):
|
||||
only ASCII characters are allowed.
|
||||
:type data: str or unicode
|
||||
|
||||
:returns: Decoded data.
|
||||
|
||||
:raises TypeError: if input is of incorrect type
|
||||
:raises ValueError: if unput is unicode with non-ASCII characters
|
||||
|
||||
:returns: Decoded data.
|
||||
|
||||
"""
|
||||
if isinstance(data, unicode):
|
||||
try:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
"""Logger."""
|
||||
import logger
|
||||
import textwrap
|
||||
import time
|
||||
|
||||
@@ -100,8 +100,7 @@ def main():
|
||||
def read_file(filename):
|
||||
"""Returns the given file's contents with universal new line support.
|
||||
|
||||
:param filename: Filename
|
||||
:type filename: str
|
||||
:param str filename: Filename
|
||||
|
||||
:returns: File contents
|
||||
:rtype: str
|
||||
@@ -119,10 +118,9 @@ def rollback(config, checkpoints):
|
||||
"""Revert configuration the specified number of checkpoints.
|
||||
|
||||
:param config: Configurator object
|
||||
:type config: ApacheConfigurator
|
||||
:type config: :class:`ApacheConfigurator`
|
||||
|
||||
:param checkpoints: Number of checkpoints to revert.
|
||||
:type checkpoints: int
|
||||
:param int checkpoints: Number of checkpoints to revert.
|
||||
|
||||
"""
|
||||
config.rollback_checkpoints(checkpoints)
|
||||
@@ -133,7 +131,7 @@ def view_checkpoints(config):
|
||||
"""View checkpoints and associated configuration changes.
|
||||
|
||||
:param config: Configurator object
|
||||
:type config: ApacheConfigurator
|
||||
:type config: :class:`ApacheConfigurator`
|
||||
|
||||
"""
|
||||
config.display_checkpoints()
|
||||
|
||||
@@ -3,6 +3,7 @@ zip_ok = false
|
||||
|
||||
[aliases]
|
||||
dev = develop easy_install letsencrypt[testing]
|
||||
docs = develop easy_install letsencrypt[docs]
|
||||
|
||||
[nosetests]
|
||||
nocapture=1
|
||||
|
||||
5
setup.py
5
setup.py
@@ -12,6 +12,10 @@ install_requires = [
|
||||
'requests',
|
||||
]
|
||||
|
||||
docs_extras = [
|
||||
'Sphinx',
|
||||
]
|
||||
|
||||
testing_extras = [
|
||||
'coverage',
|
||||
'nose',
|
||||
@@ -36,6 +40,7 @@ setup(
|
||||
tests_require=install_requires,
|
||||
test_suite='letsencrypt',
|
||||
extras_require={
|
||||
'docs': docs_extras,
|
||||
'testing': testing_extras,
|
||||
},
|
||||
entry_points={
|
||||
|
||||
Reference in New Issue
Block a user