From 4f99de246c4430f891c45afc747c14b31dad0135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?darta=C2=B7?= Date: Thu, 1 Jul 2021 17:07:08 +0200 Subject: [PATCH] Fixes certificates endtime and adds scripts to update on client apps --- admin/src/generate_certificates.sh | 4 +- admin/src/nextcloud_saml_onlycerts.py | 122 ++++++++++++++++++++++++ admin/src/wordpress_saml_onlycerts.py | 129 ++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 admin/src/nextcloud_saml_onlycerts.py create mode 100644 admin/src/wordpress_saml_onlycerts.py diff --git a/admin/src/generate_certificates.sh b/admin/src/generate_certificates.sh index 4dac558..3e7a233 100755 --- a/admin/src/generate_certificates.sh +++ b/admin/src/generate_certificates.sh @@ -5,6 +5,6 @@ O=localdomain CN_CA=$O CN_HOST=*.$O OU=$O -openssl req -nodes -new -x509 -keyout private.key -out public.cert -subj "/C=$C/L=$L/O=$O/CN=$CN_CA" +openssl req -nodes -new -x509 -keyout private.key -out public.cert -subj "/C=$C/L=$L/O=$O/CN=$CN_CA" -days 3650 cd .. -echo "Now run the python nextcloud script" \ No newline at end of file +echo "Now run the python nextcloud and wordpress scripts" \ No newline at end of file diff --git a/admin/src/nextcloud_saml_onlycerts.py b/admin/src/nextcloud_saml_onlycerts.py new file mode 100644 index 0000000..5690039 --- /dev/null +++ b/admin/src/nextcloud_saml_onlycerts.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# coding=utf-8 +import time, os +from datetime import datetime, timedelta +import pprint + +import logging as log +import traceback +import yaml, json + +import psycopg2 + +from admin.lib.postgres import Postgres +from admin.lib.keycloak_client import KeycloakClient + +import string, random + +app={} +app['config']={} + +class NextcloudSaml(): + def __init__(self): + self.url="http://isard-sso-keycloak:8080/auth/" + self.username=os.environ['KEYCLOAK_USER'] + self.password=os.environ['KEYCLOAK_PASSWORD'] + self.realm='master' + self.verify=True + + ready=False + while not ready: + try: + self.pg=Postgres('isard-apps-postgresql','nextcloud',os.environ['NEXTCLOUD_POSTGRES_USER'],os.environ['NEXTCLOUD_POSTGRES_PASSWORD']) + ready=True + except: + log.warning('Could not connect to nextcloud database. Retrying...') + time.sleep(2) + log.info('Connected to nextcloud database.') + + ready=False + while not ready: + try: + with open(os.path.join("./saml_certs/public.cert"),"r") as crt: + app['config']['PUBLIC_CERT']=crt.read() + ready=True + except IOError: + log.warning('Could not get public certificate to be used in nextcloud. Retrying...') + log.warning(' You should generate them: /admin/saml_certs # openssl req -nodes -new -x509 -keyout private.key -out public.cert') + time.sleep(2) + except: + log.error(traceback.format_exc()) + log.info('Got moodle srt certificate to be used in nextcloud.') + + ready=False + while not ready: + try: + with open(os.path.join("./saml_certs/private.key"),"r") as pem: + app['config']['PRIVATE_KEY']=pem.read() + ready=True + except IOError: + log.warning('Could not get private key to be used in nextcloud. Retrying...') + log.warning(' You should generate them: /admin/saml_certs # openssl req -nodes -new -x509 -keyout private.key -out public.cert') + time.sleep(2) + log.info('Got moodle pem certificate to be used in nextcloud.') + + # ## This seems related to the fact that the certificate generated the first time does'nt work. + # ## And when regenerating the certificate de privatekeypass seems not to be used and instead it + # ## will use always this code as filename: 0f635d0e0f3874fff8b581c132e6c7a7 + # ## As this bug I'm not able to solve, the process is: + # ## 1.- Bring up moodle and regenerate certificates on saml2 plugin in plugins-authentication + # ## 2.- Execute this script + # ## 3.- Cleanup all caches in moodle (Development tab) + # # with open(os.path.join("./moodledata/saml2/"+os.environ['NEXTCLOUD_SAML_PRIVATEKEYPASS'].replace("moodle."+os.environ['DOMAIN'],'')+'.idp.xml'),"w") as xml: + # # xml.write(self.parse_idp_metadata()) + # with open(os.path.join("./moodledata/saml2/0f635d0e0f3874fff8b581c132e6c7a7.idp.xml"),"w") as xml: + # xml.write(self.parse_idp_metadata()) + + try: + self.reset_saml_certs() + except: + print('Error resetting saml on nextcloud') + + try: + self.set_nextcloud_saml_plugin_certs() + except: + log.error(traceback.format_exc()) + print('Error adding saml on nextcloud') + + def connect(self): + self.keycloak= KeycloakClient(url=self.url, + username=self.username, + password=self.password, + realm=self.realm, + verify=self.verify) + + # def activate_saml_plugin(self): + # ## After you need to purge moodle caches: /var/www/html # php admin/cli/purge_caches.php + # return self.pg.update("""UPDATE "mdl_config" SET value = 'email,saml2' WHERE "name" = 'auth'""") + + # def get_privatekey_pass(self): + # return self.pg.select("""SELECT * FROM "mdl_config" WHERE "name" = 'siteidentifier'""")[0][2] + + def parse_idp_cert(self): + self.connect() + rsa=self.keycloak.get_server_rsa_key() + self.keycloak=None + return rsa['certificate'] + + def set_nextcloud_saml_plugin_certs(self): + self.pg.update("""INSERT INTO "oc_appconfig" ("appid", "configkey", "configvalue") VALUES +('user_saml', 'sp-privateKey', '%s'), +('user_saml', 'idp-x509cert', '%s'), +('user_saml', 'sp-x509cert', '%s');""" % (app['config']['PRIVATE_KEY'],self.parse_idp_cert(),app['config']['PUBLIC_CERT'])) + + + def reset_saml_certs(self): + cfg_list=['sp-privateKey', + 'idp-x509cert', + 'sp-x509cert'] + for cfg in cfg_list: + self.pg.update("""DELETE FROM "oc_appconfig" WHERE appid = 'user_saml' AND configkey = '%s'""" % (cfg)) + +n=NextcloudSaml() \ No newline at end of file diff --git a/admin/src/wordpress_saml_onlycerts.py b/admin/src/wordpress_saml_onlycerts.py new file mode 100644 index 0000000..16cf35e --- /dev/null +++ b/admin/src/wordpress_saml_onlycerts.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# coding=utf-8 +import time, os +from datetime import datetime, timedelta +import pprint + +import logging as log +import traceback +import yaml, json + +import psycopg2 + +from admin.lib.mysql import Mysql +from admin.lib.keycloak_client import KeycloakClient + +import string, random + +app={} +app['config']={} + +class WordpressSaml(): + def __init__(self): + self.url="http://isard-sso-keycloak:8080/auth/" + self.username=os.environ['KEYCLOAK_USER'] + self.password=os.environ['KEYCLOAK_PASSWORD'] + self.realm='master' + self.verify=True + + ready=False + while not ready: + try: + self.db=Mysql('isard-apps-mariadb','wordpress','root',os.environ['MARIADB_PASSWORD']) + ready=True + except: + log.warning('Could not connect to wordpress database. Retrying...') + time.sleep(2) + log.info('Connected to wordpress database.') + + ready=False + while not ready: + try: + with open(os.path.join("./saml_certs/public.cert"),"r") as crt: + app['config']['PUBLIC_CERT_RAW']=crt.read() + app['config']['PUBLIC_CERT']=self.cert_prepare(app['config']['PUBLIC_CERT_RAW']) + ready=True + except IOError: + log.warning('Could not get public certificate to be used in wordpress. Retrying...') + log.warning(' You should generate them: /admin/saml_certs # openssl req -nodes -new -x509 -keyout private.key -out public.cert') + time.sleep(2) + except: + log.error(traceback.format_exc()) + log.info('Got moodle srt certificate to be used in wordpress.') + + ready=False + while not ready: + try: + with open(os.path.join("./saml_certs/private.key"),"r") as pem: + app['config']['PRIVATE_KEY']=self.cert_prepare(pem.read()) + ready=True + except IOError: + log.warning('Could not get private key to be used in wordpress. Retrying...') + log.warning(' You should generate them: /admin/saml_certs # openssl req -nodes -new -x509 -keyout private.key -out public.cert') + time.sleep(2) + log.info('Got moodle pem certificate to be used in wordpress.') + + # ## This seems related to the fact that the certificate generated the first time does'nt work. + # ## And when regenerating the certificate de privatekeypass seems not to be used and instead it + # ## will use always this code as filename: 0f635d0e0f3874fff8b581c132e6c7a7 + # ## As this bug I'm not able to solve, the process is: + # ## 1.- Bring up moodle and regenerate certificates on saml2 plugin in plugins-authentication + # ## 2.- Execute this script + # ## 3.- Cleanup all caches in moodle (Development tab) + # # with open(os.path.join("./moodledata/saml2/"+os.environ['NEXTCLOUD_SAML_PRIVATEKEYPASS'].replace("moodle."+os.environ['DOMAIN'],'')+'.idp.xml'),"w") as xml: + # # xml.write(self.parse_idp_metadata()) + # with open(os.path.join("./moodledata/saml2/0f635d0e0f3874fff8b581c132e6c7a7.idp.xml"),"w") as xml: + # xml.write(self.parse_idp_metadata()) + + try: + self.reset_saml_certs() + except: + print(traceback.format_exc()) + print('Error resetting saml certs on wordpress') + + try: + self.set_wordpress_saml_plugin_certs() + except: + print(traceback.format_exc()) + print('Error adding saml on wordpress') + + # SAML clients don't work well with composite roles so disabling and adding on realm + # self.add_client_roles() + + # def activate_saml_plugin(self): + # ## After you need to purge moodle caches: /var/www/html # php admin/cli/purge_caches.php + # return self.db.update("""UPDATE "mdl_config" SET value = 'email,saml2' WHERE "name" = 'auth'""") + + # def get_privatekey_pass(self): + # return self.db.select("""SELECT * FROM "mdl_config" WHERE "name" = 'siteidentifier'""")[0][2] + + def connect(self): + self.keycloak= KeycloakClient(url=self.url, + username=self.username, + password=self.password, + realm=self.realm, + verify=self.verify) + + def cert_prepare(self,cert): + return ''.join(cert.split('-----')[2].splitlines()) + + def parse_idp_cert(self): + self.connect() + rsa=self.keycloak.get_server_rsa_key() + self.keycloak=None + return rsa['certificate'] + + def set_wordpress_saml_plugin_certs(self): + # ('active_plugins', 'a:2:{i:0;s:33:\"edwiser-bridge/edwiser-bridge.php\";i:1;s:17:\"onelogin_saml.php\";}', 'yes'), + self.db.update("""INSERT INTO wp_options (option_name, option_value, autoload) VALUES +('onelogin_saml_idp_x509cert', '%s', 'yes'), +('onelogin_saml_advanced_settings_sp_x509cert', '%s', 'yes'), +('onelogin_saml_advanced_settings_sp_privatekey', '%s', 'yes');""" % (self.parse_idp_cert(),app['config']['PUBLIC_CERT'],app['config']['PRIVATE_KEY'])) + + + def reset_saml_certs(self): + self.db.update("""DELETE FROM wp_options WHERE option_name == 'onelogin_saml_idp_x509cert'""") + self.db.update("""DELETE FROM wp_options WHERE option_name == 'onelogin_saml_advanced_settings_sp_x509cert'""") + self.db.update("""DELETE FROM wp_options WHERE option_name == 'onelogin_saml_advanced_settings_sp_privatekey'""") + +nw=WordpressSaml() \ No newline at end of file