mirror of
https://github.com/certbot/certbot.git
synced 2026-06-04 22:33:00 -04:00
Merge branch 'master' into ecdsa
This commit is contained in:
commit
692227d824
27 changed files with 516 additions and 56 deletions
259
AUTHORS.md
Normal file
259
AUTHORS.md
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
Authors
|
||||
=======
|
||||
|
||||
* [Aaron Zirbes](https://github.com/aaronzirbes)
|
||||
* Aaron Zuehlke
|
||||
* Ada Lovelace
|
||||
* [Adam Woodbeck](https://github.com/awoodbeck)
|
||||
* [Aidin Gharibnavaz](https://github.com/aidin36)
|
||||
* [AJ ONeal](https://github.com/coolaj86)
|
||||
* [Alcaro](https://github.com/Alcaro)
|
||||
* [Alexander Mankuta](https://github.com/pointlessone)
|
||||
* [Alex Bowers](https://github.com/alexbowers)
|
||||
* [Alex Conlin](https://github.com/alexconlin)
|
||||
* [Alex Gaynor](https://github.com/alex)
|
||||
* [Alex Halderman](https://github.com/jhalderm)
|
||||
* [Alex Jordan](https://github.com/strugee)
|
||||
* [Amjad Mashaal](https://github.com/TheNavigat)
|
||||
* [Andrew Murray](https://github.com/radarhere)
|
||||
* [Anselm Levskaya](https://github.com/levskaya)
|
||||
* [Antoine Jacoutot](https://github.com/ajacoutot)
|
||||
* [asaph](https://github.com/asaph)
|
||||
* [Axel Beckert](https://github.com/xtaran)
|
||||
* [Bas](https://github.com/Mechazawa)
|
||||
* [benbankes](https://github.com/benbankes)
|
||||
* [Ben Irving](https://github.com/benileo)
|
||||
* [Benjamin Kerensa](https://github.com/bkerensa)
|
||||
* [Benjamin Neff](https://github.com/SuperTux88)
|
||||
* [Benjamin Piouffle](https://github.com/Betree)
|
||||
* [Ben Ubois](https://github.com/benubois)
|
||||
* [Ben Wolfe](https://github.com/bwolfe)
|
||||
* [Bigfish](https://github.com/bwolfe)
|
||||
* [Blake Griffith](https://github.com/cowlicks)
|
||||
* [Brad Warren](https://github.com/bmw)
|
||||
* [Brandon Kraft](https://github.com/kraftbj)
|
||||
* [Brandon Kreisel](https://github.com/kraftbj)
|
||||
* [Ceesjan Luiten](https://github.com/quinox)
|
||||
* [Chad Whitacre](https://github.com/whit537)
|
||||
* [Chhatoi Pritam Baral](https://github.com/pritambaral)
|
||||
* [Chris Johns](https://github.com/ter0)
|
||||
* [Chris Lamb](https://github.com/lamby)
|
||||
* [chrismarget](https://github.com/chrismarget)
|
||||
* [Christian Gärtner](https://github.com/ChristianGaertner)
|
||||
* [Christian Rosentreter](https://github.com/the-real-tokai)
|
||||
* [Christopher Brown](https://github.com/chbrown)
|
||||
* [Christopher Manning](https://github.com/christophermanning)
|
||||
* [Christoph Kisfeld](https://github.com/chk1)
|
||||
* [Clif Houck](https://github.com/ClifHouck)
|
||||
* [Cooper Quintin](https://github.com/cooperq)
|
||||
* [Corey Farwell](https://github.com/frewsxcv)
|
||||
* [Craig Smith](https://github.com/dashaxiong)
|
||||
* [Damian Poddebniak](https://github.com/duesee)
|
||||
* [Damien Nozay](https://github.com/dnozay)
|
||||
* [Damien Tournoud](https://github.com/damz)
|
||||
* [DanCld](https://github.com/DanCld)
|
||||
* [Daniel Albers](https://github.com/AID)
|
||||
* [Daniel Aleksandersen](https://github.com/da2x)
|
||||
* [Daniel Convissor](https://github.com/convissor)
|
||||
* [Daniel Huang](https://github.com/dhuang)
|
||||
* [Dave Guarino](https://github.com/daguar)
|
||||
* [David cz](https://github.com/dave-cz)
|
||||
* [David Dworken](https://github.com/ddworken)
|
||||
* [David Kreitschmann](https://kreitschmann.de)
|
||||
* [David Xia](https://github.com/davidxia)
|
||||
* [Devin Howard](https://github.com/devvmh)
|
||||
* [dokazaki](https://github.com/dokazaki)
|
||||
* [Dominic Cleal](https://github.com/domcleal)
|
||||
* [Dominic Lüchinger](https://github.com/dol)
|
||||
* [Douglas José](https://github.com/douglasjose)
|
||||
* [Erica Portnoy](https://github.com/ohemorange)
|
||||
* [Eric Engestrom](https://github.com/1ace)
|
||||
* [Eric Rescorla](https://github.com/ekr)
|
||||
* [Eric Wustrow](https://github.com/ewust)
|
||||
* [Erik Rose](https://github.com/erikrose)
|
||||
* [Eugene Kazakov](https://github.com/xgin)
|
||||
* [Fabian](https://github.com/faerbit)
|
||||
* [Faidon Liambotis](https://github.com/paravoid)
|
||||
* [Fan Jiang](https://github.com/tcz001)
|
||||
* [Felix Schwarz](https://github.com/FelixSchwarz)
|
||||
* [Felix Yan](https://github.com/felixonmars)
|
||||
* [Filip Ochnik](https://github.com/filipochnik)
|
||||
* [Francois Marier](https://github.com/fmarier)
|
||||
* [Frank](https://github.com/Frankkkkk)
|
||||
* [Frederic BLANC](https://github.com/fblanc)
|
||||
* [Garrett Robinson](https://github.com/garrettr)
|
||||
* [Gene Wood](https://github.com/gene1wood)
|
||||
* [Geoffroy Doucet](https://www.geoffroydoucet.com)
|
||||
* [Gian Carlo Pace](https://github.com/gicappa)
|
||||
* [Gilles Pietri](https://github.com/gilou)
|
||||
* [Giovanni Pellerano](https://github.com/evilaliv3)
|
||||
* [Giovanni Toraldo](https://github.com/gionn)
|
||||
* [Gordin](https://github.com/Gordin)
|
||||
* [Gregor Dschung](https://github.com/chkpnt)
|
||||
* [Gregory L. Dietsche](https://github.com/farmergreg)
|
||||
* [Greg Osuri](https://github.com/gosuri)
|
||||
* [Guillaume Boudreau](https://github.com/gboudreau)
|
||||
* [Harlan Lieberman-Berg](https://github.com/hlieberman)
|
||||
* [Henri Salo](https://github.com/fgeek)
|
||||
* [Henry Chen](https://github.com/henrychen95)
|
||||
* [Ingolf Becker](https://github.com/watercrossing)
|
||||
* [Jaap Eldering](https://github.com/eldering)
|
||||
* [Jacob Hoffman-Andrews](https://github.com/jsha)
|
||||
* [Jacob Sachs](https://github.com/jsachs)
|
||||
* [Jairo Llopis](https://github.com/Yajo)
|
||||
* [Jakub Warmuz](https://github.com/kuba)
|
||||
* [James Kasten](https://github.com/jdkasten)
|
||||
* [Jason Grinblat](https://github.com/ptychomancer)
|
||||
* [Jay Faulkner](https://github.com/jayofdoom)
|
||||
* [J.C. Jones](https://github.com/jcjones)
|
||||
* [Jeff Hodges](https://github.com/jmhodges)
|
||||
* [Jeremy Gillula](https://github.com/jgillula)
|
||||
* [Jeroen Ketelaar](https://github.com/JKetelaar)
|
||||
* [Jeroen Pluimers](https://github.com/jpluimers)
|
||||
* [j](https://github.com/bit)
|
||||
* [Jim Tittsler](https://github.com/jimt)
|
||||
* [Joe Ranweiler](https://github.com/ranweiler)
|
||||
* [Joerg Sonnenberger](https://github.com/jsonn)
|
||||
* [John Leach](https://github.com/johnl)
|
||||
* [John Reed](https://github.com/leerspace)
|
||||
* [Jonas Berlin](https://github.com/xkr47)
|
||||
* [Jonathan Herlin](https://github.com/Jonher937)
|
||||
* [Jon Walsh](https://github.com/code-tree)
|
||||
* [Joona Hoikkala](https://github.com/joohoi)
|
||||
* [Josh Soref](https://github.com/jsoref)
|
||||
* [Joubin Jabbari](https://github.com/joubin)
|
||||
* [Juho Juopperi](https://github.com/jkjuopperi)
|
||||
* [Kane York](https://github.com/riking)
|
||||
* [Kenneth Skovhede](https://github.com/kenkendk)
|
||||
* [Kevin Burke](https://github.com/kevinburke)
|
||||
* [Kevin London](https://github.com/kevinlondon)
|
||||
* [Kubilay Kocak](https://github.com/koobs)
|
||||
* [LeCoyote](https://github.com/LeCoyote)
|
||||
* [Lee Watson](https://github.com/TheReverend403)
|
||||
* [Leo Famulari](https://github.com/lfam)
|
||||
* [lf](https://github.com/lf-)
|
||||
* [Liam Marshall](https://github.com/liamim)
|
||||
* [Lior Sabag](https://github.com/liorsbg)
|
||||
* [Lipis](https://github.com/lipis)
|
||||
* [lord63](https://github.com/lord63)
|
||||
* [Luca Beltrame](https://github.com/lbeltrame)
|
||||
* [Luca Ebach](https://github.com/lucebac)
|
||||
* [Luca Olivetti](https://github.com/olivluca)
|
||||
* [Luke Rogers](https://github.com/lukeroge)
|
||||
* [Maarten](https://github.com/mrtndwrd)
|
||||
* [Maikel Martens](https://github.com/krukas)
|
||||
* [Malte Janduda](https://github.com/MalteJ)
|
||||
* [Mantas Mikulėnas](https://github.com/grawity)
|
||||
* [Marcel Krüger](https://github.com/zauguin)
|
||||
* [Marcos Caceres](https://github.com/marcoscaceres)
|
||||
* [Marek Viger](https://github.com/freezy-sk)
|
||||
* [Mario Villaplana](https://github.com/supermari0)
|
||||
* [Marius Gedminas](https://github.com/mgedmin)
|
||||
* [Martey Dodoo](https://github.com/martey)
|
||||
* [Martijn Bastiaan](https://github.com/martijnbastiaan)
|
||||
* [Martijn Braam](https://github.com/MartijnBraam)
|
||||
* [Martin Brugger](https://github.com/mbrugger)
|
||||
* [Mathieu Leduc-Hamel](https://github.com/mlhamel)
|
||||
* [Matt Bostock](https://github.com/mattbostock)
|
||||
* [Matthew Ames](https://github.com/SuperMatt)
|
||||
* [Michael Schumacher](https://github.com/schumaml)
|
||||
* [Michael Strache](https://github.com/Jarodiv)
|
||||
* [Michael Sverdlin](https://github.com/sveder)
|
||||
* [Michal Moravec](https://github.com/https://github.com/Majkl578)
|
||||
* [Michal Papis](https://github.com/mpapis)
|
||||
* [Minn Soe](https://github.com/MinnSoe)
|
||||
* [Min RK](https://github.com/minrk)
|
||||
* [Miquel Ruiz](https://github.com/miquelruiz)
|
||||
* [Môshe van der Sterre](https://github.com/moshevds)
|
||||
* [mrstanwell](https://github.com/mrstanwell)
|
||||
* [Nav Aulakh](https://github.com/Nav)
|
||||
* [Nelson Elhage](https://github.com/nelhage)
|
||||
* [Nick Fong](https://github.com/nickfong)
|
||||
* [Nick Le Mouton](https://github.com/NoodlesNZ)
|
||||
* [Nikos Roussos](https://github.com/comzeradd)
|
||||
* [Noah Swartz](https://github.com/swartzcr)
|
||||
* [Ola Bini](https://github.com/olabini)
|
||||
* [Ondřej Súkup](https://github.com/mimi1vx)
|
||||
* [Ondřej Surý](https://github.com/oerdnj)
|
||||
* [osirisinferi](https://github.com/osirisinferi)
|
||||
* Patrick Figel
|
||||
* [Patrick Heppler](https://github.com/PatrickHeppler)
|
||||
* [Paul Feitzinger](https://github.com/pfeyz)
|
||||
* [Pavan Gupta](https://github.com/pavgup)
|
||||
* [Pavel Pavlov](https://github.com/ghost355)
|
||||
* [Peter Conrad](https://github.com/pconrad-fb)
|
||||
* [Peter Eckersley](https://github.com/pde)
|
||||
* [Peter Mosmans](https://github.com/PeterMosmans)
|
||||
* [Philippe Langlois](https://github.com/langloisjp)
|
||||
* [Philipp Spitzer](https://github.com/spitza)
|
||||
* [Piero Steinger](https://github.com/Jadaw1n)
|
||||
* [Pierre Jaury](https://github.com/kaiyou)
|
||||
* [Piotr Kasprzyk](https://github.com/kwadrat)
|
||||
* [Prayag Verma](https://github.com/pra85)
|
||||
* [Reinaldo de Souza Jr](https://github.com/juniorz)
|
||||
* [Remi Rampin](https://github.com/remram44)
|
||||
* [Rémy HUBSCHER](https://github.com/Natim)
|
||||
* [Rémy Léone](https://github.com/sieben)
|
||||
* [Richard Barnes](https://github.com/r-barnes)
|
||||
* [Richard Panek](https://github.com/kernelpanek)
|
||||
* [Robert Buchholz](https://github.com/rbu)
|
||||
* [Robert Habermann](https://github.com/frennkie)
|
||||
* [Robert Xiao](https://github.com/nneonneo)
|
||||
* [Roland Shoemaker](https://github.com/rolandshoemaker)
|
||||
* [Roy Wellington Ⅳ](https://github.com/thanatos)
|
||||
* [rugk](https://github.com/rugk)
|
||||
* [Sachi King](https://github.com/nakato)
|
||||
* [Sagi Kedmi](https://github.com/sagi)
|
||||
* [Sam Lanning](https://github.com/samlanning)
|
||||
* [sapics](https://github.com/sapics)
|
||||
* [Scott Barr](https://github.com/scottjbarr)
|
||||
* [Scott Merrill](https://github.com/skpy)
|
||||
* [Sebastian Bögl](https://github.com/TheBoegl)
|
||||
* [Sebastian Wagner](https://github.com/sebix)
|
||||
* [sedrubal](https://github.com/sedrubal)
|
||||
* [Seppe Stas](https://github.com/seppestas)
|
||||
* [Sergey Nuzdhin](https://github.com/lwolf)
|
||||
* [Seth Schoen](https://github.com/schoen)
|
||||
* [Sharif Nassar](https://github.com/mrwacky42)
|
||||
* [Shaun Cummiskey](https://github.com/ampersign)
|
||||
* [Shiloh Heurich](https://github.com/sheurich)
|
||||
* [silverwind](https://github.com/silverwind)
|
||||
* [Sorvani](https://github.com/sorvani)
|
||||
* [Spencer Bliven](https://github.com/sbliven)
|
||||
* [Stacey Sheldon](https://github.com/solidgoldbomb)
|
||||
* [Stavros Korokithakis](https://github.com/skorokithakis)
|
||||
* [Stefan Weil](https://github.com/stweil)
|
||||
* [Steve Desmond](https://github.com/stevedesmond-ca)
|
||||
* [Tan Jay Jun](https://github.com/jayjun)
|
||||
* [Tapple Gao](https://github.com/tapple)
|
||||
* [Telepenin Nikolay](https://github.com/telepenin)
|
||||
* [Thomas Cottier](https://github.com/tcottier-enalean)
|
||||
* [Thomas Mayer](https://github.com/thomaszbz)
|
||||
* [Thomas Waldmann](https://github.com/ThomasWaldmann)
|
||||
* [Thom Wiggers](https://github.com/thomwiggers)
|
||||
* [Till Maas](https://github.com/tyll)
|
||||
* [Timothy Guan-tin Chien](https://github.com/timdream)
|
||||
* [Torsten Bögershausen](https://github.com/tboegi)
|
||||
* [Travis Raines](https://github.com/rainest)
|
||||
* [Trung Ngo](https://github.com/Ngo-The-Trung)
|
||||
* [Valentin](https://github.com/e00E)
|
||||
* [venyii](https://github.com/venyii)
|
||||
* [Viktor Szakats](https://github.com/vszakats)
|
||||
* [Ville Skyttä](https://github.com/scop)
|
||||
* [Vinney Cavallo](https://github.com/vcavallo)
|
||||
* [Vladimir Rutsky](https://github.com/rutsky)
|
||||
* [Wang Yu](https://github.com/wyhitcs)
|
||||
* [Ward Vandewege](https://github.com/cure)
|
||||
* [Whyfoo](https://github.com/whyfoo)
|
||||
* [Wilfried Teiken](https://github.com/wteiken)
|
||||
* [Willem Fibbe](https://github.com/fibbers)
|
||||
* [William Budington](https://github.com/Hainish)
|
||||
* [Will Newby](https://github.com/willnewby)
|
||||
* [Will Oller](https://github.com/willoller)
|
||||
* [Yan](https://github.com/diracdeltas)
|
||||
* [Yen Chi Hsuan](https://github.com/yan12125)
|
||||
* [Yomna](https://github.com/ynasser)
|
||||
* [Yoni Jah](https://github.com/yonjah)
|
||||
* [YourDaddyIsHere](https://github.com/YourDaddyIsHere)
|
||||
* [Zach Shepherd](https://github.com/zjs)
|
||||
* [陈三](https://github.com/chenxsan)
|
||||
|
|
@ -8,7 +8,6 @@ version = '0.14.0.dev0'
|
|||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'argparse',
|
||||
# load_pem_private/public_key (>=0.6)
|
||||
# rsa_recover_prime_factors (>=0.8)
|
||||
'cryptography>=0.8',
|
||||
|
|
@ -28,6 +27,10 @@ install_requires = [
|
|||
'six',
|
||||
]
|
||||
|
||||
# env markers cause problems with older pip and setuptools
|
||||
if sys.version_info < (2, 7):
|
||||
install_requires.append('argparse')
|
||||
|
||||
dev_extras = [
|
||||
'nose',
|
||||
'tox',
|
||||
|
|
@ -59,6 +62,7 @@ setup(
|
|||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
],
|
||||
|
|
|
|||
2
certbot-apache/setup.cfg
Normal file
2
certbot-apache/setup.cfg
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
|
@ -42,6 +42,11 @@ setup(
|
|||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
|
|
|||
2
certbot-compatibility-test/setup.cfg
Normal file
2
certbot-compatibility-test/setup.cfg
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
|
@ -42,6 +42,11 @@ setup(
|
|||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
],
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class NginxParser(object):
|
|||
srv = servers[filename] # workaround undefined loop var in lambdas
|
||||
|
||||
# Find all the server blocks
|
||||
_do_for_subarray(tree, lambda x: x[0] == ['server'],
|
||||
_do_for_subarray(tree, lambda x: len(x) >= 2 and x[0] == ['server'],
|
||||
lambda x, y: srv.append((x[1], y)))
|
||||
|
||||
# Find 'include' statements in server blocks and append their trees
|
||||
|
|
|
|||
|
|
@ -125,13 +125,13 @@ class NginxParserTest(util.NginxTest):
|
|||
False, True,
|
||||
set(['localhost',
|
||||
r'~^(www\.)?(example|bar)\.']),
|
||||
[], [9, 1, 9])
|
||||
[], [10, 1, 9])
|
||||
vhost2 = obj.VirtualHost(nparser.abs_path('nginx.conf'),
|
||||
[obj.Addr('somename', '8080', False, False),
|
||||
obj.Addr('', '8000', False, False)],
|
||||
False, True,
|
||||
set(['somename', 'another.alias', 'alias']),
|
||||
[], [9, 1, 12])
|
||||
[], [10, 1, 12])
|
||||
vhost3 = obj.VirtualHost(nparser.abs_path('sites-enabled/example.com'),
|
||||
[obj.Addr('69.50.225.155', '9000',
|
||||
False, False),
|
||||
|
|
@ -186,7 +186,7 @@ class NginxParserTest(util.NginxTest):
|
|||
None, None, None,
|
||||
set(['localhost',
|
||||
r'~^(www\.)?(example|bar)\.']),
|
||||
None, [9, 1, 9])
|
||||
None, [10, 1, 9])
|
||||
nparser.add_server_directives(mock_vhost,
|
||||
[['foo', 'bar'], ['\n ', 'ssl_certificate', ' ',
|
||||
'/etc/ssl/cert.pem']],
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ events {
|
|||
worker_connections 1024;
|
||||
}
|
||||
|
||||
empty {
|
||||
}
|
||||
|
||||
include foo.conf;
|
||||
|
||||
http {
|
||||
|
|
|
|||
|
|
@ -100,9 +100,13 @@ class NginxTlsSni01(common.TLSSNI01):
|
|||
if line[0] == ['http']:
|
||||
body = line[1]
|
||||
found_bucket = False
|
||||
posn = 0
|
||||
for inner_line in body:
|
||||
if inner_line[0] == bucket_directive[1]:
|
||||
if int(inner_line[1]) < int(bucket_directive[3]):
|
||||
body[posn] = bucket_directive
|
||||
found_bucket = True
|
||||
posn += 1
|
||||
if not found_bucket:
|
||||
body.insert(0, bucket_directive)
|
||||
if include_directive not in body:
|
||||
|
|
|
|||
2
certbot-nginx/setup.cfg
Normal file
2
certbot-nginx/setup.cfg
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
|
@ -42,6 +42,11 @@ setup(
|
|||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
|
|
|||
|
|
@ -1115,10 +1115,13 @@ def _create_subparsers(helpful):
|
|||
helpful.add(
|
||||
None, "--user-agent", default=None,
|
||||
help="Set a custom user agent string for the client. User agent strings allow "
|
||||
"the CA to collect high level statistics about success rates by OS and "
|
||||
"plugin. If you wish to hide your server OS version from the Let's "
|
||||
"the CA to collect high level statistics about success rates by OS, "
|
||||
"plugin and use case, and to know when to deprecate support for past Python "
|
||||
"versions and flags. If you wish to hide this information from the Let's "
|
||||
'Encrypt server, set this to "". '
|
||||
'(default: {0})'.format(sample_user_agent()))
|
||||
'(default: {0}). The flags encoded in the user agent are: '
|
||||
'--duplicate, --force-renew, --allow-subset-of-names, -n, and '
|
||||
'whether any hooks are set.'.format(sample_user_agent()))
|
||||
helpful.add("certonly",
|
||||
"--csr", type=read_file,
|
||||
help="Path to a Certificate Signing Request (CSR) in DER or PEM format."
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Certbot client API."""
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
|
|
@ -53,21 +54,49 @@ def determine_user_agent(config):
|
|||
"""
|
||||
|
||||
if config.user_agent is None:
|
||||
ua = "CertbotACMEClient/{0} ({1}) Authenticator/{2} Installer/{3}"
|
||||
ua = ua.format(certbot.__version__, util.get_os_info_ua(),
|
||||
config.authenticator, config.installer)
|
||||
ua = ("CertbotACMEClient/{0} ({1}; {2}) Authenticator/{3} Installer/{4} "
|
||||
"({5}; flags: {6}) Py/{7}")
|
||||
ua = ua.format(certbot.__version__, cli.cli_command, util.get_os_info_ua(),
|
||||
config.authenticator, config.installer, config.verb,
|
||||
ua_flags(config), platform.python_version())
|
||||
else:
|
||||
ua = config.user_agent
|
||||
return ua
|
||||
|
||||
def ua_flags(config):
|
||||
"Turn some very important CLI flags into clues in the user agent."
|
||||
if isinstance(config, DummyConfig):
|
||||
return "FLAGS"
|
||||
flags = []
|
||||
if config.duplicate:
|
||||
flags.append("dup")
|
||||
if config.renew_by_default:
|
||||
flags.append("frn")
|
||||
if config.allow_subset_of_names:
|
||||
flags.append("asn")
|
||||
if config.noninteractive_mode:
|
||||
flags.append("n")
|
||||
hook_names = ("pre", "post", "renew", "manual_auth", "manual_cleanup")
|
||||
hooks = [getattr(config, h + "_hook") for h in hook_names]
|
||||
if any(hooks):
|
||||
flags.append("hook")
|
||||
return " ".join(flags)
|
||||
|
||||
class DummyConfig(object):
|
||||
"Shim for computing a sample user agent."
|
||||
def __init__(self):
|
||||
self.authenticator = "XXX"
|
||||
self.installer = "YYY"
|
||||
self.user_agent = None
|
||||
self.verb = "SUBCOMMAND"
|
||||
|
||||
def __getattr__(self, name):
|
||||
"Any config properties we might have are None."
|
||||
return None
|
||||
|
||||
def sample_user_agent():
|
||||
"Document what this Certbot's user agent string will be like."
|
||||
class DummyConfig(object):
|
||||
"Shim for computing a sample user agent."
|
||||
def __init__(self):
|
||||
self.authenticator = "XXX"
|
||||
self.installer = "YYY"
|
||||
self.user_agent = None
|
||||
|
||||
return determine_user_agent(DummyConfig())
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,13 +50,13 @@ def save_key(key_pem, key_dir, keyname="key-certbot.pem"):
|
|||
config.strict_permissions)
|
||||
if config.dry_run:
|
||||
key_path = None
|
||||
logger.info("Dry run, not saving private key to file")
|
||||
logger.debug("Dry run, not saving private key to file")
|
||||
else:
|
||||
key_f, key_path = util.unique_file(
|
||||
os.path.join(key_dir, keyname), 0o600, "wb")
|
||||
with key_f:
|
||||
key_f.write(key_pem)
|
||||
logger.info("Saving private key: %s", key_path)
|
||||
logger.debug("Saving private key: %s", key_path)
|
||||
|
||||
return util.Key(key_path, key_pem)
|
||||
|
||||
|
|
@ -85,13 +85,13 @@ def init_save_csr(privkey, names, path):
|
|||
config.strict_permissions)
|
||||
if config.dry_run:
|
||||
csr_filename = None
|
||||
logger.info("Creating CSR: not saving to file")
|
||||
logger.debug("Creating CSR: not saving to file")
|
||||
else:
|
||||
csr_f, csr_filename = util.unique_file(
|
||||
os.path.join(path, "csr-certbot.pem"), 0o644, "wb")
|
||||
with csr_f:
|
||||
csr_f.write(csr_pem)
|
||||
logger.info("Creating CSR: %s", csr_filename)
|
||||
logger.debug("Creating CSR: %s", csr_filename)
|
||||
|
||||
return util.CSR(csr_filename, csr_pem, "pem")
|
||||
|
||||
|
|
|
|||
|
|
@ -289,3 +289,60 @@ def _gen_https_names(domains):
|
|||
domains[-1])
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
def _get_validated(method, validator, message, default=None, **kwargs):
|
||||
if default is not None:
|
||||
try:
|
||||
validator(default)
|
||||
except errors.Error as error:
|
||||
logger.debug('Encountered invalid default value "%s" when prompting for "%s"',
|
||||
default,
|
||||
message,
|
||||
exc_info=True)
|
||||
raise AssertionError('Invalid default "{0}"'.format(default))
|
||||
|
||||
while True:
|
||||
code, raw = method(message, default=default, **kwargs)
|
||||
if code == display_util.OK:
|
||||
try:
|
||||
validator(raw)
|
||||
return code, raw
|
||||
except errors.Error as error:
|
||||
logger.debug('Validator rejected "%s" when prompting for "%s"',
|
||||
raw,
|
||||
message,
|
||||
exc_info=True)
|
||||
zope.component.getUtility(interfaces.IDisplay).notification(str(error), pause=False)
|
||||
else:
|
||||
return code, raw
|
||||
|
||||
|
||||
def validated_input(validator, *args, **kwargs):
|
||||
"""Like `~certbot.interfaces.IDisplay.input`, but with validation.
|
||||
|
||||
:param callable validator: A method which will be called on the
|
||||
supplied input. If the method raises a `errors.Error`, its
|
||||
text will be displayed and the user will be re-prompted.
|
||||
:param list *args: Arguments to be passed to `~certbot.interfaces.IDisplay.input`
|
||||
:param dict **kwargs: Arguments to be passed to `~certbot.interfaces.IDisplay.input`
|
||||
:return: as `~certbot.interfaces.IDisplay.input`
|
||||
:rtype: tuple
|
||||
"""
|
||||
return _get_validated(zope.component.getUtility(interfaces.IDisplay).input,
|
||||
validator, *args, **kwargs)
|
||||
|
||||
|
||||
def validated_directory(validator, *args, **kwargs):
|
||||
"""Like `~certbot.interfaces.IDisplay.directory_select`, but with validation.
|
||||
|
||||
:param callable validator: A method which will be called on the
|
||||
supplied input. If the method raises a `errors.Error`, its
|
||||
text will be displayed and the user will be re-prompted.
|
||||
:param list *args: Arguments to be passed to `~certbot.interfaces.IDisplay.directory_select`
|
||||
:param dict **kwargs: Arguments to be passed to `~certbot.interfaces.IDisplay.directory_select`
|
||||
:return: as `~certbot.interfaces.IDisplay.directory_select`
|
||||
:rtype: tuple
|
||||
"""
|
||||
return _get_validated(zope.component.getUtility(interfaces.IDisplay).directory_select,
|
||||
validator, *args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -123,7 +123,6 @@ class FileDisplay(object):
|
|||
|
||||
def input(self, message, default=None,
|
||||
cli_flag=None, force_interactive=False, **unused_kwargs):
|
||||
# pylint: disable=no-self-use
|
||||
"""Accept input from the user.
|
||||
|
||||
:param str message: message to display to the user
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from certbot import cli
|
|||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.display import util as display_util
|
||||
from certbot.display import ops
|
||||
from certbot.plugins import common
|
||||
|
||||
|
||||
|
|
@ -136,22 +137,17 @@ to serve all files under specified web root ({0})."""
|
|||
return None if index == 0 else known_webroots[index - 1]
|
||||
|
||||
def _prompt_for_new_webroot(self, domain):
|
||||
display = zope.component.getUtility(interfaces.IDisplay)
|
||||
|
||||
while True:
|
||||
code, webroot = display.directory_select(
|
||||
"Input the webroot for {0}:".format(domain),
|
||||
force_interactive=True)
|
||||
if code == display_util.HELP:
|
||||
# Displaying help is not currently implemented
|
||||
return None
|
||||
elif code == display_util.CANCEL:
|
||||
return None
|
||||
else: # code == display_util.OK
|
||||
try:
|
||||
return _validate_webroot(webroot)
|
||||
except errors.PluginError as error:
|
||||
display.notification(str(error), pause=False)
|
||||
code, webroot = ops.validated_directory(
|
||||
_validate_webroot,
|
||||
"Input the webroot for {0}:".format(domain),
|
||||
force_interactive=True)
|
||||
if code == display_util.HELP:
|
||||
# Displaying help is not currently implemented
|
||||
return None
|
||||
elif code == display_util.CANCEL or code == display_util.ESC:
|
||||
return None
|
||||
else: # code == display_util.OK
|
||||
return _validate_webroot(webroot)
|
||||
|
||||
def _create_challenge_dirs(self):
|
||||
path_map = self.conf("map")
|
||||
|
|
|
|||
|
|
@ -100,22 +100,16 @@ class AuthenticatorTest(unittest.TestCase):
|
|||
self.config.webroot_path = []
|
||||
self.config.webroot_map = {}
|
||||
|
||||
imaginary_dir = os.path.join(os.sep, "imaginary", "dir")
|
||||
|
||||
mock_display = mock_get_utility()
|
||||
mock_display.menu.return_value = (display_util.OK, 0,)
|
||||
mock_display.directory_select.side_effect = (
|
||||
(display_util.HELP, -1,), (display_util.CANCEL, -1,),
|
||||
(display_util.OK, imaginary_dir,), (display_util.OK, self.path,),)
|
||||
self.auth.perform([self.achall])
|
||||
with mock.patch('certbot.display.ops.validated_directory') as m:
|
||||
m.side_effect = ((display_util.HELP, -1),
|
||||
(display_util.CANCEL, -1),
|
||||
(display_util.OK, self.path,))
|
||||
|
||||
self.assertTrue(mock_display.notification.called)
|
||||
for call in mock_display.notification.call_args_list:
|
||||
self.assertTrue(imaginary_dir in call[0][0])
|
||||
self.auth.perform([self.achall])
|
||||
|
||||
self.assertTrue(mock_display.directory_select.called)
|
||||
for call in mock_display.directory_select.call_args_list:
|
||||
self.assertTrue(self.achall.domain in call[0][0])
|
||||
self.assertEqual(self.config.webroot_map[self.achall.domain], self.path)
|
||||
|
||||
def test_perform_missing_root(self):
|
||||
self.config.webroot_path = None
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from certbot import account
|
|||
from certbot import errors
|
||||
|
||||
from certbot.display import util as display_util
|
||||
from certbot.display import ops
|
||||
|
||||
import certbot.tests.util as test_util
|
||||
|
||||
|
|
@ -112,7 +113,6 @@ class ChooseAccountTest(test_util.TempDirTestCase):
|
|||
|
||||
@classmethod
|
||||
def _call(cls, accounts):
|
||||
from certbot.display import ops
|
||||
return ops.choose_account(accounts)
|
||||
|
||||
@test_util.patch_get_utility("certbot.display.ops.z_util")
|
||||
|
|
@ -405,5 +405,77 @@ class SuccessRevocationTest(unittest.TestCase):
|
|||
os.linesep), pause=False)
|
||||
self.assertTrue(path in mock_util().notification.call_args[0][0])
|
||||
|
||||
|
||||
class ValidatorTests(unittest.TestCase):
|
||||
"""Tests for `validated_input` and `validated_directory`."""
|
||||
|
||||
__ERROR = "Must be non-empty"
|
||||
|
||||
valid_input = "asdf"
|
||||
valid_directory = "/var/www/html"
|
||||
|
||||
@staticmethod
|
||||
def __validator(m):
|
||||
if m == "":
|
||||
raise errors.PluginError(ValidatorTests.__ERROR)
|
||||
|
||||
@test_util.patch_get_utility()
|
||||
def test_input_blank_with_validator(self, mock_util):
|
||||
mock_util().input.side_effect = [(display_util.OK, ""),
|
||||
(display_util.OK, ""),
|
||||
(display_util.OK, ""),
|
||||
(display_util.OK, self.valid_input)]
|
||||
|
||||
returned = ops.validated_input(self.__validator, "message", force_interactive=True)
|
||||
self.assertEqual(ValidatorTests.__ERROR, mock_util().notification.call_args[0][0])
|
||||
self.assertEqual(returned, (display_util.OK, self.valid_input))
|
||||
|
||||
@test_util.patch_get_utility()
|
||||
def test_input_validation_with_default(self, mock_util):
|
||||
mock_util().input.side_effect = [(display_util.OK, self.valid_input)]
|
||||
|
||||
returned = ops.validated_input(self.__validator, "msg", default="other")
|
||||
self.assertEqual(returned, (display_util.OK, self.valid_input))
|
||||
|
||||
@test_util.patch_get_utility()
|
||||
def test_input_validation_with_bad_default(self, mock_util):
|
||||
mock_util().input.side_effect = [(display_util.OK, self.valid_input)]
|
||||
|
||||
self.assertRaises(AssertionError,
|
||||
ops.validated_input,
|
||||
self.__validator, "msg", default="")
|
||||
|
||||
@test_util.patch_get_utility()
|
||||
def test_input_cancel_with_validator(self, mock_util):
|
||||
mock_util().input.side_effect = [(display_util.CANCEL, "")]
|
||||
|
||||
code, unused_raw = ops.validated_input(self.__validator, "message", force_interactive=True)
|
||||
self.assertEqual(code, display_util.CANCEL)
|
||||
|
||||
@test_util.patch_get_utility()
|
||||
def test_directory_select_validation(self, mock_util):
|
||||
mock_util().directory_select.side_effect = [(display_util.OK, ""),
|
||||
(display_util.OK, self.valid_directory)]
|
||||
|
||||
returned = ops.validated_directory(self.__validator, "msg", force_interactive=True)
|
||||
self.assertEqual(ValidatorTests.__ERROR, mock_util().notification.call_args[0][0])
|
||||
self.assertEqual(returned, (display_util.OK, self.valid_directory))
|
||||
|
||||
@test_util.patch_get_utility()
|
||||
def test_directory_select_validation_with_default(self, mock_util):
|
||||
mock_util().directory_select.side_effect = [(display_util.OK, self.valid_directory)]
|
||||
|
||||
returned = ops.validated_directory(self.__validator, "msg", default="other")
|
||||
self.assertEqual(returned, (display_util.OK, self.valid_directory))
|
||||
|
||||
@test_util.patch_get_utility()
|
||||
def test_directory_select_validation_with_bad_default(self, mock_util):
|
||||
mock_util().directory_select.side_effect = [(display_util.OK, self.valid_directory)]
|
||||
|
||||
self.assertRaises(AssertionError,
|
||||
ops.validated_directory,
|
||||
self.__validator, "msg", default="")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ your system.
|
|||
System Requirements
|
||||
===================
|
||||
|
||||
Certbot currently requires Python 2.6 or 2.7. By default, it requires root
|
||||
access in order to write to ``/etc/letsencrypt``,
|
||||
Certbot currently requires Python 2.6, 2.7, or 3.3+. By default, it requires
|
||||
root access in order to write to ``/etc/letsencrypt``,
|
||||
``/var/log/letsencrypt``, ``/var/lib/letsencrypt``; to bind to ports 80 and 443
|
||||
(if you use the ``standalone`` plugin) and to read and modify webserver
|
||||
configurations (if you use the ``apache`` or ``nginx`` plugins). If none of
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ In Fedora 23+.
|
|||
FreeBSD
|
||||
-------
|
||||
|
||||
- https://svnweb.freebsd.org/ports/head/security/py-certbot/
|
||||
- https://www.freshports.org/security/py-acme/
|
||||
- https://www.freshports.org/security/py-certbot/
|
||||
|
||||
Gentoo
|
||||
------
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ The ``http`` challenge will ask you to place a file with a specific name and
|
|||
specific content in the ``/.well-known/acme-challenge/`` directory directly
|
||||
in the top-level directory (“web root”) containing the files served by your
|
||||
webserver. In essence it's the same as the webroot_ plugin, but not automated.
|
||||
When using the ``dns`` plugin, ``certbot`` will ask you to place a TXT DNS
|
||||
When using the ``dns`` challenge, ``certbot`` will ask you to place a TXT DNS
|
||||
record with specific contents under the domain name consisting of the hostname
|
||||
for which you want a certificate issued, prepended by ``_acme-challenge``.
|
||||
|
||||
|
|
|
|||
2
letshelp-certbot/setup.cfg
Normal file
2
letshelp-certbot/setup.cfg
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
|
@ -33,6 +33,11 @@ setup(
|
|||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
||||
[easy_install]
|
||||
zip_ok = false
|
||||
|
||||
|
|
|
|||
10
setup.py
10
setup.py
|
|
@ -36,7 +36,6 @@ version = meta['version']
|
|||
# https://github.com/pypa/pip/issues/988 for more info.
|
||||
install_requires = [
|
||||
'acme=={0}'.format(version),
|
||||
'argparse',
|
||||
# We technically need ConfigArgParse 0.10.0 for Python 2.6 support, but
|
||||
# saying so here causes a runtime error against our temporary fork of 0.9.3
|
||||
# in which we added 2.6 support (see #2243), so we relax the requirement.
|
||||
|
|
@ -56,6 +55,10 @@ install_requires = [
|
|||
'zope.interface',
|
||||
]
|
||||
|
||||
# env markers cause problems with older pip and setuptools
|
||||
if sys.version_info < (2, 7):
|
||||
install_requires.append('argparse')
|
||||
|
||||
dev_extras = [
|
||||
# Pin astroid==1.3.5, pylint==1.4.2 as a workaround for #289
|
||||
'astroid==1.3.5',
|
||||
|
|
@ -94,6 +97,11 @@ setup(
|
|||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
|
|
|||
Loading…
Reference in a new issue