From fc541b6eb9beb3f3a192345333d13ed304b0d917 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Filip=20Str=C3=B6mb=C3=A4ck?= <filip.stromback@liu.se>
Date: Fri, 27 Nov 2020 14:20:05 +0100
Subject: [PATCH] Added the key database to the system to support sign in with
 SSH keys.

---
 files/auth/auth.service        |  4 +-
 files/auth/config.json         | 79 ++++++++++++++++++++++------------
 files/auth/keydb.service       | 17 ++++++++
 files/auth/on_update.sh        |  3 +-
 files/auth/on_update_keydb.sh  |  4 ++
 files/auth/temp_userdb.service | 17 ++++++++
 files/broker/broker.service    |  2 +-
 files/broker/on_update.sh      |  3 +-
 manifests/auth.pp              | 16 +++++--
 manifests/auth_keydb.pp        | 69 +++++++++++++++++++++++++++++
 manifests/init.pp              |  1 +
 11 files changed, 179 insertions(+), 36 deletions(-)
 create mode 100644 files/auth/keydb.service
 create mode 100644 files/auth/on_update_keydb.sh
 create mode 100644 files/auth/temp_userdb.service
 create mode 100644 manifests/auth_keydb.pp

diff --git a/files/auth/auth.service b/files/auth/auth.service
index cf6ba59..7405190 100644
--- a/files/auth/auth.service
+++ b/files/auth/auth.service
@@ -1,5 +1,5 @@
 [Unit]
-Description=Exam System Message Broker
+Description=Exam System Authentication Service
 After=network.target
 
 [Service]
@@ -11,7 +11,7 @@ Restart=on-failure
 RestartSec=10
 
 # No limit. We won't overload the system anyway.
-StartLimitIntervalSec=0
+StartLimitInterval=0
 
 [Install]
 WantedBy=multi-user.target
diff --git a/files/auth/config.json b/files/auth/config.json
index c7d0302..465a738 100644
--- a/files/auth/config.json
+++ b/files/auth/config.json
@@ -4,8 +4,8 @@
 // These are in place to make it easy to strip the comments without knowledge of JSON before passing
 // it to the JSON parser.
 {
-    // Timeout for all authentications, in minutes
-    "timeout" : 1,
+    // Timeout for all authentications, in seconds
+    "timeout" : 30,
 
     // All groups known to the system, and what permissions we assign each group.
     "groups" : {
@@ -18,6 +18,18 @@
 	    "groups" : [ "TEST" ]
 	},
 
+	// SSH key database.
+	"KDB" : {
+	    "message_size" : 102400,
+	    "groups" : [ "KMGR", "AUTH" ]
+	},
+
+	// SSH key manager.
+	"KMGR" : {
+	    "message_size" : 102400,
+	    "groups" : [ "KDB" ]
+	},
+
 	// Admin clients.
 	"ADMC" : {
 	    "message_size" : 1024000,
@@ -27,7 +39,7 @@
 	// Examiner clients.
 	"EC" : {
 	    "message_size" : 1024000,
-	    "groups" : [ "", "MS" ]
+	    "groups" : [ "", "MS", "EC" ]
 	},
 
 	// Student clients.
@@ -50,6 +62,29 @@
 	}
     },
 
+    // How should the system tie acquired identity strings to system IDs? The information here is
+    // used by all authentication systems that figure out some kind of identity and need to tie that
+    // to some kind of database ID.
+    "identity" : {
+	// Address of the server that holds all identities.
+	"server" : {
+	    "group" : "DB",
+	    "id" : 1
+	},
+
+	// Mapping from group names to one or more categories that users in that group may belong
+	// to. This lets the system know which tables to examine in a query, and roughly what
+	// permissions are required for the different groups.
+	"groups" : {
+	    "SC" : [ "student" ],
+	    "EC" : [ "staff", "admin" ],
+	    "ADMC" : [ "admin" ],
+	    // Note: This might not be a good idea in the long run. We should at least
+	    // put "admin" here instead of "staff".
+	    "KMGR" : [ "staff" ]
+	}
+    },
+
     // All authentication methods the auth server is going to support. Each method may appear multiple
     // times with different configuration if different groups are to be guarded with different levels
     // of security.
