1
0
mirror of https://github.com/certbot/certbot.git synced 2026-01-26 07:41:33 +03:00

Merge pull request #498 from kuba/simplehttp

SimpleHTTPS -> SimpleHTTP[S]
This commit is contained in:
Jacob Hoffman-Andrews
2015-06-12 13:28:47 -07:00
17 changed files with 70 additions and 45 deletions

View File

@@ -42,16 +42,17 @@ class ChallengeResponse(jose.TypedJSONObjectWithFields):
@Challenge.register
class SimpleHTTPS(DVChallenge):
"""ACME "simpleHttps" challenge."""
typ = "simpleHttps"
class SimpleHTTP(DVChallenge):
"""ACME "simpleHttp" challenge."""
typ = "simpleHttp"
token = jose.Field("token")
tls = jose.Field("tls", default=True, omitempty=True)
@ChallengeResponse.register
class SimpleHTTPSResponse(ChallengeResponse):
"""ACME "simpleHttps" challenge response."""
typ = "simpleHttps"
class SimpleHTTPResponse(ChallengeResponse):
"""ACME "simpleHttp" challenge response."""
typ = "simpleHttp"
path = jose.Field("path")
URI_TEMPLATE = "https://{domain}/.well-known/acme-challenge/{path}"
@@ -61,7 +62,7 @@ class SimpleHTTPSResponse(ChallengeResponse):
"""Create an URI to the provisioned resource.
Forms an URI to the HTTPS server provisioned resource (containing
:attr:`~SimpleHTTPS.token`) by populating the :attr:`URI_TEMPLATE`.
:attr:`~SimpleHTTP.token`) by populating the :attr:`URI_TEMPLATE`.
:param str domain: Domain name being verified.

View File

@@ -18,36 +18,45 @@ KEY = jose.HashableRSAKey(Crypto.PublicKey.RSA.importKey(
'acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
class SimpleHTTPSTest(unittest.TestCase):
class SimpleHTTPTest(unittest.TestCase):
def setUp(self):
from acme.challenges import SimpleHTTPS
self.msg = SimpleHTTPS(
from acme.challenges import SimpleHTTP
self.msg = SimpleHTTP(
token='evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA')
self.jmsg = {
'type': 'simpleHttps',
'type': 'simpleHttp',
'token': 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA',
'tls': True,
}
def test_no_tls(self):
from acme.challenges import SimpleHTTP
self.assertEqual(SimpleHTTP(token='tok', tls=False).to_json(), {
'tls': False,
'token': 'tok',
'type': 'simpleHttp',
})
def test_to_partial_json(self):
self.assertEqual(self.jmsg, self.msg.to_partial_json())
def test_from_json(self):
from acme.challenges import SimpleHTTPS
self.assertEqual(self.msg, SimpleHTTPS.from_json(self.jmsg))
from acme.challenges import SimpleHTTP
self.assertEqual(self.msg, SimpleHTTP.from_json(self.jmsg))
def test_from_json_hashable(self):
from acme.challenges import SimpleHTTPS
hash(SimpleHTTPS.from_json(self.jmsg))
from acme.challenges import SimpleHTTP
hash(SimpleHTTP.from_json(self.jmsg))
class SimpleHTTPSResponseTest(unittest.TestCase):
class SimpleHTTPResponseTest(unittest.TestCase):
def setUp(self):
from acme.challenges import SimpleHTTPSResponse
self.msg = SimpleHTTPSResponse(path='6tbIMBC5Anhl5bOlWT5ZFA')
from acme.challenges import SimpleHTTPResponse
self.msg = SimpleHTTPResponse(path='6tbIMBC5Anhl5bOlWT5ZFA')
self.jmsg = {
'type': 'simpleHttps',
'type': 'simpleHttp',
'path': '6tbIMBC5Anhl5bOlWT5ZFA',
}
@@ -59,13 +68,13 @@ class SimpleHTTPSResponseTest(unittest.TestCase):
self.assertEqual(self.jmsg, self.msg.to_partial_json())
def test_from_json(self):
from acme.challenges import SimpleHTTPSResponse
from acme.challenges import SimpleHTTPResponse
self.assertEqual(
self.msg, SimpleHTTPSResponse.from_json(self.jmsg))
self.msg, SimpleHTTPResponse.from_json(self.jmsg))
def test_from_json_hashable(self):
from acme.challenges import SimpleHTTPSResponse
hash(SimpleHTTPSResponse.from_json(self.jmsg))
from acme.challenges import SimpleHTTPResponse
hash(SimpleHTTPResponse.from_json(self.jmsg))
class DVSNITest(unittest.TestCase):

View File

@@ -62,7 +62,7 @@ class Field(object):
definition of being empty, e.g. for some more exotic data types.
"""
return not value
return not isinstance(value, bool) and not value
def omit(self, value):
"""Omit the value in output?"""

