mirror of
https://github.com/certbot/certbot.git
synced 2026-01-26 07:41:33 +03:00
error_uri to allow displaying useful error messages from server
This commit is contained in:
@@ -6,6 +6,9 @@ chocolate_server_name = "ca.theobroma.info"
|
||||
# called followed by a slash and then the 64 hex digit session ID)
|
||||
payment_uri = "https://ca.theobroma.info/payment.py"
|
||||
|
||||
# Where are on-line error messages about failures located?
|
||||
error_uri = "https://ca.theobroma.info/failures/"
|
||||
|
||||
# The shortest length in bits of an acceptable RSA modulus.
|
||||
min_keysize = 2048
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from google.protobuf.message import DecodeError
|
||||
from CONFIG import chocolate_server_name, min_keysize, difficulty, polldelay
|
||||
from CONFIG import max_names, max_csr_size, maximum_session_age
|
||||
from CONFIG import maximum_challenge_age, hashcash_expiry, extra_name_blacklist
|
||||
from CONFIG import cert_chain_file, debug, payment_uri
|
||||
from CONFIG import cert_chain_file, debug, payment_uri, error_uri
|
||||
|
||||
poll_interval = 10
|
||||
|
||||
@@ -153,7 +153,7 @@ class session(object):
|
||||
# Whoops!
|
||||
pass
|
||||
else:
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/internalerror")
|
||||
self.die(r, r.BadRequest, uri="%sinternalerror" % error_uri)
|
||||
return
|
||||
|
||||
def check_hashcash(self, h, n):
|
||||
@@ -177,14 +177,14 @@ class session(object):
|
||||
# Check for some ways in which the message from the client
|
||||
# can be inappropriate.
|
||||
if m.challenge or m.proceed.IsInitialized() or m.success.IsInitialized():
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/invalidfromclient")
|
||||
self.die(r, r.BadRequest, uri="%sinvalidfromclient" % error_uri)
|
||||
return
|
||||
distinct_messages = 0
|
||||
if m.request.IsInitialized(): distinct_messages += 1
|
||||
if m.failure.IsInitialized(): distinct_messages += 1
|
||||
if m.completedchallenge: distinct_messages += 1
|
||||
if distinct_messages > 1:
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/mixedmessages")
|
||||
self.die(r, r.BadRequest, uri="%smixedmessages" % error_uri)
|
||||
return
|
||||
# The rule that a new session must contain a request is enforced
|
||||
# by handlenewsession. The rule that an existing session must
|
||||
@@ -203,7 +203,7 @@ class session(object):
|
||||
r.session = ""
|
||||
if not safe("session", m.session):
|
||||
# Note that self.id is still uninitialized here.
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/illegalsession")
|
||||
self.die(r, r.BadRequest, uri="%sillegalsession" % error_uri)
|
||||
return
|
||||
self.id = m.session
|
||||
r.session = m.session
|
||||
@@ -227,7 +227,7 @@ class session(object):
|
||||
if r.failure.IsInitialized(): return
|
||||
if not m.request.IsInitialized():
|
||||
# It is mandatory to make a signing request at the outset of a session.
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/missingrequest")
|
||||
self.die(r, r.BadRequest, uri="%smissingrequest" % error_uri)
|
||||
return
|
||||
timestamp = m.request.timestamp
|
||||
recipient = m.request.recipient
|
||||
@@ -239,18 +239,18 @@ class session(object):
|
||||
# helpful error message (because the hashcash will be wrong automatically
|
||||
# if it's addressed to a different server!).
|
||||
if recipient != chocolate_server_name:
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/recipient")
|
||||
self.die(r, r.BadRequest, uri="%srecipient" % error_uri)
|
||||
return
|
||||
# Check hashcash before doing any crypto or database access.
|
||||
names = CSR.subject_names(csr)
|
||||
if not m.request.clientpuzzle or not self.check_hashcash(m.request.clientpuzzle, len(names)):
|
||||
self.die(r, r.NeedClientPuzzle, uri="https://ca.example.com/failures/hashcash")
|
||||
self.die(r, r.NeedClientPuzzle, uri="%shashcash" % error_uri)
|
||||
return
|
||||
if self.request_made():
|
||||
# Can't make new signing requests if there have already been requests in
|
||||
# this session. (All signing requests should occur together at the
|
||||
# beginning.)
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/priorrequest")
|
||||
self.die(r, r.BadRequest, uri="%spriorrequest" % error_uri)
|
||||
return
|
||||
# Process the request.
|
||||
# TODO: check that each element of the CA/B Forum Baseline
|
||||
@@ -258,16 +258,16 @@ class session(object):
|
||||
# TODO: check that the request involves a public key algorithm
|
||||
# that we support.
|
||||
if not all([safe("recipient", recipient), safe("csr", csr)]):
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/illegalcharacter")
|
||||
self.die(r, r.BadRequest, uri="%sillegalcharacter" % error_uri)
|
||||
return
|
||||
if timestamp - time.time() > 5:
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/future")
|
||||
self.die(r, r.BadRequest, uri="%sfuture" % error_uri)
|
||||
return
|
||||
if time.time() - timestamp > 100:
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/past")
|
||||
self.die(r, r.BadRequest, uri="%spast" % error_uri)
|
||||
return
|
||||
if len(csr) > max_csr_size:
|
||||
self.die(r, r.BadCSR, uri="https://ca.example.com/failures/longcsr")
|
||||
self.die(r, r.BadCSR, uri="%slongcsr" % error_uri)
|
||||
return
|
||||
if not CSR.parse(csr):
|
||||
self.die(r, r.BadCSR)
|
||||
@@ -283,23 +283,23 @@ class session(object):
|
||||
self.die(r, r.BadCSR)
|
||||
return
|
||||
if len(names) > max_names:
|
||||
self.die(r, r.BadCSR, uri="https://ca.example.com/failures/toomanynames")
|
||||
self.die(r, r.BadCSR, uri="%stoomanynames" % error_uri)
|
||||
return
|
||||
for san in names: # includes CN as well as SANs
|
||||
if not safe("hostname", san) or not CSR.can_sign(san) or san in extra_name_blacklist:
|
||||
# TODO: Is there a problem including client-supplied data in the URL?
|
||||
self.die(r, r.CannotIssueThatName, uri="https://ca.example.com/failures/name?%s" % san)
|
||||
self.die(r, r.CannotIssueThatName, uri="%sname?%s" % (error_uri,san))
|
||||
return
|
||||
try:
|
||||
# Check whether the SSL Observatory has seen a valid cert for this name.
|
||||
# XXX: This has been disabled because this API is unavailable
|
||||
# or unreliable.
|
||||
if False and urllib2.urlopen("https://observatory.eff.org/check_name?domain_name=%s" % san).read().strip() != "False":
|
||||
self.die(r, r.CannotIssueThatName, uri="https://ca.example.com/failures/observatory?%s" % san)
|
||||
self.die(r, r.CannotIssueThatName, uri="%sobservatory?%s" % (error_uri,san))
|
||||
return
|
||||
wildcard_variant = "*." + san.partition(".")[2]
|
||||
if False and urllib2.urlopen("https://observatory.eff.org/check_name?domain_name=%s" % wildcard_variant).read().strip() != "False":
|
||||
self.die(r, r.CannotIssueThatName, uri="https://ca.example.com/failures/observatory?%s" % san)
|
||||
self.die(r, r.CannotIssueThatName, uri="%sobservatory?%s" % (error_uri,san))
|
||||
return
|
||||
except urllib2.HTTPError:
|
||||
# Currently, don't consider it fatal if the Observatory blacklist
|
||||
@@ -317,14 +317,14 @@ class session(object):
|
||||
def handleexistingsession(self, m, r):
|
||||
self.log("received message from %s" % web.ctx.ip)
|
||||
if m.request.IsInitialized():
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/requestinexistingsession")
|
||||
self.die(r, r.BadRequest, uri="%srequestinexistingsession" % error_uri)
|
||||
return
|
||||
# The caller has verified that this session exists and is live.
|
||||
# If we have no state, something is crazy (maybe a race from two
|
||||
# instances of the client?).
|
||||
state = self.state()
|
||||
if state is None:
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/uninitializedsession")
|
||||
self.die(r, r.BadRequest, uri="%suninitializedsession" % error_uri)
|
||||
return
|
||||
# If we're in makechallenge or issue, tell the client to come back later.
|
||||
if state == "makechallenge" or state == "issue":
|
||||
@@ -362,7 +362,7 @@ class session(object):
|
||||
self.send_cert(m, r)
|
||||
return
|
||||
# Unknown session status.
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/internalerror")
|
||||
self.die(r, r.BadRequest, uri="%sinternalerror" % error_uri)
|
||||
return
|
||||
# TODO: Process challenge-related messages from the client.
|
||||
|
||||
@@ -391,7 +391,7 @@ class session(object):
|
||||
# Currently, we can only handle challenge type 0 (dvsni)
|
||||
# TODO: unify names "succeeded" vs. "satisfied"?
|
||||
if int(c["type"]) != 0:
|
||||
self.die(r, r.BadRequest, uri="https://ca.example.com/failures/internalerror")
|
||||
self.die(r, r.BadRequest, uri="%sinternalerror" % error_uri)
|
||||
return
|
||||
chall = r.challenge.add()
|
||||
chall.type = int(c["type"])
|
||||
|
||||
Reference in New Issue
Block a user