# -*- mode: shell-script -*- ssl_get_plugin_fun() { local cfg="$1" type="$(echo "$cfg" | shyaml -y get-type 2>/dev/null)" || return 1 case "$type" in bool) err "Option ${WHITE}ssl${NORMAL} value '$cfg' is not supported." return 1 ;; str) keys=("$cfg") ;; struct) keys=( $(echo "$cfg" | shyaml keys 2>/dev/null) ) ;; *) err "Invalid ${WHITE}ssl${NORMAL} value type '$type': please provide a string or a struct." return 1 ;; esac for key in "${keys[@]}"; do target_relation="cert-provider" fun="ssl_plugin_${target_relation}" while read-0 relation_name target_service relation_config tech_dep; do [ "$relation_name" == "${target_relation}" ] || continue [ "$target_service" == "$key" ] || continue verb "Corresponding plugin ${DARKGREEN}found${NORMAL}" \ "in ${DARKBLUE}$relation_name${NORMAL}/${DARKYELLOW}$key${NORMAL}" ssl_cfg=$(printf "%s" "$cfg" | shyaml get-value "$key" 2>/dev/null) || true merged_config=$(merge_yaml_str "$relation_config" "$ssl_cfg") || return 1 printf "%s\0" "$fun" "$key" "$merged_config" return 0 done < <(get_service_relations "$SERVICE_NAME") || return 1 case "$key" in cert|ca-cert|key) : ;; *) err "Invalid key '$key' in ${WHITE}ssl${NORMAL}:" \ "no corresponding services declared in ${DARKBLUE}${target_relation}$NORMAL" return 1 ;; esac done } ssl_fallback_vars() { local cfg="$1" DOMAIN="$2" cert key ca_cert base_dir=/etc/ssl print "%s\0" \ "$base_dir"/certs/"${DOMAIN}".pem \ "$base_dir"/private/"${DOMAIN}".key \ "$base_dir"/certs/"${DOMAIN}"-ca.pem print "%s\0" "$base_dir"/cert.pem "$base_dir"/privkey.pem "$base_dir"/chain.pem } ssl_fallback_prepare() { local cfg="$1" service="$2" l_cert l_key l_ca_cert shift 2 read-0 l_cert l_key l_ca_cert < <(ssl_fallback_vars "$cfg" "$@") dst="$CONFIGSTORE/$BASE_SERVICE_NAME" volumes="" for label in cert key ca-cert; do if content=$(echo "$cfg" | shyaml get-value "$label" 2>/dev/null); then location="$(eval echo "\$l_${label//-/_}")" echo "$content" | file_put "$dst$location" config_hash=$(printf "%s\0" "$config_hash" "$label" "$content" | md5_compat) volumes="$volumes - $dst$location:$location:ro" fi done if [ "$volumes" ]; then init-config-add "\ $MASTER_TARGET_SERVICE_NAME: volumes: $volumes " fi } ssl_plugin_cert-provider_vars() { local cfg="$1" DOMAIN="$2" base_dir="/etc/letsencrypt/live/$DOMAIN" print "%s\0" "$base_dir"/cert.pem "$base_dir"/privkey.pem "$base_dir"/chain.pem } ssl_plugin_cert-provider_prepare() { local cfg="$1" service="$2" options shift 2 options=$(yaml_key_val_str "options" "$cfg") || return 1 service_config=$(yaml_key_val_str "$service" "$options") compose --debug --add-compose-content "$service_config" run --rm --service-ports "$service" \ crt create "$@" || { err "Failed to launch letsencrypt for certificate creation." return 1 } init-config-add "\ $MASTER_TARGET_SERVICE_NAME: volumes: - $DATASTORE/$service/etc/letsencrypt:/etc/letsencrypt:ro " || return 1 } make_pasv_options() { local pasv="$1" if [[ "${pasv,,}" =~ ^(false|no|n|0|disable|disabled)$ ]]; then echo "pasv_enable=no" return 0 fi ports="$(printf "%s" "$pasv" | shyaml get-value -q "ports")" if [ "$ports" ]; then if [[ "$ports" =~ ^[0-9]+-[0-9]+$ ]]; then port_min=${ports##*-} port_max=${ports%%-*} if [ "$port_min" -gt "$port_max" ]; then die "Invalid value for ${WHITE}ports${NORMAL}: first port in range has to be lesser than second." fi else die "Invalid value for ${WHITE}ports${NORMAL}: please specify a port range (ie: '123-345')." fi fi port_min=${port_min:-21100} port_max=${port_max:-21110} host_address="$(printf "%s" "$pasv" | shyaml get-value -q "address")" if [ -z "$host_address" ]; then if [[ "$SERVICE_NAME" =~ ^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$ ]]; then host_address="$SERVICE_NAME" fi fi if [ -z "$host_address" ]; then echo "## Could not find appropriate host return address" echo "pasv_enable=no" return 0 fi if ! str_is_ipv4 "$host_address"; then host_address="$(get_ip_from_hostname "$host_address")" || { err "Can't resolve given hostname '$host_address'" return 1 } else err "You should NOT provide a direct IP for ${WHITE}pasv.address${NORMAL}," \ "try a resolvable address." return 1 fi cat <&2 if [ "$first" ]; then first_group="$group" first= else remaining_groups+=("$group") fi groups+=("$group") done < <(echo "$user_def" | shyaml get-values-0 groups 2>/dev/null) password=$(echo "$user_def" | shyaml get-value password 2>/dev/null) || password=$(gen_password 14) uid=$(echo "$user_def" | shyaml get-value uid 2>/dev/null) useradd_options=( "-D" ## don't assign a password "-s" "/bin/false" ## default shell ) if [ "$uid" ]; then useradd_options+=("-u" "$uid") ## force uid fi if [ "$first_group" ]; then useradd_options+=("-G" "$first_group") ## force main group fi code+="adduser ${useradd_options[*]} \"$user\""$'\n' code+="mkdir -p \"/home/$user\""$'\n' if [ "$allow_writeable_chroot" ]; then code+="chown $user \"/home/$user\""$'\n' ## sanitize else code+="chown root:root \"/home/$user\""$'\n' ## sanitize fi code+="chmod 755 \"/home/$user\""$'\n' ## sanitize code+="echo '$user:$password' | chpasswd"$'\n' for group in "${remaining_groups[@]}"; do code+="adduser \"$user\" \"$group\""$'\n' done done < <(echo "$users_def" | shyaml key-values-0) echo -n "$fixed_groups_code" echo -n "$groups_code" echo -n "$code" }