Commit 37aae0a1 authored by Alain Takoudjou's avatar Alain Takoudjou

slapos cli: register computer uses new certificate generation style, configure...

slapos cli: register computer uses new certificate generation style, configure client generate csr with random CN
parent 98475e38
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
import re import re
import os import os
import sys import sys
import uuid
import requests import requests
from caucase.cli_flask import CertificateAuthorityRequest from caucase.cli_flask import CertificateAuthorityRequest
...@@ -60,9 +61,6 @@ class ConfigureClientCommand(ClientConfigCommand): ...@@ -60,9 +61,6 @@ class ConfigureClientCommand(ClientConfigCommand):
help="SlapOS 'credential security' authentication token " help="SlapOS 'credential security' authentication token "
"(use '--token ask' for interactive prompt)") "(use '--token ask' for interactive prompt)")
ap.add_argument('--login',
help="Your username on SlapOS Master web")
return ap return ap
def take_action(self, args): def take_action(self, args):
...@@ -101,7 +99,7 @@ def fetch_configuration_template(): ...@@ -101,7 +99,7 @@ def fetch_configuration_template():
return req.text return req.text
def do_configure_client(logger, master_url_web, token, config_path, master_url, login): def do_configure_client(logger, master_url_web, token, config_path, master_url):
while not token: while not token:
token = raw_input('Credential security token: ').strip() token = raw_input('Credential security token: ').strip()
...@@ -141,7 +139,9 @@ def do_configure_client(logger, master_url_web, token, config_path, master_url, ...@@ -141,7 +139,9 @@ def do_configure_client(logger, master_url_web, token, config_path, master_url,
logger.debug('Generating key to %s', key_path) logger.debug('Generating key to %s', key_path)
ca_client.generatePrivatekey(key_path, size=2048) ca_client.generatePrivatekey(key_path, size=2048)
csr_string = ca_client.generateCertificateRequest(key_path, cn=login) csr_string = ca_client.generateCertificateRequest(
key_path,
cn=str(uuid.uuid4()))
# retrieve a template for the configuration file # retrieve a template for the configuration file
......
...@@ -35,7 +35,9 @@ import stat ...@@ -35,7 +35,9 @@ import stat
import sys import sys
import pkg_resources import pkg_resources
import requests import requests
import uuid
from caucase.cli_flask import CertificateAuthorityRequest
from slapos.cli.command import Command, must_be_root from slapos.cli.command import Command, must_be_root
from slapos.util import parse_certificate_key_pair from slapos.util import parse_certificate_key_pair
...@@ -143,16 +145,19 @@ def check_credentials(url, login, password): ...@@ -143,16 +145,19 @@ def check_credentials(url, login, password):
return 'Logout' in req.text return 'Logout' in req.text
def get_certificate_key_pair(logger, master_url_web, node_name, token=None, login=None, password=None): def sign_certificate(logger, master_url_web, node_name, csr_string,
"""Download certificates from SlapOS Master""" token=None, login=None, password=None):
"""Sign certificates on SlapOS Master"""
data = {'title': node_name, 'certificate_request': csr_string}
if token: if token:
req = requests.post('/'.join([master_url_web, 'add-a-server/WebSection_registerNewComputer']), req = requests.post('/'.join([master_url_web, 'add-a-server/WebSection_registerNewComputer']),
data={'title': node_name}, data=data,
headers={'X-Access-Token': token}, headers={'X-Access-Token': token},
verify=False) verify=False)
else: else:
register_server_url = '/'.join([master_url_web, ("add-a-server/WebSection_registerNewComputer?title={}".format(node_name))]) register_server_url = '/'.join([master_url_web,
"add-a-server/WebSection_registerNewComputer?%s" % urllib.urlencode(data)])
req = requests.get(register_server_url, auth=(login, password), verify=False) req = requests.get(register_server_url, auth=(login, password), verify=False)
if not req.ok and 'Certificate still active.' in req.text: if not req.ok and 'Certificate still active.' in req.text:
...@@ -178,14 +183,16 @@ def get_certificate_key_pair(logger, master_url_web, node_name, token=None, logi ...@@ -178,14 +183,16 @@ def get_certificate_key_pair(logger, master_url_web, node_name, token=None, logi
else: else:
req.raise_for_status() req.raise_for_status()
return parse_certificate_key_pair(req.text)
return (get_computer_name(req.text), parse_certificate_from_html(req.text))
def get_computer_name(certificate):
"""Parse certificate to get computer name and return it""" def get_computer_name(text_string):
k = certificate.find("COMP-") """Parse text string to get computer name and return it"""
i = certificate.find("/email", k) regex = r"<div[\w\s=\"]+>(COMP\-\d+)</div>"
return certificate[k:i] result = re.search(regex, text_string)
if result:
return result.groups()[0]
def save_former_config(conf): def save_former_config(conf):
...@@ -240,16 +247,12 @@ def slapconfig(conf): ...@@ -240,16 +247,12 @@ def slapconfig(conf):
if not dry_run: if not dry_run:
os.mkdir(user_certificate_repository_path, 0o711) os.mkdir(user_certificate_repository_path, 0o711)
key_file = os.path.join(user_certificate_repository_path, 'key') conf.logger.info('Copying to %r, and setting minimum privileges', conf.certificate_path)
cert_file = os.path.join(user_certificate_repository_path, 'certificate') if not dry_run:
with open(conf.certificate_path, 'w') as destination:
for src, dst in [(conf.key, key_file), (conf.certificate, cert_file)]: destination.write(''.join(src))
conf.logger.info('Copying to %r, and setting minimum privileges', dst) os.chmod(conf.certificate_path, 0o600)
if not dry_run: os.chown(conf.certificate_path, 0, 0)
with open(dst, 'w') as destination:
destination.write(''.join(src))
os.chmod(dst, 0o600)
os.chown(dst, 0, 0)
certificate_repository_path = os.path.join(slap_conf_dir, 'ssl', 'partition_pki') certificate_repository_path = os.path.join(slap_conf_dir, 'ssl', 'partition_pki')
if not os.path.exists(certificate_repository_path): if not os.path.exists(certificate_repository_path):
...@@ -294,6 +297,8 @@ class RegisterConfig(object): ...@@ -294,6 +297,8 @@ class RegisterConfig(object):
def __init__(self, logger): def __init__(self, logger):
self.logger = logger self.logger = logger
self.computer_id = None
self.certificate = None
def setConfig(self, options): def setConfig(self, options):
""" """
...@@ -303,11 +308,11 @@ class RegisterConfig(object): ...@@ -303,11 +308,11 @@ class RegisterConfig(object):
for option, value in options.__dict__.items(): for option, value in options.__dict__.items():
setattr(self, option, value) setattr(self, option, value)
def COMPConfig(self, slapos_configuration, computer_id, certificate, key): def COMPConfig(self, slapos_configuration):
ssl_path = os.path.join(slapos_configuration, 'ssl')
self.slapos_configuration = slapos_configuration self.slapos_configuration = slapos_configuration
self.computer_id = computer_id self.certificate_path = os.path.join(ssl_path, 'certificate')
self.certificate = certificate self.key_path = os.path.join(ssl_path, 'key')
self.key = key
def displayUserConfig(self): def displayUserConfig(self):
self.logger.debug('Computer Name: %s', self.node_name) self.logger.debug('Computer Name: %s', self.node_name)
...@@ -333,6 +338,22 @@ def gen_auth(conf): ...@@ -333,6 +338,22 @@ def gen_auth(conf):
def do_register(conf): def do_register(conf):
"""Register new computer on SlapOS Master and generate slapos.cfg""" """Register new computer on SlapOS Master and generate slapos.cfg"""
# Getting configuration parameters
conf.COMPConfig(slapos_configuration='/etc/opt/slapos/')
# create certificate authority client
ca_client = CertificateAuthorityRequest(
conf.key_path,
conf.certificate_path,
ca_cert_path,
ca_url='')
conf.logger.info('Generating private key to %s', conf.key_path)
ca_client.generatePrivatekey(conf.key_path, size=2048)
csr_string = ca_client.generateCertificateRequest(
conf.key_path,
cn=str(uuid.uuid4()))
if conf.login or conf.login_auth: if conf.login or conf.login_auth:
for login, password in gen_auth(conf): for login, password in gen_auth(conf):
if check_credentials(conf.master_url_web, login, password): if check_credentials(conf.master_url_web, login, password):
...@@ -341,28 +362,25 @@ def do_register(conf): ...@@ -341,28 +362,25 @@ def do_register(conf):
else: else:
return 1 return 1
certificate, key = get_certificate_key_pair(conf.logger, computer_id, certificate = sign_certificate(conf.logger,
conf.master_url_web, conf.master_url_web,
conf.node_name, conf.node_name,
csr_string,
login=login, login=login,
password=password) password=password)
else: else:
while not conf.token: while not conf.token:
conf.token = raw_input('Computer security token: ').strip() conf.token = raw_input('Computer security token: ').strip()
certificate, key = get_certificate_key_pair(conf.logger, computer_id, certificate = sign_certificate(conf.logger,
conf.master_url_web, conf.master_url_web,
conf.node_name, conf.node_name,
csr_string,
token=conf.token) token=conf.token)
# get computer id # get computer id
COMP = get_computer_name(certificate) conf.computer_id = computer_id
conf.certificate = certificate
# Getting configuration parameters
conf.COMPConfig(slapos_configuration='/etc/opt/slapos/',
computer_id=COMP,
certificate=certificate,
key=key)
# Save former configuration # Save former configuration
if not conf.dry_run: if not conf.dry_run:
......
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