From 36dc3a0ec0bdd0cf41d171d961c411480124bc8c Mon Sep 17 00:00:00 2001 From: Louis Abel Date: Wed, 1 Mar 2023 19:10:11 -0700 Subject: [PATCH] init --- .ansible-lint | 6 +++ .pre-commit-config.yaml | 35 ++++++++++++ .yamllint | 11 ++++ CHANGELOG.md | 18 +++++++ LICENSE | 21 ++++++++ README.md | 2 + defaults/main.yml | 53 ++++++++++++++++++ files/generate-oidc-token | 97 +++++++++++++++++++++++++++++++++ files/genkey.py | 18 +++++++ files/rocky.py | 31 +++++++++++ files/rocky_logo.png | Bin 0 -> 12142 bytes handlers/main.yml | 11 ++++ meta/main.yml | 53 ++++++++++++++++++ tasks/main.yml | 102 +++++++++++++++++++++++++++++++++++ templates/configuration.conf | 74 +++++++++++++++++++++++++ templates/ipsilon.conf | 24 +++++++++ vars/main.yml | 3 ++ 17 files changed, 559 insertions(+) create mode 100644 .ansible-lint create mode 100644 .pre-commit-config.yaml create mode 100644 .yamllint create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 defaults/main.yml create mode 100644 files/generate-oidc-token create mode 100644 files/genkey.py create mode 100644 files/rocky.py create mode 100644 files/rocky_logo.png create mode 100644 handlers/main.yml create mode 100644 meta/main.yml create mode 100644 tasks/main.yml create mode 100644 templates/configuration.conf create mode 100644 templates/ipsilon.conf create mode 100644 vars/main.yml diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..5efe51a --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,6 @@ +# .ansible-lint +warn_list: + - '204' # Lines should be less than 160 characters + - 'meta-no-info' +skip_list: + - 'role-name' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f64d238 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,35 @@ +--- +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-added-large-files + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-json + - id: pretty-format-json + - id: detect-private-key + + - repo: local + hooks: + - id: ansible-lint + name: Ansible-lint + description: This hook runs ansible-lint. + entry: ansible-lint -v --force-color + language: python + # do not pass files to ansible-lint, see: + # https://github.com/ansible/ansible-lint/issues/611 + pass_filenames: false + always_run: true + additional_dependencies: + - ansible-core>=2.13.3 + + - repo: https://github.com/adrienverge/yamllint.git + rev: v1.29.0 + hooks: + - id: yamllint + files: \.(yaml|yml)$ + types: [file, yaml] + entry: yamllint diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..4a8ae86 --- /dev/null +++ b/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 140 + level: warning + +ignore: | + .travis.yml + .github diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..60554f6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,18 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] +- what do we need to do + +## [0.0.1] - 2020-12-13 +### Added +- Initial + +### Changed +- None + +### Removed +- None diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4330a18 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Louis Abel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..df596e8 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Ansible template role: Ipsilon +Role that fulfills some need (ipsilon )and there was not some sort of equivalent elsewhere. diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..1b43bd2 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,53 @@ +--- +# Defaults variables for role ipsilon +ipsilon_db_user: ipsilon +ipsilon_db_password: ThisIsNotThePassword +ipsilon_db_host: dbhost +ipsilon_db_name: ipsilon_db +idp_hostname: accounts.rockylinux.org + +# The list of ipsilon packages +ipsilon_packages: + - ipsilon + - ipsilon-authform + - ipsilon-base + - ipsilon-filesystem + - ipsilon-infofas + - ipsilon-infosssd + - ipsilon-openid + - ipsilon-openidc + - ipsilon-saml2 + - ipsilon-saml2-base + - ipsilon-tools-ipa + - python3-setuptools + - python3-freeipa + - httpd + - mod_ssl + - mod_auth_openidc + - mod_auth_gssapi + - git + +ipsilon_booleans: + - httpd_can_network_connect + - httpd_can_network_connect_db + - httpd_dbus_sssd + - httpd_tmp_exec + - httpd_mod_auth_patm + +ipsilon_openid_trusted_roots: + - https://git.rockylinux.org/ + - https://vote.rockylinux.org/ + - https://lists.resf.org/ + +ipsilon_openidc_scopes: + - ipsilon + - rocky + +ipsilon_openidc_custom_scopes: + - rocky + +ipsilon_fas_username: userman +ipsilon_fas_password: ThisIsNotThePassword +ipsilon_oidc_salt: data +ipsilon_saml2_salt: data +... diff --git a/files/generate-oidc-token b/files/generate-oidc-token new file mode 100644 index 0000000..28e2272 --- /dev/null +++ b/files/generate-oidc-token @@ -0,0 +1,97 @@ +#!/usr/bin/python3 +# Copyright (c) 2018 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +""" +This script will accept some parameters and will print out some SQL you can run against the Ipsilon +database, and a token you can give to an application to authenticate against a service. +""" +import base64 +import json +import os +import time +import uuid + +import click + + +secret = base64.urlsafe_b64encode(os.urandom(64))[:64].decode() + + +template = """ +Run this SQL against Ipsilon's database: + +--------START CUTTING HERE-------- +BEGIN; +insert into token values ('{uuid}','username','{service_name}@service'); +insert into token values ('{uuid}','security_check','{secret}'); +insert into token values ('{uuid}','client_id','{service_name}'); +insert into token values ('{uuid}','expires_at','{expiration}'); +insert into token values ('{uuid}','type','Bearer'); +insert into token values ('{uuid}','issued_at','{now}'); +insert into token values ('{uuid}','scope','{scope}'); +COMMIT; +-------- END CUTTING HERE -------- + +""" + + +def validate_scopes(ctx, param, scopes): + """ + Ensure that the user provided at least one scope. + + Args: + ctx(click.core.Context): Unused. + param (click.core.Option): Unused. + scopes (tuple): The scopes provided by the user that we are validating. + Raises: + click.BadParameter: If the length of the scopes tuple is less than 1. + """ + if len(scopes) < 1: + raise click.BadParameter('At least one scope must be provided.') + + return scopes + + +@click.command() +@click.argument('service_name') +@click.option('--expiration', '-e', prompt='Number of days until expiration', type=int, + help='The number of days from now until this token expires.') +@click.option('--scope', '-s', multiple=True, callback=validate_scopes, + help='A scope to include for this token. May be supplied multiple times.') +@click.option('--no-openid', is_flag=True, help='Do not use "openid" as the first item in scope.') +def generate_token(service_name, expiration, scope, no_openid): + """ + Print out SQL to insert a token in the Ipsilon database, and the token itself. + + SERVICE_NAME is the name of the service that the token will be used by, (e.g., bodhi). + """ + identifier = uuid.uuid4() + + now = int(time.time()) + expiration = now + (expiration * 24 * 3600) + + scope = list(scope) + if not no_openid: + scope.insert(0, 'openid') + scope = json.dumps(scope) + + print(template.format(uuid=identifier, service_name=service_name, secret=secret, + expiration=expiration, scope=scope, now=now)) + + print("Token: {}_{}\n".format(identifier, secret)) + + +if __name__ == '__main__': + generate_token() diff --git a/files/genkey.py b/files/genkey.py new file mode 100644 index 0000000..5138728 --- /dev/null +++ b/files/genkey.py @@ -0,0 +1,18 @@ +#!/usr/bin/python3 +import time +import os.path + +from jwcrypto.jwk import JWK, JWKSet + +keyid = int(time.time()) +keyset = JWKSet() +rsasig = JWK(generate='RSA', size=2048, use='sig', + kid='%s-sig' % keyid) +keyset.add(rsasig) +rsasig = JWK(generate='RSA', size=2048, use='enc', + kid='%s-enc' % keyid) +keyset.add(rsasig) + +with open('/etc/ipsilon/openidc.key', 'w') as m: + m.write(keyset.export()) + diff --git a/files/rocky.py b/files/rocky.py new file mode 100644 index 0000000..d690b91 --- /dev/null +++ b/files/rocky.py @@ -0,0 +1,31 @@ +from __future__ import absolute_import + +from ipsilon.providers.openidc.plugins.common import OpenidCExtensionBase + + +class OpenidCExtension(OpenidCExtensionBase): + name = 'rocky' + display_name = 'Rocky Tokens' + scopes = { + 'openid': { + 'display_name': 'openid', + }, + 'profile': { + 'display_name': 'profile', + }, + 'email': { + 'display_name': 'email', + }, + 'address': { + 'display_name': 'address', + }, + 'phone': { + 'display_name': 'phone', + }, + 'https://mbs.rockylinux.org/oidc/mbs-submit-build': { + 'display_name': 'mbs', + }, + 'https://id.fedoraproject.org/scope/groups': { + 'display_name': 'groups', + } + } diff --git a/files/rocky_logo.png b/files/rocky_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..14acdf7ea0bbf68e4a3ce568638a17ab1ceb478a GIT binary patch literal 12142 zcmeHtWmKEZ);12s1I48fij-o(El6>9*CYff9)d%0D^6*V7Kh^Q6!%gJr4%pj#c6S9 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 + ipsilon-server-install + --secure yes + --openid yes + --openidc yes + --saml2 yes + --ipa yes + --info-sssd yes + --form yes + --gssapi-httpd-keytab /etc/httpd.keytab + --admin-user admin + --hostname {{ idp_hostname }} + args: + creates: /etc/ipsilon/idp/ipsilon.conf + no_log: true + register: ipsilon_install + tags: + - init + +- name: Set booleans + ansible.posix.seboolean: + name: "{{ item }}" + state: true + persistent: true + loop: "{{ ipsilon_booleans }}" + tags: + - selinux + +- name: Branding ipsilon with logo + ansible.builtin.copy: + src: rocky_logo.png + dest: "{{ item }}" + owner: root + group: root + mode: '0644' + with_items: + - /usr/share/ipsilon/ui/img/brand-lg.png + - /usr/share/ipsilon/ui/img/brand.png + +- name: Distributing openidc genkey script + ansible.builtin.copy: + src: genkey.py + dest: /var/lib/ipsilon/idp/genkey.py + mode: '0755' + owner: ipsilon + group: ipsilon + +- name: Generate oidc token script + ansible.builtin.copy: + src: generate-oidc-token + dest: /var/lib/ipsilon/idp/generate-oidc-token + mode: '0755' + owner: ipsilon + group: ipsilon + +- name: Distribute ipsilon.conf + ansible.builtin.template: + src: "ipsilon.conf" + dest: /etc/ipsilon/idp/ipsilon.conf + owner: ipsilon + group: ipsilon + mode: 0600 + tags: + - config + notify: + - restart_httpd + +- name: Distribute configuration.conf + ansible.builtin.template: + src: "configuration.conf" + dest: /etc/ipsilon/idp/configuration.conf + owner: ipsilon + group: ipsilon + mode: 0600 + tags: + - config + notify: + - restart_httpd + +- name: Configure SSSD part 1 + ansible.builtin.replace: + path: /etc/sssd/sssd.conf + regexp: ^ldap_user_extra_attrs = [\w,\s]+$ + replace: ldap_user_extra_attrs = mail, street, locality, st, postalCode, telephoneNumber, givenname, sn, fasTimeZone, fasLocale, fasIRCNick, fasGPGKeyId, fasCreationTime, fasStatusNote, fasRHBZEmail, fasGitHubUsername, fasGitLabUsername, fasWebsiteURL, fasIsPrivate, ipaSshPubKey + notify: restart_sssd + +- name: Configure SSSD part 2 + ansible.builtin.replace: + path: /etc/sssd/sssd.conf + regexp: ^user_attributes = [\w,\s]+$ + replace: user_attributes = +mail, +street, +locality, +st, +postalCode, +telephoneNumber, +givenname, +sn, +fasTimeZone, +fasLocale, +fasIRCNick, +fasGPGKeyId, +fasCreationTime, +fasStatusNote, +fasRHBZEmail, +fasGitHubUsername, +fasGitLabUsername, +fasWebsiteURL, +fasIsPrivate, +ipaSshPubKey + notify: restart_sssd +... diff --git a/templates/configuration.conf b/templates/configuration.conf new file mode 100644 index 0000000..26ee8df --- /dev/null +++ b/templates/configuration.conf @@ -0,0 +1,74 @@ +[info_config] +sssd preconfigured = True +global enabled = sssd,nss,fas +fas fas url = https://accounts.rockylinux.org/ +fas fas proxy client user agent = Ipsilon v1.0 +fas fas insecure auth = False +fas bind username = {{ ipsilon_fas_username }} +fas bind password = {{ ipsilon_fas_password }} +fas preconfigured=True + +[sssd_data] + +[nss_data] + +[fas_data] + +[login_config] +fas fas url = https://accounts.rockylinux.org +fas fas proxy client user agent = Ipsilon v1.0 +fas fas insecure auth = False +fas username text = RAS Username +fas password text = Password +fas help text = Login with your RAS credentials +global enabled = gssapi,form + +[gssapi_data] + +[form_data] + +[provider_config] +openidc database url = postgresql://{{ ipsilon_db_user }}:{{ ipsilon_db_password }}@{{ ipsilon_db_host }}/{{ ipsilon_db_name }} +openidc static database url = postgresql://{{ ipsilon_db_user }}:{{ ipsilon_db_password }}@{{ ipsilon_db_host }}/{{ ipsilon_db_name }} +openidc enabled extensions = ipsilon, mbs, fedora-account +openidc endpoint url = https://{{ idp_hostname }}/idp/openidc/ +openidc documentation url = https://ipsilonproject.org/doc/openidc/ +openidc policy url = http://www.example.com/ +openidc tos url = http://www.example.com/ +openidc idp key file = /var/lib/ipsilon/idp/openidc/openidc.key +openidc idp sig key id = 1633884828-sig +openidc idp subject salt = {{ ipsilon_oidc_salt }} +openidc allow dynamic client registration = True +openidc default attribute mapping = [["*", "*"], ["_groups", "groups"], [["_extras", "cla"], "cla"], ["fullname", "name"], ["_username", "nickname"], ["_username", "preferred_username"], ["fasIRCNick", "ircnick"], ["fasLocale", "locale"], ["fasTimeZone", "zoneinfo"], ["fasTimeZone", "timezone"], ["fasWebsiteURL", "website"], ["fasGPGKeyId", "gpg_keyid"], ["ipaSshPubKey", "ssh_key"], ["fasIsPrivate", "privacy"], ["fullname", "human_name"]] +openidc default allowed attributes = ["*"] +openidc access token lifetime = 3600 +openidc refresh token lifetime = 31536000 +global enabled = openidc,saml2,openid +openid default allowed attributes = ["*"] +openid database url = postgresql://{{ ipsilon_db_user }}:{{ ipsilon_db_password }}@{{ ipsilon_db_host }}/{{ ipsilon_db_name }} +openid default email domain = +openid endpoint url = https://{{ idp_hostname }}/idp/openid/ +openid identity url template = https://{{ idp_hostname }}/idp/openid/id/%(username)s +openid trusted roots = {{ ipsilon_openid_trust_roots }} +openid untrusted roots = +openid enabled extensions = Attribute Exchange, CLAs, Fedora Teams, Simple Registration, Teams, API +openid default attribute mapping = [["*", "*"], ["_groups", "groups"], [["_extras", "cla"], "cla"], ["fullname", "name"], ["_username", "nickname"], ["_username", "preferred_username"], ["fasIRCNick", "ircnick"], ["fasLocale", "locale"], ["fasTimeZone", "zoneinfo"], ["fasTimeZone", "timezone"], ["fasWebsiteURL", "website"], ["fasGPGKeyId", "gpg_keyid"], ["ipaSshPubKey", "ssh_key"], ["fasIsPrivate", "privacy"], ["fullname", "human_name"], ["mail", "email"]] +saml2 idp storage path = /var/lib/ipsilon/idp/saml2 +saml2 idp metadata file = metadata.xml +saml2 idp certificate file = /var/lib/ipsilon/idp/saml2/idp.pem +saml2 idp key file = /var/lib/ipsilon/idp/saml2/idp.key +saml2 idp nameid salt = {{ ipsilon_saml2_salt }} +saml2 idp metadata validity = 1825 +saml2 session database url = postgresql://{{ ipsilon_db_user }}:{{ ipsilon_db_password }}@{{ ipsilon_db_host }}/{{ ipsilon_db_name }} + +[openidc_data] + +[saml2_data] + +[openid_data] + +[authz_config] +global enabled = allow + +[allow_data] + diff --git a/templates/ipsilon.conf b/templates/ipsilon.conf new file mode 100644 index 0000000..e2d4d68 --- /dev/null +++ b/templates/ipsilon.conf @@ -0,0 +1,24 @@ +[global] +debug = True +tools.log_request_response.on = True +template_dir = "templates" +cache_dir = "/var/cache/ipsilon" +cleanup_interval = 30 +db.conn.log = False +db.echo = False + +base.mount = "/idp" +base.dir = "/usr/share/ipsilon" +#admin.config.db = "configfile:///etc/ipsilon/idp/configuration.conf" +admin.config.db = "postgresql://{{ ipsilon_db_user }}:{{ ipsilon_db_password }}@{{ ipsilon_db_host }}/{{ ipsilon_db_name }}" +user.prefs.db = "postgresql://{{ ipsilon_db_user }}:{{ ipsilon_db_password }}@{{ ipsilon_db_host }}/{{ ipsilon_db_name }}" +transactions.db = "postgresql://{{ ipsilon_db_user }}:{{ ipsilon_db_password }}@{{ ipsilon_db_host }}/{{ ipsilon_db_name }}" + +tools.sessions.on = True +tools.sessions.name = "idp_ipsilon_session_id" +tools.sessions.storage_type = "file" +tools.sessions.storage_path = "/var/lib/ipsilon/idp/sessions" +tools.sessions.path = "/idp" +tools.sessions.timeout = 30 +tools.sessions.httponly = True +tools.sessions.secure = True diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..0d75ed2 --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,3 @@ +--- +# vars file - Nothing should really go here but dynamic imports +# and truely static items \ No newline at end of file