From 61d05f768cf0f7962808dbaddfb4416ce7ce0704 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Diemer?= <stephane.diemer@ubicast.eu>
Date: Fri, 10 Mar 2017 16:23:06 +0100
Subject: [PATCH] Added public SSH keys management (refs #20615).

---
 1.Base/2.ubicast_shell_access/0_setup.py      | 37 ++++++++++++++-----
 .../1.Download_envsetup_config/0_setup.py     |  9 ++++-
 global-conf.sh                                |  2 +
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/1.Base/2.ubicast_shell_access/0_setup.py b/1.Base/2.ubicast_shell_access/0_setup.py
index 6d80ccfc..64eb7a73 100644
--- a/1.Base/2.ubicast_shell_access/0_setup.py
+++ b/1.Base/2.ubicast_shell_access/0_setup.py
@@ -1,10 +1,31 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
+import os
 import subprocess
 
 import utils
 
 
+def add_allowed_keys(path, keys):
+    content = ''
+    if os.path.exists(path):
+        with open(path, 'r') as fo:
+            content = fo.read()
+    new_content = content.strip()
+    for key in keys:
+        if key not in new_content:
+            new_content += '\n' + key
+            utils.log('The key "%s" will be added in "%s".' % (key.split(' ')[-1], path))
+        else:
+            utils.log('The key "%s" is already in "%s".' % (key.split(' ')[-1], path))
+    if new_content != content:
+        with open(path, 'w') as fo:
+            fo.write(new_content)
+        utils.log('The file "%s" has been updated.' % path)
+    else:
+        utils.log('The file "%s" is already up to date.' % path)
+
+
 def setup(interactive=True):
     dir_path = utils.get_dir(__file__)
     cmds = list()
@@ -18,23 +39,19 @@ def setup(interactive=True):
         cmds.append('usermod -aG sudo ubicast')
     # Add SSH key
     cmds.append('echo "Checking ubicast and root SSH keys"')
+    allowed_keys = utils.get_conf('SSH_ALLOWED_KEYS', '').strip().split('\n')
+    with open('%s/ubicast_support.pub' % dir_path, 'r') as fo:
+        support_key = fo.read()
+    allowed_keys.append(support_key.strip())
     # root
     cmds.append('mkdir -p /root/.ssh')
     cmds.append('chmod 700 /root/.ssh')
-    code, out = utils.exec_cmd(['rgrep', 'support@ubicast', '/root/.ssh'])
-    if code != 0:
-        cmds.append('cat "%s/ubicast_support.pub" >> /root/.ssh/authorized_keys' % dir_path)
-    else:
-        utils.log('The key "ubicast_support.pub" is already in /root/.ssh/authorized_keys.')
+    add_allowed_keys('/root/.ssh/authorized_keys', allowed_keys)
     # ubicast
     cmds.append('mkdir -p /home/ubicast')
     cmds.append('mkdir -p /home/ubicast/.ssh')
     cmds.append('chmod 700 /home/ubicast/.ssh')
-    code, out = utils.exec_cmd(['rgrep', 'support@ubicast', '/home/ubicast/.ssh'])
-    if code != 0:
-        cmds.append('cat "%s/ubicast_support.pub" >> /home/ubicast/.ssh/authorized_keys' % dir_path)
-    else:
-        utils.log('The key "ubicast_support.pub" is already in /home/ubicast/.ssh/authorized_keys.')
+    add_allowed_keys('/home/ubicast/.ssh/authorized_keys', allowed_keys)
     cmds.append('cp "/root/.bashrc" "/home/ubicast/.bashrc"')
     cmds.append('chown -R ubicast:ubicast /home/ubicast/.ssh')
 
diff --git a/3.New_server_deployment/1.Download_envsetup_config/0_setup.py b/3.New_server_deployment/1.Download_envsetup_config/0_setup.py
index 05311396..f3b91802 100644
--- a/3.New_server_deployment/1.Download_envsetup_config/0_setup.py
+++ b/3.New_server_deployment/1.Download_envsetup_config/0_setup.py
@@ -6,6 +6,13 @@ import utils
 
 
 def setup(interactive=True):
+    # Generate SSH key if not already done
+    if not os.path.exists('/root/.ssh/id_rsa'):
+        code, out = utils.exec_cmd('ssh-keygen -b 4096 -t rsa -f /root/.ssh/id_rsa -P ""')
+        if code != 0:
+            raise Exception('Failed to create SSH key: ssh-keygen returned code %s:\n%s' % (code, out))
+    with open('/root/.ssh/id_rsa.pub', 'r') as fo:
+        public_key = fo.read()
     # Get requests module
     cmds = [
         'apt-get update',
@@ -31,7 +38,7 @@ def setup(interactive=True):
         if not act_key:
             utils.log('\033[1;33m No activation key is set, skipping configuration download. \033[0m')
             return
-        req = requests.get(sk_url + '/erp/credentials/envsetup-conf.sh', params=dict(key=act_key), verify=verify, timeout=20)
+        req = requests.post(sk_url + '/erp/credentials/envsetup-conf.sh', data=dict(key=act_key, public_key=public_key), verify=verify, timeout=20)
     else:
         # Get conf using an api key
         # (deprecated, for compatibility, to be removed when Panel version will be > 5.2)
diff --git a/global-conf.sh b/global-conf.sh
index 6e7811d4..43f61e8e 100644
--- a/global-conf.sh
+++ b/global-conf.sh
@@ -19,6 +19,8 @@ SKYREACH_API_KEY=
 SKYREACH_ACTIVATION_KEY=
 # NTP
 NTP_SERVER='ntp.ubuntu.com'
+# SSH
+SSH_ALLOWED_KEYS=
 # SSL certificate
 SSL_CERTIFICATE='/etc/ssl/certs/ssl-cert-snakeoil.pem'
 SSL_CERTIFICATE_KEY='/etc/ssl/private/ssl-cert-snakeoil.key'
-- 
GitLab