diff --git a/apps/pusher_app_prem/bin/credentials_manager.py b/apps/pusher_app_prem/bin/credentials_manager.py new file mode 100644 index 00000000..99929aba --- /dev/null +++ b/apps/pusher_app_prem/bin/credentials_manager.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Git Pusher - Credentials Manager +Gère les credentials de manière sécurisée via Splunk storage/passwords +ou via un fichier chiffré local. +""" + +import os +import sys +import json +import base64 +import hashlib +from pathlib import Path + +# Chemin vers le fichier de credentials chiffré +CREDENTIALS_FILE = "/opt/splunk/etc/apps/pusher_app_prem/local/.credentials" +ENCRYPTION_KEY_FILE = "/opt/splunk/etc/apps/pusher_app_prem/local/.key" + + +def get_machine_id(): + """Obtenir un identifiant unique de la machine pour le chiffrement""" + machine_id = "" + + # Essayer différentes sources + try: + with open('/etc/machine-id', 'r') as f: + machine_id = f.read().strip() + except: + pass + + if not machine_id: + try: + import socket + machine_id = socket.gethostname() + except: + machine_id = "default_key" + + return machine_id + + +def derive_key(password, salt=None): + """Dériver une clé de chiffrement à partir d'un mot de passe""" + if salt is None: + salt = get_machine_id().encode() + + # Utiliser PBKDF2-like avec SHA256 + key = hashlib.pbkdf2_hmac( + 'sha256', + password.encode(), + salt, + 100000 + ) + return base64.b64encode(key).decode() + + +def simple_encrypt(data, key): + """Chiffrement simple XOR (pour une sécurité basique)""" + # Pour une vraie sécurité, utiliser cryptography.fernet + key_bytes = key.encode() * (len(data) // len(key) + 1) + encrypted = bytes([a ^ b for a, b in zip(data.encode(), key_bytes[:len(data)])]) + return base64.b64encode(encrypted).decode() + + +def simple_decrypt(encrypted_data, key): + """Déchiffrement simple XOR""" + try: + data = base64.b64decode(encrypted_data) + key_bytes = key.encode() * (len(data) // len(key) + 1) + decrypted = bytes([a ^ b for a, b in zip(data, key_bytes[:len(data)])]) + return decrypted.decode() + except Exception as e: + return None + + +def get_encryption_key(): + """Obtenir ou créer la clé de chiffrement""" + if os.path.exists(ENCRYPTION_KEY_FILE): + with open(ENCRYPTION_KEY_FILE, 'r') as f: + return f.read().strip() + else: + # Générer une nouvelle clé basée sur la machine + key = derive_key(get_machine_id()) + + # Sauvegarder la clé + os.makedirs(os.path.dirname(ENCRYPTION_KEY_FILE), exist_ok=True) + with open(ENCRYPTION_KEY_FILE, 'w') as f: + f.write(key) + + # Protéger le fichier + os.chmod(ENCRYPTION_KEY_FILE, 0o600) + + return key + + +def save_credentials(username, password): + """Sauvegarder les credentials de manière chiffrée""" + key = get_encryption_key() + + credentials = { + 'username': username, + 'password': simple_encrypt(password, key) + } + + os.makedirs(os.path.dirname(CREDENTIALS_FILE), exist_ok=True) + + with open(CREDENTIALS_FILE, 'w') as f: + json.dump(credentials, f) + + # Protéger le fichier + os.chmod(CREDENTIALS_FILE, 0o600) + + print(f"✓ Credentials saved securely to {CREDENTIALS_FILE}") + + +def load_credentials(): + """Charger les credentials chiffrés""" + if not os.path.exists(CREDENTIALS_FILE): + return None, None + + try: + key = get_encryption_key() + + with open(CREDENTIALS_FILE, 'r') as f: + credentials = json.load(f) + + username = credentials.get('username') + encrypted_password = credentials.get('password') + + password = simple_decrypt(encrypted_password, key) + + return username, password + + except Exception as e: + print(f"Error loading credentials: {e}", file=sys.stderr) + return None, None + + +def delete_credentials(): + """Supprimer les credentials stockés""" + if os.path.exists(CREDENTIALS_FILE): + os.remove(CREDENTIALS_FILE) + print("✓ Credentials deleted") + else: + print("No credentials file found") + + +def get_credentials_for_script(): + """ + Fonction utilisée par le script de démarrage pour obtenir les credentials. + Retourne username et password, ou None si non configurés. + """ + username, password = load_credentials() + + if username and password: + return username, password + + # Fallback sur les variables d'environnement + env_user = os.environ.get('SPLUNK_USERNAME') + env_pass = os.environ.get('SPLUNK_PASSWORD') + + if env_user and env_pass: + return env_user, env_pass + + return None, None + + +# ============================================ +# CLI +# ============================================ + +def interactive_setup(): + """Configuration interactive des credentials""" + print("=" * 50) + print("Git Pusher - Credentials Setup") + print("=" * 50) + print() + print("This will securely store your Splunk credentials.") + print(f"Credentials will be encrypted and saved to:") + print(f" {CREDENTIALS_FILE}") + print() + + username = input("Splunk Username [admin]: ").strip() or "admin" + + import getpass + password = getpass.getpass("Splunk Password: ") + + if not password: + print("Error: Password cannot be empty") + return + + # Confirmer + password2 = getpass.getpass("Confirm Password: ") + + if password != password2: + print("Error: Passwords do not match") + return + + save_credentials(username, password) + print() + print("✓ Credentials configured successfully!") + print() + print("You can now start Git Pusher without specifying credentials:") + print(" ./start_git_pusher.sh start") + + +def show_status(): + """Afficher le statut des credentials""" + print("=" * 50) + print("Credentials Status") + print("=" * 50) + + if os.path.exists(CREDENTIALS_FILE): + print(f"✓ Credentials file exists: {CREDENTIALS_FILE}") + + username, password = load_credentials() + if username: + print(f" Username: {username}") + print(f" Password: {'*' * len(password) if password else 'ERROR'}") + else: + print(" Error: Could not decrypt credentials") + else: + print("✗ No credentials file found") + print() + print("Run: python credentials_manager.py setup") + + +if __name__ == '__main__': + if len(sys.argv) < 2: + show_status() + sys.exit(0) + + command = sys.argv[1] + + if command == 'setup': + interactive_setup() + + elif command == 'status': + show_status() + + elif command == 'delete': + delete_credentials() + + elif command == 'get': + # Pour utilisation dans les scripts bash + username, password = get_credentials_for_script() + if username and password: + print(f"{username}") + print(f"{password}") + else: + sys.exit(1) + + elif command == 'export': + # Exporter pour utilisation dans bash + username, password = get_credentials_for_script() + if username and password: + print(f"export SPLUNK_USERNAME='{username}'") + print(f"export SPLUNK_PASSWORD='{password}'") + else: + print("# No credentials found", file=sys.stderr) + sys.exit(1) + + else: + print("Usage: python credentials_manager.py [setup|status|delete|get|export]") + print() + print("Commands:") + print(" setup - Configure credentials interactively") + print(" status - Show credentials status") + print(" delete - Delete stored credentials") + print(" get - Output credentials (for scripts)") + print(" export - Output as bash export commands") \ No newline at end of file diff --git a/apps/pusher_app_prem/bin/git_pusher.pid b/apps/pusher_app_prem/bin/git_pusher.pid index 679e2eb3..d548103a 100644 --- a/apps/pusher_app_prem/bin/git_pusher.pid +++ b/apps/pusher_app_prem/bin/git_pusher.pid @@ -1 +1 @@ -212462 +431858 diff --git a/apps/pusher_app_prem/bin/start_git_pusher.sh b/apps/pusher_app_prem/bin/start_git_pusher.sh index d205939a..5f700770 100755 --- a/apps/pusher_app_prem/bin/start_git_pusher.sh +++ b/apps/pusher_app_prem/bin/start_git_pusher.sh @@ -1,20 +1,23 @@ #!/bin/bash # ============================================ # Git Pusher - Start Script -# Version 2.0 avec système de licence +# Version 2.0 avec credentials sécurisés # ============================================ # Configuration SPLUNK_HOME=${SPLUNK_HOME:-/opt/splunk} -APP_HOME="${SPLUNK_HOME}/etc/apps/pusher_app_prem" +APP_NAME="pusher_app_prem" +APP_HOME="${SPLUNK_HOME}/etc/apps/${APP_NAME}" BIN_DIR="${APP_HOME}/bin" LOG_DIR="${SPLUNK_HOME}/var/log/splunk" PID_FILE="${BIN_DIR}/git_pusher.pid" +CREDENTIALS_MANAGER="${BIN_DIR}/credentials_manager.py" # Couleurs pour les logs RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' +BLUE='\033[0;34m' NC='\033[0m' # No Color # Fonction de logging @@ -30,6 +33,45 @@ log_error() { echo -e "${RED}[ERROR]${NC} $1" } +log_debug() { + echo -e "${BLUE}[DEBUG]${NC} $1" +} + +# Charger les credentials de manière sécurisée +load_credentials() { + # Méthode 1: Utiliser le credentials manager (recommandé) + if [ -f "$CREDENTIALS_MANAGER" ]; then + CREDS=$(python3 "$CREDENTIALS_MANAGER" get 2>/dev/null) + if [ $? -eq 0 ]; then + export SPLUNK_USERNAME=$(echo "$CREDS" | head -1) + export SPLUNK_PASSWORD=$(echo "$CREDS" | tail -1) + log_info "Credentials loaded from secure storage" + return 0 + fi + fi + + # Méthode 2: Variables d'environnement déjà définies + if [ -n "$SPLUNK_USERNAME" ] && [ -n "$SPLUNK_PASSWORD" ]; then + log_info "Using credentials from environment variables" + return 0 + fi + + # Méthode 3: Fichier .env (moins sécurisé mais pratique) + ENV_FILE="${APP_HOME}/local/.env" + if [ -f "$ENV_FILE" ]; then + source "$ENV_FILE" + if [ -n "$SPLUNK_USERNAME" ] && [ -n "$SPLUNK_PASSWORD" ]; then + log_warn "Using credentials from .env file (consider using 'credentials setup' for better security)" + return 0 + fi + fi + + # Aucune credential trouvée + log_error "No credentials found!" + log_error "Please run: $0 credentials setup" + return 1 +} + # Vérifier si le serveur est déjà en cours d'exécution check_running() { if [ -f "$PID_FILE" ]; then @@ -41,6 +83,34 @@ check_running() { return 1 # Not running } +# Configurer les credentials +setup_credentials() { + if [ -f "$CREDENTIALS_MANAGER" ]; then + python3 "$CREDENTIALS_MANAGER" setup + else + log_error "Credentials manager not found at $CREDENTIALS_MANAGER" + exit 1 + fi +} + +# Afficher le statut des credentials +credentials_status() { + if [ -f "$CREDENTIALS_MANAGER" ]; then + python3 "$CREDENTIALS_MANAGER" status + else + log_error "Credentials manager not found" + fi +} + +# Supprimer les credentials +delete_credentials() { + if [ -f "$CREDENTIALS_MANAGER" ]; then + python3 "$CREDENTIALS_MANAGER" delete + else + log_error "Credentials manager not found" + fi +} + # Démarrer le serveur start_server() { log_info "Starting Git Pusher server..." @@ -51,14 +121,14 @@ start_server() { return 1 fi + # Charger les credentials + if ! load_credentials; then + exit 1 + fi + # Créer le répertoire de logs mkdir -p "$LOG_DIR" - # Variables d'environnement pour l'authentification Splunk - # IMPORTANT: Modifiez ces valeurs ou utilisez des variables d'environnement - export SPLUNK_USERNAME=${SPLUNK_USERNAME:-admin} - export SPLUNK_PASSWORD=${SPLUNK_PASSWORD:-changeme} - # Démarrer le serveur Python cd "$BIN_DIR" python3 git_pusher.py > "${LOG_DIR}/git_pusher_startup.log" 2>&1 & @@ -80,8 +150,7 @@ start_server() { if [ -f "${APP_HOME}/local/license.lic" ]; then log_info "License file found" else - log_warn "No license file found at ${APP_HOME}/local/license.lic" - log_warn "The application will require license activation" + log_warn "No license file found - activation required" fi return 0 @@ -139,11 +208,11 @@ show_status() { if check_running; then PID=$(cat "$PID_FILE") - echo -e "Status: ${GREEN}RUNNING${NC}" + echo -e "Server Status: ${GREEN}RUNNING${NC}" echo "PID: $PID" echo "Port: 9999" else - echo -e "Status: ${RED}STOPPED${NC}" + echo -e "Server Status: ${RED}STOPPED${NC}" fi echo "" @@ -153,6 +222,16 @@ show_status() { echo " Log Dir: $LOG_DIR" echo "" + # Statut des credentials + echo "Credentials:" + if [ -f "${APP_HOME}/local/.credentials" ]; then + echo -e " Secure storage: ${GREEN}Configured${NC}" + else + echo -e " Secure storage: ${YELLOW}Not configured${NC}" + fi + + echo "" + # Statut de la licence echo "License:" if [ -f "${APP_HOME}/local/license.lic" ]; then @@ -162,14 +241,17 @@ show_status() { python3 -c " import sys sys.path.insert(0, '$BIN_DIR') -from license_validator import validate_license -result = validate_license() -if result.get('valid'): - print(f\" Type: {result.get('type_name', 'N/A')}\") - print(f\" Expires: {result.get('expires', 'N/A')}\") - print(f\" Days remaining: {result.get('days_remaining', 'N/A')}\") -else: - print(f\" Status: Invalid - {result.get('error', 'Unknown error')}\") +try: + from license_validator import validate_license + result = validate_license() + if result.get('valid'): + print(f\" Type: {result.get('type_name', 'N/A')}\") + print(f\" Expires: {result.get('expires', 'N/A')}\") + print(f\" Days remaining: {result.get('days_remaining', 'N/A')}\") + else: + print(f\" Status: Invalid - {result.get('error', 'Unknown error')}\") +except Exception as e: + print(f' Unable to read license: {e}') " 2>/dev/null || echo " Unable to read license details" fi else @@ -198,22 +280,29 @@ show_logs() { # Menu d'aide show_help() { - echo "Git Pusher - Server Management Script" + echo "Git Pusher - Server Management Script v2.0" echo "" - echo "Usage: $0 {start|stop|restart|status|logs|help}" + echo "Usage: $0 {command} [options]" echo "" - echo "Commands:" - echo " start Start the Git Pusher server" - echo " stop Stop the Git Pusher server" - echo " restart Restart the Git Pusher server" - echo " status Show the current status" - echo " logs Show recent logs (use -f for follow)" - echo " help Show this help message" + echo "Server Commands:" + echo " start Start the Git Pusher server" + echo " stop Stop the Git Pusher server" + echo " restart Restart the Git Pusher server" + echo " status Show the current status" + echo " logs [-f] Show recent logs (-f for follow)" echo "" - echo "Environment variables:" - echo " SPLUNK_USERNAME Splunk admin username (default: admin)" - echo " SPLUNK_PASSWORD Splunk admin password (default: changeme)" - echo " SPLUNK_HOME Splunk installation directory (default: /opt/splunk)" + echo "Credentials Commands:" + echo " credentials setup Configure Splunk credentials securely" + echo " credentials status Show credentials status" + echo " credentials delete Delete stored credentials" + echo "" + echo "Other:" + echo " help Show this help message" + echo "" + echo "Examples:" + echo " $0 credentials setup # First time setup" + echo " $0 start # Start server" + echo " $0 logs -f # Follow logs" } # Main @@ -233,17 +322,33 @@ case "$1" in logs) show_logs "$2" ;; + credentials) + case "$2" in + setup) + setup_credentials + ;; + status) + credentials_status + ;; + delete) + delete_credentials + ;; + *) + echo "Usage: $0 credentials {setup|status|delete}" + ;; + esac + ;; help|--help|-h) show_help ;; *) - # Par défaut, démarrer le serveur (pour compatibilité) if [ -z "$1" ]; then - start_server + show_help else echo "Unknown command: $1" + echo "" show_help exit 1 fi ;; -esac +esac \ No newline at end of file diff --git a/apps/pusher_app_prem/bin/start_git_pusher.sh.V1 b/apps/pusher_app_prem/bin/start_git_pusher.sh.V1 new file mode 100755 index 00000000..d205939a --- /dev/null +++ b/apps/pusher_app_prem/bin/start_git_pusher.sh.V1 @@ -0,0 +1,249 @@ +#!/bin/bash +# ============================================ +# Git Pusher - Start Script +# Version 2.0 avec système de licence +# ============================================ + +# Configuration +SPLUNK_HOME=${SPLUNK_HOME:-/opt/splunk} +APP_HOME="${SPLUNK_HOME}/etc/apps/pusher_app_prem" +BIN_DIR="${APP_HOME}/bin" +LOG_DIR="${SPLUNK_HOME}/var/log/splunk" +PID_FILE="${BIN_DIR}/git_pusher.pid" + +# Couleurs pour les logs +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Fonction de logging +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Vérifier si le serveur est déjà en cours d'exécution +check_running() { + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p $PID > /dev/null 2>&1; then + return 0 # Running + fi + fi + return 1 # Not running +} + +# Démarrer le serveur +start_server() { + log_info "Starting Git Pusher server..." + + # Vérifier si déjà en cours + if check_running; then + log_warn "Git Pusher is already running (PID: $(cat $PID_FILE))" + return 1 + fi + + # Créer le répertoire de logs + mkdir -p "$LOG_DIR" + + # Variables d'environnement pour l'authentification Splunk + # IMPORTANT: Modifiez ces valeurs ou utilisez des variables d'environnement + export SPLUNK_USERNAME=${SPLUNK_USERNAME:-admin} + export SPLUNK_PASSWORD=${SPLUNK_PASSWORD:-changeme} + + # Démarrer le serveur Python + cd "$BIN_DIR" + python3 git_pusher.py > "${LOG_DIR}/git_pusher_startup.log" 2>&1 & + + # Sauvegarder le PID + echo $! > "$PID_FILE" + + # Attendre un peu et vérifier + sleep 2 + + if check_running; then + log_info "Git Pusher started successfully (PID: $(cat $PID_FILE))" + log_info "Server listening on port 9999" + + # Vérifier le statut de la licence + HOSTNAME=$(hostname) + log_info "Hostname: $HOSTNAME" + + if [ -f "${APP_HOME}/local/license.lic" ]; then + log_info "License file found" + else + log_warn "No license file found at ${APP_HOME}/local/license.lic" + log_warn "The application will require license activation" + fi + + return 0 + else + log_error "Failed to start Git Pusher" + log_error "Check logs at ${LOG_DIR}/git_pusher.log" + return 1 + fi +} + +# Arrêter le serveur +stop_server() { + log_info "Stopping Git Pusher server..." + + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + + if ps -p $PID > /dev/null 2>&1; then + kill $PID + sleep 2 + + # Force kill si nécessaire + if ps -p $PID > /dev/null 2>&1; then + log_warn "Force killing process..." + kill -9 $PID + fi + + rm -f "$PID_FILE" + log_info "Git Pusher stopped" + return 0 + else + log_warn "Process not running, cleaning up PID file" + rm -f "$PID_FILE" + return 0 + fi + else + log_warn "PID file not found, Git Pusher may not be running" + return 1 + fi +} + +# Redémarrer le serveur +restart_server() { + log_info "Restarting Git Pusher server..." + stop_server + sleep 1 + start_server +} + +# Afficher le statut +show_status() { + echo "============================================" + echo "Git Pusher Status" + echo "============================================" + + if check_running; then + PID=$(cat "$PID_FILE") + echo -e "Status: ${GREEN}RUNNING${NC}" + echo "PID: $PID" + echo "Port: 9999" + else + echo -e "Status: ${RED}STOPPED${NC}" + fi + + echo "" + echo "Paths:" + echo " App Home: $APP_HOME" + echo " Bin Dir: $BIN_DIR" + echo " Log Dir: $LOG_DIR" + echo "" + + # Statut de la licence + echo "License:" + if [ -f "${APP_HOME}/local/license.lic" ]; then + echo -e " File: ${GREEN}Present${NC}" + # Essayer de lire quelques infos + if command -v python3 &> /dev/null; then + python3 -c " +import sys +sys.path.insert(0, '$BIN_DIR') +from license_validator import validate_license +result = validate_license() +if result.get('valid'): + print(f\" Type: {result.get('type_name', 'N/A')}\") + print(f\" Expires: {result.get('expires', 'N/A')}\") + print(f\" Days remaining: {result.get('days_remaining', 'N/A')}\") +else: + print(f\" Status: Invalid - {result.get('error', 'Unknown error')}\") +" 2>/dev/null || echo " Unable to read license details" + fi + else + echo -e " File: ${YELLOW}Not found${NC}" + fi + + echo "" + echo "Hostname: $(hostname)" + echo "============================================" +} + +# Afficher les logs +show_logs() { + LOG_FILE="${LOG_DIR}/git_pusher.log" + + if [ -f "$LOG_FILE" ]; then + if [ "$1" == "-f" ]; then + tail -f "$LOG_FILE" + else + tail -n 50 "$LOG_FILE" + fi + else + log_warn "Log file not found at $LOG_FILE" + fi +} + +# Menu d'aide +show_help() { + echo "Git Pusher - Server Management Script" + echo "" + echo "Usage: $0 {start|stop|restart|status|logs|help}" + echo "" + echo "Commands:" + echo " start Start the Git Pusher server" + echo " stop Stop the Git Pusher server" + echo " restart Restart the Git Pusher server" + echo " status Show the current status" + echo " logs Show recent logs (use -f for follow)" + echo " help Show this help message" + echo "" + echo "Environment variables:" + echo " SPLUNK_USERNAME Splunk admin username (default: admin)" + echo " SPLUNK_PASSWORD Splunk admin password (default: changeme)" + echo " SPLUNK_HOME Splunk installation directory (default: /opt/splunk)" +} + +# Main +case "$1" in + start) + start_server + ;; + stop) + stop_server + ;; + restart) + restart_server + ;; + status) + show_status + ;; + logs) + show_logs "$2" + ;; + help|--help|-h) + show_help + ;; + *) + # Par défaut, démarrer le serveur (pour compatibilité) + if [ -z "$1" ]; then + start_server + else + echo "Unknown command: $1" + show_help + exit 1 + fi + ;; +esac diff --git a/apps/pusher_app_prem/local/.credentials b/apps/pusher_app_prem/local/.credentials new file mode 100644 index 00000000..388185fd --- /dev/null +++ b/apps/pusher_app_prem/local/.credentials @@ -0,0 +1 @@ +{"username": "admin", "password": "VgNoQiAmDzgUO3NQ"} \ No newline at end of file diff --git a/apps/pusher_app_prem/local/.key b/apps/pusher_app_prem/local/.key new file mode 100644 index 00000000..1da59971 --- /dev/null +++ b/apps/pusher_app_prem/local/.key @@ -0,0 +1 @@ +d0YpjIlHuVRowV+y4yQh+VuqDhq7QikC3qepdfLE9+o= \ No newline at end of file diff --git a/apps/pusher_app_prem/local/usage_stats.json b/apps/pusher_app_prem/local/usage_stats.json index 73139971..7619f5e5 100644 --- a/apps/pusher_app_prem/local/usage_stats.json +++ b/apps/pusher_app_prem/local/usage_stats.json @@ -1 +1 @@ -{"pushes_today": 9, "pushes_total": 9, "last_push_date": "2026-01-31", "apps_pushed": []} \ No newline at end of file +{"pushes_today": 1, "pushes_total": 10, "last_push_date": "2026-02-01", "apps_pushed": []} \ No newline at end of file