From 62b5868e1e864a000be210d250602d43a2719b51 Mon Sep 17 00:00:00 2001 From: Mustafa Baser Date: Mon, 30 May 2022 16:25:37 +0300 Subject: [PATCH] feat: jans linux setup openbanking CLI and certificate automation (#1472) * fix: jans-linux-setup openbanking CLI fixes * fix: jans-linux-setup openbanking attribute,grant-types * fix: jans-cli jans-linux-setup fixes for openbanking * fix: jans-linux-setup ob fixes * fix: jans-linux-setup move ob test key to static folder * feat: jans-linux-setup ob MTLS configuration * feat: jans-linux-setup download ob cert from jwksUri * feat: jans-linux-setup log downloading cert * fix: jans-linux-setup code smells --- jans-linux-setup/jans_setup/install.py | 3 + jans-linux-setup/jans_setup/jans_setup.py | 9 +- .../jans_setup/openbanking/.borrows | 1 + .../openbanking/static/ob-gluu-test.key | 28 +++++ .../templates/apache/https_jans.conf | 64 ++++++++-- .../openbanking/templates/attributes.ldif | 21 ++++ .../templates/jans-auth/jans-auth-config.json | 7 +- .../openbanking/templates/scopes.ldif | 60 +++++++++ .../openbanking/templates/scripts.ldif | 15 ++- .../jans_setup/setup_app/config.py | 10 +- .../jans_setup/setup_app/installers/httpd.py | 24 +++- .../setup_app/installers/jans_auth.py | 41 ++++--- .../jans_setup/setup_app/setup_options.py | 16 ++- .../jans_setup/setup_app/static.py | 5 + .../jans_setup/setup_app/utils/arg_parser.py | 10 +- .../setup_app/utils/collect_properties.py | 16 +-- .../jans_setup/setup_app/utils/crypto64.py | 116 ++++++++++++++---- .../setup_app/utils/properties_utils.py | 39 +++--- .../templates/jans-cli/.#client.ldif | 1 + 19 files changed, 379 insertions(+), 107 deletions(-) create mode 100644 jans-linux-setup/jans_setup/openbanking/.borrows create mode 100644 jans-linux-setup/jans_setup/openbanking/static/ob-gluu-test.key create mode 120000 jans-linux-setup/jans_setup/templates/jans-cli/.#client.ldif diff --git a/jans-linux-setup/jans_setup/install.py b/jans-linux-setup/jans_setup/install.py index 420afa2f9ee..7939efe58ea 100755 --- a/jans-linux-setup/jans_setup/install.py +++ b/jans-linux-setup/jans_setup/install.py @@ -88,6 +88,7 @@ def check_installation(): def profile_setup(): print("Preparing Setup for profile {}".format(argsp.profile)) + profile_dir = os.path.join(argsp.setup_dir, argsp.profile) replace_dirs = [] if not os.path.exists(profile_dir): @@ -123,6 +124,8 @@ def profile_setup(): print("Copying", source_file, target_dir) shutil.copy(source_file, target_dir) + + def extract_setup(): if os.path.exists(argsp.setup_dir): shutil.move(argsp.setup_dir, argsp.setup_dir + bacup_ext) diff --git a/jans-linux-setup/jans_setup/jans_setup.py b/jans-linux-setup/jans_setup/jans_setup.py index c1eef1352c4..9ff583cac0c 100755 --- a/jans-linux-setup/jans_setup/jans_setup.py +++ b/jans-linux-setup/jans_setup/jans_setup.py @@ -351,7 +351,6 @@ def do_installation(): Config.ldapTrustStoreFn = Config.opendj_p12_fn Config.encoded_ldapTrustStorePass = Config.encoded_opendj_p12_pass - jansInstaller.prepare_base64_extension_scripts() jansInstaller.render_templates() jansInstaller.render_configuration_template() @@ -446,7 +445,13 @@ def do_installation(): if Config.install_config_api or Config.install_scim_server: msg.installation_completed += "CLI available to manage Jannsen Server:\n" if Config.install_config_api: - msg.installation_completed += "/opt/jans/jans-cli/config-cli.py\n" + msg.installation_completed += "/opt/jans/jans-cli/config-cli.py" + if base.current_app.profile == static.SetupProfiles.OPENBANKING: + ca_dir = os.path.join(Config.output_dir, 'CA') + crt_fn = os.path.join(ca_dir, 'client.crt') + key_fn = os.path.join(ca_dir, 'client.key') + msg.installation_completed += ' -CC {} -CK {}'.format(crt_fn, key_fn) + msg.installation_completed +="\n" if Config.profile == 'jans' and Config.install_scim_server: msg.installation_completed += "/opt/jans/jans-cli/scim-cli.py" diff --git a/jans-linux-setup/jans_setup/openbanking/.borrows b/jans-linux-setup/jans_setup/openbanking/.borrows new file mode 100644 index 00000000000..075fc7c6fe0 --- /dev/null +++ b/jans-linux-setup/jans_setup/openbanking/.borrows @@ -0,0 +1 @@ +jans_setup/static/extension/introspection/introspection_role_based_scope.py \ No newline at end of file diff --git a/jans-linux-setup/jans_setup/openbanking/static/ob-gluu-test.key b/jans-linux-setup/jans_setup/openbanking/static/ob-gluu-test.key new file mode 100644 index 00000000000..135ec1b27ba --- /dev/null +++ b/jans-linux-setup/jans_setup/openbanking/static/ob-gluu-test.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdTYepO49LgdCs +iunlHlFjInS/uODFX+rW3N+XNNpyAGFL5/rwvUqoJkMnfo28WTGLYHKTw3u2A8qB +6bd8OaWJM/ztw/Eu7o+JCeNN9ldJyKkqkzCz13psxJCiKpygrZLyzn1NyNsFGIKl +V7GIUZg6mK8LwxuIEiEfqKvGNiu9iy33pcSvAVQAZR+J75FVC8hXQcnZkXO2srah +Rm1+rdvE9C5gbDfkcRvzE+Rdmhe9Er43hpckxWcnHGffaP4hRy8Y3dhRFRCHKKn3 +MjOEsZzUrFRwjAReuRJo6AZ2Mq+j/OEEYWvGci01jdPVdP7TdASoWZXP+BF66VeK +MO1ilPSXAgMBAAECggEAAcy9Hx4RKyYpQDgh/0mZWR7aosZCPW/grM7/zefrEeqC +3SP31ouhOuBJMhP8GioTwN+nH/KuISx/mNHsPq3IK5Qz3M06SV+ttmiDDcV3molY +X3t/T1Iep/eYcgqLxTjchA5XF63od5v1WV/x+43MxerbodunHnzv8mqdyy7xJteC +umAlhE+UpKEfS+sVDjzd+lwswx9OPCLZzOxAVEgYiZikXcRCR1liaZKW1dY4jzjD +a+T2og85fpUZklIdQ2xmWjLN8d15bpatKAu5+Ijoq7LSCyNVroXuNqjsKW2zVyu7 +DQJRFEQ7EAmv1SxpJhMaLjNV/ou8VClXTZOhJv6IcQKBgQDKKFWtzBWOU3b4xdP9 +8DLKgHDVNVUNJFufiXOm8aiPl9b7J7D0A0rCWbmYHsPERfhFA9/dPY0qTVL+gzGA +V/p0gvMmnEIOFw48n1kIfnCt0bE8Ms8HPdcJ+y064nhm491Krao+ZEvSfJezREkM +J+vVeo8Nyu1szG7mU1ypf7lC0QKBgQDHMuBfG+ctyl8gUoRIkq4Dn1eK/N2JpJOK +kRAWFoU3kbYqCOQ4Ac//e07kXldqBJBwNuCHXehxfl7lbsKWPbiw0mgOZd9emM7H +OobwjeQdLdSpEdoR8i9zts08PG5JIsQvQ96UdecU0AkBfVf+VwEgc6ke2WBhO0Bq +L71QBVWK5wKBgQCjKvUkx2Hqs8GGQB7AizxjqFHqNRbF+b+eQFJBwDHeXJ8frsSr +33Ba+BLODp7Sb+tYwSzSpNio+Spw1TGCNwCnQ/6//kVum/tYwQEa0vtdwK++OABU +BvznSH4UVjD6UxcNLKkJnOh6JyhGgGo5TouSjk6iwlTqiQNGEqjrAnVk0QKBgQCI +naD6ObXUVs3k6hLlfwuvWlH89a2un9u8lf61V16oHNwVeiGjM8MGUfhqcTV8dYLm +IwzcahBn/iZxLgRwbAZF5xgMf9uxEhYG12ICix3e0TbfeWnZEwNuVfnuDPgKWri4 +PdDievYv9PmoNuHpgpw4OHrNuIH8TVnBOdqZjf78EwKBgEHgsp4OLISHMOhSek/j +wK2bYLCJ2gDveyF03VUCIMHOKjLGxB+RdjRTaL9D0cxQa2MLMyDwox2+S7AHNDpN +KViApNjCjWzq6OKcwq98mMlSelWrjZPB2j3hXEvrEoI6+1Li0fIYRMP0m6wKUfiZ +gOmC/q0WZPsS6s0r3U0hQqa1 +-----END PRIVATE KEY----- diff --git a/jans-linux-setup/jans_setup/openbanking/templates/apache/https_jans.conf b/jans-linux-setup/jans_setup/openbanking/templates/apache/https_jans.conf index 0eaea6a085e..6c1b9ed6be0 100644 --- a/jans-linux-setup/jans_setup/openbanking/templates/apache/https_jans.conf +++ b/jans-linux-setup/jans_setup/openbanking/templates/apache/https_jans.conf @@ -1,16 +1,16 @@ - ServerName bank.gluu.org - Redirect / https://bank.gluu.org/ + ServerName %(hostname)s + Redirect / https://%(hostname)s/ DocumentRoot "/var/www/html/" RewriteEngine on - RewriteCond %{SERVER_NAME} =bank.gluu.org + RewriteCond %{SERVER_NAME} =%(hostname)s RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] DocumentRoot "/var/www/html/" - ServerName bank.gluu.org:443 + ServerName %(hostname)s:443 SSLOptions +StdEnvVars @@ -26,15 +26,15 @@ SSLProtocol -all +TLSv1.2 SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256 SSLHonorCipherOrder On - SSLCertificateFile /etc/certs/httpd.crt - SSLCertificateKeyFile /etc/certs/httpd.key + SSLCertificateFile /etc/certs/ob/server.crt + SSLCertificateKeyFile /etc/certs/ob/server.key - #SSLCertificateFile /etc/letsencrypt/live/bank.gluu.org/fullchain.pem - #SSLCertificateKeyFile /etc/letsencrypt/live/bank.gluu.org/privkey.pem + #SSLCertificateFile /etc/letsencrypt/live/%(hostname)s/fullchain.pem + #SSLCertificateKeyFile /etc/letsencrypt/live/%(hostname)s/privkey.pem #Include /etc/letsencrypt/options-ssl-apache.conf #following lines for OB trusted certs and revoked certs - #SSLCACertificateFile /etc/apache2/certs/matls.pem + SSLCACertificateFile /etc/certs/ob/ca.crt #SSLCARevocationFile revoked.pem #SSLCARevocationCheck chain no_crl_for_cert_ok #SSLCARevocationPath /etc/apache2/certs/revoke/ @@ -49,7 +49,7 @@ # Header always append X-Frame-Options SAMEORIGIN Header always set X-Xss-Protection "1; mode=block" Header always set X-Content-Type-Options nosniff - # Header always set Content-Security-Policy "default-src 'self' 'unsafe-inline' https://bank.gluu.org" + # Header always set Content-Security-Policy "default-src 'self' 'unsafe-inline' https://%(hostname)s" Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" Header edit Set-Cookie ^((?!opbs|session_state).*)$ $1;HttpOnly @@ -143,8 +143,6 @@ Allow from all - - SSLVerifyClient require SSLVerifyDepth 10 @@ -161,6 +159,48 @@ Allow from all + + ProxyPass http://localhost:8081/jans-auth/restv1/device_authorization + Order deny,allow + Allow from all + + + + ProxyPass http://localhost:8081/jans-auth/device_authorization.htm + Order deny,allow + Allow from all + + + + ProxyPass http://localhost:8081/jans-auth/js + Order deny,allow + Allow from all + + + + ProxyPass http://localhost:8081/jans-auth/stylesheet + Order deny,allow + Allow from all + + + + ProxyPass http://localhost:8081/jans-auth/servlet + Order deny,allow + Allow from all + + + + ProxyPass http://localhost:8081/jans-auth/restv1/userinfo + Order deny,allow + Allow from all + + + + ProxyPass http://localhost:8081/jans-auth/jakarta.faces.resource + Order deny,allow + Allow from all + + SSLVerifyClient optional_no_ca SSLVerifyDepth 10 diff --git a/jans-linux-setup/jans_setup/openbanking/templates/attributes.ldif b/jans-linux-setup/jans_setup/openbanking/templates/attributes.ldif index ecdbbb185e2..02155068af0 100644 --- a/jans-linux-setup/jans_setup/openbanking/templates/attributes.ldif +++ b/jans-linux-setup/jans_setup/openbanking/templates/attributes.ldif @@ -1253,3 +1253,24 @@ objectClass: top objectClass: jansAttr urn: urn:mace:dir:attribute-def:jansBackchannelUsrCode +dn: inum=4CF1,ou=attributes,o=jans +description: jansAdminUIRole +displayName: jansAdminUIRole +inum: 4CF1 +jansAttrEditTyp: admin +jansAttrEditTyp: user +jansAttrName: jansAdminUIRole +jansAttrOrigin: jansCustomPerson +jansAttrSystemEditTyp: admin +jansAttrSystemEditTyp: user +jansAttrTyp: string +jansAttrViewTyp: admin +jansAttrViewTyp: user +jansClaimName: jansAdminUIRole +jansMultivaluedAttr: true +jansSAML1URI: urn:mace:dir:attribute-def:jansAdminUIRole +jansSAML2URI: urn:mace:dir:attribute-def:jansAdminUIRole +jansStatus: active +objectClass: top +objectClass: jansAttr +urn: sampleurn diff --git a/jans-linux-setup/jans_setup/openbanking/templates/jans-auth/jans-auth-config.json b/jans-linux-setup/jans_setup/openbanking/templates/jans-auth/jans-auth-config.json index 7608c50e8ed..49658bf698a 100644 --- a/jans-linux-setup/jans_setup/openbanking/templates/jans-auth/jans-auth-config.json +++ b/jans-linux-setup/jans_setup/openbanking/templates/jans-auth/jans-auth-config.json @@ -8,7 +8,7 @@ "clientInfoEndpoint":"https://%(hostname)s/jans-auth/restv1/clientinfo", "checkSessionIFrame":"https://%(hostname)s/jans-auth/opiframe.htm", "endSessionEndpoint":"https://%(hostname)s/jans-auth/restv1/end_session", - "jwksUri":"%(jwksUri)s", + "jwksUri":"%(jwks_uri)s", "registrationEndpoint":"https://%(hostname)s/jans-auth/restv1/register", "openIdDiscoveryEndpoint":"https://%(hostname)s/.well-known/webfinger", "openIdConfigurationEndpoint":"https://%(hostname)s/.well-known/openid-configuration", @@ -67,7 +67,8 @@ "grantTypesSupported":[ "client_credentials", "authorization_code", - "refresh_token" + "refresh_token", + "urn:ietf:params:oauth:grant-type:device_code" ], "allowIdTokenWithoutImplicitGrantType": true, "subjectTypesSupported":[ @@ -359,7 +360,7 @@ "deviceAuthzRequestExpiresIn": 1800, "deviceAuthzTokenPollInterval": 5, "deviceAuthzResponseTypeToProcessAuthz": "code", - "staticKid": "%(staticKid)s", + "staticKid": "%(static_kid)s", "forceOfflineAccessScopeToEnableRefreshToken" : false, "redirectUrisRegexEnabled": false, "useHighestLevelScriptIfAcrScriptNotFound": true diff --git a/jans-linux-setup/jans_setup/openbanking/templates/scopes.ldif b/jans-linux-setup/jans_setup/openbanking/templates/scopes.ldif index 4164ac448ed..bb91475a55c 100644 --- a/jans-linux-setup/jans_setup/openbanking/templates/scopes.ldif +++ b/jans-linux-setup/jans_setup/openbanking/templates/scopes.ldif @@ -42,3 +42,63 @@ jansScopeTyp: openid objectClass: top objectClass: jansScope +dn: inum=C4F7,ou=scopes,o=jans +jansId: jans_stat +inum: C4F7 +description: This scope is required for calling Statistic Endpoint +jansDefScope: false +jansAttrs: {"spontaneousClientId":"","spontaneousClientScopes":[],"showInConfigurationEndpoint":false} +jansScopeTyp: openid +objectClass: top +objectClass: jansScope + +dn: inum=C4F6,ou=scopes,o=jans +description: This scope value requests that an OAuth 2.0 Refresh Token be issued. +displayName: refresh_token +inum: C4F6 +jansAttrs: {"spontaneousClientId":"","spontaneousClientScopes":[],"showInConfigurationEndpoint":true} +jansDefScope: true +jansId: offline_access +jansScopeTyp: openid +objectClass: top +objectClass: jansScope + +dn: inum=43F1,ou=scopes,o=jans +description: View your basic profile info. +displayName: view_profile +inum: 43F1 +jansAttrs: {"spontaneousClientId":"","spontaneousClientScopes":[],"showInConfigurationEndpoint":true} +jansClaim: inum=2B29,ou=attributes,o=jans +jansClaim: inum=0C85,ou=attributes,o=jans +jansClaim: inum=B4B0,ou=attributes,o=jans +jansClaim: inum=A0E8,ou=attributes,o=jans +jansClaim: inum=5EC6,ou=attributes,o=jans +jansClaim: inum=B52A,ou=attributes,o=jans +jansClaim: inum=64A0,ou=attributes,o=jans +jansClaim: inum=EC3A,ou=attributes,o=jans +jansClaim: inum=3B47,ou=attributes,o=jans +jansClaim: inum=3692,ou=attributes,o=jans +jansClaim: inum=98FC,ou=attributes,o=jans +jansClaim: inum=A901,ou=attributes,o=jans +jansClaim: inum=36D9,ou=attributes,o=jans +jansClaim: inum=BE64,ou=attributes,o=jans +jansClaim: inum=6493,ou=attributes,o=jans +jansClaim: inum=4CF1,ou=attributes,o=jans +jansDefScope: false +jansId: profile +jansScopeTyp: openid +objectClass: top +objectClass: jansScope + +dn: inum=764C,ou=scopes,o=jans +description: View your email address. +displayName: view_email_address +inum: 764C +jansAttrs: {"spontaneousClientId":"","spontaneousClientScopes":[],"showInConfigurationEndpoint":true} +jansClaim: inum=8F88,ou=attributes,o=jans +jansClaim: inum=CAE3,ou=attributes,o=jans +jansDefScope: false +jansId: email +jansScopeTyp: openid +objectClass: top +objectClass: jansScope diff --git a/jans-linux-setup/jans_setup/openbanking/templates/scripts.ldif b/jans-linux-setup/jans_setup/openbanking/templates/scripts.ldif index 72b68cd0a72..96c9d1bd3a6 100644 --- a/jans-linux-setup/jans_setup/openbanking/templates/scripts.ldif +++ b/jans-linux-setup/jans_setup/openbanking/templates/scripts.ldif @@ -4,7 +4,7 @@ displayName: urn:openbanking:psd2:sca inum: A51E-76DA jansConfProperty: {"value1":"redirect_url","value2":"https://bank-op.gluu.org/oxauth/authorize.htm?scope=openid+profile+email+user_name&acr_values=basic&response_type=code&redirect_uri=https%3A%2F%2Fbank.gluu.org%2Fjans-auth%2Fpostlogin.htm&nonce=72fc1a52-25a7-4293-929d-b61b8a05c9c4&client_id=0c76f3bb-b6de-49c4-8dff-f53d7b768f96 ","description":""} jansConfProperty: {"value1":"tpp_jwks_url","value2":"https://keystore.openbankingtest.org.uk/0014H00001lFE7dQAG/0014H00001lFE7dQAG.jwks","description":""} -jansEnabled: 1 +jansEnabled: %(enable_ob_auth_script)s jansLevel: 10 jansModuleProperty: {"value1":"usage_type","value2":"interactive","description":""} jansModuleProperty: {"value1":"location_type","value2":"ldap","description":""} @@ -72,3 +72,16 @@ jansScrTyp: introspection objectClass: top objectClass: jansCustomScr +dn: inum=A44E-4F3D,ou=scripts,o=jans +objectClass: top +objectClass: jansCustomScr +description: Role Based Scopes +displayName: role_based_scopes +inum: A44E-4F3D +jansEnabled: true +jansLevel: 1 +jansModuleProperty: {"value1":"location_type","value2":"ldap","description":""} +jansProgLng: python +jansRevision: 1 +jansScr::%(introspection_introspection_role_based_scope)s +jansScrTyp: introspection diff --git a/jans-linux-setup/jans_setup/setup_app/config.py b/jans-linux-setup/jans_setup/setup_app/config.py index b0928b9e69c..f5f07e0b01b 100644 --- a/jans-linux-setup/jans_setup/setup_app/config.py +++ b/jans-linux-setup/jans_setup/setup_app/config.py @@ -139,9 +139,11 @@ def progress(self, service_name, msg, incr=False): if self.profile == OPENBANKING_PROFILE: self.use_external_key = True - self.ob_key_fn = '/root/obsigning-axV5umCvTMBMjPwjFQgEvb_NO_UPLOAD.key' - self.ob_cert_fn = '/root/obsigning.pem' - self.ob_alias = 'GkwIzWy88xWSlcWnLiEc8ip9s2M' + self.ob_key_fn = '' + self.ob_cert_fn = '' + self.ob_alias = '' + self.static_kid = '' + self.jwks_uri = '' # Component ithversions self.apache_version = None @@ -398,7 +400,7 @@ def progress(self, service_name, msg, incr=False): if self.profile == OPENBANKING_PROFILE: #default locations are rdbm - self.mapping_locations = {'default': 'rdbm'} + self.mapping_locations = { group: 'rdbm' for group in self.couchbaseBucketDict } else: #default locations are OpenDJ self.mapping_locations = { group: 'ldap' for group in self.couchbaseBucketDict } diff --git a/jans-linux-setup/jans_setup/setup_app/installers/httpd.py b/jans-linux-setup/jans_setup/setup_app/installers/httpd.py index ecf63b9de5d..b4cc062c189 100644 --- a/jans-linux-setup/jans_setup/setup_app/installers/httpd.py +++ b/jans-linux-setup/jans_setup/setup_app/installers/httpd.py @@ -4,7 +4,7 @@ from setup_app import paths from setup_app.utils import base -from setup_app.static import AppType, InstallOption +from setup_app.static import AppType, InstallOption, SetupProfiles from setup_app.config import Config from setup_app.utils.setup_utils import SetupUtils from setup_app.installers.base import BaseInstaller @@ -162,8 +162,11 @@ def configure(self): Config.httpdKeyPass = self.getPW() - # generate httpd self signed certificate - self.gen_cert('httpd', Config.httpdKeyPass, 'jetty') + if Config.profile == SetupProfiles.OPENBANKING: + self.ob_mtls_config() + else: + # generate httpd self signed certificate + self.gen_cert('httpd', Config.httpdKeyPass, 'jetty') self.enable() self.start() @@ -190,5 +193,20 @@ def write_httpd_config(self): self.run([paths.cmd_ln, '-s', self.https_jans_fn, '/etc/apache2/sites-enabled/https_jans.conf']) + def ob_mtls_config(self): + + ca_key_fn, ca_crt_fn = self.gen_ca() + server_key_fn, server_csr_fn, server_crt_fn = self.gen_key_cert_from_ca(fn_suffix='server') + ob_certs_dir = os.path.join(Config.certFolder, 'ob') + self.run([paths.cmd_mkdir, '-p', ob_certs_dir]) + self.copyFile(ca_crt_fn, ob_certs_dir) + self.copyFile(server_key_fn, ob_certs_dir) + self.copyFile(server_crt_fn, ob_certs_dir) + + # create client cert + cn = 'cli.' + Config.hostname + self.gen_key_cert_from_ca(fn_suffix='client', cn=cn) + + def installed(self): return os.path.exists(self.https_jans_fn) diff --git a/jans-linux-setup/jans_setup/setup_app/installers/jans_auth.py b/jans-linux-setup/jans_setup/setup_app/installers/jans_auth.py index c40682f2e66..aec8d2fdb96 100644 --- a/jans-linux-setup/jans_setup/setup_app/installers/jans_auth.py +++ b/jans-linux-setup/jans_setup/setup_app/installers/jans_auth.py @@ -13,7 +13,7 @@ from setup_app.utils import base from setup_app.config import Config from setup_app.installers.jetty import JettyInstaller -from setup_app.static import AppType, InstallOption +from setup_app.static import AppType, InstallOption, SetupProfiles class JansAuthInstaller(JettyInstaller): @@ -43,8 +43,9 @@ def __init__(self): self.ldif_people = os.path.join(self.output_folder, 'people.ldif') self.ldif_groups = os.path.join(self.output_folder, 'groups.ldif') - if Config.profile == 'openbanking': - Config.jwksUri = base.argsp.jwks_uri + if Config.profile == SetupProfiles.OPENBANKING: + Config.enable_ob_auth_script = '0' if base.argsp.disable_ob_auth_script else '1' + Config.jwks_uri = base.argsp.jwks_uri def install(self): self.logIt("Copying auth.war into jetty webapps folder...") @@ -63,8 +64,7 @@ def generate_configuration(self): if not Config.get('admin_inum'): Config.admin_inum = str(uuid.uuid4()) - if Config.profile == 'jans': - Config.encoded_admin_password = self.ldap_encode(Config.admin_password) + Config.encoded_admin_password = self.ldap_encode(Config.admin_password) self.logIt("Generating OAuth openid keys", pbar=self.service_name) sig_keys = 'RS256 RS384 RS512 ES256 ES256K ES384 ES512 PS256 PS384 PS512' @@ -114,13 +114,20 @@ def render_import_templates(self): Config.templateRenderingDict['person_custom_object_class_list'] = '[]' if Config.mapping_locations['default'] == 'rdbm' else '["jansCustomPerson", "jansPerson"]' - templates = [self.oxauth_config_json] - if Config.profile == 'jans': - templates += [self.ldif_people, self.ldif_groups] + templates = [self.oxauth_config_json, self.ldif_people, self.ldif_groups] for tmp in templates: self.renderTemplateInOut(tmp, self.templates_folder, self.output_folder) + if Config.profile == SetupProfiles.OPENBANKING: + base.extract_file( + base.current_app.jans_zip, + 'jans-linux-setup/jans_setup/static/extension/introspection/introspection_role_based_scope.py', + os.path.join(Config.extensionFolder, 'introspection/') + ) + + self.prepare_base64_extension_scripts() + Config.templateRenderingDict['oxauth_config_base64'] = self.generate_base64_ldap_file(self.oxauth_config_json) Config.templateRenderingDict['oxauth_static_conf_base64'] = self.generate_base64_ldap_file(self.oxauth_static_conf_json) Config.templateRenderingDict['oxauth_error_base64'] = self.generate_base64_ldap_file(self.oxauth_error_json) @@ -131,16 +138,16 @@ def render_import_templates(self): for temp in (self.ldif_config, self.ldif_role_scope_mappings): self.renderTemplateInOut(temp, self.templates_folder, self.output_folder) - self.dbUtils.import_ldif([self.ldif_config, self.ldif_scripts, self.ldif_role_scope_mappings]) - if Config.profile == 'jans': - self.dbUtils.import_ldif([self.ldif_people, self.ldif_groups]) - if Config.profile == 'openbanking': + self.dbUtils.import_ldif([self.ldif_config, self.ldif_scripts, self.ldif_role_scope_mappings, self.ldif_people, self.ldif_groups]) + + if Config.profile == SetupProfiles.OPENBANKING: self.import_openbanking_certificate() def genRandomString(self, N): return ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for _ in range(N)) + def make_salt(self, enforce=False): if not Config.get('pairwiseCalculationKey') or enforce: Config.pairwiseCalculationKey = self.genRandomString(random.randint(20,30)) @@ -157,8 +164,8 @@ def copy_static(self): def import_openbanking_certificate(self): self.logIt("Importing openbanking ssl certificate") oxauth_config_json = base.readJsonFile(self.oxauth_config_json) - jwksUri = oxauth_config_json['jwksUri'] - o = urlparse(jwksUri) + jwks_uri = oxauth_config_json['jwksUri'] + o = urlparse(jwks_uri) jwks_addr = o.netloc open_banking_cert = self.get_server_certificate(jwks_addr) alias = jwks_addr.replace('.', '_') @@ -172,6 +179,8 @@ def import_openbanking_certificate(self): def import_openbanking_key(self): - if os.path.isfile(Config.ob_key_fn) and os.path.isfile(Config.ob_cert_fn): - self.gen_keystore('obsigning', self.oxauth_openid_jks_fn, Config.oxauth_openid_jks_pass, Config.ob_key_fn, Config.ob_cert_fn, Config.ob_alias) + if not os.path.isfile(Config.ob_cert_fn): + self.download_ob_cert(Config.ob_cert_fn) + if os.path.isfile(Config.ob_key_fn) and os.path.isfile(Config.ob_cert_fn): + self.import_key_cert_into_keystore('obsigning', self.oxauth_openid_jks_fn, Config.oxauth_openid_jks_pass, Config.ob_key_fn, Config.ob_cert_fn, Config.ob_alias) diff --git a/jans-linux-setup/jans_setup/setup_app/setup_options.py b/jans-linux-setup/jans_setup/setup_app/setup_options.py index 33599e14313..1c6c1e36232 100644 --- a/jans-linux-setup/jans_setup/setup_app/setup_options.py +++ b/jans-linux-setup/jans_setup/setup_app/setup_options.py @@ -2,7 +2,7 @@ import sys import argparse -from setup_app.static import InstallTypes +from setup_app.static import InstallTypes, SetupProfiles from setup_app.utils import base def get_setup_options(): @@ -146,10 +146,18 @@ def get_setup_options(): setupOptions['properties_password'] = base.argsp.properties_password - if base.current_app.profile == 'openbanking': + if base.current_app.profile == SetupProfiles.OPENBANKING: setupOptions['opendj_install'] = InstallTypes.NONE - if base.argsp.static_kid: - setupOptions['staticKid'] = base.argsp.static_kid + setupOptions['static_kid'] = base.argsp.static_kid + setupOptions['ob_key_fn'] = base.argsp.ob_key_fn + setupOptions['ob_cert_fn'] = base.argsp.ob_cert_fn + setupOptions['ob_alias'] = base.argsp.ob_alias + setupOptions['jwks_uri'] = base.argsp.jwks_uri + + if base.argsp.no_external_key: + setupOptions['use_external_key'] = False + + if base.argsp.ip_address: setupOptions['ip'] = base.argsp.ip_address diff --git a/jans-linux-setup/jans_setup/setup_app/static.py b/jans-linux-setup/jans_setup/setup_app/static.py index 1b3f78a1f9f..d5bf9cf3653 100644 --- a/jans-linux-setup/jans_setup/setup_app/static.py +++ b/jans-linux-setup/jans_setup/setup_app/static.py @@ -29,6 +29,11 @@ class InstallOption: MONDATORY = 1 OPTONAL = 2 +class SetupProfiles: + JANS = 'jans' + OPENBANKING = 'openbanking' + + COMPLETED = -99 ERROR = -101 diff --git a/jans-linux-setup/jans_setup/setup_app/utils/arg_parser.py b/jans-linux-setup/jans_setup/setup_app/utils/arg_parser.py index bd0652b7d5f..6c172cee0d7 100644 --- a/jans-linux-setup/jans_setup/setup_app/utils/arg_parser.py +++ b/jans-linux-setup/jans_setup/setup_app/utils/arg_parser.py @@ -54,6 +54,7 @@ parser.add_argument('--disable-config-api-security', help="Turn off oauth2 security validation for jans-config-api", action='store_true') parser.add_argument('--cli-test-client', help="Use config api test client for CLI", action='store_true') +parser.add_argument('--import-ldif', help="Render ldif templates from directory and import them in Database") if PROFILE != OPENBANKING_PROFILE: @@ -100,12 +101,13 @@ else: # openbanking parser.add_argument('--no-external-key', help="Don't use external key", action='store_true') - parser.add_argument('-ob-key-fn', help="Openbanking key filename") - parser.add_argument('-ob-cert-fn', help="Openbanking certificate filename") - parser.add_argument('-ob-alias', help="Openbanking key alias") + parser.add_argument('-ob-key-fn', help="Openbanking key filename", default='/root/obsigning-axV5umCvTMBMjPwjFQgEvb_NO_UPLOAD.key') + parser.add_argument('-ob-cert-fn', help="Openbanking certificate filename", default='/root/obsigning.pem') + parser.add_argument('-ob-alias', help="Openbanking key alias", default='GkwIzWy88xWSlcWnLiEc8ip9s2M') parser.add_argument('-static-kid', help="Openbanking static kid") parser.add_argument('-jwks-uri', help="Openbanking jwksUri", default="https://keystore.openbankingtest.org.uk/0014H00001lFE7dQAG/axV5umCvTMBMjPwjFQgEvb.jwks") - parser.add_argument('--import-ldif', help="Render ldif templates from directory and import them in Database") + parser.add_argument('--disable-ob-auth-script', help="Disable Openbanking authentication script and use default backend", action='store_true') + def add_to_me(you): diff --git a/jans-linux-setup/jans_setup/setup_app/utils/collect_properties.py b/jans-linux-setup/jans_setup/setup_app/utils/collect_properties.py index c0c547d8125..d19e8b47dbe 100644 --- a/jans-linux-setup/jans_setup/setup_app/utils/collect_properties.py +++ b/jans-linux-setup/jans_setup/setup_app/utils/collect_properties.py @@ -132,18 +132,6 @@ def collect(self): if result: Config.oxtrust_requesting_party_client_id = result['inum'] - #admin_dn = None - #result = dbUtils.search('o=jans', search_filter='(jansGrpTyp=jansManagerGroup)', search_scope=ldap3.SUBTREE) - #if result: - # admin_dn = result['member'][0] - - - #if admin_dn: - # for rd in dnutils.parse_dn(admin_dn): - # if rd[0] == 'inum': - # Config.admin_inum = str(rd[1]) - # break - oxConfiguration = dbUtils.search(jans_ConfigurationDN, search_filter='(objectClass=jansAppConf)', search_scope=ldap3.BASE) if 'jansIpAddress' in oxConfiguration: Config.ip = oxConfiguration['jansIpAddress'] @@ -194,7 +182,9 @@ def collect(self): if 'keyStoreSecret' in oxAuthConfDynamic: Config.oxauth_openid_jks_pass = oxAuthConfDynamic['keyStoreSecret'] - ssl_subj = self.get_ssl_subject('/etc/certs/httpd.crt') + httpd_crt_fn = '/etc/certs/httpd.crt' + crt_fn = httpd_crt_fn if os.path.exists(httpd_crt_fn) else '/etc/certs/ob/server.crt' + ssl_subj = self.get_ssl_subject(crt_fn) Config.countryCode = ssl_subj.get('countryName', '') Config.state = ssl_subj.get('stateOrProvinceName', '') diff --git a/jans-linux-setup/jans_setup/setup_app/utils/crypto64.py b/jans-linux-setup/jans_setup/setup_app/utils/crypto64.py index e4b054c5450..d3b9bb5e0f9 100644 --- a/jans-linux-setup/jans_setup/setup_app/utils/crypto64.py +++ b/jans-linux-setup/jans_setup/setup_app/utils/crypto64.py @@ -4,6 +4,7 @@ import json import socket import ssl +import urllib.request from collections import OrderedDict from pathlib import Path @@ -99,6 +100,61 @@ def gen_cert(self, suffix, password, user='root', cn=None, truststore_fn=None): "-file", public_certificate, "-keystore", truststore_fn, \ "-storepass", "changeit", "-noprompt"]) + + def gen_ca(self, ca_suffix='ca'): + self.logIt('Generating CA Certificate') + + out_dir = os.path.join(Config.output_dir, 'CA') + self.run([paths.cmd_mkdir, '-p', out_dir]) + + ca_key_fn = os.path.join(out_dir, ca_suffix+'.key') + ca_crt_fn = os.path.join(out_dir, ca_suffix+'.crt') + + self.run([paths.cmd_openssl, 'req', + '-newkey', 'rsa:2048', '-nodes', + '-keyform', 'PEM', + '-keyout', ca_key_fn, + '-x509', + '-days', '3650', + '-outform', 'PEM', + '-out', ca_crt_fn, + '-subj', '/C={}/ST={}/L={}/O={}/CN={}/emailAddress={}'.format(Config.countryCode, Config.state, Config.city, Config.orgName, Config.hostname, Config.admin_email) + ]) + + return ca_key_fn, ca_crt_fn + + + def gen_key_cert_from_ca(self, fn_suffix, ca_suffix='ca', cn=None): + if not cn: + cn = Config.hostname + out_dir = os.path.join(Config.output_dir, 'CA') + ca_key_fn = os.path.join(out_dir, ca_suffix+'.key') + ca_crt_fn = os.path.join(out_dir, ca_suffix+'.crt') + + key_fn = os.path.join(out_dir, fn_suffix+'.key') + self.run([paths.cmd_openssl, 'genrsa', '-out', key_fn, '2048']) + + csr_fn = os.path.join(out_dir, fn_suffix+'.csr') + self.run([paths.cmd_openssl, 'req', '-new', + '-key', key_fn, + '-out', csr_fn, + '-subj', '/C={}/ST={}/L={}/O={}/CN={}/emailAddress={}'.format(Config.countryCode, Config.state, Config.city, Config.orgName, cn, Config.admin_email) + ]) + + crt_fn = os.path.join(out_dir, fn_suffix+'.crt') + self.run([paths.cmd_openssl, 'x509', '-req', + '-in', csr_fn, + '-CA', ca_crt_fn, + '-CAkey', ca_key_fn, + '-set_serial', '101', + '-days', '365', + '-outform', 'PEM', + '-out', crt_fn + ]) + + return key_fn, csr_fn, crt_fn + + def prepare_base64_extension_scripts(self, extensions=[]): self.logIt("Preparing scripts") extension_path = Path(Config.extensionFolder) @@ -133,42 +189,29 @@ def generate_base64_file(self, fn, num_spaces): def generate_base64_ldap_file(self, fn): return self.generate_base64_file(fn, 1) - def gen_keystore(self, suffix, keystoreFN, keystorePW, inKey, inCert, alias=None): + def import_key_cert_into_keystore(self, suffix, keystore_fn, keystore_pw, in_key, in_cert, alias=None): self.logIt("Creating keystore %s" % suffix) # Convert key to pkcs12 pkcs_fn = '%s/%s.pkcs12' % (Config.certFolder, suffix) self.run([paths.cmd_openssl, - 'pkcs12', - '-export', - '-inkey', - inKey, - '-in', - inCert, - '-out', - pkcs_fn, - '-name', - alias or Config.hostname, - '-passout', - 'pass:%s' % keystorePW + 'pkcs12', '-export', + '-inkey', in_key, + '-in', in_cert, + '-out', pkcs_fn, + '-name', alias or Config.hostname, + '-passout', 'pass:%s' % keystore_pw ]) + # Import p12 to keystore import_cmd = [Config.cmd_keytool, '-importkeystore', - '-srckeystore', - '%s/%s.pkcs12' % (Config.certFolder, suffix), - '-srcstorepass', - keystorePW, - '-srcstoretype', - 'PKCS12', - '-destkeystore', - keystoreFN, - '-deststorepass', - keystorePW, - '-deststoretype', - 'JKS', - '-keyalg', - 'RSA', + '-srckeystore', '%s/%s.pkcs12' % (Config.certFolder, suffix), + '-srcstorepass', keystore_pw, + '-srcstoretype', 'PKCS12', + '-destkeystore', keystore_fn, + '-deststorepass', keystore_pw, + '-deststoretype', 'JKS', '-noprompt' ] if alias: @@ -332,3 +375,22 @@ def get_server_certificate(self, host): ssl_sock.connect((host, 443)) cert_der = ssl_sock.getpeercert(True) return ssl.DER_cert_to_PEM_cert(cert_der) + + def download_ob_cert(self, ob_cert_fn=None): + self.logIt("Downloading Openbanking Certificate from {}".format(Config.jwks_uri)) + if not ob_cert_fn: + ob_cert_fn = Config.ob_cert_fn + + try: + req = urllib.request.Request(Config.jwks_uri) + with urllib.request.urlopen(req) as f: + data = f.read().decode('utf-8') + keys = json.loads(data) + + with open(ob_cert_fn, 'w') as w: + w.write('-----BEGIN CERTIFICATE-----\n') + w.write(keys["keys"][0]["x5c"][0]) + w.write('\n-----END CERTIFICATE-----') + except Exception as e: + print("{}Can't download certificate{}".format(static.colors.DANGER, static.colors.ENDC)) + print(e) diff --git a/jans-linux-setup/jans_setup/setup_app/utils/properties_utils.py b/jans-linux-setup/jans_setup/setup_app/utils/properties_utils.py index 6894de0d614..9b343d0b910 100644 --- a/jans-linux-setup/jans_setup/setup_app/utils/properties_utils.py +++ b/jans-linux-setup/jans_setup/setup_app/utils/properties_utils.py @@ -101,13 +101,14 @@ def check_properties(self): tld = Config.hostname Config.admin_email = "support@%s" % tld - if Config.profile == 'jans': - if not Config.admin_password and Config.ldapPass: - Config.admin_password = Config.ldapPass + if not Config.admin_password and Config.ldapPass: + Config.admin_password = Config.ldapPass + + if not Config.admin_password: + Config.admin_password = self.getPW() - if not Config.admin_password: - Config.admin_password = self.getPW() + if Config.profile == 'jans': if not Config.ldapPass: Config.ldapPass = Config.admin_password @@ -801,7 +802,7 @@ def openbanking_properties(self): self.prompt_for_rdbm() - Config.staticKid = self.getPrompt("Enter Openbanking static kid") + Config.static_kid = self.getPrompt("Enter Openbanking static kid: ", Config.static_kid) use_external_key_prompt = input('Use external key? [Y|n] : ') Config.use_external_key = not use_external_key_prompt.lower().startswith('n') @@ -816,6 +817,9 @@ def openbanking_properties(self): while True: ob_cert_fn = self.getPrompt(' Openbanking Certificate File', Config.ob_cert_fn) + if not os.path.isfile(ob_cert_fn): + self.download_ob_cert(ob_cert_fn) + if os.path.isfile(ob_cert_fn): Config.ob_cert_fn = ob_cert_fn break @@ -889,22 +893,21 @@ def promptForProperties(self): Config.jans_max_mem = self.getPrompt("Enter maximum RAM for applications in MB", str(Config.jans_max_mem)) + admin_password = Config.ldapPass or Config.cb_password or Config.rdbm_password or self.getPW(special='.*=!%&+/-') + + while True: + adminPass = self.getPrompt("Enter Password for Admin User", admin_password) + if len(adminPass) > 3: + break + else: + print("Admin password should be at least four characters in length.") + + Config.admin_password = adminPass + if Config.profile == 'openbanking': self.openbanking_properties() - else: self.prompt_for_backend() - admin_password = Config.ldapPass or Config.cb_password or Config.rdbm_password or self.getPW(special='.*=!%&+/-') - - while True: - adminPass = self.getPrompt("Enter Password for Admin User", admin_password) - if len(adminPass) > 3: - break - else: - print("Admin password should be at least four characters in length.") - - Config.admin_password = adminPass - self.promptForConfigApi() self.promptForScimServer() self.promptForFido2Server() diff --git a/jans-linux-setup/jans_setup/templates/jans-cli/.#client.ldif b/jans-linux-setup/jans_setup/templates/jans-cli/.#client.ldif new file mode 120000 index 00000000000..a2282884379 --- /dev/null +++ b/jans-linux-setup/jans_setup/templates/jans-cli/.#client.ldif @@ -0,0 +1 @@ +mbaser@ubuntu.7772 \ No newline at end of file