diff --git a/aws_buildspec.yml b/aws_buildspec.yml new file mode 100644 index 00000000..28d3872c --- /dev/null +++ b/aws_buildspec.yml @@ -0,0 +1,39 @@ +version: 0.2 + +env: + shell: bash + variables: + LABEL: "1.1.0" + exported-variables: + - LABEL + +phases: + pre_build: + commands: + - echo Logging in to Amazon ECR... + - aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/u0z2s2z8 + - echo Logging in to Docker Hub + - docker login --username skoranda --password $HUB_DOCKER_COM_TOKEN + - echo Logging in to GitHub + - docker login --username skoranda --password $GITHUB_COM_TOKEN + build: + commands: + - echo Build started on `date` + - container/build.sh --image_registry=public.ecr.aws --repository=u0z2s2z8 --label=$LABEL --suffix=$CODEBUILD_BUILD_NUMBER match all + - container/build.sh --image_registry=docker.io --repository=comanageproject --label=$LABEL --suffix=$CODEBUILD_BUILD_NUMBER match all + - container/build.sh --image_registry=ghcr.io --repository=cilogon --label=$LABEL --suffix=$CODEBUILD_BUILD_NUMBER match all + post_build: + commands: + - echo Build completed on `date` + - echo Pushing the Docker images to AWS public repository... + - docker push public.ecr.aws/u0z2s2z8/comanage-match:$LABEL-basic-auth-$CODEBUILD_BUILD_NUMBER + - docker push public.ecr.aws/u0z2s2z8/comanage-match:$LABEL-mod_auth_openidc-$CODEBUILD_BUILD_NUMBER + - docker push public.ecr.aws/u0z2s2z8/comanage-match:$LABEL-shibboleth-sp-supervisor-$CODEBUILD_BUILD_NUMBER + - echo Pushing the Docker images to Docker Hub public repository... + - docker push docker.io/comanageproject/comanage-match:$LABEL-basic-auth-$CODEBUILD_BUILD_NUMBER + - docker push docker.io/comanageproject/comanage-match:$LABEL-mod_auth_openidc-$CODEBUILD_BUILD_NUMBER + - docker push docker.io/comanageproject/comanage-match:$LABEL-shibboleth-sp-supervisor-$CODEBUILD_BUILD_NUMBER + - echo Pushing the Docker images to GitHub public repository... + - docker push ghcr.io/cilogon/comanage-match:$LABEL-basic-auth-$CODEBUILD_BUILD_NUMBER + - docker push ghcr.io/cilogon/comanage-match:$LABEL-mod_auth_openidc-$CODEBUILD_BUILD_NUMBER + - docker push ghcr.io/cilogon/comanage-match:$LABEL-shibboleth-sp-supervisor-$CODEBUILD_BUILD_NUMBER diff --git a/aws_buildspec_develop.yml b/aws_buildspec_develop.yml new file mode 100644 index 00000000..1ae31894 --- /dev/null +++ b/aws_buildspec_develop.yml @@ -0,0 +1,24 @@ +version: 0.2 + +env: + shell: bash + +phases: + pre_build: + commands: + - echo Logging in to Amazon ECR... + - aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/u0z2s2z8 + - echo Logging in to Docker Hub + - docker login --username skoranda --password $HUB_DOCKER_COM_TOKEN + build: + commands: + - echo Build started on `date` + - SHORT_COMMIT_HASH="${CODEBUILD_RESOLVED_SOURCE_VERSION:0:8}" + - container/build.sh --image_registry=public.ecr.aws --repository=u0z2s2z8 --label=develop-$SHORT_COMMIT_HASH --suffix=$CODEBUILD_BUILD_NUMBER match all + post_build: + commands: + - echo Build completed on `date` + - echo Pushing the Docker images to AWS public repository... + - docker push public.ecr.aws/u0z2s2z8/comanage-match:develop-$SHORT_COMMIT_HASH-basic-auth-$CODEBUILD_BUILD_NUMBER + - docker push public.ecr.aws/u0z2s2z8/comanage-match:develop-$SHORT_COMMIT_HASH-mod_auth_openidc-$CODEBUILD_BUILD_NUMBER + - docker push public.ecr.aws/u0z2s2z8/comanage-match:develop-$SHORT_COMMIT_HASH-shibboleth-sp-supervisor-$CODEBUILD_BUILD_NUMBER diff --git a/container/build.sh b/container/build.sh new file mode 100755 index 00000000..28e18e1f --- /dev/null +++ b/container/build.sh @@ -0,0 +1,621 @@ +#!/bin/bash +# +# Build containers for COmanage Match and associated tools. +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +########################################################################### +# Build the Match base image. +# Globals: +# None +# Arguments: +# Full image name prefix, a string. +# Tag label, a string. +# Tag suffix, a string. +# Docker build flags, other flags for docker build. +# Outputs: +# None +########################################################################### +function build_base() { + local docker_build_command + local docker_build_flags + local label + local prefix + local suffix + + prefix="$1" + label="$2" + suffix="$3" + + if [[ -z "${label}" ]]; then + err "ERROR:build_base: label cannot be empty" + return 1 + fi + + if [[ -z "${suffix}" ]]; then + err "ERROR:build_base: suffix cannot be empty" + return 1 + fi + + declare -a docker_build_flags=("${@:4}") + + tag="comanage-match-base:${label}-${suffix}" + + docker_build_command=(docker build) + + if ((${#docker_build_flags[@]})); then + for flag in "${docker_build_flags[@]}"; do + docker_build_command+=("${flag}") + done + fi + + docker_build_command+=(--tag "${tag}") + docker_build_command+=(--build-arg COMANAGE_MATCH_VERSION="${label}") + docker_build_command+=(--file container/match/base/Dockerfile) + docker_build_command+=(.) + + "${docker_build_command[@]}" + + if (( $? != 0 )); then + exit 1 + fi + + if [[ -n "${prefix}" ]]; then + target="${prefix}${tag}" + docker tag "${tag}" "${target}" + fi +} + +########################################################################### +# Build the Match basic auth image. +# Globals: +# None +# Arguments: +# Full image name prefix, a string. +# Tag label, a string. +# Tag suffix, a string. +# Docker build flags, other flags for docker build. +# Outputs: +# None +########################################################################### +function build_basic_auth() { + local docker_build_command + local docker_build_flags + local label + local prefix + local suffix + + prefix="$1" + label="$2" + suffix="$3" + + if [[ -z "${label}" ]]; then + err "ERROR:build_basic_auth: label cannot be empty" + return 1 + fi + + if [[ -z "${suffix}" ]]; then + err "ERROR:build_basic_auth: suffix cannot be empty" + return 1 + fi + + declare -a docker_build_flags=("${@:4}") + + tag="comanage-match:${label}-basic-auth-${suffix}" + + docker_build_command=(docker build) + + if ((${#docker_build_flags[@]})); then + for flag in "${docker_build_flags[@]}"; do + docker_build_command+=("${flag}") + done + fi + + docker_build_command+=(--tag "${tag}") + docker_build_command+=(--build-arg COMANAGE_MATCH_VERSION="${label}") + docker_build_command+=(--build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION="${suffix}") + docker_build_command+=(--file container/match/basic-auth/Dockerfile) + docker_build_command+=(.) + + "${docker_build_command[@]}" + + if (( $? != 0 )); then + exit 1 + fi + + if [[ -n "${prefix}" ]]; then + target="${prefix}${tag}" + docker tag "${tag}" "${target}" + fi +} + +########################################################################### +# Build the Match mod_auth_openidc image. +# Globals: +# None +# Arguments: +# Full image name prefix, a string. +# Tag label, a string. +# Tag suffix, a string. +# Docker build flags, other flags for docker build. +# Outputs: +# None +########################################################################### +function build_mod_auth_openidc() { + local docker_build_command + local docker_build_flags + local label + local prefix + local suffix + + prefix="$1" + label="$2" + suffix="$3" + + if [[ -z "${label}" ]]; then + err "ERROR:build_mod_auth_openidc: label cannot be empty" + return 1 + fi + + if [[ -z "${suffix}" ]]; then + err "ERROR:build_mod_auth_openidc: suffix cannot be empty" + return 1 + fi + + declare -a docker_build_flags=("${@:4}") + + tag="comanage-match:${label}-mod_auth_openidc-${suffix}" + + docker_build_command=(docker build) + + if ((${#docker_build_flags[@]})); then + for flag in "${docker_build_flags[@]}"; do + docker_build_command+=("${flag}") + done + fi + + docker_build_command+=(--tag "${tag}") + docker_build_command+=(--build-arg COMANAGE_MATCH_VERSION="${label}") + docker_build_command+=(--build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION="${suffix}") + docker_build_command+=(--file container/match/mod_auth_openidc/Dockerfile) + docker_build_command+=(.) + + "${docker_build_command[@]}" + + if (( $? != 0 )); then + exit 1 + fi + + if [[ -n "${prefix}" ]]; then + target="${prefix}${tag}" + docker tag "${tag}" "${target}" + fi +} + +########################################################################### +# Build the Shibboleth SP base image. +# Globals: +# None +# Arguments: +# Full image name prefix, a string. +# Shibboleth SP version. +# Tag suffix, a string. +# Docker build flags, other flags for docker build. +# Outputs: +# None +########################################################################### +function build_shibboleth_sp_base() { + local docker_build_command + local docker_build_flags + local label + local prefix + local suffix + + prefix="$1" + label="$2" + suffix="$3" + + if [[ -z "${label}" ]]; then + err "ERROR:build_shibboleth_sp_base: label cannot be empty" + return 1 + fi + + if [[ -z "${suffix}" ]]; then + err "ERROR:build_shibboleth_sp_base: suffix cannot be empty" + return 1 + fi + + declare -a docker_build_flags=("${@:4}") + + tag="comanage-match-shibboleth-sp-base:${label}-${suffix}" + + docker_build_command=(docker build) + + if ((${#docker_build_flags[@]})); then + for flag in "${docker_build_flags[@]}"; do + docker_build_command+=("${flag}") + done + fi + + docker_build_command+=(--tag "${tag}") + docker_build_command+=(--build-arg SHIBBOLETH_SP_VERSION="${label}") + docker_build_command+=(--file container/shibboleth-sp-base/Dockerfile) + docker_build_command+=(.) + + "${docker_build_command[@]}" + + if (( $? != 0 )); then + exit 1 + fi + + if [[ -n "${prefix}" ]]; then + target="${prefix}${tag}" + docker tag "${tag}" "${target}" + fi +} + +########################################################################### +# Build the Shibboleth SP with supervisor image. +# Globals: +# None +# Arguments: +# Full image name prefix, a string. +# Tag label, a string. +# Tag suffix, a string. +# Shibboleth SP version. +# Shibboleth SP base image version. +# Docker build flags, other flags for docker build. +# Outputs: +# None +########################################################################### +function build_shibboleth_sp_supervisor() { + local docker_build_command + local docker_build_flags + local label + local prefix + local shib_label + local shib_suffix + local suffix + + prefix="$1" + label="$2" + suffix="$3" + shib_label="$4" + shib_suffix="$5" + + if [[ -z "${label}" ]]; then + err "ERROR:build_shibboleth_sp_supervisor: label cannot be empty" + return 1 + fi + + if [[ -z "${suffix}" ]]; then + err "ERROR:build_shibboleth_sp_supervisor: suffix cannot be empty" + return 1 + fi + + if [[ -z "${shib_label}" ]]; then + err "ERROR:build_shibboleth_sp_supervisor: shib_label cannot be empty" + return 1 + fi + + if [[ -z "${shib_suffix}" ]]; then + err "ERROR:build_shibboleth_sp_supervisor: shib_suffix cannot be empty" + return 1 + fi + + declare -a docker_build_flags=("${@:6}") + + tag="comanage-match:${label}-shibboleth-sp-supervisor-${suffix}" + + docker_build_command=(docker build) + + if ((${#docker_build_flags[@]})); then + for flag in "${docker_build_flags[@]}"; do + docker_build_command+=("${flag}") + done + fi + + docker_build_command+=(--tag "${tag}") + docker_build_command+=(--build-arg COMANAGE_MATCH_VERSION="${label}") + docker_build_command+=(--build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION="${suffix}") + docker_build_command+=(--build-arg COMANAGE_MATCH_SHIBBOLETH_SP_VERSION="${shib_label}") + docker_build_command+=(--build-arg COMANAGE_MATCH_SHIBBOLETH_SP_BASE_IMAGE_VERSION="${shib_suffix}") + docker_build_command+=(--file container/match/shibboleth-sp-supervisor/Dockerfile) + docker_build_command+=(.) + + "${docker_build_command[@]}" + + if (( $? != 0 )); then + exit 1 + fi + + if [[ -n "${prefix}" ]]; then + target="${prefix}${tag}" + docker tag "${tag}" "${target}" + fi +} + +########################################################################### +# Echo errors to stderr with timestamp. +# Globals: +# None +# Arguments: +# None +# Outputs: +# Writes errors to stderr. +########################################################################### +function err() { + echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 +} + +########################################################################### +# Echo usage message to stdout. +# Globals: +# None +# Arguments: +# Array of all input parameters +# Outputs: +# Writes usage message to stdout. +########################################################################### +function usage() { + local usage + + read -d '' usage < /dev/null 2>&1 + if (( $? == 0 )); then + branch="$(git rev-parse --abbrev-ref HEAD)" + if [[ "${branch}" == "main" ]]; then + label="$(git describe --tags --abbrev=0)" + else + label="${branch}-$(git rev-parse --short HEAD)" + fi + else + label="$(git rev-parse --short HEAD)" + fi + + echo "${label}" +} + +########################################################################### +# Parse command line and execute as specified. +# Globals: +# SHIBBOLETH_SP_VERSION, string +# Arguments: +# Array of all input parameters +# Outputs: +# None +########################################################################### +function main() { + local authentication + local docker_build_flags + local gnu_getopt_out + local image_registry + local label="" + local prefix="" + local product + local repository + local suffix + + declare -a docker_build_flags=() + + gnu_getopt_out=$(/usr/bin/getopt \ + --options hl:os: \ + --longoptions help \ + --longoptions image_match: \ + --longoptions label: \ + --longoptions no-cache \ + --longoptions owner: \ + --longoptions repository: \ + --longoptions rm \ + --longoptions suffix: \ + --name 'build.sh' -- "${@}") + + if [[ $? != 0 ]]; then + err "ERROR: unable to parse command line" + exit 1 + fi + + eval set -- "${gnu_getopt_out}" + + while true; do + case "$1" in + -h | --help ) usage $@; exit ;; + --image_registry ) image_registry="$2"; shift 2 ;; + -l | --label ) label="$2"; shift 2 ;; + --no-cache ) docker_build_flags+=(--no-cache) ; shift 1 ;; + -o | --owner ) repository="$2"; shift 2 ;; + --repository ) repository="$2"; shift 2 ;; + --rm ) docker_build_flags+=(--rm) ; shift 1 ;; + -s | --suffix ) suffix="$2"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + if [[ -z "${suffix}" ]]; then + err "ERROR: --suffix must be specified" + exit 1 + fi + + if [[ -z "${repository}" && -n "${image_registry}" ]]; then + err "ERROR: --repository must be specified if --image_registry is specified" + exit 1 + fi + + if [[ -z "${label}" ]]; then + label="$(label_from_repository)" + fi + + if [[ -n "${repository}" ]]; then + prefix="${repository}/" + if [[ -n "${image_repository}" ]]; then + prefix="${image_repository}/${prefix}" + fi + fi + + product="$1" + + case "${product}" in + match ) + authentication="$2" + case "${authentication}" in + all ) + build_base "${prefix}" "${label}" "${suffix}" "${docker_build_flags[@]}" \ + && build_basic_auth "${prefix}" "${label}" "${suffix}" "${docker_build_flags[@]}" \ + && build_mod_auth_openidc "${prefix}" "${label}" "${suffix}" "${docker_build_flags[@]}" \ + && build_shibboleth_sp_base "${prefix}" "${SHIBBOLETH_SP_VERSION}" "${suffix}" "${docker_build_flags[@]}" \ + && build_shibboleth_sp_supervisor "${prefix}" "${label}" "${suffix}" "${SHIBBOLETH_SP_VERSION}" "${suffix}" "${docker_build_flags[@]}" + ;; + basic-auth ) + build_base "${prefix}" "${label}" "${suffix}" "${docker_build_flags[@]}" \ + && build_basic_auth "${prefix}" "${label}" "${suffix}" "${docker_build_flags[@]}" + ;; + mod_auth_openidc ) + build_base "${prefix}" "${label}" "${suffix}" "${docker_build_flags[@]}" \ + && build_mod_auth_openidc "${prefix}" "${label}" "${suffix}" "${docker_build_flags[@]}" + ;; + shibboleth-sp-supervisor ) + build_base "${prefix}" "${label}" "${suffix}" "${docker_build_flags[@]}" \ + && build_shibboleth_sp_base "${prefix}" "${SHIBBOLETH_SP_VERSION}" "${suffix}" "${docker_build_flags[@]}" \ + && build_shibboleth_sp_supervisor "${prefix}" "${label}" "${suffix}" "${SHIBBOLETH_SP_VERSION}" "${suffix}" "${docker_build_flags[@]}" + ;; + *) + err "ERROR: Unrecognized authentication" + echo + usage + ;; + esac + ;; + *) + err "ERROR: unrecogized product" + echo + usage + ;; + esac +} + +# Globals +SHIBBOLETH_SP_VERSION=3.3.0 + +main "$@" diff --git a/container/match/base/DatabaseConnectivityTestCommand.php b/container/match/base/DatabaseConnectivityTestCommand.php new file mode 100644 index 00000000..812e63bf --- /dev/null +++ b/container/match/base/DatabaseConnectivityTestCommand.php @@ -0,0 +1,78 @@ +config(); + + $config = new \Doctrine\DBAL\Configuration(); + + $cfargs = [ + 'dbname' => $cfg['database'], + 'user' => $cfg['username'], + 'password' => $cfg['password'], + 'host' => $cfg['host'], + 'driver' => ($cfg['driver'] == 'Cake\Database\Driver\Postgres' ? "pdo_pgsql" : "pdo_mysql") + ]; + + $conn = DriverManager::getConnection($cfargs, $config); + + try { + $conn->query('SELECT NOW()'); + $io->out("Connected to database"); + return 0; + } + catch(\Exception $e) { + $io->out("Unable to connect to database"); + return 1; + } + } +} diff --git a/container/match/base/DatabaseSetupAlreadyCommand.php b/container/match/base/DatabaseSetupAlreadyCommand.php new file mode 100644 index 00000000..6a66fda0 --- /dev/null +++ b/container/match/base/DatabaseSetupAlreadyCommand.php @@ -0,0 +1,60 @@ +findById('1')->firstOrFail(); + $io->out("Match database is setup"); + return 0; + } + catch(\Exception $e) { + $io->out("Match database is not setup"); + return 1; + } + } +} diff --git a/container/match/base/Dockerfile b/container/match/base/Dockerfile new file mode 100644 index 00000000..d505ef6d --- /dev/null +++ b/container/match/base/Dockerfile @@ -0,0 +1,106 @@ +# COmanage Match Dockerfile +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +FROM php:8.1.13-apache-bullseye + +# Official PHP image with Apache HTTPD includes +# --with-openssl +# but intl, pdo, pdo_pgsql, pgsql +# extensions must be built. +RUN apt-get update && apt-get install -y \ + libicu-dev \ + libpq-dev \ + patch \ + ssl-cert \ + wget \ + zlib1g \ + libpcre3-dev \ + && docker-php-ext-configure intl \ + && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ + && docker-php-ext-install intl pdo pdo_pgsql pgsql \ + && docker-php-source delete \ + && apt-get purge -y \ + libicu-dev \ + libpq-dev \ + && apt-get clean + +# Build the redis extension to use Redis for session storage. +RUN docker-php-source extract \ + && pecl bundle -d /usr/src/php/ext redis \ + && docker-php-ext-install redis \ + && docker-php-ext-enable redis \ + && docker-php-source delete + +# Copy the production php.ini into place. +RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +ARG COMANAGE_MATCH_VERSION +ENV COMANAGE_MATCH_VERSION ${COMANAGE_MATCH_VERSION:-develop} +LABEL comanage_match_version=${COMANAGE_MATCH_VERSION} + +ARG COMANAGE_MATCH_DIR +ENV COMANAGE_MATCH_DIR ${COMANAGE_MATCH_DIR:-/srv/comanage-match} +LABEL comanage_match_dir=${COMANAGE_MATCH_DIR} + +WORKDIR $COMANAGE_MATCH_DIR + +COPY app ${COMANAGE_MATCH_DIR}/app/ +COPY LICENSE ${COMANAGE_MATCH_DIR}/ +COPY NOTICE ${COMANAGE_MATCH_DIR}/ + +RUN rm -f ${COMANAGE_MATCH_DIR}/app/tmp \ + && rm -r ${COMANAGE_MATCH_DIR}/app/logs \ + && mkdir ${COMANAGE_MATCH_DIR}/app/tmp \ + && chown -R www-data:www-data ${COMANAGE_MATCH_DIR}/app/tmp \ + && cd /var/www/html \ + && ln -s ${COMANAGE_MATCH_DIR}/app/webroot match \ + && mkdir ${COMANAGE_MATCH_DIR}/local + +RUN a2enmod headers \ + && a2enmod ssl \ + && a2enmod rewrite \ + && a2dissite 000-default.conf \ + && a2disconf other-vhosts-access-log \ + && cd /etc/apache2 \ + && ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem cert.pem \ + && ln -s /etc/ssl/private/ssl-cert-snakeoil.key privkey.pem + +COPY container/match/base/comanage_utils.sh /usr/local/lib/ +COPY container/match/base/comanage_shibboleth_sp_utils.sh /usr/local/lib/ +COPY container/match/base/docker-comanage-match-entrypoint /usr/local/bin/ + +COPY container/match/base/DatabaseConnectivityTestCommand.php ${COMANAGE_MATCH_DIR}/app/src/Command/ +COPY container/match/base/DatabaseSetupAlreadyCommand.php ${COMANAGE_MATCH_DIR}/app/src/Command/ + +EXPOSE 80 443 + +# Allow values for first administrator bootstrapped into the +# platform to be specified at image build time, in addition to +# being injected at run time through the entrypoint script. +ARG COMANAGE_MATCH_ADMIN_USERNAME + +# Set simple defaults for first administrator bootstrapped into the +# platform to make simple evaluation of the platform easier. +ENV COMANAGE_MATCH_ADMIN_USERNAME ${COMANAGE_MATCH_ADMIN_USERNAME:-match.admin} + +# Signal this is a containerized deployment +ENV COMANAGE_MATCH_CONTAINER=1 + +ENTRYPOINT ["docker-comanage-match-entrypoint"] + +CMD ["apache2-foreground"] diff --git a/container/match/base/comanage_shibboleth_sp_utils.sh b/container/match/base/comanage_shibboleth_sp_utils.sh new file mode 100755 index 00000000..02ac2098 --- /dev/null +++ b/container/match/base/comanage_shibboleth_sp_utils.sh @@ -0,0 +1,355 @@ +#!/bin/bash + +# COmanage Match Shibboleth SP Dockerfile entrypoint +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -n "$COMANAGE_DEBUG" ] +then + OUTPUT=/dev/stdout +else + OUTPUT=/dev/null +fi + +########################################## +# Consume injected environment variables +# Globals: +# See function +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_shibboleth_sp_utils::consume_injected_environment() { + + echo "Examining environment variables for Shibboleth SP..." > "$OUTPUT" + + # Configuration details that may be injected through environment + # variables or the contents of files. + # + # SHIBBOLETH_SP_METADATA_PROVIDER_XML may also be injected in the + # same way but because of the presence of special characters in the + # XML it is handled differently. + + injectable_config_vars=( + SHIBBOLETH_SP_ENTITY_ID + SHIBBOLETH_SP_CERT + SHIBBOLETH_SP_PRIVKEY + SHIBBOLETH_SP_SIGNING_CERT + SHIBBOLETH_SP_SIGNING_PRIVKEY + SHIBBOLETH_SP_ENCRYPT_CERT + SHIBBOLETH_SP_ENCRYPT_PRIVKEY + SHIBBOLETH_SP_SAMLDS_URL + ) + + # If the file associated with a configuration variable is present then + # read the value from it into the appropriate variable. So for example + # if the variable COMANAGE_MATCH_DATABASE_USER_PASSWORD_FILE exists and its + # value points to a file on the file system then read the contents + # of that file into the variable COMANAGE_MATCH_DATABASE_USER_PASSWORD. + + for config_var in "${injectable_config_vars[@]}" + do + eval file_name=\$"${config_var}_FILE"; + + if [ -e "$file_name" ]; then + payload=`cat $file_name` + declare "${config_var}"="${payload}" + fi + done + + echo "Done examining environment variables" > "$OUTPUT" +} + +########################################## +# Prepare shibboleth2.xml configuration file +# Globals: +# OUTPUT +# SHIBBOLETH_SP_ENTITY_ID +# SHIBBOLETH_SP_SAMLDS_URL +# SHIBBOLETH_SP_METADATA_PROVIDER_XML_FILE +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_shibboleth_sp_utils::prepare_shibboleth2xml() { + + local shib_file + local xml_content_file + local sed_script_file + + # If no shibboleth2.xml file is present then create one using + # injected information or defaults that are not particularly + # useful in a federated context but will allow shibd to start. + shib_file='/etc/shibboleth/shibboleth2.xml' + + if [[ ! -e "${shib_file}" ]]; then + cp "${shib_file}.template" "${shib_file}" > "${OUTPUT}" 2>&1 + sed -i -e s@%%SHIBBOLETH_SP_ENTITY_ID%%@"${SHIBBOLETH_SP_ENTITY_ID:-https://comanage.match/shibboleth}"@ "${shib_file}" > "${OUTPUT}" 2>&1 + sed -i -e s@%%SHIBBOLETH_SP_SAMLDS_URL%%@"${SHIBBOLETH_SP_SAMLDS_URL:-https://localhost/match/pages/eds/index}"@ "${shib_file}" > "${OUTPUT}" 2>&1 + + # The metadata provider injected input most likely contains special characters + # so use a sed script instead of simple substitution on the command line. + + if [[ -n "${SHIBBOLETH_SP_METADATA_PROVIDER_XML_FILE}" ]]; then + xml_content_file="${SHIBBOLETH_SP_METADATA_PROVIDER_XML_FILE}" + else + xml_content_file=`/bin/mktemp` + echo "${SHIBBOLETH_SP_METADATA_PROVIDER_XML:-}" > "${xml_content_file}" + fi + + sed_script_file=`/bin/mktemp` + cat > ${sed_script_file}< "${OUTPUT}" 2>&1 + + chmod 0644 "${shib_file}" > "${OUTPUT}" 2>&1 + + rm -f "${xml_content_file}" > "${OUTPUT}" 2>&1 + rm -f "${sed_script_file}" > "${OUTPUT}" 2>&1 + + fi +} + +########################################## +# Prepare SAML certs and keys +# Globals: +# SHIBBOLETH_SP_CERT +# SHIBBOLETH_SP_PRIVKEY +# SHIBBOLETH_SP_SIGNING_CERT +# SHIBBOLETH_SP_SIGNING_PRIVKEY +# SHIBBOLETH_SP_ENCRYPT_CERT +# SHIBBOLETH_SP_ENCRYPT_PRIVKEY +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_shibboleth_sp_utils::prepare_saml_cert_key() { + + local saml_file + local owner + + if [[ -e '/etc/debian_version' ]]; then + owner='_shibd' + elif [[ -e '/etc/centos-release' ]]; then + owner='shibd' + fi + + # If defined use configured location of Shibboleth SP SAML certificate and key. + saml_file='/etc/shibboleth/sp-cert.pem' + if [[ -n "${SHIBBOLETH_SP_CERT}" ]]; then + cp "${SHIBBOLETH_SP_CERT}" "${saml_file}" + chown "${owner}" "${saml_file}" + chmod 0644 "${saml_file}" + fi + + saml_file='/etc/shibboleth/sp-key.pem' + if [[ -n "${SHIBBOLETH_SP_PRIVKEY}" ]]; then + cp "${SHIBBOLETH_SP_PRIVKEY}" "${saml_file}" + chown "${owner}" "${saml_file}" + chmod 0600 "${saml_file}" + fi + + saml_file='/etc/shibboleth/sp-signing-cert.pem' + if [[ -n "${SHIBBOLETH_SP_SIGNING_CERT}" ]]; then + cp "${SHIBBOLETH_SP_SIGNING_CERT}" "${saml_file}" + chown "${owner}" "${saml_file}" + chmod 0644 "${saml_file}" + fi + + saml_file='/etc/shibboleth/sp-signing-key.pem' + if [[ -n "${SHIBBOLETH_SP_SIGNING_PRIVKEY}" ]]; then + cp "${SHIBBOLETH_SP_SIGNING_PRIVKEY}" "${saml_file}" + chown "${owner}" "${saml_file}" + chmod 0600 "${saml_file}" + fi + + saml_file='/etc/shibboleth/sp-encrypt-cert.pem' + if [[ -n "${SHIBBOLETH_SP_ENCRYPT_CERT}" ]]; then + cp "${SHIBBOLETH_SP_ENCRYPT_CERT}" "${saml_file}" + chown "${owner}" "${saml_file}" + chmod 0644 "${saml_file}" + fi + + saml_file='/etc/shibboleth/sp-encrypt-key.pem' + if [[ -n "${SHIBBOLETH_SP_ENCRYPT_PRIVKEY}" ]]; then + cp "${SHIBBOLETH_SP_ENCRYPT_PRIVKEY}" "${saml_file}" + chown "${owner}" "${saml_file}" + chmod 0600 "${saml_file}" + fi +} + +########################################## +# Process ect/shibboleth in slash root directory if exists +# Globals: +# COMANAGE_MATCH_SLASH_ROOT_DIRECTORY +# OUTPUT +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_shibboleth_sp_utils::process_slash_root() { + + local slash_root + + slash_root="${COMANAGE_MATCH_SLASH_ROOT_DIRECTORY:-/opt/match/slashRoot}" + + # Exit if directory does not exist. + if [[ ! -d "${slash_root}/etc/shibboleth" ]]; then + return 0 + fi + + echo "Processing slash root directory ${slash_root}/etc/shibboleth..." + + pushd "${slash_root}" + + # Copy all files and preserve all details but exclude any files + # for the Shibboleth SP if they exist to allow the Shib SP + # entrypoint script to process that path and prevent a race + # condition. + find etc/shibboleth -type f | xargs -I{} cp --preserve=all --parents {} / > ${OUTPUT} 2>&1 + + popd + + echo "Done processing slash root directory ${slash_root}/etc/shibboleth" +} + +########################################## +# Manage UID and GID on files +# Globals: +# None +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_shibboleth_sp_utils::manage_uid_gid() { + + local owner + local ownership + local not_readable + + # A deployer may make their own mapping between the shibd username + # and the UID, and between the shibd group and GID, so before starting + # make sure files have the correct ownership and group. + + not_readable='/tmp/shibd-not-readable' + + if [[ -e '/etc/debian_version' ]]; then + owner='_shibd' + ownership="${owner}:${owner}" + + chown "${ownership}" /etc/shibboleth/sp-cert.pem > /dev/null 2>&1 + chown "${ownership}" /etc/shibboleth/sp-key.pem > /dev/null 2>&1 + + chown "${ownership}" /etc/shibboleth/sp-signing-cert.pem > /dev/null 2>&1 + chown "${ownership}" /etc/shibboleth/sp-signing-key.pem > /dev/null 2>&1 + + chown "${ownership}" /etc/shibboleth/sp-encrypt-cert.pem > /dev/null 2>&1 + chown "${ownership}" /etc/shibboleth/sp-encrypt-key.pem > /dev/null 2>&1 + + chown "${ownership}" /opt/shibboleth-sp/var > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/run > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/run/shibboleth > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/run/shibboleth/shibd.sock > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/log > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth/transaction.log > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth/signature.log > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth/shibd_warn.log > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth/shibd.log > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth-www > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/cache > /dev/null 2>&1 + chown "${ownership}" /opt/shibboleth-sp/var/cache/shibboleth > /dev/null 2>&1 + elif [[ -e '/etc/centos-release' ]]; then + owner='shibd' + ownership="${owner}:${owner}" + + chown "${ownership}" /etc/shibboleth/sp-cert.pem > /dev/null 2>&1 + chown "${ownership}" /etc/shibboleth/sp-key.pem > /dev/null 2>&1 + + chown "${ownership}" /etc/shibboleth/sp-signing-cert.pem > /dev/null 2>&1 + chown "${ownership}" /etc/shibboleth/sp-signing-key.pem > /dev/null 2>&1 + + chown "${ownership}" /etc/shibboleth/sp-encrypt-cert.pem > /dev/null 2>&1 + chown "${ownership}" /etc/shibboleth/sp-encrypt-key.pem > /dev/null 2>&1 + fi + + # Warn about any files the shibd user cannot read. + sudo -u "${owner}" find /etc/shibboleth ! -readable > "${not_readable}" 2>/dev/null + if [[ -s "${not_readable}" ]]; then + echo "WARNING: the following files are not readable by ${owner}" + cat "${not_readable}" + echo "" + fi + + rm -f "${not_readable}" > /dev/null 2>&1 +} + +########################################## +# Exec to start and become Shibboleth SP shibd +# Globals: +# None +# Arguments: +# Command and arguments to exec +# Returns: +# Does not return +########################################## +function comanage_shibboleth_sp_utils::exec_shibboleth_sp_daemon() { + + local user + local group + local shibd_daemon + local config + local pidfile + + comanage_shibboleth_sp_utils::consume_injected_environment + + comanage_shibboleth_sp_utils::process_slash_root + + comanage_shibboleth_sp_utils::prepare_shibboleth2xml + + comanage_shibboleth_sp_utils::prepare_saml_cert_key + + comanage_shibboleth_sp_utils::manage_uid_gid + + config='/etc/shibboleth/shibboleth2.xml' + pidfile='/var/run/shibboleth/shibd.pid' + + if [[ -e '/etc/debian_version' ]]; then + user='_shibd' + group='_shibd' + shibd_daemon='/opt/shibboleth-sp/sbin/shibd' + elif [[ -e '/etc/centos-release' ]]; then + user='shibd' + group='shibd' + shibd_daemon='/usr/sbin/shibd' + export LD_LIBRARY_PATH=/opt/shibboleth/lib64 + fi + + exec "${shibd_daemon}" -f -u "${user}" -g "${group}" -c "${config}" -p "${pidfile}" -F +} diff --git a/container/match/base/comanage_utils.sh b/container/match/base/comanage_utils.sh new file mode 100644 index 00000000..a1fed70b --- /dev/null +++ b/container/match/base/comanage_utils.sh @@ -0,0 +1,1059 @@ +#!/bin/bash + +# COmanage Match bash shell utilities +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -n "$COMANAGE_DEBUG" ] +then + OUTPUT=/dev/stdout +else + OUTPUT=/dev/null +fi + +########################################## +# Consume injected environment variables +# Globals: +# See function +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::consume_injected_environment() { + + echo "Examining environment variables..." > "$OUTPUT" + + # Configuration details that may be injected through environment + # variables or the contents of files. + local injectable_config_vars + + injectable_config_vars=( + COMANAGE_MATCH_ADMIN_USERNAME + COMANAGE_MATCH_DATABASE + COMANAGE_MATCH_DATABASE_HOST + COMANAGE_MATCH_DATABASE_PORT + COMANAGE_MATCH_DATABASE_USER + COMANAGE_MATCH_DATABASE_USER_PASSWORD + COMANAGE_MATCH_EMAIL_ACCOUNT + COMANAGE_MATCH_EMAIL_ACCOUNT_PASSWORD + COMANAGE_MATCH_EMAIL_FROM + COMANAGE_MATCH_EMAIL_HOST + COMANAGE_MATCH_EMAIL_PORT + COMANAGE_MATCH_EMAIL_TIMEOUT + COMANAGE_MATCH_EMAIL_TLS + COMANAGE_MATCH_EMAIL_TRANSPORT + COMANAGE_MATCH_HTTP_LISTEN_PORT + COMANAGE_MATCH_HTTP_NO + COMANAGE_MATCH_HTTPS_LISTEN_PORT + COMANAGE_MATCH_HTTPS_NO + COMANAGE_MATCH_OIDC_AUTH_REQUEST_PARAMS + COMANAGE_MATCH_OIDC_CLIENT_ID + COMANAGE_MATCH_OIDC_CLIENT_SECRET + COMANAGE_MATCH_OIDC_CRYPTO_PASSPHRASE + COMANAGE_MATCH_OIDC_FORWARD_HEADERS + COMANAGE_MATCH_OIDC_PROVIDER_METADATA_URL + COMANAGE_MATCH_OIDC_REMOTE_USER_CLAIM + COMANAGE_MATCH_OIDC_SCOPES + COMANAGE_MATCH_OIDC_SESSION_INACTIVITY_TIMEOUT + COMANAGE_MATCH_OIDC_SESSION_MAX_DURATION + COMANAGE_MATCH_NO_DATABASE_CONFIG + COMANAGE_MATCH_NO_EMAIL_CONFIG + COMANAGE_MATCH_REMOTE_IP + COMANAGE_MATCH_REMOTE_IP_HEADER + COMANAGE_MATCH_REMOTE_IP_INTERNAL_PROXY + COMANAGE_MATCH_REMOTE_IP_INTERNAL_PROXY_LIST + COMANAGE_MATCH_REMOTE_IP_PROXIES_HEADER + COMANAGE_MATCH_REMOTE_IP_PROXY_PROTOCOL + COMANAGE_MATCH_REMOTE_IP_PROXY_PROTOCOL_EXCEPTIONS + COMANAGE_MATCH_REMOTE_IP_TRUSTED_PROXY + COMANAGE_MATCH_REMOTE_IP_TRUSTED_PROXY_LIST + COMANAGE_MATCH_SECURITY_SALT + COMANAGE_MATCH_PHP_SESSION_REDIS_URL + COMANAGE_MATCH_SKIP_SETUP + COMANAGE_MATCH_SKIP_UPGRADE + COMANAGE_MATCH_SLASH_ROOT_DIRECTORY + COMANAGE_MATCH_VIRTUAL_HOST_FQDN + COMANAGE_MATCH_VIRTUAL_HOST_REDIRECT_HTTP_NO + COMANAGE_MATCH_VIRTUAL_HOST_SCHEME + COMANAGE_MATCH_VIRTUAL_HOST_PORT + HTTPS_CERT_FILE + HTTPS_PRIVKEY_FILE + ) + + # If the file associated with a configuration variable is present then + # read the value from it into the appropriate variable. So for example + # if the variable COMANAGE_MATCH_DATABASE_USER_PASSWORD_FILE exists and its + # value points to a file on the file system then read the contents + # of that file into the variable COMANAGE_MATCH_DATABASE_USER_PASSWORD. + + local config_var + for config_var in "${injectable_config_vars[@]}" + do + local file_name + eval file_name=\$"${config_var}_FILE"; + + if [[ -e "$file_name" ]]; then + declare -g "${config_var}"=`cat $file_name` + echo "Set ${config_var} to be contents of ${file_name}" > "$OUTPUT" + fi + done + + echo "Done examining environment variables" > "$OUTPUT" +} + +########################################## +# Enable the Apache HTTP Server virtual host +# Globals: +# OUTPUT +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::enable_virtual_host() { + + local a2site + + a2site="000-comanage" + + /usr/sbin/a2ensite "${a2site}" > "${OUTPUT}" 2>&1 +} + +########################################## +# Exec to start and become Apache HTTP Server +# Globals: +# COMANAGE_MATCH_NO_DATABASE_CONFIG +# COMANAGE_MATCH_NO_EMAIL_CONFIG +# Arguments: +# Command and arguments to exec +# Returns: +# Does not return +########################################## +function comanage_utils::exec_apache_http_server() { + + comanage_utils::consume_injected_environment + + comanage_utils::process_slash_root + + comanage_utils::prepare_local_directory + + if [[ -z ${COMANAGE_MATCH_NO_DATABASE_CONFIG} ]]; then + comanage_utils::prepare_database_config + fi + + if [[ -z ${COMANAGE_MATCH_NO_EMAIL_CONFIG} ]]; then + comanage_utils::prepare_email_config + fi + + comanage_utils::prepare_https_cert_key + + comanage_utils::prepare_server_name + + comanage_utils::prepare_mod_remoteip + + comanage_utils::prepare_virtual_host + + comanage_utils::enable_virtual_host + + comanage_utils::prepare_php_session + + comanage_utils::wait_database_connectivity + + comanage_utils::match_setup + + comanage_utils::match_upgrade + + comanage_utils::match_clear_cache + + comanage_utils::tmp_ownership + + # first arg is `-f` or `--some-option` + if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" + fi + + exec "$@" +} + +########################################## +# Prepare database configuration +# Globals: +# COMANAGE_MATCH_DATABASE +# COMANAGE_MATCH_DATABASE_HOST +# COMANAGE_MATCH_DATABASE_PORT +# COMANAGE_MATCH_DATABASE_USER +# COMANAGE_MATCH_DATABASE_USER_PASSWORD +# COMANAGE_MATCH_DIR +# OUTPUT +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::prepare_database_config() { + + # If the COmanage Match database configuration file does not exist + # then try to create it from injected information with reasonable defaults + # that aid simple evaluation deployments. + local database_config + database_config="$COMANAGE_MATCH_DIR/local/Config/database.php" + + # File already exists so return. + if [[ -e "$database_config" ]]; then + return + fi + + # File does not exist so create it. + local php_string + + read -r -d '' php_string <<'EOF' + [ + 'default' => [ + 'className' => 'Cake\Database\Connection', + 'driver' => 'Cake\Database\Driver\Postgres', +EOF + php_string+=$'\n ' + php_string+="'host' => '${COMANAGE_MATCH_DATABASE_HOST:-comanage-match-database}'," + + php_string+=$'\n ' + php_string+="'username' => '${COMANAGE_MATCH_DATABASE_USER:-match_user}'," + + php_string+=$'\n ' + php_string+="'password' => '${COMANAGE_MATCH_DATABASE_USER_PASSWORD:-password}'," + + php_string+=$'\n ' + php_string+="'database' => '${COMANAGE_MATCH_DATABASE:-match}'," + + # The value of port is an integer. + if [[ -n "${COMANAGE_MATCH_DATABASE_PORT}" ]]; then + php_string+=$'\n ' + php_string+="'port' => ${COMANAGE_MATCH_DATABASE_PORT}," + fi + + php_string+=$'\n ]\n ]\n\n ];\n'; + + printf "%s" "$php_string" > $database_config + + echo "Wrote new database configuration file ${database_config}" > "$OUTPUT" +} + +########################################## +# Prepare email configuration +# Globals: +# COMANAGE_MATCH_EMAIL_ACCOUNT +# COMANAGE_MATCH_EMAIL_ACCOUNT_PASSWORD +# COMANAGE_MATCH_EMAIL_FROM +# COMANAGE_MATCH_EMAIL_HOST +# COMANAGE_MATCH_EMAIL_PORT +# COMANAGE_MATCH_EMAIL_TIMEOUT +# COMANAGE_MATCH_EMAIL_TLS +# COMANAGE_MATCH_EMAIL_TRANSPORT +# COMANAGE_MATCH_DIR +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::prepare_email_config() { + + # If the COmanage Match email configuration file does not exist + # then try to create it from injected information with reasonable defaults + # that aid simple evaluation deployments. + local email_config + email_config="$COMANAGE_MATCH_DIR/local/Config/email.php" + + # File already exists so return. + if [[ -e "$email_config" ]]; then + return + fi + + # File does not exist so create it. + local php_string + + read -r -d '' php_string <<'EOF' + [ + 'default' => [ +EOF + php_string+=$'\n ' + php_string+="'transport' => '${COMANAGE_MATCH_EMAIL_TRANSPORT:-Smtp}'," + + if [[ -n "${COMANAGE_MATCH_EMAIL_HOST}" ]]; then + php_string+=$'\n ' + php_string+="'host' => '${COMANAGE_MATCH_EMAIL_HOST}'," + fi + + # The value of port is an integer. + if [[ -n "${COMANAGE_MATCH_EMAIL_PORT}" ]]; then + php_string+=$'\n ' + php_string+="'port' => ${COMANAGE_MATCH_EMAIL_PORT}," + fi + + # The value of timeout is an integer. + if [[ -n "${COMANAGE_MATCH_EMAIL_TIMEOUT}" ]]; then + php_string+=$'\n ' + php_string+="'timeout' => ${COMANAGE_MATCH_EMAIL_TIMEOUT}," + fi + + if [[ -n "${COMANAGE_MATCH_EMAIL_ACCOUNT}" ]]; then + php_string+=$'\n ' + php_string+="'username' => '${COMANAGE_MATCH_EMAIL_ACCOUNT}'," + fi + + if [[ -n "${COMANAGE_MATCH_EMAIL_ACCOUNT_PASSWORD}" ]]; then + php_string+=$'\n ' + php_string+="'password' => '${COMANAGE_MATCH_EMAIL_ACCOUNT_PASSWORD}'," + fi + + # The value of tls is a PHP boolean. + php_string+=$'\n ' + php_string+="'tls' => ${COMANAGE_MATCH_EMAIL_TLS:-true}," + + php_string+=$'\n ],' + php_string+=$'\n ],' + php_string+=$'\n ' + php_string+=$"'Email' => [" + php_string+=$'\n ' + php_string+=$"'default' => [" + php_string+=$'\n ' + php_string+=$"'transport' => 'default'," + + php_string+=$'\n ' + + # Prefer the array of sender email and name if available, but + # if not then prefer the sender email over the older default + # and if neither is set use a default since the 'from' + # configuration key is always required. + if [[ -n "${COMANAGE_MATCH_EMAIL_FROM_EMAIL}" && -n "${COMANAGE_MATCH_EMAIL_FROM_NAME}" ]]; then + php_string+="'from' => ['${COMANAGE_MATCH_EMAIL_FROM_EMAIL}' => '${COMANAGE_MATCH_EMAIL_FROM_NAME}']," + elif [[ -n "${COMANAGE_MATCH_EMAIL_FROM_EMAIL}" && -z "${COMANAGE_MATCH_EMAIL_FROM_NAME}" ]]; then + php_string+="'from' => '${COMANAGE_MATCH_EMAIL_FROM_EMAIL}'," + elif [[ -n "${COMANAGE_MATCH_EMAIL_FROM}" && -z "${COMANAGE_MATCH_EMAIL_FROM_EMAIL}" ]]; then + php_string+="'from' => '${COMANAGE_MATCH_EMAIL_FROM}'," + elif [[ -z "${COMANAGE_MATCH_EMAIL_FROM}" ]]; then + php_string+="'from' => 'you@localhost'," + fi + + php_string+=$'\n ],\n ],\n ];\n' + + printf "%s" "$php_string" > $email_config +} + +########################################## +# Prepare cert and key for HTTPS +# Globals: +# HTTPS_CERT_FILE +# HTTPS_PRIVKEY_FILE +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::prepare_https_cert_key() { + + local cert_path + local privkey_path + local web_user + + if [[ -e '/etc/debian_version' ]]; then + cert_path='/etc/apache2/cert.pem' + privkey_path='/etc/apache2/privkey.pem' + web_user='www-data' + elif [[ -e '/etc/centos-release' ]]; then + cert_path='/etc/httpd/cert.pem' + privkey_path='/etc/httpd/privkey.pem' + web_user='apache' + fi + + # If defined use configured location of Apache HTTP Server + # HTTPS certificate and key files. The certificate file may also + # include intermediate CA certificates, sorted from leaf to root. + if [[ -n "${HTTPS_CERT_FILE}" ]]; then + rm -f "${cert_path}" + cp "${HTTPS_CERT_FILE}" "${cert_path}" + chown "${web_user}" "${cert_path}" + chmod 0644 "${cert_path}" + echo "Copied HTTPS certificate file ${HTTPS_CERT_FILE} to ${cert_path}" > "$OUTPUT" + echo "Set ownership of ${cert_path} to ${web_user}" > "$OUTPUT" + fi + + if [[ -n "${HTTPS_PRIVKEY_FILE}" ]]; then + rm -f "${privkey_path}" + cp "${HTTPS_PRIVKEY_FILE}" "${privkey_path}" + chown "${web_user}" "${privkey_path}" + chmod 0600 "${privkey_path}" + echo "Copied HTTPS private key file ${HTTPS_PRIVKEY_FILE} to ${privkey_path}" > "$OUTPUT" + echo "Set ownership of ${privkey_path} to ${web_user}" > "$OUTPUT" + fi +} + +########################################## +# Prepare local directory structure +# Globals: +# COMANAGE_MATCH_DIR +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::prepare_local_directory() { + + # Make sure the directory structure we need is available + # in the data volume for $COMANAGE_MATCH_DIR/local + local directories + + declare -a directories=("Config" + "logs" + "tmp" + ) + + local dir + local full_path + for dir in "${directories[@]}" + do + full_path="${COMANAGE_MATCH_DIR}/local/${dir}" + if [[ ! -d "${full_path}" ]]; then + mkdir -p "${full_path}" > "$OUTPUT" 2>&1 + echo "Created directory ${full_path}" + fi + done +} + +########################################## +# Prepare mod_remoteip +# Globals: +# COMANAGE_MATCH_REMOTE_IP +# COMANAGE_MATCH_REMOTE_IP_HEADER +# COMANAGE_MATCH_REMOTE_IP_INTERNAL_PROXY +# COMANAGE_MATCH_REMOTE_IP_INTERNAL_PROXY_LIST +# COMANAGE_MATCH_REMOTE_IP_PROXIES_HEADER +# COMANAGE_MATCH_REMOTE_IP_PROXY_PROTOCOL +# COMANAGE_MATCH_REMOTE_IP_PROXY_PROTOCOL_EXCEPTIONS +# COMANAGE_MATCH_REMOTE_IP_TRUSTED_PROXY +# COMANAGE_MATCH_REMOTE_IP_TRUSTED_PROXY_LIST +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::prepare_mod_remoteip() { + + local remoteip_config + remoteip_config="/etc/apache2/mods-available/remoteip.conf" + + if [[ -n "${COMANAGE_MATCH_REMOTE_IP}" ]]; then + echo "RemoteIPHeader ${COMANAGE_MATCH_REMOTE_IP_HEADER:-X-Forwarded-For}" >> $remoteip_config + + if [[ -n "${COMANAGE_MATCH_REMOTE_IP_INTERNAL_PROXY}" ]]; then + echo "RemoteIPInternalProxy ${COMANAGE_MATCH_REMOTE_IP_INTERNAL_PROXY}" >> $remoteip_config + fi + + if [[ -n "${COMANAGE_MATCH_REMOTE_IP_INTERNAL_PROXY_LIST}" ]]; then + echo "RemoteIPInternalProxyList ${COMANAGE_MATCH_REMOTE_IP_INTERNAL_PROXY_LIST}" >> $remoteip_config + fi + + if [[ -n "${COMANAGE_MATCH_REMOTE_IP_PROXIES_HEADER}" ]]; then + echo "RemoteIPProxiesHeader ${COMANAGE_MATCH_REMOTE_IP_PROXIES_HEADER}" >> $remoteip_config + fi + + if [[ -n "${COMANAGE_MATCH_REMOTE_IP_PROXY_PROTOCOL}" ]]; then + echo "RemoteIPProxyProtocol ${COMANAGE_MATCH_REMOTE_IP_PROXY_PROTOCOL}" >> $remoteip_config + fi + + if [[ -n "${COMANAGE_MATCH_REMOTE_IP_PROXY_PROTOCOL_EXCEPTIONS}" ]]; then + echo "RemoteIPProxyProcotolException ${COMANAGE_MATCH_REMOTE_IP_PROXY_PROTOCOL_EXCEPTIONS}" >> $remoteip_config + fi + + if [[ -n "${COMANAGE_MATCH_REMOTE_IP_TRUSTED_PROXY}" ]]; then + echo "RemoteIPTrustedProxy ${COMANAGE_MATCH_REMOTE_IP_TRUSTED_PROXY}" >> $remoteip_config + fi + + if [[ -n "${COMANAGE_MATCH_REMOTE_IP_TRUSTED_PROXY_LIST}" ]]; then + echo "RemoteIPTrustedProxyList ${COMANAGE_MATCH_REMOTE_IP_TRUSTED_PROXY_LIST}" >> $remoteip_config + fi + + /usr/sbin/a2enmod remoteip > "$OUTPUT" 2>&1 + fi +} + +########################################## +# Prepare PHP session storage +# Globals: +# COMANAGE_MATCH_PHP_SESSION_REDIS_URL +# OUTPUT +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::prepare_php_session() { + + local php_ini + php_ini="/usr/local/etc/php" + + # Configure Redis for sessions if so configured. + if [[ -n "${COMANAGE_MATCH_PHP_SESSION_REDIS_URL}" ]]; then + sed -i -e '/session.save_handler/ s+files+redis+' $php_ini > ${OUTPUT} 2>&1 + sed -i -e "/session.save_handler/a session.save_path = ${COMANAGE_MATCH_PHP_SESSION_REDIS_URL}" $phi_ini > ${OUTPUT} 2>&1 + fi +} + +########################################## +# Prepare web server name +# Globals: +# SERVER_NAME +# COMANAGE_MATCH_VIRTUAL_HOST_FQDN +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::prepare_server_name() { + + # If COMANAGE_MATCH_VIRTUAL_HOST_FQDN has not been injected try to determine + # it from the HTTPS_CERT_FILE. + if [[ -z "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then + COMANAGE_MATCH_VIRTUAL_HOST_FQDN=$(openssl x509 -in /etc/apache2/cert.pem -text -noout | + sed -n '/X509v3 Subject Alternative Name:/ {n;p}' | + sed -E 's/.*DNS:(.*)\s*$/\1/') + if [[ -n "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then + echo "Set COMANAGE_MATCH_VIRTUAL_HOST_FQDN=${COMANAGE_MATCH_VIRTUAL_HOST_FQDN} using Subject Alternative Name from x509 certificate" > "$OUTPUT" + else + COMANAGE_MATCH_VIRTUAL_HOST_FQDN=$(openssl x509 -in /etc/apache2/cert.pem -subject -noout | + sed -E 's/subject=.*CN=(.*)\s*/\1/') + if [[ -n "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then + echo "Set COMANAGE_MATCH_VIRTUAL_HOST_FQDN=${COMANAGE_MATCH_VIRTUAL_HOST_FQDN} using CN from x509 certificate" > "$OUTPUT" + fi + fi + fi + + # Configure Apache HTTP Server with the server name. + # This configures the server name for the default Debian + # Apache HTTP Server configuration but not the server name used + # by any virtual hosts. + if [[ -e '/etc/debian_version' ]]; then + cat > /etc/apache2/conf-available/server-name.conf < "$OUTPUT" 2>&1 + fi + + # Export the server name so that it may be used by + # Apache HTTP Server virtual host configurations. + export COMANAGE_MATCH_VIRTUAL_HOST_FQDN +} + +########################################## +# Prepare web server virtual host configuration +# Globals: +# COMANAGE_MATCH_HTTP_LISTEN_PORT +# COMANAGE_MATCH_HTTP_NO +# COMANAGE_MATCH_HTTPS_LISTEN_PORT +# COMANAGE_MATCH_HTTPS_NO +# COMANAGE_MATCH_VIRTUAL_HOST_REDIRECT_HTTP_NO +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::prepare_virtual_host() { + + local ports_config + local virtual_host_config + + ports_config="/etc/apache2/ports.conf" + virtual_host_config="/etc/apache2/sites-available/000-comanage.conf" + + # Configure the listening ports. + /bin/rm -f $ports_config > "${OUTPUT}" 2>&1 + + if [[ -z "${COMANAGE_MATCH_HTTP_NO}" ]]; then + echo "Listen ${COMANAGE_MATCH_HTTP_LISTEN_PORT:-80}" >> $ports_config + fi + + if [[ -z "${COMANAGE_MATCH_HTTPS_NO}" ]]; then + echo "Listen ${COMANAGE_MATCH_HTTPS_LISTEN_PORT:-443}" >> $ports_config + fi + + # Do not overwrite an existing virtual host configuration. + if [[ -e $virtual_host_config ]]; then + return 0 + fi + + if [[ -z "${COMANAGE_MATCH_HTTP_NO}" ]]; then + # Write configuration for HTTP virtual host. + comanage_utils::virtual_host_http_opening $virtual_host_config + + if [[ -z "${COMANAGE_MATCH_VIRTUAL_HOST_REDIRECT_HTTP_NO}" ]]; then + # Write configuration for redirecting HTTP to HTTPS. + comanage_utils::virtual_host_http_redirect $virtual_host_config + else + # Write full configuration for HTTP including authentication. + comanage_utils::virtual_host_general_config $virtual_host_config + comanage_utils::virtual_host_authentication $virtual_host_config + fi + + # Write close for virtual host. + comanage_utils::virtual_host_close $virtual_host_config + + fi + + if [[ -z "${COMANAGE_MATCH_HTTPS_NO}" ]]; then + # Write configuration for HTTPS. + comanage_utils::virtual_host_https_opening $virtual_host_config + comanage_utils::virtual_host_general_config $virtual_host_config + comanage_utils::virtual_host_authentication $virtual_host_config + comanage_utils::virtual_host_close $virtual_host_config + fi +} + +########################################## +# Process slash root directory if exists +# Globals: +# COMANAGE_MATCH_SLASH_ROOT_DIRECTORY +# OUTPUT +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::process_slash_root() { + + local slash_root + + slash_root="${COMANAGE_MATCH_SLASH_ROOT_DIRECTORY:-/opt/match/slashRoot}" + + # Exit if directory does not exist. + if [[ ! -d "${slash_root}" ]]; then + return 0 + fi + + echo "Processing slash root directory ${slash_root}..." + + pushd "${slash_root}" + + # Copy all files and preserve all details but exclude any files + # for the Shibboleth SP if they exist to allow the Shib SP + # entrypoint script to process that path and prevent a race + # condition. + find . -type f -not -path "./etc/shibboleth/*" | xargs -I{} cp --preserve=all --parents {} / > ${OUTPUT} 2>&1 + + popd + + echo "Done processing slash root directory ${slash_root}" +} + +########################################## +# Clear CakePHP cache files +# Globals: +# COMANAGE_MATCH_DIR +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::match_clear_cache() { + + pushd "${COMANAGE_MATCH_DIR}/app" > "$OUTPUT" 2>&1 + + ./bin/cake cache clear_all > "$OUTPUT" 2>&1 + ./bin/cake schema_cache clear > "$OUTPUT" 2>&1 + + echo "Cleared COmanage Match CakePHP cache files" > "$OUTPUT" + + popd > "$OUTPUT" 2>&1 +} + +########################################## +# Run COmanage Match setup shell command +# Globals: +# COMANAGE_MATCH_ADMIN_USERNAME +# COMANAGE_MATCH_DIR +# COMANAGE_MATCH_SECURITY_SALT +# COMANAGE_MATCH_SKIP_SETUP +# OUTPUT +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::match_setup() { + + if [[ -n "${COMANAGE_MATCH_SKIP_SETUP}" ]]; then + echo "Skipping database setup step" > "$OUTPUT" 2>&1 + return 0 + fi + + # We only want to run the setup script once since it creates + # state in the database. + local auto_generated_security + pushd "$COMANAGE_MATCH_DIR/app" > "$OUTPUT" 2>&1 + echo "Testing if COmanage Match setup has been done previously..." > "$OUTPUT" + if ! ./bin/cake databaseSetupAlready > "$OUTPUT" 2>&1; then + echo "COmanage Match database is not setup yet..." > "$OUTPUT" + rm -f "$COMANAGE_MATCH_DIR/local/Config/security.salt" > "$OUTPUT" 2>&1 + echo "Running ./bin/cake setup..." > "$OUTPUT" + ./bin/cake setup --admin-username "${COMANAGE_MATCH_ADMIN_USERNAME}" > "$OUTPUT" 2>&1 + echo "Set admin username ${COMANAGE_MATCH_ADMIN_USERNAME}" > "$OUTPUT" + auto_generated_security=1 + fi + + popd > "$OUTPUT" 2>&1 + + comanage_utils::match_clear_cache + + # If COmanage Match CakePHP security salt has been + # injected and the files do not otherwise exist create them. + if [[ -n "$COMANAGE_MATCH_SECURITY_SALT" && + ( -n "$auto_generated_security" || ! -e "$COMANAGE_MATCH_DIR/local/Config/security.salt" ) ]]; then + echo "$COMANAGE_MATCH_SECURITY_SALT" > "$COMANAGE_MATCH_DIR/local/Config/security.salt" + fi +} + +########################################## +# Set tmp directory file ownership +# Globals: +# COMANAGE_MATCH_DIR +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::tmp_ownership() { + + # Ensure that the web server user owns the tmp directory + # and all children. + local tmp_dir + local ownership + + if [[ -e '/etc/debian_version' ]]; then + ownership='www-data:www-data' + elif [[ -e '/etc/centos-release' ]]; then + ownership='apache:apache' + fi + + tmp_dir="${COMANAGE_MATCH_DIR}/app/tmp" + + chown -R "${ownership}" "${tmp_dir}" + + echo "Recursively set ownership of ${tmp_dir} to ${ownership}" > "$OUTPUT" + +} + +########################################## +# Write virtual host authentication stanza +# Globals: +# COMANAGE_MATCH_OIDC_AUTH_REQUEST_PARAMS +# COMANAGE_MATCH_OIDC_CLIENT_ID +# COMANAGE_MATCH_OIDC_CLIENT_SECRET +# COMANAGE_MATCH_OIDC_CRYPTO_PASSPHRASE +# COMANAGE_MATCH_OIDC_FORWARD_HEADERS +# COMANAGE_MATCH_OIDC_PROVIDER_METADATA_URL +# COMANAGE_MATCH_OIDC_REMOTE_USER_CLAIM +# COMANAGE_MATCH_OIDC_SCOPES +# COMANAGE_MATCH_OIDC_SESSION_INACTIVITY_TIMEOUT +# COMANAGE_MATCH_OIDC_SESSION_MAX_DURATION +# COMANAGE_MATCH_VIRTUAL_HOST_FQDN +# Arguments: +# Path to file +# Returns: +# None +########################################## +function comanage_utils::virtual_host_authentication() { + local a2query_out + local mod_auth_openidc + local shib + local virtual_host_config + + virtual_host_config="$1" + + mod_auth_openidc=0 + shib=0 + + # Test for mod_auth_openidc module. + (a2query -m auth_openidc) > /dev/null 2>&1 + a2query_out=$? + if [[ $a2query_out -eq 0 ]]; then + mod_auth_openidc=1 + fi + + # Test for shib2 module. + (a2query -m shib2) > /dev/null 2>&1 + a2query_out=$? + if [[ $a2query_out -eq 0 ]]; then + shib=1 + fi + + # Write mod_auth_openidc if module enabled. + if [[ $mod_auth_openidc -eq 1 ]]; then + cat >> $virtual_host_config <> $virtual_host_config <> $virtual_host_config <> $virtual_host_config < + AuthType openid-connect + Require valid-user + + + +Options Indexes FollowSymLinks +DirectoryIndex index.php +AllowOverride All +AuthType openid-connect +OIDCUnAuthAction pass +Require valid-user + + + +AuthType openid-connect +OIDCUnAuthAction auth +Require valid-user + + +RewriteEngine On +RewriteCond %{QUERY_STRING} !after_redirect +RewriteRule ^/match/auth/logout/logout.php https://%{HTTP_HOST}/secure/redirect?logout=https://%{HTTP_HOST}/match/auth/logout/logout.php?after_redirect [L,R] +EOF + + # Write shib if module enabled. + elif [[ $shib -eq 1 ]]; then + cat >> $virtual_host_config < +SetHandler shib + + + +AuthType shibboleth +ShibRequestSetting requireSession 1 +Require valid-user + + + +AuthType shibboleth +Require shibboleth + + +RewriteEngine On +RewriteCond %{QUERY_STRING} !after_redirect +RewriteRule ^/match/auth/logout/logout.php https://%{HTTP_HOST}/Shibboleth.sso/Logout?return=https://%{HTTP_HOST}/match/auth/logout/logout.php?after_redirect [L,R] +EOF + + # Else assume basic authentication. + else + cat >> $virtual_host_config < +AuthType Basic +AuthName "COmanage Match Login" +AuthBasicProvider file +AuthUserFile "/etc/apache2/basic-auth" +Require valid-user + +EOF + fi +} + +########################################## +# Write virtual host closing stanza +# Globals: +# Arguments: +# Path to file +# Returns: +# None +########################################## +function comanage_utils::virtual_host_close() { + local virtual_host_config + + virtual_host_config="$1" + + cat >> $virtual_host_config < +EOF +} + +########################################## +# Write virtual host general configuration +# Globals: +# Arguments: +# Path to file +# Returns: +# None +########################################## +function comanage_utils::virtual_host_general_config() { + + local virtual_host_config + virtual_host_config="$1" + + cat >> $virtual_host_config <<"EOF" +DocumentRoot /var/www/html + +RedirectMatch ^/$ /match/ + +LogFormat "%a %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogLevel warn +ErrorLog ${APACHE_LOG_DIR}/error.log +CustomLog ${APACHE_LOG_DIR}/access.log combined + + +Options Indexes FollowSymLinks +DirectoryIndex index.php +AllowOverride All +Require all granted + +EOF + +} + +########################################## +# Write virtual host HTTP opening stanza +# Globals: +# COMANAGE_MATCH_HTTP_LISTEN_PORT +# COMANAGE_MATCH_VIRTUAL_HOST_FQDN +# COMANAGE_MATCH_VIRTUAL_HOST_PORT +# COMANAGE_MATCH_VIRTUAL_HOST_SCHEME +# Arguments: +# Path to file +# Returns: +# None +########################################## +function comanage_utils::virtual_host_http_opening() { + + local virtual_host_config + virtual_host_config="$1" + + cat >> $virtual_host_config < +ServerName ${COMANAGE_MATCH_VIRTUAL_HOST_SCHEME:-http}://${COMANAGE_MATCH_VIRTUAL_HOST_FQDN}:${COMANAGE_MATCH_VIRTUAL_HOST_PORT:-80} +UseCanonicalName On +EOF +} + +########################################## +# Write virtual host HTTPS opening stanza +# Globals: +# COMANAGE_MATCH_VIRTUAL_HOST_SCHEME +# COMANAGE_MATCH_VIRTUAL_HOST_FQDN +# COMANAGE_MATCH_VIRTUAL_HOST_PORT +# COMANAGE_MATCH_HTTPS_LISTEN_PORT +# Arguments: +# Path to file +# Returns: +# None +########################################## +function comanage_utils::virtual_host_https_opening() { + + local virtual_host_config + virtual_host_config="$1" + + cat >> $virtual_host_config < +ServerName ${COMANAGE_MATCH_VIRTUAL_HOST_SCHEME:-https}://${COMANAGE_MATCH_VIRTUAL_HOST_FQDN}:${COMANAGE_MATCH_VIRTUAL_HOST_PORT:-443} +UseCanonicalName On + +Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" + +SSLEngine on +SSLProtocol all -SSLv2 -SSLv3 +SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH +SSLHonorCipherOrder on + +SSLCertificateFile /etc/apache2/cert.pem +SSLCertificateKeyFile /etc/apache2/privkey.pem +EOF + +} + +########################################## +# Write virtual host HTTP redirect stanza +# Globals: +# Arguments: +# Path to file +# Returns: +# None +########################################## +function comanage_utils::virtual_host_http_redirect() { + + local virtual_host_config + virtual_host_config="$1" + + cat >> $virtual_host_config <<"EOF" +RewriteEngine On +RewriteCond %{HTTPS} off +RewriteRule ^ https://%{HTTP_HOST}:443%{REQUEST_URI} [R=302,L,QSA] +EOF + +} + +########################################## +# Wait until able to connect to database +# Globals: +# COMANAGE_MATCH_DIR +# OUTPUT +# Arguments: +# None +# Returns: +# None +########################################## +function comanage_utils::wait_database_connectivity() { + pushd "$COMANAGE_MATCH_DIR/app" > "$OUTPUT" 2>&1 + + # Loop until we are able to open a connection to the database. + echo "Testing database connectivity..." > "$OUTPUT" + until ./bin/cake databaseConnectivityTest > "$OUTPUT" 2>&1; do + >&2 echo "Database is unavailable - sleeping" + sleep 1 + done + + echo "Database is available" > "$OUTPUT" + + popd > "$OUTPUT" 2>&1 +} diff --git a/container/match/base/docker-comanage-match-entrypoint b/container/match/base/docker-comanage-match-entrypoint new file mode 100755 index 00000000..2200e7d9 --- /dev/null +++ b/container/match/base/docker-comanage-match-entrypoint @@ -0,0 +1,24 @@ +#!/bin/bash + +# COmanage Match Dockerfile entrypoint +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +source /usr/local/lib/comanage_utils.sh + +comanage_utils::exec_apache_http_server "$@" diff --git a/container/match/basic-auth/Dockerfile b/container/match/basic-auth/Dockerfile new file mode 100644 index 00000000..ba719676 --- /dev/null +++ b/container/match/basic-auth/Dockerfile @@ -0,0 +1,27 @@ +# COmanage Match Dockerfile +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +ARG COMANAGE_MATCH_VERSION=develop +ARG COMANAGE_MATCH_BASE_IMAGE_VERSION=1 +FROM comanage-match-base:${COMANAGE_MATCH_VERSION}-${COMANAGE_MATCH_BASE_IMAGE_VERSION} + +ARG COMANAGE_MATCH_BASE_IMAGE_VERSION +ENV COMANAGE_MATCH_BASE_IMAGE_VERSION ${COMANAGE_MATCH_BASE_IMAGE_VERSION} +LABEL comanage_match_base_image_version=${COMANAGE_MATCH_BASE_IMAGE_VERSION} + +COPY container/match/basic-auth/basic-auth /etc/apache2/ diff --git a/container/match/basic-auth/basic-auth b/container/match/basic-auth/basic-auth new file mode 100644 index 00000000..fee8aa3b --- /dev/null +++ b/container/match/basic-auth/basic-auth @@ -0,0 +1 @@ +match.admin:$apr1$qqrvav7G$nSHYErU4ljDPmO1wNBG6e0 diff --git a/container/match/mod_auth_openidc/Dockerfile b/container/match/mod_auth_openidc/Dockerfile new file mode 100644 index 00000000..d161476d --- /dev/null +++ b/container/match/mod_auth_openidc/Dockerfile @@ -0,0 +1,71 @@ +# COmanage Match Dockerfile +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +ARG COMANAGE_MATCH_VERSION=develop +ARG COMANAGE_MATCH_BASE_IMAGE_VERSION=1 +ARG MOD_AUTH_OPENIDC_VERSION + +FROM comanage-match-base:${COMANAGE_MATCH_VERSION}-${COMANAGE_MATCH_BASE_IMAGE_VERSION} AS comanage + +FROM debian:11-slim AS building + +ARG MOD_AUTH_OPENIDC_VERSION +ENV MOD_AUTH_OPENIDC_VERSION ${MOD_AUTH_OPENIDC_VERSION:-2.4.11} + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apache2 \ + apache2-dev \ + automake \ + ca-certificates \ + libcjose0 \ + libcjose-dev \ + libcurl4-openssl-dev \ + libjansson-dev \ + libpcre3-dev \ + libssl-dev \ + pkg-config \ + wget + +RUN MOD_AUTH_OPENIDC_URL="https://github.com/zmartzone/mod_auth_openidc/releases/download/v${MOD_AUTH_OPENIDC_VERSION}/mod_auth_openidc-${MOD_AUTH_OPENIDC_VERSION}.tar.gz" \ + && mkdir -p /tmp/mod_auth_openidc \ + && wget -O mod_auth_openidc.tar.gz "${MOD_AUTH_OPENIDC_URL}" \ + && tar -zxf mod_auth_openidc.tar.gz -C /tmp/mod_auth_openidc --strip-components=1 \ + && cd /tmp/mod_auth_openidc \ + && ./configure --with-apxs2=`which apxs2` \ + && make \ + && make install + +FROM comanage + +ARG COMANAGE_MATCH_BASE_IMAGE_VERSION +ENV COMANAGE_MATCH_BASE_IMAGE_VERSION ${COMANAGE_MATCH_BASE_IMAGE_VERSION} +LABEL comanage_match_base_image_version=${COMANAGE_MATCH_BASE_IMAGE_VERSION} + +ARG MOD_AUTH_OPENIDC_VERSION +ENV MOD_AUTH_OPENIDC_VERSION ${MOD_AUTH_OPENIDC_VERSION:-2.4.10} +LABEL mod_auth_openidc_version ${MOD_AUTH_OPENIDC_VERSION} + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + libcjose0 + +COPY --from=building /usr/lib/apache2/modules/mod_auth_openidc.so /usr/lib/apache2/modules/mod_auth_openidc.so + +RUN echo "LoadModule auth_openidc_module /usr/lib/apache2/modules/mod_auth_openidc.so" > /etc/apache2/mods-available/auth_openidc.load \ + && a2enmod auth_openidc diff --git a/container/match/shibboleth-sp-supervisor/Dockerfile b/container/match/shibboleth-sp-supervisor/Dockerfile new file mode 100644 index 00000000..37b6722f --- /dev/null +++ b/container/match/shibboleth-sp-supervisor/Dockerfile @@ -0,0 +1,64 @@ +# COmanage Match Dockerfile +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +ARG COMANAGE_MATCH_VERSION=develop +ARG COMANAGE_MATCH_BASE_IMAGE_VERSION=1 +ARG COMANAGE_MATCH_SHIBBOLETH_SP_VERSION="3.4.0" +ARG COMANAGE_MATCH_SHIBBOLETH_SP_BASE_IMAGE_VERSION=1 + +FROM comanage-match-shibboleth-sp-base:${COMANAGE_MATCH_SHIBBOLETH_SP_VERSION}-${COMANAGE_MATCH_SHIBBOLETH_SP_BASE_IMAGE_VERSION} AS shib-base + +FROM comanage-match-base:${COMANAGE_MATCH_VERSION}-${COMANAGE_MATCH_BASE_IMAGE_VERSION} AS comanage + +ARG COMANAGE_MATCH_BASE_IMAGE_VERSION +ENV COMANAGE_MATCH_BASE_IMAGE_VERSION ${COMANAGE_MATCH_BASE_IMAGE_VERSION} +LABEL comanage_match_base_image_version=${COMANAGE_MATCH_BASE_IMAGE_VERSION} + +ARG COMANAGE_MATCH_SHIBBOLETH_SP_VERSION +ENV COMANAGE_MATCH_SHIBBOLETH_SP_VERSION ${COMANAGE_MATCH_SHIBBOLETH_SP_VERSION} +LABEL comanage_match_shibboleth_sp_version=${COMANAGE_MATCH_SHIBBOLETH_SP_VERSION} + +ARG COMANAGE_MATCH_SHIBBOLETH_SP_BASE_IMAGE_VERSION +ENV COMANAGE_MATCH_SHIBBOLETH_SP_BASE_IMAGE_VERSION ${COMANAGE_MATCH_SHIBBOLETH_SP_BASE_IMAGE_VERSION} +LABEL comanage_match_shibboleth_sp_base_image_version ${COMANAGE_MATCH_SHIBBOLETH_SP_BASE_IMAGE_VERSION} + +RUN apt-get install -y --no-install-recommends supervisor \ + && mkdir -p /var/log/supervisor + +COPY --from=shib-base /opt/shibboleth-sp /opt/shibboleth-sp/ +COPY --from=shib-base /opt/shibboleth-sp/etc/shibboleth/shib2.load /etc/apache2/mods-available/ + +RUN /usr/sbin/useradd --system _shibd \ + && mkdir -p /var/run/shibboleth \ + && chown _shibd:_shibd /var/run/shibboleth \ + && chown -R _shibd:_shibd /opt/shibboleth-sp/var \ + && cp -a /opt/shibboleth-sp/etc/shibboleth /etc/shibboleth \ + && rm -f /etc/shibboleth/shibboleth2.xml \ + && chown _shibd:_shibd /etc/shibboleth/sp-signing-cert.pem \ + && chown _shibd:_shibd /etc/shibboleth/sp-signing-key.pem \ + && chown _shibd:_shibd /etc/shibboleth/sp-encrypt-cert.pem \ + && chown _shibd:_shibd /etc/shibboleth/sp-encrypt-key.pem \ + && cd /opt/shibboleth-sp/etc \ + && rm -rf shibboleth \ + && ln -s /etc/shibboleth shibboleth \ + && a2enmod shib2 + +COPY container/match/shibboleth-sp-supervisor/supervisord.conf /usr/local/etc/supervisord.conf +COPY container/match/shibboleth-sp-supervisor/docker-comanage-shibboleth-sp-entrypoint /usr/local/bin/ + +ENTRYPOINT ["/usr/bin/supervisord", "-c", "/usr/local/etc/supervisord.conf"] diff --git a/container/match/shibboleth-sp-supervisor/docker-comanage-shibboleth-sp-entrypoint b/container/match/shibboleth-sp-supervisor/docker-comanage-shibboleth-sp-entrypoint new file mode 100755 index 00000000..3addec0f --- /dev/null +++ b/container/match/shibboleth-sp-supervisor/docker-comanage-shibboleth-sp-entrypoint @@ -0,0 +1,24 @@ +#!/bin/bash + +# COmanage Match Shibboleth SP Dockerfile entrypoint +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +source /usr/local/lib/comanage_shibboleth_sp_utils.sh + +comanage_shibboleth_sp_utils::exec_shibboleth_sp_daemon diff --git a/container/match/shibboleth-sp-supervisor/supervisord.conf b/container/match/shibboleth-sp-supervisor/supervisord.conf new file mode 100644 index 00000000..b7b713b4 --- /dev/null +++ b/container/match/shibboleth-sp-supervisor/supervisord.conf @@ -0,0 +1,36 @@ +; COmanage Match Docker supervisord configuration +; +; Portions licensed to the University Corporation for Advanced Internet +; Development, Inc. ("UCAID") under one or more contributor license agreements. +; See the NOTICE file distributed with this work for additional information +; regarding copyright ownership. +; +; UCAID licenses this file to you under the Apache License, Version 2.0 +; (the "License"); you may not use this file except in compliance with the +; License. You may obtain a copy of the License at: +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +[supervisord] +nodaemon=true +user=root + +[program:apache2] +command=/usr/local/bin/docker-comanage-match-entrypoint apache2-foreground +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:shibd] +command=/usr/local/bin/docker-comanage-shibboleth-sp-entrypoint +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/container/shibboleth-sp-base/Dockerfile b/container/shibboleth-sp-base/Dockerfile new file mode 100644 index 00000000..532e773e --- /dev/null +++ b/container/shibboleth-sp-base/Dockerfile @@ -0,0 +1,188 @@ +# Dockerfile for Shibboleth SP for COmanage Registry +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +FROM debian:11-slim + +ARG LOG4SHIB_VERSION +ENV LOG4SHIB_VERSION=${LOG4SHIB_VERSION:-2.0.1} + +ARG XERCESC_VERSION +ENV XERCESC_VERSION=${XERCESC_VERSION:-3.2.4} + +ARG XMLSECC_VERSION +ENV XMLSECC_VERSION=${XMLSECC_VERSION:-2.0.4} + +ARG XMLTOOLING_VERSION +ENV XMLTOOLING_VERSION=${XMLTOOLING_VERSION:-3.2.2} + +ARG OPENSAMLC_VERSION +ENV OPENSAMLC_VERSION=${OPENSAMLC_VERSION:-3.2.1} + +ARG SHIBBOLETH_SP_VERSION +ENV SHIBBOLETH_SP_VERSION=${SHIBBOLETH_SP_VERSION:-3.4.0} + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apache2 \ + apache2-dev \ + ca-certificates \ + file \ + gcc \ + g++ \ + libboost-dev \ + libcurl4-openssl-dev \ + libssl-dev \ + libssl1.1 \ + make \ + pkg-config \ + wget \ + zlib1g-dev + + +RUN LOG4SHIB_URL="https://shibboleth.net/downloads/log4shib/${LOG4SHIB_VERSION}/log4shib-${LOG4SHIB_VERSION}.tar.gz" \ + && wget -O log4shib.tar.gz "${LOG4SHIB_URL}" \ + && mkdir -p src \ + && tar -zxf log4shib.tar.gz -C src --strip-components=1 \ + && rm -f log4shib.tar.gz \ + && cd src \ + && LD_FLAGS=-lpthread CXXFLAGS="-fPIC" ./configure --disable-static \ + --disable-doxygen \ + --prefix=/opt/shibboleth-sp \ + --build=x86_64 \ + && LD_FLAGS=-lpthread make \ + && make -j 2 install \ + && cd .. \ + && rm -r src + +RUN XERCESC_DIST_URLS="\ + https://mirrors.ocf.berkeley.edu/apache/xerces/c/3/sources/xerces-c-${XERCESC_VERSION}.tar.gz \ + http://www.gtlib.gatech.edu/pub/apache//xerces/c/3/sources/xerces-c-${XERCESC_VERSION}.tar.gz \ + http://apache.mirrors.spacedump.net/xerces/c/3/sources/xerces-c-${XERCESC_VERSION}.tar.gz \ + http://apache.mirror.serversaustralia.com.au/xerces/c/3/sources/xerces-c-${XERCESC_VERSION}.tar.gz" \ + && for distUrl in ${XERCESC_DIST_URLS}; \ + do \ + if wget -nv -O xerces.tar.gz "${distUrl}"; then \ + break; \ + fi; \ + done \ + && mkdir -p src \ + && tar -zxf xerces.tar.gz -C src --strip-components=1 \ + && rm -f xerces.tar.gz \ + && cd src \ + && ./configure --prefix=/opt/shibboleth-sp \ + && make -j 2 \ + && make install \ + && cd .. \ + && rm -r src + +RUN XMLSECC_DIST_URLS="\ + https://mirrors.ocf.berkeley.edu/apache/santuario/c-library/xml-security-c-${XMLSECC_VERSION}.tar.gz \ + https://mirrors.ocf.berkeley.edu/apache/santuario/c-library/xml-security-c-${XMLSECC_VERSION}.tar.gz \ + http://www.gtlib.gatech.edu/pub/apache/santuario/c-library/xml-security-c-${XMLSECC_VERSION}.tar.gz \ + http://apache.mirrors.spacedump.net/santuario/c-library/xml-security-c-${XMLSECC_VERSION}.tar.gz \ + http://apache.mirror.serversaustralia.com.au/santuario/c-library/xml-security-c-${XMLSECC_VERSION}.tar.gz" \ + && for distUrl in ${XMLSECC_DIST_URLS}; \ + do \ + if wget -nv -O xmlsecc.tar.gz "${distUrl}"; then \ + break; \ + fi; \ + done \ + && mkdir -p src \ + && tar -zxf xmlsecc.tar.gz -C src --strip-components=1 \ + && rm -f xmlsecc.tar.gz \ + && cd src \ + && PKG_CONFIG_PATH=/opt/shibboleth-sp/lib/pkgconfig ./configure --prefix=/opt/shibboleth-sp \ + --with-openssl=/usr \ + --disable-static \ + --without-xalan \ + && make -j 2 \ + && make install \ + && cd .. \ + && rm -r src + +RUN XMLTOOLING_URL="https://shibboleth.net/downloads/c++-opensaml/${OPENSAMLC_VERSION}/xmltooling-${XMLTOOLING_VERSION}.tar.gz" \ + && wget -O xmltooling.tar.gz "${XMLTOOLING_URL}" \ + && mkdir -p src \ + && tar -zxf xmltooling.tar.gz -C src --strip-components=1 \ + && rm -f xmltooling.tar.gz \ + && cd src \ + && CXXFLAGS="-fPIC" \ + PKG_CONFIG_PATH=/opt/shibboleth-sp/lib/pkgconfig \ + ./configure --prefix=/opt/shibboleth-sp \ + --with-log4shib=/opt/shibboleth-sp \ + -C \ + && make -j 2 \ + && make install \ + && cd .. \ + && rm -r src + +RUN OPENSAMLC_URL="https://shibboleth.net/downloads/c++-opensaml/${OPENSAMLC_VERSION}/opensaml-${OPENSAMLC_VERSION}.tar.gz" \ + && wget -O opensamlc.tar.gz "${OPENSAMLC_URL}" \ + && mkdir -p src \ + && tar -zxf opensamlc.tar.gz -C src --strip-components=1 \ + && rm -f opensamlc.tar.gz \ + && cd src \ + && PKG_CONFIG_PATH=/opt/shibboleth-sp/lib/pkgconfig \ + ./configure --prefix=/opt/shibboleth-sp \ + --with-log4shib=/opt/shibboleth-sp \ + -C \ + && make -j 2 \ + && make install \ + && cd .. \ + && rm -r src + +RUN SHIBBOLETH_SP_URL="https://shibboleth.net/downloads/service-provider/${SHIBBOLETH_SP_VERSION}/shibboleth-sp-${SHIBBOLETH_SP_VERSION}.tar.gz" \ + && wget -O shibboleth-sp.tar.gz "${SHIBBOLETH_SP_URL}" \ + && mkdir -p src \ + && tar -zxf shibboleth-sp.tar.gz -C src --strip-components=1 \ + && rm -f shibboleth-sp.tar.gz \ + && cd src \ + && CXXFLAGS="-Wno-unused-parameter" \ + PKG_CONFIG_PATH=/opt/shibboleth-sp/lib/pkgconfig \ + ./configure --prefix=/opt/shibboleth-sp \ + --with-log4shib=/opt/shibboleth-sp \ + --with-saml=/opt/shibboleth-sp \ + --with-xerces=/opt/shibboleth-sp \ + --with-xmlsec=/opt/shibboleth-sp \ + --with-xmltooling=/opt/shibboleth-sp \ + --enable-apache-24 \ + --with-apxs24=/usr/bin/apxs \ + --disable-adfs \ + --disable-obc \ + && make -j 2 \ + && make install \ + && cd .. \ + && rm -r src + +COPY container/shibboleth-sp-base/shib2.load /opt/shibboleth-sp/etc/shibboleth/shib2.load +COPY container/shibboleth-sp-base/shibboleth2.xml.template /opt/shibboleth-sp/etc/shibboleth/shibboleth2.xml.template +COPY container/shibboleth-sp-base/shibd.logger /opt/shibboleth-sp/etc/shibboleth/shibd.logger +COPY container/shibboleth-sp-base/native.logger /opt/shibboleth-sp/etc/shibboleth/native.logger +COPY container/shibboleth-sp-base/console.logger /opt/shibboleth-sp/etc/shibboleth/console.logger + +RUN apt-get purge -y \ + apache2-dev \ + file \ + gcc \ + g++ \ + libboost-dev \ + libcurl4-openssl-dev \ + libssl-dev \ + make \ + pkg-config \ + && apt-get clean diff --git a/container/shibboleth-sp-base/console.logger b/container/shibboleth-sp-base/console.logger new file mode 100644 index 00000000..fb256f18 --- /dev/null +++ b/container/shibboleth-sp-base/console.logger @@ -0,0 +1,32 @@ +log4j.rootCategory=WARN, console + +# fairly verbose for DEBUG, so generally leave at INFO +log4j.category.XMLTooling.XMLObject=INFO +log4j.category.XMLTooling.KeyInfoResolver=INFO +log4j.category.Shibboleth.IPRange=INFO +log4j.category.Shibboleth.PropertySet=INFO + +# raise for low-level tracing of SOAP client HTTP/SSL behavior +log4j.category.XMLTooling.libcurl=INFO + +# useful categories to tune independently: +# +# tracing of SAML messages and security policies +#log4j.category.OpenSAML.MessageDecoder=DEBUG +#log4j.category.OpenSAML.MessageEncoder=DEBUG +#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG +# interprocess message remoting +#log4j.category.Shibboleth.Listener=DEBUG +# mapping of requests to applicationId +#log4j.category.Shibboleth.RequestMapper=DEBUG +# high level session cache operations +#log4j.category.Shibboleth.SessionCache=DEBUG +# persistent storage and caching +#log4j.category.XMLTooling.StorageService=DEBUG + +# define the appender + +log4j.appender.console=org.apache.log4j.ConsoleAppender +#log4j.appender.console.layout=org.apache.log4j.BasicLayout +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=console_log %d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n diff --git a/container/shibboleth-sp-base/native.logger b/container/shibboleth-sp-base/native.logger new file mode 100644 index 00000000..3858c443 --- /dev/null +++ b/container/shibboleth-sp-base/native.logger @@ -0,0 +1,31 @@ +# set overall behavior +log4j.rootCategory=INFO, native_log + +# fairly verbose for DEBUG, so generally leave at WARN/INFO +log4j.category.XMLTooling.XMLObject=WARN +log4j.category.XMLTooling.KeyInfoResolver=WARN +log4j.category.Shibboleth.IPRange=WARN +log4j.category.Shibboleth.PropertySet=WARN + +# raise for low-level tracing of SOAP client HTTP/SSL behavior +log4j.category.XMLTooling.libcurl=WARN + +# useful categories to tune independently: +# +# tracing of SAML messages and security policies +#log4j.category.OpenSAML.MessageDecoder=DEBUG +#log4j.category.OpenSAML.MessageEncoder=DEBUG +#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG +# interprocess message remoting +#log4j.category.Shibboleth.Listener=DEBUG +# mapping of requests to applicationId +#log4j.category.Shibboleth.RequestMapper=DEBUG +# high level session cache operations +#log4j.category.Shibboleth.SessionCache=DEBUG +# persistent storage and caching +#log4j.category.XMLTooling.StorageService=DEBUG + +# define the appender +log4j.appender.native_log=org.apache.log4j.ConsoleAppender +log4j.appender.native_log.layout=org.apache.log4j.PatternLayout +log4j.appender.native_log.layout.ConversionPattern=native_log %p %c %x: %m%n diff --git a/container/shibboleth-sp-base/shib2.load b/container/shibboleth-sp-base/shib2.load new file mode 100644 index 00000000..b518d603 --- /dev/null +++ b/container/shibboleth-sp-base/shib2.load @@ -0,0 +1,20 @@ +# COmanage Registry Apache HTTP Server configuration +# +# Portions licensed to the University Corporation for Advanced Internet +# Development, Inc. ("UCAID") under one or more contributor license agreements. +# See the NOTICE file distributed with this work for additional information +# regarding copyright ownership. +# +# UCAID licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LoadModule mod_shib /opt/shibboleth-sp/lib/shibboleth/mod_shib_24.so diff --git a/container/shibboleth-sp-base/shibboleth2.xml.template b/container/shibboleth-sp-base/shibboleth2.xml.template new file mode 100644 index 00000000..79c1caa9 --- /dev/null +++ b/container/shibboleth-sp-base/shibboleth2.xml.template @@ -0,0 +1,55 @@ + + + + + + + + + + SAML2 + + + Local + + + + + + + + + + + + + + + %%SHIBBOLETH_SP_METADATA_PROVIDER_XML%% + + + + + + + + + + + + + + + diff --git a/container/shibboleth-sp-base/shibd.logger b/container/shibboleth-sp-base/shibd.logger new file mode 100644 index 00000000..39f152d6 --- /dev/null +++ b/container/shibboleth-sp-base/shibd.logger @@ -0,0 +1,56 @@ +# set overall behavior +log4j.rootCategory=INFO, shibd_log + +# fairly verbose for DEBUG, so generally leave at INFO +log4j.category.XMLTooling.XMLObject=INFO +log4j.category.XMLTooling.KeyInfoResolver=INFO +log4j.category.Shibboleth.IPRange=INFO +log4j.category.Shibboleth.PropertySet=INFO + +# raise for low-level tracing of SOAP client HTTP/SSL behavior +log4j.category.XMLTooling.libcurl=INFO + +# useful categories to tune independently: +# +# tracing of SAML messages and security policies +#log4j.category.OpenSAML.MessageDecoder=DEBUG +#log4j.category.OpenSAML.MessageEncoder=DEBUG +#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG +#log4j.category.XMLTooling.SOAPClient=DEBUG +# interprocess message remoting +#log4j.category.Shibboleth.Listener=DEBUG +# mapping of requests to applicationId +#log4j.category.Shibboleth.RequestMapper=DEBUG +# high level session cache operations +#log4j.category.Shibboleth.SessionCache=DEBUG +# persistent storage and caching +#log4j.category.XMLTooling.StorageService=DEBUG + +# logs XML being signed or verified if set to DEBUG +log4j.category.XMLTooling.Signature.Debugger=INFO, sig_log +log4j.additivity.XMLTooling.Signature.Debugger=false +log4j.ownAppenders.XMLTooling.Signature.Debugger=true + +# the tran log blocks the "default" appender(s) at runtime +# Level should be left at INFO for this category +log4j.category.Shibboleth-TRANSACTION=INFO, tran_log +log4j.additivity.Shibboleth-TRANSACTION=false +log4j.ownAppenders.Shibboleth-TRANSACTION=true + +# uncomment to suppress particular event types +#log4j.category.Shibboleth-TRANSACTION.AuthnRequest=WARN +#log4j.category.Shibboleth-TRANSACTION.Login=WARN +#log4j.category.Shibboleth-TRANSACTION.Logout=WARN + +# define the appenders +log4j.appender.shibd_log=org.apache.log4j.ConsoleAppender +log4j.appender.shibd_log.layout=org.apache.log4j.PatternLayout +log4j.appender.shibd_log.layout.ConversionPattern=shibd_log %d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n + +log4j.appender.tran_log=org.apache.log4j.ConsoleAppender +log4j.appender.tran_log.layout=org.apache.log4j.PatternLayout +log4j.appender.tran_log.layout.ConversionPattern=tran_log %d{%Y-%m-%d %H:%M:%S}|%c|%m%n + +log4j.appender.sig_log=org.apache.log4j.ConsoleAppender +log4j.appender.sig_log.layout=org.apache.log4j.PatternLayout +log4j.appender.sig_log.layout.ConversionPattern=sig_log %m