@@ -57,7 +92,7 @@
 	{
 	    // A list of groups that we allow authenticating using this method. This is mandatory
 	    // for all elements in here.
-	    "allow" : [ "TEST" ],
+	    "allow" : [ "TEST", "EC", "SC", "MS" ],
 
 	    // The debug auth is the simplest. It just allows whatever the connected client
 	    // claimed. It is not good to use in production, and is always disabled unless the
@@ -65,7 +100,7 @@
 	    "type" : "debug"
 	},
 	{
-	    "allow" : [ "DB", "MS" ],
+	    "allow" : [ "DB", "MS", "KDB" ],
 
 	    // File system authentication. This works for clients on the same system as the
 	    // authentication server (e.g. DB, ARLA, etc.), and relies on UNIX permissions. This
@@ -79,11 +114,11 @@
 	    "permissions" : "0770",
 
 	    // Group of the file. If not present or null, we won't change the group.
-	    "group" : null
+	    "group" : "aes_local_auth"
 	},
 	{
-	    // Slightly different requirements for ADMC.
-	    "allow" : [ "ADMC" ],
+	    // Slightly different requirements for ADMC and the Key manager.
+	    "allow" : [ "ADMC", "KMGR" ],
 	    "type" : "fs",
 	    "path" : "/tmp",
 	    "permissions" : "0777",
@@ -98,29 +133,19 @@
 	    "group" : null
 	},
 	{
-	    // Allow authenticating EC with Kerberos.
-	    "allow" : [ "EC" ],
-	    "type" : "kerberos",
-
-	    // What is the address of the database server we shall query for information?
-	    "db" : {
-		"group" : "DB",
-		"id" : 1
-	    },
-
-	    "user_type" : "staff"
+	    // Allow authenticating SC, EC and AdmC with Kerberos.
+	    "allow" : [ "EC", "SC", "ADMC" ],
+	    "type" : "kerberos"
 	},
 	{
-	    // Allow authenticating SC with Kerberos.
-	    "allow" : [ "SC" ],
-	    "type" : "kerberos",
+	    // Allow TEST, EC, SC, and KMGR with SSH.
+	    "allow" : [ "TEST", "EC", "SC", "KMGR" ],
+	    "type" : "ssh",
 
-	    "db" : {
-		"group" : "DB",
+	    "identity_db" : {
+		"group" : "KDB",
 		"id" : 1
-	    },
-
-	    "user_type" : "student"
+	    }
 	}
     ]
 }
diff --git a/files/auth/keydb.service b/files/auth/keydb.service
new file mode 100644
index 0000000..4494687
--- /dev/null
+++ b/files/auth/keydb.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Exam System SSH Key Storage
+After=network.target
+
+[Service]
+Type=simple
+User=auth_keydb
+WorkingDirectory=/srv/auth_keydb/
+ExecStart=/usr/bin/env python3 /srv/auth_keydb/src/keydb/keydb.py localhost 31337
+Restart=on-failure
+RestartSec=10
+
+# No limit. We won't overload the system anyway.
+StartLimitInterval=0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/files/auth/on_update.sh b/files/auth/on_update.sh
index 848eb18..cadcd6e 100644
--- a/files/auth/on_update.sh
+++ b/files/auth/on_update.sh
@@ -10,6 +10,7 @@ make
 
 cd
 mkdir -p bin/
+rm -f bin/auth
 cp src/auth/auth bin/
 EOF
 )
@@ -18,5 +19,5 @@ EOF
 sudo --user auth --group auth --set-home -- bash -c "$run_as_broker"
 
 # Then, we can restart the services.
-systemctl service restart aes_auth.service
+systemctl restart aes_auth.service
 
diff --git a/files/auth/on_update_keydb.sh b/files/auth/on_update_keydb.sh
new file mode 100644
index 0000000..3ed0354
--- /dev/null
+++ b/files/auth/on_update_keydb.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+systemctl restart aes_auth_keydb.service
+systemctl restart aes_temp_userdb.service
diff --git a/files/auth/temp_userdb.service b/files/auth/temp_userdb.service
new file mode 100644
index 0000000..d0c3df8
--- /dev/null
+++ b/files/auth/temp_userdb.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Exam System Temporary User Database
+After=network.target
+
+[Service]
+Type=simple
+User=auth_keydb
+WorkingDirectory=/srv/auth_keydb/
+ExecStart=/usr/bin/env python3 /srv/auth_keydb/src/temporary_userdb/userdb.py localhost 31337
+Restart=on-failure
+RestartSec=10
+
+# No limit. We won't overload the system anyway.
+StartLimitIntervalSec=0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/files/broker/broker.service b/files/broker/broker.service
index f4f902a..c8f80a8 100644
--- a/files/broker/broker.service
+++ b/files/broker/broker.service
@@ -11,7 +11,7 @@ Restart=on-failure
 RestartSec=10
 
 # No limit. We won't overload the system anyway.
-StartLimitIntervalSec=0
+StartLimitInterval=0
 
 [Install]
 WantedBy=multi-user.target
diff --git a/files/broker/on_update.sh b/files/broker/on_update.sh
index ec79273..9c16c68 100644
--- a/files/broker/on_update.sh
+++ b/files/broker/on_update.sh
@@ -10,6 +10,7 @@ make
 
 cd
 mkdir -p bin/
