Merge branch 'master' of https://git.erp5.org/repos/vifibnet
[re6stnet.git] / setup.py
1 #!/usr/bin/env python
2 import argparse, os, subprocess, sqlite3, sys, xmlrpclib
3 from OpenSSL import crypto
4
5 def main():
6 parser = argparse.ArgumentParser(
7 description='Setup script for vifib')
8 _ = parser.add_argument
9 _('--ca-only', action='store_true',
10 help='To only get CA form server')
11 _('--db-only', action='store_true',
12 help='To only get CA and setup peer db with bootstrap peer')
13 _('--no-boot', action='store_true',
14 help='Enable to skip getting bootstrap peer')
15 _('--server', required=True,
16 help='Address of the server delivering certifiactes')
17 _('--port', required=True, type=int,
18 help='Port to which connect on the server')
19 _('-d', '--dir', default='/etc/vifib',
20 help='Directory where the key and certificate will be stored')
21 _('-r', '--req', nargs='+',
22 help='''Certificate request additional arguments. For example :
23 --req name1 value1 name2 value2, to add attributes name1 and name2''')
24 config = parser.parse_args()
25 if config.req and len(config.req) % 2 == 1:
26 print "Sorry, request argument was incorrect, there must be an even number of request arguments"
27 sys.exit(1)
28
29 # Establish connection with server
30 s = xmlrpclib.ServerProxy('http://%s:%u' % (config.server, config.port))
31
32 # Get CA
33 ca = s.getCa()
34 with open(os.path.join(config.dir, 'ca.pem'), 'w') as f:
35 f.write(ca)
36
37 if config.ca_only:
38 sys.exit(0)
39
40 # Create and initialize peers DB
41 db = sqlite3.connect(os.path.join(config.dir, 'peers.db'), isolation_level=None)
42 try:
43 db.execute("""CREATE TABLE peers (
44 id INTEGER PRIMARY KEY AUTOINCREMENT,
45 ip TEXT NOT NULL,
46 port INTEGER NOT NULL,
47 proto TEXT NOT NULL,
48 used INTEGER NOT NULL default 0,
49 date INTEGER DEFAULT (strftime('%s', 'now')))""")
50 db.execute("CREATE INDEX _peers_used ON peers(used)")
51 db.execute("CREATE UNIQUE INDEX _peers_address ON peers(ip, port, proto)")
52 if not config.no_boot:
53 boot_ip, boot_port, boot_proto = s.getBootstrapPeer()
54 db.execute("INSERT INTO peers (ip, port, proto) VALUES (?,?,?)", (boot_ip, boot_port, boot_proto))
55 except sqlite3.OperationalError, e:
56 if e.args[0] == 'table peers already exists':
57 print "Table peers already exists, leaving it as it is"
58 else:
59 print "sqlite3.OperationalError :" + e.args[0]
60 sys.exit(1)
61
62 if config.db_only:
63 sys.exit(0)
64
65 # Get token
66 email = raw_input('Please enter your email address : ')
67 _ = s.requestToken(email)
68 token = raw_input('Please enter your token : ')
69
70 # Generate key and cert request
71 pkey = crypto.PKey()
72 pkey.generate_key(crypto.TYPE_RSA, 2048)
73 key = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
74
75 req = crypto.X509Req()
76 subj = req.get_subject()
77 if config.req:
78 while len(config.req) > 1:
79 key = config.req.pop(0)
80 value = config.req.pop(0)
81 setattr(subj, key, value)
82 req.set_pubkey(pkey)
83 req.sign(pkey, 'sha1')
84 req = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
85
86 # Get certificate
87 cert = s.requestCertificate(token, req)
88
89 # Store cert and key
90 with open(os.path.join(config.dir, 'cert.key'), 'w') as f:
91 f.write(key)
92 with open(os.path.join(config.dir, 'cert.crt'), 'w') as f:
93 f.write(cert)
94
95 # Generating dh file
96 if not os.access(os.path.join(config.dir, 'dh2048.pem'), os.F_OK):
97 subprocess.call(['openssl', 'dhparam', '-out', os.path.join(config.dir, 'dh2048.pem'), '2048'])
98
99 print "Certificate setup complete."
100
101 if __name__ == "__main__":
102 main()