Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
- Added WineCspHttpProvider class to interface with Wine-hosted CryptoPro CSP. - Implemented ICryptoProvider, ICryptoProviderDiagnostics, and IDisposable interfaces. - Introduced WineCspHttpSigner and WineCspHttpHasher for signing and hashing operations. - Created WineCspProviderOptions for configuration settings including service URL and key options. - Developed CryptoProGostSigningService to handle GOST signing operations and key management. - Implemented HTTP service for the Wine CSP with endpoints for signing, verification, and hashing. - Added Swagger documentation for API endpoints. - Included health checks and error handling for service availability. - Established DTOs for request and response models in the service.
382 lines
10 KiB
Bash
382 lines
10 KiB
Bash
#!/bin/bash
|
|
# setup-wine-csp-service.sh - Set up Wine environment for CryptoPro CSP service
|
|
#
|
|
# This script:
|
|
# 1. Creates a dedicated Wine prefix
|
|
# 2. Installs required Windows components
|
|
# 3. Builds the WineCspService for Windows target
|
|
# 4. Optionally installs CryptoPro CSP (if installer is provided)
|
|
#
|
|
# Prerequisites:
|
|
# - Wine 7.0+ installed (wine, wine64, winetricks)
|
|
# - .NET SDK 8.0+ installed
|
|
# - CryptoPro CSP installer (optional, for full functionality)
|
|
#
|
|
# Usage:
|
|
# ./setup-wine-csp-service.sh [--csp-installer /path/to/csp_setup.msi]
|
|
#
|
|
# Environment variables:
|
|
# WINE_PREFIX - Wine prefix location (default: ~/.stellaops-wine-csp)
|
|
# CSP_INSTALLER - Path to CryptoPro CSP installer
|
|
# WINE_CSP_PORT - HTTP port for service (default: 5099)
|
|
|
|
set -euo pipefail
|
|
|
|
# Configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
WINE_PREFIX="${WINE_PREFIX:-$HOME/.stellaops-wine-csp}"
|
|
WINE_CSP_PORT="${WINE_CSP_PORT:-5099}"
|
|
SERVICE_DIR="$REPO_ROOT/src/__Tools/WineCspService"
|
|
OUTPUT_DIR="$REPO_ROOT/artifacts/wine-csp-service"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
|
# Parse arguments
|
|
CSP_INSTALLER=""
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--csp-installer)
|
|
CSP_INSTALLER="$2"
|
|
shift 2
|
|
;;
|
|
--help)
|
|
echo "Usage: $0 [--csp-installer /path/to/csp_setup.msi]"
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_error "Unknown option: $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Check prerequisites
|
|
check_prerequisites() {
|
|
log_info "Checking prerequisites..."
|
|
|
|
if ! command -v wine &> /dev/null; then
|
|
log_error "Wine is not installed. Please install Wine 7.0+"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v winetricks &> /dev/null; then
|
|
log_warn "winetricks not found. Some components may not install correctly."
|
|
fi
|
|
|
|
if ! command -v dotnet &> /dev/null; then
|
|
log_error ".NET SDK not found. Please install .NET 8.0+"
|
|
exit 1
|
|
fi
|
|
|
|
log_info "Prerequisites OK"
|
|
}
|
|
|
|
# Initialize Wine prefix
|
|
init_wine_prefix() {
|
|
log_info "Initializing Wine prefix at $WINE_PREFIX..."
|
|
|
|
export WINEPREFIX="$WINE_PREFIX"
|
|
export WINEARCH="win64"
|
|
|
|
# Create prefix if it doesn't exist
|
|
if [[ ! -d "$WINE_PREFIX" ]]; then
|
|
wineboot --init
|
|
log_info "Wine prefix created"
|
|
else
|
|
log_info "Wine prefix already exists"
|
|
fi
|
|
|
|
# Set Windows version
|
|
wine reg add "HKCU\\Software\\Wine\\Version" /v Windows /d "win10" /f 2>/dev/null || true
|
|
}
|
|
|
|
# Install Windows components via winetricks
|
|
install_windows_components() {
|
|
log_info "Installing Windows components..."
|
|
|
|
if command -v winetricks &> /dev/null; then
|
|
export WINEPREFIX="$WINE_PREFIX"
|
|
|
|
# Install Visual C++ runtime
|
|
log_info "Installing Visual C++ runtime..."
|
|
winetricks -q vcrun2019 || log_warn "vcrun2019 installation may have issues"
|
|
|
|
# Install core fonts (optional, for UI)
|
|
# winetricks -q corefonts || true
|
|
|
|
log_info "Windows components installed"
|
|
else
|
|
log_warn "Skipping winetricks components (winetricks not available)"
|
|
fi
|
|
}
|
|
|
|
# Install CryptoPro CSP if installer provided
|
|
install_cryptopro_csp() {
|
|
if [[ -z "$CSP_INSTALLER" ]]; then
|
|
log_warn "No CryptoPro CSP installer provided. Service will run in limited mode."
|
|
log_warn "Provide installer with: --csp-installer /path/to/csp_setup_x64.msi"
|
|
return 0
|
|
fi
|
|
|
|
if [[ ! -f "$CSP_INSTALLER" ]]; then
|
|
log_error "CryptoPro installer not found: $CSP_INSTALLER"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Installing CryptoPro CSP from $CSP_INSTALLER..."
|
|
|
|
export WINEPREFIX="$WINE_PREFIX"
|
|
|
|
# Run MSI installer
|
|
wine msiexec /i "$CSP_INSTALLER" /qn ADDLOCAL=ALL || {
|
|
log_error "CryptoPro CSP installation failed"
|
|
log_info "You may need to run the installer manually:"
|
|
log_info " WINEPREFIX=$WINE_PREFIX wine msiexec /i $CSP_INSTALLER"
|
|
return 1
|
|
}
|
|
|
|
# Verify installation
|
|
if wine reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\Crypto-Pro GOST R 34.10-2012" 2>/dev/null; then
|
|
log_info "CryptoPro CSP installed successfully"
|
|
else
|
|
log_warn "CryptoPro CSP may not be registered correctly"
|
|
fi
|
|
}
|
|
|
|
# Build WineCspService for Windows
|
|
build_service() {
|
|
log_info "Building WineCspService..."
|
|
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
|
# Build for Windows x64
|
|
dotnet publish "$SERVICE_DIR/WineCspService.csproj" \
|
|
-c Release \
|
|
-r win-x64 \
|
|
--self-contained true \
|
|
-o "$OUTPUT_DIR" \
|
|
|| {
|
|
log_error "Build failed"
|
|
exit 1
|
|
}
|
|
|
|
log_info "Service built: $OUTPUT_DIR/WineCspService.exe"
|
|
}
|
|
|
|
# Create launcher script
|
|
create_launcher() {
|
|
log_info "Creating launcher script..."
|
|
|
|
cat > "$OUTPUT_DIR/run-wine-csp-service.sh" << EOF
|
|
#!/bin/bash
|
|
# Wine CSP Service Launcher
|
|
# Generated by setup-wine-csp-service.sh
|
|
|
|
export WINEPREFIX="$WINE_PREFIX"
|
|
export WINEDEBUG="-all" # Suppress Wine debug output
|
|
|
|
PORT=\${WINE_CSP_PORT:-$WINE_CSP_PORT}
|
|
SERVICE_DIR="\$(dirname "\$0")"
|
|
|
|
echo "Starting Wine CSP Service on port \$PORT..."
|
|
echo "Wine prefix: \$WINEPREFIX"
|
|
echo ""
|
|
|
|
cd "\$SERVICE_DIR"
|
|
exec wine WineCspService.exe --urls "http://0.0.0.0:\$PORT"
|
|
EOF
|
|
|
|
chmod +x "$OUTPUT_DIR/run-wine-csp-service.sh"
|
|
log_info "Launcher created: $OUTPUT_DIR/run-wine-csp-service.sh"
|
|
}
|
|
|
|
# Create systemd service file
|
|
create_systemd_service() {
|
|
log_info "Creating systemd service file..."
|
|
|
|
cat > "$OUTPUT_DIR/wine-csp-service.service" << EOF
|
|
[Unit]
|
|
Description=Wine CSP Service for CryptoPro GOST signing
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=$USER
|
|
Environment=WINEPREFIX=$WINE_PREFIX
|
|
Environment=WINEDEBUG=-all
|
|
Environment=WINE_CSP_PORT=$WINE_CSP_PORT
|
|
WorkingDirectory=$OUTPUT_DIR
|
|
ExecStart=/bin/bash $OUTPUT_DIR/run-wine-csp-service.sh
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
log_info "Systemd service file created: $OUTPUT_DIR/wine-csp-service.service"
|
|
log_info "To install: sudo cp $OUTPUT_DIR/wine-csp-service.service /etc/systemd/system/"
|
|
log_info "To enable: sudo systemctl enable --now wine-csp-service"
|
|
}
|
|
|
|
# Create Docker Compose configuration
|
|
create_docker_compose() {
|
|
log_info "Creating Docker Compose configuration..."
|
|
|
|
cat > "$OUTPUT_DIR/docker-compose.yml" << EOF
|
|
# Wine CSP Service - Docker Compose configuration
|
|
# Requires: Docker with Wine support or Windows container
|
|
version: '3.8'
|
|
|
|
services:
|
|
wine-csp-service:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.wine
|
|
ports:
|
|
- "${WINE_CSP_PORT}:5099"
|
|
environment:
|
|
- ASPNETCORE_URLS=http://+:5099
|
|
volumes:
|
|
# Mount CSP installer if available
|
|
- ./csp-installer:/installer:ro
|
|
# Persist Wine prefix for keys/certificates
|
|
- wine-prefix:/root/.wine
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:5099/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
volumes:
|
|
wine-prefix:
|
|
EOF
|
|
|
|
# Create Dockerfile
|
|
cat > "$OUTPUT_DIR/Dockerfile.wine" << 'EOF'
|
|
# Wine CSP Service Dockerfile
|
|
FROM ubuntu:22.04
|
|
|
|
# Install Wine and dependencies
|
|
RUN dpkg --add-architecture i386 && \
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
wine64 \
|
|
wine32 \
|
|
winetricks \
|
|
curl \
|
|
ca-certificates \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Initialize Wine prefix
|
|
RUN wineboot --init && \
|
|
winetricks -q vcrun2019 || true
|
|
|
|
# Copy service
|
|
WORKDIR /app
|
|
COPY WineCspService.exe .
|
|
COPY *.dll ./
|
|
|
|
# Expose port
|
|
EXPOSE 5099
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
|
|
CMD curl -f http://localhost:5099/health || exit 1
|
|
|
|
# Run service
|
|
CMD ["wine", "WineCspService.exe", "--urls", "http://0.0.0.0:5099"]
|
|
EOF
|
|
|
|
log_info "Docker configuration created in $OUTPUT_DIR/"
|
|
}
|
|
|
|
# Test the service
|
|
test_service() {
|
|
log_info "Testing service startup..."
|
|
|
|
export WINEPREFIX="$WINE_PREFIX"
|
|
export WINEDEBUG="-all"
|
|
|
|
# Start service in background
|
|
cd "$OUTPUT_DIR"
|
|
wine WineCspService.exe --urls "http://localhost:$WINE_CSP_PORT" &
|
|
SERVICE_PID=$!
|
|
|
|
# Wait for startup
|
|
sleep 5
|
|
|
|
# Test health endpoint
|
|
if curl -s "http://localhost:$WINE_CSP_PORT/health" | grep -q "Healthy"; then
|
|
log_info "Service is running and healthy"
|
|
|
|
# Test status endpoint
|
|
log_info "CSP Status:"
|
|
curl -s "http://localhost:$WINE_CSP_PORT/status" | python3 -m json.tool 2>/dev/null || \
|
|
curl -s "http://localhost:$WINE_CSP_PORT/status"
|
|
else
|
|
log_warn "Service health check failed"
|
|
fi
|
|
|
|
# Stop service
|
|
kill $SERVICE_PID 2>/dev/null || true
|
|
wait $SERVICE_PID 2>/dev/null || true
|
|
}
|
|
|
|
# Print summary
|
|
print_summary() {
|
|
echo ""
|
|
log_info "=========================================="
|
|
log_info "Wine CSP Service Setup Complete"
|
|
log_info "=========================================="
|
|
echo ""
|
|
echo "Wine prefix: $WINE_PREFIX"
|
|
echo "Service directory: $OUTPUT_DIR"
|
|
echo "HTTP port: $WINE_CSP_PORT"
|
|
echo ""
|
|
echo "To start the service:"
|
|
echo " $OUTPUT_DIR/run-wine-csp-service.sh"
|
|
echo ""
|
|
echo "To test endpoints:"
|
|
echo " curl http://localhost:$WINE_CSP_PORT/status"
|
|
echo " curl http://localhost:$WINE_CSP_PORT/keys"
|
|
echo " curl -X POST http://localhost:$WINE_CSP_PORT/hash \\"
|
|
echo " -H 'Content-Type: application/json' \\"
|
|
echo " -d '{\"dataBase64\":\"SGVsbG8gV29ybGQ=\"}'"
|
|
echo ""
|
|
if [[ -z "$CSP_INSTALLER" ]]; then
|
|
echo "NOTE: CryptoPro CSP is not installed."
|
|
echo " The service will report 'CSP not available'."
|
|
echo " To install CSP, run:"
|
|
echo " $0 --csp-installer /path/to/csp_setup_x64.msi"
|
|
fi
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
log_info "Wine CSP Service Setup"
|
|
log_info "Repository: $REPO_ROOT"
|
|
|
|
check_prerequisites
|
|
init_wine_prefix
|
|
install_windows_components
|
|
install_cryptopro_csp
|
|
build_service
|
|
create_launcher
|
|
create_systemd_service
|
|
create_docker_compose
|
|
test_service
|
|
print_summary
|
|
}
|
|
|
|
main "$@"
|