mirror of
https://github.com/certbot/certbot.git
synced 2026-01-26 07:41:33 +03:00
some reorganization and a start toward processing requests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import web, shelve, time
|
||||
import CSR
|
||||
from Crypto.Hash import SHA256, HMAC
|
||||
from Crypto import Random
|
||||
from chocolate_protocol_pb2 import chocolatemessage
|
||||
@@ -42,11 +43,91 @@ class sessionstore(object):
|
||||
def age(self, session):
|
||||
return int(time.time()) - self.f[session]["created"]
|
||||
|
||||
def make_request(self, session, request):
|
||||
self.f["request"] = request
|
||||
|
||||
def get_request(self, session):
|
||||
return self.f["request"]
|
||||
|
||||
def request_made(self, session):
|
||||
return "request" in self.f[session]
|
||||
|
||||
class index:
|
||||
def GET(self):
|
||||
web.header("Content-type", "text/html")
|
||||
return "Hello, world! This server only accepts POST requests."
|
||||
|
||||
def killsession(self):
|
||||
self.sessions.kill(self.session)
|
||||
|
||||
def handlesession(self, m, r):
|
||||
if m.session == "":
|
||||
# New session
|
||||
r.session = SHA256.new(Random.get_random_bytes(32)).hexdigest()
|
||||
self.session = r.session.encode("UTF8")
|
||||
self.sessions.create(self.session, int(time.time()))
|
||||
elif m.session and not r.failure.IsInitialized():
|
||||
self.session = m.session.encode("UTF8")
|
||||
r.session = self.session
|
||||
if not self.sessions.exists(self.session):
|
||||
r.failure.cause = r.StaleRequest
|
||||
elif not self.sessions.live(self.session):
|
||||
r.failure.cause = r.StaleRequest
|
||||
elif self.sessions.age(self.session) > MaximumSessionAge:
|
||||
self.killsession()
|
||||
r.failure.cause = r.StaleRequest
|
||||
|
||||
def handleclientfailure(self, m, r):
|
||||
if r.failure.IsInitialized(): return
|
||||
if m.failure.IsInitialized():
|
||||
# Received failure message from client!
|
||||
self.killsession()
|
||||
r.failure.cause = r.AbandonedRequest
|
||||
|
||||
def handlesigningrequest(self, m, r):
|
||||
if r.failure.IsInitialized(): return
|
||||
if not m.request: return
|
||||
if self.sessions.request_made(self.session):
|
||||
self.killsession()
|
||||
r.failure.cause = r.BadRequest
|
||||
r.failure.uri = "https://ca.example.com/failures/request"
|
||||
return
|
||||
# TODO: currently only examine the first request
|
||||
# TODO: check client puzzle
|
||||
timestamp = m.request[0].timestamp
|
||||
recipient = m.request[0].recipient
|
||||
nonce = m.request[0].nonce
|
||||
csr = m.request[0].csr
|
||||
sig = m.request[0].sig
|
||||
if timestamp > time.time() or time.time() - timestamp > 100:
|
||||
self.killsession()
|
||||
r.failure.cause = r.BadRequest
|
||||
r.failure.affectedrequest = nonce
|
||||
r.failure.uri = "https://ca.example.com/failures/time"
|
||||
return
|
||||
if recipient != "ca.example.com":
|
||||
self.killsession()
|
||||
r.failure.cause = r.BadRequest
|
||||
r.failure.affectedrequest = nonce
|
||||
r.failure.uri = "https://ca.example.com/failures/recipient"
|
||||
return
|
||||
if not CSR.parse(csr):
|
||||
self.killsession()
|
||||
r.failure.cause = r.BadCSR
|
||||
r.failure.affectedrequest = nonce
|
||||
return
|
||||
# if CSR.verify(pubkey(csr), sig) != hmac("chocolate-request-ca-example.com", /%s/%s/%s/%s" % (timestamp, recipient, nonce, csr))):
|
||||
# self.killsession()
|
||||
# r.failure.cause = BadSignature
|
||||
# r.failure.affectedrequest = nonce
|
||||
# self.killsession()
|
||||
# return
|
||||
if not CSR.goodkey(csr):
|
||||
self.killsession()
|
||||
r.failure.cause = r.UnsafeKey
|
||||
r.failure.affectedrequest = nonce
|
||||
return
|
||||
|
||||
def POST(self):
|
||||
web.header("Content-type", "application/x-protobuf")
|
||||
# web.setcookie("chocolate", hmac("foo", "bar"),
|
||||
@@ -62,21 +143,13 @@ class index:
|
||||
else:
|
||||
if m.chocolateversion != 1:
|
||||
r.failure.cause = r.UnsupportedVersion
|
||||
if m.session == "":
|
||||
# New session
|
||||
r.session = SHA256.new(Random.get_random_bytes(32)).hexdigest()
|
||||
session = r.session.encode("UTF8")
|
||||
self.sessions.create(session, int(time.time()))
|
||||
elif m.session and not r.failure.IsInitialized():
|
||||
session = m.session.encode("UTF8")
|
||||
r.session = session
|
||||
if not self.sessions.exists(session):
|
||||
r.failure.cause = r.StaleRequest
|
||||
elif not self.sessions.live(session):
|
||||
r.failure.cause = r.StaleRequest
|
||||
elif self.sessions.age(session) > MaximumSessionAge:
|
||||
self.sessions.kill(session)
|
||||
r.failure.cause = r.StaleRequest
|
||||
self.handlesession(m, r)
|
||||
|
||||
self.handleclientfailure(m, r)
|
||||
|
||||
self.handlesigningrequest(m, r)
|
||||
|
||||
# Send reply
|
||||
if m.debug:
|
||||
web.header("Content-type", "text/plain")
|
||||
return "SAW MESSAGE: %s\n" % str(r)
|
||||
|
||||
Reference in New Issue
Block a user