Commit a58be345 authored by Guillaume Bury's avatar Guillaume Bury

Certificate request now works

parent b0e093f3
#!/usr/bin/env python #!/usr/bin/env python
import argparse, math, random, smtplib, sqlite3 import argparse, math, random, smtplib, sqlite3, string, time
from email.mime.text import MIMEText from email.mime.text import MIMEText
from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleXMLRPCServer import SimpleXMLRPCServer
from OpenSSL import crypto from OpenSSL import crypto
import netaddr import netaddr
import traceback
class main(object): class main(object):
...@@ -20,30 +21,41 @@ class main(object): ...@@ -20,30 +21,41 @@ class main(object):
help='Path to ca.crt file') help='Path to ca.crt file')
_('--key', required=True, _('--key', required=True,
help='Path to certificate key') help='Path to certificate key')
config = parser.parser_arg() _('--mailhost', required=True,
help='SMTP server mail host')
self.config = parser.parse_args()
# Database initializing # Database initializing
self.db = sqlite3.connect(config.db, isolation_level=None) self.db = sqlite3.connect(self.config.db, isolation_level=None)
self.db.execute("""CREATE TABLE IF NOT EXISTS tokens ( self.db.execute("""CREATE TABLE IF NOT EXISTS tokens (
token text primary key not null, token text primary key not null,
email text not null, email text not null,
prefix_len integer not null default 16, prefix_len integer not null,
date integer not null)""") date integer not null)""")
self.db.execute("""CREATE TABLE IF NOT EXISTS vifib ( try:
prefix text primary key not null, self.db.execute("""CREATE TABLE vifib (
email text, prefix text primary key not null,
cert text)""") email text,
cert text)""")
except sqlite3.OperationalError, e:
if e.args[0] == 'table vifib already exists':
pass
else:
raise RuntimeError
else:
self.db.execute("INSERT INTO vifib VALUES ('',null,null)")
# Loading certificates # Loading certificates
with open(config.ca) as f: with open(self.config.ca) as f:
self.ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) self.ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
with open(config.key) as f: with open(self.config.key) as f:
self.key = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) self.key = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read())
# Get vifib network prefix # Get vifib network prefix
self.network = bin(self.ca.get_serial())[3:] self.network = bin(self.ca.get_serial_number())[3:]
# Starting server # Starting server
server = SimpleXMLRPCServer(("localhost", 8000)) server = SimpleXMLRPCServer(("localhost", 8000), allow_none=True)
server.register_instance(self) server.register_instance(self)
server.serve_forever() server.serve_forever()
...@@ -53,13 +65,13 @@ class main(object): ...@@ -53,13 +65,13 @@ class main(object):
token = ''.join(random.sample(string.ascii_lowercase, 8)) token = ''.join(random.sample(string.ascii_lowercase, 8))
# Updating database # Updating database
try: try:
self.db.execute("INSERT INTO tokens (?,?,null,?)", (token, email, int(time.time()))) self.db.execute("INSERT INTO tokens VALUES (?,?,?,?)", (token, email, 16, int(time.time())))
break break
except sqlite3.IntegrityError, e: except sqlite3.IntegrityError, e:
pass pass
# Creating and sending email # Creating and sending email
s = smtplib.SMTP('localhost') s = smtplib.SMTP(self.config.mailhost)
me = 'postmaster@vifibnet.com' me = 'postmaster@vifibnet.com'
msg = MIMEText('Hello world !\nYour token : %s' % (token,)) msg = MIMEText('Hello world !\nYour token : %s' % (token,))
msg['Subject'] = '[Vifibnet] Token Request' msg['Subject'] = '[Vifibnet] Token Request'
...@@ -70,22 +82,23 @@ class main(object): ...@@ -70,22 +82,23 @@ class main(object):
def _getPrefix(self, prefix_len): def _getPrefix(self, prefix_len):
assert 0 < prefix_len <= 128 - len(self.network) assert 0 < prefix_len <= 128 - len(self.network)
for prefix in self.db.execute("""SELECT prefix FROM vifib WHERE length(prefix) <= ? AND cert is null for prefix, in self.db.execute("""SELECT prefix FROM vifib WHERE length(prefix) <= ? AND cert is null
ORDER BY length(prefix) DESC""", (prefix_len,)): ORDER BY length(prefix) DESC""", (prefix_len,)):
while len(prefix) < prefix_len: while len(prefix) < prefix_len:
self.db.execute("UPDATE vifib SET prefix = ? WHERE prefix = ?", (prefix + '1', prefix)) self.db.execute("UPDATE vifib SET prefix = ? WHERE prefix = ?", (prefix + '1', prefix))
prefix += '0' prefix += '0'
self.db.execute("INSERT INTO vifib VALUES (?,null,null)", (prefix,)) self.db.execute("INSERT INTO vifib VALUES (?,null,null)", (prefix,))
return prefix return prefix
raise RuntimeError # TODO: raise better exception raise RuntimeError # TODO: raise better exception
def requestCertificate(self, token, cert_req): def requestCertificate(self, token, cert_req):
try:
req = crypto.load_certificate_request(crypto.FILETYPE_PEM, cert_req) req = crypto.load_certificate_request(crypto.FILETYPE_PEM, cert_req)
with self.db: with self.db:
try: try:
token, email, prefix_len, _ = self.db.execute("SELECT * FROM tokens WHERE token = ?", (token,)).next() token, email, prefix_len, _ = self.db.execute("SELECT * FROM tokens WHERE token = ?", (token,)).next()
except StopIteration: except StopIteration:
# TODO: return nice error message # TODO: return nice error message
raise raise
self.db.execute("DELETE FROM tokens WHERE token = ?", (token,)) self.db.execute("DELETE FROM tokens WHERE token = ?", (token,))
...@@ -102,7 +115,7 @@ class main(object): ...@@ -102,7 +115,7 @@ class main(object):
# Create certificate # Create certificate
cert = crypto.X509() cert = crypto.X509()
#cert.set_serial_number(serial) #cert.set_serial_number(serial)
cert.set_notBefore(0) cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(self.cert_duration) cert.gmtime_adj_notAfter(self.cert_duration)
cert.set_issuer(self.ca.get_subject()) cert.set_issuer(self.ca.get_subject())
subject = req.get_subject() subject = req.get_subject()
...@@ -113,9 +126,12 @@ class main(object): ...@@ -113,9 +126,12 @@ class main(object):
cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert) cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
# Insert certificate into db # Insert certificate into db
self.db.execute("UPDATE certificates SET email = ?, cert = ? WHERE prefix = ?", (email, cert, prefix) ) self.db.execute("UPDATE vifib SET email = ?, cert = ? WHERE prefix = ?", (email, cert, prefix) )
return cert return cert
except:
traceback.print_exc()
raise
if __name__ == "__main__": if __name__ == "__main__":
main() main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment