upgrade to CAM v2.0
[stack/cam.git] / cam / main.py
diff --git a/cam/main.py b/cam/main.py
new file mode 100755 (executable)
index 0000000..2e80029
--- /dev/null
@@ -0,0 +1,112 @@
+#!/usr/bin/python
+
+import logging
+import optparse
+import os
+import sys
+import time
+from cam import config
+
+
+USAGE = '''cam [<OPTIONS>] <COMMAND> [<ARG>...]
+CAM v2.0 - (c)2012 by <ale@incal.net> 
+A Certification Authority manager for complex situations.
+
+Known commands:
+
+  init [<RSA_CRT> [<DSA_CRT>]]
+    Initialize the environment and create a new CA certificate
+    (you can also import your own existing certificates)
+
+  gen <TAG>...
+    Create (or re-create) the certificates corresponding
+    to TAG
+
+  gencrl
+    Update the CRL
+
+  list
+    List all known certificates
+
+  files <TAG>...
+    Dump all the certificate-related files of this TAG
+
+  check 
+    Should be run weekly from a cron job to warn you if some
+    certificates are about to expire (controlled by the 'warning_days'
+    parameter in the 'global' section of the configuration)
+
+The configuration file consists of a ini-style file, with one 'ca'
+section that specifies global CA parameters, and more sections for
+each tag with certificate-specific information. See the examples for
+more details on how to write your own configuration.
+'''
+
+
+def find_cert(certs, name):
+    for c in certs:
+        if c.name == name:
+            return c
+    raise Exception('Certificate "%s" not found' % name)
+
+
+def main():
+    parser = optparse.OptionParser(usage=USAGE)
+    parser.add_option('-d', '--debug', dest='debug', help='Be verbose',
+                      action='store_true')
+    parser.add_option('-c', '--config', dest='config', help='Config file')
+    opts, args = parser.parse_args()
+    if not opts.config:
+        parser.error('Must specify --config')
+    if len(args) < 1:
+        parser.error('Must specify a command')
+
+    logging.basicConfig()
+    logging.getLogger().setLevel(opts.debug and logging.DEBUG or logging.INFO)
+
+    global_config, ca, certs = config.read_config(opts.config)
+
+    cmd, args = args[0], args[1:]
+
+    try:
+        if cmd == 'init':
+            ca.create()
+        elif cmd == 'gen':
+            if len(args) != 1:
+                parser.error('Wrong number of arguments')
+            ca.generate(find_cert(certs, args[0]))
+        elif cmd == 'gencrl':
+            ca.gencrl()
+        elif cmd == 'files':
+            if len(args) != 1:
+                parser.error('Wrong number of arguments')
+            c = find_cert(certs, args[0])
+            print c.public_key_file
+            print c.private_key_file
+        elif cmd == 'list':
+            for cert in sorted(certs, key=lambda x: x.name):
+                print cert.name, cert.cn, cert.get_expiration_date()
+        elif cmd == 'check':
+            now = time.time()
+            warning_time = 8640000 * int(global_config.get('warning_days', 15))
+            for cert in certs:
+                exp = cert.get_expiration_date()
+                if exp and (exp - now) < warning_time:
+                    print '%s (%s) is about to expire.' % (cert.name, cert.cn)
+        else:
+            parser.error('unknown command "%s"' % cmd)
+    finally:
+        ca.close()
+
+
+def main_wrapper():
+    try:
+        main()
+        return 0
+    except Exception, e:
+        logging.exception('uncaught exception')
+        return 1
+
+
+if __name__ == '__main__':
+    sys.exit(main_wrapper())