diff --git a/CHANGES.rst b/CHANGES.rst index 55e4bd796..4ce41a8bc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,9 +3,9 @@ ChangeLog Please note: the change log will only get updated after first release - for now please use the -`commit log `_. +`commit log `_. To see the changes in a given release, inspect the github milestone for the release. For instance: -https://github.com/letsencrypt/letsencrypt/issues?utf8=%E2%9C%93&q=milestone%3A0.3.0 +https://github.com/certbot/certbot/issues?utf8=%E2%9C%93&q=milestone%3A0.3.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bf19b18e1..5f1625658 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,4 +15,4 @@ to the Sphinx generated docs is provided below. --> -https://letsencrypt.readthedocs.org/en/latest/contributing.html +https://certbot.eff.org/docs/contributing.html diff --git a/README.rst b/README.rst index 91a3cfcb5..20b49083f 100644 --- a/README.rst +++ b/README.rst @@ -11,43 +11,60 @@ For more information regarding the status of the project, please see https://letsencrypt.org. Be sure to checkout the `Frequently Asked Questions (FAQ) `_. -About the Let's Encrypt Client +About Certbot ============================== -The Let's Encrypt Client is a fully-featured, extensible client for the Let's +Certbot is a fully-featured, extensible client for the Let's Encrypt CA (or any other CA that speaks the `ACME `_ protocol) that can automate the tasks of obtaining certificates and configuring webservers to use them. This client runs on Unix-based operating systems. +Until May 2016, Certbot was named simply ``letsencrypt`` or ``letsencrypt-auto``, +depending on install method. Instructions on the Internet, and some pieces of the +software, may still refer to this older name. + +Contributing +------------ + +If you'd like to contribute to this project please read `Developer Guide +`_. + Installation ------------ -If ``letsencrypt`` is packaged for your Unix OS, you can install it from -there, and run it by typing ``letsencrypt``. Because not all operating -systems have packages yet, we provide a temporary solution via the -``letsencrypt-auto`` wrapper script, which obtains some dependencies -from your OS and puts others in a python virtual environment:: +If ``certbot`` (or ``letsencrypt``) is packaged for your Unix OS, you can install +it from there, and run it by typing ``certbot`` (or ``letsencrypt``). +Because not all operating systems have packages yet, we provide a temporary +solution via the ``certbot-auto`` wrapper script, which obtains some +dependencies from your OS and puts others in a python virtual environment:: - user@webserver:~$ git clone https://github.com/letsencrypt/letsencrypt - user@webserver:~$ cd letsencrypt - user@webserver:~/letsencrypt$ ./letsencrypt-auto --help + user@webserver:~$ wget https://dl.eff.org/certbot-auto + user@webserver:~$ chmod a+x ./certbot-auto + user@webserver:~$ ./certbot-auto --help -Or for full command line help, type:: +.. hint:: The certbot-auto download is protected by HTTPS, which is pretty good, but if you'd like to + double check the integrity of the ``certbot-auto`` script, you can use these steps for verification before running it:: - ./letsencrypt-auto --help all + user@server:~$ wget -N https://dl.eff.org/certbot-auto.asc + user@server:~$ gpg2 --recv-key A2CFB51FA275A7286234E7B24D17C995CD9775F2 + user@server:~$ gpg2 --trusted-key 4D17C995CD9775F2 --verify certbot-auto.asc certbot-auto -``letsencrypt-auto`` updates to the latest client release automatically. And -since ``letsencrypt-auto`` is a wrapper to ``letsencrypt``, it accepts exactly +And for full command line help, you can type:: + + ./certbot-auto --help all + +``certbot-auto`` updates to the latest client release automatically. And +since ``certbot-auto`` is a wrapper to ``certbot``, it accepts exactly the same command line flags and arguments. More details about this script and other installation methods can be found `in the User Guide -`_. +`_. How to run the client --------------------- -In many cases, you can just run ``letsencrypt-auto`` or ``letsencrypt``, and the +In many cases, you can just run ``certbot-auto`` or ``certbot``, and the client will guide you through the process of obtaining and installing certs interactively. @@ -56,7 +73,7 @@ For instance, if you want to obtain a cert for ``example.com``, ``www.example.com``, and ``other.example.net``, using the Apache plugin to both obtain and install the certs, you could do this:: - ./letsencrypt-auto --apache -d example.com -d www.example.com -d other.example.net + ./certbot-auto --apache -d example.com -d www.example.com -d other.example.net (The first time you run the command, it will make an account, and ask for an email and agreement to the Let's Encrypt Subscriber Agreement; you can @@ -65,7 +82,7 @@ automate those with ``--email`` and ``--agree-tos``) If you want to use a webserver that doesn't have full plugin support yet, you can still use "standalone" or "webroot" plugins to obtain a certificate:: - ./letsencrypt-auto certonly --standalone --email admin@example.com -d example.com -d www.example.com -d other.example.net + ./certbot-auto certonly --standalone --email admin@example.com -d example.com -d www.example.com -d other.example.net Understanding the client in more depth @@ -73,21 +90,21 @@ Understanding the client in more depth To understand what the client is doing in detail, it's important to understand the way it uses plugins. Please see the `explanation of -plugins `_ in +plugins `_ in the User Guide. Links ===== -Documentation: https://letsencrypt.readthedocs.org +Documentation: https://certbot.eff.org/docs -Software project: https://github.com/letsencrypt/letsencrypt +Software project: https://github.com/certbot/certbot -Notes for developers: https://letsencrypt.readthedocs.org/en/latest/contributing.html +Notes for developers: https://certbot.eff.org/docs/contributing.html Main Website: https://letsencrypt.org/ -IRC Channel: #letsencrypt on `Freenode`_ +IRC Channel: #letsencrypt on `Freenode`_ or #certbot on `OFTC`_ Community: https://community.letsencrypt.org @@ -103,12 +120,12 @@ email to client-dev+subscribe@letsencrypt.org) -.. |build-status| image:: https://travis-ci.org/letsencrypt/letsencrypt.svg?branch=master - :target: https://travis-ci.org/letsencrypt/letsencrypt +.. |build-status| image:: https://travis-ci.org/certbot/certbot.svg?branch=master + :target: https://travis-ci.org/certbot/certbot :alt: Travis CI status -.. |coverage| image:: https://coveralls.io/repos/letsencrypt/letsencrypt/badge.svg?branch=master - :target: https://coveralls.io/r/letsencrypt/letsencrypt +.. |coverage| image:: https://coveralls.io/repos/certbot/certbot/badge.svg?branch=master + :target: https://coveralls.io/r/certbot/certbot :alt: Coverage status .. |docs| image:: https://readthedocs.org/projects/letsencrypt/badge/ @@ -151,10 +168,10 @@ Current Features - standalone (runs its own simple webserver to prove you control a domain) - webroot (adds files to webroot directories in order to prove control of domains and obtain certs) - - nginx/0.8.48+ (highly experimental, not included in letsencrypt-auto) + - nginx/0.8.48+ (highly experimental, not included in certbot-auto) * The private key is generated locally on your system. -* Can talk to the Let's Encrypt CA or optionally to other ACME +* Can talk to the Let's Encrypt CA or optionally to other ACME compliant services. * Can get domain-validated (DV) certificates. * Can revoke certificates. @@ -169,4 +186,5 @@ Current Features .. _Freenode: https://webchat.freenode.net?channels=%23letsencrypt +.. _OFTC: https://webchat.oftc.net?channels=%23certbot .. _client-dev: https://groups.google.com/a/letsencrypt.org/forum/#!forum/client-dev diff --git a/acme/setup.py b/acme/setup.py index cbd3bfb87..d38864dc1 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.6.0.dev0' +version = '0.7.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-apache/docs/conf.py b/certbot-apache/docs/conf.py index 2f996c7f4..d2fe15581 100644 --- a/certbot-apache/docs/conf.py +++ b/certbot-apache/docs/conf.py @@ -314,5 +314,5 @@ texinfo_documents = [ intersphinx_mapping = { 'python': ('https://docs.python.org/', None), 'acme': ('https://acme-python.readthedocs.org/en/latest/', None), - 'certbot': ('https://letsencrypt.readthedocs.org/en/latest/', None), + 'certbot': ('https://certbot.eff.org/docs/', None), } diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index 7358c7041..56c6a451d 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.6.0.dev0' +version = '0.7.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-auto b/certbot-auto new file mode 100755 index 000000000..8c6e6c486 --- /dev/null +++ b/certbot-auto @@ -0,0 +1,1088 @@ +#!/bin/sh +# +# Download and run the latest release version of the Certbot client. +# +# NOTE: THIS SCRIPT IS AUTO-GENERATED AND SELF-UPDATING +# +# IF YOU WANT TO EDIT IT LOCALLY, *ALWAYS* RUN YOUR COPY WITH THE +# "--no-self-upgrade" FLAG +# +# IF YOU WANT TO SEND PULL REQUESTS, THE REAL SOURCE FOR THIS FILE IS +# letsencrypt-auto-source/letsencrypt-auto.template AND +# letsencrypt-auto-source/pieces/bootstrappers/* + +set -e # Work even if somebody does "sh thisscript.sh". + +# Note: you can set XDG_DATA_HOME or VENV_PATH before running this script, +# if you want to change where the virtual environment will be installed +XDG_DATA_HOME=${XDG_DATA_HOME:-~/.local/share} +VENV_NAME="letsencrypt" +VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"} +VENV_BIN="$VENV_PATH/bin" +LE_AUTO_VERSION="0.6.0" +BASENAME=$(basename $0) +USAGE="Usage: $BASENAME [OPTIONS] +A self-updating wrapper script for the Certbot ACME client. When run, updates +to both this script and certbot will be downloaded and installed. After +ensuring you have the latest versions installed, certbot will be invoked with +all arguments you have provided. + +Help for certbot itself cannot be provided until it is installed. + + --debug attempt experimental installation + -h, --help print this help + -n, --non-interactive, --noninteractive run without asking for user input + --no-self-upgrade do not download updates + --os-packages-only install OS dependencies and exit + -v, --verbose provide more output + +All arguments are accepted and forwarded to the Certbot client when run." + +while getopts ":hnv" arg; do + case $arg in + h) + HELP=1;; + n) + ASSUME_YES=1;; + v) + VERBOSE=1;; + esac +done + +for arg in "$@" ; do + case "$arg" in + --debug) + DEBUG=1;; + --os-packages-only) + OS_PACKAGES_ONLY=1;; + --no-self-upgrade) + # Do not upgrade this script (also prevents client upgrades, because each + # copy of the script pins a hash of the python client) + NO_SELF_UPGRADE=1;; + --help) + HELP=1;; + --noninteractive|--non-interactive) + ASSUME_YES=1;; + --verbose) + VERBOSE=1;; + esac +done + +# certbot-auto needs root access to bootstrap OS dependencies, and +# certbot itself needs root access for almost all modes of operation +# The "normal" case is that sudo is used for the steps that need root, but +# this script *can* be run as root (not recommended), or fall back to using +# `su` +SUDO_ENV="" +export CERTBOT_AUTO="$0" +if test "`id -u`" -ne "0" ; then + if command -v sudo 1>/dev/null 2>&1; then + SUDO=sudo + SUDO_ENV="CERTBOT_AUTO=$0" + else + echo \"sudo\" is not available, will use \"su\" for installation steps... + # Because the parameters in `su -c` has to be a string, + # we need properly escape it + su_sudo() { + args="" + # This `while` loop iterates over all parameters given to this function. + # For each parameter, all `'` will be replace by `'"'"'`, and the escaped string + # will be wrapped in a pair of `'`, then appended to `$args` string + # For example, `echo "It's only 1\$\!"` will be escaped to: + # 'echo' 'It'"'"'s only 1$!' + # │ │└┼┘│ + # │ │ │ └── `'s only 1$!'` the literal string + # │ │ └── `\"'\"` is a single quote (as a string) + # │ └── `'It'`, to be concatenated with the strings following it + # └── `echo` wrapped in a pair of `'`, it's totally fine for the shell command itself + while [ $# -ne 0 ]; do + args="$args'$(printf "%s" "$1" | sed -e "s/'/'\"'\"'/g")' " + shift + done + su root -c "$args" + } + SUDO=su_sudo + fi +else + SUDO= +fi + +if [ $BASENAME = "letsencrypt-auto" ]; then + # letsencrypt-auto does not respect --help or --yes for backwards compatibility + ASSUME_YES=1 + HELP=0 +fi + +ExperimentalBootstrap() { + # Arguments: Platform name, bootstrap function name + if [ "$DEBUG" = 1 ]; then + if [ "$2" != "" ]; then + echo "Bootstrapping dependencies via $1..." + $2 + fi + else + echo "WARNING: $1 support is very experimental at present..." + echo "if you would like to work on improving it, please ensure you have backups" + echo "and then run this script again with the --debug flag!" + exit 1 + fi +} + +DeterminePythonVersion() { + for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do + # Break (while keeping the LE_PYTHON value) if found. + command -v "$LE_PYTHON" > /dev/null && break + done + if [ "$?" != "0" ]; then + echo "Cannot find any Pythons; please install one!" + exit 1 + fi + export LE_PYTHON + + PYVER=`"$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'` + if [ "$PYVER" -lt 26 ]; then + echo "You have an ancient version of Python entombed in your operating system..." + echo "This isn't going to work; you'll need at least version 2.6." + exit 1 + fi +} + +BootstrapDebCommon() { + # Current version tested with: + # + # - Ubuntu + # - 14.04 (x64) + # - 15.04 (x64) + # - Debian + # - 7.9 "wheezy" (x64) + # - sid (2015-10-21) (x64) + + # Past versions tested with: + # + # - Debian 8.0 "jessie" (x64) + # - Raspbian 7.8 (armhf) + + # Believed not to work: + # + # - Debian 6.0.10 "squeeze" (x64) + + $SUDO apt-get update || echo apt-get update hit problems but continuing anyway... + + # virtualenv binary can be found in different packages depending on + # distro version (#346) + + virtualenv= + if apt-cache show virtualenv > /dev/null 2>&1; then + virtualenv="virtualenv" + fi + + if apt-cache show python-virtualenv > /dev/null 2>&1; then + virtualenv="$virtualenv python-virtualenv" + fi + + augeas_pkg="libaugeas0 augeas-lenses" + AUGVERSION=`apt-cache show --no-all-versions libaugeas0 | grep ^Version: | cut -d" " -f2` + + if [ "$ASSUME_YES" = 1 ]; then + YES_FLAG="-y" + fi + + AddBackportRepo() { + # ARGS: + BACKPORT_NAME="$1" + BACKPORT_SOURCELINE="$2" + echo "To use the Apache Certbot plugin, augeas needs to be installed from $BACKPORT_NAME." + if ! grep -v -e ' *#' /etc/apt/sources.list | grep -q "$BACKPORT_NAME" ; then + # This can theoretically error if sources.list.d is empty, but in that case we don't care. + if ! grep -v -e ' *#' /etc/apt/sources.list.d/* 2>/dev/null | grep -q "$BACKPORT_NAME"; then + if [ "$ASSUME_YES" = 1 ]; then + /bin/echo -n "Installing augeas from $BACKPORT_NAME in 3 seconds..." + sleep 1s + /bin/echo -ne "\e[0K\rInstalling augeas from $BACKPORT_NAME in 2 seconds..." + sleep 1s + /bin/echo -e "\e[0K\rInstalling augeas from $BACKPORT_NAME in 1 second ..." + sleep 1s + add_backports=1 + else + read -p "Would you like to enable the $BACKPORT_NAME repository [Y/n]? " response + case $response in + [yY][eE][sS]|[yY]|"") + add_backports=1;; + *) + add_backports=0;; + esac + fi + if [ "$add_backports" = 1 ]; then + $SUDO sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list" + $SUDO apt-get update + fi + fi + fi + if [ "$add_backports" != 0 ]; then + $SUDO apt-get install $YES_FLAG --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg + augeas_pkg= + fi + } + + + if dpkg --compare-versions 1.0 gt "$AUGVERSION" ; then + if lsb_release -a | grep -q wheezy ; then + AddBackportRepo wheezy-backports "deb http://http.debian.net/debian wheezy-backports main" + elif lsb_release -a | grep -q precise ; then + # XXX add ARM case + AddBackportRepo precise-backports "deb http://archive.ubuntu.com/ubuntu precise-backports main restricted universe multiverse" + else + echo "No libaugeas0 version is available that's new enough to run the" + echo "Certbot apache plugin..." + fi + # XXX add a case for ubuntu PPAs + fi + + $SUDO apt-get install $YES_FLAG --no-install-recommends \ + python \ + python-dev \ + $virtualenv \ + gcc \ + dialog \ + $augeas_pkg \ + libssl-dev \ + libffi-dev \ + ca-certificates \ + + + + if ! command -v virtualenv > /dev/null ; then + echo Failed to install a working \"virtualenv\" command, exiting + exit 1 + fi +} + +BootstrapRpmCommon() { + # Tested with: + # - Fedora 20, 21, 22, 23 (x64) + # - Centos 7 (x64: on DigitalOcean droplet) + # - CentOS 7 Minimal install in a Hyper-V VM + # - CentOS 6 (EPEL must be installed manually) + + if type dnf 2>/dev/null + then + tool=dnf + elif type yum 2>/dev/null + then + tool=yum + + else + echo "Neither yum nor dnf found. Aborting bootstrap!" + exit 1 + fi + + pkgs=" + gcc + dialog + augeas-libs + openssl + openssl-devel + libffi-devel + redhat-rpm-config + ca-certificates + " + + # Some distros and older versions of current distros use a "python27" + # instead of "python" naming convention. Try both conventions. + if $SUDO $tool list python >/dev/null 2>&1; then + pkgs="$pkgs + python + python-devel + python-virtualenv + python-tools + python-pip + " + else + pkgs="$pkgs + python27 + python27-devel + python27-virtualenv + python27-tools + python27-pip + " + fi + + if $SUDO $tool list installed "httpd" >/dev/null 2>&1; then + pkgs="$pkgs + mod_ssl + " + fi + + if [ "$ASSUME_YES" = 1 ]; then + yes_flag="-y" + fi + + if ! $SUDO $tool install $yes_flag $pkgs; then + echo "Could not install OS dependencies. Aborting bootstrap!" + exit 1 + fi +} + +BootstrapSuseCommon() { + # SLE12 don't have python-virtualenv + + if [ "$ASSUME_YES" = 1 ]; then + zypper_flags="-nq" + install_flags="-l" + fi + + $SUDO zypper $zypper_flags in $install_flags \ + python \ + python-devel \ + python-virtualenv \ + gcc \ + dialog \ + augeas-lenses \ + libopenssl-devel \ + libffi-devel \ + ca-certificates +} + +BootstrapArchCommon() { + # Tested with: + # - ArchLinux (x86_64) + # + # "python-virtualenv" is Python3, but "python2-virtualenv" provides + # only "virtualenv2" binary, not "virtualenv" necessary in + # ./tools/_venv_common.sh + + deps=" + python2 + python-virtualenv + gcc + dialog + augeas + openssl + libffi + ca-certificates + pkg-config + " + + # pacman -T exits with 127 if there are missing dependencies + missing=$($SUDO pacman -T $deps) || true + + if [ "$ASSUME_YES" = 1 ]; then + noconfirm="--noconfirm" + fi + + if [ "$missing" ]; then + $SUDO pacman -S --needed $missing $noconfirm + fi +} + +BootstrapGentooCommon() { + PACKAGES=" + dev-lang/python:2.7 + dev-python/virtualenv + dev-util/dialog + app-admin/augeas + dev-libs/openssl + dev-libs/libffi + app-misc/ca-certificates + virtual/pkgconfig" + + case "$PACKAGE_MANAGER" in + (paludis) + $SUDO cave resolve --preserve-world --keep-targets if-possible $PACKAGES -x + ;; + (pkgcore) + $SUDO pmerge --noreplace --oneshot $PACKAGES + ;; + (portage|*) + $SUDO emerge --noreplace --oneshot $PACKAGES + ;; + esac +} + +BootstrapFreeBsd() { + $SUDO pkg install -Ay \ + python \ + py27-virtualenv \ + augeas \ + libffi +} + +BootstrapMac() { + if hash brew 2>/dev/null; then + echo "Using Homebrew to install dependencies..." + pkgman=brew + pkgcmd="brew install" + elif hash port 2>/dev/null; then + echo "Using MacPorts to install dependencies..." + pkgman=port + pkgcmd="$SUDO port install" + else + echo "No Homebrew/MacPorts; installing Homebrew..." + ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + pkgman=brew + pkgcmd="brew install" + fi + + $pkgcmd augeas + $pkgcmd dialog + if [ "$(which python)" = "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python" ]; then + # We want to avoid using the system Python because it requires root to use pip. + # python.org, MacPorts or HomeBrew Python installations should all be OK. + echo "Installing python..." + $pkgcmd python + fi + + # Workaround for _dlopen not finding augeas on OS X + if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then + echo "Applying augeas workaround" + $SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib + fi + + if ! hash pip 2>/dev/null; then + echo "pip not installed" + echo "Installing pip..." + curl --silent --show-error --retry 5 https://bootstrap.pypa.io/get-pip.py | python + fi + + if ! hash virtualenv 2>/dev/null; then + echo "virtualenv not installed." + echo "Installing with pip..." + pip install virtualenv + fi +} + + +# Install required OS packages: +Bootstrap() { + if [ -f /etc/debian_version ]; then + echo "Bootstrapping dependencies for Debian-based OSes..." + BootstrapDebCommon + elif [ -f /etc/redhat-release ]; then + echo "Bootstrapping dependencies for RedHat-based OSes..." + BootstrapRpmCommon + elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then + echo "Bootstrapping dependencies for openSUSE-based OSes..." + BootstrapSuseCommon + elif [ -f /etc/arch-release ]; then + if [ "$DEBUG" = 1 ]; then + echo "Bootstrapping dependencies for Archlinux..." + BootstrapArchCommon + else + echo "Please use pacman to install letsencrypt packages:" + echo "# pacman -S letsencrypt letsencrypt-apache" + echo + echo "If you would like to use the virtualenv way, please run the script again with the" + echo "--debug flag." + exit 1 + fi + elif [ -f /etc/manjaro-release ]; then + ExperimentalBootstrap "Manjaro Linux" BootstrapArchCommon + elif [ -f /etc/gentoo-release ]; then + ExperimentalBootstrap "Gentoo" BootstrapGentooCommon + elif uname | grep -iq FreeBSD ; then + ExperimentalBootstrap "FreeBSD" BootstrapFreeBsd + elif uname | grep -iq Darwin ; then + ExperimentalBootstrap "Mac OS X" BootstrapMac + elif grep -iq "Amazon Linux" /etc/issue ; then + ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon + else + echo "Sorry, I don't know how to bootstrap Certbot on your operating system!" + echo + echo "You will need to bootstrap, configure virtualenv, and run pip install manually." + echo "Please see https://letsencrypt.readthedocs.org/en/latest/contributing.html#prerequisites" + echo "for more info." + fi +} + +TempDir() { + mktemp -d 2>/dev/null || mktemp -d -t 'le' # Linux || OS X +} + + + +if [ "$1" = "--le-auto-phase2" ]; then + # Phase 2: Create venv, install LE, and run. + + shift 1 # the --le-auto-phase2 arg + if [ -f "$VENV_BIN/letsencrypt" ]; then + # --version output ran through grep due to python-cryptography DeprecationWarnings + # grep for both certbot and letsencrypt until certbot and shim packages have been released + INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | grep "^certbot\|^letsencrypt" | cut -d " " -f 2) + else + INSTALLED_VERSION="none" + fi + if [ "$LE_AUTO_VERSION" != "$INSTALLED_VERSION" ]; then + echo "Creating virtual environment..." + DeterminePythonVersion + rm -rf "$VENV_PATH" + if [ "$VERBOSE" = 1 ]; then + virtualenv --no-site-packages --python "$LE_PYTHON" "$VENV_PATH" + else + virtualenv --no-site-packages --python "$LE_PYTHON" "$VENV_PATH" > /dev/null + fi + + echo "Installing Python packages..." + TEMP_DIR=$(TempDir) + # There is no $ interpolation due to quotes on starting heredoc delimiter. + # ------------------------------------------------------------------------- + cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt" +# This is the flattened list of packages certbot-auto installs. To generate +# this, do `pip install --no-cache-dir -e acme -e . -e certbot-apache`, and +# then use `hashin` or a more secure method to gather the hashes. + +argparse==1.4.0 \ + --hash=sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314 \ + --hash=sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4 + +# This comes before cffi because cffi will otherwise install an unchecked +# version via setup_requires. +pycparser==2.14 \ + --hash=sha256:7959b4a74abdc27b312fed1c21e6caf9309ce0b29ea86b591fd2e99ecdf27f73 + +cffi==1.4.2 \ + --hash=sha256:53c1c9ddb30431513eb7f3cdef0a3e06b0f1252188aaa7744af0f5a4cd45dbaf \ + --hash=sha256:a568f49dfca12a8d9f370187257efc58a38109e1eee714d928561d7a018a64f8 \ + --hash=sha256:809c6ca8cfbcaeebfbd432b4576001b40d38ff2463773cb57577d75e1a020bc3 \ + --hash=sha256:86cdca2cd9cba41422230390df17dfeaa9f344a911e3975c8be9da57b35548e9 \ + --hash=sha256:24b13db84aec385ca23c7b8ded83ef8bb4177bc181d14758f9f975be5d020d86 \ + --hash=sha256:969aeffd7c0e097f6be1efd682c156ae226591a0793a94b6c2d5e4293f4c8d4e \ + --hash=sha256:000f358d4b0fa249feaab9c1ce7d5b2fe7e02e7bdf6806c26418505fc685e268 \ + --hash=sha256:a9d86f460bbd8358a2d513ad779e3f3fc878e3b93a00b5002faebf616ffe6b9c \ + --hash=sha256:3127b3ab33eb23ccac071f9a0802748e5cf7c5cbcd02482bb063e35b41dbb0b0 \ + --hash=sha256:e2b2d42236469a40224d39e7b6c60575f388b2f423f354c7ee90a5b7f58c8065 \ + --hash=sha256:8c2dccafee89b1b424b0bec6ad2dd9622c949d2024e929f5da1ed801eac75f1d \ + --hash=sha256:a4de7a4d11aed488bab4fb14f4988587a829bece5a20433f780d6e33b08083cb \ + --hash=sha256:5ca8fe30425265a49274e4b0213a1bc98f4b13449ae5e96f984771e5d83e58c1 \ + --hash=sha256:a4fd38802f59e714eba81a024f62db710b27dbe27a7ea12e911537327aa84d30 \ + --hash=sha256:86cd6912bbc83e9405d4a73cd7f4b4ee8353652d2dbc7c820106ed5b4d1bab3a \ + --hash=sha256:8f1d177d364ea35900415ae24ca3e471be3d5334ed0419294068c49f45913998 +ConfigArgParse==0.10.0 \ + --hash=sha256:3b50a83dd58149dfcee98cb6565265d10b53e9c0a2bca7eeef7fb5f5524890a7 +configobj==5.0.6 \ + --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 +cryptography==1.2.3 \ + --hash=sha256:031938f73a5c5eb3e809e18ff7caeb6865351871417be6050cb8c86a9a202b9a \ + --hash=sha256:a179a38d50f8d68b491d7a313db78f8cabe290842cecddddc7b34d408e59db0a \ + --hash=sha256:906c88b2aadcf99cfabb24098263d1bf65ab0c8688acde10dae1f09d865920f1 \ + --hash=sha256:6e706c5c6088770b1d1b634e959e21963e315b0255f5f4777125ad3d54082977 \ + --hash=sha256:f5ebf8e31c48f8707921dca0e994de77813a9c9b9bf03c119c5ddf97bdcffe73 \ + --hash=sha256:c7b89e42288cc7fbee3812e99ef5c744f22452e11d6822f6807afc6d6b3be83e \ + --hash=sha256:8408d29865947109d8b68f1837a7cde1aa4dc86e0f79ca3ba58c0c44e443d6a5 \ + --hash=sha256:c7e76cf3c3d925dd31fa238cfb806cffba718c0f08707d77a538768477969956 \ + --hash=sha256:7d8de35380f31702758b7753bb5c40723832c73006dedb2f9099bf61a37f7287 \ + --hash=sha256:5edbee71fae5469ee83fe0a37866b9398c8ce3a46325c24fcedfbf097bb48a19 \ + --hash=sha256:594edafe4801c13bdc1cc305e7704a90c19617e95936f6ab457ee4ffe000ba50 \ + --hash=sha256:b7fdb16a0a7f481be42da744bfe1ea2163025de21f90f2c688a316f3c354da9c \ + --hash=sha256:207b8bf0fe0907336df38b733b487521cf9e138189aba9234ad54fe545dd0db8 \ + --hash=sha256:509a2f05386270cf783993c90d49ffefb3dd62aee45bf1ea8ce3d2cde7271c21 \ + --hash=sha256:ac69b65dd1af0179ede40c9f15788c88f73e628ea6c0519de3838e279bb388c6 \ + --hash=sha256:8df6fad6c6ae12fd7004ea29357f0a2b4d3774eaeca7656530d08d2d90cd41aa \ + --hash=sha256:0b8b96dd81cc1533a04f30382c0fe21c1972e189f794d0c4261a18cec08fd9b5 \ + --hash=sha256:cae8fca1883f23c50ea78d89de6fe4fefdb4cea83177760f47177559414ded93 \ + --hash=sha256:1a471ca576a9cdce1b1cd9f3a22b1d09ee44d46862037557de17919c0db44425 \ + --hash=sha256:8ec4e8e3d453b3a1b63b5f57737a434dcf1ee4a2f26f6ff7c5a37c3f679104d2 \ + --hash=sha256:8eb11c77dd8e73f48df6b2f7a7e16173fe0fe8fdfe266232832e88477e08454e +enum34==1.1.2 \ + --hash=sha256:2475d7fcddf5951e92ff546972758802de5260bf409319a9f1934e6bbc8b1dc7 \ + --hash=sha256:35907defb0f992b75ab7788f65fedc1cf20ffa22688e0e6f6f12afc06b3ea501 +funcsigs==0.4 \ + --hash=sha256:ff5ad9e2f8d9e5d1e8bbfbcf47722ab527cf0d51caeeed9da6d0f40799383fde \ + --hash=sha256:d83ce6df0b0ea6618700fe1db353526391a8a3ada1b7aba52fed7a61da772033 +idna==2.0 \ + --hash=sha256:9b2fc50bd3c4ba306b9651b69411ef22026d4d8335b93afc2214cef1246ce707 \ + --hash=sha256:16199aad938b290f5be1057c0e1efc6546229391c23cea61ca940c115f7d3d3b +ipaddress==1.0.16 \ + --hash=sha256:935712800ce4760701d89ad677666cd52691fd2f6f0b340c8b4239a3c17988a5 \ + --hash=sha256:5a3182b322a706525c46282ca6f064d27a02cffbd449f9f47416f1dc96aa71b0 +linecache2==1.0.0 \ + --hash=sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef \ + --hash=sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c +ndg-httpsclient==0.4.0 \ + --hash=sha256:e8c155fdebd9c4bcb0810b4ed01ae1987554b1ee034dd7532d7b8fdae38a6274 +ordereddict==1.1 \ + --hash=sha256:1c35b4ac206cef2d24816c89f89cf289dd3d38cf7c449bb3fab7bf6d43f01b1f +parsedatetime==2.1 \ + --hash=sha256:ce9d422165cf6e963905cd5f74f274ebf7cc98c941916169178ef93f0e557838 \ + --hash=sha256:17c578775520c99131634e09cfca5a05ea9e1bd2a05cd06967ebece10df7af2d +pbr==1.8.1 \ + --hash=sha256:46c8db75ae75a056bd1cc07fa21734fe2e603d11a07833ecc1eeb74c35c72e0c \ + --hash=sha256:e2127626a91e6c885db89668976db31020f0af2da728924b56480fc7ccf09649 +psutil==3.3.0 \ + --hash=sha256:584f0b29fcc5d523b433cb8918b2fc74d67e30ee0b44a95baf031528f424619f \ + --hash=sha256:28ca0b6e9d99aa8dc286e8747a4471362b69812a25291de29b6a8d70a1545a0d \ + --hash=sha256:167ad5fff52a672c4ddc1c1a0b25146d6813ebb08a9aab0a3ac45f8a5b669c3b \ + --hash=sha256:e6dea6173a988727bb223d3497349ad5cdef5c0b282eff2d83e5f9065c53f85f \ + --hash=sha256:2af5e0a4aad66049955d0734aa4e3dc8caa17a9eaf8b4c1a27a5f1ee6e40f6fc \ + --hash=sha256:d9884dc0dc2e55e2448e495778dc9899c1c8bf37aeb2f434c1bea74af93c2683 \ + --hash=sha256:e27c2fe6dfcc8738be3d2c5a022f785eb72971057e1a9e1e34fba73bce8a71a6 \ + --hash=sha256:65afd6fecc8f3aed09ee4be63583bc8eb472f06ceaa4fe24c4d1d5a1a3c0e13f \ + --hash=sha256:ba1c558fbfcdf94515c2394b1155c1dc56e2bc2a9c17d30349827c9ed8a67e46 \ + --hash=sha256:ba95ea0022dcb64d36f0c1335c0605fae35bdf3e0fea8d92f5d0f6456a35e55b \ + --hash=sha256:421b6591d16b509aaa8d8c15821d66bb94cb4a8dc4385cad5c51b85d4a096d85 \ + --hash=sha256:326b305cbdb6f94dafbfe2c26b11da88b0ab07b8a07f8188ab9d75ff0c6e841a \ + --hash=sha256:9aede5b2b6fe46b3748ea8e5214443890d1634027bef3d33b7dad16556830278 \ + --hash=sha256:73bed1db894d1aa9c3c7e611d302cdeab7ae8a0dc0eeaf76727878db1ac5cd87 \ + --hash=sha256:935b5dd6d558af512f42501a7c08f41d7aff139af1bb3959daa3abb859234d6c \ + --hash=sha256:4ca0111cf157dcc0f2f69a323c5b5478718d68d45fc9435d84be0ec0f186215b \ + --hash=sha256:b6f13c95398a3fcf0226c4dcfa448560ba5865259cd96ec2810658651e932189 \ + --hash=sha256:ee6be30d1635bbdea4c4325d507dc8a0dbbde7e1c198bd62ddb9f43198b9e214 \ + --hash=sha256:dfa786858c268d7fbbe1b6175e001ec02738d7cfae0a7ce77bf9b651af676729 \ + --hash=sha256:aa77f9de72af9c16cc288cd4a24cf58824388f57d7a81e400c4616457629870e \ + --hash=sha256:f500093357d04da8140d87932cac2e54ef592a54ca8a743abb2850f60c2c22eb +pyasn1==0.1.9 \ + --hash=sha256:61f9d99e3cef65feb1bfe3a2eef7a93eb93819d345bf54bcd42f4e63d5204dae \ + --hash=sha256:1802a6dd32045e472a419db1441aecab469d33e0d2749e192abdec52101724af \ + --hash=sha256:35025cd9422c96504912f04e2f15fe79390a8597b430c2ca5d0534cf9309ffa0 \ + --hash=sha256:2f96ed5a0c329ca16230b326ca12b7461ec8f65e0be3e4f997516f36bf82a345 \ + --hash=sha256:28fee44217991cfad9e6a0b9f7e3f26041e21ebc96629e94e585ccd05d49fa65 \ + --hash=sha256:326e7a854a17fab07691204747695f8f692d674588a355c441fb14f660bf4e68 \ + --hash=sha256:cda5a90485709ca6795c86056c3e5fe7266028b05e53f1d527fdf93a6365a6b8 \ + --hash=sha256:0cb2a14742b543fdd68f931a14ce3829186ed2b1b2267a06787388c96b2dd9be \ + --hash=sha256:5191ff6b9126d2c039dd87f8ff025bed274baf07fa78afa46f556b1ad7265d6e \ + --hash=sha256:8323e03637b2d072cc7041300bac6ec448c3c28950ab40376036788e9a1af629 \ + --hash=sha256:853cacd96d1f701ddd67aa03ecc05f51890135b7262e922710112f12a2ed2a7f +pyOpenSSL==0.15.1 \ + --hash=sha256:88e45e6bb25dfed272a1ef2e728461d44b634c2cd689e989b6e56a349c5a3ae5 \ + --hash=sha256:f0a26070d6db0881de8bcc7846934b7c3c930d8f9c79d45883ee48984bc0d672 +pyRFC3339==1.0 \ + --hash=sha256:eea31835c56e2096af4363a5745a784878a61d043e247d3a6d6a0a32a9741f56 \ + --hash=sha256:8dfbc6c458b8daba1c0f3620a8c78008b323a268b27b7359e92a4ae41325f535 +python-augeas==0.5.0 \ + --hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2 +python2-pythondialog==3.3.0 \ + --hash=sha256:04e93f24995c43dd90f338d5d865ca72ce3fb5a5358d4daa4965571db35fc3ec \ + --hash=sha256:3e6f593fead98f8a526bc3e306933533236e33729f552f52896ea504f55313fa +pytz==2015.7 \ + --hash=sha256:3abe6a6d3fc2fbbe4c60144211f45da2edbe3182a6f6511af6bbba0598b1f992 \ + --hash=sha256:939ef9c1e1224d980405689a97ffcf7828c56d1517b31d73464356c1f2b7769e \ + --hash=sha256:ead4aefa7007249e05e51b01095719d5a8dd95760089f5730aac5698b1932918 \ + --hash=sha256:3cca0df08bd0ed98432390494ce3ded003f5e661aa460be7a734bffe35983605 \ + --hash=sha256:3ede470d3d17ba3c07638dfa0d10452bc1b6e5ad326127a65ba77e6aaeb11bec \ + --hash=sha256:68c47964f7186eec306b13629627722b9079cd4447ed9e5ecaecd4eac84ca734 \ + --hash=sha256:dd5d3991950aae40a6c81de1578942e73d629808cefc51d12cd157980e6cfc18 \ + --hash=sha256:a77c52062c07eb7c7b30545dbc73e32995b7e117eea750317b5cb5c7a4618f14 \ + --hash=sha256:81af9aec4bc960a9a0127c488f18772dae4634689233f06f65443e7b11ebeb51 \ + --hash=sha256:e079b1dadc5c06246cc1bb6fe1b23a50b1d1173f2edd5104efd40bb73a28f406 \ + --hash=sha256:fbd26746772c24cb93c8b97cbdad5cb9e46c86bbdb1b9d8a743ee00e2fb1fc5d \ + --hash=sha256:99266ef30a37e43932deec2b7ca73e83c8dbc3b9ff703ec73eca6b1dae6befea \ + --hash=sha256:8b6ce1c993909783bc96e0b4f34ea223bff7a4df2c90bdb9c4e0f1ac928689e3 +requests==2.9.1 \ + --hash=sha256:113fbba5531a9e34945b7d36b33a084e8ba5d0664b703c81a7c572d91919a5b8 \ + --hash=sha256:c577815dd00f1394203fc44eb979724b098f88264a9ef898ee45b8e5e9cf587f +six==1.10.0 \ + --hash=sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1 \ + --hash=sha256:105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a +traceback2==1.4.0 \ + --hash=sha256:8253cebec4b19094d67cc5ed5af99bf1dba1285292226e98a31929f87a5d6b23 \ + --hash=sha256:05acc67a09980c2ecfedd3423f7ae0104839eccb55fc645773e1caa0951c3030 +unittest2==1.1.0 \ + --hash=sha256:13f77d0875db6d9b435e1d4f41e74ad4cc2eb6e1d5c824996092b3430f088bb8 \ + --hash=sha256:22882a0e418c284e1f718a822b3b022944d53d2d908e1690b319a9d3eb2c0579 +zope.component==4.2.2 \ + --hash=sha256:282c112b55dd8e3c869a3571f86767c150ab1284a9ace2bdec226c592acaf81a +zope.event==4.1.0 \ + --hash=sha256:dc7a59a2fd91730d3793131a5d261b29e93ec4e2a97f1bc487ce8defee2fe786 +zope.interface==4.1.3 \ + --hash=sha256:f07b631f7a601cd8cbd3332d54f43142c7088a83299f859356f08d1d4d4259b3 \ + --hash=sha256:de5cca083b9439d8002fb76bbe6b4998c5a5a721fab25b84298967f002df4c94 \ + --hash=sha256:6788416f7ea7f5b8a97be94825377aa25e8bdc73463e07baaf9858b29e737077 \ + --hash=sha256:6f3230f7254518201e5a3708cbb2de98c848304f06e3ded8bfb39e5825cba2e1 \ + --hash=sha256:5fa575a5240f04200c3088427d0d4b7b737f6e9018818a51d8d0f927a6a2517a \ + --hash=sha256:522194ad6a545735edd75c8a83f48d65d1af064e432a7d320d64f56bafc12e99 \ + --hash=sha256:e8c7b2d40943f71c99148c97f66caa7f5134147f57423f8db5b4825099ce9a09 \ + --hash=sha256:279024f0208601c3caa907c53876e37ad88625f7eaf1cb3842dbe360b2287017 \ + --hash=sha256:2e221a9eec7ccc58889a278ea13dcfed5ef939d80b07819a9a8b3cb1c681484f \ + --hash=sha256:69118965410ec86d44dc6b9017ee3ddbd582e0c0abeef62b3a19dbf6c8ad132b \ + --hash=sha256:d04df8686ec864d0cade8cf199f7f83aecd416109a20834d568f8310ded12dea \ + --hash=sha256:e75a947e15ee97e7e71e02ea302feb2fc62d3a2bb4668bf9dfbed43a506ac7e7 \ + --hash=sha256:4e45d22fb883222a5ab9f282a116fec5ee2e8d1a568ccff6a2d75bbd0eb6bcfc \ + --hash=sha256:bce9339bb3c7a55e0803b63d21c5839e8e479bc85c4adf42ae415b72f94facb2 \ + --hash=sha256:928138365245a0e8869a5999fbcc2a45475a0a6ed52a494d60dbdc540335fedd \ + --hash=sha256:0d841ba1bb840eea0e6489dc5ecafa6125554971f53b5acb87764441e61bceba \ + --hash=sha256:b09c8c1d47b3531c400e0195697f1414a63221de6ef478598a4f1460f7d9a392 +mock==1.0.1 \ + --hash=sha256:b839dd2d9c117c701430c149956918a423a9863b48b09c90e30a6013e7d2f44f \ + --hash=sha256:8f83080daa249d036cbccfb8ae5cc6ff007b88d6d937521371afabe7b19badbc + +# THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. + +acme==0.6.0 \ + --hash=sha256:cbe4e7a340a19725a8740ed86e30abdbe18fc22c4c6022b7a8e56642d502bcc3 \ + --hash=sha256:ec4e6009dfbd629b58473eb06bbebfd9fb2a79fc8831c149e9205bc38a98ecc6 +certbot==0.6.0 \ + --hash=sha256:a893632d228864b0a751db9f3fdd93439ed34b988ea21b64fb0f0fa2ceded6a2 \ + --hash=sha256:80b0b7dc5afeec2816ef638a61e7c628d73cd72666eebf4984be426d1c2b492d +certbot-apache==0.6.0 \ + --hash=sha256:0ab077f0913b81ed5c1b141c3a7c4c0228ef3738d8d61a93db794d9a80718d43 \ + --hash=sha256:1cfbe751209079a803758f472200816fac559f2a36fdd582d25e3ba5601423a1 +letsencrypt==0.6.0 \ + --hash=sha256:93196c7dcd57272a753e525d145c5a9987c8968c22ec954bcf83dcc9d2499a76 \ + --hash=sha256:a16d6c395f1bf5fd61a28ef83dc78f42dbecbad9d00be6236f2ad8915645c154 +letsencrypt-apache==0.6.0 \ + --hash=sha256:02fadc52a0796e53978c508beec9c53e1fc047660240832b9bde5d53ab3a1379 \ + --hash=sha256:1c5522d94d7750bdb9bfa6201d2c263e914f662c9d0079e673167233cf4364f1 + +UNLIKELY_EOF + # ------------------------------------------------------------------------- + cat << "UNLIKELY_EOF" > "$TEMP_DIR/pipstrap.py" +#!/usr/bin/env python +"""A small script that can act as a trust root for installing pip 8 + +Embed this in your project, and your VCS checkout is all you have to trust. In +a post-peep era, this lets you claw your way to a hash-checking version of pip, +with which you can install the rest of your dependencies safely. All it assumes +is Python 2.6 or better and *some* version of pip already installed. If +anything goes wrong, it will exit with a non-zero status code. + +""" +# This is here so embedded copies are MIT-compliant: +# Copyright (c) 2016 Erik Rose +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +from __future__ import print_function +from hashlib import sha256 +from os.path import join +from pipes import quote +from shutil import rmtree +try: + from subprocess import check_output +except ImportError: + from subprocess import CalledProcessError, PIPE, Popen + + def check_output(*popenargs, **kwargs): + if 'stdout' in kwargs: + raise ValueError('stdout argument not allowed, it will be ' + 'overridden.') + process = Popen(stdout=PIPE, *popenargs, **kwargs) + output, unused_err = process.communicate() + retcode = process.poll() + if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise CalledProcessError(retcode, cmd) + return output +from sys import exit, version_info +from tempfile import mkdtemp +try: + from urllib2 import build_opener, HTTPHandler, HTTPSHandler +except ImportError: + from urllib.request import build_opener, HTTPHandler, HTTPSHandler +try: + from urlparse import urlparse +except ImportError: + from urllib.parse import urlparse # 3.4 + + +__version__ = 1, 1, 1 + + +# wheel has a conditional dependency on argparse: +maybe_argparse = ( + [('https://pypi.python.org/packages/source/a/argparse/' + 'argparse-1.4.0.tar.gz', + '62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4')] + if version_info < (2, 7, 0) else []) + + +PACKAGES = maybe_argparse + [ + # Pip has no dependencies, as it vendors everything: + ('https://pypi.python.org/packages/source/p/pip/pip-8.0.3.tar.gz', + '30f98b66f3fe1069c529a491597d34a1c224a68640c82caf2ade5f88aa1405e8'), + # This version of setuptools has only optional dependencies: + ('https://pypi.python.org/packages/source/s/setuptools/' + 'setuptools-20.2.2.tar.gz', + '24fcfc15364a9fe09a220f37d2dcedc849795e3de3e4b393ee988e66a9cbd85a'), + ('https://pypi.python.org/packages/source/w/wheel/wheel-0.29.0.tar.gz', + '1ebb8ad7e26b448e9caa4773d2357849bf80ff9e313964bcaf79cbf0201a1648') +] + + +class HashError(Exception): + def __str__(self): + url, path, actual, expected = self.args + return ('{url} did not match the expected hash {expected}. Instead, ' + 'it was {actual}. The file (left at {path}) may have been ' + 'tampered with.'.format(**locals())) + + +def hashed_download(url, temp, digest): + """Download ``url`` to ``temp``, make sure it has the SHA-256 ``digest``, + and return its path.""" + # Based on pip 1.4.1's URLOpener but with cert verification removed. Python + # >=2.7.9 verifies HTTPS certs itself, and, in any case, the cert + # authenticity has only privacy (not arbitrary code execution) + # implications, since we're checking hashes. + def opener(): + opener = build_opener(HTTPSHandler()) + # Strip out HTTPHandler to prevent MITM spoof: + for handler in opener.handlers: + if isinstance(handler, HTTPHandler): + opener.handlers.remove(handler) + return opener + + def read_chunks(response, chunk_size): + while True: + chunk = response.read(chunk_size) + if not chunk: + break + yield chunk + + response = opener().open(url) + path = join(temp, urlparse(url).path.split('/')[-1]) + actual_hash = sha256() + with open(path, 'wb') as file: + for chunk in read_chunks(response, 4096): + file.write(chunk) + actual_hash.update(chunk) + + actual_digest = actual_hash.hexdigest() + if actual_digest != digest: + raise HashError(url, path, actual_digest, digest) + return path + + +def main(): + temp = mkdtemp(prefix='pipstrap-') + try: + downloads = [hashed_download(url, temp, digest) + for url, digest in PACKAGES] + check_output('pip install --no-index --no-deps -U ' + + ' '.join(quote(d) for d in downloads), + shell=True) + except HashError as exc: + print(exc) + except Exception: + rmtree(temp) + raise + else: + rmtree(temp) + return 0 + return 1 + + +if __name__ == '__main__': + exit(main()) + +UNLIKELY_EOF + # ------------------------------------------------------------------------- + # Set PATH so pipstrap upgrades the right (v)env: + PATH="$VENV_BIN:$PATH" "$VENV_BIN/python" "$TEMP_DIR/pipstrap.py" + set +e + PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1` + PIP_STATUS=$? + set -e + rm -rf "$TEMP_DIR" + if [ "$PIP_STATUS" != 0 ]; then + # Report error. (Otherwise, be quiet.) + echo "Had a problem while installing Python packages:" + echo "$PIP_OUT" + rm -rf "$VENV_PATH" + exit 1 + fi + echo "Installation succeeded." + fi + echo "Requesting root privileges to run certbot..." + if [ -z "$SUDO_ENV" ] ; then + # SUDO is su wrapper / noop + echo " " $SUDO "$VENV_BIN/letsencrypt" "$@" + $SUDO "$VENV_BIN/letsencrypt" "$@" + else + # sudo + echo " " $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@" + $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@" + fi + +else + # Phase 1: Upgrade certbot-auto if neceesary, then self-invoke. + # + # Each phase checks the version of only the thing it is responsible for + # upgrading. Phase 1 checks the version of the latest release of + # certbot-auto (which is always the same as that of the certbot + # package). Phase 2 checks the version of the locally installed certbot. + + if [ ! -f "$VENV_BIN/letsencrypt" ]; then + if [ "$HELP" = 1 ]; then + echo "$USAGE" + exit 0 + fi + # If it looks like we've never bootstrapped before, bootstrap: + Bootstrap + fi + if [ "$OS_PACKAGES_ONLY" = 1 ]; then + echo "OS packages installed." + exit 0 + fi + + if [ "$NO_SELF_UPGRADE" != 1 ]; then + echo "Checking for new version..." + TEMP_DIR=$(TempDir) + # --------------------------------------------------------------------------- + cat << "UNLIKELY_EOF" > "$TEMP_DIR/fetch.py" +"""Do downloading and JSON parsing without additional dependencies. :: + + # Print latest released version of LE to stdout: + python fetch.py --latest-version + + # Download letsencrypt-auto script from git tag v1.2.3 into the folder I'm + # in, and make sure its signature verifies: + python fetch.py --le-auto-script v1.2.3 + +On failure, return non-zero. + +""" +from distutils.version import LooseVersion +from json import loads +from os import devnull, environ +from os.path import dirname, join +import re +from subprocess import check_call, CalledProcessError +from sys import argv, exit +from urllib2 import build_opener, HTTPHandler, HTTPSHandler, HTTPError + +PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq +OzQb2eyW15YFjDDEMI0ZOzt8f504obNs920lDnpPD2/KqgsfjOgw2K7xWDJIj/18 +xUvWPk3LDkrnokNiRkA3KOx3W6fHycKL+zID7zy+xZYBuh2fLyQtWV1VGQ45iNRp +9+Zo7rH86cdfgkdnWTlNSHyTLW9NbXvyv/E12bppPcEvgCTAQXgnDVJ0/sqmeiij +n9tTFh03aM+R2V/21h8aTraAS24qiPCz6gkmYGC8yr6mglcnNoYbsLNYZ69zF1XH +cXPduCPdPdfLlzVlKK1/U7hkA28eG3BIAMh6uJYBRJTpiGgaGdPd7YekUB8S6cy+ +CQIDAQAB +-----END PUBLIC KEY----- +""") + +class ExpectedError(Exception): + """A novice-readable exception that also carries the original exception for + debugging""" + + +class HttpsGetter(object): + def __init__(self): + """Build an HTTPS opener.""" + # Based on pip 1.4.1's URLOpener + # This verifies certs on only Python >=2.7.9. + self._opener = build_opener(HTTPSHandler()) + # Strip out HTTPHandler to prevent MITM spoof: + for handler in self._opener.handlers: + if isinstance(handler, HTTPHandler): + self._opener.handlers.remove(handler) + + def get(self, url): + """Return the document contents pointed to by an HTTPS URL. + + If something goes wrong (404, timeout, etc.), raise ExpectedError. + + """ + try: + return self._opener.open(url).read() + except (HTTPError, IOError) as exc: + raise ExpectedError("Couldn't download %s." % url, exc) + + +def write(contents, dir, filename): + """Write something to a file in a certain directory.""" + with open(join(dir, filename), 'w') as file: + file.write(contents) + + +def latest_stable_version(get): + """Return the latest stable release of letsencrypt.""" + metadata = loads(get( + environ.get('LE_AUTO_JSON_URL', + 'https://pypi.python.org/pypi/letsencrypt/json'))) + # metadata['info']['version'] actually returns the latest of any kind of + # release release, contrary to https://wiki.python.org/moin/PyPIJSON. + # The regex is a sufficient regex for picking out prereleases for most + # packages, LE included. + return str(max(LooseVersion(r) for r + in metadata['releases'].iterkeys() + if re.match('^[0-9.]+$', r))) + + +def verified_new_le_auto(get, tag, temp_dir): + """Return the path to a verified, up-to-date letsencrypt-auto script. + + If the download's signature does not verify or something else goes wrong + with the verification process, raise ExpectedError. + + """ + le_auto_dir = environ.get( + 'LE_AUTO_DIR_TEMPLATE', + 'https://raw.githubusercontent.com/letsencrypt/letsencrypt/%s/' + 'letsencrypt-auto-source/') % tag + write(get(le_auto_dir + 'letsencrypt-auto'), temp_dir, 'letsencrypt-auto') + write(get(le_auto_dir + 'letsencrypt-auto.sig'), temp_dir, 'letsencrypt-auto.sig') + write(PUBLIC_KEY, temp_dir, 'public_key.pem') + try: + with open(devnull, 'w') as dev_null: + check_call(['openssl', 'dgst', '-sha256', '-verify', + join(temp_dir, 'public_key.pem'), + '-signature', + join(temp_dir, 'letsencrypt-auto.sig'), + join(temp_dir, 'letsencrypt-auto')], + stdout=dev_null, + stderr=dev_null) + except CalledProcessError as exc: + raise ExpectedError("Couldn't verify signature of downloaded " + "certbot-auto.", exc) + + +def main(): + get = HttpsGetter().get + flag = argv[1] + try: + if flag == '--latest-version': + print latest_stable_version(get) + elif flag == '--le-auto-script': + tag = argv[2] + verified_new_le_auto(get, tag, dirname(argv[0])) + except ExpectedError as exc: + print exc.args[0], exc.args[1] + return 1 + else: + return 0 + + +if __name__ == '__main__': + exit(main()) + +UNLIKELY_EOF + # --------------------------------------------------------------------------- + DeterminePythonVersion + if ! REMOTE_VERSION=`"$LE_PYTHON" "$TEMP_DIR/fetch.py" --latest-version` ; then + echo "WARNING: unable to check for updates." + elif [ "$LE_AUTO_VERSION" != "$REMOTE_VERSION" ]; then + echo "Upgrading certbot-auto $LE_AUTO_VERSION to $REMOTE_VERSION..." + + # Now we drop into Python so we don't have to install even more + # dependencies (curl, etc.), for better flow control, and for the option of + # future Windows compatibility. + "$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION" + + # Install new copy of certbot-auto. + # TODO: Deal with quotes in pathnames. + echo "Replacing certbot-auto..." + # Clone permissions with cp. chmod and chown don't have a --reference + # option on OS X or BSD, and stat -c on Linux is stat -f on OS X and BSD: + $SUDO cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone" + $SUDO cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone" + # Using mv rather than cp leaves the old file descriptor pointing to the + # original copy so the shell can continue to read it unmolested. mv across + # filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the + # cp is unlikely to fail (esp. under sudo) if the rm doesn't. + $SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" + # TODO: Clean up temp dir safely, even if it has quotes in its path. + rm -rf "$TEMP_DIR" + fi # A newer version is available. + fi # Self-upgrading is allowed. + + "$0" --le-auto-phase2 "$@" +fi diff --git a/certbot-compatibility-test/docs/conf.py b/certbot-compatibility-test/docs/conf.py index 1ef69ab2d..f89f4b368 100644 --- a/certbot-compatibility-test/docs/conf.py +++ b/certbot-compatibility-test/docs/conf.py @@ -311,7 +311,7 @@ texinfo_documents = [ intersphinx_mapping = { 'python': ('https://docs.python.org/', None), 'acme': ('https://acme-python.readthedocs.org/en/latest/', None), - 'certbot': ('https://letsencrypt.readthedocs.org/en/latest/', None), + 'certbot': ('https://certbot.eff.org/docs/', None), 'certbot-apache': ( 'https://letsencrypt-apache.readthedocs.org/en/latest/', None), 'certbot-nginx': ( diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index c62a10f89..8f9452c5a 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.6.0.dev0' +version = '0.7.0.dev0' install_requires = [ 'certbot=={0}'.format(version), diff --git a/certbot-nginx/certbot_nginx/nginxparser.py b/certbot-nginx/certbot_nginx/nginxparser.py index 8ab7adb0a..1577c7b1e 100644 --- a/certbot-nginx/certbot_nginx/nginxparser.py +++ b/certbot-nginx/certbot_nginx/nginxparser.py @@ -30,10 +30,11 @@ class RawNginxParser(object): assignment = (key + Optional(space + value, default=None) + semicolon) location_statement = Optional(space + modifier) + Optional(space + location) if_statement = Literal("if") + space + Regex(r"\(.+\)") + space + map_statement = Literal("map") + space + Regex(r"\S+") + space + Regex(r"\$\S+") + space block = Forward() block << Group( - (Group(key + location_statement) ^ Group(if_statement)) + + (Group(key + location_statement) ^ Group(if_statement) ^ Group(map_statement)) + left_bracket + Group(ZeroOrMore(Group(comment | assignment) | block)) + right_bracket) diff --git a/certbot-nginx/docs/conf.py b/certbot-nginx/docs/conf.py index fa00e6503..167abb4fb 100644 --- a/certbot-nginx/docs/conf.py +++ b/certbot-nginx/docs/conf.py @@ -307,5 +307,5 @@ texinfo_documents = [ intersphinx_mapping = { 'python': ('https://docs.python.org/', None), 'acme': ('https://acme-python.readthedocs.org/en/latest/', None), - 'certbot': ('https://letsencrypt.readthedocs.org/en/latest/', None), + 'certbot': ('https://certbot.eff.org/docs/', None), } diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 0e5c27a0a..a74b93093 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.6.0.dev0' +version = '0.7.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot/__init__.py b/certbot/__init__.py index a48d62548..85f370e7a 100644 --- a/certbot/__init__.py +++ b/certbot/__init__.py @@ -1,4 +1,4 @@ """Certbot client.""" # version number like 1.2.3a0, must have at least 2 parts, like 1.2 -__version__ = '0.6.0.dev0' +__version__ = '0.7.0.dev0' diff --git a/docs/ciphers.rst b/docs/ciphers.rst index ef644b7a0..8996dd9ef 100644 --- a/docs/ciphers.rst +++ b/docs/ciphers.rst @@ -17,15 +17,13 @@ Autoupdates Within certain limits, TLS server software can choose what kind of cryptography to use when a client connects. These choices can affect security, compatibility, and performance in complex ways. Most of -these options are independent of a particular certificate. The Let's -Encrypt client tries to provide defaults that we think are most useful -to our users. +these options are independent of a particular certificate. Certbot +tries to provide defaults that we think are most useful to our users. -As described below, the Let's Encrypt client will default to modifying +As described below, Certbot will default to modifying server software's cryptographic settings to keep these up-to-date with -what we think are appropriate defaults when new versions of the Let's -Encrypt client are installed (for example, by an operating system package -manager). +what we think are appropriate defaults when new versions of the Certbot +are installed (for example, by an operating system package manager). When this feature is implemented, this document will be updated to describe how to disable these automatic changes. @@ -54,7 +52,7 @@ improve, others' security. But important information that improves our understanding of the state of the art is published regularly. When enabling TLS support in a compatible web server (which is a separate -step from obtaining a certificate), Let's Encrypt has the ability to +step from obtaining a certificate), Certbot has the ability to update that web server's TLS configuration. Again, this is *different from the cryptographic particulars of the certificate itself*; the certificate as of the initial release will be RSA-signed using one of @@ -80,30 +78,29 @@ art. However, the Let's Encrypt certificate authority does *not* dictate end-users' security policy, and any site is welcome to change its preferences in accordance with its own policy or its administrators' preferences, and use different cryptographic mechanisms or parameters, -or a different priority order, than the defaults provided by the Let's -Encrypt client. +or a different priority order, than the defaults provided by Certbot. -If you don't use the Let's Encrypt client to configure your server -directly, because the client doesn't integrate with your server software -or because you chose not to use this integration, then the cryptographic -defaults haven't been modified, and the cryptography chosen by the server -will still be whatever the default for your software was. For example, -if you obtain a certificate using *standalone* mode and then manually -install it in an IMAP or LDAP server, your cryptographic settings will -not be modified by the client in any way. +If you don't use Certbot to configure your server directly, because the +client doesn't integrate with your server software or because you chose +not to use this integration, then the cryptographic defaults haven't been +modified, and the cryptography chosen by the server will still be whatever +the default for your software was. For example, if you obtain a +certificate using *standalone* mode and then manually install it in an IMAP +or LDAP server, your cryptographic settings will not be modified by the +client in any way. Sources of defaults ------------------- -Initially, the Let's Encrypt client will configure users' servers to -use the cryptographic defaults recommended by the Mozilla project. -These settings are well-reasoned recommendations that carefully -consider client software compatibility. They are described at +Initially, Certbot will configure users' servers to use the cryptographic +defaults recommended by the Mozilla project. These settings are well-reasoned +recommendations that carefully consider client software compatibility. They +are described at https://wiki.mozilla.org/Security/Server_Side_TLS -and the version implemented by the Let's Encrypt client will be the +and the version implemented by Certbot will be the version that was most current as of the release date of each client version. Mozilla offers three separate sets of cryptographic options, which trade off security and compatibility differently. These are @@ -113,12 +110,12 @@ to most-backwards compatible). The client will follow the Mozilla defaults for the *Intermediate* configuration by default, at least with regards to ciphersuites and TLS versions. Mozilla's web site describes which client software will be compatible with each configuration. You can also use -the Qualys SSL Labs site, which the Let's Encrypt software will suggest +the Qualys SSL Labs site, which Certbot will suggest when installing a certificate, to test your server and see whether it will be compatible with particular software versions. -It will be possible to ask the Let's Encrypt client to instead apply -(and track) Modern or Old configurations. +It will be possible to ask Certbot to instead apply (and track) Modern +or Old configurations. The Let's Encrypt project expects to follow the Mozilla recommendations in the future as those recommendations are updated. (For example, some @@ -127,15 +124,15 @@ which uses the ChaCha and Poly1305 algorithms, and which is already implemented by the Chrome browser. Mozilla has delayed recommending ``0xcc13`` over compatibility and standardization concerns, but is likely to recommend it in the future once these concerns have been addressed. At -that point, the Let's Encrypt client would likely follow the Mozilla -recommendations and favor the use of this ciphersuite as well.) +that point, Certbot would likely follow the Mozilla recommendations and favor +the use of this ciphersuite as well.) The Let's Encrypt project may deviate from the Mozilla recommendations in the future if good cause is shown and we believe our users' priorities would be well-served by doing so. In general, please address relevant proposals for changing priorities to the Mozilla security -team first, before asking the Let's Encrypt project to change the -client's priorities. The Mozilla security team is likely to have more +team first, before asking the Certbot developers to change +Certbot's priorities. The Mozilla security team is likely to have more resources and expertise to bring to bear on evaluating reasons why its recommendations should be updated. @@ -144,8 +141,8 @@ small number of alternative configurations (apart from Modern, Intermediate, and Old) that there's reason to believe would be widely used by sysadmins; this would usually be a preferable course to modifying an existing configuration. For example, if many sysadmins want their -servers configured to track a different expert recommendation, Let's -Encrypt could add an option to do so. +servers configured to track a different expert recommendation, Certbot +could add an option to do so. Resources for recommendations @@ -156,9 +153,9 @@ recommendations with sources of expert guidance on ciphersuites and other cryptographic parameters. We're grateful to everyone who contributed suggestions. The recommendations we received are available at -https://github.com/letsencrypt/letsencrypt/wiki/Ciphersuite-guidance +https://github.com/certbot/certbot/wiki/Ciphersuite-guidance -Let's Encrypt client users are welcome to review these authorities to +Certbot users are welcome to review these authorities to better inform their own cryptographic parameter choices. We also welcome suggestions of other resources to add to this list. Please keep in mind that different recommendations may reflect different priorities @@ -172,26 +169,25 @@ This will probably look something like .. code-block:: shell - letsencrypt --cipher-recommendations mozilla-secure - letsencrypt --cipher-recommendations mozilla-intermediate - letsencrypt --cipher-recommendations mozilla-old + certbot --cipher-recommendations mozilla-secure + certbot --cipher-recommendations mozilla-intermediate + certbot --cipher-recommendations mozilla-old to track Mozilla's *Secure*, *Intermediate*, or *Old* recommendations, and .. code-block:: shell - letsencrypt --update-ciphers on + certbot --update-ciphers on -to enable updating ciphers with each new Let's Encrypt client release, -or +to enable updating ciphers with each new Certbot release, or .. code-block:: shell - letsencrypt --update-ciphers off + certbot --update-ciphers off to disable automatic configuration updates. These features have not yet -been implemented and this syntax may change then they are implemented. +been implemented and this syntax may change when they are implemented. TODO @@ -200,7 +196,7 @@ TODO The status of this feature is tracked as part of issue #1123 in our bug tracker. -https://github.com/letsencrypt/letsencrypt/issues/1123 +https://github.com/certbot/certbot/issues/1123 Prior to implementation of #1123, the client does not actually modify ciphersuites (this is intended to be implemented as a "configuration diff --git a/docs/conf.py b/docs/conf.py index fb2bdea73..e387e1eae 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -64,8 +64,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'Let\'s Encrypt' -copyright = u'2014-2015, Let\'s Encrypt Project' +project = u'Certbot' +copyright = u'2014-2016 - The Certbot software and documentation are licensed under the Apache 2.0 license as described at https://eff.org/cb-license ' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -225,7 +225,7 @@ html_static_path = ['_static'] #html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'LetsEncryptdoc' +htmlhelp_basename = 'Certbotdoc' # -- Options for LaTeX output --------------------------------------------- @@ -247,8 +247,8 @@ latex_elements = { # (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'), + ('index', 'Certbot.tex', u'Certbot Documentation', + u'Certbot Project', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -277,7 +277,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'certbot', u'Let\'s Encrypt Documentation', + ('index', 'certbot', u'Certbot Documentation', [project], 7), ('man/certbot', 'certbot', u'certbot script documentation', [project], 1), @@ -293,8 +293,8 @@ man_pages = [ # (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.', + ('index', 'Certbot', u'Certbot Documentation', + u'Certbot Project', 'Certbot', 'One line description of project.', 'Miscellaneous'), ] diff --git a/docs/contributing.rst b/docs/contributing.rst index 216cd4888..49e9e146d 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -20,8 +20,8 @@ once: .. code-block:: shell - git clone https://github.com/letsencrypt/letsencrypt - cd letsencrypt + git clone https://github.com/certbot/certbot + cd certbot ./letsencrypt-auto-source/letsencrypt-auto --os-packages-only ./tools/venv.sh @@ -57,8 +57,8 @@ your pull request must have thorough unit test coverage, pass our `integration`_ tests, and be compliant with the :ref:`coding style `. -.. _github issue tracker: https://github.com/letsencrypt/letsencrypt/issues -.. _Good Volunteer Task: https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+Volunteer+Task%22 +.. _github issue tracker: https://github.com/certbot/certbot/issues +.. _Good Volunteer Task: https://github.com/certbot/certbot/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+Volunteer+Task%22 Testing ------- @@ -175,8 +175,8 @@ Configurators may implement just one of those). There are also `~certbot.interfaces.IDisplay` plugins, which implement bindings to alternative UI libraries. -.. _interfaces.py: https://github.com/letsencrypt/letsencrypt/blob/master/certbot/interfaces.py -.. _plugins/common.py: https://github.com/letsencrypt/letsencrypt/blob/master/certbot/plugins/common.py#L34 +.. _interfaces.py: https://github.com/certbot/certbot/blob/master/certbot/interfaces.py +.. _plugins/common.py: https://github.com/certbot/certbot/blob/master/certbot/plugins/common.py#L34 Authenticators @@ -323,7 +323,7 @@ Steps: See `Known Issues`_. If it's not a known issue, fix any errors. .. _Known Issues: - https://github.com/letsencrypt/letsencrypt/wiki/Known-issues + https://github.com/certbot/certbot/wiki/Known-issues Updating the documentation ========================== diff --git a/docs/index.rst b/docs/index.rst index 68289d760..b541e376e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,4 +1,4 @@ -Welcome to the Let's Encrypt client documentation! +Welcome to the Certbot documentation! ================================================== .. toctree:: diff --git a/docs/packaging.rst b/docs/packaging.rst index 5f09b65fa..bd366dbaa 100644 --- a/docs/packaging.rst +++ b/docs/packaging.rst @@ -3,4 +3,4 @@ Packaging Guide =============== Documentation can be found at -https://github.com/letsencrypt/letsencrypt/wiki/Packaging. +https://github.com/certbot/certbot/wiki/Packaging. diff --git a/docs/using.rst b/docs/using.rst index 47746c110..2c3465324 100644 --- a/docs/using.rst +++ b/docs/using.rst @@ -10,12 +10,12 @@ User Guide Installation ============ -.. _letsencrypt-auto: +.. _certbot-auto: -letsencrypt-auto +certbot-auto ---------------- -``letsencrypt-auto`` is a wrapper which installs some dependencies +``certbot-auto`` is a wrapper which installs some dependencies from your OS standard package repositories (e.g. using `apt-get` or `yum`), and for other dependencies it sets up a virtualized Python environment with packages downloaded from PyPI [#venv]_. It also @@ -25,33 +25,33 @@ To install and run the client, just type... .. code-block:: shell - ./letsencrypt-auto + ./certbot-auto -.. hint:: During the beta phase, Let's Encrypt enforces strict rate limits on - the number of certificates issued for one domain. It is recommended to - initially use the test server via `--test-cert` until you get the desired +.. hint:: The Let's Encrypt servers enforce rate + limits on the number of certificates issued for one domain. It is recommended + to initially use the test server via `--test-cert` until you get the desired certificates. Throughout the documentation, whenever you see references to -``letsencrypt`` script/binary, you can substitute in -``letsencrypt-auto``. For example, to get basic help you would type: +``certbot`` script/binary, you can substitute in +``certbot-auto``. For example, to get basic help you would type: .. code-block:: shell - ./letsencrypt-auto --help + ./certbot-auto --help or for full help, type: .. code-block:: shell - ./letsencrypt-auto --help all + ./certbot-auto --help all -``letsencrypt-auto`` is the recommended method of running the Let's Encrypt +``certbot-auto`` is the recommended method of running the Certbot client beta releases on systems that don't have a packaged version. Debian, Arch Linux, Gentoo, FreeBSD, and OpenBSD now have native packages, so on those -systems you can just install ``letsencrypt`` (and perhaps -``letsencrypt-apache``). If you'd like to run the latest copy from Git, or +systems you can just install ``certbot`` (and perhaps +``certbot-apache``). If you'd like to run the latest copy from Git, or run your own locally modified copy of the client, follow the instructions in the :doc:`contributing`. Some `other methods of installation`_ are discussed below. @@ -60,11 +60,11 @@ below. Plugins ======= -The Let's Encrypt client supports a number of different "plugins" that can be +The Certbot client supports a number of different "plugins" that can be used to obtain and/or install certificates. Plugins that can obtain a cert are called "authenticators" and can be used with the "certonly" command. Plugins that can install a cert are called "installers". Plugins that do both -can be used with the "letsencrypt run" command, which is the default. +can be used with the "certbot run" command, which is the default. =========== ==== ==== =============================================================== Plugin Auth Inst Notes @@ -79,7 +79,7 @@ standalone_ Y N Uses a "standalone" webserver to obtain a cert. Requires webserver is not supported or not desired. manual_ Y N Helps you obtain a cert by giving you instructions to perform domain validation yourself. -nginx_ Y Y Very experimental and not included in letsencrypt-auto_. +nginx_ Y Y Very experimental and not included in certbot-auto_. =========== ==== ==== =============================================================== Third-party plugins @@ -145,16 +145,16 @@ specified ``--webroot-path``. So, for instance, :: - letsencrypt certonly --webroot -w /var/www/example/ -d www.example.com -d example.com -w /var/www/other -d other.example.net -d another.other.example.net + certbot certonly --webroot -w /var/www/example/ -d www.example.com -d example.com -w /var/www/other -d other.example.net -d another.other.example.net would obtain a single certificate for all of those names, using the ``/var/www/example`` webroot directory for the first two, and ``/var/www/other`` for the second two. The webroot plugin works by creating a temporary file for each of your requested -domains in ``${webroot-path}/.well-known/acme-challenge``. Then the Let's -Encrypt validation server makes HTTP requests to validate that the DNS for each -requested domain resolves to the server running letsencrypt. An example request +domains in ``${webroot-path}/.well-known/acme-challenge``. Then the Let's Encrypt +validation server makes HTTP requests to validate that the DNS for each +requested domain resolves to the server running certbot. An example request made to your web server would look like: :: @@ -188,7 +188,7 @@ specified port using each requested domain name. Manual ------ -If you'd like to obtain a cert running ``letsencrypt`` on a machine +If you'd like to obtain a cert running ``certbot`` on a machine other than your target webserver or perform the steps for domain validation yourself, you can use the manual plugin. While hidden from the UI, you can use the plugin to obtain a cert by specifying @@ -201,11 +201,10 @@ Nginx In the future, if you're running Nginx you will hopefully be able to use this plugin to automatically obtain and install your certificate. The Nginx plugin is -still experimental, however, and is not installed with letsencrypt-auto_. If +still experimental, however, and is not installed with certbot-auto_. If installed, you can select this plugin on the command line by including ``--nginx``. - Renewal ======= @@ -213,11 +212,11 @@ Renewal days). Make sure you renew the certificates at least once in 3 months. -The ``letsencrypt`` client now supports a ``renew`` action to check +The ``certbot`` client now supports a ``renew`` action to check all installed certificates for impending expiry and attempt to renew them. The simplest form is simply -``letsencrypt renew`` +``certbot renew`` This will attempt to renew any previously-obtained certificates that expire in less than 30 days. The same plugin and options that were used @@ -228,14 +227,14 @@ You can also specify hooks to be run before or after a certificate is renewed. For example, if you want to use the standalone_ plugin to renew your certificates, you may want to use a command like -``letsencrypt renew --standalone --pre-hook "service nginx stop" --post-hook "service nginx start"`` +``certbot renew --standalone --pre-hook "service nginx stop" --post-hook "service nginx start"`` This will stop Nginx so standalone can bind to the necessary ports and then restart Nginx after the plugin is finished. The hooks will only be run if a certificate is due for renewal, so you can run this command frequently without unnecessarily stopping your webserver. More information about renewal hooks can be found by running -``letsencrypt --help renew``. +``certbot --help renew``. If you're sure that this command executes successfully without human intervention, you can add the command to ``crontab`` (since certificates @@ -251,9 +250,9 @@ certificate regardless of its age. (This form is not appropriate to run daily because each certificate will be renewed every day, which will quickly run into the certificate authority rate limit.) -Note that options provided to ``letsencrypt renew`` will apply to +Note that options provided to ``certbot renew`` will apply to *every* certificate for which renewal is attempted; for example, -``letsencrypt renew --rsa-key-size 4096`` would try to replace every +``certbot renew --rsa-key-size 4096`` would try to replace every near-expiry certificate with an equivalent certificate using a 4096-bit RSA public key. If a certificate is successfully renewed using specified options, those options will be saved and used for future @@ -262,12 +261,12 @@ renewals of that certificate. An alternative form that provides for more fine-grained control over the renewal process (while renewing specified certificates one at a time), -is ``letsencrypt certonly`` with the complete set of subject domains of +is ``certbot certonly`` with the complete set of subject domains of a specific certificate specified via `-d` flags. You may also want to include the ``-n`` or ``--noninteractive`` flag to prevent blocking on user input (which is useful when running the command from cron). -``letsencrypt certonly -n -d example.com -d www.example.com`` +``certbot certonly -n -d example.com -d www.example.com`` (All of the domains covered by the certificate must be specified in this case in order to renew and replace the old certificate rather @@ -280,7 +279,7 @@ The ``certonly`` form attempts to renew one individual certificate. Please note that the CA will send notification emails to the address you provide if you do not renew certificates that are about to expire. -Let's Encrypt is working hard on improving the renewal process, and we +Certbot is working hard on improving the renewal process, and we apologize for any inconveniences you encounter in integrating these commands into your individual environment. @@ -311,7 +310,7 @@ The following files are available: Private key for the certificate. .. warning:: This **must be kept secret at all times**! Never share - it with anyone, including Let's Encrypt developers. You cannot + it with anyone, including Certbot developers. You cannot put it into a safe, however - your server still needs to access this file in order for SSL/TLS to work. @@ -364,7 +363,7 @@ Configuration file ================== It is possible to specify configuration file with -``letsencrypt-auto --config cli.ini`` (or shorter ``-c cli.ini``). An +``certbot-auto --config cli.ini`` (or shorter ``-c cli.ini``). An example configuration file is shown below: .. include:: ../examples/cli.ini @@ -383,13 +382,14 @@ By default, the following locations are searched: Getting help ============ -If you're having problems you can chat with us on `IRC (#letsencrypt @ -Freenode) `_ or -get support on our `forums `_. +If you're having problems you can chat with us on `IRC (#certbot @ +OFTC) `_ or at +`IRC (#letsencrypt @ freenode) `_ +or get support on the Let's Encrypt `forums `_. If you find a bug in the software, please do report it in our `issue tracker -`_. Remember to +`_. Remember to give us as much information as possible: - copy and paste exact command line used and the output (though mind @@ -397,7 +397,7 @@ give us as much information as possible: information, including your email and domains) - copy and paste logs from ``/var/log/letsencrypt`` (though mind they also might contain personally identifiable information) -- copy and paste ``letsencrypt --version`` output +- copy and paste ``certbot --version`` output - your operating system, including specific version - specify which installation_ method you've chosen @@ -414,10 +414,10 @@ plugins cannot reach it from inside the Docker container. You should definitely read the :ref:`where-certs` section, in order to know how to manage the certs -manually. https://github.com/letsencrypt/letsencrypt/wiki/Ciphersuite-guidance +manually. https://github.com/certbot/certbot/wiki/Ciphersuite-guidance provides some information about recommended ciphersuites. If none of these make much sense to you, you should definitely use the -letsencrypt-auto_ method, which enables you to use installer plugins +certbot-auto_ method, which enables you to use installer plugins that cover both of those hard topics. If you're still not convinced and have decided to use this method, @@ -426,7 +426,7 @@ to, `install Docker`_, then issue the following command: .. code-block:: shell - sudo docker run -it --rm -p 443:443 -p 80:80 --name letsencrypt \ + sudo docker run -it --rm -p 443:443 -p 80:80 --name certbot \ -v "/etc/letsencrypt:/etc/letsencrypt" \ -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ quay.io/letsencrypt/letsencrypt:latest auth @@ -456,19 +456,19 @@ Operating System Packages .. code-block:: shell - sudo pacman -S letsencrypt letsencrypt-apache + sudo pacman -S letsencrypt **Debian** -If you run Debian Stretch or Debian Sid, you can install letsencrypt packages. +If you run Debian Stretch or Debian Sid, you can install certbot packages. .. code-block:: shell sudo apt-get update - sudo apt-get install letsencrypt python-letsencrypt-apache + sudo apt-get install certbot python-certbot-apache If you don't want to use the Apache plugin, you can omit the -``python-letsencrypt-apache`` package. +``python-certbot-apache`` package. Packages exist for Debian Jessie via backports. First you'll have to follow the instructions at http://backports.debian.org/Instructions/ to enable the Jessie backports @@ -486,7 +486,7 @@ repo, if you have not already done so. Then run: **Gentoo** -The official Let's Encrypt client is available in Gentoo Portage. If you +The official Certbot client is available in Gentoo Portage. If you want to use the Apache plugin, it has to be installed separately: .. code-block:: shell @@ -495,8 +495,12 @@ want to use the Apache plugin, it has to be installed separately: emerge -av app-crypt/letsencrypt-apache Currently, only the Apache plugin is included in Portage. However, if you -want the nginx plugin, you can use Layman to add the mrueg overlay which -does include the nginx plugin package: +Warning! +You can use Layman to add the mrueg overlay which does include a package for the +Certbot Nginx plugin, however, this plugin is known to be buggy and should only +be used with caution after creating a backup up your Nginx configuration. +We strongly recommend you use the app-crypt/letsencrypt package instead until +the Nginx plugin is ready. .. code-block:: shell @@ -533,7 +537,7 @@ Note: this change is not required for the other plugins. **Other Operating Systems** OS packaging is an ongoing effort. If you'd like to package -Let's Encrypt client for your distribution of choice please have a +Certbot for your distribution of choice please have a look at the :doc:`packaging`. @@ -549,19 +553,19 @@ whole process is described in the :doc:`contributing`. environment, e.g. ``sudo python setup.py install``, ``sudo pip install``, ``sudo ./venv/bin/...``. These modes of operation might corrupt your operating system and are **not supported** by the - Let's Encrypt team! + Certbot team! Comparison of different methods ------------------------------- -Unless you have a very specific requirements, we kindly ask you to use -the letsencrypt-auto_ method. It's the fastest, the most thoroughly +Unless you have a very specific requirements, we kindly suggest that you use +the certbot-auto_ method. It's the fastest, the most thoroughly tested and the most reliable way of getting our software and the free -SSL certificates! +TLS/SSL certificates! Beyond the methods discussed here, other methods may be possible, such as -installing Let's Encrypt directly with pip from PyPI or downloading a ZIP +installing Certbot directly with pip from PyPI or downloading a ZIP archive from GitHub may be technically possible but are not presently recommended or supported. diff --git a/letsencrypt-apache/setup.py b/letsencrypt-apache/setup.py index a52044f87..b94746150 100644 --- a/letsencrypt-apache/setup.py +++ b/letsencrypt-apache/setup.py @@ -16,7 +16,7 @@ here = os.path.abspath(os.path.dirname(__file__)) readme = read_file(os.path.join(here, 'README.rst')) -version = '0.6.0.dev0' +version = '0.7.0.dev0' # This package is a simple shim around certbot-apache diff --git a/letsencrypt-auto b/letsencrypt-auto index 942fd8ea2..8c6e6c486 100755 --- a/letsencrypt-auto +++ b/letsencrypt-auto @@ -1,6 +1,6 @@ #!/bin/sh # -# Download and run the latest release version of the Let's Encrypt client. +# Download and run the latest release version of the Certbot client. # # NOTE: THIS SCRIPT IS AUTO-GENERATED AND SELF-UPDATING # @@ -19,11 +19,36 @@ XDG_DATA_HOME=${XDG_DATA_HOME:-~/.local/share} VENV_NAME="letsencrypt" VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"} VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.5.0" +LE_AUTO_VERSION="0.6.0" +BASENAME=$(basename $0) +USAGE="Usage: $BASENAME [OPTIONS] +A self-updating wrapper script for the Certbot ACME client. When run, updates +to both this script and certbot will be downloaded and installed. After +ensuring you have the latest versions installed, certbot will be invoked with +all arguments you have provided. + +Help for certbot itself cannot be provided until it is installed. + + --debug attempt experimental installation + -h, --help print this help + -n, --non-interactive, --noninteractive run without asking for user input + --no-self-upgrade do not download updates + --os-packages-only install OS dependencies and exit + -v, --verbose provide more output + +All arguments are accepted and forwarded to the Certbot client when run." + +while getopts ":hnv" arg; do + case $arg in + h) + HELP=1;; + n) + ASSUME_YES=1;; + v) + VERBOSE=1;; + esac +done -# This script takes the same arguments as the main letsencrypt program, but it -# additionally responds to --verbose (more output) and --debug (allow support -# for experimental platforms) for arg in "$@" ; do case "$arg" in --debug) @@ -34,25 +59,26 @@ for arg in "$@" ; do # Do not upgrade this script (also prevents client upgrades, because each # copy of the script pins a hash of the python client) NO_SELF_UPGRADE=1;; + --help) + HELP=1;; + --noninteractive|--non-interactive) + ASSUME_YES=1;; --verbose) VERBOSE=1;; - [!-]*|-*[!v]*|-) - # Anything that isn't -v, -vv, etc.: that is, anything that does not - # start with a -, contains anything that's not a v, or is just "-" - ;; - *) # -v+ remains. - VERBOSE=1;; esac done -# letsencrypt-auto needs root access to bootstrap OS dependencies, and -# letsencrypt itself needs root access for almost all modes of operation +# certbot-auto needs root access to bootstrap OS dependencies, and +# certbot itself needs root access for almost all modes of operation # The "normal" case is that sudo is used for the steps that need root, but # this script *can* be run as root (not recommended), or fall back to using # `su` +SUDO_ENV="" +export CERTBOT_AUTO="$0" if test "`id -u`" -ne "0" ; then if command -v sudo 1>/dev/null 2>&1; then SUDO=sudo + SUDO_ENV="CERTBOT_AUTO=$0" else echo \"sudo\" is not available, will use \"su\" for installation steps... # Because the parameters in `su -c` has to be a string, @@ -81,6 +107,12 @@ else SUDO= fi +if [ $BASENAME = "letsencrypt-auto" ]; then + # letsencrypt-auto does not respect --help or --yes for backwards compatibility + ASSUME_YES=1 + HELP=0 +fi + ExperimentalBootstrap() { # Arguments: Platform name, bootstrap function name if [ "$DEBUG" = 1 ]; then @@ -151,30 +183,45 @@ BootstrapDebCommon() { augeas_pkg="libaugeas0 augeas-lenses" AUGVERSION=`apt-cache show --no-all-versions libaugeas0 | grep ^Version: | cut -d" " -f2` + if [ "$ASSUME_YES" = 1 ]; then + YES_FLAG="-y" + fi + AddBackportRepo() { # ARGS: BACKPORT_NAME="$1" BACKPORT_SOURCELINE="$2" + echo "To use the Apache Certbot plugin, augeas needs to be installed from $BACKPORT_NAME." if ! grep -v -e ' *#' /etc/apt/sources.list | grep -q "$BACKPORT_NAME" ; then # This can theoretically error if sources.list.d is empty, but in that case we don't care. if ! grep -v -e ' *#' /etc/apt/sources.list.d/* 2>/dev/null | grep -q "$BACKPORT_NAME"; then - /bin/echo -n "Installing augeas from $BACKPORT_NAME in 3 seconds..." - sleep 1s - /bin/echo -ne "\e[0K\rInstalling augeas from $BACKPORT_NAME in 2 seconds..." - sleep 1s - /bin/echo -e "\e[0K\rInstalling augeas from $BACKPORT_NAME in 1 second ..." - sleep 1s - if echo $BACKPORT_NAME | grep -q wheezy ; then - /bin/echo '(Backports are only installed if explicitly requested via "apt-get install -t wheezy-backports")' + if [ "$ASSUME_YES" = 1 ]; then + /bin/echo -n "Installing augeas from $BACKPORT_NAME in 3 seconds..." + sleep 1s + /bin/echo -ne "\e[0K\rInstalling augeas from $BACKPORT_NAME in 2 seconds..." + sleep 1s + /bin/echo -e "\e[0K\rInstalling augeas from $BACKPORT_NAME in 1 second ..." + sleep 1s + add_backports=1 + else + read -p "Would you like to enable the $BACKPORT_NAME repository [Y/n]? " response + case $response in + [yY][eE][sS]|[yY]|"") + add_backports=1;; + *) + add_backports=0;; + esac + fi + if [ "$add_backports" = 1 ]; then + $SUDO sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list" + $SUDO apt-get update fi - - $SUDO sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list" - $SUDO apt-get update fi fi - $SUDO apt-get install -y --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg - augeas_pkg= - + if [ "$add_backports" != 0 ]; then + $SUDO apt-get install $YES_FLAG --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg + augeas_pkg= + fi } @@ -186,12 +233,12 @@ BootstrapDebCommon() { AddBackportRepo precise-backports "deb http://archive.ubuntu.com/ubuntu precise-backports main restricted universe multiverse" else echo "No libaugeas0 version is available that's new enough to run the" - echo "Let's Encrypt apache plugin..." + echo "Certbot apache plugin..." fi # XXX add a case for ubuntu PPAs fi - $SUDO apt-get install -y --no-install-recommends \ + $SUDO apt-get install $YES_FLAG --no-install-recommends \ python \ python-dev \ $virtualenv \ @@ -212,9 +259,10 @@ BootstrapDebCommon() { BootstrapRpmCommon() { # Tested with: - # - Fedora 22, 23 (x64) + # - Fedora 20, 21, 22, 23 (x64) # - Centos 7 (x64: on DigitalOcean droplet) # - CentOS 7 Minimal install in a Hyper-V VM + # - CentOS 6 (EPEL must be installed manually) if type dnf 2>/dev/null then @@ -228,54 +276,62 @@ BootstrapRpmCommon() { exit 1 fi + pkgs=" + gcc + dialog + augeas-libs + openssl + openssl-devel + libffi-devel + redhat-rpm-config + ca-certificates + " + # Some distros and older versions of current distros use a "python27" # instead of "python" naming convention. Try both conventions. - if ! $SUDO $tool install -y \ - python \ - python-devel \ - python-virtualenv \ - python-tools \ - python-pip - then - if ! $SUDO $tool install -y \ - python27 \ - python27-devel \ - python27-virtualenv \ - python27-tools \ - python27-pip - then - echo "Could not install Python dependencies. Aborting bootstrap!" - exit 1 - fi + if $SUDO $tool list python >/dev/null 2>&1; then + pkgs="$pkgs + python + python-devel + python-virtualenv + python-tools + python-pip + " + else + pkgs="$pkgs + python27 + python27-devel + python27-virtualenv + python27-tools + python27-pip + " fi - if ! $SUDO $tool install -y \ - gcc \ - dialog \ - augeas-libs \ - openssl \ - openssl-devel \ - libffi-devel \ - redhat-rpm-config \ - ca-certificates - then - echo "Could not install additional dependencies. Aborting bootstrap!" - exit 1 - fi - - if $SUDO $tool list installed "httpd" >/dev/null 2>&1; then - if ! $SUDO $tool install -y mod_ssl - then - echo "Apache found, but mod_ssl could not be installed." - fi + pkgs="$pkgs + mod_ssl + " + fi + + if [ "$ASSUME_YES" = 1 ]; then + yes_flag="-y" + fi + + if ! $SUDO $tool install $yes_flag $pkgs; then + echo "Could not install OS dependencies. Aborting bootstrap!" + exit 1 fi } BootstrapSuseCommon() { # SLE12 don't have python-virtualenv - $SUDO zypper -nq in -l \ + if [ "$ASSUME_YES" = 1 ]; then + zypper_flags="-nq" + install_flags="-l" + fi + + $SUDO zypper $zypper_flags in $install_flags \ python \ python-devel \ python-virtualenv \ @@ -310,8 +366,12 @@ BootstrapArchCommon() { # pacman -T exits with 127 if there are missing dependencies missing=$($SUDO pacman -T $deps) || true + if [ "$ASSUME_YES" = 1 ]; then + noconfirm="--noconfirm" + fi + if [ "$missing" ]; then - $SUDO pacman -S --needed $missing + $SUDO pacman -S --needed $missing $noconfirm fi } @@ -426,7 +486,7 @@ Bootstrap() { elif grep -iq "Amazon Linux" /etc/issue ; then ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon else - echo "Sorry, I don't know how to bootstrap Let's Encrypt on your operating system!" + echo "Sorry, I don't know how to bootstrap Certbot on your operating system!" echo echo "You will need to bootstrap, configure virtualenv, and run pip install manually." echo "Please see https://letsencrypt.readthedocs.org/en/latest/contributing.html#prerequisites" @@ -446,7 +506,8 @@ if [ "$1" = "--le-auto-phase2" ]; then shift 1 # the --le-auto-phase2 arg if [ -f "$VENV_BIN/letsencrypt" ]; then # --version output ran through grep due to python-cryptography DeprecationWarnings - INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | grep ^letsencrypt | cut -d " " -f 2) + # grep for both certbot and letsencrypt until certbot and shim packages have been released + INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | grep "^certbot\|^letsencrypt" | cut -d " " -f 2) else INSTALLED_VERSION="none" fi @@ -465,8 +526,8 @@ if [ "$1" = "--le-auto-phase2" ]; then # There is no $ interpolation due to quotes on starting heredoc delimiter. # ------------------------------------------------------------------------- cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt" -# This is the flattened list of packages letsencrypt-auto installs. To generate -# this, do `pip install --no-cache-dir -e acme -e . -e letsencrypt-apache`, and +# This is the flattened list of packages certbot-auto installs. To generate +# this, do `pip install --no-cache-dir -e acme -e . -e certbot-apache`, and # then use `hashin` or a more secure method to gather the hashes. argparse==1.4.0 \ @@ -645,15 +706,21 @@ mock==1.0.1 \ # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. -acme==0.5.0 \ - --hash=sha256:ceb4127c13213f0006a564be82176b968c6b374d20d9fc78555d0658a252b275 \ - --hash=sha256:0605c63c656d33c883a05675f5db9cfb85d503f2771c885031800e0da7631abd -letsencrypt==0.5.0 \ - --hash=sha256:f90f883e99cdbdf8142335bdbf4f74a8af143ee4b4ec60fb49c6e47418c1114c \ - --hash=sha256:e38a2b70b82be79bc195307652244a3e012ec73d897d4dbd3f80cf698496d15a -letsencrypt-apache==0.5.0 \ - --hash=sha256:a767882164a7b09d9c12c80684a28a782135fdaf35654ef5a02c0b7b1d27ab8d \ - --hash=sha256:c20e7b9c517aa4a7d70e6bd9382da7259f00bc191b9e60d8e312e48837a00c41 +acme==0.6.0 \ + --hash=sha256:cbe4e7a340a19725a8740ed86e30abdbe18fc22c4c6022b7a8e56642d502bcc3 \ + --hash=sha256:ec4e6009dfbd629b58473eb06bbebfd9fb2a79fc8831c149e9205bc38a98ecc6 +certbot==0.6.0 \ + --hash=sha256:a893632d228864b0a751db9f3fdd93439ed34b988ea21b64fb0f0fa2ceded6a2 \ + --hash=sha256:80b0b7dc5afeec2816ef638a61e7c628d73cd72666eebf4984be426d1c2b492d +certbot-apache==0.6.0 \ + --hash=sha256:0ab077f0913b81ed5c1b141c3a7c4c0228ef3738d8d61a93db794d9a80718d43 \ + --hash=sha256:1cfbe751209079a803758f472200816fac559f2a36fdd582d25e3ba5601423a1 +letsencrypt==0.6.0 \ + --hash=sha256:93196c7dcd57272a753e525d145c5a9987c8968c22ec954bcf83dcc9d2499a76 \ + --hash=sha256:a16d6c395f1bf5fd61a28ef83dc78f42dbecbad9d00be6236f2ad8915645c154 +letsencrypt-apache==0.6.0 \ + --hash=sha256:02fadc52a0796e53978c508beec9c53e1fc047660240832b9bde5d53ab3a1379 \ + --hash=sha256:1c5522d94d7750bdb9bfa6201d2c263e914f662c9d0079e673167233cf4364f1 UNLIKELY_EOF # ------------------------------------------------------------------------- @@ -823,18 +890,30 @@ UNLIKELY_EOF fi echo "Installation succeeded." fi - echo "Requesting root privileges to run letsencrypt..." - echo " " $SUDO "$VENV_BIN/letsencrypt" "$@" - $SUDO "$VENV_BIN/letsencrypt" "$@" + echo "Requesting root privileges to run certbot..." + if [ -z "$SUDO_ENV" ] ; then + # SUDO is su wrapper / noop + echo " " $SUDO "$VENV_BIN/letsencrypt" "$@" + $SUDO "$VENV_BIN/letsencrypt" "$@" + else + # sudo + echo " " $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@" + $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@" + fi + else - # Phase 1: Upgrade letsencrypt-auto if neceesary, then self-invoke. + # Phase 1: Upgrade certbot-auto if neceesary, then self-invoke. # # Each phase checks the version of only the thing it is responsible for # upgrading. Phase 1 checks the version of the latest release of - # letsencrypt-auto (which is always the same as that of the letsencrypt - # package). Phase 2 checks the version of the locally installed letsencrypt. + # certbot-auto (which is always the same as that of the certbot + # package). Phase 2 checks the version of the locally installed certbot. if [ ! -f "$VENV_BIN/letsencrypt" ]; then + if [ "$HELP" = 1 ]; then + echo "$USAGE" + exit 0 + fi # If it looks like we've never bootstrapped before, bootstrap: Bootstrap fi @@ -953,7 +1032,7 @@ def verified_new_le_auto(get, tag, temp_dir): stderr=dev_null) except CalledProcessError as exc: raise ExpectedError("Couldn't verify signature of downloaded " - "letsencrypt-auto.", exc) + "certbot-auto.", exc) def main(): @@ -978,29 +1057,27 @@ if __name__ == '__main__': UNLIKELY_EOF # --------------------------------------------------------------------------- DeterminePythonVersion - REMOTE_VERSION=`"$LE_PYTHON" "$TEMP_DIR/fetch.py" --latest-version` - if [ "$LE_AUTO_VERSION" != "$REMOTE_VERSION" ]; then - echo "Upgrading letsencrypt-auto $LE_AUTO_VERSION to $REMOTE_VERSION..." + if ! REMOTE_VERSION=`"$LE_PYTHON" "$TEMP_DIR/fetch.py" --latest-version` ; then + echo "WARNING: unable to check for updates." + elif [ "$LE_AUTO_VERSION" != "$REMOTE_VERSION" ]; then + echo "Upgrading certbot-auto $LE_AUTO_VERSION to $REMOTE_VERSION..." # Now we drop into Python so we don't have to install even more # dependencies (curl, etc.), for better flow control, and for the option of # future Windows compatibility. "$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION" - # Install new copy of letsencrypt-auto. + # Install new copy of certbot-auto. # TODO: Deal with quotes in pathnames. - echo "Replacing letsencrypt-auto..." + echo "Replacing certbot-auto..." # Clone permissions with cp. chmod and chown don't have a --reference # option on OS X or BSD, and stat -c on Linux is stat -f on OS X and BSD: - echo " " $SUDO cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone" $SUDO cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone" - echo " " $SUDO cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone" $SUDO cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone" # Using mv rather than cp leaves the old file descriptor pointing to the # original copy so the shell can continue to read it unmolested. mv across # filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the # cp is unlikely to fail (esp. under sudo) if the rm doesn't. - echo " " $SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" $SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" # TODO: Clean up temp dir safely, even if it has quotes in its path. rm -rf "$TEMP_DIR" diff --git a/letsencrypt-auto-source/certbot-auto.asc b/letsencrypt-auto-source/certbot-auto.asc new file mode 100644 index 000000000..8b4f34c70 --- /dev/null +++ b/letsencrypt-auto-source/certbot-auto.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iQEcBAABAgAGBQJXM9ZDAAoJEE0XyZXNl3XyzGkH/2KeR0jYxXKlvwfCkxU6hSC0 +eXcxZVQk59hCSvkNGE6Mj6rwQcyjSqmRp14MaJpq7NZADN6F+HWb6VB/Wq6moMQs +PJtthqwhF767Qg+Py9Hp6XmlKscjXB6AKCVxq5TBwEIOTtj0rhQRLF9/+GW6jFuf +kT6aUcDWNjOyWWUtp9vOVprDtegrltp0/2DNitlvPu263pKC+7I3GyLTq4fKP4EE +auZSAhFry9SNR3Usf2wD3kzhvLSrT3h9Yh5oA04oaX9H6e86EHwt6RJJRHpg8s6b +e0CBIIuaRJEmdiMUWlV/gAfH6M2PbG1wtJdxc0ThNEoWAjTsopr61BoHJ3cpCy4= +=+e7/ +-----END PGP SIGNATURE----- diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 8578feef2..b255a99a7 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -19,7 +19,7 @@ XDG_DATA_HOME=${XDG_DATA_HOME:-~/.local/share} VENV_NAME="letsencrypt" VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"} VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.6.0.dev0" +LE_AUTO_VERSION="0.7.0.dev0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -706,15 +706,21 @@ mock==1.0.1 \ # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. -acme==0.5.0 \ - --hash=sha256:ceb4127c13213f0006a564be82176b968c6b374d20d9fc78555d0658a252b275 \ - --hash=sha256:0605c63c656d33c883a05675f5db9cfb85d503f2771c885031800e0da7631abd -letsencrypt==0.5.0 \ - --hash=sha256:f90f883e99cdbdf8142335bdbf4f74a8af143ee4b4ec60fb49c6e47418c1114c \ - --hash=sha256:e38a2b70b82be79bc195307652244a3e012ec73d897d4dbd3f80cf698496d15a -letsencrypt-apache==0.5.0 \ - --hash=sha256:a767882164a7b09d9c12c80684a28a782135fdaf35654ef5a02c0b7b1d27ab8d \ - --hash=sha256:c20e7b9c517aa4a7d70e6bd9382da7259f00bc191b9e60d8e312e48837a00c41 +acme==0.6.0 \ + --hash=sha256:cbe4e7a340a19725a8740ed86e30abdbe18fc22c4c6022b7a8e56642d502bcc3 \ + --hash=sha256:ec4e6009dfbd629b58473eb06bbebfd9fb2a79fc8831c149e9205bc38a98ecc6 +certbot==0.6.0 \ + --hash=sha256:a893632d228864b0a751db9f3fdd93439ed34b988ea21b64fb0f0fa2ceded6a2 \ + --hash=sha256:80b0b7dc5afeec2816ef638a61e7c628d73cd72666eebf4984be426d1c2b492d +certbot-apache==0.6.0 \ + --hash=sha256:0ab077f0913b81ed5c1b141c3a7c4c0228ef3738d8d61a93db794d9a80718d43 \ + --hash=sha256:1cfbe751209079a803758f472200816fac559f2a36fdd582d25e3ba5601423a1 +letsencrypt==0.6.0 \ + --hash=sha256:93196c7dcd57272a753e525d145c5a9987c8968c22ec954bcf83dcc9d2499a76 \ + --hash=sha256:a16d6c395f1bf5fd61a28ef83dc78f42dbecbad9d00be6236f2ad8915645c154 +letsencrypt-apache==0.6.0 \ + --hash=sha256:02fadc52a0796e53978c508beec9c53e1fc047660240832b9bde5d53ab3a1379 \ + --hash=sha256:1c5522d94d7750bdb9bfa6201d2c263e914f662c9d0079e673167233cf4364f1 UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/letsencrypt-auto-source/letsencrypt-auto.sig b/letsencrypt-auto-source/letsencrypt-auto.sig index 36ab206aa..cb360f89e 100644 Binary files a/letsencrypt-auto-source/letsencrypt-auto.sig and b/letsencrypt-auto-source/letsencrypt-auto.sig differ diff --git a/letsencrypt-auto-source/pieces/bootstrappers/mac.sh b/letsencrypt-auto-source/pieces/bootstrappers/mac.sh index 79e58eb3f..e41db04b1 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/mac.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/mac.sh @@ -26,7 +26,8 @@ BootstrapMac() { # Workaround for _dlopen not finding augeas on OS X if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then echo "Applying augeas workaround" - $SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib + $SUDO mkdir -p /usr/local/lib/ + $SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib/ fi if ! hash pip 2>/dev/null; then diff --git a/letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt b/letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt index 3a1ce34f1..f4ceae536 100644 --- a/letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt +++ b/letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt @@ -178,12 +178,18 @@ mock==1.0.1 \ # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. -acme==0.5.0 \ - --hash=sha256:ceb4127c13213f0006a564be82176b968c6b374d20d9fc78555d0658a252b275 \ - --hash=sha256:0605c63c656d33c883a05675f5db9cfb85d503f2771c885031800e0da7631abd -letsencrypt==0.5.0 \ - --hash=sha256:f90f883e99cdbdf8142335bdbf4f74a8af143ee4b4ec60fb49c6e47418c1114c \ - --hash=sha256:e38a2b70b82be79bc195307652244a3e012ec73d897d4dbd3f80cf698496d15a -letsencrypt-apache==0.5.0 \ - --hash=sha256:a767882164a7b09d9c12c80684a28a782135fdaf35654ef5a02c0b7b1d27ab8d \ - --hash=sha256:c20e7b9c517aa4a7d70e6bd9382da7259f00bc191b9e60d8e312e48837a00c41 +acme==0.6.0 \ + --hash=sha256:cbe4e7a340a19725a8740ed86e30abdbe18fc22c4c6022b7a8e56642d502bcc3 \ + --hash=sha256:ec4e6009dfbd629b58473eb06bbebfd9fb2a79fc8831c149e9205bc38a98ecc6 +certbot==0.6.0 \ + --hash=sha256:a893632d228864b0a751db9f3fdd93439ed34b988ea21b64fb0f0fa2ceded6a2 \ + --hash=sha256:80b0b7dc5afeec2816ef638a61e7c628d73cd72666eebf4984be426d1c2b492d +certbot-apache==0.6.0 \ + --hash=sha256:0ab077f0913b81ed5c1b141c3a7c4c0228ef3738d8d61a93db794d9a80718d43 \ + --hash=sha256:1cfbe751209079a803758f472200816fac559f2a36fdd582d25e3ba5601423a1 +letsencrypt==0.6.0 \ + --hash=sha256:93196c7dcd57272a753e525d145c5a9987c8968c22ec954bcf83dcc9d2499a76 \ + --hash=sha256:a16d6c395f1bf5fd61a28ef83dc78f42dbecbad9d00be6236f2ad8915645c154 +letsencrypt-apache==0.6.0 \ + --hash=sha256:02fadc52a0796e53978c508beec9c53e1fc047660240832b9bde5d53ab3a1379 \ + --hash=sha256:1c5522d94d7750bdb9bfa6201d2c263e914f662c9d0079e673167233cf4364f1 diff --git a/letsencrypt-nginx/setup.py b/letsencrypt-nginx/setup.py index b94b7f69f..95ffd6cd8 100644 --- a/letsencrypt-nginx/setup.py +++ b/letsencrypt-nginx/setup.py @@ -16,7 +16,7 @@ here = os.path.abspath(os.path.dirname(__file__)) readme = read_file(os.path.join(here, 'README.rst')) -version = '0.6.0.dev0' +version = '0.7.0.dev0' # This package is a simple shim around certbot-nginx diff --git a/letsencrypt/setup.py b/letsencrypt/setup.py index 708c31f4b..7c974ea9b 100644 --- a/letsencrypt/setup.py +++ b/letsencrypt/setup.py @@ -20,7 +20,7 @@ readme = read_file(os.path.join(here, 'README.rst')) install_requires = ['certbot'] -version = '0.6.0.dev0' +version = '0.7.0.dev0' setup( diff --git a/letshelp-certbot/docs/conf.py b/letshelp-certbot/docs/conf.py index 905d70662..17d8b3ea9 100644 --- a/letshelp-certbot/docs/conf.py +++ b/letshelp-certbot/docs/conf.py @@ -307,5 +307,5 @@ texinfo_documents = [ intersphinx_mapping = { 'python': ('https://docs.python.org/', None), 'acme': ('https://acme-python.readthedocs.org/en/latest/', None), - 'certbot': ('https://letsencrypt.readthedocs.org/en/latest/', None), + 'certbot': ('https://certbot.eff.org/docs/', None), } diff --git a/letshelp-certbot/setup.py b/letshelp-certbot/setup.py index 8359d2766..b616da688 100644 --- a/letshelp-certbot/setup.py +++ b/letshelp-certbot/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.6.0.dev0' +version = '0.7.0.dev0' install_requires = [ 'setuptools', # pkg_resources diff --git a/letshelp-letsencrypt/setup.py b/letshelp-letsencrypt/setup.py index 875c6fc92..10380c49b 100644 --- a/letshelp-letsencrypt/setup.py +++ b/letshelp-letsencrypt/setup.py @@ -16,7 +16,7 @@ here = os.path.abspath(os.path.dirname(__file__)) readme = read_file(os.path.join(here, 'README.rst')) -version = '0.6.0.dev0' +version = '0.7.0.dev0' # This package is a simple shim around letshelp-certbot diff --git a/tools/release.sh b/tools/release.sh index e6169c5c8..8c2d04cd4 100755 --- a/tools/release.sh +++ b/tools/release.sh @@ -187,6 +187,12 @@ while ! openssl dgst -sha256 -verify $RELEASE_OPENSSL_PUBKEY -signature \ read -p "Please correctly sign letsencrypt-auto with offline-signrequest.sh" done +# This signature is not quite as strong, but easier for people to verify out of band +gpg -u "$RELEASE_GPG_KEY" --detach-sign --armor --sign letsencrypt-auto-source/letsencrypt-auto +# We can't rename the openssl letsencrypt-auto.sig for compatibility reasons, +# but we can use the right name for cerbot-auto.asc from day one +mv letsencrypt-auto-source/letsencrypt-auto.asc letsencrypt-auto-source/certbot-auto.asc + # copy leauto to the root, overwriting the previous release version cp -p letsencrypt-auto-source/letsencrypt-auto certbot-auto cp -p letsencrypt-auto-source/letsencrypt-auto letsencrypt-auto