#!/bin/bash # CryptoPro CSP Installation Script for Wine # # Installs customer-provided CryptoPro CSP MSI under Wine environment. # This script is called by entrypoint.sh when CSP installer is available. # # IMPORTANT: CryptoPro CSP is commercial software. The installer MSI must be # provided by the customer with appropriate licensing. StellaOps does not # distribute CryptoPro CSP. set -euo pipefail # ------------------------------------------------------------------------------ # Configuration # ------------------------------------------------------------------------------ WINE_CSP_INSTALLER_PATH="${WINE_CSP_INSTALLER_PATH:-/opt/cryptopro/csp-installer.msi}" WINE_PREFIX="${WINEPREFIX:-$HOME/.wine}" DISPLAY="${DISPLAY:-:99}" # Expected CSP installation paths (under Wine prefix) CSP_PROGRAM_FILES="${WINE_PREFIX}/drive_c/Program Files/Crypto Pro" CSP_MARKER="${WINE_PREFIX}/.csp_installed" CSP_VERSION_FILE="${WINE_PREFIX}/.csp_version" # Installation timeout (5 minutes) INSTALL_TIMEOUT=300 # Log prefix log() { echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] [install-csp] $*" } log_error() { echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] [install-csp] [ERROR] $*" >&2 } # ------------------------------------------------------------------------------ # Pre-Installation Checks # ------------------------------------------------------------------------------ check_prerequisites() { log "Checking installation prerequisites" # Check installer exists if [[ ! -f "${WINE_CSP_INSTALLER_PATH}" ]]; then log_error "CSP installer not found: ${WINE_CSP_INSTALLER_PATH}" return 1 fi # Verify file is an MSI if ! file "${WINE_CSP_INSTALLER_PATH}" | grep -qi "microsoft installer"; then log_error "File does not appear to be an MSI installer" return 1 fi # Check Wine is available if ! command -v wine64 &> /dev/null; then log_error "wine64 not found" return 1 fi # Check Wine prefix exists if [[ ! -d "${WINE_PREFIX}" ]]; then log_error "Wine prefix not initialized: ${WINE_PREFIX}" return 1 fi log "Prerequisites check passed" return 0 } # ------------------------------------------------------------------------------ # Installation # ------------------------------------------------------------------------------ install_csp() { log "Starting CryptoPro CSP installation" log "Installer: ${WINE_CSP_INSTALLER_PATH}" # Create installation log directory local log_dir="${WINE_PREFIX}/csp_install_logs" mkdir -p "${log_dir}" local install_log="${log_dir}/install_$(date -u '+%Y%m%d_%H%M%S').log" # Run MSI installer silently # /qn = silent mode, /norestart = don't restart, /l*v = verbose logging log "Running msiexec installer (this may take several minutes)..." timeout "${INSTALL_TIMEOUT}" wine64 msiexec /i "${WINE_CSP_INSTALLER_PATH}" \ /qn /norestart /l*v "${install_log}" \ AGREETOLICENSE=Yes \ 2>&1 | tee -a "${install_log}" || { local exit_code=$? log_error "MSI installation failed with exit code: ${exit_code}" log_error "Check installation log: ${install_log}" return 1 } # Wait for Wine to finish wineserver --wait log "MSI installation completed" return 0 } # ------------------------------------------------------------------------------ # Post-Installation Verification # ------------------------------------------------------------------------------ verify_installation() { log "Verifying CryptoPro CSP installation" # Check for CSP program files if [[ -d "${CSP_PROGRAM_FILES}" ]]; then log "Found CSP directory: ${CSP_PROGRAM_FILES}" else log_error "CSP program directory not found" return 1 fi # Check for key CSP DLLs local csp_dll="${WINE_PREFIX}/drive_c/windows/system32/cpcspi.dll" if [[ -f "${csp_dll}" ]]; then log "Found CSP DLL: ${csp_dll}" else log "Warning: CSP DLL not found at expected location" # This might be OK depending on CSP version fi # Try to query CSP registry entries local csp_registry csp_registry=$(wine64 reg query "HKLM\\SOFTWARE\\Crypto Pro" 2>/dev/null || true) if [[ -n "${csp_registry}" ]]; then log "CSP registry entries found" else log "Warning: CSP registry entries not found" fi # Extract version if possible local version="unknown" if [[ -f "${CSP_PROGRAM_FILES}/CSP/version.txt" ]]; then version=$(cat "${CSP_PROGRAM_FILES}/CSP/version.txt" 2>/dev/null || echo "unknown") fi echo "${version}" > "${CSP_VERSION_FILE}" log "CSP version: ${version}" log "Installation verification completed" return 0 } # ------------------------------------------------------------------------------ # Cleanup on Failure # ------------------------------------------------------------------------------ cleanup_failed_install() { log "Cleaning up failed installation" # Try to uninstall via msiexec wine64 msiexec /x "${WINE_CSP_INSTALLER_PATH}" /qn 2>/dev/null || true wineserver --wait # Remove any partial installation directories rm -rf "${CSP_PROGRAM_FILES}" 2>/dev/null || true # Remove marker files rm -f "${CSP_MARKER}" "${CSP_VERSION_FILE}" 2>/dev/null || true log "Cleanup completed" } # ------------------------------------------------------------------------------ # Main # ------------------------------------------------------------------------------ main() { log "==========================================" log "CryptoPro CSP Installation Script" log "==========================================" # Check if already installed if [[ -f "${CSP_MARKER}" ]]; then log "CryptoPro CSP is already installed" if [[ -f "${CSP_VERSION_FILE}" ]]; then log "Installed version: $(cat "${CSP_VERSION_FILE}")" fi return 0 fi # Run prerequisite checks if ! check_prerequisites; then log_error "Prerequisites check failed" return 1 fi # Perform installation if ! install_csp; then log_error "Installation failed" cleanup_failed_install return 1 fi # Verify installation if ! verify_installation; then log_error "Installation verification failed" cleanup_failed_install return 1 fi # Create installation marker touch "${CSP_MARKER}" log "==========================================" log "CryptoPro CSP installation successful" log "==========================================" return 0 } main "$@"