View File

@@ -1,4 +1,5 @@
"""Tests for acme.jose.json_util."""
import itertools
import os
import pkg_resources
import unittest
@@ -20,6 +21,13 @@ CSR = M2Crypto.X509.load_request(pkg_resources.resource_filename(
class FieldTest(unittest.TestCase):
"""Tests for acme.jose.json_util.Field."""
def test_no_omit_boolean(self):
from acme.jose.json_util import Field
for default, omitempty, value in itertools.product(
[True, False], [True, False], [True, False]):
self.assertFalse(
Field("foo", default=default, omitempty=omitempty).omit(value))
def test_descriptors(self):
mock_value = mock.MagicMock()

View File

@@ -183,7 +183,7 @@ class AuthorizationTest(unittest.TestCase):
self.challbs = (
ChallengeBody(
uri='http://challb1', status=STATUS_VALID,
chall=challenges.SimpleHTTPS(token='IlirfxKKXAsHtmzK29Pj8A')),
chall=challenges.SimpleHTTP(token='IlirfxKKXAsHtmzK29Pj8A')),
ChallengeBody(uri='http://challb2', status=STATUS_VALID,
chall=challenges.DNS(token='DGyRejmCefe7v4NfDGDKfA')),
ChallengeBody(uri='http://challb3', status=STATUS_VALID,

View File

@@ -63,7 +63,7 @@ class ChallengeTest(unittest.TestCase):
def setUp(self):
challs = (
challenges.SimpleHTTPS(token='IlirfxKKXAsHtmzK29Pj8A'),
challenges.SimpleHTTP(token='IlirfxKKXAsHtmzK29Pj8A'),
challenges.DNS(token='DGyRejmCefe7v4NfDGDKfA'),
challenges.RecoveryToken(),
)
@@ -94,7 +94,7 @@ class ChallengeTest(unittest.TestCase):
def test_resolved_combinations(self):
self.assertEqual(self.msg.resolved_combinations, (
(
challenges.SimpleHTTPS(token='IlirfxKKXAsHtmzK29Pj8A'),
challenges.SimpleHTTP(token='IlirfxKKXAsHtmzK29Pj8A'),
challenges.RecoveryToken()
),
(
@@ -183,7 +183,7 @@ class AuthorizationRequestTest(unittest.TestCase):
def setUp(self):
self.responses = (
challenges.SimpleHTTPSResponse(path='Hf5GrX4Q7EBax9hc2jJnfw'),
challenges.SimpleHTTPResponse(path='Hf5GrX4Q7EBax9hc2jJnfw'),
None, # null
challenges.RecoveryTokenResponse(token='23029d88d9e123e'),
)

View File

@@ -7,7 +7,7 @@
"required": ["type", "token"],
"properties": {
"type": {
"enum" : [ "simpleHttps" ]
"enum" : [ "simpleHttp" ]
},
"token": {
"type": "string"

View File

@@ -7,7 +7,7 @@
"required": ["type", "path"],
"properties": {
"type": {
"enum" : [ "simpleHttps" ]
"enum" : [ "simpleHttp" ]
},
"path": {
"type": "string"

View File

@@ -62,10 +62,10 @@ class DVSNI(AnnotatedChallenge):
return cert_pem, response
class SimpleHTTPS(AnnotatedChallenge):
"""Client annotated "simpleHttps" ACME challenge."""
class SimpleHTTP(AnnotatedChallenge):
"""Client annotated "simpleHttp" ACME challenge."""
__slots__ = ('challb', 'domain', 'key')
acme_type = challenges.SimpleHTTPS
acme_type = challenges.SimpleHTTP
class DNS(AnnotatedChallenge):

View File

@@ -336,9 +336,9 @@ def challb_to_achall(challb, key, domain):
logging.info(" DVSNI challenge for %s.", domain)
return achallenges.DVSNI(
challb=challb, domain=domain, key=key)
elif isinstance(chall, challenges.SimpleHTTPS):
logging.info(" SimpleHTTPS challenge for %s.", domain)
return achallenges.SimpleHTTPS(
elif isinstance(chall, challenges.SimpleHTTP):
logging.info(" SimpleHTTP challenge for %s.", domain)
return achallenges.SimpleHTTP(
challb=challb, domain=domain, key=key)
elif isinstance(chall, challenges.DNS):
logging.info(" DNS challenge for %s.", domain)

View File

@@ -252,6 +252,9 @@ def create_parser(plugins):
add("-t", "--text", dest="text_mode", action="store_true",
help="Use the text output instead of the curses UI.")
add("--no-simple-http-tls", action="store_true",
help=config_help("no_simple_http_tls"))
testing_group = parser.add_argument_group(
"testing", description="The following flags are meant for "
"testing purposes only! Do NOT change them, unless you "

View File

@@ -41,7 +41,7 @@ RENEWER_DEFAULTS = dict(
EXCLUSIVE_CHALLENGES = frozenset([frozenset([
challenges.DVSNI, challenges.SimpleHTTPS])])
challenges.DVSNI, challenges.SimpleHTTP])])
"""Mutually exclusive challenges."""

View File

@@ -188,6 +188,10 @@ class IConfig(zope.interface.Interface):
"Port number to perform DVSNI challenge. "
"Boulder in testing mode defaults to 5001.")
# TODO: not implemented
no_simple_http_tls = zope.interface.Attribute(
"Do not use TLS when solving SimpleHTTP challenges.")
class IInstaller(IPlugin):
"""Generic Let's Encrypt Installer Interface.

View File

@@ -16,7 +16,7 @@ KEY = jose.HashableRSAKey(Crypto.PublicKey.RSA.importKey(
"acme.jose", os.path.join("testdata", "rsa512_key.pem"))))
# Challenges
SIMPLE_HTTPS = challenges.SimpleHTTPS(
SIMPLE_HTTPS = challenges.SimpleHTTP(
token="evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA")
DVSNI = challenges.DVSNI(
r="O*\xb4-\xad\xec\x95>\xed\xa9\r0\x94\xe8\x97\x9c&6\xbf'\xb3"

View File

@@ -17,7 +17,7 @@ from letsencrypt.tests import acme_util
TRANSLATE = {
"dvsni": "DVSNI",
"simpleHttps": "SimpleHTTPS",
"simpleHttp": "SimpleHTTP",
"dns": "DNS",
"recoveryToken": "RecoveryToken",
"recoveryContact": "RecoveryContact",
@@ -299,7 +299,7 @@ class GenChallengePathTest(unittest.TestCase):
return gen_challenge_path(challbs, preferences, combinations)
def test_common_case(self):
"""Given DVSNI and SimpleHTTPS with appropriate combos."""
"""Given DVSNI and SimpleHTTP with appropriate combos."""
challbs = (acme_util.DVSNI_P, acme_util.SIMPLE_HTTPS_P)
prefs = [challenges.DVSNI]
combos = ((0,), (1,))
@@ -334,7 +334,7 @@ class GenChallengePathTest(unittest.TestCase):
# Attempted to make the order realistic
prefs = [challenges.RecoveryToken,
challenges.ProofOfPossession,
challenges.SimpleHTTPS,
challenges.SimpleHTTP,
challenges.DVSNI,
challenges.RecoveryContact]
combos = acme_util.gen_combos(challbs)
@@ -403,8 +403,8 @@ class IsPreferredTest(unittest.TestCase):
def _call(cls, chall, satisfied):
from letsencrypt.auth_handler import is_preferred
return is_preferred(chall, satisfied, exclusive_groups=frozenset([
frozenset([challenges.DVSNI, challenges.SimpleHTTPS]),
frozenset([challenges.DNS, challenges.SimpleHTTPS]),
frozenset([challenges.DVSNI, challenges.SimpleHTTP]),
frozenset([challenges.DNS, challenges.SimpleHTTP]),
]))
def test_empty_satisfied(self):

View File

@@ -18,7 +18,7 @@ class ApacheDvsni(object):
larger array. ApacheDvsni is capable of solving many challenges
at once which causes an indexing issue within ApacheConfigurator
who must return all responses in order. Imagine ApacheConfigurator
maintaining state about where all of the SimpleHTTPS Challenges,
maintaining state about where all of the SimpleHTTP Challenges,
Dvsni Challenges belong in the response array. This is an optional
utility.

View File

@@ -24,7 +24,7 @@ class NginxDvsni(ApacheDvsni):
larger array. NginxDvsni is capable of solving many challenges
at once which causes an indexing issue within NginxConfigurator
who must return all responses in order. Imagine NginxConfigurator
maintaining state about where all of the SimpleHTTPS Challenges,
maintaining state about where all of the SimpleHTTP Challenges,
Dvsni Challenges belong in the response array. This is an optional
utility.