diff --git a/.gitignore b/.gitignore index 341843f98..38c95986c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ dist*/ /venv*/ /kgs/ /.tox/ +/releases/ letsencrypt.log # coverage diff --git a/.travis.yml b/.travis.yml index d5d18737a..6b325e985 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ matrix: env: TOXENV=le_auto services: docker before_install: + addons: - python: "2.7" env: TOXENV=cover - python: "3.3" diff --git a/acme/setup.py b/acme/setup.py index 5a77f8a67..0843288e6 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -18,7 +18,9 @@ install_requires = [ 'pyrfc3339', 'pytz', 'requests', - 'setuptools', # pkg_resources + # For pkg_resources. >=1.0 so pip resolves it to a version cryptography + # will tolerate; see #2599: + 'setuptools>=1.0', 'six', ] diff --git a/letsencrypt-apache/setup.py b/letsencrypt-apache/setup.py index a8e010f0e..46f4da54c 100644 --- a/letsencrypt-apache/setup.py +++ b/letsencrypt-apache/setup.py @@ -11,7 +11,9 @@ install_requires = [ 'acme=={0}'.format(version), 'letsencrypt=={0}'.format(version), 'python-augeas', - 'setuptools', # pkg_resources + # For pkg_resources. >=1.0 so pip resolves it to a version cryptography + # will tolerate; see #2599: + 'setuptools>=1.0', 'zope.component', 'zope.interface', ] diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 415bcbbc7..9b05092ed 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -421,6 +421,19 @@ TempDir() { mktemp -d 2>/dev/null || mktemp -d -t 'le' # Linux || OS X } +InstallRequirements() { + set +e + PEEP_OUT=`"$VENV_BIN/python" "$TEMP_DIR/peep.py" install -r "$TEMP_DIR/$1"` + PEEP_STATUS=$? + set -e + if [ "$PEEP_STATUS" != 0 ]; then + # Report error. (Otherwise, be quiet.) + echo "Had a problem while downloading and verifying Python packages:" + echo "$PEEP_OUT" + rm -rf "$VENV_PATH" + exit 1 + fi +} if [ "$1" = "--le-auto-phase2" ]; then @@ -444,7 +457,17 @@ if [ "$1" = "--le-auto-phase2" ]; then echo "Installing Python packages..." TEMP_DIR=$(TempDir) + trap "rm -rf '$TEMP_DIR'" EXIT # There is no $ interpolation due to quotes on starting heredoc delimiter. + # ------------------------------------------------------------------------- + cat << "UNLIKELY_EOF" > "$TEMP_DIR/setuptools-requirements.txt" +# cryptography requires a more modern version of setuptools. +# sha256: _ANFf7h6utSdwJ-cMTOGNpPn3bbKgrtQpzmnc3nOWpo +# sha256: JPz8FTZKn-CaIg830tztyEl5Xj3j5LOT7piOZqnL2Fo +# sha256: gJaELiTE8ddN_xKr6Qwm0S8F0NmlbtXgb8qm-qHkC2o +setuptools==20.2.2 + +UNLIKELY_EOF # ------------------------------------------------------------------------- cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt" # This is the flattened list of packages letsencrypt-auto installs. To generate @@ -455,6 +478,11 @@ if [ "$1" = "--le-auto-phase2" ]; then # sha256: YrCJpVvh2JSc0rx-DfC9254Cj678jDIDjMhIYq791uQ argparse==1.4.0 +# This comes before cffi because cffi will otherwise install an unchecked +# version via setup_requires. +# sha256: eVm0p0q9wnsxL-0cIebK-TCc4LKeqGtZH9Lpns3yf3M +pycparser==2.14 + # sha256: U8HJ3bMEMVE-t_PN7wo-BrDxJSGIqqd0SvD1pM1F268 # sha256: pWj0nfyhKo2fNwGHJX78WKOBCeHu5xTZKFYdegGKZPg # sha256: gJxsqM-8ruv71DK0V2ABtA04_yRjdzy1dXfXXhoCC8M @@ -479,28 +507,28 @@ ConfigArgParse==0.10.0 # sha256: ovVlB3DhyH-zNa8Zqbfrc_wFzPIhROto230AzSvLCQI configobj==5.0.6 -# sha256: 1U_hszrB4J8cEj4vl0948z6V1h1PSALdISIKXD6MEX0 -# sha256: B1X2aE4RhSAFs2MTdh7ctbqEOmTNAizhrC3L1JqTYG0 -# sha256: zjhNo4lZlluh90VKJfVp737yqxRd8ueiml4pS3TgRnc -# sha256: GvQDkV3LmWHDB2iuZRr6tpKC0dpaut-mN1IhrBGHdQM -# sha256: ag08d91PH-W8ZfJ--3fsjQSjiNpesl66DiBAwJgZ30o -# sha256: KdelgcO6_wTh--IAaltHjZ7cfPmib8ijWUkkf09lA3k -# sha256: IPAWEKpAh_bVadjMIMR4uB8DhIYnWqqx3Dx12VAsZ-A -# sha256: l9hGUIulDVomml82OK4cFmWbNTFaH0B_oVF2cH2j0Jc -# sha256: djfqRMLL1NsvLKccsmtmPRczORqnafi8g2xZVilbd5g -# sha256: gR-eqJVbPquzLgQGU0XDB4Ui5rPuPZLz0n08fNcWpjM -# sha256: DXCMjYz97Qm4fCoLqHY856ZjWG4EPmrEL9eDHpKQHLY -# sha256: Efnq11YqPgATWGytM5o_em9Yg8zhw7S5jhrGnft3p_Y -# sha256: dNhnm55-0ePs-wq1NNyTUruxz3PTYsmQkJTAlyivqJY -# sha256: z1Hd-123eBaiB1OKZgEUuC4w4IAD_uhJmwILi4SA2sU -# sha256: 47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU -# sha256: dITvgYGUFB3_eUdf-74vd6-FHiw7v-Lk1ZEjEi-KTjM -# sha256: 7gLB6J7l7pUBV6VK1YTXN8Ec83putMCFPozz8n6WLcA -# sha256: pfGPaxhQpVVKV9v2YsrSUSpGBW5paHJqmFjngN1bnQo -# sha256: 26GA8xrb5xi6qdbPirY0hJSwlLK4GAL_8zvVDSfRPnM -# sha256: 5RinlLjzjoOC9_B3kUGBPOtIE6z9MRVBwNsOGJ69eN4 -# sha256: f1FFn4TWcERCdeYVg59FQsk1R6Euk4oKSQba_l994VM -cryptography==1.1.2 +# sha256: Axk49zpcXrPoCeGP98rraGU1GHFBe-YFDLjIapogK5o +# sha256: oXmjjVD41otJHXoxPbePjKvikIQs7N3dx7NNQI5Z2wo +# sha256: kGyIsqrc-Zz6uyQJgmPRv2WrDIaIrN4Q2uHwnYZZIPE +# sha256: bnBsXGCIdwsdG2NOlZ4hlj4xWwJV9fR3cSWtPVQIKXc +# sha256: 9ev44xxI-HB5Idyg6ZTed4E6nJub8DwRnF3fl73P_nM +# sha256: x7ieQiiMx_vuOBLpnvXHRPIkUuEdaCL2gHr8bWs76D4 +# sha256: hAjSmGWUcQnYto8YN6fN4apNyG4Peco7pYwMRORD1qU +# sha256: x-ds88PZJd0x-iOM-4Bs_7pxjA8IcH13pTh2hHeWmVY +# sha256: fY3jU4DzFwJ1i3dTu1xAcjgyxzAG3tsvkJm_YaN_coc +# sha256: XtvucfrlRp7oP-CjeGa5OYyM46RjJcJPzt-_CXu0ihk +# sha256: WU7a_kgBwTvcHMMF53BKkMGWF-lZNvarRX7k_-AAulA +# sha256: t_2xagp_SBvkLadEv-HqIWMCXeIfkPLGiKMW88NU2pw +# sha256: IHuL8P4JBzNt84tzO0h1Ic-eE4GJq6kjStVP5UXdDbg +# sha256: UJovBThicM94OZPJDUn_77PdYq7kW_HqjOPSzecnHCE +# sha256: rGm2XdGvAXnt5AyfFXiMiPc-Yo6mwFGd44OOJ5uziMY +# sha256: jfb61sauEv1wBOopNX8KK003dOrsp2VlMNCNLZDNQao +# sha256: C4uW3YHMFTOgTzA4LA_iHBly4Yn3lNDEJhoYzsCP2bU +# sha256: yuj8oYg_I8UOp42J3m_k_v20zqgxd3YPRxd1WUFN7ZM +# sha256: GkccpXapzc4bHNnzoisdCe5E1GhiA3VX3heRnA20RCU +# sha256: jsTo49RTs6G2O19Xc3pDTc8e5KLyb2_3xaN8P2eRBNI +# sha256: jrEcd92Oc_SN9rL3p-Fhc_4P6P3-JmIygy6IR34IRU4 +cryptography==1.2.3 # sha256: JHXX_N31lR6S_1RpcnWIAt5SYL9Akxmp8ZNOa7yLHcc # sha256: NZB977D5krdat3iPZf7cHPIP-iJojg5vbxKvwGs-pQE @@ -528,9 +556,9 @@ ndg-httpsclient==0.4.0 # sha256: HDW0rCBs7y0kgWyJ-Jzyid09OM98RJuz-re_bUPwGx8 ordereddict==1.1 -# sha256: OnTxAPkNZZGDFf5kkHca0gi8PxOv0y01_P5OjQs7gSs -# sha256: Paa-K-UG9ZzOMuGeMOIBBT4btNB-JWaJGOAPikmtQKs -parsedatetime==1.5 +# sha256: zp1CIWXPbpY5Bc1fdPJ06_fMmMlBkWFpF475Pw5VeDg +# sha256: F8V4d1UgyZExY04Jz8paBeqeG9KgXNBpZ-vs4Q33ry0 +parsedatetime==2.1 # sha256: Rsjbda51oFa9HMB_ohc0_i5gPRGgeDPswe63TDXHLgw # sha256: 4hJ2JqkebIhduJZol22zECDwry2nKJJLVkgPx8zwlkk @@ -572,9 +600,6 @@ psutil==3.3.0 # sha256: hTys2W0fcB3dZ6oD7MBfUYkBNbcmLpInEBEvEqLtKn8 pyasn1==0.1.9 -# sha256: eVm0p0q9wnsxL-0cIebK-TCc4LKeqGtZH9Lpns3yf3M -pycparser==2.14 - # sha256: iORea7Jd_tJyoe8ucoRh1EtjTCzWiemJtuVqNJxaOuU # sha256: 8KJgcNbbCIHei8x4RpNLfDyTDY-cedRYg-5ImEvA1nI pyOpenSSL==0.15.1 @@ -1641,18 +1666,8 @@ if __name__ == '__main__': UNLIKELY_EOF # ------------------------------------------------------------------------- - set +e - PEEP_OUT=`"$VENV_BIN/python" "$TEMP_DIR/peep.py" install -r "$TEMP_DIR/letsencrypt-auto-requirements.txt"` - PEEP_STATUS=$? - set -e - rm -rf "$TEMP_DIR" - if [ "$PEEP_STATUS" != 0 ]; then - # Report error. (Otherwise, be quiet.) - echo "Had a problem while downloading and verifying Python packages:" - echo "$PEEP_OUT" - rm -rf "$VENV_PATH" - exit 1 - fi + InstallRequirements "setuptools-requirements.txt" + InstallRequirements "letsencrypt-auto-requirements.txt" echo "Installation succeeded." fi echo "Requesting root privileges to run letsencrypt..." diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index ea4d064b7..291d2ee9e 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -169,6 +169,19 @@ TempDir() { mktemp -d 2>/dev/null || mktemp -d -t 'le' # Linux || OS X } +InstallRequirements() { + set +e + PEEP_OUT=`"$VENV_BIN/python" "$TEMP_DIR/peep.py" install -r "$TEMP_DIR/$1"` + PEEP_STATUS=$? + set -e + if [ "$PEEP_STATUS" != 0 ]; then + # Report error. (Otherwise, be quiet.) + echo "Had a problem while downloading and verifying Python packages:" + echo "$PEEP_OUT" + rm -rf "$VENV_PATH" + exit 1 + fi +} if [ "$1" = "--le-auto-phase2" ]; then @@ -192,7 +205,12 @@ if [ "$1" = "--le-auto-phase2" ]; then echo "Installing Python packages..." TEMP_DIR=$(TempDir) + trap "rm -rf '$TEMP_DIR'" EXIT # There is no $ interpolation due to quotes on starting heredoc delimiter. + # ------------------------------------------------------------------------- + cat << "UNLIKELY_EOF" > "$TEMP_DIR/setuptools-requirements.txt" +{{ setuptools-requirements.txt }} +UNLIKELY_EOF # ------------------------------------------------------------------------- cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt" {{ letsencrypt-auto-requirements.txt }} @@ -202,18 +220,8 @@ UNLIKELY_EOF {{ peep.py }} UNLIKELY_EOF # ------------------------------------------------------------------------- - set +e - PEEP_OUT=`"$VENV_BIN/python" "$TEMP_DIR/peep.py" install -r "$TEMP_DIR/letsencrypt-auto-requirements.txt"` - PEEP_STATUS=$? - set -e - rm -rf "$TEMP_DIR" - if [ "$PEEP_STATUS" != 0 ]; then - # Report error. (Otherwise, be quiet.) - echo "Had a problem while downloading and verifying Python packages:" - echo "$PEEP_OUT" - rm -rf "$VENV_PATH" - exit 1 - fi + InstallRequirements "setuptools-requirements.txt" + InstallRequirements "letsencrypt-auto-requirements.txt" echo "Installation succeeded." fi echo "Requesting root privileges to run letsencrypt..." diff --git a/letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt b/letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt index 7ec4db444..381759a5c 100644 --- a/letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt +++ b/letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt @@ -6,6 +6,11 @@ # sha256: YrCJpVvh2JSc0rx-DfC9254Cj678jDIDjMhIYq791uQ argparse==1.4.0 +# This comes before cffi because cffi will otherwise install an unchecked +# version via setup_requires. +# sha256: eVm0p0q9wnsxL-0cIebK-TCc4LKeqGtZH9Lpns3yf3M +pycparser==2.14 + # sha256: U8HJ3bMEMVE-t_PN7wo-BrDxJSGIqqd0SvD1pM1F268 # sha256: pWj0nfyhKo2fNwGHJX78WKOBCeHu5xTZKFYdegGKZPg # sha256: gJxsqM-8ruv71DK0V2ABtA04_yRjdzy1dXfXXhoCC8M @@ -30,28 +35,28 @@ ConfigArgParse==0.10.0 # sha256: ovVlB3DhyH-zNa8Zqbfrc_wFzPIhROto230AzSvLCQI configobj==5.0.6 -# sha256: 1U_hszrB4J8cEj4vl0948z6V1h1PSALdISIKXD6MEX0 -# sha256: B1X2aE4RhSAFs2MTdh7ctbqEOmTNAizhrC3L1JqTYG0 -# sha256: zjhNo4lZlluh90VKJfVp737yqxRd8ueiml4pS3TgRnc -# sha256: GvQDkV3LmWHDB2iuZRr6tpKC0dpaut-mN1IhrBGHdQM -# sha256: ag08d91PH-W8ZfJ--3fsjQSjiNpesl66DiBAwJgZ30o -# sha256: KdelgcO6_wTh--IAaltHjZ7cfPmib8ijWUkkf09lA3k -# sha256: IPAWEKpAh_bVadjMIMR4uB8DhIYnWqqx3Dx12VAsZ-A -# sha256: l9hGUIulDVomml82OK4cFmWbNTFaH0B_oVF2cH2j0Jc -# sha256: djfqRMLL1NsvLKccsmtmPRczORqnafi8g2xZVilbd5g -# sha256: gR-eqJVbPquzLgQGU0XDB4Ui5rPuPZLz0n08fNcWpjM -# sha256: DXCMjYz97Qm4fCoLqHY856ZjWG4EPmrEL9eDHpKQHLY -# sha256: Efnq11YqPgATWGytM5o_em9Yg8zhw7S5jhrGnft3p_Y -# sha256: dNhnm55-0ePs-wq1NNyTUruxz3PTYsmQkJTAlyivqJY -# sha256: z1Hd-123eBaiB1OKZgEUuC4w4IAD_uhJmwILi4SA2sU -# sha256: 47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU -# sha256: dITvgYGUFB3_eUdf-74vd6-FHiw7v-Lk1ZEjEi-KTjM -# sha256: 7gLB6J7l7pUBV6VK1YTXN8Ec83putMCFPozz8n6WLcA -# sha256: pfGPaxhQpVVKV9v2YsrSUSpGBW5paHJqmFjngN1bnQo -# sha256: 26GA8xrb5xi6qdbPirY0hJSwlLK4GAL_8zvVDSfRPnM -# sha256: 5RinlLjzjoOC9_B3kUGBPOtIE6z9MRVBwNsOGJ69eN4 -# sha256: f1FFn4TWcERCdeYVg59FQsk1R6Euk4oKSQba_l994VM -cryptography==1.1.2 +# sha256: Axk49zpcXrPoCeGP98rraGU1GHFBe-YFDLjIapogK5o +# sha256: oXmjjVD41otJHXoxPbePjKvikIQs7N3dx7NNQI5Z2wo +# sha256: kGyIsqrc-Zz6uyQJgmPRv2WrDIaIrN4Q2uHwnYZZIPE +# sha256: bnBsXGCIdwsdG2NOlZ4hlj4xWwJV9fR3cSWtPVQIKXc +# sha256: 9ev44xxI-HB5Idyg6ZTed4E6nJub8DwRnF3fl73P_nM +# sha256: x7ieQiiMx_vuOBLpnvXHRPIkUuEdaCL2gHr8bWs76D4 +# sha256: hAjSmGWUcQnYto8YN6fN4apNyG4Peco7pYwMRORD1qU +# sha256: x-ds88PZJd0x-iOM-4Bs_7pxjA8IcH13pTh2hHeWmVY +# sha256: fY3jU4DzFwJ1i3dTu1xAcjgyxzAG3tsvkJm_YaN_coc +# sha256: XtvucfrlRp7oP-CjeGa5OYyM46RjJcJPzt-_CXu0ihk +# sha256: WU7a_kgBwTvcHMMF53BKkMGWF-lZNvarRX7k_-AAulA +# sha256: t_2xagp_SBvkLadEv-HqIWMCXeIfkPLGiKMW88NU2pw +# sha256: IHuL8P4JBzNt84tzO0h1Ic-eE4GJq6kjStVP5UXdDbg +# sha256: UJovBThicM94OZPJDUn_77PdYq7kW_HqjOPSzecnHCE +# sha256: rGm2XdGvAXnt5AyfFXiMiPc-Yo6mwFGd44OOJ5uziMY +# sha256: jfb61sauEv1wBOopNX8KK003dOrsp2VlMNCNLZDNQao +# sha256: C4uW3YHMFTOgTzA4LA_iHBly4Yn3lNDEJhoYzsCP2bU +# sha256: yuj8oYg_I8UOp42J3m_k_v20zqgxd3YPRxd1WUFN7ZM +# sha256: GkccpXapzc4bHNnzoisdCe5E1GhiA3VX3heRnA20RCU +# sha256: jsTo49RTs6G2O19Xc3pDTc8e5KLyb2_3xaN8P2eRBNI +# sha256: jrEcd92Oc_SN9rL3p-Fhc_4P6P3-JmIygy6IR34IRU4 +cryptography==1.2.3 # sha256: JHXX_N31lR6S_1RpcnWIAt5SYL9Akxmp8ZNOa7yLHcc # sha256: NZB977D5krdat3iPZf7cHPIP-iJojg5vbxKvwGs-pQE @@ -79,9 +84,9 @@ ndg-httpsclient==0.4.0 # sha256: HDW0rCBs7y0kgWyJ-Jzyid09OM98RJuz-re_bUPwGx8 ordereddict==1.1 -# sha256: OnTxAPkNZZGDFf5kkHca0gi8PxOv0y01_P5OjQs7gSs -# sha256: Paa-K-UG9ZzOMuGeMOIBBT4btNB-JWaJGOAPikmtQKs -parsedatetime==1.5 +# sha256: zp1CIWXPbpY5Bc1fdPJ06_fMmMlBkWFpF475Pw5VeDg +# sha256: F8V4d1UgyZExY04Jz8paBeqeG9KgXNBpZ-vs4Q33ry0 +parsedatetime==2.1 # sha256: Rsjbda51oFa9HMB_ohc0_i5gPRGgeDPswe63TDXHLgw # sha256: 4hJ2JqkebIhduJZol22zECDwry2nKJJLVkgPx8zwlkk @@ -123,9 +128,6 @@ psutil==3.3.0 # sha256: hTys2W0fcB3dZ6oD7MBfUYkBNbcmLpInEBEvEqLtKn8 pyasn1==0.1.9 -# sha256: eVm0p0q9wnsxL-0cIebK-TCc4LKeqGtZH9Lpns3yf3M -pycparser==2.14 - # sha256: iORea7Jd_tJyoe8ucoRh1EtjTCzWiemJtuVqNJxaOuU # sha256: 8KJgcNbbCIHei8x4RpNLfDyTDY-cedRYg-5ImEvA1nI pyOpenSSL==0.15.1 diff --git a/letsencrypt-auto-source/pieces/setuptools-requirements.txt b/letsencrypt-auto-source/pieces/setuptools-requirements.txt new file mode 100644 index 000000000..ab9d30da2 --- /dev/null +++ b/letsencrypt-auto-source/pieces/setuptools-requirements.txt @@ -0,0 +1,5 @@ +# cryptography requires a more modern version of setuptools. +# sha256: _ANFf7h6utSdwJ-cMTOGNpPn3bbKgrtQpzmnc3nOWpo +# sha256: JPz8FTZKn-CaIg830tztyEl5Xj3j5LOT7piOZqnL2Fo +# sha256: gJaELiTE8ddN_xKr6Qwm0S8F0NmlbtXgb8qm-qHkC2o +setuptools==20.2.2 diff --git a/letsencrypt-nginx/setup.py b/letsencrypt-nginx/setup.py index 656d6e04f..e53bef059 100644 --- a/letsencrypt-nginx/setup.py +++ b/letsencrypt-nginx/setup.py @@ -12,7 +12,9 @@ install_requires = [ 'letsencrypt=={0}'.format(version), 'PyOpenSSL', 'pyparsing>=1.5.5', # Python3 support; perhaps unnecessary? - 'setuptools', # pkg_resources + # For pkg_resources. >=1.0 so pip resolves it to a version cryptography + # will tolerate; see #2599: + 'setuptools>=1.0', 'zope.interface', ] diff --git a/letsencrypt/cli.py b/letsencrypt/cli.py index 3551d5a10..024f53d0b 100644 --- a/letsencrypt/cli.py +++ b/letsencrypt/cli.py @@ -19,6 +19,7 @@ import traceback import configargparse import OpenSSL +import six import zope.component import zope.interface.exceptions import zope.interface.verify @@ -806,12 +807,18 @@ def _restore_required_config_elements(config, renewalparams): # int-valued items to add if they're present for config_item in INT_CONFIG_ITEMS: if config_item in renewalparams and not _set_by_cli(config_item): - try: - value = int(renewalparams[config_item]) - setattr(config.namespace, config_item, value) - except ValueError: - raise errors.Error( - "Expected a numeric value for {0}".format(config_item)) + config_value = renewalparams[config_item] + # the default value for http01_port was None during private beta + if config_item == "http01_port" and config_value == "None": + logger.info("updating legacy http01_port value") + int_value = flag_default("http01_port") + else: + try: + int_value = int(config_value) + except ValueError: + raise errors.Error( + "Expected a numeric value for {0}".format(config_item)) + setattr(config.namespace, config_item, int_value) def _restore_plugin_configs(config, renewalparams): @@ -842,7 +849,7 @@ def _restore_plugin_configs(config, renewalparams): if renewalparams.get("installer", None) is not None: plugin_prefixes.append(renewalparams["installer"]) for plugin_prefix in set(plugin_prefixes): - for config_item, config_value in renewalparams.iteritems(): + for config_item, config_value in six.iteritems(renewalparams): if config_item.startswith(plugin_prefix + "_") and not _set_by_cli(config_item): # Values None, True, and False need to be treated specially, # As they don't get parsed correctly based on type @@ -1159,10 +1166,10 @@ class HelpfulArgumentParser(object): # List of topics for which additional help can be provided HELP_TOPICS = ["all", "security", - "paths", "automation", "testing"] + VERBS.keys() + "paths", "automation", "testing"] + list(six.iterkeys(VERBS)) def __init__(self, args, plugins, detect_defaults=False): - plugin_names = [name for name, _p in plugins.iteritems()] + plugin_names = list(six.iterkeys(plugins)) self.help_topics = self.HELP_TOPICS + plugin_names + [None] usage, short_usage = usage_strings(plugins) self.parser = configargparse.ArgParser( @@ -1432,7 +1439,7 @@ class HelpfulArgumentParser(object): may or may not be displayed as help topics. """ - for name, plugin_ep in plugins.iteritems(): + for name, plugin_ep in six.iteritems(plugins): parser_or_group = self.add_group(name, description=plugin_ep.description) #print(parser_or_group) plugin_ep.plugin_cls.inject_parser_options(parser_or_group, name) @@ -1827,7 +1834,7 @@ def _process_domain(args_or_config, domain_arg, webroot_path=None): class WebrootMapProcessor(argparse.Action): # pylint: disable=missing-docstring def __call__(self, parser, args, webroot_map_arg, option_string=None): webroot_map = json.loads(webroot_map_arg) - for domains, webroot_path in webroot_map.iteritems(): + for domains, webroot_path in six.iteritems(webroot_map): _process_domain(args, domains, [webroot_path]) diff --git a/letsencrypt/plugins/webroot_test.py b/letsencrypt/plugins/webroot_test.py index 7a34b3fcc..8c1427340 100644 --- a/letsencrypt/plugins/webroot_test.py +++ b/letsencrypt/plugins/webroot_test.py @@ -1,4 +1,7 @@ """Tests for letsencrypt.plugins.webroot.""" + +from __future__ import print_function + import errno import os import shutil @@ -74,7 +77,7 @@ class AuthenticatorTest(unittest.TestCase): os.chmod(self.path, 0o000) try: open(permission_canary, "r") - print "Warning, running tests as root skips permissions tests..." + print("Warning, running tests as root skips permissions tests...") except IOError: # ok, permissions work, test away... self.assertRaises(errors.PluginError, self.auth.prepare) diff --git a/letsencrypt/reporter.py b/letsencrypt/reporter.py index 81106be34..147928e3c 100644 --- a/letsencrypt/reporter.py +++ b/letsencrypt/reporter.py @@ -4,10 +4,10 @@ from __future__ import print_function import collections import logging import os -import Queue import sys import textwrap +from six.moves import queue # pylint: disable=import-error import zope.interface from letsencrypt import interfaces @@ -21,7 +21,7 @@ logger = logging.getLogger(__name__) class Reporter(object): """Collects and displays information to the user. - :ivar `Queue.PriorityQueue` messages: Messages to be displayed to + :ivar `queue.PriorityQueue` messages: Messages to be displayed to the user. """ @@ -36,7 +36,7 @@ class Reporter(object): _msg_type = collections.namedtuple('ReporterMsg', 'priority text on_crash') def __init__(self): - self.messages = Queue.PriorityQueue() + self.messages = queue.PriorityQueue() def add_message(self, msg, priority, on_crash=True): """Adds msg to the list of messages to be printed. diff --git a/letsencrypt/storage.py b/letsencrypt/storage.py index 6786ac745..cff2d53e1 100644 --- a/letsencrypt/storage.py +++ b/letsencrypt/storage.py @@ -694,7 +694,7 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes for i in (cli_config.renewal_configs_dir, cli_config.archive_dir, cli_config.live_dir): if not os.path.exists(i): - os.makedirs(i, 0700) + os.makedirs(i, 0o700) logger.debug("Creating directory %s.", i) config_file, config_filename = le_util.unique_lineage_name( cli_config.renewal_configs_dir, lineagename) diff --git a/letsencrypt/tests/cli_test.py b/letsencrypt/tests/cli_test.py index aef3447c3..bfd3818c1 100644 --- a/letsencrypt/tests/cli_test.py +++ b/letsencrypt/tests/cli_test.py @@ -1,15 +1,18 @@ """Tests for letsencrypt.cli.""" + +from __future__ import print_function + import argparse import functools import itertools import os import shutil -import StringIO import traceback import tempfile import unittest import mock +import six from acme import jose @@ -81,7 +84,7 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods def _help_output(self, args): "Run a command, and return the ouput string for scrutiny" - output = StringIO.StringIO() + output = six.StringIO() with mock.patch('letsencrypt.cli.sys.stdout', new=output): self.assertRaises(SystemExit, self._call_stdout, args) out = output.getvalue() @@ -580,7 +583,7 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods try: ret, _, _, _ = self._call(args) if ret: - print "Returned", ret + print("Returned", ret) raise AssertionError(ret) assert not error_expected, "renewal should have errored" except: # pylint: disable=bare-except @@ -628,8 +631,8 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods def _dump_log(self): with open(os.path.join(self.logs_dir, "letsencrypt.log")) as lf: - print "Logs:" - print lf.read() + print("Logs:") + print(lf.read()) def _make_test_renewal_conf(self, testfile): @@ -710,6 +713,12 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods self._test_renew_common(renewalparams=renewalparams, error_expected=True, assert_oc_called=False) + def test_renew_with_nonetype_http01(self): + renewalparams = {'authenticator': 'webroot', + 'http01_port': 'None'} + self._test_renew_common(renewalparams=renewalparams, error_expected=False, + assert_oc_called=True) + def test_renew_with_bad_domain(self): renewalparams = {'authenticator': 'webroot'} names = ['*.example.com'] diff --git a/letsencrypt/tests/colored_logging_test.py b/letsencrypt/tests/colored_logging_test.py index 5b49ec820..4080157fc 100644 --- a/letsencrypt/tests/colored_logging_test.py +++ b/letsencrypt/tests/colored_logging_test.py @@ -1,8 +1,9 @@ """Tests for letsencrypt.colored_logging.""" import logging -import StringIO import unittest +import six + from letsencrypt import le_util @@ -12,7 +13,7 @@ class StreamHandlerTest(unittest.TestCase): def setUp(self): from letsencrypt import colored_logging - self.stream = StringIO.StringIO() + self.stream = six.StringIO() self.stream.isatty = lambda: True self.handler = colored_logging.StreamHandler(self.stream) diff --git a/letsencrypt/tests/le_util_test.py b/letsencrypt/tests/le_util_test.py index 87894f837..191b70801 100644 --- a/letsencrypt/tests/le_util_test.py +++ b/letsencrypt/tests/le_util_test.py @@ -4,11 +4,11 @@ import errno import os import shutil import stat -import StringIO import tempfile import unittest import mock +import six from letsencrypt import errors @@ -307,14 +307,14 @@ class AddDeprecatedArgumentTest(unittest.TestCase): self.assertTrue("--old-option is deprecated" in stderr) def _get_argparse_warnings(self, args): - stderr = StringIO.StringIO() + stderr = six.StringIO() with mock.patch("letsencrypt.le_util.sys.stderr", new=stderr): self.parser.parse_args(args) return stderr.getvalue() def test_help(self): self._call("--old-option", 2) - stdout = StringIO.StringIO() + stdout = six.StringIO() with mock.patch("letsencrypt.le_util.sys.stdout", new=stdout): try: self.parser.parse_args(["-h"]) diff --git a/letsencrypt/tests/reporter_test.py b/letsencrypt/tests/reporter_test.py index c848b1cab..26a1105c8 100644 --- a/letsencrypt/tests/reporter_test.py +++ b/letsencrypt/tests/reporter_test.py @@ -1,8 +1,9 @@ """Tests for letsencrypt.reporter.""" -import StringIO import sys import unittest +import six + class ReporterTest(unittest.TestCase): """Tests for letsencrypt.reporter.Reporter.""" @@ -12,7 +13,7 @@ class ReporterTest(unittest.TestCase): self.reporter = reporter.Reporter() self.old_stdout = sys.stdout - sys.stdout = StringIO.StringIO() + sys.stdout = six.StringIO() def tearDown(self): sys.stdout = self.old_stdout diff --git a/letsencrypt/tests/testdata/sample-renewal-ancient.conf b/letsencrypt/tests/testdata/sample-renewal-ancient.conf old mode 100755 new mode 100644 diff --git a/letsencrypt/tests/testdata/sample-renewal.conf b/letsencrypt/tests/testdata/sample-renewal.conf old mode 100755 new mode 100644 diff --git a/letshelp-letsencrypt/letshelp_letsencrypt/apache.py b/letshelp-letsencrypt/letshelp_letsencrypt/apache.py index ac4e9b831..d7cb05b70 100755 --- a/letshelp-letsencrypt/letshelp_letsencrypt/apache.py +++ b/letshelp-letsencrypt/letshelp_letsencrypt/apache.py @@ -1,5 +1,8 @@ #!/usr/bin/env python """Let's Encrypt Apache configuration submission script""" + +from __future__ import print_function + import argparse import atexit import contextlib @@ -48,20 +51,20 @@ def make_and_verify_selection(server_root, temp_dir): """ copied_files, copied_dirs = copy_config(server_root, temp_dir) - print textwrap.fill("A secure copy of the files that have been selected " + print(textwrap.fill("A secure copy of the files that have been selected " "for submission has been created under {0}. All " "comments have been removed and the files are only " "accessible by the current user. A list of the files " "that have been included is shown below. Please make " "sure that this selection does not contain private " "keys, passwords, or any other sensitive " - "information.".format(temp_dir)) - print "\nFiles:" + "information.".format(temp_dir))) + print("\nFiles:") for copied_file in copied_files: - print copied_file - print "Directories (including all contained files):" + print(copied_file) + print("Directories (including all contained files):") for copied_dir in copied_dirs: - print copied_dir + print(copied_dir) sys.stdout.write("\nIs it safe to submit these files? ") while True: diff --git a/setup.py b/setup.py index d07582e2b..b187e6fdb 100644 --- a/setup.py +++ b/setup.py @@ -39,13 +39,15 @@ install_requires = [ 'ConfigArgParse>=0.9.3', 'configobj', 'cryptography>=0.7', # load_pem_x509_certificate - 'parsedatetime<2.0', # parsedatetime 2.0 doesn't work on py26 + 'parsedatetime', 'psutil>=2.1.0', # net_connections introduced in 2.1.0 'PyOpenSSL', 'pyrfc3339', 'python2-pythondialog>=3.2.2rc1', # Debian squeeze support, cf. #280 'pytz', - 'setuptools', # pkg_resources + # For pkg_resources. >=1.0 so pip resolves it to a version cryptography + # will tolerate; see #2599: + 'setuptools>=1.0', 'six', 'zope.component', 'zope.interface', diff --git a/tools/eff-pubkey.pem b/tools/eff-pubkey.pem new file mode 100644 index 000000000..fe6c2f5bb --- /dev/null +++ b/tools/eff-pubkey.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq +OzQb2eyW15YFjDDEMI0ZOzt8f504obNs920lDnpPD2/KqgsfjOgw2K7xWDJIj/18 +xUvWPk3LDkrnokNiRkA3KOx3W6fHycKL+zID7zy+xZYBuh2fLyQtWV1VGQ45iNRp +9+Zo7rH86cdfgkdnWTlNSHyTLW9NbXvyv/E12bppPcEvgCTAQXgnDVJ0/sqmeiij +n9tTFh03aM+R2V/21h8aTraAS24qiPCz6gkmYGC8yr6mglcnNoYbsLNYZ69zF1XH +cXPduCPdPdfLlzVlKK1/U7hkA28eG3BIAMh6uJYBRJTpiGgaGdPd7YekUB8S6cy+ +CQIDAQAB +-----END PUBLIC KEY----- diff --git a/tools/release.sh b/tools/release.sh index 78babcff2..00c986534 100755 --- a/tools/release.sh +++ b/tools/release.sh @@ -216,6 +216,8 @@ echo twine upload "$root/dist.$version/*/*" if [ "$RELEASE_BRANCH" = candidate-"$version" ] ; then SetVersion "$nextversion".dev0 + letsencrypt-auto-source/build.py + git add letsencrypt-auto-source/letsencrypt-auto git diff git commit -m "Bump version to $nextversion" fi