From be58b8759a89edb01f3d2ed0ebb0c26c32b43a97 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Sat, 14 Jul 2012 14:56:19 -0700 Subject: [PATCH] notes on locking and concurrency --- server-ca/CSR.py | 5 +++++ server-ca/daemon.py | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/server-ca/CSR.py b/server-ca/CSR.py index 62d930293..9a659b8ba 100644 --- a/server-ca/CSR.py +++ b/server-ca/CSR.py @@ -208,6 +208,11 @@ def encrypt(key, data): def issue(csr, subjects): """Issue a certificate requested by CSR, specifying the subject names indicated in subjects, and return the certificate.""" + # TODO: The caller should have to acquire a lock in the database to + # prevent two certs from being issued at exactly the same time, + # because openssl ca doesn't handle this case safely. There + # is a longer comment in daemon.py describing how to implement + # this lock with Redis setnx. if not subjects: return None csr = str(csr) diff --git a/server-ca/daemon.py b/server-ca/daemon.py index 9ec679801..71f90cc34 100644 --- a/server-ca/daemon.py +++ b/server-ca/daemon.py @@ -38,7 +38,19 @@ # request, period, while still allowing clients to look # up successfully issued certs. # TODO: implement multithreading to allow several parallel -# worker processes. +# worker processes. But note: + +# The ca command is effectively a single user command: no locking +# is done on the various files and attempts to run more than one +# ca command on the same database can have unpredictable results. +# +# -- ca(1SSL) + +# So we need to implement our own locking mechanism. This +# can be done easily in Redis with "setnx": +# http://redis.io/commands/setnx +# However apparently the proper recovery after crashes can +# be complicated. # NOTE: The daemon enforces its own timeouts, which are # defined in the ancient() function. These timeouts apply