Easy CA management
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.7 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import cmd
  4. import hashlib
  5. import json
  6. import os
  7. import os.path
  8. import shutil
  9. import sqlite3
  10. import tempfile
  11. from paths import *
  12. from lookup import CALookup, RequestLookup
  13. __doc__= """
  14. Define classes to interact with certificate requests and Certification Authority
  15. """
  16. class CAManager(object):
  17. """
  18. Middleware to interact with ssh-keygen
  19. """
  20. def __init__(self, path):
  21. self.path = path
  22. self.ca = CALookup(self.ssh_ca_dir, self.ssl_ca_dir)
  23. self.request = RequestLookup()
  24. def __enter__(self):
  25. """
  26. Enter a context block, connect to database
  27. """
  28. self.conn = sqlite3.connect(self.db_path)
  29. self.ca.conn = self.conn
  30. return self
  31. def __exit__(self, exc_type, exc_value, traceback):
  32. """
  33. Exit a context block, disconnect from database
  34. """
  35. if exc_type is not None:
  36. print(exc_type, exc_value)
  37. print(traceback)
  38. self.ca.conn = None
  39. self.conn.close()
  40. @property
  41. def db_path(self):
  42. return os.path.join(self.path, 'ca_manager.db')
  43. @property
  44. def ssh_ca_dir(self):
  45. return os.path.join(self.path, 'ssh_cas')
  46. @property
  47. def ssl_ca_dir(self):
  48. return os.path.join(self.path, 'ssl_cas')
  49. def get_requests(self, ca_type=None):
  50. req_objs = []
  51. for request_name in os.listdir(REQUESTS_PATH):
  52. request_path = os.path.join(REQUESTS_PATH, request_name)
  53. with open(request_path, 'r') as stream:
  54. req = json.load(stream)
  55. if ca_type and not req['keyType'].startswith("%s_"%ca_type):
  56. continue
  57. if req['keyType'] == 'ssh_user':
  58. user_name = req['userName']
  59. root_requested = req['rootRequested']
  60. key_data = req['keyData']
  61. req_objs.append(
  62. UserSSHRequest(
  63. request_name, user_name, root_requested, key_data))
  64. elif req['keyType'] == 'ssh_host':
  65. host_name = req['hostName']
  66. key_data = req['keyData']
  67. req_objs.append(
  68. HostSSHRequest(
  69. request_name, host_name, key_data))
  70. elif req['keyType'] == 'ssl_host':
  71. host_name = req['hostName']
  72. key_data = req['keyData']
  73. req_objs.append(
  74. HostSSLRequest(
  75. request_name, host_name, key_data))
  76. return req_objs
  77. def drop_request(self, request):
  78. os.unlink(os.path.join(REQUESTS_PATH, request.req_id))
  79. def init_manager(paths):
  80. """
  81. Initiate the manager by creating the
  82. directories to store CAs and requests.
  83. Create a database to store the information
  84. """
  85. db_path = os.path.join(paths[0], 'ca_manager.db')
  86. directories = ['ssh_cas', 'ssl_cas']
  87. # ensure the directories needed by CAManager
  88. # exists
  89. for dirpath in paths:
  90. if not os.path.exists(dirpath):
  91. os.makedirs(dirpath)
  92. # ensure ssh_cas ad ssl_cas directories
  93. # exists in MANAGER_PATH
  94. for dirname in directories:
  95. dirpath = os.path.join(paths[0], dirname)
  96. if not os.path.exists(dirpath):
  97. os.mkdir(dirpath)
  98. # ensure the database exists
  99. # in MANAGER_PATH
  100. if not os.path.exists(db_path):
  101. conn = sqlite3.connect(db_path)
  102. c = conn.cursor()
  103. c.execute("""CREATE TABLE cas (id text, name text, type text)""")
  104. conn.commit()
  105. conn.close()
  106. def sign_request(ca_manager, request_name, authority_name):
  107. request = None
  108. try:
  109. authority = ca_manager.ca[authority_name]
  110. except IndexError:
  111. print("Could not find CA '%d'" % choosen_ca)
  112. return
  113. requests = ca_manager.get_requests()
  114. for i in requests:
  115. if str(i) == request_name:
  116. request = i
  117. if request is None:
  118. raise(IndexError)
  119. h = hashlib.sha256()
  120. h.update(request.key_data.encode('utf-8'))
  121. print("Request hash: %s" % h.hexdigest())
  122. print("You are about to sign this request with the following CA:")
  123. confirm = input('Proceed? (type yes)> ')
  124. if confirm != 'yes':
  125. print ("user aborT")
  126. return
  127. cert_path = authority.sign(request)
  128. ca_manager.drop_request(request)
  129. shutil.copy(cert_path, os.path.join(RESULTS_PATH, request.req_id))
  130. if __name__ == '__main__':
  131. from ca_shell import CAManagerShell
  132. init_manager([
  133. MANAGER_PATH,
  134. REQUESTS_PATH,
  135. OUTPUT_PATH,
  136. RESULTS_PATH,
  137. ])
  138. with CAManager(MANAGER_PATH) as ca_manager:
  139. CAManagerShell(ca_manager).cmdloop()