+rm -f bin/broker
 cp src/broker/broker bin/
 EOF
 )
@@ -18,5 +19,5 @@ EOF
 sudo --user broker --group broker --set-home -- bash -c "$run_as_broker"
 
 # Then, we can restart the services.
-systemctl service restart aes_broker.service
+systemctl restart aes_broker.service
 
diff --git a/manifests/auth.pp b/manifests/auth.pp
index b8a159a..1eebfba 100644
--- a/manifests/auth.pp
+++ b/manifests/auth.pp
@@ -12,16 +12,24 @@ class aes::auth {
     [
 	'krb5-libs',
 	'krb5-devel',
+	'openssl-devel',
     ]:
       ensure => installed,
   }
 
+  # Group for local authentication. All accounts that are members
+  # of this group are considered trusted by the authentication system.
+  group { "aes_local_auth" :
+    ensure => present
+  }
+
   user { "${auth_user}" :
     ensure => present,
     home => "${auth_home}",
     comment => 'Authentication server for AES',
     managehome => false,
     membership => inclusive,
+    groups => [ "aes_local_auth" ],
     system => true,
     shell => '/sbin/nologin',
   }
@@ -51,16 +59,16 @@ class aes::auth {
 
   file { "${auth_home}/config.json" :
     ensure => present,
-    owner  => auth,
-    group  => auth,
+    owner  => "${auth_user}",
+    group  => "${auth_group}",
     mode   => '0644',
     source => "puppet:///modules/${module_name}/auth/config.json",
   }
 
   file { "${auth_home}/start.sh" :
     ensure => present,
-    owner  => auth,
-    group  => auth,
+    owner  => "${auth_user}",
+    group  => "${auth_group}",
     mode   => '0755',
     source => "puppet:///modules/${module_name}/auth/start.sh",
   }
diff --git a/manifests/auth_keydb.pp b/manifests/auth_keydb.pp
new file mode 100644
index 0000000..559a87b
--- /dev/null
+++ b/manifests/auth_keydb.pp
@@ -0,0 +1,69 @@
+class aes::auth_keydb {
+
+  $keydb_user = auth_keydb
+  $keydb_group = "${keydb_user}"
+  $keydb_home = "/srv/${keydb_user}"
+  $keydb_service = "aes_auth_keydb"
+
+  user { "${keydb_user}" :
+    ensure => present,
+    home => "${keydb_home}",
+    comment => 'Authentication server for AES',
+    managehome => false,
+    membership => inclusive,
+    groups => [ "aes_local_auth" ],
+    system => true,
+    shell => '/sbin/nologin',
+  }
+
+  file { "${keydb_home}" :
+    ensure => directory,
+    owner => "${keydb_user}",
+    group => "${keydb_group}",
+    mode => '0755',
+  }
+
+  file { "/etc/systemd/system/${keydb_service}.service" :
+    ensure => present,
+    owner  => root,
+    group  => root,
+    mode   => '0644',
+    source => "puppet:///modules/${module_name}/auth/keydb.service",
+  }
+
+  file { "${keydb_home}/on_update.sh" :
+    ensure => present,
+    owner  => root,
+    group  => root,
+    mode   => '0700',
+    source => "puppet:///modules/${module_name}/auth/on_update_keydb.sh",
+  }
+
+  exec { 'update-keydb-repo' :
+    command => "/opt/utils/update_repo.sh ${keydb_home}/src https://oauth2:F-agHaRXCdyFy38q4c-N@gitlab.liu.se/upp-aes/communication.git production",
+    environment => [ "REPO_USER=${keydb_user}", "REPO_GROUP=${keydb_group}", "REPO_ON_UPDATE=${keydb_home}/on_update.sh" ],
+    # This command will need to run "on_update" as root in order to restart the service.
+    user => root,
+    group => root,
+    cwd => "${keydb_home}",
+    require => File["${keydb_home}/on_update.sh"],
+  }
+
+  service { "${keydb_service}" : 
+    ensure => "running",
+  }
+
+  # These are temporary until the AdmC database is up and running.
+
+  file { "/etc/systemd/system/aes_temp_userdb.service" :
+    ensure => present,
+    owner  => root,
+    group  => root,
+    mode   => '0644',
+    source => "puppet:///modules/${module_name}/auth/temp_userdb.service",
+  }
+
+  service { "aes_temp_userdb" :
+    ensure => "running",
+  }
+}
\ No newline at end of file
diff --git a/manifests/init.pp b/manifests/init.pp
index ae5f965..c6f128b 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -6,6 +6,7 @@ class aes {
   include aes::latex
   include aes::broker
   include aes::auth
+  include aes::auth_keydb
   include ::liurepo::centos_sclo_rh
 
   package {
-- 
GitLab