Guide

Nouvelles mises à jour et améliorations de Roundfleet.

Gestion à Distance d'Entreprise et Contrôle d'Accès Sécurisé sur macOS

Implémentez une gestion à distance complète et un contrôle d'accès sécurisé sur vos appareils Roundfleet. Ce tutoriel couvre la configuration d'Apple Remote Desktop, la gestion d'accès à distance multi-protocoles, l'application de politiques de sécurité, les cadres de conformité et le déploiement automatisé à l'échelle de la flotte pour les environnements d'entreprise.

Comprendre la Gestion à Distance macOS

macOS fournit plusieurs protocoles et services de gestion à distance :

  • Apple Remote Desktop (ARD) - Solution de bureau à distance native macOS avec fonctionnalités de gestion complètes
  • SSH (Secure Shell) - Accès à distance en ligne de commande avec chiffrement fort
  • VNC (Virtual Network Computing) - Protocole de bureau à distance multi-plateforme
  • Partage d'Écran - Fonctionnalité de partage d'écran intégrée à macOS
  • Connexion à Distance - Accès à distance basé sur terminal
  • Apple Configurator - Outil de configuration et gestion d'appareils

Configuration Basique de Gestion à Distance

Activer Apple Remote Desktop

#!/bin/bash

# Activer Apple Remote Desktop avec configuration de base
enable_remote_desktop() {
    echo "=== Activation d'Apple Remote Desktop ==="
    
    local kickstart_path="/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart"
    
    if [[ ! -f "$kickstart_path" ]]; then
        echo "❌ Agent ARD non trouvé sur ce système"
        return 1
    fi
    
    # Activer la Gestion à Distance
    if sudo "$kickstart_path" -activate; then
        echo "✅ Apple Remote Desktop activé avec succès"
    else
        echo "❌ Échec de l'activation d'Apple Remote Desktop"
        return 1
    fi
    
    # Configurer les paramètres de base
    sudo "$kickstart_path" -configure -allowAccessFor -allUsers -privs -all
    
    # Redémarrer l'Agent ARD
    sudo "$kickstart_path" -restart -agent
    
    echo "✅ Configuration d'Apple Remote Desktop terminée"
    return 0
}

# Exécuter la fonction
enable_remote_desktop

Désactiver la Gestion à Distance

#!/bin/bash

# Désactiver Apple Remote Desktop
disable_remote_desktop() {
    echo "=== Désactivation d'Apple Remote Desktop ==="
    
    local kickstart_path="/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart"
    
    if [[ ! -f "$kickstart_path" ]]; then
        echo "❌ Agent ARD non trouvé sur ce système"
        return 1
    fi
    
    # Désactiver la Gestion à Distance
    if sudo "$kickstart_path" -deactivate; then
        echo "✅ Apple Remote Desktop désactivé avec succès"
    else
        echo "❌ Échec de la désactivation d'Apple Remote Desktop"
        return 1
    fi
    
    return 0
}

# Exécuter la fonction
disable_remote_desktop

Configurer l'Accès Spécifique aux Utilisateurs

#!/bin/bash

# Configurer la Gestion à Distance pour des utilisateurs spécifiques
configure_user_access() {
    local target_users="$1"
    local privileges="$2"
    
    echo "=== Configuration de l'Accès à Distance Spécifique aux Utilisateurs ==="
    
    local kickstart_path="/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart"
    
    if [[ -z "$target_users" ]]; then
        echo "❌ Utilisateurs cibles requis"
        echo "Usage: configure_user_access 'user1,user2' 'privileges'"
        return 1
    fi
    
    # Activer avec utilisateurs spécifiés
    sudo "$kickstart_path" -activate -configure -allowAccessFor -specifiedUsers
    
    # Configurer les privilèges utilisateur
    IFS=',' read -ra USERS <<< "$target_users"
    for user in "${USERS[@]}"; do
        if id "$user" &>/dev/null; then
            sudo "$kickstart_path" -configure -users "$user" -access -on -privs -all
            echo "✅ Accès configuré pour l'utilisateur: $user"
        else
            echo "⚠️  Utilisateur non trouvé: $user"
        fi
    done
    
    return 0
}

# Exemple d'utilisation
# configure_user_access "admin,support" "all"

Système de Gestion à Distance d'Entreprise

#!/bin/bash

# Système de Gestion à Distance d'Entreprise Roundfleet
# Contrôle d'accès à distance complet, conformité sécuritaire et gestion de flotte

# Configuration
LOG_FILE="/var/log/roundfleet_remote_management.log"
CONFIG_DIR="/etc/roundfleet/remote_management"
POLICIES_DIR="$CONFIG_DIR/policies"
REPORTS_DIR="$CONFIG_DIR/reports"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"
SECURITY_DIR="$CONFIG_DIR/security"
SESSION_DIR="$CONFIG_DIR/sessions"

# Protocoles d'accès à distance
declare -A REMOTE_PROTOCOLS=(
    ["ard"]="Apple Remote Desktop"
    ["ssh"]="Secure Shell"
    ["vnc"]="Virtual Network Computing"
    ["screen_sharing"]="Partage d'Écran macOS"
    ["remote_login"]="Connexion à Distance Terminal"
)

# Cadres de conformité sécuritaire
declare -A COMPLIANCE_FRAMEWORKS=(
    ["nist"]="access_control,encryption_in_transit,session_management,audit_trails"
    ["iso27001"]="secure_remote_access,access_control,monitoring,documentation"
    ["cis"]="secure_protocols,authentication,session_limits,logging"
    ["sox"]="financial_access_control,audit_requirements,change_management"
    ["hipaa"]="minimum_necessary,access_controls,audit_logs,encryption"
    ["pci_dss"]="secure_protocols,access_control,monitoring,encryption"
)

# Niveaux de privilège d'accès
declare -A PRIVILEGE_LEVELS=(
    ["view_only"]="observe,report"
    ["control"]="observe,control,interact"
    ["manage"]="observe,control,interact,copy_files,restart"
    ["admin"]="observe,control,interact,copy_files,restart,change_settings"
    ["full"]="all_privileges"
)

# Politiques de sécurité
declare -A SECURITY_POLICIES=(
    ["strict"]="mfa_required,encryption_mandatory,session_timeout_15min,audit_all"
    ["standard"]="password_auth,encryption_preferred,session_timeout_30min,audit_admin"
    ["relaxed"]="basic_auth,session_timeout_60min,audit_changes"
    ["compliance"]="enterprise_auth,full_encryption,session_timeout_10min,comprehensive_audit"
)

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Configuration des répertoires
setup_directories() {
    for dir in "$CONFIG_DIR" "$POLICIES_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR" "$SECURITY_DIR" "$SESSION_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Répertoire créé: $dir"
        fi
    done
}

# Vérifier le statut actuel de la gestion à distance
check_remote_management_status() {
    echo "=== Vérification du Statut de Gestion à Distance ==="
    
    local status_report="$REPORTS_DIR/remote_status_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$status_report" << EOF
{
    "status_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "os_version": "$(sw_vers -productVersion)"
    },
    "remote_services": {
EOF

    local first=true
    
    # Vérifier Apple Remote Desktop
    local ard_status="disabled"
    if ps aux | grep -q "ARDAgent" && ! echo "$!" | grep -q "grep"; then
        ard_status="enabled"
    fi
    
    cat >> "$status_report" << EOF
        "apple_remote_desktop": {
            "status": "$ard_status",
            "process_running": $(pgrep -q ARDAgent && echo "true" || echo "false"),
            "port": "5900"
        },
EOF

    # Vérifier SSH
    local ssh_status="disabled"
    if sudo systemsetup -getremotelogin | grep -q "On"; then
        ssh_status="enabled"
    fi
    
    cat >> "$status_report" << EOF
        "ssh": {
            "status": "$ssh_status",
            "port": "22",
            "service_running": $(launchctl list | grep -q "com.openssh.sshd" && echo "true" || echo "false")
        },
EOF

    # Vérifier VNC/Partage d'Écran
    local vnc_status="disabled"
    if launchctl list | grep -q "com.apple.screensharing"; then
        vnc_status="enabled"
    fi
    
    cat >> "$status_report" << EOF
        "screen_sharing": {
            "status": "$vnc_status",
            "port": "5900",
            "service_running": $(launchctl list | grep -q "com.apple.screensharing" && echo "true" || echo "false")
        }
    },
    "security_assessment": $(assess_remote_security),
    "active_sessions": $(get_active_remote_sessions)
}
EOF

    log_action "✅ Vérification du statut de gestion à distance terminée: $status_report"
    echo "$status_report"
}

# Évaluer la sécurité d'accès à distance
assess_remote_security() {
    local security_score=0
    local total_checks=10
    
    # Vérifier le chiffrement
    if sudo systemsetup -getremotelogin | grep -q "On"; then
        security_score=$((security_score + 2))  # SSH est chiffré
    fi
    
    # Vérifier le statut du pare-feu
    if sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate | grep -q "enabled"; then
        security_score=$((security_score + 2))
    fi
    
    # Vérifier la complexité des mots de passe
    if pwpolicy -getaccountpolicies 2>/dev/null | grep -q "minLength"; then
        security_score=$((security_score + 1))
    fi
    
    # Vérifier les tentatives de connexion échouées
    local failed_attempts
    failed_attempts=$(grep "authentication failure" /var/log/auth.log 2>/dev/null | wc -l || echo 0)
    if [[ $failed_attempts -lt 10 ]]; then
        security_score=$((security_score + 1))
    fi
    
    # Vérifier la surveillance active
    if [[ -f "$LOG_FILE" ]]; then
        security_score=$((security_score + 1))
    fi
    
    # Vérifications de sécurité supplémentaires
    security_score=$((security_score + 3))  # Placeholder pour vérifications supplémentaires
    
    local security_percentage
    security_percentage=$(awk "BEGIN {printf \"%.0f\", ($security_score/$total_checks)*100}")
    
    local risk_level="faible"
    if [[ $security_percentage -lt 60 ]]; then
        risk_level="eleve"
    elif [[ $security_percentage -lt 80 ]]; then
        risk_level="moyen"
    fi
    
    echo "{\"score\": $security_score, \"percentage\": $security_percentage, \"risk_level\": \"$risk_level\"}"
}

# Obtenir les sessions à distance actives
get_active_remote_sessions() {
    local sessions='['
    local first=true
    
    # Vérifier les sessions SSH
    local ssh_sessions
    ssh_sessions=$(who | grep "pts/" || echo "")
    
    while IFS= read -r session; do
        if [[ -n "$session" ]]; then
            if [[ "$first" == true ]]; then
                first=false
            else
                sessions+=','
            fi
            
            local user
            user=$(echo "$session" | awk '{print $1}')
            local terminal
            terminal=$(echo "$session" | awk '{print $2}')
            local login_time
            login_time=$(echo "$session" | awk '{print $3, $4}')
            local remote_host
            remote_host=$(echo "$session" | awk '{print $5}' | tr -d '()')
            
            sessions+="{\"type\": \"ssh\", \"user\": \"$user\", \"terminal\": \"$terminal\", \"login_time\": \"$login_time\", \"remote_host\": \"$remote_host\"}"
        fi
    done <<< "$ssh_sessions"
    
    # Vérifier les sessions VNC/ARD
    local vnc_sessions
    vnc_sessions=$(netstat -an | grep ":5900" | grep "ESTABLISHED" || echo "")
    
    while IFS= read -r connection; do
        if [[ -n "$connection" ]]; then
            if [[ "$first" == true ]]; then
                first=false
            else
                sessions+=','
            fi
            
            local remote_ip
            remote_ip=$(echo "$connection" | awk '{print $5}' | cut -d: -f1)
            
            sessions+="{\"type\": \"vnc_ard\", \"remote_ip\": \"$remote_ip\", \"port\": \"5900\"}"
        fi
    done <<< "$vnc_sessions"
    
    sessions+=']'
    echo "$sessions"
}

# Configurer l'accès à distance d'entreprise
configure_enterprise_remote_access() {
    local access_policy="$1"
    local target_protocols="$2"
    local user_groups="$3"
    
    log_action "Configuration de l'accès à distance d'entreprise avec politique: $access_policy"
    
    # Analyser la configuration de politique
    local policy_config="${SECURITY_POLICIES[$access_policy]}"
    if [[ -z "$policy_config" ]]; then
        log_action "❌ Politique de sécurité inconnue: $access_policy"
        return 1
    fi
    
    # Configurer chaque protocole spécifié
    IFS=',' read -ra PROTOCOLS <<< "$target_protocols"
    for protocol in "${PROTOCOLS[@]}"; do
        case "$protocol" in
            "ard")
                configure_ard_enterprise "$access_policy" "$user_groups"
                ;;
            "ssh")
                configure_ssh_enterprise "$access_policy" "$user_groups"
                ;;
            "vnc")
                configure_vnc_enterprise "$access_policy" "$user_groups"
                ;;
            "screen_sharing")
                configure_screen_sharing_enterprise "$access_policy" "$user_groups"
                ;;
            *)
                log_action "⚠️  Protocole inconnu: $protocol"
                ;;
        esac
    done
    
    # Appliquer les paramètres de politique de sécurité
    apply_security_policy_settings "$access_policy"
    
    log_action "✅ Configuration d'accès à distance d'entreprise terminée"
}

# Configurer Apple Remote Desktop pour l'entreprise
configure_ard_enterprise() {
    local policy="$1"
    local user_groups="$2"
    
    echo "🖥️  Configuration d'Apple Remote Desktop pour l'entreprise"
    
    local kickstart_path="/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart"
    
    # Activer ARD
    sudo "$kickstart_path" -activate -restart
    
    # Configurer selon la politique
    case "$policy" in
        "strict"|"compliance")
            # Accès restreint avec utilisateurs spécifiques uniquement
            sudo "$kickstart_path" -configure -allowAccessFor -specifiedUsers
            sudo "$kickstart_path" -configure -privs -observe -control -interact
            ;;
        "standard")
            # Configuration standard
            sudo "$kickstart_path" -configure -allowAccessFor -specifiedUsers
            sudo "$kickstart_path" -configure -privs -observe -control
            ;;
        "relaxed")
            # Configuration plus permissive
            sudo "$kickstart_path" -configure -allowAccessFor -allUsers
            sudo "$kickstart_path" -configure -privs -all
            ;;
    esac
    
    # Configurer des utilisateurs spécifiques si fournis
    if [[ -n "$user_groups" ]]; then
        IFS=',' read -ra GROUPS <<< "$user_groups"
        for group in "${GROUPS[@]}"; do
            # Ajouter les utilisateurs du groupe à l'accès ARD
            local group_users
            group_users=$(dscl . -read "/Groups/$group" GroupMembership 2>/dev/null | cut -d: -f2)
            
            for user in $group_users; do
                if id "$user" &>/dev/null; then
                    sudo "$kickstart_path" -configure -users "$user" -access -on
                    log_action "Accès ARD ajouté pour l'utilisateur: $user"
                fi
            done
        done
    fi
    
    # Créer une sauvegarde de configuration ARD
    local ard_config="$SECURITY_DIR/ard_config_$(date '+%Y%m%d_%H%M%S').conf"
    cat > "$ard_config" << EOF
# Configuration Apple Remote Desktop
# Politique: $policy
# Configuré: $(date)

POLICY="$policy"
USER_GROUPS="$user_groups"
CONFIGURATION_DATE="$(date -Iseconds)"
ARD_STATUS="enabled"
ACCESS_CONTROL="specified_users"
EOF

    log_action "✅ Configuration ARD d'entreprise terminée"
}

# Configurer SSH pour l'entreprise
configure_ssh_enterprise() {
    local policy="$1"
    local user_groups="$2"
    
    echo "🔐 Configuration SSH pour l'entreprise"
    
    # Activer SSH (Connexion à Distance)
    sudo systemsetup -setremotelogin on
    
    # Configurer la sécurité SSH selon la politique
    local sshd_config="/etc/ssh/sshd_config"
    local custom_config="$SECURITY_DIR/ssh_custom_config"
    
    case "$policy" in
        "strict"|"compliance")
            cat > "$custom_config" << EOF
# Configuration SSH d'Entreprise - Politique Stricte
Protocol 2
PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication yes
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
MaxSessions 5
LoginGraceTime 60
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes
EOF
            ;;
        "standard")
            cat > "$custom_config" << EOF
# Configuration SSH d'Entreprise - Politique Standard
Protocol 2
PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication yes
MaxAuthTries 5
ClientAliveInterval 600
ClientAliveCountMax 3
MaxSessions 10
LoginGraceTime 120
PermitEmptyPasswords no
EOF
            ;;
        "relaxed")
            cat > "$custom_config" << EOF
# Configuration SSH d'Entreprise - Politique Souple
Protocol 2
PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication yes
MaxAuthTries 10
ClientAliveInterval 900
MaxSessions 20
EOF
            ;;
    esac
    
    # Sauvegarder la configuration originale et appliquer la configuration personnalisée
    if [[ -f "$sshd_config" ]]; then
        sudo cp "$sshd_config" "$sshd_config.backup.$(date '+%Y%m%d_%H%M%S')"
    fi
    
    # Appliquer la configuration SSH personnalisée
    sudo cp "$custom_config" "/etc/ssh/sshd_config.d/roundfleet_enterprise.conf"
    
    # Redémarrer le service SSH
    sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist 2>/dev/null
    sudo launchctl load /System/Library/LaunchDaemons/ssh.plist
    
    log_action "✅ Configuration SSH d'entreprise terminée"
}

# Surveiller les sessions d'accès à distance
monitor_remote_sessions() {
    log_action "Démarrage de la surveillance des sessions à distance"
    
    local monitoring_report="$SESSION_DIR/session_monitoring_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$monitoring_report" << EOF
{
    "monitoring_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "monitoring_period": "temps_reel"
    },
    "active_sessions": $(get_active_remote_sessions),
    "session_analytics": {
        "total_active_sessions": $(get_active_remote_sessions | jq '. | length'),
        "protocols_in_use": $(get_protocols_in_use),
        "unique_remote_hosts": $(get_unique_remote_hosts),
        "session_duration_analysis": $(analyze_session_durations)
    },
    "security_events": $(detect_security_events)
}
EOF

    log_action "✅ Surveillance des sessions à distance terminée: $monitoring_report"
    echo "$monitoring_report"
}

# Détecter les événements de sécurité
detect_security_events() {
    local events='['
    local first=true
    
    # Vérifier les tentatives de connexion échouées
    local failed_logins
    failed_logins=$(grep "authentication failure" /var/log/auth.log 2>/dev/null | tail -10)
    
    while IFS= read -r event; do
        if [[ -n "$event" ]]; then
            if [[ "$first" == true ]]; then
                first=false
            else
                events+=','
            fi
            
            local timestamp
            timestamp=$(echo "$event" | awk '{print $1, $2, $3}')
            local user
            user=$(echo "$event" | grep -o "user=[^ ]*" | cut -d= -f2 || echo "inconnu")
            
            events+="{\"type\": \"failed_login\", \"timestamp\": \"$timestamp\", \"user\": \"$user\", \"severity\": \"moyen\"}"
        fi
    done <<< "$failed_logins"
    
    # Vérifier les modèles de connexion inhabituels
    local unusual_connections
    unusual_connections=$(netstat -an | grep ":22\|:5900" | grep "ESTABLISHED" | wc -l)
    
    if [[ $unusual_connections -gt 10 ]]; then
        if [[ "$first" == true ]]; then
            first=false
        else
            events+=','
        fi
        
        events+="{\"type\": \"high_connection_count\", \"count\": $unusual_connections, \"severity\": \"eleve\"}"
    fi
    
    events+=']'
    echo "$events"
}

# Générer un rapport de conformité
generate_compliance_report() {
    local framework="$1"
    
    log_action "Génération du rapport de conformité d'accès à distance pour: $framework"
    
    local compliance_report="$COMPLIANCE_DIR/remote_compliance_${framework}_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$compliance_report" << EOF
{
    "compliance_metadata": {
        "timestamp": "$(date -Iseconds)",
        "framework": "$framework",
        "hostname": "$(hostname)",
        "generator": "Roundfleet Remote Management Compliance"
    },
    "framework_requirements": $(get_framework_requirements "$framework"),
    "compliance_assessment": {
        "overall_score": $(calculate_compliance_score "$framework"),
        "protocol_compliance": $(assess_protocol_compliance "$framework"),
        "security_compliance": $(assess_security_compliance "$framework"),
        "access_control_compliance": $(assess_access_control_compliance "$framework")
    },
    "recommendations": $(generate_compliance_recommendations "$framework"),
    "remediation_actions": $(generate_remediation_actions "$framework")
}
EOF

    log_action "✅ Rapport de conformité généré: $compliance_report"
    echo "$compliance_report"
}

# Calculer le score de conformité
calculate_compliance_score() {
    local framework="$1"
    
    local total_score=0
    local check_count=0
    
    # Vérifications de conformité de base
    check_count=$((check_count + 1))
    if sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate | grep -q "enabled"; then
        total_score=$((total_score + 20))
    fi
    
    check_count=$((check_count + 1))
    if [[ -f "$LOG_FILE" ]]; then
        total_score=$((total_score + 20))
    fi
    
    check_count=$((check_count + 1))
    if sudo systemsetup -getremotelogin | grep -q "On"; then
        total_score=$((total_score + 15))  # Chiffrement SSH
    fi
    
    check_count=$((check_count + 1))
    if [[ -d "$SECURITY_DIR" ]]; then
        total_score=$((total_score + 15))
    fi
    
    # Vérifications spécifiques au cadre
    case "$framework" in
        "nist"|"iso27001")
            check_count=$((check_count + 1))
            if [[ -f "$SECURITY_DIR/ard_config"* ]]; then
                total_score=$((total_score + 15))
            fi
            
            check_count=$((check_count + 1))
            if [[ -f "/etc/ssh/sshd_config.d/roundfleet_enterprise.conf" ]]; then
                total_score=$((total_score + 15))
            fi
            ;;
    esac
    
    local final_score
    final_score=$(awk "BEGIN {printf \"%.0f\", ($total_score/$check_count)}")
    
    echo "$final_score"
}

# Appliquer les politiques de sécurité automatisées
apply_automated_security_policies() {
    local policy_type="$1"
    
    log_action "Application des politiques de sécurité automatisées: $policy_type"
    
    case "$policy_type" in
        "session_timeout")
            configure_session_timeouts
            ;;
        "failed_login_protection")
            configure_failed_login_protection
            ;;
        "encryption_enforcement")
            enforce_encryption_policies
            ;;
        "access_logging")
            configure_comprehensive_logging
            ;;
        *)
            log_action "⚠️  Type de politique inconnu: $policy_type"
            return 1
            ;;
    esac
    
    log_action "✅ Politiques de sécurité automatisées appliquées"
}

# Configurer les timeouts de session
configure_session_timeouts() {
    echo "⏰ Configuration des timeouts de session"
    
    # Timeouts de session SSH (déjà configurés dans la configuration SSH d'entreprise)
    # Configuration du timeout de session ARD
    local timeout_config="$SECURITY_DIR/session_timeouts.conf"
    
    cat > "$timeout_config" << EOF
# Configuration des Timeouts de Session
SSH_CLIENT_ALIVE_INTERVAL=300
SSH_CLIENT_ALIVE_COUNT_MAX=2
ARD_SESSION_TIMEOUT=1800
VNC_SESSION_TIMEOUT=1800
SCREEN_SHARING_TIMEOUT=1800
IDLE_DISCONNECT_TIME=900
EOF

    log_action "✅ Timeouts de session configurés"
}

# Fonction d'exécution principale
main() {
    local action="${1:-status}"
    local parameter="$2"
    local additional_param="$3"
    local extra_param="$4"
    
    log_action "=== Gestion à Distance Roundfleet Démarrée ==="
    log_action "Action: $action"
    log_action "Paramètre: ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "enable")
            if [[ -z "$parameter" ]]; then
                enable_remote_desktop
            else
                configure_enterprise_remote_access "$parameter" "${additional_param:-ard}" "$extra_param"
            fi
            ;;
        "disable")
            disable_remote_desktop
            ;;
        "status")
            check_remote_management_status
            ;;
        "configure")
            if [[ -z "$parameter" || -z "$additional_param" ]]; then
                echo "Usage: $0 configure <politique> <protocoles> [groupes_utilisateurs]"
                echo "Politiques: ${!SECURITY_POLICIES[*]}"
                echo "Protocoles: ${!REMOTE_PROTOCOLS[*]}"
                exit 1
            fi
            configure_enterprise_remote_access "$parameter" "$additional_param" "$extra_param"
            ;;
        "monitor")
            monitor_remote_sessions
            ;;
        "compliance")
            if [[ -z "$parameter" ]]; then
                echo "Cadres de conformité disponibles:"
                for framework in "${!COMPLIANCE_FRAMEWORKS[@]}"; do
                    echo "  - $framework: ${COMPLIANCE_FRAMEWORKS[$framework]}"
                done
                echo ""
                echo "Usage: $0 compliance <cadre>"
                exit 1
            fi
            generate_compliance_report "$parameter"
            ;;
        "users")
            if [[ -z "$parameter" || -z "$additional_param" ]]; then
                echo "Usage: $0 users <liste_utilisateurs> <privileges>"
                echo "Exemple: $0 users 'admin,support' 'control'"
                exit 1
            fi
            configure_user_access "$parameter" "$additional_param"
            ;;
        "security")
            if [[ -z "$parameter" ]]; then
                echo "Politiques de sécurité disponibles:"
                echo "  - session_timeout"
                echo "  - failed_login_protection"
                echo "  - encryption_enforcement"
                echo "  - access_logging"
                echo ""
                echo "Usage: $0 security <type_politique>"
                exit 1
            fi
            apply_automated_security_policies "$parameter"
            ;;
        *)
            echo "Usage: $0 {enable|disable|status|configure|monitor|compliance|users|security}"
            echo "  enable      - Activer la gestion à distance de base ou configurer une politique d'entreprise"
            echo "  disable     - Désactiver la gestion à distance"
            echo "  status      - Vérifier le statut actuel de la gestion à distance"
            echo "  configure   - Configurer l'accès à distance d'entreprise avec politiques"
            echo "  monitor     - Surveiller les sessions à distance actives"
            echo "  compliance  - Générer un rapport de conformité"
            echo "  users       - Configurer l'accès spécifique aux utilisateurs"
            echo "  security    - Appliquer les politiques de sécurité automatisées"
            exit 1
            ;;
    esac
    
    log_action "=== Opération de gestion à distance terminée ==="
}

# Exécuter la fonction principale
main "$@"

Fonctionnalités Avancées de Gestion à Distance

Gestion de Sessions Multi-Protocoles

#!/bin/bash

# Gestion complète de sessions multi-protocoles
manage_multi_protocol_sessions() {
    echo "=== Gestion de Sessions Multi-Protocoles ==="
    
    local session_config="$SESSION_DIR/protocol_management.json"
    
    cat > "$session_config" << EOF
{
    "protocol_management": {
        "apple_remote_desktop": {
            "port": 5900,
            "encryption": "AES-128",
            "authentication": "comptes_systeme",
            "max_concurrent_sessions": 5,
            "session_timeout": 1800
        },
        "ssh": {
            "port": 22,
            "encryption": "AES-256",
            "authentication": "cles_preferees",
            "max_concurrent_sessions": 10,
            "session_timeout": 3600
        },
        "vnc": {
            "port": 5900,
            "encryption": "optionnel",
            "authentication": "mot_de_passe_vnc",
            "max_concurrent_sessions": 3,
            "session_timeout": 1800
        },
        "screen_sharing": {
            "port": 5900,
            "encryption": "integre",
            "authentication": "comptes_systeme",
            "max_concurrent_sessions": 2,
            "session_timeout": 2700
        }
    },
    "security_policies": {
        "force_encryption": true,
        "require_mfa": false,
        "log_all_sessions": true,
        "geographic_restrictions": false,
        "time_based_access": false
    }
}
EOF

    echo "📊 Gestion de sessions multi-protocoles configurée: $session_config"
}

# Surveillance de sécurité avancée
advanced_security_monitoring() {
    echo "🔍 Surveillance de Sécurité Avancée"
    
    local monitoring_script="$SECURITY_DIR/advanced_monitoring.sh"
    
    cat > "$monitoring_script" << 'EOF'
#!/bin/bash

# Surveillance de Sécurité d'Accès à Distance Avancée

while true; do
    # Surveiller les tentatives de connexion
    CONNECTION_ATTEMPTS=$(netstat -an | grep -E ":22|:5900" | grep "SYN_RECV" | wc -l)
    
    if [[ $CONNECTION_ATTEMPTS -gt 20 ]]; then
        logger "Roundfleet: Nombre élevé de tentatives de connexion à distance détecté: $CONNECTION_ATTEMPTS"
        # Envoyer une alerte
        echo "Tentatives de connexion élevées: $CONNECTION_ATTEMPTS" | mail -s "Alerte Sécurité Roundfleet" [email protected]
    fi
    
    # Surveiller les échecs d'authentification
    FAILED_AUTH=$(grep "authentication failure" /var/log/auth.log | grep "$(date '+%Y-%m-%d')" | wc -l)
    
    if [[ $FAILED_AUTH -gt 10 ]]; then
        logger "Roundfleet: Nombre élevé d'échecs d'authentification: $FAILED_AUTH"
    fi
    
    # Surveiller les modèles d'accès à distance inhabituels
    UNIQUE_IPS=$(netstat -an | grep -E ":22|:5900" | grep "ESTABLISHED" | awk '{print $5}' | cut -d: -f1 | sort -u | wc -l)
    
    if [[ $UNIQUE_IPS -gt 5 ]]; then
        logger "Roundfleet: Plusieurs IPs à distance uniques détectées: $UNIQUE_IPS"
    fi
    
    sleep 300  # Vérifier toutes les 5 minutes
done
EOF

    chmod +x "$monitoring_script"
    echo "🔐 Script de surveillance de sécurité avancée créé"
}

Accès à Distance Zero Trust

#!/bin/bash

# Implémenter les principes d'accès à distance Zero Trust
implement_zero_trust_remote_access() {
    echo "🛡️  Implémentation de l'Accès à Distance Zero Trust"
    
    local zero_trust_config="$SECURITY_DIR/zero_trust_config.json"
    
    cat > "$zero_trust_config" << EOF
{
    "zero_trust_principles": {
        "verify_explicitly": {
            "device_verification": true,
            "user_verification": true,
            "location_verification": true,
            "behavior_analysis": true
        },
        "least_privilege_access": {
            "session_based_permissions": true,
            "time_limited_access": true,
            "resource_specific_access": true,
            "privilege_escalation_monitoring": true
        },
        "assume_breach": {
            "continuous_monitoring": true,
            "anomaly_detection": true,
            "session_recording": true,
            "immediate_response": true
        }
    },
    "implementation_controls": {
        "device_trust_score": "requis",
        "user_risk_assessment": "continu",
        "network_segmentation": "active",
        "encrypted_channels_only": true,
        "session_isolation": true
    }
}
EOF

    echo "🎯 Configuration d'accès à distance Zero Trust créée"
}

Meilleures Pratiques de Sécurité

🔐 Contrôle d'Accès et Authentification

  • Authentification multi-facteurs avec intégration d'identité d'entreprise
  • Contrôle d'accès basé sur les rôles avec gestion granulaire des permissions
  • Vérification de confiance d'appareil avec authentification basée sur certificats
  • Contrôle d'accès basé sur session avec permissions limitées dans le temps

🛡️ Sécurité Réseau et Chiffrement

  • Chiffrement de bout en bout pour tous les protocoles à distance (AES-256)
  • Intégration VPN avec établissement de tunnel sécurisé
  • Segmentation réseau avec application de micro-périmètre
  • Analyse de trafic avec détection d'anomalies et intelligence des menaces

📊 Surveillance et Conformité

  • Surveillance de session en temps réel avec journalisation complète
  • Support de cadres de conformité (NIST, ISO 27001, CIS, SOX, HIPAA, PCI DSS)
  • Évaluation de sécurité automatisée avec scoring de risque et alertes
  • Capacités forensiques avec pistes d'audit détaillées et enregistrement de sessions

🚀 Opérations d'Entreprise

  • Déploiement à l'échelle de la flotte avec gestion centralisée des politiques
  • Provisioning automatisé avec intégration du cycle de vie d'identité
  • Haute disponibilité avec équilibrage de charge et capacités de basculement
  • Écosystème d'intégration avec SIEM, IAM et outils de sécurité

Notes Importantes

  • Apple Remote Desktop nécessite une licence appropriée pour un usage d'entreprise
  • Gestion des clés SSH essentielle pour les déploiements d'entreprise sécurisés
  • Configuration du pare-feu réseau requise pour compléter la sécurité au niveau appareil
  • Évaluations de sécurité régulières nécessaires pour maintenir la posture de conformité
  • Formation utilisateur critique pour les pratiques d'accès à distance sécurisé
  • Procédures de réponse aux incidents doivent être établies pour les événements de sécurité

Réduction du mouvement et de la transparence sur les appareils macOS

macOS propose diverses options d'accessibilité pour améliorer l'expérience utilisateur, particulièrement pour les utilisateurs sensibles aux effets visuels ou nécessitant des performances optimisées. La section Affichage des paramètres d'Accessibilité permet aux utilisateurs de modifier les paramètres d'affichage selon leurs besoins, incluant les options pour réduire le mouvement et la transparence. Ce guide complet fournit des scripts et techniques pour gérer ces paramètres sur les flottes Mac.

Comprendre les paramètres de mouvement et de transparence

Réduire le mouvement

Le paramètre "Réduire le mouvement" modifie les animations d'interface pour les rendre plus simples et visuellement plus confortables. Quand activé, il remplace les animations complexes par des effets de fondu croisé plus simples, réduisant l'inconfort potentiel pour les utilisateurs sensibles au mouvement.

Avantages :

  • Réduit la fatigue oculaire et le mal des transports
  • Améliore les performances sur le matériel plus ancien
  • Crée une interface utilisateur plus prévisible
  • Aide les utilisateurs avec des troubles vestibulaires ou une sensibilité au mouvement

Réduire la transparence

Le paramètre "Réduire la transparence" change les éléments semi-transparents de l'interface utilisateur en éléments solides, supprimant les effets de flou et de transparence à travers le système.

Avantages :

  • Améliore la lisibilité et le contraste
  • Réduit les distractions visuelles
  • Meilleures performances sur les systèmes avec des capacités graphiques limitées
  • Aide les utilisateurs avec des déficiences visuelles

Prérequis

Avant de configurer les paramètres de mouvement et de transparence, assurez-vous d'avoir :

  • Privilèges administrateur sur le Mac
  • Accès Terminal ou SSH
  • Compréhension des exigences de contexte utilisateur
  • Sauvegarde des paramètres actuels (recommandé)

Commandes de configuration de base

Comprendre le processus de configuration

Les paramètres d'accessibilité macOS sont stockés dans les préférences utilisateur et nécessitent des approches spécifiques :

  • Contexte utilisateur : Les paramètres doivent être appliqués pour l'utilisateur correct
  • Fichiers de préférences : Les paramètres sont stockés dans com.apple.universalaccess.plist
  • Intégration système : Les changements affectent toute l'interface utilisateur
  • Application en temps réel : Les paramètres prennent effet immédiatement

Détection de l'utilisateur actuel

La plupart des paramètres d'accessibilité requièrent un contexte utilisateur. Voici comment détecter l'utilisateur actuel :

#!/bin/bash

# Obtenir l'utilisateur de console actuel
get_current_user() {
    local current_user=$(ls -l /dev/console | awk '{ print $3 }')
    echo "$current_user"
}

# Obtenir le répertoire home de l'utilisateur
get_user_home() {
    local username=$1
    local user_home=$(eval echo ~$username)
    echo "$user_home"
}

# Exemple d'utilisation
current_user=$(get_current_user)
user_home=$(get_user_home "$current_user")

echo "Utilisateur actuel: $current_user"
echo "Répertoire home: $user_home"

Réduction de base du mouvement et de la transparence

Script d'activation simple

Script de base pour activer à la fois la réduction du mouvement et de la transparence :

#!/bin/bash

# Activer la réduction du mouvement et de la transparence
echo "Configuration des paramètres d'accessibilité..."

# Obtenir l'utilisateur actuel
loggedInUser=$(ls -l /dev/console | awk '{ print $3 }')

if [ -z "$loggedInUser" ] || [ "$loggedInUser" = "root" ]; then
    echo "Erreur: Aucune session utilisateur valide trouvée"
    exit 1
fi

echo "Configuration des paramètres pour l'utilisateur: $loggedInUser"

# Activer la réduction du mouvement
if su -l "$loggedInUser" -c "defaults write com.apple.universalaccess reduceMotion -bool true"; then
    echo "✓ Réduction du mouvement activée"
else
    echo "✗ Échec de l'activation de la réduction du mouvement"
    exit 1
fi

# Activer la réduction de la transparence
if su -l "$loggedInUser" -c "defaults write com.apple.universalaccess reduceTransparency -bool true"; then
    echo "✓ Réduction de la transparence activée"
else
    echo "✗ Échec de l'activation de la réduction de la transparence"
    exit 1
fi

echo "Paramètres d'accessibilité configurés avec succès"

Script de configuration avancé

Script plus complet avec validation et journalisation :

#!/bin/bash

# Script avancé de configuration d'accessibilité
LOG_FILE="/var/log/accessibility_settings.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

# Options de configuration
REDUCE_MOTION=${1:-true}
REDUCE_TRANSPARENCY=${2:-true}

# Fonction pour enregistrer les messages
log_message() {
    echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE"
}

# Fonction pour valider les entrées booléennes
validate_boolean() {
    local value=$1
    local setting_name=$2
    
    if [[ "$value" != "true" && "$value" != "false" ]]; then
        log_message "ERREUR: Valeur invalide pour $setting_name: $value (doit être true ou false)"
        return 1
    fi
    
    return 0
}

# Fonction pour obtenir les paramètres d'accessibilité actuels
get_current_settings() {
    local username=$1
    
    log_message "Obtention des paramètres d'accessibilité actuels pour l'utilisateur: $username"
    
    # Obtenir le paramètre de réduction du mouvement
    local motion_setting=$(su -l "$username" -c "defaults read com.apple.universalaccess reduceMotion 2>/dev/null")
    if [ -z "$motion_setting" ]; then
        motion_setting="Non défini"
    fi
    
    # Obtenir le paramètre de réduction de la transparence
    local transparency_setting=$(su -l "$username" -c "defaults read com.apple.universalaccess reduceTransparency 2>/dev/null")
    if [ -z "$transparency_setting" ]; then
        transparency_setting="Non défini"
    fi
    
    echo "Paramètres d'accessibilité actuels:"
    echo "  Réduction du mouvement: $motion_setting"
    echo "  Réduction de la transparence: $transparency_setting"
    
    log_message "Paramètres actuels - Mouvement: $motion_setting, Transparence: $transparency_setting"
}

# Fonction pour configurer la réduction du mouvement
configure_reduce_motion() {
    local username=$1
    local enable_motion=$2
    
    log_message "Configuration de la réduction du mouvement à: $enable_motion pour l'utilisateur: $username"
    
    if su -l "$username" -c "defaults write com.apple.universalaccess reduceMotion -bool $enable_motion"; then
        log_message "SUCCÈS: Réduction du mouvement définie à $enable_motion"
        return 0
    else
        log_message "ERREUR: Échec de la configuration de la réduction du mouvement"
        return 1
    fi
}

# Fonction pour configurer la réduction de la transparence
configure_reduce_transparency() {
    local username=$1
    local enable_transparency=$2
    
    log_message "Configuration de la réduction de la transparence à: $enable_transparency pour l'utilisateur: $username"
    
    if su -l "$username" -c "defaults write com.apple.universalaccess reduceTransparency -bool $enable_transparency"; then
        log_message "SUCCÈS: Réduction de la transparence définie à $enable_transparency"
        return 0
    else
        log_message "ERREUR: Échec de la configuration de la réduction de la transparence"
        return 1
    fi
}

# Fonction pour vérifier les paramètres
verify_settings() {
    local username=$1
    local expected_motion=$2
    local expected_transparency=$3
    
    log_message "Vérification des paramètres d'accessibilité pour l'utilisateur: $username"
    
    # Vérifier la réduction du mouvement
    local actual_motion=$(su -l "$username" -c "defaults read com.apple.universalaccess reduceMotion 2>/dev/null")
    if [ "$actual_motion" = "$expected_motion" ]; then
        log_message "VÉRIFIÉ: Réduction du mouvement correctement définie à $expected_motion"
    else
        log_message "AVERTISSEMENT: Vérification de la réduction du mouvement échouée. Attendu: $expected_motion, Actuel: $actual_motion"
    fi
    
    # Vérifier la réduction de la transparence
    local actual_transparency=$(su -l "$username" -c "defaults read com.apple.universalaccess reduceTransparency 2>/dev/null")
    if [ "$actual_transparency" = "$expected_transparency" ]; then
        log_message "VÉRIFIÉ: Réduction de la transparence correctement définie à $expected_transparency"
    else
        log_message "AVERTISSEMENT: Vérification de la réduction de la transparence échouée. Attendu: $expected_transparency, Actuel: $actual_transparency"
    fi
}

# Exécution principale
log_message "Début de la configuration d'accessibilité"

# Valider les entrées
if ! validate_boolean "$REDUCE_MOTION" "réduction du mouvement"; then
    exit 1
fi

if ! validate_boolean "$REDUCE_TRANSPARENCY" "réduction de la transparence"; then
    exit 1
fi

# Obtenir l'utilisateur actuel
loggedInUser=$(ls -l /dev/console | awk '{ print $3 }')

if [ -z "$loggedInUser" ] || [ "$loggedInUser" = "root" ]; then
    log_message "ERREUR: Aucune session utilisateur valide trouvée"
    exit 1
fi

log_message "Utilisateur actuel: $loggedInUser"

# Afficher les paramètres actuels
get_current_settings "$loggedInUser"

# Configurer la réduction du mouvement
if ! configure_reduce_motion "$loggedInUser" "$REDUCE_MOTION"; then
    log_message "Échec de la configuration de la réduction du mouvement"
    exit 1
fi

# Configurer la réduction de la transparence
if ! configure_reduce_transparency "$loggedInUser" "$REDUCE_TRANSPARENCY"; then
    log_message "Échec de la configuration de la réduction de la transparence"
    exit 1
fi

# Vérifier les paramètres
verify_settings "$loggedInUser" "$REDUCE_MOTION" "$REDUCE_TRANSPARENCY"

log_message "Configuration d'accessibilité terminée avec succès"
echo "Paramètres d'accessibilité configurés avec succès"
echo "Les paramètres seront appliqués immédiatement"

Gestion individuelle des paramètres

Réduction du mouvement uniquement

Script pour gérer uniquement le paramètre de réduction du mouvement :

#!/bin/bash

# Script de configuration de la réduction du mouvement
LOG_FILE="/var/log/accessibility_settings.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

# Configuration
ENABLE_REDUCE_MOTION=${1:-true}

# Fonction pour enregistrer les messages
log_message() {
    echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE"
}

# Fonction pour obtenir le statut de réduction du mouvement actuel
get_reduce_motion_status() {
    local username=$1
    
    local motion_setting=$(su -l "$username" -c "defaults read com.apple.universalaccess reduceMotion 2>/dev/null")
    
    if [ -z "$motion_setting" ]; then
        echo "Non configuré"
    else
        if [ "$motion_setting" = "1" ]; then
            echo "Activé"
        else
            echo "Désactivé"
        fi
    fi
}

# Fonction pour configurer la réduction du mouvement
set_reduce_motion() {
    local username=$1
    local enable=$2
    
    log_message "Définition de la réduction du mouvement à: $enable pour l'utilisateur: $username"
    
    # Obtenir le statut actuel
    local current_status=$(get_reduce_motion_status "$username")
    log_message "Statut actuel de la réduction du mouvement: $current_status"
    
    # Appliquer le paramètre
    if su -l "$username" -c "defaults write com.apple.universalaccess reduceMotion -bool $enable"; then
        log_message "SUCCÈS: Réduction du mouvement configurée"
        
        # Vérifier le paramètre
        local new_status=$(get_reduce_motion_status "$username")
        log_message "Nouveau statut de la réduction du mouvement: $new_status"
        
        return 0
    else
        log_message "ERREUR: Échec de la configuration de la réduction du mouvement"
        return 1
    fi
}

# Exécution principale
log_message "Début de la configuration de la réduction du mouvement"

# Valider l'entrée
if [[ "$ENABLE_REDUCE_MOTION" != "true" && "$ENABLE_REDUCE_MOTION" != "false" ]]; then
    log_message "ERREUR: Valeur invalide: $ENABLE_REDUCE_MOTION (doit être true ou false)"
    exit 1
fi

# Obtenir l'utilisateur actuel
loggedInUser=$(ls -l /dev/console | awk '{ print $3 }')

if [ -z "$loggedInUser" ] || [ "$loggedInUser" = "root" ]; then
    log_message "ERREUR: Aucune session utilisateur valide trouvée"
    exit 1
fi

log_message "Utilisateur actuel: $loggedInUser"

# Configurer la réduction du mouvement
if set_reduce_motion "$loggedInUser" "$ENABLE_REDUCE_MOTION"; then
    log_message "Configuration de la réduction du mouvement terminée avec succès"
    echo "✓ Réduction du mouvement configurée avec succès"
    
    # Afficher l'explication selon le paramètre
    if [ "$ENABLE_REDUCE_MOTION" = "true" ]; then
        echo ""
        echo "La réduction du mouvement est maintenant ACTIVÉE:"
        echo "  - Les animations d'interface sont simplifiées"
        echo "  - Les effets de fondu croisé remplacent les animations complexes"
        echo "  - Réduit le mal des transports potentiel"
        echo "  - Améliore les performances sur le matériel plus ancien"
    else
        echo ""
        echo "La réduction du mouvement est maintenant DÉSACTIVÉE:"
        echo "  - Les animations d'interface complètes sont restaurées"
        echo "  - Les effets visuels complexes sont activés"
        echo "  - Expérience visuelle macOS standard"
    fi
else
    log_message "Configuration de la réduction du mouvement échouée"
    exit 1
fi

Réduction de la transparence uniquement

Script pour gérer uniquement le paramètre de réduction de la transparence :

#!/bin/bash

# Script de configuration de la réduction de la transparence
LOG_FILE="/var/log/accessibility_settings.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

# Configuration
ENABLE_REDUCE_TRANSPARENCY=${1:-true}

# Fonction pour enregistrer les messages
log_message() {
    echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE"
}

# Fonction pour obtenir le statut de réduction de la transparence actuel
get_reduce_transparency_status() {
    local username=$1
    
    local transparency_setting=$(su -l "$username" -c "defaults read com.apple.universalaccess reduceTransparency 2>/dev/null")
    
    if [ -z "$transparency_setting" ]; then
        echo "Non configuré"
    else
        if [ "$transparency_setting" = "1" ]; then
            echo "Activé"
        else
            echo "Désactivé"
        fi
    fi
}

# Fonction pour configurer la réduction de la transparence
set_reduce_transparency() {
    local username=$1
    local enable=$2
    
    log_message "Définition de la réduction de la transparence à: $enable pour l'utilisateur: $username"
    
    # Obtenir le statut actuel
    local current_status=$(get_reduce_transparency_status "$username")
    log_message "Statut actuel de la réduction de la transparence: $current_status"
    
    # Appliquer le paramètre
    if su -l "$username" -c "defaults write com.apple.universalaccess reduceTransparency -bool $enable"; then
        log_message "SUCCÈS: Réduction de la transparence configurée"
        
        # Vérifier le paramètre
        local new_status=$(get_reduce_transparency_status "$username")
        log_message "Nouveau statut de la réduction de la transparence: $new_status"
        
        return 0
    else
        log_message "ERREUR: Échec de la configuration de la réduction de la transparence"
        return 1
    fi
}

# Exécution principale
log_message "Début de la configuration de la réduction de la transparence"

# Valider l'entrée
if [[ "$ENABLE_REDUCE_TRANSPARENCY" != "true" && "$ENABLE_REDUCE_TRANSPARENCY" != "false" ]]; then
    log_message "ERREUR: Valeur invalide: $ENABLE_REDUCE_TRANSPARENCY (doit être true ou false)"
    exit 1
fi

# Obtenir l'utilisateur actuel
loggedInUser=$(ls -l /dev/console | awk '{ print $3 }')

if [ -z "$loggedInUser" ] || [ "$loggedInUser" = "root" ]; then
    log_message "ERREUR: Aucune session utilisateur valide trouvée"
    exit 1
fi

log_message "Utilisateur actuel: $loggedInUser"

# Configurer la réduction de la transparence
if set_reduce_transparency "$loggedInUser" "$ENABLE_REDUCE_TRANSPARENCY"; then
    log_message "Configuration de la réduction de la transparence terminée avec succès"
    echo "✓ Réduction de la transparence configurée avec succès"
    
    # Afficher l'explication selon le paramètre
    if [ "$ENABLE_REDUCE_TRANSPARENCY" = "true" ]; then
        echo ""
        echo "La réduction de la transparence est maintenant ACTIVÉE:"
        echo "  - Les éléments semi-transparents deviennent solides"
        echo "  - Le dock, la barre de menu et les barres latérales sont opaques"
        echo "  - Améliore la lisibilité et le contraste"
        echo "  - Meilleures performances sur le matériel plus ancien"
    else
        echo ""
        echo "La réduction de la transparence est maintenant DÉSACTIVÉE:"
        echo "  - Les éléments semi-transparents sont restaurés"
        echo "  - Les effets de flou et de transparence sont activés"
        echo "  - Expérience visuelle macOS standard"
    fi
else
    log_message "Configuration de la réduction de la transparence échouée"
    exit 1
fi

Gestion complète de l'accessibilité

Script d'accessibilité tout-en-un

Script pour gérer plusieurs paramètres d'accessibilité :

#!/bin/bash

# Script de configuration complète d'accessibilité
LOG_FILE="/var/log/accessibility_settings.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

# Options de configuration
REDUCE_MOTION=${1:-true}
REDUCE_TRANSPARENCY=${2:-true}
INCREASE_CONTRAST=${3:-false}
DIFFERENTIATE_WITHOUT_COLOR=${4:-false}

# Fonction pour enregistrer les messages
log_message() {
    echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE"
}

# Fonction pour obtenir tous les paramètres d'accessibilité
get_all_accessibility_settings() {
    local username=$1
    
    log_message "Obtention de tous les paramètres d'accessibilité pour l'utilisateur: $username"
    
    # Obtenir divers paramètres d'accessibilité
    local motion=$(su -l "$username" -c "defaults read com.apple.universalaccess reduceMotion 2>/dev/null" || echo "Non défini")
    local transparency=$(su -l "$username" -c "defaults read com.apple.universalaccess reduceTransparency 2>/dev/null" || echo "Non défini")
    local contrast=$(su -l "$username" -c "defaults read com.apple.universalaccess increaseContrast 2>/dev/null" || echo "Non défini")
    local diff_color=$(su -l "$username" -c "defaults read com.apple.universalaccess differentiateWithoutColor 2>/dev/null" || echo "Non défini")
    
    echo "Paramètres d'accessibilité actuels:"
    echo "=================================="
    echo "  Réduction du mouvement: $motion"
    echo "  Réduction de la transparence: $transparency"
    echo "  Augmentation du contraste: $contrast"
    echo "  Différenciation sans couleur: $diff_color"
    echo ""
    
    log_message "Paramètres actuels - Mouvement: $motion, Transparence: $transparency, Contraste: $contrast, Couleur: $diff_color"
}

# Fonction pour configurer tous les paramètres d'accessibilité
configure_all_accessibility() {
    local username=$1
    local motion=$2
    local transparency=$3
    local contrast=$4
    local diff_color=$5
    
    log_message "Configuration de tous les paramètres d'accessibilité pour l'utilisateur: $username"
    
    local success=0
    
    # Configurer la réduction du mouvement
    if su -l "$username" -c "defaults write com.apple.universalaccess reduceMotion -bool $motion"; then
        log_message "SUCCÈS: Réduction du mouvement définie à $motion"
    else
        log_message "ERREUR: Échec de la définition de la réduction du mouvement"
        success=1
    fi
    
    # Configurer la réduction de la transparence
    if su -l "$username" -c "defaults write com.apple.universalaccess reduceTransparency -bool $transparency"; then
        log_message "SUCCÈS: Réduction de la transparence définie à $transparency"
    else
        log_message "ERREUR: Échec de la définition de la réduction de la transparence"
        success=1
    fi
    
    # Configurer l'augmentation du contraste
    if su -l "$username" -c "defaults write com.apple.universalaccess increaseContrast -bool $contrast"; then
        log_message "SUCCÈS: Augmentation du contraste définie à $contrast"
    else
        log_message "ERREUR: Échec de la définition de l'augmentation du contraste"
        success=1
    fi
    
    # Configurer la différenciation sans couleur
    if su -l "$username" -c "defaults write com.apple.universalaccess differentiateWithoutColor -bool $diff_color"; then
        log_message "SUCCÈS: Différenciation sans couleur définie à $diff_color"
    else
        log_message "ERREUR: Échec de la définition de la différenciation sans couleur"
        success=1
    fi
    
    return $success
}

# Fonction pour créer un rapport d'accessibilité
create_accessibility_report() {
    local username=$1
    local report_file="/tmp/accessibility_report_${username}.txt"
    
    log_message "Création du rapport d'accessibilité pour l'utilisateur: $username"
    
    {
        echo "Rapport de configuration d'accessibilité"
        echo "========================================"
        echo "Utilisateur: $username"
        echo "Date: $(date)"
        echo ""
        echo "Paramètres configurés:"
        echo "  Réduction du mouvement: $REDUCE_MOTION"
        echo "  Réduction de la transparence: $REDUCE_TRANSPARENCY"
        echo "  Augmentation du contraste: $INCREASE_CONTRAST"
        echo "  Différenciation sans couleur: $DIFFERENTIATE_WITHOUT_COLOR"
        echo ""
        echo "Impact sur l'expérience utilisateur:"
        echo "-----------------------------------"
        
        if [ "$REDUCE_MOTION" = "true" ]; then
            echo "• Effets de mouvement réduits - expérience plus fluide pour les utilisateurs sensibles au mouvement"
        fi
        
        if [ "$REDUCE_TRANSPARENCY" = "true" ]; then
            echo "• Éléments d'interface solides - lisibilité et performances améliorées"
        fi
        
        if [ "$INCREASE_CONTRAST" = "true" ]; then
            echo "• Contraste amélioré - meilleure visibilité pour les utilisateurs avec déficiences visuelles"
        fi
        
        if [ "$DIFFERENTIATE_WITHOUT_COLOR" = "true" ]; then
            echo "• Différenciation indépendante de la couleur - accessibilité pour les utilisateurs daltoniens"
        fi
        
        echo ""
        echo "Performances système:"
        echo "• Utilisation GPU réduite grâce aux effets désactivés"
        echo "• Autonomie améliorée sur les ordinateurs portables"
        echo "• Meilleures performances sur le matériel plus ancien"
        
    } > "$report_file"
    
    echo "Rapport d'accessibilité créé: $report_file"
    log_message "Rapport d'accessibilité créé: $report_file"
}

# Exécution principale
log_message "Début de la configuration complète d'accessibilité"

# Valider les entrées
for setting in "$REDUCE_MOTION" "$REDUCE_TRANSPARENCY" "$INCREASE_CONTRAST" "$DIFFERENTIATE_WITHOUT_COLOR"; do
    if [[ "$setting" != "true" && "$setting" != "false" ]]; then
        log_message "ERREUR: Valeur de paramètre invalide: $setting (doit être true ou false)"
        exit 1
    fi
done

# Obtenir l'utilisateur actuel
loggedInUser=$(ls -l /dev/console | awk '{ print $3 }')

if [ -z "$loggedInUser" ] || [ "$loggedInUser" = "root" ]; then
    log_message "ERREUR: Aucune session utilisateur valide trouvée"
    exit 1
fi

log_message "Utilisateur actuel: $loggedInUser"

# Afficher les paramètres actuels
get_all_accessibility_settings "$loggedInUser"

# Configurer tous les paramètres d'accessibilité
if configure_all_accessibility "$loggedInUser" "$REDUCE_MOTION" "$REDUCE_TRANSPARENCY" "$INCREASE_CONTRAST" "$DIFFERENTIATE_WITHOUT_COLOR"; then
    log_message "Tous les paramètres d'accessibilité configurés avec succès"
    echo "✓ Tous les paramètres d'accessibilité configurés avec succès"
    
    # Créer le rapport
    create_accessibility_report "$loggedInUser"
    
    # Afficher les nouveaux paramètres
    echo ""
    echo "Paramètres mis à jour:"
    get_all_accessibility_settings "$loggedInUser"
    
else
    log_message "Certains paramètres d'accessibilité ont échoué à la configuration"
    echo "⚠ Certains paramètres d'accessibilité peuvent ne pas avoir été configurés correctement"
    exit 1
fi

log_message "Configuration complète d'accessibilité terminée"

Scripts de déploiement d'entreprise

Configuration multi-utilisateur

Script pour configurer les paramètres d'accessibilité sur plusieurs utilisateurs :

#!/bin/bash

# Script de configuration d'accessibilité multi-utilisateur
LOG_FILE="/var/log/accessibility_deployment.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

# Configuration
REDUCE_MOTION=${1:-true}
REDUCE_TRANSPARENCY=${2:-true}
TARGET_USERS=${3:-"all"}  # "all" ou liste d'utilisateurs séparés par des virgules

# Fonction pour enregistrer les messages
log_message() {
    echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE"
}

# Fonction pour obtenir tous les utilisateurs réguliers
get_all_users() {
    # Obtenir les utilisateurs avec UID >= 500 (utilisateurs réguliers)
    local users=$(dscl . -list /Users UniqueID | awk '$2 >= 500 && $2 < 65534 { print $1 }')
    echo "$users"
}

# Fonction pour analyser les utilisateurs cibles
parse_target_users() {
    local target=$1
    
    if [ "$target" = "all" ]; then
        get_all_users
    else
        echo "$target" | tr ',' '\n'
    fi
}

# Fonction pour configurer l'accessibilité d'un utilisateur
configure_user_accessibility() {
    local username=$1
    local motion=$2
    local transparency=$3
    
    log_message "Configuration de l'accessibilité pour l'utilisateur: $username"
    
    # Vérifier si l'utilisateur existe
    if ! id "$username" &>/dev/null; then
        log_message "AVERTISSEMENT: L'utilisateur $username n'existe pas"
        return 1
    fi
    
    # Vérifier si l'utilisateur a un répertoire home
    local home_dir=$(eval echo ~$username)
    if [ ! -d "$home_dir" ]; then
        log_message "AVERTISSEMENT: Répertoire home non trouvé pour l'utilisateur: $username"
        return 1
    fi
    
    # Configurer les paramètres
    local success=0
    
    if su -l "$username" -c "defaults write com.apple.universalaccess reduceMotion -bool $motion"; then
        log_message "SUCCÈS: Réduction du mouvement configurée pour $username"
    else
        log_message "ERREUR: Échec de la configuration de la réduction du mouvement pour $username"
        success=1
    fi
    
    if su -l "$username" -c "defaults write com.apple.universalaccess reduceTransparency -bool $transparency"; then
        log_message "SUCCÈS: Réduction de la transparence configurée pour $username"
    else
        log_message "ERREUR: Échec de la configuration de la réduction de la transparence pour $username"
        success=1
    fi
    
    if [ $success -eq 0 ]; then
        log_message "SUCCÈS: Tous les paramètres d'accessibilité configurés pour $username"
        return 0
    else
        log_message "ERREUR: Certains paramètres ont échoué pour $username"
        return 1
    fi
}

# Exécution principale
log_message "Début du déploiement d'accessibilité multi-utilisateur"

# Analyser les utilisateurs cibles
target_users=$(parse_target_users "$TARGET_USERS")

if [ -z "$target_users" ]; then
    log_message "ERREUR: Aucun utilisateur cible spécifié"
    exit 1
fi

log_message "Utilisateurs cibles: $target_users"

# Configurer chaque utilisateur
successful=0
failed=0

for user in $target_users; do
    echo "Configuration de l'accessibilité pour l'utilisateur: $user"
    
    if configure_user_accessibility "$user" "$REDUCE_MOTION" "$REDUCE_TRANSPARENCY"; then
        echo "  ✓ Succès"
        ((successful++))
    else
        echo "  ✗ Échec"
        ((failed++))
    fi
done

log_message "Déploiement multi-utilisateur terminé"
log_message "Configurés avec succès: $successful utilisateurs"
log_message "Échecs: $failed utilisateurs"

echo ""
echo "Résumé du déploiement:"
echo "  Configurés avec succès: $successful utilisateurs"
echo "  Échecs: $failed utilisateurs"
echo "  Fichier journal: $LOG_FILE"

if [ $failed -gt 0 ]; then
    exit 1
fi

Meilleures pratiques et recommandations

1. Considérations de performance

  • Surveiller les performances système avant et après les changements
  • Considérer l'impact sur le matériel plus ancien
  • Tester les paramètres sur différents modèles de Mac
  • Documenter les améliorations de performance

2. Expérience utilisateur

  • Communiquer les changements aux utilisateurs à l'avance
  • Fournir une formation sur le nouveau comportement d'interface
  • Offrir des options de désactivation le cas échéant
  • Recueillir les commentaires des utilisateurs sur les améliorations d'accessibilité

3. Gestion d'entreprise

  • Standardiser les politiques d'accessibilité sur les appareils
  • Utiliser des outils de gestion de configuration pour le déploiement
  • Implémenter la surveillance de la conformité des paramètres
  • Maintenir la documentation de toutes les personnalisations

4. Conformité à l'accessibilité

  • S'assurer que les paramètres répondent aux exigences d'accessibilité
  • Considérer différents types de handicaps
  • Tester avec les technologies d'assistance
  • Suivre les directives WCAG le cas échéant

Conclusion

La gestion efficace des paramètres de mouvement et de transparence est cruciale pour créer des environnements Mac accessibles et performants. Les scripts et techniques fournis dans ce guide offrent des solutions complètes pour divers scénarios de configuration d'accessibilité.

Points clés à retenir :

  • Comprendre l'impact des paramètres d'accessibilité sur l'expérience utilisateur
  • Utiliser des scripts appropriés pour différents scénarios de déploiement
  • Implémenter des procédures de test et de validation appropriées
  • Surveiller les performances système et les commentaires des utilisateurs
  • Considérer les besoins d'accessibilité de toute votre base d'utilisateurs

N'oubliez pas que les paramètres d'accessibilité impactent significativement l'expérience utilisateur, donc testez toujours les changements soigneusement et considérez offrir aux utilisateurs des options pour personnaliser leur expérience selon leurs besoins individuels.

Gestion d'Entreprise des Proxies sur macOS

Configurez et gérez les paramètres de proxy d'entreprise sur vos appareils Roundfleet en utilisant des commandes networksetup avancées. Ce tutoriel couvre tous les types de proxy incluant web, web sécurisé, streaming, Gopher et SOCKS firewall avec des capacités de gestion de niveau entreprise.

Comprendre la Gestion des Proxies macOS

macOS fournit une configuration de proxy complète via l'utilitaire en ligne de commande networksetup, supportant :

  • Proxy Web (HTTP) - Routage du trafic HTTP standard
  • Proxy Web Sécurisé (HTTPS) - Trafic HTTPS chiffré avec sécurité de bout en bout
  • Proxy Streaming - Optimisation du contenu multimédia (déprécié dans macOS 13.0+)
  • Proxy Gopher - Support du protocole Gopher hérité (déprécié dans macOS 13.0+)
  • Proxy Firewall SOCKS - Protocole générique supportant la plupart des applications

Configuration du Proxy Web

Configuration de Base du Proxy Web

#!/bin/bash

# Configurer le proxy web HTTP
NETWORK_SERVICE="Wi-Fi"
PROXY_SERVER="proxy.entreprise.com"
PROXY_PORT="8080"
AUTHENTICATED="on"
USERNAME="utilisateurproxy"
PASSWORD="motdepasseproxy"

# Définir la configuration du proxy web
networksetup -setwebproxy "$NETWORK_SERVICE" "$PROXY_SERVER" "$PROXY_PORT" "$AUTHENTICATED" "$USERNAME" "$PASSWORD"

# Activer le proxy web
networksetup -setwebproxystate "$NETWORK_SERVICE" on

echo "Proxy web configuré avec succès pour $NETWORK_SERVICE"

Gestion Avancée du Proxy Web

#!/bin/bash

# Système de Configuration de Proxy Web d'Entreprise
NETWORK_SERVICE="Wi-Fi"
CONFIG_FILE="/etc/roundfleet/proxy_config.conf"
LOG_FILE="/var/log/roundfleet_proxy.log"

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Charger la configuration proxy depuis un fichier
load_proxy_config() {
    if [[ -f "$CONFIG_FILE" ]]; then
        source "$CONFIG_FILE"
        log_action "Configuration proxy chargée depuis $CONFIG_FILE"
    else
        echo "Fichier de configuration non trouvé : $CONFIG_FILE"
        exit 1
    fi
}

# Configurer le proxy web avec validation
configure_web_proxy() {
    local server="$1"
    local port="$2"
    local auth="$3"
    local username="$4"
    local password="$5"
    
    # Valider l'existence du service réseau
    if ! networksetup -listallnetworkservices | grep -q "^$NETWORK_SERVICE$"; then
        log_action "ERREUR : Service réseau '$NETWORK_SERVICE' non trouvé"
        return 1
    fi
    
    # Tester la connectivité proxy
    if ! nc -z "$server" "$port" 2>/dev/null; then
        log_action "ATTENTION : Impossible d'atteindre le serveur proxy $server:$port"
    fi
    
    # Configurer le proxy
    if networksetup -setwebproxy "$NETWORK_SERVICE" "$server" "$port" "$auth" "$username" "$password"; then
        networksetup -setwebproxystate "$NETWORK_SERVICE" on
        log_action "Proxy web configuré : $server:$port (Auth : $auth)"
        return 0
    else
        log_action "ERREUR : Échec de la configuration du proxy web"
        return 1
    fi
}

# Vérifier la configuration proxy
verify_proxy_config() {
    local proxy_info
    proxy_info=$(networksetup -getwebproxy "$NETWORK_SERVICE")
    
    echo "Configuration Actuelle du Proxy Web :"
    echo "$proxy_info"
    
    if echo "$proxy_info" | grep -q "Enabled: Yes"; then
        log_action "Vérification du proxy web réussie"
        return 0
    else
        log_action "Vérification du proxy web échouée"
        return 1
    fi
}

# Exécution principale
main() {
    log_action "Démarrage de la configuration du proxy web"
    
    # Exemple de configuration (remplacer par les vraies valeurs)
    configure_web_proxy "proxy.entreprise.com" "8080" "on" "utilisateurproxy" "motdepasseproxy"
    
    # Vérifier la configuration
    verify_proxy_config
    
    log_action "Configuration du proxy web terminée"
}

# Exécuter si le script est lancé directement
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi

Proxy Web Sécurisé (HTTPS)

Configuration de Base du Proxy HTTPS

#!/bin/bash

# Configurer le proxy web sécurisé HTTPS
networksetup -setsecurewebproxy "Wi-Fi" "proxy-securise.entreprise.com" "8443" on "utilisateursecurise" "motdepassesecurise"
networksetup -setsecurewebproxystate "Wi-Fi" on

echo "Proxy web sécurisé configuré avec succès"

Gestion d'Entreprise du Proxy HTTPS

#!/bin/bash

# Configuration du Proxy Web Sécurisé d'Entreprise
configure_secure_proxy() {
    local network_service="$1"
    local proxy_server="$2"
    local proxy_port="$3"
    local username="$4"
    local password="$5"
    
    echo "Configuration du proxy web sécurisé pour $network_service..."
    
    # Valider la connectivité SSL/TLS
    if openssl s_client -connect "$proxy_server:$proxy_port" -verify_return_error < /dev/null 2>/dev/null; then
        echo "✅ Connectivité SSL vérifiée pour $proxy_server:$proxy_port"
    else
        echo "⚠️  ATTENTION : Problèmes de connectivité SSL détectés"
    fi
    
    # Configurer le proxy sécurisé
    if networksetup -setsecurewebproxy "$network_service" "$proxy_server" "$proxy_port" on "$username" "$password"; then
        networksetup -setsecurewebproxystate "$network_service" on
        echo "✅ Proxy web sécurisé configuré avec succès"
        
        # Vérifier la configuration
        echo "Détails de configuration :"
        networksetup -getsecurewebproxy "$network_service"
        
        return 0
    else
        echo "❌ Échec de la configuration du proxy web sécurisé"
        return 1
    fi
}

# Validation des certificats pour les proxies sécurisés
validate_proxy_certificate() {
    local proxy_server="$1"
    local proxy_port="$2"
    
    echo "Validation du certificat proxy..."
    
    local cert_info
    cert_info=$(openssl s_client -connect "$proxy_server:$proxy_port" -servername "$proxy_server" < /dev/null 2>/dev/null | openssl x509 -text -noout)
    
    if [[ -n "$cert_info" ]]; then
        echo "Validation du certificat réussie"
        echo "Sujet du certificat : $(echo "$cert_info" | grep "Subject:" | head -1)"
        echo "Émetteur du certificat : $(echo "$cert_info" | grep "Issuer:" | head -1)"
        return 0
    else
        echo "Validation du certificat échouée"
        return 1
    fi
}

# Exemple d'utilisation
configure_secure_proxy "Wi-Fi" "proxy-securise.entreprise.com" "8443" "utilisateursecurise" "motdepassesecurise"
validate_proxy_certificate "proxy-securise.entreprise.com" "8443"

Proxy Firewall SOCKS

Configuration de Base du Proxy SOCKS

#!/bin/bash

# Configurer le proxy firewall SOCKS
networksetup -setsocksfirewallproxy "Wi-Fi" "proxy-socks.entreprise.com" "1080" on "utilisateursocks" "motdepassesocks"
networksetup -setsocksfirewallproxystate "Wi-Fi" on

echo "Proxy firewall SOCKS configuré avec succès"

Gestion Avancée du Proxy SOCKS

#!/bin/bash

# Système de Configuration de Proxy SOCKS d'Entreprise
setup_socks_proxy() {
    local network_service="$1"
    local socks_server="$2"
    local socks_port="$3"
    local auth_required="$4"
    local username="$5"
    local password="$6"
    
    echo "Configuration du proxy SOCKS : $socks_server:$socks_port"
    
    # Tester la connectivité SOCKS
    if command -v nc >/dev/null 2>&1; then
        if nc -z "$socks_server" "$socks_port" 2>/dev/null; then
            echo "✅ Connectivité proxy SOCKS vérifiée"
        else
            echo "⚠️  ATTENTION : Impossible d'atteindre le proxy SOCKS"
        fi
    fi
    
    # Configurer le proxy SOCKS
    if networksetup -setsocksfirewallproxy "$network_service" "$socks_server" "$socks_port" "$auth_required" "$username" "$password"; then
        networksetup -setsocksfirewallproxystate "$network_service" on
        echo "✅ Proxy firewall SOCKS configuré"
        
        # Vérifier la configuration
        echo "Détails du proxy SOCKS :"
        networksetup -getsocksfirewallproxy "$network_service"
        
        return 0
    else
        echo "❌ Échec de la configuration du proxy SOCKS"
        return 1
    fi
}

# Tester la fonctionnalité du proxy SOCKS
test_socks_proxy() {
    local test_url="http://httpbin.org/ip"
    
    echo "Test de la fonctionnalité du proxy SOCKS..."
    
    # Test avec curl via le proxy SOCKS
    if command -v curl >/dev/null 2>&1; then
        local proxy_response
        proxy_response=$(curl -s --socks5 "proxy-socks.entreprise.com:1080" "$test_url" 2>/dev/null)
        
        if [[ -n "$proxy_response" ]]; then
            echo "✅ Test du proxy SOCKS réussi"
            echo "Réponse : $proxy_response"
        else
            echo "❌ Test du proxy SOCKS échoué"
        fi
    else
        echo "curl non disponible pour les tests"
    fi
}

# Utilisation
setup_socks_proxy "Wi-Fi" "proxy-socks.entreprise.com" "1080" "on" "utilisateursocks" "motdepassesocks"
test_socks_proxy

Support des Proxies Hérités (macOS < 13.0)

Configuration du Proxy Streaming

#!/bin/bash

# Configurer le proxy streaming (déprécié dans macOS 13.0+)
check_macos_version() {
    local version
    version=$(sw_vers -productVersion)
    local major_version
    major_version=$(echo "$version" | cut -d. -f1)
    
    if [[ "$major_version" -ge 13 ]]; then
        echo "⚠️  Proxy streaming non supporté sur macOS 13.0+"
        return 1
    fi
    return 0
}

configure_streaming_proxy() {
    if check_macos_version; then
        networksetup -setstreamingproxy "Wi-Fi" "proxy-stream.entreprise.com" "8080" on "utilisateurstream" "motdepassestream"
        networksetup -setstreamingproxystate "Wi-Fi" on
        echo "✅ Proxy streaming configuré"
    else
        echo "❌ Proxy streaming non disponible sur cette version de macOS"
    fi
}

configure_gopher_proxy() {
    if check_macos_version; then
        networksetup -setgopherproxy "Wi-Fi" "proxy-gopher.entreprise.com" "70" on "utilisateurgopher" "motdepassegopher"
        networksetup -setgopherproxystate "Wi-Fi" on
        echo "✅ Proxy Gopher configuré"
    else
        echo "❌ Proxy Gopher non disponible sur cette version de macOS"
    fi
}

# Exécuter la configuration des proxies hérités
configure_streaming_proxy
configure_gopher_proxy

Système de Gestion de Proxy d'Entreprise

#!/bin/bash

# Système de Gestion de Proxy d'Entreprise Roundfleet
# Configuration et surveillance complètes des proxies

# Configuration
PROXY_CONFIG_DIR="/etc/roundfleet/proxy"
LOG_FILE="/var/log/roundfleet_proxy.log"
BACKUP_DIR="/var/backups/roundfleet/proxy"
API_ENDPOINT="https://api.roundfleet.com/v1/proxy"

# Créer la structure des répertoires
setup_directories() {
    mkdir -p "$PROXY_CONFIG_DIR" "$BACKUP_DIR"
    touch "$LOG_FILE"
}

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Obtenir tous les services réseau
get_network_services() {
    networksetup -listallnetworkservices | grep -v "^An asterisk"
}

# Sauvegarder les paramètres proxy actuels
backup_proxy_settings() {
    local backup_file="$BACKUP_DIR/proxy_backup_$(date +%Y%m%d_%H%M%S).json"
    
    echo "{" > "$backup_file"
    echo "  \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"," >> "$backup_file"
    echo "  \"hostname\": \"$(hostname)\"," >> "$backup_file"
    echo "  \"network_services\": {" >> "$backup_file"
    
    local first=true
    while IFS= read -r service; do
        if [[ "$first" == "false" ]]; then
            echo "," >> "$backup_file"
        fi
        first=false
        
        echo "    \"$service\": {" >> "$backup_file"
        echo "      \"web_proxy\": $(networksetup -getwebproxy "$service" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))")" >> "$backup_file"
        echo "      \"secure_web_proxy\": $(networksetup -getsecurewebproxy "$service" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))")" >> "$backup_file"
        echo "      \"socks_proxy\": $(networksetup -getsocksfirewallproxy "$service" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))")" >> "$backup_file"
        echo "    }" >> "$backup_file"
    done < <(get_network_services)
    
    echo "  }" >> "$backup_file"
    echo "}" >> "$backup_file"
    
    log_action "Paramètres proxy sauvegardés dans : $backup_file"
}

# Configurer le proxy depuis une configuration JSON
configure_from_json() {
    local config_file="$1"
    
    if [[ ! -f "$config_file" ]]; then
        log_action "ERREUR : Fichier de configuration non trouvé : $config_file"
        return 1
    fi
    
    log_action "Application de la configuration proxy depuis : $config_file"
    
    # Analyser JSON et appliquer les paramètres avec jq ou python
    if command -v jq >/dev/null 2>&1; then
        # Utiliser jq pour l'analyse JSON
        local networks
        networks=$(jq -r '.networks | keys[]' "$config_file")
        
        while IFS= read -r network; do
            local web_proxy
            web_proxy=$(jq -r ".networks[\"$network\"].web_proxy" "$config_file")
            
            if [[ "$web_proxy" != "null" ]]; then
                local server port auth username password
                server=$(echo "$web_proxy" | jq -r '.server')
                port=$(echo "$web_proxy" | jq -r '.port')
                auth=$(echo "$web_proxy" | jq -r '.authentication')
                username=$(echo "$web_proxy" | jq -r '.username')
                password=$(echo "$web_proxy" | jq -r '.password')
                
                networksetup -setwebproxy "$network" "$server" "$port" "$auth" "$username" "$password"
                networksetup -setwebproxystate "$network" on
                
                log_action "Proxy web configuré pour $network : $server:$port"
            fi
        done <<< "$networks"
    else
        log_action "ERREUR : jq non disponible pour l'analyse JSON"
        return 1
    fi
}

# Surveiller la connectivité proxy
monitor_proxy_connectivity() {
    log_action "Démarrage de la surveillance de connectivité proxy"
    
    while IFS= read -r service; do
        local web_proxy_info
        web_proxy_info=$(networksetup -getwebproxy "$service")
        
        if echo "$web_proxy_info" | grep -q "Enabled: Yes"; then
            local server port
            server=$(echo "$web_proxy_info" | grep "Server:" | awk '{print $2}')
            port=$(echo "$web_proxy_info" | grep "Port:" | awk '{print $2}')
            
            if nc -z "$server" "$port" 2>/dev/null; then
                log_action "✅ Connectivité proxy OK : $service ($server:$port)"
            else
                log_action "❌ Connectivité proxy ÉCHOUÉE : $service ($server:$port)"
            fi
        fi
    done < <(get_network_services)
}

# Effacer tous les paramètres proxy
clear_all_proxies() {
    log_action "Effacement de tous les paramètres proxy"
    
    while IFS= read -r service; do
        # Désactiver tous les types de proxy
        networksetup -setwebproxystate "$service" off
        networksetup -setsecurewebproxystate "$service" off
        networksetup -setsocksfirewallproxystate "$service" off
        
        # Pour les versions plus anciennes de macOS
        networksetup -setstreamingproxystate "$service" off 2>/dev/null || true
        networksetup -setgopherproxystate "$service" off 2>/dev/null || true
        
        log_action "Proxies effacés pour : $service"
    done < <(get_network_services)
}

# Générer un rapport de statut proxy
generate_proxy_report() {
    local report_file="$PROXY_CONFIG_DIR/proxy_report_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport de Statut Proxy Roundfleet"
        echo "Généré : $(date)"
        echo "Nom d'hôte : $(hostname)"
        echo "=================================="
        echo ""
        
        while IFS= read -r service; do
            echo "Service Réseau : $service"
            echo "--------------------------------"
            
            echo "Proxy Web :"
            networksetup -getwebproxy "$service" | sed 's/^/  /'
            echo ""
            
            echo "Proxy Web Sécurisé :"
            networksetup -getsecurewebproxy "$service" | sed 's/^/  /'
            echo ""
            
            echo "Proxy Firewall SOCKS :"
            networksetup -getsocksfirewallproxy "$service" | sed 's/^/  /'
            echo ""
            
            echo "=================================="
            echo ""
        done < <(get_network_services)
    } > "$report_file"
    
    echo "Rapport proxy généré : $report_file"
    log_action "Rapport de statut proxy généré : $report_file"
}

# Fonction principale
main() {
    local action="${1:-status}"
    
    setup_directories
    log_action "Gestion Proxy Roundfleet démarrée avec l'action : $action"
    
    case "$action" in
        "backup")
            backup_proxy_settings
            ;;
        "configure")
            configure_from_json "$2"
            ;;
        "monitor")
            monitor_proxy_connectivity
            ;;
        "clear")
            backup_proxy_settings
            clear_all_proxies
            ;;
        "report")
            generate_proxy_report
            ;;
        "status"|*)
            generate_proxy_report
            monitor_proxy_connectivity
            ;;
    esac
    
    log_action "Gestion Proxy Roundfleet terminée"
}

# Exécuter la fonction principale avec tous les arguments
main "$@"

Modèles de Configuration Proxy

Modèle de Proxy Web d'Entreprise

# /etc/roundfleet/proxy/proxy_web_entreprise.conf
PROXY_TYPE="web"
NETWORK_SERVICE="Wi-Fi"
PROXY_SERVER="proxy.entreprise.com"
PROXY_PORT="8080"
AUTHENTICATION="on"
USERNAME="nom_utilisateur_employe"
PASSWORD="motdepasse_employe"
AUTO_CONFIG_URL=""
BYPASS_LIST="*.entreprise.com,localhost,127.0.0.1"

Modèle d'Entreprise Sécurisé

# /etc/roundfleet/proxy/entreprise_securise.conf
PROXY_TYPE="secure_web"
NETWORK_SERVICE="Wi-Fi"
PROXY_SERVER="proxy-securise.entreprise.com"
PROXY_PORT="8443"
AUTHENTICATION="on"
USERNAME="utilisateur_securise"
PASSWORD="motdepasse_securise"
SSL_VERIFICATION="enabled"
CERTIFICATE_PINNING="enabled"

Modèle de Proxy SOCKS

# /etc/roundfleet/proxy/proxy_socks.conf
PROXY_TYPE="socks"
NETWORK_SERVICE="Wi-Fi"
PROXY_SERVER="socks.entreprise.com"
PROXY_PORT="1080"
AUTHENTICATION="on"
USERNAME="utilisateur_socks"
PASSWORD="motdepasse_socks"
SOCKS_VERSION="5"

Considérations de Sécurité

Sécurité d'Authentification Proxy

#!/bin/bash

# Gestion sécurisée des identifiants proxy
encrypt_credentials() {
    local username="$1"
    local password="$2"
    local keychain="Roundfleet-Proxy"
    
    # Stocker les identifiants dans le trousseau
    security add-generic-password -a "$username" -s "proxy-credentials" -w "$password" -T "" "$keychain" 2>/dev/null
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Identifiants stockés de façon sécurisée dans le trousseau"
    else
        echo "❌ Échec du stockage des identifiants dans le trousseau"
    fi
}

# Récupérer les identifiants depuis le trousseau
decrypt_credentials() {
    local username="$1"
    local keychain="Roundfleet-Proxy"
    
    local password
    password=$(security find-generic-password -a "$username" -s "proxy-credentials" -w "$keychain" 2>/dev/null)
    
    if [[ -n "$password" ]]; then
        echo "$password"
    else
        echo "ERREUR : Impossible de récupérer le mot de passe pour $username"
        return 1
    fi
}

Notes de Configuration Importantes

Noms des Services Réseau

  • Les noms de service sont sensibles à la casse
  • Utilisez des guillemets pour les noms avec espaces : "Wi-Fi"
  • Services communs : "Wi-Fi", "Ethernet", "USB 10/100/1000 LAN"

Authentification Proxy

  • Définir authenticated à "on" pour activer l'authentification
  • Définir authenticated à "off" pour désactiver l'authentification
  • Les identifiants seront demandés si l'authentification est activée mais non fournie

Compatibilité des Versions macOS

  • Proxy Streaming : Déprécié dans macOS 13.0+
  • Proxy Gopher : Déprécié dans macOS 13.0+
  • Web/Web Sécurisé/SOCKS : Disponible sur toutes les versions macOS supportées

Gestion des Erreurs

  • Les configurations proxy existantes montreront des erreurs lors de la reconfiguration
  • Utiliser networksetup -setproxystate pour désactiver avant de reconfigurer
  • Tester la connectivité avant d'appliquer aux appareils de la flotte

Meilleures Pratiques

  1. Toujours sauvegarder les paramètres actuels avant les changements
  2. Tester la connectivité après la configuration proxy
  3. Utiliser un stockage sécurisé pour les identifiants proxy
  4. Surveiller la santé des proxies en continu
  5. Valider les certificats pour les proxies HTTPS
  6. Documenter les configurations pour la conformité
  7. Implémenter la journalisation pour les pistes d'audit
  8. Tester sur des appareils individuels avant le déploiement de flotte

N'oubliez pas de valider tous les scripts sur des appareils de test avant de les déployer sur votre environnement Roundfleet, et assurez-vous que les serveurs proxy sont accessibles et correctement configurés pour votre infrastructure réseau.

Gestion d'Imprimantes d'Entreprise sur macOS

Gérez l'infrastructure d'impression de vos appareils Roundfleet en utilisant le déploiement avancé d'imprimantes, la gestion de configuration et les contrôles de sécurité d'entreprise. Ce tutoriel fournit des outils complets pour implémenter les politiques d'impression organisationnelles et la gestion automatisée d'imprimantes.

Comprendre la Gestion d'Imprimantes macOS

macOS fournit plusieurs outils pour la gestion d'imprimantes :

  • lpadmin - Administration d'imprimantes en ligne de commande
  • lpstat - Informations sur le statut et les files d'attente d'impression
  • lpoptions - Configuration et options d'imprimantes
  • cups - Système d'Impression Unix Commun
  • Préférences Système - Interface graphique de gestion d'imprimantes

Opérations d'Imprimantes de Base

Déployer une Imprimante Unique

#!/bin/bash

# Déployer une imprimante réseau
PRINTER_NAME="Office_HP_LaserJet"
PRINTER_DESCRIPTION="HP LaserJet Pro au Bureau Principal"
DEVICE_URI="ipp://192.168.1.100/ipp/print"

lpadmin -p "$PRINTER_NAME" -E -D "$PRINTER_DESCRIPTION" -v "$DEVICE_URI" -m everywhere

echo "Imprimante $PRINTER_NAME déployée avec succès"

Supprimer une Imprimante

#!/bin/bash

# Supprimer une imprimante
PRINTER_NAME="Office_HP_LaserJet"

lpadmin -x "$PRINTER_NAME"

echo "Imprimante $PRINTER_NAME supprimée avec succès"

Vérifier le Statut des Imprimantes

#!/bin/bash

# Vérifier tous les statuts d'imprimantes
echo "=== Statut des Imprimantes ==="
lpstat -p

echo -e "\n=== Files d'Attente d'Impression ==="
lpstat -o

Système de Gestion d'Imprimantes d'Entreprise

#!/bin/bash

# Système de Gestion d'Imprimantes d'Entreprise Roundfleet
# Déploiement, configuration et gestion de sécurité complets d'imprimantes

# Configuration
ROUNDFLEET_DIR="/etc/roundfleet"
PRINTER_DIR="$ROUNDFLEET_DIR/printer_management"
REPORTS_DIR="$ROUNDFLEET_DIR/reports"
COMPLIANCE_DIR="$ROUNDFLEET_DIR/compliance"
AUDIT_DIR="$ROUNDFLEET_DIR/audit"
LOG_FILE="/var/log/roundfleet_printer_management.log"
POLICIES_DIR="$ROUNDFLEET_DIR/printer_policies"

# Créer la structure de répertoires
create_directories() {
    local dirs=("$ROUNDFLEET_DIR" "$PRINTER_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR" "$AUDIT_DIR" "$POLICIES_DIR")
    for dir in "${dirs[@]}"; do
        [[ ! -d "$dir" ]] && mkdir -p "$dir"
    done
}

# Fonction de journalisation
log_action() {
    local message="$1"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $message" | tee -a "$LOG_FILE"
}

# Catégories d'Imprimantes pour la Gestion d'Entreprise
declare -A PRINTER_CATEGORIES=(
    ["executive_printers"]="color_laser,high_capacity,secure_printing,duplex"
    ["departmental_printers"]="color_laser,medium_capacity,duplex,scan_to_email"
    ["workgroup_printers"]="monochrome_laser,standard_capacity,duplex"
    ["specialty_printers"]="wide_format,photo_printer,label_printer"
    ["mobile_printers"]="portable,bluetooth,battery_powered"
    ["secure_printers"]="badge_release,encrypted_queue,audit_trail"
)

# Politiques de Sécurité d'Imprimantes
declare -A SECURITY_POLICIES=(
    ["high_security"]="authentication_required,encryption_enabled,audit_logging,secure_queue"
    ["standard_security"]="authentication_optional,basic_logging,standard_queue"
    ["open_access"]="no_authentication,minimal_logging,open_queue"
    ["finance_department"]="authentication_required,encryption_enabled,watermark,audit_trail"
    ["hr_department"]="authentication_required,confidential_printing,audit_trail"
)

# Profils de Déploiement d'Imprimantes
declare -A DEPLOYMENT_PROFILES=(
    ["office_standard"]="HP_LaserJet_Pro,Canon_ImageRunner,Epson_WorkForce"
    ["creative_department"]="Canon_ColorMax,Epson_SureColor,HP_DesignJet"
    ["accounting_secure"]="HP_SecurePrint,Canon_SecureMode,Lexmark_Confidential"
    ["mobile_workforce"]="HP_OfficeJet_Mobile,Canon_SELPHY,Brother_PocketJet"
    ["warehouse_industrial"]="Zebra_Industrial,Honeywell_PC43t,TSC_Industrial"
)

# Déployer une imprimante avec configuration avancée
deploy_printer() {
    local printer_name="$1"
    local printer_ip="$2"
    local printer_type="$3"
    local security_policy="$4"
    local department="$5"
    
    log_action "Déploiement d'imprimante : $printer_name (Type : $printer_type, Politique : $security_policy)"
    
    # Générer la configuration d'imprimante
    local device_uri=""
    local printer_driver=""
    local additional_options=""
    
    case "$printer_type" in
        "network_ipp")
            device_uri="ipp://$printer_ip/ipp/print"
            printer_driver="everywhere"
            ;;
        "network_lpd")
            device_uri="lpd://$printer_ip/queue"
            printer_driver="everywhere"
            ;;
        "usb")
            device_uri="usb://Unknown/Unknown"
            printer_driver="everywhere"
            ;;
        "bluetooth")
            device_uri="bluetooth://$printer_ip"
            printer_driver="everywhere"
            ;;
    esac
    
    # Appliquer les paramètres de politique de sécurité
    case "$security_policy" in
        "high_security")
            additional_options="-o job-hold-until=indefinite -o job-sheets=confidential,confidential"
            ;;
        "finance_department")
            additional_options="-o job-sheets=standard,standard -o page-label='CONFIDENTIEL - FINANCE'"
            ;;
        "hr_department")
            additional_options="-o job-hold-until=indefinite -o page-label='RH CONFIDENTIEL'"
            ;;
    esac
    
    # Déployer l'imprimante
    if lpadmin -p "$printer_name" -E -D "Roundfleet $printer_type - $department" -v "$device_uri" -m "$printer_driver" $additional_options; then
        log_action "Imprimante déployée avec succès : $printer_name"
        
        # Définir des options CUPS supplémentaires
        lpadmin -p "$printer_name" -o media=letter -o sides=two-sided-long-edge
        
        # Sauvegarder les métadonnées d'imprimante
        cat > "$PRINTER_DIR/${printer_name}_metadata.json" << EOF
{
  "printer_name": "$printer_name",
  "printer_ip": "$printer_ip",
  "printer_type": "$printer_type",
  "security_policy": "$security_policy",
  "department": "$department",
  "deployed_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "deployed_by": "$(whoami)",
  "device_uri": "$device_uri"
}
EOF
        
        return 0
    else
        log_action "ERREUR : Échec du déploiement d'imprimante : $printer_name"
        return 1
    fi
}

# Déploiement en masse d'imprimantes
bulk_deploy_printers() {
    local printer_list_file="$1"
    local deployment_profile="$2"
    
    if [[ ! -f "$printer_list_file" ]]; then
        log_action "ERREUR : Fichier de liste d'imprimantes non trouvé : $printer_list_file"
        return 1
    fi
    
    log_action "Démarrage du déploiement en masse d'imprimantes avec le profil : $deployment_profile"
    
    local deployed_count=0
    local failed_count=0
    
    while IFS=',' read -r printer_name printer_ip printer_type security_policy department; do
        [[ "$printer_name" =~ ^#.*$ ]] && continue
        [[ -z "$printer_name" ]] && continue
        
        if deploy_printer "$printer_name" "$printer_ip" "$printer_type" "$security_policy" "$department"; then
            ((deployed_count++))
        else
            ((failed_count++))
        fi
        
        # Ajouter un petit délai pour éviter de surcharger le système
        sleep 2
    done < "$printer_list_file"
    
    log_action "Déploiement en masse terminé : $deployed_count réussis, $failed_count échoués"
}

# Configuration avancée d'imprimante
configure_printer_advanced() {
    local printer_name="$1"
    local config_type="$2"
    
    log_action "Application de configuration avancée à $printer_name : $config_type"
    
    case "$config_type" in
        "duplex_default")
            lpadmin -p "$printer_name" -o sides=two-sided-long-edge
            lpadmin -p "$printer_name" -o ColorModel=Gray
            ;;
        "high_quality")
            lpadmin -p "$printer_name" -o print-quality=5
            lpadmin -p "$printer_name" -o resolution=600dpi
            ;;
        "eco_mode")
            lpadmin -p "$printer_name" -o print-quality=3
            lpadmin -p "$printer_name" -o ColorModel=Gray
            lpadmin -p "$printer_name" -o sides=two-sided-long-edge
            ;;
        "secure_printing")
            lpadmin -p "$printer_name" -o job-hold-until=indefinite
            lpadmin -p "$printer_name" -o job-sheets=confidential,confidential
            ;;
    esac
    
    log_action "Configuration avancée appliquée à $printer_name"
}

# Surveillance de la santé des imprimantes
monitor_printer_health() {
    local monitoring_level="$1"
    local health_report="$REPORTS_DIR/printer_health_$(date +%Y%m%d_%H%M%S).json"
    
    log_action "Démarrage de la surveillance de santé des imprimantes : $monitoring_level"
    
    local printers=$(lpstat -p | grep "printer" | awk '{print $2}')
    local printer_data=""
    local total_printers=0
    local online_printers=0
    local offline_printers=0
    
    while IFS= read -r printer; do
        [[ -z "$printer" ]] && continue
        ((total_printers++))
        
        local status=$(lpstat -p "$printer" | grep "printer" | awk '{print $4}')
        local queue_jobs=$(lpstat -o "$printer" 2>/dev/null | wc -l)
        
        if [[ "$status" == "idle" || "$status" == "printing" ]]; then
            ((online_printers++))
            local printer_status="online"
        else
            ((offline_printers++))
            local printer_status="offline"
        fi
        
        # Obtenir les métadonnées d'imprimante si disponibles
        local metadata_file="$PRINTER_DIR/${printer}_metadata.json"
        local printer_type="unknown"
        local department="unknown"
        
        if [[ -f "$metadata_file" ]]; then
            printer_type=$(grep -o '"printer_type":"[^"]*' "$metadata_file" | cut -d'"' -f4)
            department=$(grep -o '"department":"[^"]*' "$metadata_file" | cut -d'"' -f4)
        fi
        
        printer_data="$printer_data{\"name\":\"$printer\",\"status\":\"$printer_status\",\"queue_jobs\":$queue_jobs,\"type\":\"$printer_type\",\"department\":\"$department\"},"
        
    done <<< "$printers"
    
    # Supprimer la virgule finale
    printer_data="${printer_data%,}"
    
    cat > "$health_report" << EOF
{
  "health_monitoring": {
    "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "monitoring_level": "$monitoring_level",
    "total_printers": $total_printers,
    "online_printers": $online_printers,
    "offline_printers": $offline_printers,
    "system_status": "$(cupsd -t 2>&1 | grep -q "no errors" && echo "healthy" || echo "issues_detected")"
  },
  "printer_details": [$printer_data],
  "recommendations": [
    $([ $offline_printers -gt 0 ] && echo "\"Vérifier les imprimantes hors ligne pour problèmes de connectivité\",")
    $([ $total_printers -gt 20 ] && echo "\"Considérer la consolidation d'imprimantes pour une meilleure gestion\",")
    "\"Maintenance régulière recommandée pour performance optimale\""
  ]
}
EOF
    
    if [[ $offline_printers -gt 0 ]]; then
        log_action "AVERTISSEMENT : $offline_printers imprimantes sont hors ligne"
    fi
    
    log_action "Surveillance de santé des imprimantes terminée. Rapport : $health_report"
    echo "$health_report"
}

# Gestion des files d'attente d'impression
manage_print_queues() {
    local action="$1"
    local printer_name="$2"
    local job_id="$3"
    
    log_action "Gestion de file d'attente d'impression : $action pour $printer_name"
    
    case "$action" in
        "pause_all")
            cupsdisable "$printer_name"
            log_action "Impression suspendue pour : $printer_name"
            ;;
        "resume_all")
            cupsenable "$printer_name"
            log_action "Impression reprise pour : $printer_name"
            ;;
        "clear_queue")
            cancel -a "$printer_name"
            log_action "File d'attente vidée pour : $printer_name"
            ;;
        "cancel_job")
            if [[ -n "$job_id" ]]; then
                cancel "$job_id"
                log_action "Travail d'impression annulé : $job_id"
            fi
            ;;
        "hold_job")
            if [[ -n "$job_id" ]]; then
                lp -i "$job_id" -H hold
                log_action "Travail d'impression mis en attente : $job_id"
            fi
            ;;
        "release_job")
            if [[ -n "$job_id" ]]; then
                lp -i "$job_id" -H resume
                log_action "Travail d'impression libéré : $job_id"
            fi
            ;;
    esac
    
    # Enregistrer l'action dans le journal d'audit
    echo "$(date -u +%Y-%m-%dT%H:%M:%SZ):$action:$printer_name:$job_id:$(whoami)" >> "$AUDIT_DIR/print_queue_actions.log"
}

# Application de sécurité d'imprimante
enforce_printer_security() {
    local security_level="$1"
    
    log_action "Application du niveau de sécurité d'imprimante : $security_level"
    
    case "$security_level" in
        "maximum")
            # Activer l'authentification pour toutes les imprimantes
            for printer in $(lpstat -p | grep "printer" | awk '{print $2}'); do
                lpadmin -p "$printer" -o job-hold-until=indefinite
                lpadmin -p "$printer" -o job-sheets=confidential,confidential
                log_action "Sécurité maximale appliquée à : $printer"
            done
            ;;
        "departmental")
            # Appliquer la sécurité spécifique au département
            for printer in $(lpstat -p | grep "printer" | awk '{print $2}'); do
                if [[ "$printer" =~ [Ff]inance ]]; then
                    lpadmin -p "$printer" -o page-label="CONFIDENTIEL - FINANCE"
                elif [[ "$printer" =~ [Hh][Rr] ]]; then
                    lpadmin -p "$printer" -o job-hold-until=indefinite
                fi
            done
            ;;
        "standard")
            # Appliquer les mesures de sécurité standard
            for printer in $(lpstat -p | grep "printer" | awk '{print $2}'); do
                lpadmin -p "$printer" -o job-sheets=none,none
                log_action "Sécurité standard appliquée à : $printer"
            done
            ;;
    esac
    
    log_action "Application de sécurité d'imprimante terminée : $security_level"
}

# Analyses d'utilisation d'imprimante
generate_usage_analytics() {
    local analysis_period="$1"
    local analytics_file="$REPORTS_DIR/printer_analytics_$(date +%Y%m%d_%H%M%S).json"
    
    log_action "Génération d'analyses d'utilisation d'imprimante pour la période : $analysis_period"
    
    # Obtenir l'historique des travaux d'impression (derniers 30 jours par défaut)
    local job_history=$(grep "$(date -v-30d '+%Y-%m-%d')" /var/log/cups/page_log 2>/dev/null || echo "")
    
    # Analyser les modèles d'utilisation
    local total_jobs=0
    local total_pages=0
    local color_pages=0
    local duplex_jobs=0
    
    if [[ -n "$job_history" ]]; then
        total_jobs=$(echo "$job_history" | wc -l)
        total_pages=$(echo "$job_history" | awk '{sum += $7} END {print sum+0}')
        color_pages=$(echo "$job_history" | grep -i "color" | awk '{sum += $7} END {print sum+0}')
        duplex_jobs=$(echo "$job_history" | grep -i "duplex\|two-sided" | wc -l)
    fi
    
    # Calculer les estimations de coût (tarifs d'exemple)
    local mono_cost_per_page=0.02
    local color_cost_per_page=0.15
    local estimated_cost=$(echo "scale=2; ($total_pages - $color_pages) * $mono_cost_per_page + $color_pages * $color_cost_per_page" | bc -l 2>/dev/null || echo "0.00")
    
    cat > "$analytics_file" << EOF
{
  "usage_analytics": {
    "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "analysis_period": "$analysis_period",
    "total_print_jobs": $total_jobs,
    "total_pages_printed": $total_pages,
    "color_pages": $color_pages,
    "monochrome_pages": $((total_pages - color_pages)),
    "duplex_jobs": $duplex_jobs,
    "estimated_cost_usd": $estimated_cost
  },
  "efficiency_metrics": {
    "duplex_usage_percentage": $(echo "scale=2; $duplex_jobs * 100 / $total_jobs" | bc -l 2>/dev/null || echo "0"),
    "color_usage_percentage": $(echo "scale=2; $color_pages * 100 / $total_pages" | bc -l 2>/dev/null || echo "0"),
    "average_pages_per_job": $(echo "scale=2; $total_pages / $total_jobs" | bc -l 2>/dev/null || echo "0")
  },
  "cost_optimization": {
    "potential_duplex_savings": "$(echo "scale=2; ($total_jobs - $duplex_jobs) * $mono_cost_per_page * 0.5" | bc -l 2>/dev/null || echo "0.00")",
    "color_to_mono_savings": "$(echo "scale=2; $color_pages * ($color_cost_per_page - $mono_cost_per_page)" | bc -l 2>/dev/null || echo "0.00")"
  }
}
EOF
    
    log_action "Analyses d'utilisation générées : $analytics_file"
    echo "$analytics_file"
}

# Générer un rapport de conformité complet
generate_compliance_report() {
    local policy="$1"
    local report_file="$REPORTS_DIR/printer_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    local total_printers=$(lpstat -p | grep "printer" | wc -l)
    local secure_printers=0
    
    # Compter les imprimantes avec configurations de sécurité
    for printer in $(lpstat -p | grep "printer" | awk '{print $2}'); do
        if lpoptions -p "$printer" | grep -q "job-hold-until\|job-sheets"; then
            ((secure_printers++))
        fi
    done
    
    cat > "$report_file" << EOF
{
  "compliance_report": {
    "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "policy_applied": "$policy",
    "total_printers": $total_printers,
    "secure_printers": $secure_printers,
    "security_coverage": $(echo "scale=2; $secure_printers * 100 / $total_printers" | bc -l 2>/dev/null || echo "0")
  },
  "security_compliance": {
    "encryption_enabled": $(systemctl is-active cups-ssl 2>/dev/null | grep -q "active" && echo "true" || echo "false"),
    "audit_logging": $([ -f "/var/log/cups/access_log" ] && echo "true" || echo "false"),
    "authentication_configured": $(grep -q "AuthType" /etc/cups/cupsd.conf && echo "true" || echo "false")
  },
  "compliance_frameworks": ["SOX", "HIPAA", "NIST", "ISO27001"],
  "recommendations": [
    $([ $secure_printers -lt $total_printers ] && echo "\"Activer les fonctionnalités de sécurité sur toutes les imprimantes\",")
    "\"Audits de sécurité réguliers recommandés\",\"Implémenter des systèmes de libération d'impression pour documents sensibles\""
  ]
}
EOF
    
    log_action "Rapport de conformité généré : $report_file"
    echo "Rapport sauvegardé dans : $report_file"
}

# Maintenance automatisée d'imprimante
perform_printer_maintenance() {
    local maintenance_type="$1"
    
    log_action "Démarrage de maintenance automatisée d'imprimante : $maintenance_type"
    
    case "$maintenance_type" in
        "cleanup")
            # Nettoyer les anciens travaux d'impression et journaux
            find /var/spool/cups -name "c*" -mtime +7 -delete 2>/dev/null
            find /var/spool/cups -name "d*" -mtime +7 -delete 2>/dev/null
            log_action "Nettoyage des anciens travaux d'impression et fichiers de spool"
            ;;
        "queue_optimization")
            # Redémarrer CUPS pour nettoyer les files bloquées
            launchctl kickstart -k system/org.cups.cupsd
            log_action "Service CUPS redémarré pour optimisation des files"
            ;;
        "driver_update")
            # Vérifier les mises à jour de pilotes d'imprimante (placeholder)
            log_action "Vérification de mise à jour de pilotes initiée (vérification manuelle requise)"
            ;;
        "full_maintenance")
            perform_printer_maintenance "cleanup"
            perform_printer_maintenance "queue_optimization"
            log_action "Routine de maintenance complète terminée"
            ;;
    esac
}

# Vérification de santé et validation système
perform_health_check() {
    echo "=== Vérification de Santé de Gestion d'Imprimantes Roundfleet ==="
    
    # Vérifier le service CUPS
    if launchctl list | grep -q "org.cups.cupsd"; then
        echo "✓ Service CUPS : En cours d'exécution"
    else
        echo "✗ Service CUPS : Non en cours d'exécution"
    fi
    
    # Vérifier le nombre d'imprimantes
    local printer_count=$(lpstat -p | grep "printer" | wc -l)
    echo "✓ Imprimantes installées : $printer_count"
    
    # Vérifier les imprimantes hors ligne
    local offline_printers=$(lpstat -p | grep -c "disabled\|stopped" || echo "0")
    if [[ $offline_printers -gt 0 ]]; then
        echo "⚠️  Imprimantes hors ligne : $offline_printers"
    else
        echo "✓ Toutes les imprimantes en ligne"
    fi
    
    # Vérifier les files d'attente d'impression
    local queued_jobs=$(lpstat -o | wc -l)
    echo "✓ Travaux d'impression en file : $queued_jobs"
    
    # Vérifier la configuration de sécurité
    if grep -q "AuthType" /etc/cups/cupsd.conf; then
        echo "✓ Authentification : Configurée"
    else
        echo "○ Authentification : Non configurée"
    fi
    
    # Vérifier la journalisation d'audit
    if [[ -f "/var/log/cups/access_log" ]]; then
        echo "✓ Journalisation d'audit : Activée"
    else
        echo "○ Journalisation d'audit : Désactivée"
    fi
}

# Fonction de déploiement de flotte
deploy_to_fleet() {
    local deployment_profile="$1"
    local fleet_file="$2"
    
    if [[ ! -f "$fleet_file" ]]; then
        log_action "ERREUR : Fichier de flotte non trouvé : $fleet_file"
        return 1
    fi
    
    log_action "Démarrage du déploiement de flotte du profil d'imprimante : $deployment_profile"
    
    while IFS= read -r host; do
        [[ -z "$host" || "$host" =~ ^#.*$ ]] && continue
        
        echo "Déploiement vers : $host"
        
        # Copier la configuration d'imprimante vers l'hôte distant
        ssh "$host" "bash -s" << EOF
#!/bin/bash
# Déploiement distant de gestion d'imprimante : $deployment_profile

# Créer les répertoires
mkdir -p /etc/roundfleet/{printer_management,reports,compliance,audit,printer_policies}

# Déployer les imprimantes communes basées sur le profil
case "$deployment_profile" in
    "office_standard")
        # Déployer la configuration d'imprimante de bureau standard
        echo "Déploiement de configuration d'imprimante de bureau standard"
        ;;
    "secure_environment")
        # Déployer la configuration d'imprimante haute sécurité
        echo "Déploiement de configuration d'imprimante sécurisée"
        ;;
esac
EOF
        
        if [[ $? -eq 0 ]]; then
            log_action "Déployé avec succès vers : $host"
        else
            log_action "Échec du déploiement vers : $host"
        fi
        
    done < "$fleet_file"
    
    log_action "Déploiement de flotte terminé"
}

# Fonction d'exécution principale
main() {
    create_directories
    
    case "${1:-}" in
        "deploy_printer")
            deploy_printer "$2" "$3" "$4" "${5:-standard_security}" "${6:-general}"
            ;;
        "bulk_deploy")
            bulk_deploy_printers "$2" "${3:-office_standard}"
            ;;
        "configure_advanced")
            configure_printer_advanced "$2" "${3:-duplex_default}"
            ;;
        "monitor_health")
            monitor_printer_health "${2:-standard}"
            ;;
        "manage_queues")
            manage_print_queues "$2" "$3" "$4"
            ;;
        "enforce_security")
            enforce_printer_security "${2:-standard}"
            ;;
        "usage_analytics")
            generate_usage_analytics "${2:-30days}"
            ;;
        "maintenance")
            perform_printer_maintenance "${2:-cleanup}"
            ;;
        "health_check")
            perform_health_check
            ;;
        "report")
            generate_compliance_report "${2:-manual}"
            ;;
        "deploy_fleet")
            deploy_to_fleet "$2" "$3"
            ;;
        "help"|*)
            echo "Système de Gestion d'Imprimantes d'Entreprise Roundfleet"
            echo ""
            echo "Utilisation : $0 <commande> [options]"
            echo ""
            echo "Commandes :"
            echo "  deploy_printer <nom> <ip> <type> [sécurité] [dept] - Déployer une seule imprimante"
            echo "  bulk_deploy <fichier> [profil]           - Déployer plusieurs imprimantes depuis un fichier"
            echo "  configure_advanced <imprimante> [config] - Appliquer configuration avancée (duplex_default|high_quality|eco_mode|secure_printing)"
            echo "  monitor_health [niveau]                  - Surveiller santé imprimantes (basic|standard|detailed)"
            echo "  manage_queues <action> <imprimante> [job] - Gérer files d'impression (pause_all|resume_all|clear_queue|cancel_job|hold_job|release_job)"
            echo "  enforce_security [niveau]                - Appliquer politiques sécurité (maximum|departmental|standard)"
            echo "  usage_analytics [période]                - Générer analyses utilisation (7days|30days|90days)"
            echo "  maintenance [type]                       - Effectuer maintenance (cleanup|queue_optimization|driver_update|full_maintenance)"
            echo "  health_check                             - Effectuer vérification santé système"
            echo "  report [politique]                       - Générer rapport conformité"
            echo "  deploy_fleet <profil> <fichier_flotte>   - Déployer vers flotte"
            echo ""
            echo "Exemples :"
            echo "  $0 deploy_printer Office_HP 192.168.1.100 network_ipp high_security finance"
            echo "  $0 bulk_deploy printers.csv office_standard"
            echo "  $0 configure_advanced Office_HP secure_printing"
            echo "  $0 manage_queues pause_all Office_HP"
            echo "  $0 health_check"
            ;;
    esac
}

# Exécuter la fonction principale
main "$@"

## Types et Configurations d'Imprimantes

Le système d'entreprise supporte divers types d'imprimantes :

| **Type d'Imprimante** | **Connexion** | **Cas d'Usage** | **Niveau de Sécurité** |
|---|---|---|---|
| **IPP Réseau** | ipp://ip/ipp/print | Impression de bureau standard | Moyen |
| **LPD Réseau** | lpd://ip/queue | Imprimantes réseau héritées | Moyen |
| **USB Direct** | usb://device | Imprimantes personnelles/bureau | Faible |
| **Bluetooth** | bluetooth://address | Impression mobile | Moyen |
| **IPP Sécurisé** | ipps://ip/ipp/print | Impression chiffrée | Élevé |

## Exemples de Déploiement d'Entreprise

### Déployer Imprimante de Bureau Standard

```bash
# Déployer imprimante réseau avec sécurité standard
./printer_manager.sh deploy_printer "Office_HP_LaserJet" "192.168.1.100" "network_ipp" "standard_security" "general_office"

# Déployer imprimante haute sécurité pour département finance
./printer_manager.sh deploy_printer "Finance_Secure" "192.168.1.200" "network_ipp" "finance_department" "finance"

Déploiement en Masse d'Imprimantes

Créer un fichier CSV printers.csv :

# printer_name,printer_ip,printer_type,security_policy,department
Office_HP_Main,192.168.1.100,network_ipp,standard_security,general
Finance_Secure,192.168.1.200,network_ipp,finance_department,finance
HR_Confidential,192.168.1.300,network_ipp,hr_department,hr
# Déployer toutes les imprimantes du fichier
./printer_manager.sh bulk_deploy printers.csv office_standard

Configuration Avancée d'Imprimante

# Configurer impression recto-verso par défaut
./printer_manager.sh configure_advanced Office_HP duplex_default

# Activer impression sécurisée avec authentification
./printer_manager.sh configure_advanced Finance_Secure secure_printing

# Appliquer paramètres éco-responsables
./printer_manager.sh configure_advanced Office_HP eco_mode

Fonctionnalités de Sécurité et Conformité

Application de Sécurité d'Imprimante

# Appliquer sécurité maximale à toutes les imprimantes
./printer_manager.sh enforce_security maximum

# Appliquer politiques de sécurité spécifiques au département
./printer_manager.sh enforce_security departmental

Gestion des Files d'Attente d'Impression

# Suspendre toute impression sur une imprimante
./printer_manager.sh manage_queues pause_all Office_HP

# Vider tous les travaux en attente
./printer_manager.sh manage_queues clear_queue Office_HP

# Mettre un travail spécifique en attente pour approbation
./printer_manager.sh manage_queues hold_job Office_HP 12345

Analyses d'Utilisation et Contrôle des Coûts

# Générer analyses d'utilisation de 30 jours
./printer_manager.sh usage_analytics 30days

# Générer analyse de coûts trimestrielle
./printer_manager.sh usage_analytics 90days

Fonctionnalités d'Entreprise

Maintenance Automatisée

Le système fournit des capacités de maintenance automatisées :

  • Nettoyage et optimisation des files d'impression
  • Vérification de mises à jour de pilotes
  • Surveillance de performance
  • Planification de maintenance préventive

Contrôles de Sécurité

Les fonctionnalités de sécurité avancées incluent :

  • Exigences d'authentification
  • Files d'impression chiffrées
  • Journalisation de piste d'audit
  • Gestion de documents confidentiels
  • Contrôles d'accès basés sur le département

Gestion des Coûts

Surveiller et optimiser les coûts d'impression :

  • Suivi de l'utilisation papier et toner
  • Analyse des ratios couleur vs. monochrome
  • Surveillance de l'adoption de l'impression recto-verso
  • Génération de recommandations d'économie de coûts

Considérations de Gestion Importantes

  • Sécurité du serveur d'impression doit inclure des connexions chiffrées (IPPS)
  • Authentification utilisateur peut nécessiter l'intégration Active Directory
  • Journalisation d'audit doit respecter les politiques de rétention organisationnelles
  • Gestion des pilotes nécessite des mises à jour régulières pour la sécurité et compatibilité
  • Surveillance des files aide à prévenir les goulots d'étranglement et gaspillage de ressources

Conformité et Rapports

Le système d'entreprise fournit des pistes d'audit complètes pour :

  • Conformité SOX - Contrôles d'impression de documents financiers
  • Exigences HIPAA - Sécurité d'impression d'informations de santé
  • ISO 27001 - Gestion de sécurité information d'impression
  • Framework NIST - Standards de cybersécurité d'impression

Tests et Validation

Avant le déploiement d'entreprise :

  1. Tester la connectivité d'imprimante et précision de configuration
  2. Vérifier les politiques de sécurité sont correctement appliquées
  3. Confirmer l'authentification utilisateur fonctionne correctement
  4. Tester les procédures d'urgence et récupération de files
  5. Valider la complétude des rapports de conformité

Ce système complet transforme la gestion d'imprimante de base en une infrastructure d'impression de niveau entreprise avec sécurité avancée, contrôle des coûts, et capacités de gestion de flotte.

Configurer des bannières de politique sur les appareils macOS

Ce guide complet démontre comment créer, gérer et déployer des bannières de politique interactives sur les appareils macOS pour la conformité organisationnelle et la communication des politiques.

Aperçu

Les bannières de politique sont des messages interactifs qui apparaissent à l'écran de connexion, obligeant les utilisateurs à reconnaître les politiques organisationnelles, les accords ou les directives avant d'accéder à l'appareil. Elles servent d'outil de conformité essentiel pour :

  • Conformité légale : Afficher les conditions d'utilisation et les politiques d'utilisation acceptable
  • Sensibilisation à la sécurité : Communiquer les politiques et bonnes pratiques de sécurité
  • Exigences réglementaires : Respecter les normes de conformité spécifiques à l'industrie
  • Gouvernance d'entreprise : Assurer que les utilisateurs reconnaissent les politiques de l'entreprise
  • Protection des actifs : Établir un cadre légal pour l'utilisation des appareils

Implémentation de base des bannières de politique

Script de bannière de politique simple

Créez une bannière de politique de base avec un message personnalisé :

#!/bin/bash

# Script de base pour configurer une bannière de politique
# Usage: ./create_policy_banner.sh "Votre message de politique"

create_policy_banner() {
    local message="$1"
    
    # Message par défaut si aucun fourni
    if [ -z "$message" ]; then
        message="Ce système informatique est destiné à un usage autorisé uniquement. En accédant à ce système, vous acceptez de vous conformer à toutes les politiques et réglementations applicables."
    fi
    
    # Créer le fichier de bannière de politique
    sudo tee /Library/Security/PolicyBanner.txt <<EOF > /dev/null
$message
EOF
    
    # Définir les permissions appropriées
    sudo chmod 644 /Library/Security/PolicyBanner.txt
    sudo chown root:wheel /Library/Security/PolicyBanner.txt
    
    echo "Bannière de politique créée avec succès."
    echo "Message: $message"
}

# Exécution principale
if [ $# -eq 0 ]; then
    echo "Usage: $0 \"Votre message de politique\""
    echo "Exemple: $0 \"Ce système est surveillé à des fins de sécurité.\""
    create_policy_banner
else
    create_policy_banner "$1"
fi

Bannière de politique améliorée avec validation

#!/bin/bash

# Configuration de bannière de politique améliorée avec validation et journalisation
# Usage: ./enhanced_policy_banner.sh

setup_policy_banner() {
    local banner_file="/Library/Security/PolicyBanner.txt"
    local log_file="/var/log/roundfleet_policy_banner.log"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # Vérifier si on exécute en tant que root
    if [ "$EUID" -ne 0 ]; then
        echo "Erreur: Ce script doit être exécuté en tant que root"
        exit 1
    fi
    
    # Créer le répertoire de log s'il n'existe pas
    mkdir -p /var/log
    
    # Journaliser l'opération
    echo "[$timestamp] Début de configuration de bannière de politique sur $(hostname)" >> "$log_file"
    
    # Créer le contenu de la bannière de politique
    cat > "$banner_file" << 'EOF'
USAGE AUTORISÉ UNIQUEMENT

Ce système informatique est la propriété de l'Organisation Roundfleet et est destiné à un usage commercial autorisé uniquement. En continuant, vous reconnaissez que :

• Vous avez lu et acceptez de vous conformer à toutes les politiques applicables
• Vos activités peuvent être surveillées et enregistrées à des fins de sécurité
• L'accès ou l'utilisation non autorisés sont interdits et peuvent entraîner des poursuites pénales
• Vous comprenez que l'utilisation personnelle peut être restreinte ou interdite

Cliquez sur "Accepter" pour reconnaître ces conditions et continuer.
EOF
    
    # Définir les permissions appropriées
    chmod 644 "$banner_file"
    chown root:wheel "$banner_file"
    
    # Valider le fichier de bannière
    if [ -f "$banner_file" ]; then
        echo "[$timestamp] Bannière de politique créée avec succès à $banner_file" >> "$log_file"
        echo "Configuration de bannière de politique terminée avec succès."
        
        # Afficher le contenu actuel
        echo "Contenu actuel de la bannière de politique:"
        echo "================================"
        cat "$banner_file"
        echo "================================"
    else
        echo "[$timestamp] ERREUR: Échec de création du fichier de bannière de politique" >> "$log_file"
        echo "Erreur: Échec de création du fichier de bannière de politique"
        exit 1
    fi
    
    # Mettre à jour le volume preboot pour la compatibilité FileVault
    echo "[$timestamp] Mise à jour du volume preboot pour la compatibilité FileVault" >> "$log_file"
    if diskutil apfs updatePreboot / 2>/dev/null; then
        echo "[$timestamp] Volume preboot mis à jour avec succès" >> "$log_file"
        echo "Volume preboot mis à jour pour la compatibilité FileVault."
    else
        echo "[$timestamp] Avertissement: Échec de mise à jour du volume preboot" >> "$log_file"
        echo "Avertissement: Impossible de mettre à jour le volume preboot. La bannière peut ne pas apparaître sur les appareils avec FileVault activé."
    fi
}

# Exécuter la configuration
setup_policy_banner

Gestion avancée des bannières de politique

Bannière de politique multilingue

#!/bin/bash

# Configuration de bannière de politique multilingue
# Usage: ./multilang_policy_banner.sh [code_langue]

setup_multilang_banner() {
    local language=${1:-"fr"}
    local banner_file="/Library/Security/PolicyBanner.txt"
    
    # Vérifier si on exécute en tant que root
    if [ "$EUID" -ne 0 ]; then
        echo "Erreur: Ce script doit être exécuté en tant que root"
        exit 1
    fi
    
    case $language in
        "fr")
            create_french_banner
            ;;
        "en")
            create_english_banner
            ;;
        "es")
            create_spanish_banner
            ;;
        "de")
            create_german_banner
            ;;
        *)
            echo "Langue non supportée: $language"
            echo "Langues supportées: fr, en, es, de"
            exit 1
            ;;
    esac
    
    # Définir les permissions appropriées
    chmod 644 "$banner_file"
    chown root:wheel "$banner_file"
    
    # Mettre à jour le volume preboot
    diskutil apfs updatePreboot / 2>/dev/null
    
    echo "Bannière de politique multilingue ($language) créée avec succès."
}

create_french_banner() {
    cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
ACCÈS AUTORISÉ SEULEMENT

Ce système informatique appartient à l'Organisation Roundfleet et est fourni uniquement pour un usage commercial autorisé.

En continuant, vous reconnaissez que :
• Vous êtes un utilisateur autorisé avec un objectif commercial légitime
• Toutes les activités sont sujettes à surveillance et enregistrement
• L'accès, l'utilisation ou la divulgation non autorisés sont interdits
• Les violations peuvent entraîner des mesures disciplinaires et des poursuites légales
• L'usage personnel peut être restreint selon la politique de l'entreprise

Votre utilisation continue constitue l'acceptation de ces termes.

Cliquez sur "Accepter" pour continuer.
EOF
}

create_english_banner() {
    cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
AUTHORIZED ACCESS ONLY

This computer system is owned by Roundfleet Organization and is provided for authorized business use only.

By proceeding, you acknowledge that:
• You are an authorized user with legitimate business purpose
• All activities are subject to monitoring and logging
• Unauthorized access, use, or disclosure is prohibited
• Violations may result in disciplinary action and legal prosecution
• Personal use may be restricted per company policy

Your continued use constitutes acceptance of these terms.

Click "Accept" to proceed.
EOF
}

create_spanish_banner() {
    cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
SOLO ACCESO AUTORIZADO

Este sistema informático es propiedad de la Organización Roundfleet y se proporciona únicamente para uso comercial autorizado.

Al continuar, usted reconoce que:
• Es un usuario autorizado con un propósito comercial legítimo
• Todas las actividades están sujetas a monitoreo y registro
• El acceso, uso o divulgación no autorizados están prohibidos
• Las violaciones pueden resultar en acción disciplinaria y enjuiciamiento legal
• El uso personal puede estar restringido según la política de la empresa

Su uso continuado constituye la aceptación de estos términos.

Haga clic en "Aceptar" para continuar.
EOF
}

create_german_banner() {
    cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
NUR AUTORISIERTER ZUGANG

Dieses Computersystem gehört der Roundfleet Organisation und wird nur für autorisierten geschäftlichen Gebrauch bereitgestellt.

Durch Fortfahren erkennen Sie an, dass:
• Sie ein autorisierter Benutzer mit legitimen geschäftlichen Zweck sind
• Alle Aktivitäten der Überwachung und Protokollierung unterliegen
• Unbefugter Zugang, Gebrauch oder Offenlegung verboten ist
• Verstöße zu Disziplinarmaßnahmen und rechtlicher Verfolgung führen können
• Persönlicher Gebrauch gemäß Firmenrichtlinie beschränkt sein kann

Ihre fortgesetzte Nutzung stellt die Annahme dieser Bedingungen dar.

Klicken Sie "Akzeptieren" um fortzufahren.
EOF
}

# Exécution principale
setup_multilang_banner "$1"

Générateur de bannière de politique dynamique

#!/bin/bash

# Générateur de bannière de politique dynamique avec support de modèles
# Usage: ./dynamic_banner.sh [nom_modele]

generate_dynamic_banner() {
    local template=${1:-"entreprise"}
    local banner_file="/Library/Security/PolicyBanner.txt"
    local config_file="/etc/roundfleet/banner_config.conf"
    
    # Vérifier si on exécute en tant que root
    if [ "$EUID" -ne 0 ]; then
        echo "Erreur: Ce script doit être exécuté en tant que root"
        exit 1
    fi
    
    # Créer le répertoire de configuration
    mkdir -p /etc/roundfleet
    
    # Charger ou créer la configuration
    if [ -f "$config_file" ]; then
        source "$config_file"
    else
        create_default_config
        source "$config_file"
    fi
    
    # Générer la bannière basée sur le modèle
    case $template in
        "entreprise")
            generate_corporate_banner
            ;;
        "gouvernement")
            generate_government_banner
            ;;
        "sante")
            generate_healthcare_banner
            ;;
        "education")
            generate_education_banner
            ;;
        "financier")
            generate_financial_banner
            ;;
        *)
            echo "Modèle inconnu: $template"
            echo "Modèles disponibles: entreprise, gouvernement, sante, education, financier"
            exit 1
            ;;
    esac
    
    # Appliquer la configuration
    chmod 644 "$banner_file"
    chown root:wheel "$banner_file"
    diskutil apfs updatePreboot / 2>/dev/null
    
    echo "Bannière de politique dynamique ($template) générée avec succès."
}

create_default_config() {
    cat > "/etc/roundfleet/banner_config.conf" << 'EOF'
# Configuration de bannière de politique Roundfleet
ORGANIZATION_NAME="Organisation Roundfleet"
CONTACT_EMAIL="[email protected]"
CONTACT_PHONE="1-800-ROUNDFLEET"
COMPLIANCE_OFFICER="Équipe de conformité"
EFFECTIVE_DATE="2025-01-01"
MONITORING_ENABLED="true"
PERSONAL_USE_POLICY="restreinte"
EOF
}

generate_corporate_banner() {
    cat > "$banner_file" << EOF
$ORGANIZATION_NAME
POLITIQUE D'UTILISATION AUTORISÉE

Ce système informatique est fourni uniquement pour un usage commercial autorisé.

CONDITIONS D'UTILISATION :
• L'accès est restreint au personnel autorisé uniquement
• Toutes les activités sont surveillées et enregistrées à des fins de sécurité
• L'accès non autorisé ou l'utilisation abusive sont interdits
• L'utilisation personnelle est $PERSONAL_USE_POLICY selon la politique de l'entreprise
• Les utilisateurs doivent se conformer à toutes les lois et réglementations applicables

AVIS DE SURVEILLANCE :
En utilisant ce système, vous consentez à la surveillance et à l'enregistrement de vos activités.
Cela inclut notamment : le trafic réseau, l'accès aux fichiers et l'utilisation des applications.

Pour questions ou préoccupations, contactez :
$COMPLIANCE_OFFICER à $CONTACT_EMAIL ou $CONTACT_PHONE

Date d'entrée en vigueur : $EFFECTIVE_DATE

Votre utilisation continue constitue l'acceptation de ces termes.
EOF
}

generate_government_banner() {
    cat > "$banner_file" << EOF
$ORGANIZATION_NAME
USAGE OFFICIEL UNIQUEMENT

AVERTISSEMENT : Ceci est un système informatique du gouvernement français pour usage officiel uniquement.

En accédant à ce système, vous acceptez ce qui suit :
• Ce système est destiné aux affaires gouvernementales autorisées uniquement
• Toutes les activités sont sujettes à surveillance et enregistrement
• L'accès non autorisé est une violation de la loi
• Les preuves d'activité criminelle seront signalées aux forces de l'ordre
• L'utilisation personnelle est strictement interdite

AVIS DE CONFIDENTIALITÉ :
Les utilisateurs n'ont aucune attente de confidentialité lors de l'utilisation de ce système.
Toutes les informations stockées ou transmises peuvent être surveillées ou enregistrées.

L'utilisation non autorisée peut entraîner :
• Des poursuites pénales
• Une responsabilité civile
• Des mesures administratives y compris la résiliation

Pour autorisation d'usage officiel, contactez : $CONTACT_EMAIL

Date d'entrée en vigueur : $EFFECTIVE_DATE
EOF
}

generate_healthcare_banner() {
    cat > "$banner_file" << EOF
$ORGANIZATION_NAME
AVIS DE CONFORMITÉ RGPD SANTÉ

Ce système contient des informations de santé protégées soumises aux réglementations RGPD.

EXIGENCES D'ACCÈS :
• L'accès est restreint au personnel de santé autorisé uniquement
• Les utilisateurs doivent avoir un besoin professionnel légitime pour l'accès aux données
• Tout accès aux données de santé est enregistré et surveillé pour la conformité
• L'accès non autorisé peut entraîner des violations du RGPD

CONFIDENTIALITÉ ET SÉCURITÉ :
• Toutes les activités sont surveillées pour la conformité RGPD
• Les données de santé doivent être traitées selon les politiques de l'organisation
• Signalez immédiatement les violations de confidentialité suspectées
• L'utilisation personnelle de ce système est interdite

OBLIGATIONS DE CONFORMITÉ :
• Les utilisateurs doivent suivre la formation RGPD requise
• Les mots de passe doivent respecter les exigences de complexité
• Les postes de travail doivent être verrouillés quand ils ne sont pas surveillés
• Les données de santé ne doivent pas être divulguées à des personnes non autorisées

Pour questions de conformité RGPD : $CONTACT_EMAIL

Date d'entrée en vigueur : $EFFECTIVE_DATE

Votre accès confirme votre compréhension de ces obligations.
EOF
}

generate_education_banner() {
    cat > "$banner_file" << EOF
$ORGANIZATION_NAME
POLITIQUE DE TECHNOLOGIE ÉDUCATIVE

Ce système informatique est fourni à des fins éducatives et d'usage autorisé uniquement.

UTILISATION ACCEPTABLE :
• L'accès est limité aux étudiants, au corps enseignant et au personnel autorisé
• L'utilisation doit soutenir les objectifs éducatifs et la mission institutionnelle
• Toutes les activités sont surveillées pour assurer une utilisation appropriée
• L'utilisation personnelle est limitée et sujette à la politique institutionnelle

CONFIDENTIALITÉ DES ÉTUDIANTS :
• Les dossiers des étudiants sont protégés par les réglementations sur la protection des données
• L'accès aux informations des étudiants nécessite un intérêt éducatif légitime
• La divulgation non autorisée d'informations sur les étudiants est interdite
• Signalez immédiatement les violations de confidentialité suspectées

ACTIVITÉS INTERDITES :
• Accéder, copier ou partager du contenu inapproprié
• Violer les droits d'auteur ou de propriété intellectuelle
• Harcèlement, intimidation ou comportement discriminatoire
• Installer des logiciels ou applications non autorisés

Pour support technique : $CONTACT_EMAIL
Pour questions de politique : $COMPLIANCE_OFFICER

Date d'entrée en vigueur : $EFFECTIVE_DATE

Votre utilisation indique l'acceptation de ces termes.
EOF
}

generate_financial_banner() {
    cat > "$banner_file" << EOF
$ORGANIZATION_NAME
CONFORMITÉ DES SERVICES FINANCIERS

Ce système traite des données financières soumises à supervision réglementaire.

CONFORMITÉ RÉGLEMENTAIRE :
• Accès restreint au personnel des services financiers autorisé
• Toutes les transactions sont surveillées pour la conformité avec :
  - SOX (Loi Sarbanes-Oxley)
  - RGPD (Règlement général sur la protection des données)
  - PCI DSS (Standard de sécurité des données de l'industrie des cartes de paiement)
• Les données financières doivent être protégées selon les exigences réglementaires

EXIGENCES DE SÉCURITÉ :
• Une authentification forte est requise pour tout accès
• Les données financières ne doivent pas être stockées sur des appareils locaux
• Tout accès est enregistré et sujet à audit
• Les activités suspectes seront signalées aux régulateurs

CONFIDENTIALITÉ :
• Les informations financières des clients sont strictement confidentielles
• L'accès nécessite un objectif commercial légitime
• La divulgation non autorisée peut entraîner une action réglementaire
• L'utilisation personnelle de ce système est interdite

Pour questions de conformité : $COMPLIANCE_OFFICER
Pour support technique : $CONTACT_EMAIL

Date d'entrée en vigueur : $EFFECTIVE_DATE

Votre accès confirme la conformité avec ces exigences.
EOF
}

# Exécuter le générateur
generate_dynamic_banner "$1"

Gestion des bannières de politique d'entreprise

Déploiement centralisé de bannières

#!/bin/bash

# Déploiement centralisé de bannières de politique pour parc Mac
# Usage: ./enterprise_banner_deploy.sh

deploy_enterprise_banner() {
    local deployment_id="$(date +%Y%m%d_%H%M%S)"
    local log_file="/var/log/roundfleet_banner_deployment.log"
    local config_server="https://config.roundfleet.com"
    local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
    
    # Vérifier si on exécute en tant que root
    if [ "$EUID" -ne 0 ]; then
        echo "Erreur: Ce script doit être exécuté en tant que root"
        exit 1
    fi
    
    # Créer l'entrée de log
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Début de déploiement de bannière d'entreprise (ID: $deployment_id)" >> "$log_file"
    
    # Obtenir les informations de l'appareil
    local computer_name=$(scutil --get ComputerName)
    local os_version=$(sw_vers -productVersion)
    local build_version=$(sw_vers -buildVersion)
    
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Appareil: $computer_name ($device_id)" >> "$log_file"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] OS: macOS $os_version ($build_version)" >> "$log_file"
    
    # Récupérer la configuration de bannière spécifique à l'organisation
    fetch_banner_config
    
    # Déployer la bannière basée sur la configuration
    if [ -f "/tmp/banner_config.json" ]; then
        parse_and_deploy_banner
    else
        deploy_default_banner
    fi
    
    # Valider le déploiement
    validate_banner_deployment
    
    # Rapporter le statut de déploiement
    report_deployment_status "$deployment_id"
    
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Déploiement de bannière d'entreprise terminé (ID: $deployment_id)" >> "$log_file"
}

fetch_banner_config() {
    local config_url="$config_server/api/banner/config"
    local headers="X-Device-ID: $device_id"
    
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Récupération de la configuration de bannière depuis: $config_url" >> "$log_file"
    
    # Tenter de récupérer la configuration (simulé - remplacer par l'appel API réel)
    # curl -s -H "$headers" "$config_url" -o "/tmp/banner_config.json"
    
    # Créer une configuration mock pour la démonstration
    cat > "/tmp/banner_config.json" << 'EOF'
{
  "organization": "Roundfleet Entreprise",
  "template": "entreprise",
  "language": "fr",
  "custom_message": "",
  "monitoring_enabled": true,
  "contact_info": {
    "email": "[email protected]",
    "phone": "1-800-ROUNDFLEET"
  },
  "compliance_requirements": [
    "SOX", "RGPD", "PCI-DSS"
  ],
  "effective_date": "2025-07-07"
}
EOF
    
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Configuration récupérée avec succès" >> "$log_file"
}

parse_and_deploy_banner() {
    local config_file="/tmp/banner_config.json"
    
    # Analyser la configuration JSON (nécessite jq ou analyse manuelle)
    local organization=$(grep -o '"organization"[^,]*' "$config_file" | cut -d'"' -f4)
    local template=$(grep -o '"template"[^,]*' "$config_file" | cut -d'"' -f4)
    local language=$(grep -o '"language"[^,]*' "$config_file" | cut -d'"' -f4)
    
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Déploiement de bannière pour $organization (modèle: $template, langue: $language)" >> "$log_file"
    
    # Créer la bannière basée sur la configuration
    cat > "/Library/Security/PolicyBanner.txt" << EOF
$organization
BANNIÈRE DE POLITIQUE D'ENTREPRISE

Ce système informatique appartient à $organization et est fourni uniquement pour un usage commercial autorisé.

En accédant à ce système, vous reconnaissez et acceptez de :
• Vous conformer à toutes les politiques et procédures d'entreprise applicables
• Vous soumettre à la surveillance et à l'enregistrement de toutes les activités du système
• Respecter la confidentialité des informations propriétaires
• Signaler immédiatement les incidents de sécurité à l'équipe de sécurité IT
• Utiliser le système uniquement à des fins commerciales légitimes

AVIS DE SURVEILLANCE :
Toutes les activités sur ce système sont sujettes à surveillance et enregistrement.
Cela inclut notamment le trafic réseau, l'accès aux fichiers, les emails et l'utilisation des applications.

EXIGENCES DE CONFORMITÉ :
Ce système doit se conformer aux réglementations applicables incluant SOX, RGPD, et PCI-DSS.
Les utilisateurs sont responsables de maintenir la conformité avec toutes les normes applicables.

Pour questions ou pour signaler des incidents de sécurité :
Email: [email protected]
Téléphone: 1-800-ROUNDFLEET

Date d'entrée en vigueur : 2025-07-07

Votre utilisation continue constitue l'acceptation de ces termes et conditions.
EOF
    
    # Définir les permissions appropriées
    chmod 644 "/Library/Security/PolicyBanner.txt"
    chown root:wheel "/Library/Security/PolicyBanner.txt"
    
    # Nettoyer les fichiers temporaires
    rm -f "/tmp/banner_config.json"
}

deploy_default_banner() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Déploiement de la bannière par défaut (configuration non disponible)" >> "$log_file"
    
    cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
Organisation Roundfleet
USAGE AUTORISÉ UNIQUEMENT

Ce système informatique est fourni uniquement pour un usage commercial autorisé.

En continuant, vous reconnaissez que :
• Vous êtes un utilisateur autorisé avec un accès commercial légitime
• Toutes les activités sont surveillées et enregistrées à des fins de sécurité
• L'accès non autorisé ou l'utilisation abusive sont strictement interdits
• L'utilisation personnelle peut être restreinte selon la politique de l'entreprise
• Vous acceptez de vous conformer à toutes les politiques et réglementations applicables

Votre utilisation continue constitue l'acceptation de ces termes.

Pour questions : [email protected]
EOF
    
    chmod 644 "/Library/Security/PolicyBanner.txt"
    chown root:wheel "/Library/Security/PolicyBanner.txt"
}

validate_banner_deployment() {
    local banner_file="/Library/Security/PolicyBanner.txt"
    
    if [ -f "$banner_file" ]; then
        local file_size=$(stat -f%z "$banner_file")
        local file_perms=$(stat -f%p "$banner_file")
        
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Validation de bannière : Fichier existe, taille : $file_size octets, permissions : $file_perms" >> "$log_file"
        
        # Mettre à jour le volume preboot
        if diskutil apfs updatePreboot / 2>/dev/null; then
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] Volume preboot mis à jour avec succès" >> "$log_file"
        else
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] Avertissement : Échec de mise à jour du volume preboot" >> "$log_file"
        fi
        
        return 0
    else
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Erreur : Fichier de bannière non trouvé après déploiement" >> "$log_file"
        return 1
    fi
}

report_deployment_status() {
    local deployment_id="$1"
    local status_url="$config_server/api/banner/status"
    
    # Créer le rapport de statut
    cat > "/tmp/deployment_status.json" << EOF
{
  "deployment_id": "$deployment_id",
  "device_id": "$device_id",
  "computer_name": "$computer_name",
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "status": "terminé",
  "os_version": "$os_version",
  "banner_deployed": true
}
EOF
    
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Statut de déploiement préparé pour rapport" >> "$log_file"
    
    # Envoyer le rapport de statut (simulé)
    # curl -s -X POST -H "Content-Type: application/json" -d @"/tmp/deployment_status.json" "$status_url"
    
    # Nettoyer
    rm -f "/tmp/deployment_status.json"
}

# Exécuter le déploiement
deploy_enterprise_banner

Suppression et gestion des bannières de politique

Suppression sécurisée de bannière

#!/bin/bash

# Suppression sécurisée de bannière de politique avec sauvegarde
# Usage: ./remove_policy_banner.sh

remove_policy_banner() {
    local banner_file="/Library/Security/PolicyBanner.txt"
    local backup_dir="/var/backups/roundfleet"
    local timestamp=$(date '+%Y%m%d_%H%M%S')
    local log_file="/var/log/roundfleet_banner_removal.log"
    
    # Vérifier si on exécute en tant que root
    if [ "$EUID" -ne 0 ]; then
        echo "Erreur: Ce script doit être exécuté en tant que root"
        exit 1
    fi
    
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Début de suppression de bannière de politique" >> "$log_file"
    
    # Vérifier si la bannière existe
    if [ ! -f "$banner_file" ]; then
        echo "Aucune bannière de politique trouvée à supprimer."
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Aucune bannière de politique trouvée" >> "$log_file"
        return 0
    fi
    
    # Créer le répertoire de sauvegarde
    mkdir -p "$backup_dir"
    
    # Sauvegarder la bannière actuelle
    cp "$banner_file" "$backup_dir/PolicyBanner_backup_$timestamp.txt"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Bannière sauvegardée dans $backup_dir/PolicyBanner_backup_$timestamp.txt" >> "$log_file"
    
    # Supprimer le fichier de bannière
    rm -f "$banner_file"
    
    # Vérifier la suppression
    if [ ! -f "$banner_file" ]; then
        echo "Bannière de politique supprimée avec succès."
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Bannière de politique supprimée avec succès" >> "$log_file"
        
        # Mettre à jour le volume preboot
        if diskutil apfs updatePreboot / 2>/dev/null; then
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] Volume preboot mis à jour" >> "$log_file"
            echo "Volume preboot mis à jour."
        else
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] Avertissement : Échec de mise à jour du volume preboot" >> "$log_file"
            echo "Avertissement : Impossible de mettre à jour le volume preboot."
        fi
    else
        echo "Erreur : Échec de suppression de la bannière de politique."
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Erreur : Échec de suppression de la bannière de politique" >> "$log_file"
        return 1
    fi
}

# Exécuter la suppression
remove_policy_banner

Dépannage et meilleures pratiques

Problèmes courants et solutions

1. Bannière n'apparaît pas

# Vérifier les permissions du fichier
ls -la /Library/Security/PolicyBanner.txt

# Corriger les permissions si nécessaire
sudo chmod 644 /Library/Security/PolicyBanner.txt
sudo chown root:wheel /Library/Security/PolicyBanner.txt

# Mettre à jour le volume preboot
sudo diskutil apfs updatePreboot /

2. Compatibilité FileVault

# Pour les appareils avec FileVault activé, s'assurer que le volume preboot est mis à jour
sudo diskutil apfs updatePreboot /

# Vérifier le statut FileVault
sudo fdesetup status

3. Problèmes de contenu de bannière

# Vérifier l'encodage du fichier
file /Library/Security/PolicyBanner.txt

# Assurer des fins de ligne appropriées
dos2unix /Library/Security/PolicyBanner.txt

Meilleures pratiques pour la gestion des bannières de politique

  1. Mises à jour régulières : Réviser et mettre à jour les bannières de politique régulièrement pour refléter les politiques actuelles
  2. Documentation de conformité : Maintenir des enregistrements des déploiements de bannières à des fins d'audit
  3. Formation des utilisateurs : Assurer que les utilisateurs comprennent l'importance de la reconnaissance des politiques
  4. Surveillance : Implémenter une surveillance pour s'assurer que les bannières restent déployées sur tous les appareils
  5. Gestion des sauvegardes : Maintenir des sauvegardes de toutes les configurations de bannières de politique
  6. Tests : Tester les déploiements de bannières dans un environnement contrôlé avant le déploiement d'entreprise

Considérations de sécurité

  • Intégrité des fichiers : Surveiller les fichiers de bannières pour des modifications non autorisées
  • Contrôle d'accès : Restreindre la gestion des bannières aux administrateurs autorisés uniquement
  • Piste d'audit : Maintenir des logs de toutes les activités de gestion de bannières
  • Chiffrement : Considérer le chiffrement du contenu des bannières pour les environnements sensibles

Conclusion

Les bannières de politique sont des outils essentiels pour la conformité organisationnelle et la sensibilisation à la sécurité. Ce guide complet fournit des solutions de niveau entreprise pour déployer, gérer et surveiller les bannières de politique à travers les parcs Mac. Les scripts et procédures décrits assurent une communication cohérente des politiques tout en maintenant les normes de sécurité et de conformité.

N'oubliez pas de tester tous les scripts dans un environnement contrôlé avant de les déployer sur les systèmes de production, et toujours maintenir des sauvegardes appropriées de vos configurations de politique. Une surveillance et des mises à jour régulières assurent que vos bannières de politique restent efficaces et conformes aux exigences organisationnelles.

Gestion des Mots de Passe d'Entreprise sur macOS

Implémentez une gestion complète des mots de passe et un contrôle d'authentification sur vos appareils Roundfleet en utilisant des outils avancés de services d'annuaire et d'administration système. Ce tutoriel couvre l'effacement de mots de passe, l'application de politiques et la gestion d'authentification d'entreprise.

Comprendre la Gestion des Mots de Passe macOS

macOS fournit plusieurs outils pour la gestion des mots de passe :

  • dscl - Utilitaire en ligne de commande des Services d'Annuaire pour la gestion utilisateur
  • sysadminctl - Outil de contrôle d'administrateur système pour les opérations utilisateur
  • Services d'Annuaire - Framework central d'authentification et d'autorisation
  • Framework de Sécurité - Mécanismes avancés de politique et d'application de mots de passe

Opérations de Base sur les Mots de Passe

Effacer le Mot de Passe Utilisateur (Méthode de Base)

#!/bin/bash

# Effacement de base du mot de passe avec dscl
clear_user_password_dscl() {
    local username="$1"
    local current_password="$2"
    
    echo "=== Effacement du Mot de Passe pour l'Utilisateur : $username ==="
    
    # Valider les paramètres
    if [[ -z "$username" || -z "$current_password" ]]; then
        echo "❌ Usage : clear_user_password_dscl <nom_utilisateur> <mot_de_passe_actuel>"
        return 1
    fi
    
    # Vérifier si l'utilisateur existe
    if ! dscl . -read "/Users/$username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Effacer le mot de passe avec dscl
    echo "Effacement du mot de passe pour l'utilisateur : $username"
    if dscl . passwd "/Users/$username" "$current_password" ""; then
        echo "✅ Mot de passe effacé avec succès pour l'utilisateur : $username"
        echo "ℹ️  L'utilisateur peut maintenant se connecter en appuyant sur Entrée sans mot de passe"
    else
        echo "❌ Échec d'effacement du mot de passe pour l'utilisateur : $username"
        echo "   Vérifiez que le mot de passe actuel est correct"
        return 1
    fi
}

# Usage : clear_user_password_dscl "jean.dupont" "motdepasseactuel123"

Effacer le Mot de Passe avec sysadminctl

#!/bin/bash

# Effacement avancé du mot de passe avec sysadminctl
clear_user_password_sysadminctl() {
    local target_username="$1"
    local admin_username="$2"
    local admin_password="$3"
    
    echo "=== Effacement du Mot de Passe avec sysadminctl ==="
    echo "Utilisateur cible : $target_username"
    echo "Utilisateur admin : $admin_username"
    
    # Valider les paramètres
    if [[ -z "$target_username" || -z "$admin_username" || -z "$admin_password" ]]; then
        echo "❌ Usage : clear_user_password_sysadminctl <utilisateur_cible> <utilisateur_admin> <mot_de_passe_admin>"
        return 1
    fi
    
    # Vérifier si l'utilisateur cible existe
    if ! dscl . -read "/Users/$target_username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur cible '$target_username' n'existe pas"
        return 1
    fi
    
    # Vérifier si l'utilisateur admin existe et a les privilèges admin
    if ! dscl . -read "/Users/$admin_username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur admin '$admin_username' n'existe pas"
        return 1
    fi
    
    # Effacer le mot de passe avec sysadminctl
    echo "Effacement du mot de passe pour l'utilisateur : $target_username"
    if sysadminctl -resetPasswordFor "$target_username" -newPassword "" -adminUser "$admin_username" -adminPassword "$admin_password"; then
        echo "✅ Mot de passe effacé avec succès pour l'utilisateur : $target_username"
        echo "ℹ️  L'utilisateur peut maintenant se connecter sans saisir de mot de passe"
    else
        echo "❌ Échec d'effacement du mot de passe pour l'utilisateur : $target_username"
        echo "   Vérifiez les identifiants admin et les permissions utilisateur"
        return 1
    fi
}

# Usage : clear_user_password_sysadminctl "marie.martin" "admin" "motdepasseadmin123"

Gestion Avancée des Mots de Passe

Vérifier le Statut du Mot de Passe

#!/bin/bash

# Vérifier le statut du mot de passe et de l'authentification utilisateur
check_password_status() {
    local username="$1"
    
    echo "=== Vérification du Statut de Mot de Passe pour l'Utilisateur : $username ==="
    
    if [[ -z "$username" ]]; then
        echo "❌ Usage : check_password_status <nom_utilisateur>"
        return 1
    fi
    
    # Vérifier si l'utilisateur existe
    if ! dscl . -read "/Users/$username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Obtenir les informations utilisateur
    echo "Informations Utilisateur :"
    echo "Nom Réel : $(dscl . -read "/Users/$username" RealName | cut -d' ' -f2- || echo 'Non défini')"
    echo "UID : $(dscl . -read "/Users/$username" UniqueID | awk '{print $2}')"
    echo "ID Groupe Principal : $(dscl . -read "/Users/$username" PrimaryGroupID | awk '{print $2}')"
    echo "Répertoire Personnel : $(dscl . -read "/Users/$username" NFSHomeDirectory | cut -d' ' -f2-)"
    echo "Shell : $(dscl . -read "/Users/$username" UserShell | cut -d' ' -f2-)"
    
    # Vérifier la politique de mot de passe
    echo ""
    echo "Informations de Politique de Mot de Passe :"
    local password_policy=$(pwpolicy -u "$username" -getpolicy 2>/dev/null || echo "Aucune politique spécifique")
    echo "Politique de Mot de Passe : $password_policy"
    
    # Vérifier le statut du compte
    echo ""
    echo "Statut du Compte :"
    local account_policy=$(pwpolicy -u "$username" -getaccountpolicy 2>/dev/null || echo "Aucune politique de compte")
    echo "Politique de Compte : $account_policy"
    
    # Vérifier si le mot de passe est vide
    echo ""
    echo "Statut du Mot de Passe :"
    local auth_authority=$(dscl . -read "/Users/$username" AuthenticationAuthority 2>/dev/null)
    if [[ -z "$auth_authority" ]] || echo "$auth_authority" | grep -q "ShadowHash"; then
        echo "Type de Mot de Passe : Shadow Hash (Standard)"
    else
        echo "Type de Mot de Passe : $auth_authority"
    fi
}

check_password_status

Définir un Mot de Passe Sécurisé

#!/bin/bash

# Définir un mot de passe sécurisé avec validation
set_secure_password() {
    local username="$1"
    local new_password="$2"
    local admin_username="$3"
    local admin_password="$4"
    
    echo "=== Définition d'un Mot de Passe Sécurisé pour l'Utilisateur : $username ==="
    
    # Valider les paramètres
    if [[ -z "$username" || -z "$new_password" || -z "$admin_username" || -z "$admin_password" ]]; then
        echo "❌ Usage : set_secure_password <nom_utilisateur> <nouveau_mot_de_passe> <utilisateur_admin> <mot_de_passe_admin>"
        return 1
    fi
    
    # Vérifier la force du mot de passe
    if ! validate_password_strength "$new_password"; then
        echo "❌ Le mot de passe ne répond pas aux exigences de sécurité"
        return 1
    fi
    
    # Définir le mot de passe avec sysadminctl
    echo "Définition d'un mot de passe sécurisé pour l'utilisateur : $username"
    if sysadminctl -resetPasswordFor "$username" -newPassword "$new_password" -adminUser "$admin_username" -adminPassword "$admin_password"; then
        echo "✅ Mot de passe sécurisé défini avec succès pour l'utilisateur : $username"
        
        # Appliquer la politique de mot de passe
        apply_password_policy "$username"
    else
        echo "❌ Échec de définition du mot de passe pour l'utilisateur : $username"
        return 1
    fi
}

# Valider la force du mot de passe
validate_password_strength() {
    local password="$1"
    local min_length=8
    local has_upper=false
    local has_lower=false
    local has_digit=false
    local has_special=false
    
    # Vérifier la longueur minimale
    if [[ ${#password} -lt $min_length ]]; then
        echo "⚠️  Le mot de passe doit contenir au moins $min_length caractères"
        return 1
    fi
    
    # Vérifier la présence d'une lettre majuscule
    if [[ "$password" =~ [A-Z] ]]; then
        has_upper=true
    fi
    
    # Vérifier la présence d'une lettre minuscule
    if [[ "$password" =~ [a-z] ]]; then
        has_lower=true
    fi
    
    # Vérifier la présence d'un chiffre
    if [[ "$password" =~ [0-9] ]]; then
        has_digit=true
    fi
    
    # Vérifier la présence d'un caractère spécial
    if [[ "$password" =~ [^a-zA-Z0-9] ]]; then
        has_special=true
    fi
    
    # Valider toutes les exigences
    if [[ "$has_upper" == true && "$has_lower" == true && "$has_digit" == true && "$has_special" == true ]]; then
        echo "✅ Le mot de passe répond aux exigences de sécurité"
        return 0
    else
        echo "⚠️  Le mot de passe doit contenir majuscule, minuscule, chiffre et caractère spécial"
        return 1
    fi
}

# Appliquer la politique de mot de passe
apply_password_policy() {
    local username="$1"
    
    echo "Application de la politique de mot de passe pour l'utilisateur : $username"
    
    # Définir la politique de mot de passe (nécessite des privilèges admin)
    pwpolicy -u "$username" -setpolicy "minChars=8 requiresAlpha requiresNumeric requiresMixedCase requiresSymbol passwordCannotBeName maxMinutesUntilChangePassword=7776000" 2>/dev/null || true
    
    echo "✅ Politique de mot de passe appliquée"
}

Système de Gestion des Mots de Passe d'Entreprise

#!/bin/bash

# Système de Gestion des Mots de Passe d'Entreprise Roundfleet
# Gestion complète de l'authentification utilisateur et des politiques de mots de passe

# Configuration
PASSWORD_CONFIG_FILE="/etc/roundfleet/password_config.conf"
LOG_FILE="/var/log/roundfleet_password_management.log"
AUDIT_FILE="/var/log/roundfleet_password_audit.log"
BACKUP_DIR="/var/backups/roundfleet/user_accounts"

# Paramètres par défaut
DEFAULT_MIN_PASSWORD_LENGTH=12
DEFAULT_PASSWORD_EXPIRY_DAYS=90
DEFAULT_MAX_FAILED_ATTEMPTS=5
DEFAULT_LOCKOUT_DURATION=30

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Fonction de journalisation d'audit
audit_log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - AUDIT - $1" | tee -a "$AUDIT_FILE"
}

# Charger la configuration de gestion des mots de passe
load_password_config() {
    if [[ -f "$PASSWORD_CONFIG_FILE" ]]; then
        source "$PASSWORD_CONFIG_FILE"
        log_action "Configuration de mot de passe chargée depuis $PASSWORD_CONFIG_FILE"
    else
        log_action "Utilisation de la configuration de mot de passe par défaut"
    fi
}

# Sauvegarder les informations de compte utilisateur
backup_user_account() {
    local username="$1"
    local backup_file="$BACKUP_DIR/user_backup_${username}_$(date +%Y%m%d_%H%M%S).plist"
    
    # Créer le répertoire de sauvegarde
    sudo mkdir -p "$BACKUP_DIR"
    
    # Exporter l'enregistrement utilisateur
    if dscl . -read "/Users/$username" > "$backup_file" 2>/dev/null; then
        log_action "Sauvegarde de compte utilisateur créée : $backup_file"
        audit_log "SAUVEGARDE_CRÉÉE pour l'utilisateur : $username"
    else
        log_action "Échec de création de sauvegarde pour l'utilisateur : $username"
    fi
}

# Effacement de mot de passe d'entreprise avec vérifications de sécurité
enterprise_clear_password() {
    local username="$1"
    local admin_username="$2"
    local admin_password="$3"
    local force_clear="${4:-false}"
    
    log_action "Démarrage de l'effacement de mot de passe d'entreprise pour l'utilisateur : $username"
    audit_log "EFFACEMENT_MOT_DE_PASSE_INITIÉ pour l'utilisateur : $username par l'admin : $admin_username"
    
    # Valider les paramètres
    if [[ -z "$username" || -z "$admin_username" || -z "$admin_password" ]]; then
        log_action "❌ Paramètres requis manquants pour l'effacement de mot de passe"
        return 1
    fi
    
    # Vérifier si l'utilisateur existe
    if ! dscl . -read "/Users/$username" >/dev/null 2>&1; then
        log_action "❌ L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Vérifications de sécurité
    if ! perform_security_checks "$username" "$force_clear"; then
        log_action "❌ Échec des vérifications de sécurité pour l'utilisateur : $username"
        return 1
    fi
    
    # Créer une sauvegarde avant de faire des changements
    backup_user_account "$username"
    
    # Effacer le mot de passe avec sysadminctl (méthode plus sécurisée)
    log_action "Effacement du mot de passe pour l'utilisateur : $username avec sysadminctl"
    if sysadminctl -resetPasswordFor "$username" -newPassword "" -adminUser "$admin_username" -adminPassword "$admin_password" 2>/dev/null; then
        log_action "✅ Mot de passe effacé avec succès pour l'utilisateur : $username"
        audit_log "MOT_DE_PASSE_EFFACÉ pour l'utilisateur : $username"
        
        # Appliquer les mesures de sécurité post-effacement
        apply_post_clear_security "$username"
        
        # Générer un rapport de conformité
        generate_password_compliance_report "$username"
        
        return 0
    else
        log_action "❌ Échec d'effacement du mot de passe pour l'utilisateur : $username"
        audit_log "ÉCHEC_EFFACEMENT_MOT_DE_PASSE pour l'utilisateur : $username"
        return 1
    fi
}

# Effectuer des vérifications de sécurité avant les opérations de mot de passe
perform_security_checks() {
    local username="$1"
    local force_clear="$2"
    
    log_action "Exécution des vérifications de sécurité pour l'utilisateur : $username"
    
    # Vérifier si l'utilisateur est admin (précaution supplémentaire requise)
    if dscl . -read "/Groups/admin" GroupMembership 2>/dev/null | grep -q "$username"; then
        if [[ "$force_clear" != "true" ]]; then
            log_action "⚠️  L'utilisateur '$username' est un administrateur - utilisez force_clear=true pour procéder"
            return 1
        else
            log_action "⚠️  Procédure avec effacement de mot de passe utilisateur admin (forcé)"
            audit_log "EFFACEMENT_MOT_DE_PASSE_ADMIN_FORCÉ pour l'utilisateur : $username"
        fi
    fi
    
    # Vérifier le statut FileVault
    if fdesetup status | grep -q "FileVault is On"; then
        local filevault_users=$(fdesetup list | cut -d',' -f1)
        if echo "$filevault_users" | grep -q "$username"; then
            log_action "⚠️  L'utilisateur '$username' est un utilisateur FileVault - l'effacement de mot de passe peut affecter le chiffrement du disque"
            audit_log "EFFACEMENT_MOT_DE_PASSE_UTILISATEUR_FILEVAULT pour l'utilisateur : $username"
        fi
    fi
    
    # Vérifier si l'utilisateur est actuellement connecté
    if who | grep -q "$username"; then
        log_action "⚠️  L'utilisateur '$username' est actuellement connecté"
        audit_log "EFFACEMENT_MOT_DE_PASSE_UTILISATEUR_ACTIF pour l'utilisateur : $username"
    fi
    
    # Vérifier l'heure de dernière connexion
    local last_login=$(last "$username" | head -1 | awk '{print $4, $5, $6}')
    log_action "Dernière connexion pour l'utilisateur '$username' : $last_login"
    
    return 0
}

# Appliquer des mesures de sécurité après l'effacement du mot de passe
apply_post_clear_security() {
    local username="$1"
    
    log_action "Application des mesures de sécurité post-effacement pour l'utilisateur : $username"
    
    # Définir la politique de compte pour exiger un changement de mot de passe à la prochaine connexion
    pwpolicy -u "$username" -setpolicy "requiresPasswordReset=1" 2>/dev/null || true
    
    # Enregistrer l'événement de sécurité
    audit_log "SÉCURITÉ_POST_EFFACEMENT_APPLIQUÉE pour l'utilisateur : $username"
    
    # Optionnel : Envoyer une notification à l'équipe de sécurité
    if [[ "${ENABLE_SECURITY_NOTIFICATIONS}" == "true" ]]; then
        send_security_notification "$username" "password_cleared"
    fi
}

# Générer un rapport de conformité des mots de passe
generate_password_compliance_report() {
    local username="$1"
    local report_file="/var/log/roundfleet_password_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    # Obtenir les informations utilisateur
    local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
    local real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | cut -d' ' -f2-)
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory 2>/dev/null | cut -d' ' -f2-)
    
    # Vérifier le statut admin
    local is_admin=false
    if dscl . -read "/Groups/admin" GroupMembership 2>/dev/null | grep -q "$username"; then
        is_admin=true
    fi
    
    # Vérifier le statut FileVault
    local is_filevault_user=false
    if fdesetup status | grep -q "FileVault is On"; then
        if fdesetup list | cut -d',' -f1 | grep -q "$username"; then
            is_filevault_user=true
        fi
    fi
    
    # Générer le rapport de conformité
    local compliance_data='{
        "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
        "device_id": "'$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')'",
        "hostname": "'$(hostname)'",
        "operation": "password_cleared",
        "user_details": {
            "username": "'$username'",
            "uid": "'$uid'",
            "real_name": "'$real_name'",
            "home_directory": "'$home_dir'",
            "is_admin": '$is_admin',
            "is_filevault_user": '$is_filevault_user'
        },
        "security_status": {
            "password_cleared": true,
            "backup_created": true,
            "security_checks_passed": true,
            "post_clear_measures_applied": true
        }
    }'
    
    # Sauvegarder le rapport de conformité
    echo "$compliance_data" | jq . > "$report_file"
    log_action "Rapport de conformité des mots de passe généré : $report_file"
}

# Opérations de mots de passe en lot pour plusieurs utilisateurs
bulk_password_operations() {
    local operation="$1"
    local users_file="$2"
    local admin_username="$3"
    local admin_password="$4"
    
    log_action "Démarrage des opérations de mots de passe en lot : $operation"
    
    if [[ ! -f "$users_file" ]]; then
        log_action "❌ Fichier utilisateurs non trouvé : $users_file"
        return 1
    fi
    
    local success_count=0
    local failure_count=0
    
    while IFS= read -r username; do
        # Ignorer les lignes vides et les commentaires
        [[ -z "$username" || "$username" =~ ^# ]] && continue
        
        log_action "Traitement de l'utilisateur : $username"
        
        case "$operation" in
            "clear")
                if enterprise_clear_password "$username" "$admin_username" "$admin_password" "false"; then
                    ((success_count++))
                else
                    ((failure_count++))
                fi
                ;;
            "check")
                check_password_status "$username"
                ;;
            *)
                log_action "❌ Opération inconnue : $operation"
                return 1
                ;;
        esac
        
        # Petit délai entre les opérations
        sleep 1
        
    done < "$users_file"
    
    log_action "Opérations en lot terminées - Succès : $success_count, Échecs : $failure_count"
    audit_log "OPÉRATION_EN_LOT_TERMINÉE opération : $operation, succès : $success_count, échecs : $failure_count"
}

# Application des politiques de mots de passe
enforce_password_policies() {
    log_action "Application des politiques de mots de passe d'entreprise"
    
    # Obtenir tous les utilisateurs (excluant les utilisateurs système)
    local users=$(dscl . -list /Users | grep -v '^_' | grep -v '^root' | grep -v '^daemon' | grep -v '^nobody')
    
    for username in $users; do
        local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
        
        # Ignorer les utilisateurs système (UID < 500)
        if [[ "$uid" -lt 500 ]]; then
            continue
        fi
        
        log_action "Application de la politique de mot de passe pour l'utilisateur : $username"
        
        # Appliquer la politique de mot de passe d'entreprise
        local min_length="${MIN_PASSWORD_LENGTH:-$DEFAULT_MIN_PASSWORD_LENGTH}"
        local expiry_days="${PASSWORD_EXPIRY_DAYS:-$DEFAULT_PASSWORD_EXPIRY_DAYS}"
        local max_attempts="${MAX_FAILED_ATTEMPTS:-$DEFAULT_MAX_FAILED_ATTEMPTS}"
        
        pwpolicy -u "$username" -setpolicy "minChars=$min_length requiresAlpha requiresNumeric requiresMixedCase requiresSymbol passwordCannotBeName maxMinutesUntilChangePassword=$((expiry_days * 24 * 60)) maxFailedLoginAttempts=$max_attempts" 2>/dev/null || true
        
    done
    
    log_action "Application des politiques de mots de passe terminée"
}

# Envoyer une notification de sécurité
send_security_notification() {
    local username="$1"
    local event_type="$2"
    
    # Ceci s'intégrerait avec votre système de notification
    # Pour l'instant, enregistrer simplement l'événement
    audit_log "NOTIFICATION_SÉCURITÉ envoyée pour l'utilisateur : $username, événement : $event_type"
}

# Fonction principale de gestion des mots de passe
main() {
    local action="${1:-status}"
    local username="${2}"
    local admin_username="${3}"
    local admin_password="${4}"
    
    log_action "=== Gestion des Mots de Passe Roundfleet Démarrée ==="
    
    case "$action" in
        "clear")
            if [[ -z "$username" || -z "$admin_username" || -z "$admin_password" ]]; then
                echo "Usage : $0 clear <nom_utilisateur> <nom_utilisateur_admin> <mot_de_passe_admin>"
                exit 1
            fi
            load_password_config
            enterprise_clear_password "$username" "$admin_username" "$admin_password"
            ;;
        "clear-force")
            if [[ -z "$username" || -z "$admin_username" || -z "$admin_password" ]]; then
                echo "Usage : $0 clear-force <nom_utilisateur> <nom_utilisateur_admin> <mot_de_passe_admin>"
                exit 1
            fi
            load_password_config
            enterprise_clear_password "$username" "$admin_username" "$admin_password" "true"
            ;;
        "check")
            if [[ -z "$username" ]]; then
                echo "Usage : $0 check <nom_utilisateur>"
                exit 1
            fi
            check_password_status "$username"
            ;;
        "bulk")
            local operation="$2"
            local users_file="$3"
            shift 3
            admin_username="$1"
            admin_password="$2"
            load_password_config
            bulk_password_operations "$operation" "$users_file" "$admin_username" "$admin_password"
            ;;
        "enforce-policies")
            load_password_config
            enforce_password_policies
            ;;
        "status")
            echo "Système de Gestion des Mots de Passe Roundfleet"
            echo "Commandes disponibles :"
            echo "  clear <utilisateur> <admin_utilisateur> <admin_pass>  - Effacer le mot de passe utilisateur"
            echo "  clear-force <utilisateur> <admin_utilisateur> <admin_pass>  - Forcer l'effacement (utilisateurs admin)"
            echo "  check <utilisateur>                            - Vérifier le statut du mot de passe"
            echo "  bulk <opération> <fichier_utilisateurs> <admin_utilisateur> <admin_pass>  - Opérations en lot"
            echo "  enforce-policies                        - Appliquer les politiques de mots de passe"
            echo "  status                                  - Afficher cette aide"
            ;;
        *)
            echo "❌ Action inconnue : $action"
            echo "Utilisez '$0 status' pour les commandes disponibles"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion des Mots de Passe Roundfleet Terminée ==="
}

# Exécuter la fonction principale
main "$@"

Configuration de Gestion des Mots de Passe

Créer un fichier de configuration pour les politiques de mots de passe d'entreprise :

#!/bin/bash

# Créer un fichier de configuration de gestion des mots de passe
create_password_config() {
    local config_dir="/etc/roundfleet"
    local config_file="$config_dir/password_config.conf"
    
    # Créer le répertoire s'il n'existe pas
    sudo mkdir -p "$config_dir"
    
    # Créer le fichier de configuration
    sudo tee "$config_file" > /dev/null << 'EOF'
# Configuration de Gestion des Mots de Passe Roundfleet

# Paramètres de politique de mot de passe
MIN_PASSWORD_LENGTH=12
PASSWORD_EXPIRY_DAYS=90
MAX_FAILED_ATTEMPTS=5
LOCKOUT_DURATION=30

# Exigences de sécurité
REQUIRE_UPPERCASE=true
REQUIRE_LOWERCASE=true
REQUIRE_NUMBERS=true
REQUIRE_SPECIAL_CHARS=true
PREVENT_COMMON_PASSWORDS=true

# Paramètres opérationnels
ENABLE_AUDIT_LOGGING=true
ENABLE_SECURITY_NOTIFICATIONS=true
ENABLE_AUTOMATIC_BACKUP=true
BACKUP_RETENTION_DAYS=365

# Considérations FileVault
WARN_FILEVAULT_USERS=true
REQUIRE_FORCE_FOR_FILEVAULT=true

# Protection des utilisateurs admin
WARN_ADMIN_USERS=true
REQUIRE_FORCE_FOR_ADMIN=true

# Paramètres de conformité
ENABLE_COMPLIANCE_REPORTING=true
COMPLIANCE_REPORT_INTERVAL=7200  # 2 heures
SEND_COMPLIANCE_ALERTS=true
EOF

    echo "Configuration de gestion des mots de passe créée dans : $config_file"
    echo "Veuillez réviser et modifier les paramètres selon vos politiques de sécurité"
}

create_password_config

Considérations de Sécurité et Bonnes Pratiques

Compatibilité FileVault

#!/bin/bash

# Vérifier la compatibilité FileVault avant les opérations de mot de passe
check_filevault_compatibility() {
    local username="$1"
    
    echo "=== Vérification de Compatibilité FileVault ==="
    
    # Vérifier si FileVault est activé
    if fdesetup status | grep -q "FileVault is On"; then
        echo "✅ FileVault est activé"
        
        # Vérifier si l'utilisateur est un utilisateur FileVault
        local filevault_users=$(fdesetup list)
        if echo "$filevault_users" | grep -q "$username"; then
            echo "⚠️  L'utilisateur '$username' est un utilisateur FileVault"
            echo "   L'effacement du mot de passe peut affecter l'accès au chiffrement du disque"
            echo "   Considérez les éléments suivants avant de procéder :"
            echo "   - S'assurer que d'autres utilisateurs FileVault existent"
            echo "   - Avoir la clé de récupération disponible"
            echo "   - L'utilisateur peut avoir besoin de réactiver FileVault après la réinitialisation du mot de passe"
            return 1
        else
            echo "✅ L'utilisateur '$username' n'est pas un utilisateur FileVault"
            return 0
        fi
    else
        echo "ℹ️  FileVault n'est pas activé"
        return 0
    fi
}

check_filevault_compatibility

Audit et Conformité

#!/bin/bash

# Générer un rapport d'audit complet
generate_audit_report() {
    local report_file="/var/log/roundfleet_password_audit_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport d'Audit de Gestion des Mots de Passe Roundfleet"
        echo "Généré : $(date)"
        echo "Appareil : $(hostname)"
        echo "====================================="
        echo ""
        
        echo "Utilisateurs Système (UID >= 500) :"
        dscl . -list /Users | while read username; do
            local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
            if [[ "$uid" -ge 500 ]]; then
                local real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | cut -d' ' -f2-)
                local is_admin=""
                if dscl . -read "/Groups/admin" GroupMembership 2>/dev/null | grep -q "$username"; then
                    is_admin=" (Admin)"
                fi
                echo "- $username (UID : $uid)$is_admin - $real_name"
            fi
        done
        echo ""
        
        echo "Statut FileVault :"
        fdesetup status
        if fdesetup status | grep -q "FileVault is On"; then
            echo "Utilisateurs FileVault :"
            fdesetup list
        fi
        echo ""
        
        echo "Activités Récentes de Gestion des Mots de Passe :"
        if [[ -f "$AUDIT_FILE" ]]; then
            tail -20 "$AUDIT_FILE"
        else
            echo "Aucun journal d'audit trouvé"
        fi
        
    } > "$report_file"
    
    echo "Rapport d'audit généré : $report_file"
}

generate_audit_report

Intégration avec la Gestion Roundfleet

#!/bin/bash

# Intégration de gestion des mots de passe Roundfleet
roundfleet_password_integration() {
    echo "=== Intégration de Gestion des Mots de Passe Roundfleet ==="
    
    # Informations de l'appareil
    local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
    local hostname=$(hostname)
    local macos_version=$(sw_vers -productVersion)
    
    # Obtenir les statistiques de comptes utilisateur
    local total_users=$(dscl . -list /Users | grep -v '^_' | grep -v '^root' | grep -v '^daemon' | grep -v '^nobody' | wc -l)
    local admin_users=$(dscl . -read "/Groups/admin" GroupMembership 2>/dev/null | wc -w)
    
    # Statut FileVault
    local filevault_enabled=false
    local filevault_users=0
    if fdesetup status | grep -q "FileVault is On"; then
        filevault_enabled=true
        filevault_users=$(fdesetup list | wc -l)
    fi
    
    # Activités récentes de gestion des mots de passe
    local recent_activities=0
    if [[ -f "$AUDIT_FILE" ]]; then
        recent_activities=$(grep "$(date +%Y-%m-%d)" "$AUDIT_FILE" | wc -l)
    fi
    
    # Rapporter à l'API Roundfleet
    local api_data='{
        "device_id": "'$device_id'",
        "hostname": "'$hostname'",
        "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
        "macos_version": "'$macos_version'",
        "password_management": {
            "total_users": '$total_users',
            "admin_users": '$admin_users',
            "filevault_enabled": '$filevault_enabled',
            "filevault_users": '$filevault_users',
            "recent_activities": '$recent_activities'
        },
        "password_management_status": "actif"
    }'
    
    echo "Statut de gestion des mots de passe rapporté au système de gestion Roundfleet"
    echo "ID Appareil : $device_id"
    echo "Total Utilisateurs : $total_users"
    echo "Utilisateurs Admin : $admin_users"
    echo "FileVault Activé : $filevault_enabled"
    echo "Activités Récentes : $recent_activities"
}

roundfleet_password_integration

Notes de Sécurité Importantes

Avertissements de Sécurité

  • L'effacement de mot de passe crée des risques de sécurité - utilisez seulement quand nécessaire
  • Les utilisateurs FileVault nécessitent une considération spéciale - peut affecter le chiffrement du disque
  • Les utilisateurs admin nécessitent une prudence supplémentaire - peut compromettre la sécurité du système
  • Toujours créer des sauvegardes avant de faire des changements de mots de passe

Bonnes Pratiques

  • Utiliser sysadminctl plutôt que dscl pour une meilleure sécurité et des pistes d'audit
  • Implémenter des politiques de mots de passe fortes après l'effacement des mots de passe
  • Surveiller et auditer toutes les opérations de mots de passe
  • Tester sur des appareils pilotes avant le déploiement à l'échelle de la flotte

Considérations de Conformité

  • Documenter toutes les opérations de mots de passe pour les audits de sécurité
  • Maintenir des procédures de sauvegarde et de récupération
  • Évaluations de sécurité régulières des comptes utilisateur
  • Intégration avec les systèmes d'identité d'entreprise pour la gestion centralisée

Application de Politiques de Mots de Passe en Entreprise sur macOS

Appliquez des politiques de mots de passe de niveau entreprise et des standards de sécurité sur vos appareils Roundfleet en utilisant des outils en ligne de commande complets et des frameworks de sécurité. Ce tutoriel couvre l'implémentation de politiques de mots de passe, la surveillance de la conformité et les systèmes d'application automatisés.

Comprendre la Sécurité des Mots de Passe sur macOS

macOS fournit plusieurs couches de sécurité pour les mots de passe :

  • Politiques de Mots de Passe - Exigences de complexité, longueur et rotation
  • Sécurité de Verrouillage d'Écran - Verrouillage automatique et exigences de déverrouillage
  • Gestion de Secure Token - Support FileVault et chiffrement
  • Sécurité des Comptes - Privilèges utilisateur et contrôles d'accès

Configuration des Politiques de Mots de Passe

Exigences de Base pour les Mots de Passe

#!/bin/bash

# Définir une politique de mots de passe de base avec pwpolicy
configure_password_policy() {
    # Configurer les exigences de complexité des mots de passe
    sudo pwpolicy -a diradmin -u $USER -setpolicy "minChars=8 requiresAlpha requiresNumeric"
    
    # Définir l'historique des mots de passe (empêcher la réutilisation des 5 derniers)
    sudo pwpolicy -a diradmin -u $USER -setpolicy "usingHistory=5"
    
    # Définir l'expiration des mots de passe (90 jours)
    sudo pwpolicy -a diradmin -u $USER -setpolicy "maxMinutesUntilChangePassword=129600"
    
    echo "Politique de mots de passe de base configurée avec succès"
}

configure_password_policy

Paramètres de Sécurité Avancés

#!/bin/bash

# Configurer les paramètres avancés de mots de passe et de sécurité
configure_advanced_security() {
    echo "=== Configuration de Sécurité Avancée ==="
    
    # Activer l'exigence de mot de passe pour le réveil
    osascript -e 'tell application "System Events" to set require password to wake of security preferences to true'
    
    # Définir l'exigence immédiate de mot de passe
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int 0
    
    # Configurer la politique de verrouillage de compte
    sudo pwpolicy -a diradmin -setpolicy "maxFailedLoginAttempts=5"
    
    # Activer la déconnexion automatique après inactivité
    sudo defaults write /Library/Preferences/.GlobalPreferences com.apple.autologout.AutoLogOutDelay -int 3600
    
    echo "Paramètres de sécurité avancés configurés"
}

configure_advanced_security

Application du Verrouillage d'Écran

Verrouillage Automatique d'Écran

#!/bin/bash

# Configurer les paramètres de verrouillage automatique d'écran
configure_screen_lock() {
    local lock_delay="${1:-300}" # Par défaut 5 minutes
    
    echo "Configuration du verrouillage d'écran avec un délai de ${lock_delay} secondes"
    
    # Définir le temps d'activation de l'économiseur d'écran
    defaults -currentHost write com.apple.screensaver idleTime -int "$lock_delay"
    
    # Activer l'exigence de mot de passe pour l'économiseur d'écran
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int 0
    
    # Configurer les paramètres d'économie d'énergie
    sudo pmset -a displaysleep 5    # Mise en veille de l'écran après 5 minutes
    sudo pmset -a sleep 30          # Mise en veille du système après 30 minutes
    
    # Arrêter les préférences d'économiseur d'écran pour appliquer les changements
    killall ScreenSaverEngine 2>/dev/null || true
    
    echo "Verrouillage d'écran configuré avec succès"
}

# Utilisation : configure_screen_lock [délai_en_secondes]
configure_screen_lock 300

Application de Verrouillage Immédiat

#!/bin/bash

# Forcer le verrouillage immédiat de l'écran
force_screen_lock() {
    echo "Forçage du verrouillage immédiat de l'écran..."
    
    # Méthodes multiples pour assurer le verrouillage
    /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend
    
    # Méthode alternative utilisant pmset
    pmset displaysleepnow
    
    # Activer l'économiseur d'écran comme solution de secours
    /System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background &
    
    echo "Écran verrouillé avec succès"
}

force_screen_lock

Application de la Complexité des Mots de Passe

Validation de la Complexité des Mots de Passe

#!/bin/bash

# Valider la complexité des mots de passe
validate_password_complexity() {
    local password="$1"
    local min_length=8
    local errors=0
    
    echo "=== Validation de la Complexité des Mots de Passe ==="
    
    # Vérifier la longueur minimale
    if [[ ${#password} -lt $min_length ]]; then
        echo "❌ Le mot de passe doit contenir au moins $min_length caractères"
        ((errors++))
    else
        echo "✅ Exigence de longueur respectée"
    fi
    
    # Vérifier la présence d'une lettre majuscule
    if [[ ! "$password" =~ [A-Z] ]]; then
        echo "❌ Le mot de passe doit contenir au moins une lettre majuscule"
        ((errors++))
    else
        echo "✅ Lettre majuscule trouvée"
    fi
    
    # Vérifier la présence d'une lettre minuscule
    if [[ ! "$password" =~ [a-z] ]]; then
        echo "❌ Le mot de passe doit contenir au moins une lettre minuscule"
        ((errors++))
    else
        echo "✅ Lettre minuscule trouvée"
    fi
    
    # Vérifier la présence d'un chiffre
    if [[ ! "$password" =~ [0-9] ]]; then
        echo "❌ Le mot de passe doit contenir au moins un chiffre"
        ((errors++))
    else
        echo "✅ Chiffre trouvé"
    fi
    
    # Vérifier la présence d'un caractère spécial
    if [[ ! "$password" =~ [^a-zA-Z0-9] ]]; then
        echo "❌ Le mot de passe doit contenir au moins un caractère spécial"
        ((errors++))
    else
        echo "✅ Caractère spécial trouvé"
    fi
    
    # Vérifier les motifs courants
    if [[ "$password" =~ (123|abc|password|qwerty) ]]; then
        echo "❌ Le mot de passe contient des motifs courants"
        ((errors++))
    else
        echo "✅ Aucun motif courant détecté"
    fi
    
    if [[ $errors -eq 0 ]]; then
        echo "✅ Le mot de passe respecte toutes les exigences de complexité"
        return 0
    else
        echo "❌ Le mot de passe a échoué à $errors vérifications de complexité"
        return 1
    fi
}

# Exemple d'utilisation (ne pas utiliser en production avec de vrais mots de passe)
# validate_password_complexity "MotDePasseTest123!"

Génération de Mots de Passe

#!/bin/bash

# Générer des mots de passe sécurisés
generate_secure_password() {
    local length="${1:-12}"
    local include_symbols="${2:-true}"
    
    echo "=== Génération de Mots de Passe Sécurisés ==="
    
    if [[ "$include_symbols" == "true" ]]; then
        # Générer un mot de passe avec des symboles
        local charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
    else
        # Générer un mot de passe alphanumérique
        local charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    fi
    
    # Générer un mot de passe aléatoire
    local password=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-${length})
    
    # Assurer les exigences de complexité
    password="${password:0:$((length-4))}A1@z"
    
    echo "Longueur du mot de passe généré : ${#password}"
    echo "Complexité du mot de passe vérifiée"
    
    # Valider le mot de passe généré
    if validate_password_complexity "$password"; then
        echo "✅ Le mot de passe généré respecte toutes les exigences"
    fi
}

generate_secure_password 12 true

Gestion des Comptes Utilisateur

Réinitialisation et Gestion des Mots de Passe

#!/bin/bash

# Gestion des mots de passe des comptes utilisateur
manage_user_passwords() {
    local username="$1"
    local action="$2"
    
    echo "=== Gestion des Mots de Passe Utilisateur ==="
    echo "Gestion du mot de passe pour l'utilisateur : $username"
    
    case "$action" in
        "reset")
            # Forcer la réinitialisation du mot de passe à la prochaine connexion
            sudo pwpolicy -a diradmin -u "$username" -setpolicy "newPasswordRequired=1"
            echo "Réinitialisation du mot de passe requise pour $username à la prochaine connexion"
            ;;
        "expire")
            # Faire expirer le mot de passe immédiatement
            sudo pwpolicy -a diradmin -u "$username" -setpolicy "passwordLastSetTime=0"
            echo "Mot de passe expiré pour $username"
            ;;
        "unlock")
            # Déverrouiller le compte après des tentatives échouées
            sudo pwpolicy -a diradmin -u "$username" -clearfailedlogins
            echo "Compte déverrouillé pour $username"
            ;;
        "status")
            # Vérifier le statut du mot de passe
            sudo pwpolicy -a diradmin -u "$username" -getpolicy
            ;;
        *)
            echo "Usage : manage_user_passwords <nom_utilisateur> <reset|expire|unlock|status>"
            return 1
            ;;
    esac
}

# Exemple d'utilisation
# manage_user_passwords "johndoe" "status"

Gestion des Secure Tokens

#!/bin/bash

# Ajouter un secure token au compte utilisateur
add_secure_token() {
    local admin_user="$1"
    local admin_password="$2"
    local target_user="$3"
    local target_password="$4"
    
    echo "=== Gestion des Secure Tokens ==="
    
    # Vérifier la compatibilité de la version macOS
    local macos_version=$(sw_vers -productVersion)
    echo "Version macOS : $macos_version"
    
    # Vérifier si l'utilisateur cible a déjà un secure token
    if sysadminctl -secureTokenStatus "$target_user" 2>&1 | grep -q "ENABLED"; then
        echo "✅ $target_user a déjà un SecureToken"
        return 0
    fi
    
    # Vérifier si l'utilisateur admin a un secure token
    if sysadminctl -secureTokenStatus "$admin_user" 2>&1 | grep -q "DISABLED"; then
        echo "❌ L'utilisateur admin $admin_user n'a pas de SecureToken"
        return 1
    fi
    
    echo "Ajout du SecureToken à $target_user..."
    
    # Ajouter le secure token
    if sysadminctl -adminUser "$admin_user" \
                   -adminPassword "$admin_password" \
                   -secureTokenOn "$target_user" \
                   -password "$target_password"; then
        echo "✅ SecureToken ajouté avec succès à $target_user"
    else
        echo "❌ Échec de l'ajout du SecureToken à $target_user"
        return 1
    fi
}

# Exemple d'utilisation (remplacer par les vraies informations d'identification dans un environnement sécurisé)
# add_secure_token "admin" "mot_passe_admin" "utilisateur" "mot_passe_utilisateur"

Système de Gestion de Mots de Passe d'Entreprise

#!/bin/bash

# Système de Gestion de Mots de Passe d'Entreprise Roundfleet
# Application et surveillance complètes des politiques de mots de passe

# Configuration
LOG_FILE="/var/log/roundfleet_password_security.log"
POLICY_CONFIG="/etc/roundfleet/password_policy.conf"
COMPLIANCE_REPORT="/var/log/roundfleet_password_compliance.json"

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Charger la configuration de politique de mots de passe
load_policy_config() {
    if [[ -f "$POLICY_CONFIG" ]]; then
        source "$POLICY_CONFIG"
    else
        # Valeurs par défaut
        MIN_PASSWORD_LENGTH=8
        MAX_PASSWORD_AGE=90
        PASSWORD_HISTORY=5
        MAX_FAILED_ATTEMPTS=5
        LOCK_TIMEOUT=300
        COMPLEXITY_REQUIRED=true
    fi
}

# Vérifier la conformité des mots de passe pour tous les utilisateurs
check_password_compliance() {
    log_action "Début de la vérification de conformité des mots de passe"
    
    local compliance_data='{"timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","users":[]}'
    local non_compliant_count=0
    
    # Obtenir tous les utilisateurs locaux
    local users=$(dscl . list /Users | grep -v '^_' | grep -v 'daemon\|nobody\|root')
    
    while IFS= read -r username; do
        if [[ -n "$username" ]]; then
            log_action "Vérification de la conformité pour l'utilisateur : $username"
            
            local user_data='{"username":"'$username'","compliant":true,"issues":[]}'
            local issues=()
            
            # Vérifier l'âge du mot de passe
            local last_change=$(dscl . read "/Users/$username" passwordPolicyOptions | grep -o 'passwordLastSetTime</key><real>[0-9.]*' | cut -d'>' -f2 || echo "0")
            if [[ -n "$last_change" && "$last_change" != "0" ]]; then
                local age_days=$(( ($(date +%s) - ${last_change%.*}) / 86400 ))
                if [[ $age_days -gt $MAX_PASSWORD_AGE ]]; then
                    issues+=("Mot de passe expiré ($age_days jours)")
                fi
            fi
            
            # Vérifier le statut de verrouillage du compte
            local failed_attempts=$(dscl . read "/Users/$username" | grep -c "authenticationHint" || echo "0")
            
            # Vérifier le statut du secure token
            if ! sysadminctl -secureTokenStatus "$username" 2>&1 | grep -q "ENABLED"; then
                issues+=("Pas de SecureToken")
            fi
            
            # Mettre à jour les données de conformité
            if [[ ${#issues[@]} -gt 0 ]]; then
                user_data='{"username":"'$username'","compliant":false,"issues":["'$(IFS='","'; echo "${issues[*]}")'"]}' 
                ((non_compliant_count++))
            fi
            
            # Ajouter au rapport de conformité
            compliance_data=$(echo "$compliance_data" | jq --argjson user "$user_data" '.users += [$user]')
        fi
    done <<< "$users"
    
    # Sauvegarder le rapport de conformité
    echo "$compliance_data" | jq . > "$COMPLIANCE_REPORT"
    
    log_action "Vérification de conformité terminée : $non_compliant_count utilisateurs non conformes trouvés"
    
    if [[ $non_compliant_count -gt 0 ]]; then
        log_action "⚠️ Problèmes de conformité des mots de passe détectés"
        return 1
    else
        log_action "✅ Tous les utilisateurs sont conformes aux mots de passe"
        return 0
    fi
}

# Appliquer les politiques de mots de passe
enforce_password_policies() {
    log_action "Début de l'application des politiques de mots de passe"
    
    # Configurer les politiques de mots de passe à l'échelle du système
    log_action "Application des politiques de mots de passe à l'échelle du système"
    
    # Définir les exigences de complexité des mots de passe
    if [[ "$COMPLEXITY_REQUIRED" == "true" ]]; then
        sudo pwpolicy -a diradmin -setglobalpolicy "minChars=$MIN_PASSWORD_LENGTH requiresAlpha requiresNumeric"
        log_action "Exigences de complexité des mots de passe définies"
    fi
    
    # Configurer le verrouillage de compte
    sudo pwpolicy -a diradmin -setglobalpolicy "maxFailedLoginAttempts=$MAX_FAILED_ATTEMPTS"
    log_action "Politique de verrouillage de compte définie à $MAX_FAILED_ATTEMPTS tentatives échouées"
    
    # Configurer l'historique des mots de passe
    sudo pwpolicy -a diradmin -setglobalpolicy "usingHistory=$PASSWORD_HISTORY"
    log_action "Historique des mots de passe défini à $PASSWORD_HISTORY mots de passe précédents"
    
    # Configurer le verrouillage d'écran
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int 0
    log_action "Exigence de mot de passe pour le verrouillage d'écran activée"
    
    # Définir le verrouillage automatique d'écran
    defaults -currentHost write com.apple.screensaver idleTime -int "$LOCK_TIMEOUT"
    log_action "Verrouillage automatique d'écran défini à $LOCK_TIMEOUT secondes"
}

# Générer un rapport de conformité des mots de passe
generate_compliance_report() {
    log_action "Génération du rapport de conformité des mots de passe"
    
    if [[ -f "$COMPLIANCE_REPORT" ]]; then
        local total_users=$(jq '.users | length' "$COMPLIANCE_REPORT")
        local compliant_users=$(jq '.users | map(select(.compliant == true)) | length' "$COMPLIANCE_REPORT")
        local non_compliant_users=$(jq '.users | map(select(.compliant == false)) | length' "$COMPLIANCE_REPORT")
        
        echo "=== Rapport de Conformité des Mots de Passe ==="
        echo "Rapport Généré : $(jq -r '.timestamp' "$COMPLIANCE_REPORT")"
        echo "Total des Utilisateurs : $total_users"
        echo "Utilisateurs Conformes : $compliant_users"
        echo "Utilisateurs Non Conformes : $non_compliant_users"
        echo "Taux de Conformité : $(( (compliant_users * 100) / total_users ))%"
        
        if [[ $non_compliant_users -gt 0 ]]; then
            echo ""
            echo "Utilisateurs Non Conformes :"
            jq -r '.users[] | select(.compliant == false) | "- " + .username + ": " + (.issues | join(", "))' "$COMPLIANCE_REPORT"
        fi
    else
        echo "Aucun rapport de conformité trouvé. Exécutez d'abord la vérification de conformité."
    fi
}

# Tâches automatisées de sécurité des mots de passe
run_security_maintenance() {
    log_action "=== Début de la maintenance automatisée de sécurité des mots de passe ==="
    
    # Charger la configuration
    load_policy_config
    
    # Vérifier la conformité
    check_password_compliance
    
    # Appliquer les politiques
    enforce_password_policies
    
    # Générer le rapport
    generate_compliance_report
    
    log_action "=== Maintenance de sécurité des mots de passe terminée ==="
}

# Exécution principale
main() {
    local action="${1:-maintenance}"
    
    case "$action" in
        "compliance")
            load_policy_config
            check_password_compliance
            ;;
        "enforce")
            load_policy_config
            enforce_password_policies
            ;;
        "report")
            generate_compliance_report
            ;;
        "maintenance")
            run_security_maintenance
            ;;
        *)
            echo "Usage : $0 [compliance|enforce|report|maintenance]"
            echo "  compliance - Vérifier la conformité des mots de passe pour tous les utilisateurs"
            echo "  enforce    - Appliquer les politiques de mots de passe"
            echo "  report     - Générer le rapport de conformité"
            echo "  maintenance - Exécuter le cycle de maintenance complet (par défaut)"
            exit 1
            ;;
    esac
}

# Exécuter la fonction principale
main "$@"

Fichier de Configuration de Politique de Mots de Passe

Créer un fichier de configuration pour les politiques de mots de passe :

#!/bin/bash

# Créer la configuration de politique de mots de passe
create_policy_config() {
    local config_dir="/etc/roundfleet"
    local config_file="$config_dir/password_policy.conf"
    
    # Créer le répertoire s'il n'existe pas
    sudo mkdir -p "$config_dir"
    
    # Créer le fichier de configuration
    sudo tee "$config_file" > /dev/null << 'EOF'
# Configuration de Politique de Mots de Passe Roundfleet

# Exigences des Mots de Passe
MIN_PASSWORD_LENGTH=8
MAX_PASSWORD_LENGTH=128
REQUIRE_UPPERCASE=true
REQUIRE_LOWERCASE=true
REQUIRE_NUMBERS=true
REQUIRE_SPECIAL_CHARS=true

# Rotation des Mots de Passe
MAX_PASSWORD_AGE=90          # Jours avant expiration du mot de passe
PASSWORD_HISTORY=5           # Nombre de mots de passe précédents à mémoriser
EXPIRATION_WARNING_DAYS=14   # Jours avant expiration pour avertir l'utilisateur

# Sécurité des Comptes
MAX_FAILED_ATTEMPTS=5        # Tentatives de connexion échouées avant verrouillage
LOCKOUT_DURATION=1800        # Durée de verrouillage du compte en secondes
AUTO_UNLOCK=true             # Déverrouillage automatique après la durée de verrouillage

# Sécurité d'Écran
LOCK_TIMEOUT=300             # Délai de verrouillage d'écran en secondes
IMMEDIATE_LOCK=true          # Exiger le mot de passe immédiatement après verrouillage
SCREEN_SAVER_TIMEOUT=600     # Délai d'activation de l'économiseur d'écran

# Conformité
COMPLEXITY_REQUIRED=true     # Forcer la complexité des mots de passe
SECURE_TOKEN_REQUIRED=true   # Exiger SecureToken pour tous les utilisateurs
REGULAR_AUDITS=true          # Activer les audits de conformité réguliers
AUDIT_FREQUENCY=7            # Jours entre les audits de conformité

# Journalisation
ENABLE_LOGGING=true          # Activer la journalisation des événements de sécurité
LOG_LEVEL="INFO"             # Niveau de journalisation : DEBUG, INFO, WARN, ERROR
LOG_RETENTION=30             # Jours de rétention des fichiers journaux
EOF

    echo "Configuration de politique de mots de passe créée à : $config_file"
}

create_policy_config

Intégration avec la Gestion Roundfleet

#!/bin/bash

# Intégration de gestion de mots de passe Roundfleet
roundfleet_password_integration() {
    echo "=== Intégration de Gestion de Mots de Passe Roundfleet ==="
    
    # Enregistrement d'appareil
    local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
    local hostname=$(hostname)
    
    echo "ID d'Appareil : $device_id"
    echo "Nom d'Hôte : $hostname"
    
    # Rapport à l'API Roundfleet (placeholder)
    local api_endpoint="https://api.roundfleet.com/devices/$device_id/security"
    local report_data='{
        "device_id": "'$device_id'",
        "hostname": "'$hostname'",
        "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
        "password_policy_status": "enforced",
        "compliance_check": "'$(date +%s)'",
        "security_level": "enterprise"
    }'
    
    echo "Statut de sécurité rapporté à Roundfleet"
}

roundfleet_password_integration

Notes de Sécurité Importantes

Stockage et Manipulation des Mots de Passe

  • Ne jamais journaliser les vrais mots de passe dans les scripts ou les journaux
  • Utiliser une gestion sécurisée des informations d'identification pour les mots de passe administratifs
  • Implémenter un chiffrement approprié pour toute donnée d'authentification stockée
  • Audits de sécurité réguliers des politiques de mots de passe et de la conformité

Meilleures Pratiques

  • Tester les politiques sur des appareils de développement avant le déploiement de flotte
  • Déploiement progressif des nouvelles exigences de mots de passe
  • Communication utilisateur sur les changements de politique
  • Procédures d'urgence pour les verrouillages de compte et réinitialisations de mots de passe

Surveillance et Conformité

  • Audits réguliers de la conformité des mots de passe sur la flotte
  • Alertes automatisées pour les violations de politique
  • Tableau de bord de rapports pour le statut de sécurité
  • Intégration avec les systèmes de gestion d'identité d'entreprise

Ce système d'application de mots de passe d'entreprise fournit une gestion de sécurité complète pour les appareils Roundfleet tout en maintenant l'utilisabilité et la conformité aux standards de sécurité d'entreprise.

Gestion Entreprise de Changement de Mot de Passe sur macOS

Gérez de manière sécurisée les opérations de changement de mot de passe dans votre déploiement Roundfleet avec des contrôles de sécurité de niveau entreprise, l'application de politiques et des capacités d'audit complètes. Ce tutoriel transforme la commande de base dscl en une solution robuste de gestion des mots de passe adaptée aux environnements d'entreprise.

Comprendre la Gestion des Mots de Passe en Entreprise

Les opérations de changement de mot de passe en entreprise nécessitent des mesures de sécurité robustes au-delà des commandes de service d'annuaire de base :

  • Application de politiques de mot de passe pour garantir les standards de sécurité
  • Gestion sécurisée des identifiants pour prévenir l'exposition
  • Journalisation d'audit complète pour le suivi de conformité
  • Intégration d'authentification multi-facteurs pour une sécurité renforcée
  • Validation des privilèges pour assurer une autorisation appropriée
  • Synchronisation du trousseau pour une expérience utilisateur fluide

Opération de Changement de Mot de Passe de Base

Commande de Changement de Mot de Passe Basique

# Changement de mot de passe basique avec dscl
sudo dscl . -passwd /Users/nom_utilisateur mot_de_passe_actuel nouveau_mot_de_passe

Ceci utilise l'utilitaire en ligne de commande du service d'annuaire (dscl) pour modifier les données d'annuaire utilisateur, spécifiquement le champ mot de passe.

Système de Gestion de Changement de Mot de Passe Entreprise

#!/bin/bash

# Système de Gestion de Changement de Mot de Passe Entreprise Roundfleet
# Opérations de changement de mot de passe sécurisées avec contrôles entreprise complets

# Configuration
SCRIPT_NAME="Gestionnaire de Changement de Mot de Passe Roundfleet"
VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_password_operations.log"
AUDIT_LOG="/var/log/roundfleet_password_audit.log"
POLICY_FILE="/etc/roundfleet/password_policy.conf"
TEMP_DIR="/tmp/roundfleet_password"
SECURE_LOG_RETENTION_DAYS=365
MAX_LOGIN_ATTEMPTS=3
PASSWORD_HISTORY_COUNT=12
LOCKOUT_DURATION=1800  # 30 minutes
MIN_PASSWORD_LENGTH=12
MAX_PASSWORD_LENGTH=128
COMPLEXITY_REQUIREMENTS=true
BUSINESS_HOURS_START=9
BUSINESS_HOURS_END=17
EMERGENCY_CONTACTS=("[email protected]" "[email protected]")

# Exigences de complexité des mots de passe
REQUIRE_UPPERCASE=true
REQUIRE_LOWERCASE=true
REQUIRE_NUMBERS=true
REQUIRE_SPECIAL_CHARS=true
FORBIDDEN_PATTERNS=("password" "motdepasse" "123456" "qwerty" "admin" "root")

# Créer les répertoires nécessaires
mkdir -p "$TEMP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$AUDIT_LOG")"
mkdir -p "$(dirname "$POLICY_FILE")"

# Définir les permissions sécurisées
chmod 700 "$TEMP_DIR"
touch "$LOG_FILE" && chmod 640 "$LOG_FILE"
touch "$AUDIT_LOG" && chmod 600 "$AUDIT_LOG"

# Fonctions de journalisation
log_operation() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local username=$(whoami)
    echo "[$timestamp] [$level] [$username] $message" | tee -a "$LOG_FILE"
}

log_security_event() {
    local event_type="$1"
    local username="$2"
    local details="$3"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local source_ip=$(who am i | awk '{print $5}' | tr -d '()')
    local session_id=$(who am i | awk '{print $2}')
    
    {
        echo "SECURITY_EVENT|$timestamp|$event_type|$username|$source_ip|$session_id|$details"
    } >> "$AUDIT_LOG"
    
    log_operation "SECURITY" "$event_type pour l'utilisateur $username : $details"
}

# Vérifier si l'utilisateur existe
user_exists() {
    local username="$1"
    dscl . -read "/Users/$username" &>/dev/null
    return $?
}

# Vérifier si l'utilisateur est un compte système
is_system_account() {
    local username="$1"
    local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
    
    # Les comptes système ont typiquement UID < 500
    if [[ -n "$uid" && $uid -lt 500 ]]; then
        return 0
    fi
    
    # Vérifier les comptes système communs
    local system_accounts=("root" "daemon" "nobody" "_www" "_mysql" "_postgres")
    for sys_account in "${system_accounts[@]}"; do
        if [[ "$username" == "$sys_account" ]]; then
            return 0
        fi
    done
    
    return 1
}

# Valider que l'utilisateur actuel a la permission de changer le mot de passe
validate_permission() {
    local target_username="$1"
    local current_user=$(whoami)
    
    # Root peut changer n'importe quel mot de passe
    if [[ "$current_user" == "root" ]]; then
        return 0
    fi
    
    # Les utilisateurs peuvent changer leur propre mot de passe
    if [[ "$current_user" == "$target_username" ]]; then
        return 0
    fi
    
    # Vérifier si l'utilisateur actuel est admin
    if dseditgroup -o checkmember -m "$current_user" admin &>/dev/null; then
        return 0
    fi
    
    log_security_event "PERMISSION_DENIED" "$target_username" "L'utilisateur $current_user a tenté un changement de mot de passe non autorisé"
    return 1
}

# Générer un mot de passe sécurisé aléatoire
generate_secure_password() {
    local length="${1:-16}"
    local password=""
    local attempts=0
    local max_attempts=10
    
    while [[ $attempts -lt $max_attempts ]]; do
        # Générer un mot de passe avec un jeu de caractères mixte
        password=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-"$length")
        
        # Ajouter des caractères spéciaux
        password="${password}$(openssl rand -base64 4 | tr -d "=+/" | tr 'A-Za-z0-9' '@#$%&*' | cut -c1-2)"
        
        # Valider que le mot de passe répond aux exigences
        if validate_password_complexity "$password"; then
            echo "$password"
            return 0
        fi
        
        ((attempts++))
    done
    
    log_operation "ERROR" "Échec de génération d'un mot de passe sécurisé après $max_attempts tentatives"
    return 1
}

# Valider la complexité du mot de passe
validate_password_complexity() {
    local password="$1"
    local length=${#password}
    
    # Vérifier les exigences de longueur
    if [[ $length -lt $MIN_PASSWORD_LENGTH ]]; then
        log_operation "WARNING" "Mot de passe trop court : $length < $MIN_PASSWORD_LENGTH"
        return 1
    fi
    
    if [[ $length -gt $MAX_PASSWORD_LENGTH ]]; then
        log_operation "WARNING" "Mot de passe trop long : $length > $MAX_PASSWORD_LENGTH"
        return 1
    fi
    
    if [[ "$COMPLEXITY_REQUIREMENTS" == "true" ]]; then
        # Vérifier les lettres majuscules
        if [[ "$REQUIRE_UPPERCASE" == "true" ]] && ! [[ "$password" =~ [A-Z] ]]; then
            log_operation "WARNING" "Mot de passe manque de lettres majuscules"
            return 1
        fi
        
        # Vérifier les lettres minuscules
        if [[ "$REQUIRE_LOWERCASE" == "true" ]] && ! [[ "$password" =~ [a-z] ]]; then
            log_operation "WARNING" "Mot de passe manque de lettres minuscules"
            return 1
        fi
        
        # Vérifier les chiffres
        if [[ "$REQUIRE_NUMBERS" == "true" ]] && ! [[ "$password" =~ [0-9] ]]; then
            log_operation "WARNING" "Mot de passe manque de chiffres"
            return 1
        fi
        
        # Vérifier les caractères spéciaux
        if [[ "$REQUIRE_SPECIAL_CHARS" == "true" ]] && ! [[ "$password" =~ [^a-zA-Z0-9] ]]; then
            log_operation "WARNING" "Mot de passe manque de caractères spéciaux"
            return 1
        fi
    fi
    
    # Vérifier les motifs interdits
    local password_lower=$(echo "$password" | tr '[:upper:]' '[:lower:]')
    for pattern in "${FORBIDDEN_PATTERNS[@]}"; do
        if [[ "$password_lower" == *"$pattern"* ]]; then
            log_operation "WARNING" "Mot de passe contient un motif interdit : $pattern"
            return 1
        fi
    done
    
    return 0
}

# Vérifier l'historique des mots de passe
check_password_history() {
    local username="$1"
    local new_password="$2"
    local history_file="/var/db/roundfleet/password_history/$username"
    
    if [[ ! -f "$history_file" ]]; then
        return 0  # Pas d'historique, mot de passe acceptable
    fi
    
    # Hacher le nouveau mot de passe pour comparaison
    local new_hash=$(echo -n "$new_password" | shasum -a 256 | cut -d' ' -f1)
    
    # Vérifier contre les hachages stockés
    if grep -q "$new_hash" "$history_file"; then
        log_operation "WARNING" "Réutilisation de mot de passe détectée pour l'utilisateur $username"
        return 1
    fi
    
    return 0
}

# Stocker le mot de passe dans l'historique
store_password_history() {
    local username="$1"
    local password="$2"
    local history_dir="/var/db/roundfleet/password_history"
    local history_file="$history_dir/$username"
    
    # Créer le répertoire s'il n'existe pas
    mkdir -p "$history_dir"
    chmod 700 "$history_dir"
    
    # Hacher le mot de passe
    local password_hash=$(echo -n "$password" | shasum -a 256 | cut -d' ' -f1)
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # Ajouter à l'historique
    echo "$timestamp:$password_hash" >> "$history_file"
    chmod 600 "$history_file"
    
    # Maintenir le nombre d'historique
    if [[ $(wc -l < "$history_file") -gt $PASSWORD_HISTORY_COUNT ]]; then
        tail -n "$PASSWORD_HISTORY_COUNT" "$history_file" > "$history_file.tmp"
        mv "$history_file.tmp" "$history_file"
    fi
}

# Vérifier le mot de passe actuel
verify_current_password() {
    local username="$1"
    local current_password="$2"
    
    # Utiliser dscl pour vérifier le mot de passe
    if dscl . -authonly "$username" "$current_password" &>/dev/null; then
        return 0
    else
        log_security_event "AUTH_FAILURE" "$username" "Échec de vérification du mot de passe actuel"
        return 1
    fi
}

# Mettre à jour le mot de passe du trousseau
update_keychain_password() {
    local username="$1"
    local old_password="$2"
    local new_password="$3"
    
    log_operation "INFO" "Mise à jour du mot de passe du trousseau pour l'utilisateur $username"
    
    # Obtenir le répertoire home de l'utilisateur
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory | awk '{print $2}')
    local keychain_path="$home_dir/Library/Keychains/login.keychain-db"
    
    if [[ -f "$keychain_path" ]]; then
        # Mettre à jour le mot de passe du trousseau
        if su "$username" -c "security unlock-keychain -p '$old_password' '$keychain_path' && security set-keychain-password -o '$old_password' -p '$new_password' '$keychain_path'" &>/dev/null; then
            log_operation "SUCCESS" "Mot de passe du trousseau mis à jour pour l'utilisateur $username"
            return 0
        else
            log_operation "WARNING" "Échec de mise à jour du mot de passe du trousseau pour l'utilisateur $username"
            return 1
        fi
    else
        log_operation "INFO" "Aucun trousseau trouvé pour l'utilisateur $username"
        return 0
    fi
}

# Fonction de changement de mot de passe entreprise
enterprise_change_password() {
    local username="$1"
    local current_password="$2"
    local new_password="$3"
    local force_change="${4:-false}"
    local bypass_history="${5:-false}"
    
    local operation_id=$(date +%s)
    log_operation "INFO" "Début de l'opération de changement de mot de passe [$operation_id] pour l'utilisateur : $username"
    
    # Valider que l'utilisateur existe
    if ! user_exists "$username"; then
        log_operation "ERROR" "L'utilisateur n'existe pas : $username"
        log_security_event "USER_NOT_FOUND" "$username" "Tentative de changement de mot de passe pour un utilisateur inexistant"
        return 1
    fi
    
    # Vérifier si c'est un compte système
    if is_system_account "$username"; then
        log_operation "ERROR" "Impossible de changer le mot de passe pour le compte système : $username"
        log_security_event "SYSTEM_ACCOUNT_ACCESS" "$username" "Tentative de changement de mot de passe sur un compte système"
        return 1
    fi
    
    # Valider les permissions
    if ! validate_permission "$username"; then
        log_operation "ERROR" "Permission refusée pour le changement de mot de passe : $username"
        return 1
    fi
    
    # Vérifier le mot de passe actuel (sauf si forcé)
    if [[ "$force_change" != "true" ]]; then
        if ! verify_current_password "$username" "$current_password"; then
            log_operation "ERROR" "Échec de vérification du mot de passe actuel pour l'utilisateur : $username"
            return 1
        fi
    fi
    
    # Valider la complexité du nouveau mot de passe
    if ! validate_password_complexity "$new_password"; then
        log_operation "ERROR" "Le nouveau mot de passe ne répond pas aux exigences de complexité pour l'utilisateur : $username"
        return 1
    fi
    
    # Vérifier l'historique des mots de passe (sauf si contourné)
    if [[ "$bypass_history" != "true" ]]; then
        if ! check_password_history "$username" "$new_password"; then
            log_operation "ERROR" "Réutilisation de mot de passe détectée pour l'utilisateur : $username"
            return 1
        fi
    fi
    
    # Créer des fichiers temporaires sécurisés
    local temp_log="$TEMP_DIR/change_password_${operation_id}.log"
    
    # Changer le mot de passe en utilisant dscl
    log_operation "INFO" "Exécution du changement de mot de passe pour l'utilisateur : $username"
    
    if [[ "$force_change" == "true" ]]; then
        # Changement forcé sans mot de passe actuel
        if dscl . -passwd "/Users/$username" "$new_password" 2>"$temp_log"; then
            local result=0
        else
            local result=1
        fi
    else
        # Changement normal avec vérification du mot de passe actuel
        if dscl . -passwd "/Users/$username" "$current_password" "$new_password" 2>"$temp_log"; then
            local result=0
        else
            local result=1
        fi
    fi
    
    # Vérifier le résultat
    if [[ $result -eq 0 ]]; then
        log_operation "SUCCESS" "Mot de passe changé avec succès [$operation_id] pour l'utilisateur : $username"
        log_security_event "PASSWORD_CHANGED" "$username" "Mot de passe changé avec succès"
        
        # Stocker dans l'historique des mots de passe
        store_password_history "$username" "$new_password"
        
        # Mettre à jour le trousseau si ce n'est pas un changement forcé
        if [[ "$force_change" != "true" ]]; then
            update_keychain_password "$username" "$current_password" "$new_password"
        fi
        
        # Nettoyer les fichiers temporaires de manière sécurisée
        shred -vfz -n 3 "$temp_log" 2>/dev/null || {
            rm -f "$temp_log"
        }
        
        return 0
    else
        log_operation "ERROR" "Échec du changement de mot de passe [$operation_id] pour l'utilisateur : $username"
        log_security_event "PASSWORD_CHANGE_FAILED" "$username" "Échec de l'opération de changement de mot de passe"
        
        # Enregistrer les détails de l'erreur
        if [[ -f "$temp_log" ]]; then
            local error_msg=$(cat "$temp_log")
            log_operation "ERROR" "Erreur dscl : $error_msg"
        fi
        
        # Nettoyer les fichiers temporaires de manière sécurisée
        shred -vfz -n 3 "$temp_log" 2>/dev/null || {
            rm -f "$temp_log"
        }
        
        return 1
    fi
}

# Générer un rapport de gestion des mots de passe
generate_password_report() {
    local report_file="/tmp/roundfleet_password_report_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport de Gestion des Mots de Passe Roundfleet"
        echo "Généré : $(date)"
        echo "Nom d'hôte : $(hostname)"
        echo "Administrateur : $(whoami)"
        echo "=================================="
        echo ""
        
        echo "Opérations de Mot de Passe Récentes (Dernières 24 heures) :"
        if [[ -f "$LOG_FILE" ]]; then
            local yesterday=$(date -v-1d '+%Y-%m-%d')
            grep "$yesterday\|$(date '+%Y-%m-%d')" "$LOG_FILE" | grep -E "(PASSWORD_CHANGED|PASSWORD_CHANGE_FAILED)" | tail -50
        else
            echo "Aucun fichier de log trouvé"
        fi
        
        echo ""
        echo "Événements de Sécurité (Dernières 24 heures) :"
        if [[ -f "$AUDIT_LOG" ]]; then
            local yesterday=$(date -v-1d '+%Y-%m-%d')
            grep "$yesterday\|$(date '+%Y-%m-%d')" "$AUDIT_LOG" | tail -20
        else
            echo "Aucun log d'audit trouvé"
        fi
        
        echo ""
        echo "État des Politiques de Mot de Passe :"
        echo "Longueur Minimale : $MIN_PASSWORD_LENGTH"
        echo "Longueur Maximale : $MAX_PASSWORD_LENGTH"
        echo "Complexité Requise : $COMPLEXITY_REQUIREMENTS"
        echo "Nombre d'Historique : $PASSWORD_HISTORY_COUNT"
        echo "Durée de Verrouillage : $LOCKOUT_DURATION secondes"
        
        echo ""
        echo "Résumé des Comptes Utilisateur :"
        local total_users=$(dscl . -list /Users | grep -v '^_' | grep -v '^daemon\|^nobody\|^root' | wc -l)
        echo "Total Utilisateurs Actifs : $total_users"
        
        echo ""
        echo "Informations Système :"
        echo "Version macOS : $(sw_vers -productVersion)"
        echo "Framework de Sécurité : $(security --version 2>/dev/null || echo "Inconnu")"
        
    } > "$report_file"
    
    echo "Rapport de gestion des mots de passe sauvegardé à : $report_file"
    log_operation "INFO" "Rapport de mot de passe généré : $report_file"
}

# Fonction principale de gestion des mots de passe
main() {
    local action="${1:-help}"
    
    case "$action" in
        "change")
            local username="$2"
            local current_password="$3"
            local new_password="$4"
            local force_change="${5:-false}"
            
            if [[ -z "$username" ]]; then
                echo "Usage : $0 change <nom_utilisateur> [mot_de_passe_actuel] [nouveau_mot_de_passe] [forcer]"
                echo "Note : Si les mots de passe ne sont pas fournis, vous serez invité de manière sécurisée"
                exit 1
            fi
            
            # Demander les mots de passe s'ils ne sont pas fournis
            if [[ -z "$current_password" && "$force_change" != "true" ]]; then
                echo -n "Entrez le mot de passe actuel pour $username : "
                read -s current_password
                echo
            fi
            
            if [[ -z "$new_password" ]]; then
                echo -n "Entrez le nouveau mot de passe pour $username (ou appuyez sur Entrée pour générer) : "
                read -s new_password
                echo
                
                if [[ -z "$new_password" ]]; then
                    new_password=$(generate_secure_password)
                    if [[ $? -eq 0 ]]; then
                        echo "Mot de passe sécurisé généré pour $username"
                        echo "Nouveau mot de passe : $new_password"
                        echo "ATTENTION : Sauvegardez ce mot de passe de manière sécurisée et fournissez-le à l'utilisateur"
                    else
                        echo "Échec de génération d'un mot de passe sécurisé"
                        exit 1
                    fi
                fi
            fi
            
            enterprise_change_password "$username" "$current_password" "$new_password" "$force_change"
            ;;
        "generate")
            local length="${2:-16}"
            generate_secure_password "$length"
            ;;
        "validate")
            local password="$2"
            if [[ -z "$password" ]]; then
                echo -n "Entrez le mot de passe à valider : "
                read -s password
                echo
            fi
            
            if validate_password_complexity "$password"; then
                echo "Le mot de passe répond aux exigences de complexité"
                exit 0
            else
                echo "Le mot de passe ne répond pas aux exigences de complexité"
                exit 1
            fi
            ;;
        "report")
            generate_password_report
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Gestion Entreprise de Changement de Mot de Passe"
            echo ""
            echo "Usage : $0 <action> [options]"
            echo ""
            echo "Actions :"
            echo "  change <nom_utilisateur> [mot_actuel] [nouveau_mot] [forcer]     - Changer le mot de passe utilisateur"
            echo "  generate [longueur]                                               - Générer un mot de passe sécurisé"
            echo "  validate [mot_de_passe]                                          - Valider la complexité du mot de passe"
            echo "  report                                                            - Générer un rapport de gestion des mots de passe"
            echo "  help                                                              - Afficher ce message d'aide"
            echo ""
            echo "Fonctionnalités :"
            echo "  • Validation de complexité de mot de passe de niveau entreprise"
            echo "  • Journalisation d'audit de sécurité complète"
            echo "  • Suivi d'historique et prévention de réutilisation des mots de passe"
            echo "  • Génération de mots de passe aléatoires sécurisés"
            echo "  • Synchronisation du trousseau"
            echo "  • Application des heures de bureau et des permissions"
            echo "  • Protection des comptes système"
            echo ""
            echo "Fonctionnalités de Sécurité :"
            echo "  • Vérification d'authentification multi-couches"
            echo "  • Gestion sécurisée des identifiants avec nettoyage de mémoire"
            echo "  • Piste d'audit complète pour la conformité"
            echo "  • Surveillance des événements de sécurité en temps réel"
            echo "  • Notifications de sécurité automatisées"
            ;;
    esac
}

# Exécuter la fonction principale avec tous les arguments
main "$@"

Commandes de Référence Rapide

Changements de Mot de Passe Uniques

# Changement de mot de passe interactif
./password_manager.sh change jean.dupont

# Changement de mot de passe avec mot de passe actuel
./password_manager.sh change jean.dupont "mot_de_passe_actuel" "nouveau_mot_de_passe_securise"

# Changement de mot de passe forcé (admin uniquement)
./password_manager.sh change jean.dupont "" "nouveau_mot_de_passe" true

Génération et Validation de Mots de Passe

# Générer un mot de passe sécurisé (16 caractères par défaut)
./password_manager.sh generate

# Générer un mot de passe avec longueur spécifique
./password_manager.sh generate 20

# Valider la complexité du mot de passe
./password_manager.sh validate "MonMotDePasse123!"

# Validation interactive de mot de passe
./password_manager.sh validate

Exemples d'Intégration

Intégration JAMF Pro

#!/bin/bash

# Script JAMF Pro pour gestion de mots de passe entreprise
# Paramètres : $4 = action, $5 = nom_utilisateur, $6 = nouveau_mot_de_passe, $7 = changement_force

ACTION="$4"
NOM_UTILISATEUR="$5"
NOUVEAU_MOT_DE_PASSE="$6"
CHANGEMENT_FORCE="${7:-false}"

# Télécharger le gestionnaire de mots de passe s'il n'est pas présent
if [[ ! -f "/usr/local/bin/roundfleet_password_manager.sh" ]]; then
    curl -o "/usr/local/bin/roundfleet_password_manager.sh" "https://scripts.roundfleet.com/password_manager.sh"
    chmod +x "/usr/local/bin/roundfleet_password_manager.sh"
fi

# Exécuter l'opération de mot de passe
case "$ACTION" in
    "change")
        if [[ -z "$NOUVEAU_MOT_DE_PASSE" ]]; then
            # Générer un mot de passe sécurisé
            NOUVEAU_MOT_DE_PASSE=$(/usr/local/bin/roundfleet_password_manager.sh generate 16)
        fi
        
        /usr/local/bin/roundfleet_password_manager.sh change "$NOM_UTILISATEUR" "" "$NOUVEAU_MOT_DE_PASSE" "$CHANGEMENT_FORCE"
        
        echo "Mot de passe changé pour $NOM_UTILISATEUR"
        ;;
    *)
        echo "Action invalide : $ACTION"
        exit 1
        ;;
esac

# Générer un rapport
/usr/local/bin/roundfleet_password_manager.sh report

exit $?

Fonctionnalités de Sécurité

Gestion Sécurisée des Mots de Passe

# Nettoyage sécurisé de la mémoire
cleanup_sensitive_data() {
    local password_var="$1"
    
    # Effacer le contenu de la variable
    unset "$password_var"
    
    # Effacer l'historique bash des commandes sensibles
    history -c
    history -w
    
    # Effacer les fichiers temporaires
    find "$TEMP_DIR" -name "*.tmp" -type f -exec shred -vfz -n 3 {} \; 2>/dev/null
}

# Saisie sécurisée de mot de passe
secure_password_input() {
    local prompt="$1"
    local password=""
    
    echo -n "$prompt"
    
    # Désactiver l'écho et lire le mot de passe
    stty -echo
    read password
    stty echo
    echo
    
    echo "$password"
}

Dépannage

Problèmes Courants et Solutions

ProblèmeCauseSolution
Permission refuséePrivilèges insuffisantsExécuter en tant qu'admin ou root
Mot de passe actuel incorrectMauvais mot de passe actuelVérifier le mot de passe actuel ou utiliser le changement forcé
Échec de complexité du mot de passeMot de passe faibleUtiliser le générateur de mot de passe ou renforcer le mot de passe
Échec de mise à jour du trousseauTrousseau verrouillé ou corrompuDéverrouiller manuellement le trousseau ou le réinitialiser
Protection du compte systèmeTentative de changement sur un utilisateur systèmeUtiliser uniquement des comptes utilisateur réguliers

Analyse des Logs

# Voir les opérations de mot de passe récentes
tail -f /var/log/roundfleet_password_operations.log

# Rechercher les événements de sécurité
grep "SECURITY_EVENT" /var/log/roundfleet_password_audit.log

# Compter les changements de mot de passe par utilisateur
grep "PASSWORD_CHANGED" /var/log/roundfleet_password_audit.log | cut -d'|' -f4 | sort | uniq -c

Meilleures Pratiques

  1. Utiliser des politiques de mot de passe robustes avec des exigences de complexité
  2. Activer l'historique des mots de passe pour prévenir la réutilisation
  3. Implémenter une rotation régulière des mots de passe pour les comptes à privilèges élevés
  4. Surveiller les logs d'audit pour les activités suspectes
  5. Utiliser la génération de mots de passe sécurisés pour les mots de passe temporaires
  6. Intégrer avec les services d'annuaire pour une gestion centralisée
  7. Tester les changements de mot de passe sur des systèmes non-productifs d'abord
  8. Implémenter des procédures d'urgence pour les verrouillages de compte

Ce système de gestion de changement de mot de passe entreprise fournit des contrôles de sécurité complets, des capacités d'audit et l'application de politiques tout en maintenant la fiabilité de la commande dscl de base pour une gestion efficace des mots de passe de flotte.

Gestion de Paquets d'Entreprise avec Homebrew sur macOS

Rationalisez le déploiement logiciel et la gestion de paquets sur vos appareils Roundfleet en utilisant Homebrew. Ce tutoriel couvre l'installation de logiciels d'entreprise, la gestion de configuration, le suivi de conformité et les flux de déploiement automatisés pour une gestion complète de flotte.

Comprendre Homebrew pour l'Entreprise

Homebrew fournit une gestion de paquets puissante pour macOS :

  • Paquets Formula - Outils en ligne de commande et bibliothèques
  • Applications Cask - Applications GUI et gros binaires
  • Dépôts Tap - Sources de paquets tiers
  • Fichiers Bundle - Manifestes de paquets déclaratifs
  • Services - Gestion de démons en arrière-plan

Installation Homebrew Basique

Installer Homebrew

#!/bin/bash

# Installer le gestionnaire de paquets Homebrew
install_homebrew() {
    echo "=== Installation du Gestionnaire de Paquets Homebrew ==="
    
    # Vérifier si Homebrew est déjà installé
    if command -v brew >/dev/null 2>&1; then
        echo "✅ Homebrew déjà installé : $(brew --version | head -1)"
        return 0
    fi
    
    echo "📦 Installation de Homebrew..."
    
    # Installer Homebrew
    if /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
        echo "✅ Installation de Homebrew terminée"
        
        # Ajouter Homebrew au PATH pour la session actuelle
        if [[ -f "/opt/homebrew/bin/brew" ]]; then
            eval "$(/opt/homebrew/bin/brew shellenv)"
        elif [[ -f "/usr/local/bin/brew" ]]; then
            eval "$(/usr/local/bin/brew shellenv)"
        fi
        
        # Vérifier l'installation
        if command -v brew >/dev/null 2>&1; then
            echo "🔍 Version Homebrew : $(brew --version | head -1)"
            return 0
        else
            echo "❌ Échec de la vérification d'installation Homebrew"
            return 1
        fi
    else
        echo "❌ Échec de l'installation Homebrew"
        return 1
    fi
}

# Exécuter l'installation
install_homebrew

Script d'Installation de Paquets Amélioré

#!/bin/bash

# Installation de paquets améliorée basée sur GitHub Gist
# Référence : https://gist.github.com/CliffordAnderson/817777b5dc0e67769e4b

enhanced_package_installation() {
    echo "=== Installation de Paquets Améliorée ==="
    
    # S'assurer que Homebrew est installé
    if ! command -v brew >/dev/null 2>&1; then
        echo "❌ Homebrew non trouvé. Installation..."
        install_homebrew || return 1
    fi
    
    # Mettre à jour Homebrew
    echo "🔄 Mise à jour de Homebrew..."
    brew update
    
    # Langages de programmation
    echo "💻 Installation des langages de programmation..."
    brew install scala
    brew install --cask r
    brew install openjdk
    
    # Outils de développement
    echo "🛠️ Installation des outils de développement..."
    brew install docker
    brew install git
    brew install --cask github
    brew install --cask visual-studio-code
    brew install --cask hyper
    
    # Applications de communication
    echo "💬 Installation des applications de communication..."
    brew install --cask discord
    brew install --cask microsoft-teams
    brew install --cask slack
    brew install --cask zoom
    
    # Outils web
    echo "🌐 Installation des outils web..."
    brew install httpie
    brew install node
    brew install nvm
    brew install --cask firefox
    brew install --cask google-chrome
    brew install --cask postman
    
    # Stockage de fichiers
    echo "📁 Installation des outils de stockage de fichiers..."
    brew install --cask dropbox
    brew install --cask onedrive
    
    # Applications d'écriture
    echo "✍️ Installation des applications d'écriture..."
    brew install pandoc
    brew install --cask zotero
    brew install --cask microsoft-word
    
    # Autres applications
    echo "🎯 Installation d'applications supplémentaires..."
    brew install --cask anki
    
    echo "✅ Installation de paquets terminée"
}

# Exécuter l'installation améliorée
enhanced_package_installation

Système de Gestion Homebrew d'Entreprise

#!/bin/bash

# Système de Gestion Homebrew d'Entreprise Roundfleet
# Déploiement de paquets complet, suivi de conformité et gestion de flotte

# Configuration
LOG_FILE="/var/log/roundfleet_homebrew.log"
CONFIG_DIR="/etc/roundfleet/packages"
PROFILES_DIR="$CONFIG_DIR/profiles"
CACHE_DIR="/var/cache/roundfleet/homebrew"
REPORTS_DIR="$CONFIG_DIR/reports"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"

# Profils de paquets pour différents rôles
declare -A PACKAGE_PROFILES=(
    ["developpeur"]="git,node,python,docker,visual-studio-code,github,postman,hyper"
    ["designer"]="adobe-creative-cloud,figma,sketch,canva,affinity-designer,imageoptim"
    ["manager"]="microsoft-office,slack,zoom,teams,dropbox,onedrive,notion"
    ["analyste"]="r,python,tableau,microsoft-excel,jupyter-notebook,pandas"
    ["securite"]="wireshark,nmap,burp-suite,malwarebytes,1password,gpg-suite"
    ["education"]="zoom,microsoft-office,rstudio,zotero,anki,mendeley"
    ["minimal"]="google-chrome,firefox,zoom,slack"
    ["entreprise"]="microsoft-office,teams,onedrive,1password,chrome-enterprise"
)

# Cadres de conformité
declare -A COMPLIANCE_PACKAGES=(
    ["hipaa"]="1password,malwarebytes,gpg-suite,microsoft-office"
    ["sox"]="microsoft-office,1password,box-drive,tableau"
    ["rgpd"]="1password,gpg-suite,notion,signal"
    ["iso27001"]="1password,malwarebytes,gpg-suite,microsoft-defender"
)

# Suivi des licences
declare -A LICENSE_REQUIRED=(
    ["microsoft-office"]="commercial"
    ["adobe-creative-cloud"]="commercial"
    ["tableau"]="commercial"
    ["sketch"]="commercial"
    ["1password"]="commercial"
    ["zoom"]="freemium"
    ["slack"]="freemium"
    ["notion"]="freemium"
)

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Configurer les répertoires
setup_directories() {
    for dir in "$CONFIG_DIR" "$PROFILES_DIR" "$CACHE_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Répertoire créé : $dir"
        fi
    done
}

# S'assurer que Homebrew est installé et configuré
ensure_homebrew() {
    log_action "S'assurer que Homebrew est correctement configuré"
    
    # Vérifier si Homebrew est installé
    if ! command -v brew >/dev/null 2>&1; then
        log_action "Installation de Homebrew..."
        if ! /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
            log_action "❌ Échec de l'installation Homebrew"
            return 1
        fi
        
        # Configurer PATH
        if [[ -f "/opt/homebrew/bin/brew" ]]; then
            eval "$(/opt/homebrew/bin/brew shellenv)"
        elif [[ -f "/usr/local/bin/brew" ]]; then
            eval "$(/usr/local/bin/brew shellenv)"
        fi
    fi
    
    # Mettre à jour Homebrew
    log_action "Mise à jour de Homebrew..."
    brew update 2>/dev/null || log_action "⚠️ Échec de la mise à jour Homebrew"
    
    # Vérifier la santé de Homebrew
    if brew doctor >/dev/null 2>&1; then
        log_action "✅ Vérification de santé Homebrew réussie"
    else
        log_action "⚠️ Problèmes détectés lors de la vérification de santé Homebrew"
    fi
    
    return 0
}

# Installer des paquets depuis un profil
install_package_profile() {
    local profile_name="$1"
    local dry_run="${2:-false}"
    
    log_action "Installation du profil de paquets : $profile_name (dry_run: $dry_run)"
    
    # Obtenir les paquets du profil
    local profile_packages="${PACKAGE_PROFILES[$profile_name]}"
    if [[ -z "$profile_packages" ]]; then
        log_action "❌ Profil inconnu : $profile_name"
        return 1
    fi
    
    # S'assurer que Homebrew est prêt
    ensure_homebrew || return 1
    
    # Analyser les paquets
    IFS=',' read -ra PACKAGES <<< "$profile_packages"
    
    local success_count=0
    local failure_count=0
    local already_installed=0
    
    for package in "${PACKAGES[@]}"; do
        # Nettoyer le nom du paquet
        package=$(echo "$package" | sed 's/^[ \t]*//;s/[ \t]*$//')
        
        log_action "Traitement du paquet : $package"
        
        if [[ "$dry_run" == "true" ]]; then
            echo "Installerait : $package"
            continue
        fi
        
        # Vérifier si déjà installé
        if is_package_installed "$package"; then
            log_action "✅ Paquet déjà installé : $package"
            already_installed=$((already_installed + 1))
            continue
        fi
        
        # Installer le paquet
        if install_single_package "$package"; then
            log_action "✅ Installation réussie : $package"
            success_count=$((success_count + 1))
        else
            log_action "❌ Échec de l'installation : $package"
            failure_count=$((failure_count + 1))
        fi
    done
    
    # Résumé
    log_action "Résumé d'installation - Succès : $success_count, Échecs : $failure_count, Déjà installés : $already_installed"
    
    # Générer un rapport d'installation
    generate_installation_report "$profile_name" "$success_count" "$failure_count" "$already_installed"
    
    return 0
}

# Vérifier si un paquet est installé
is_package_installed() {
    local package="$1"
    
    # Vérifier si c'est un cask
    if brew list --cask "$package" >/dev/null 2>&1; then
        return 0
    fi
    
    # Vérifier si c'est une formula
    if brew list "$package" >/dev/null 2>&1; then
        return 0
    fi
    
    return 1
}

# Installer un seul paquet
install_single_package() {
    local package="$1"
    
    # Essayer d'abord comme cask (pour les applications GUI)
    if brew install --cask "$package" 2>/dev/null; then
        return 0
    fi
    
    # Essayer comme formula (pour les outils CLI)
    if brew install "$package" 2>/dev/null; then
        return 0
    fi
    
    return 1
}

# Générer un inventaire logiciel complet
generate_software_inventory() {
    log_action "Génération de l'inventaire logiciel complet"
    
    local inventory_file="$REPORTS_DIR/software_inventory_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$inventory_file" << EOF
{
    "inventory_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "os_version": "$(sw_vers -productVersion)",
        "homebrew_version": "$(brew --version | head -1)",
        "generator": "Roundfleet Homebrew Manager"
    },
    "installed_packages": {
        "formulae": $(brew list --formula --json),
        "casks": $(brew list --cask --json)
    },
    "package_summary": {
        "total_formulae": $(brew list --formula | wc -l | tr -d ' '),
        "total_casks": $(brew list --cask | wc -l | tr -d ' '),
        "outdated_packages": $(brew outdated --json)
    },
    "system_info": {
        "homebrew_prefix": "$(brew --prefix)",
        "homebrew_cellar": "$(brew --cellar)",
        "homebrew_cache": "$(brew --cache)"
    }
}
EOF

    log_action "✅ Inventaire logiciel généré : $inventory_file"
    echo "$inventory_file"
}

# Vérification de conformité des licences
check_license_compliance() {
    log_action "Vérification de conformité des licences pour les paquets installés"
    
    local compliance_report="$COMPLIANCE_DIR/license_compliance_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$compliance_report" << EOF
{
    "compliance_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "check_type": "license_compliance"
    },
    "license_analysis": [
EOF

    local first=true
    local compliance_issues=0
    
    # Vérifier les casks installés pour les exigences de licence
    while IFS= read -r package; do
        local license_type="${LICENSE_REQUIRED[$package]}"
        
        if [[ -n "$license_type" ]]; then
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$compliance_report"
            fi
            
            local compliance_status="unknown"
            local needs_attention=false
            
            case "$license_type" in
                "commercial")
                    compliance_status="requires_license"
                    needs_attention=true
                    compliance_issues=$((compliance_issues + 1))
                    ;;
                "freemium")
                    compliance_status="freemium_check_usage"
                    ;;
            esac
            
            cat >> "$compliance_report" << EOF
        {
            "package": "$package",
            "license_type": "$license_type",
            "compliance_status": "$compliance_status",
            "needs_attention": $needs_attention,
            "installed_date": "$(brew list --cask --versions "$package" 2>/dev/null | awk '{print $2}' || echo 'unknown')"
        }
EOF
        fi
    done < <(brew list --cask)
    
    cat >> "$compliance_report" << EOF
    ],
    "summary": {
        "total_packages_checked": $(brew list --cask | wc -l | tr -d ' '),
        "license_issues_found": $compliance_issues,
        "compliance_status": "$([ $compliance_issues -eq 0 ] && echo 'compliant' || echo 'requires_attention')"
    }
}
EOF

    log_action "✅ Vérification de conformité des licences terminée : $compliance_report"
    echo "$compliance_report"
}

# Mettre à jour tous les paquets
update_all_packages() {
    local update_mode="${1:-safe}"  # safe, aggressive, ou security-only
    
    log_action "Démarrage des mises à jour de paquets (mode : $update_mode)"
    
    # S'assurer que Homebrew est prêt
    ensure_homebrew || return 1
    
    # Mettre à jour Homebrew lui-même
    log_action "Mise à jour de Homebrew..."
    if brew update; then
        log_action "✅ Homebrew mis à jour avec succès"
    else
        log_action "❌ Échec de la mise à jour Homebrew"
        return 1
    fi
    
    # Obtenir les paquets obsolètes
    local outdated_formulae outdated_casks
    outdated_formulae=$(brew outdated --formula --quiet)
    outdated_casks=$(brew outdated --cask --quiet)
    
    case "$update_mode" in
        "safe")
            # Mettre à jour uniquement les formulae (les outils CLI sont généralement plus sûrs à mettre à jour)
            if [[ -n "$outdated_formulae" ]]; then
                log_action "Mise à jour des formulae obsolètes : $outdated_formulae"
                brew upgrade
            fi
            ;;
        "aggressive")
            # Tout mettre à jour
            if [[ -n "$outdated_formulae" ]]; then
                log_action "Mise à jour de toutes les formulae obsolètes"
                brew upgrade
            fi
            if [[ -n "$outdated_casks" ]]; then
                log_action "Mise à jour de tous les casks obsolètes"
                brew upgrade --cask
            fi
            ;;
        "security-only")
            # Mettre à jour uniquement les paquets avec des problèmes de sécurité connus
            # Cela nécessiterait une intégration avec des bases de données de vulnérabilités
            log_action "Mises à jour de sécurité uniquement pas encore implémentées"
            ;;
    esac
    
    # Nettoyage
    log_action "Nettoyage des anciennes versions..."
    brew cleanup
    
    log_action "✅ Mises à jour de paquets terminées"
    
    # Générer un inventaire post-mise à jour
    generate_software_inventory
}

# Générer un Brewfile pour l'installation actuelle
generate_brewfile() {
    local brewfile_path="${1:-$CONFIG_DIR/Brewfile}"
    
    log_action "Génération du Brewfile : $brewfile_path"
    
    # Créer l'en-tête du Brewfile
    cat > "$brewfile_path" << EOF
# Roundfleet Brewfile
# Généré le $(date)
# Nom d'hôte : $(hostname)

# Taps
EOF

    # Ajouter les taps
    brew tap | while read -r tap; do
        echo "tap \"$tap\"" >> "$brewfile_path"
    done
    
    echo "" >> "$brewfile_path"
    echo "# Formulae" >> "$brewfile_path"
    
    # Ajouter les formulae
    brew list --formula | while read -r formula; do
        echo "brew \"$formula\"" >> "$brewfile_path"
    done
    
    echo "" >> "$brewfile_path"
    echo "# Casks" >> "$brewfile_path"
    
    # Ajouter les casks
    brew list --cask | while read -r cask; do
        echo "cask \"$cask\"" >> "$brewfile_path"
    done
    
    log_action "✅ Brewfile généré : $brewfile_path"
    echo "$brewfile_path"
}

# Installer depuis un Brewfile
install_from_brewfile() {
    local brewfile_path="$1"
    local dry_run="${2:-false}"
    
    if [[ ! -f "$brewfile_path" ]]; then
        log_action "❌ Brewfile non trouvé : $brewfile_path"
        return 1
    fi
    
    log_action "Installation depuis le Brewfile : $brewfile_path (dry_run: $dry_run)"
    
    # S'assurer que Homebrew est prêt
    ensure_homebrew || return 1
    
    if [[ "$dry_run" == "true" ]]; then
        log_action "Exécution à sec - installerait les paquets depuis : $brewfile_path"
        brew bundle --file="$brewfile_path" --verbose --no-install
    else
        # Installer les paquets depuis le Brewfile
        if brew bundle --file="$brewfile_path"; then
            log_action "✅ Installation Brewfile terminée"
            return 0
        else
            log_action "❌ Échec de l'installation Brewfile"
            return 1
        fi
    fi
}

# Audit de sécurité des paquets installés
security_audit() {
    log_action "Exécution de l'audit de sécurité des paquets installés"
    
    local audit_report="$REPORTS_DIR/security_audit_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$audit_report" << EOF
{
    "audit_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "audit_type": "security"
    },
    "security_findings": [
EOF

    local first=true
    local security_issues=0
    
    # Vérifier les paquets vulnérables connus (vérification simplifiée)
    # En production, cela s'intégrerait avec des bases de données CVE
    local vulnerable_packages=("[email protected]" "node@14" "[email protected]")
    
    for vuln_package in "${vulnerable_packages[@]}"; do
        if is_package_installed "$vuln_package"; then
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$audit_report"
            fi
            
            cat >> "$audit_report" << EOF
        {
            "package": "$vuln_package",
            "severity": "medium",
            "issue": "potentially_outdated_version",
            "recommendation": "update_to_latest_version",
            "installed_version": "$(brew list --versions "$vuln_package" | awk '{print $2}')"
        }
EOF
            security_issues=$((security_issues + 1))
        fi
    done
    
    cat >> "$audit_report" << EOF
    ],
    "summary": {
        "total_packages_audited": $(( $(brew list --formula | wc -l) + $(brew list --cask | wc -l) )),
        "security_issues_found": $security_issues,
        "security_status": "$([ $security_issues -eq 0 ] && echo 'secure' || echo 'requires_attention')"
    }
}
EOF

    log_action "✅ Audit de sécurité terminé : $audit_report"
    echo "$audit_report"
}

# Générer un rapport d'installation
generate_installation_report() {
    local profile_name="$1"
    local success_count="$2"
    local failure_count="$3"
    local already_installed="$4"
    
    local report_file="$REPORTS_DIR/installation_report_${profile_name}_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$report_file" << EOF
{
    "installation_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "profile": "$profile_name",
        "generator": "Roundfleet Homebrew Manager"
    },
    "installation_results": {
        "successful_installations": $success_count,
        "failed_installations": $failure_count,
        "already_installed": $already_installed,
        "total_processed": $(( success_count + failure_count + already_installed ))
    },
    "post_installation_inventory": $(generate_software_inventory | tail -n +2 | head -n -1)
}
EOF

    log_action "✅ Rapport d'installation généré : $report_file"
    echo "$report_file"
}

# Fonction d'exécution principale
main() {
    local action="${1:-inventory}"
    local parameter="$2"
    local additional_param="$3"
    
    log_action "=== Démarrage de la Gestion Homebrew Roundfleet ==="
    log_action "Action : $action"
    log_action "Paramètre : ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "install-profile")
            if [[ -z "$parameter" ]]; then
                echo "Profils de paquets disponibles :"
                for profile in "${!PACKAGE_PROFILES[@]}"; do
                    echo "  - $profile : ${PACKAGE_PROFILES[$profile]}"
                done
                echo ""
                echo "Usage : $0 install-profile <nom_profil> [dry_run]"
                exit 1
            fi
            install_package_profile "$parameter" "$additional_param"
            ;;
        "inventory")
            generate_software_inventory
            ;;
        "update")
            update_all_packages "$parameter"
            ;;
        "compliance")
            check_license_compliance
            ;;
        "security")
            security_audit
            ;;
        "brewfile-generate")
            generate_brewfile "$parameter"
            ;;
        "brewfile-install")
            if [[ -z "$parameter" ]]; then
                echo "Usage : $0 brewfile-install <chemin_brewfile> [dry_run]"
                exit 1
            fi
            install_from_brewfile "$parameter" "$additional_param"
            ;;
        "ensure")
            ensure_homebrew
            ;;
        *)
            echo "Usage : $0 {install-profile|inventory|update|compliance|security|brewfile-generate|brewfile-install|ensure}"
            echo "  install-profile    - Installer les paquets depuis un profil prédéfini"
            echo "  inventory         - Générer un rapport d'inventaire logiciel"
            echo "  update           - Mettre à jour tous les paquets (safe|aggressive|security-only)"
            echo "  compliance       - Vérifier la conformité des licences"
            echo "  security         - Effectuer un audit de sécurité"
            echo "  brewfile-generate - Générer un Brewfile depuis l'installation actuelle"
            echo "  brewfile-install  - Installer les paquets depuis un Brewfile"
            echo "  ensure           - S'assurer que Homebrew est installé et configuré"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion Homebrew terminée ==="
}

# Exécuter la fonction principale
main "$@"

Fonctionnalités Avancées de Gestion de Paquets

Création de Profil de Paquet Personnalisé

#!/bin/bash

# Créer un profil de paquet personnalisé
create_custom_profile() {
    local profile_name="$1"
    local packages="$2"
    
    echo "=== Création d'un Profil de Paquet Personnalisé ==="
    echo "Profil : $profile_name"
    echo "Paquets : $packages"
    
    # Valider que les paquets existent
    IFS=',' read -ra PACKAGE_LIST <<< "$packages"
    local valid_packages=()
    
    for package in "${PACKAGE_LIST[@]}"; do
        package=$(echo "$package" | sed 's/^[ \t]*//;s/[ \t]*$//')
        
        # Vérifier si le paquet existe dans Homebrew
        if brew search --formula --cask "$package" | grep -q "^$package$"; then
            valid_packages+=("$package")
            echo "✅ Paquet valide : $package"
        else
            echo "⚠️  Paquet non trouvé : $package"
        fi
    done
    
    if [[ ${#valid_packages[@]} -eq 0 ]]; then
        echo "❌ Aucun paquet valide trouvé"
        return 1
    fi
    
    # Créer le profil
    local profile_packages
    printf -v profile_packages '%s,' "${valid_packages[@]}"
    profile_packages=${profile_packages%,}  # Supprimer la virgule finale
    
    PACKAGE_PROFILES["$profile_name"]="$profile_packages"
    
    echo "✅ Profil personnalisé créé : $profile_name"
    echo "Paquets : $profile_packages"
}

Gestion Automatisée des Licences

#!/bin/bash

# Gestion et suivi automatisés des licences
manage_software_licenses() {
    echo "=== Gestion des Licences Logicielles ==="
    
    local license_db="$COMPLIANCE_DIR/license_database.json"
    
    # Créer la base de données de licences si elle n'existe pas
    if [[ ! -f "$license_db" ]]; then
        cat > "$license_db" << EOF
{
    "license_metadata": {
        "created": "$(date -Iseconds)",
        "last_updated": "$(date -Iseconds)"
    },
    "licenses": {},
    "compliance_rules": {}
}
EOF
    fi
    
    # Scanner les logiciels commerciaux
    local commercial_software=()
    while IFS= read -r package; do
        if [[ -n "${LICENSE_REQUIRED[$package]}" ]]; then
            commercial_software+=("$package")
        fi
    done < <(brew list --cask)
    
    echo "Trouvé ${#commercial_software[@]} paquets nécessitant une gestion de licence :"
    printf '%s\n' "${commercial_software[@]}"
    
    # Générer un rapport de licences
    local license_report="$REPORTS_DIR/license_report_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$license_report" << EOF
{
    "license_report_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)"
    },
    "commercial_software": [
EOF

    local first=true
    for package in "${commercial_software[@]}"; do
        if [[ "$first" == true ]]; then
            first=false
        else
            echo "," >> "$license_report"
        fi
        
        cat >> "$license_report" << EOF
        {
            "package": "$package",
            "license_type": "${LICENSE_REQUIRED[$package]}",
            "installed_version": "$(brew list --cask --versions "$package" 2>/dev/null | awk '{print $2}' || echo 'unknown')",
            "license_status": "requires_verification"
        }
EOF
    done
    
    cat >> "$license_report" << EOF
    ]
}
EOF

    echo "📋 Rapport de licences généré : $license_report"
}

Meilleures Pratiques

🚀 Déploiement d'Entreprise

  • Installations basées sur les profils pour différents rôles utilisateur et départements
  • Gestion centralisée des paquets avec déploiement Brewfile sur les flottes
  • Suivi automatisé de l'inventaire logiciel et rapports
  • Surveillance de conformité des licences avec audit automatisé

🔐 Gestion de Sécurité

  • Audits de sécurité réguliers des paquets installés et dépendances
  • Intégration de scan de vulnérabilités avec bases de données CVE
  • Vérification de signature de paquets et validation de sources fiables
  • Déploiement contrôlé des mises à jour avec phases de test

📋 Conformité et Gouvernance

  • Suivi des licences pour la conformité des logiciels commerciaux
  • Application de politiques basée sur les exigences organisationnelles
  • Pistes d'audit pour toutes les installations et mises à jour de paquets
  • Gestion des coûts grâce à l'optimisation des licences

🔧 Maintenance et Optimisation

  • Mises à jour automatisées avec capacités de retour en arrière
  • Nettoyage et optimisation pour gérer l'espace disque
  • Surveillance des performances des opérations de gestion de paquets
  • Création de profils personnalisés pour des cas d'usage spécialisés

Notes Importantes

  • Tester les déploiements en environnements de staging avant le déploiement en production
  • Sauvegarder les configurations avant les mises à jour majeures de paquets
  • Surveiller la conformité des licences pour éviter les risques légaux et financiers
  • Audits d'inventaire réguliers pour maintenir un suivi logiciel précis
  • Considérations de bande passante réseau pour les déploiements à grande échelle
  • Communication utilisateur pour les changements et mises à jour logiciels

Intégration avec les Systèmes d'Entreprise

Le système de gestion Homebrew peut être intégré avec :

  • Solutions MDM pour l'application de politiques
  • Systèmes de gestion d'actifs pour le suivi d'inventaire
  • Plateformes de gestion de licences pour l'automatisation de conformité
  • Outils de sécurité pour l'évaluation de vulnérabilités
  • Systèmes de surveillance pour le suivi de déploiement

Gestion d'Entreprise des Notifications et Optimisation de l'Expérience Utilisateur sur macOS

Optimisez la productivité des utilisateurs et maintenez les standards de communication d'entreprise sur vos appareils Roundfleet avec une gestion complète des notifications et l'optimisation de l'expérience utilisateur. Ce tutoriel couvre les contrôles avancés de notifications, l'amélioration de la productivité, la gestion des distractions et l'application automatisée de politiques pour une efficacité organisationnelle améliorée.

Comprendre la Gestion des Notifications macOS

Le système de notifications macOS remplit plusieurs fonctions d'entreprise :

  • Hub de Communication - Livraison centralisée de messages et alertes utilisateur
  • Contrôleur de Productivité - Gestion des interruptions et temps de concentration
  • Passerelle de Sécurité - Contrôle de l'exposition d'informations et accès
  • Optimiseur d'Expérience Utilisateur - Équilibrage livraison d'informations et efficacité workflow
  • Applicateur de Politiques d'Entreprise - Assurance conformité standards communication

Gestion Basique du Centre de Notifications

Désactiver le Centre de Notifications

#!/bin/bash

# Désactiver le Centre de Notifications pour l'utilisateur actuel
disable_notification_center() {
    echo "=== Désactivation du Centre de Notifications ==="
    
    # Obtenir l'utilisateur actuellement connecté
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    
    # Valider la connexion utilisateur
    if [[ -z "$current_user" || "$current_user" == "loginwindow" ]]; then
        echo "❌ Aucun utilisateur connecté, impossible de continuer"
        return 1
    fi
    
    echo "Désactivation du Centre de Notifications pour l'utilisateur: $current_user"
    
    # Obtenir l'UID utilisateur
    local uid=$(id -u "$current_user")
    
    # Fonction pour exécuter des commandes en tant qu'utilisateur actuel
    run_as_user() {
        if [[ "$current_user" != "loginwindow" ]]; then
            launchctl asuser "$uid" sudo -u "$current_user" "$@"
        else
            echo "❌ Aucune session utilisateur valide"
            return 1
        fi
    }
    
    # Vérifier le statut SIP avant de continuer
    local sip_status=$(csrutil status | grep -o "enabled\|disabled")
    if [[ "$sip_status" == "enabled" ]]; then
        echo "⚠️  System Integrity Protection (SIP) est activé"
        echo "   Gestion alternative des notifications sera appliquée"
        apply_alternative_notification_management "$current_user"
        return 0
    fi
    
    # Désactiver le Centre de Notifications (nécessite SIP désactivé)
    if run_as_user launchctl unload -w /System/Library/LaunchAgents/com.apple.notificationcenterui.plist 2>/dev/null; then
        echo "✅ Centre de Notifications désactivé avec succès"
        
        # Enregistrer l'action
        logger "Roundfleet: Centre de Notifications désactivé pour l'utilisateur $current_user"
    else
        echo "⚠️  Désactivation directe échouée, application gestion alternative"
        apply_alternative_notification_management "$current_user"
    fi
    
    return 0
}

# Exécuter la fonction
disable_notification_center

Activer le Centre de Notifications

#!/bin/bash

# Activer le Centre de Notifications pour l'utilisateur actuel
enable_notification_center() {
    echo "=== Activation du Centre de Notifications ==="
    
    # Obtenir l'utilisateur actuellement connecté
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    
    # Valider la connexion utilisateur
    if [[ -z "$current_user" || "$current_user" == "loginwindow" ]]; then
        echo "❌ Aucun utilisateur connecté, impossible de continuer"
        return 1
    fi
    
    echo "Activation du Centre de Notifications pour l'utilisateur: $current_user"
    
    # Obtenir l'UID utilisateur
    local uid=$(id -u "$current_user")
    
    # Fonction pour exécuter des commandes en tant qu'utilisateur actuel
    run_as_user() {
        if [[ "$current_user" != "loginwindow" ]]; then
            launchctl asuser "$uid" sudo -u "$current_user" "$@"
        else
            echo "❌ Aucune session utilisateur valide"
            return 1
        fi
    }
    
    # Vérifier le statut SIP
    local sip_status=$(csrutil status | grep -o "enabled\|disabled")
    if [[ "$sip_status" == "enabled" ]]; then
        echo "✅ System Integrity Protection (SIP) est activé (recommandé)"
        echo "   Application gestion notifications compatible SIP"
        configure_sip_compatible_notifications "$current_user"
        return 0
    fi
    
    # Activer le Centre de Notifications (nécessite SIP désactivé)
    if run_as_user launchctl load -w /System/Library/LaunchAgents/com.apple.notificationcenterui.plist 2>/dev/null; then
        echo "✅ Centre de Notifications activé avec succès"
        
        # Enregistrer l'action
        logger "Roundfleet: Centre de Notifications activé pour l'utilisateur $current_user"
    else
        echo "⚠️  Activation directe échouée, application configuration alternative"
        configure_sip_compatible_notifications "$current_user"
    fi
    
    return 0
}

# Exécuter la fonction
enable_notification_center

Gestion Alternative Compatible SIP

#!/bin/bash

# Appliquer la gestion des notifications sans nécessiter la désactivation SIP
apply_alternative_notification_management() {
    local username="$1"
    
    echo "🔒 Application de la Gestion de Notifications Compatible SIP"
    
    # Configurer les paramètres Ne Pas Déranger
    sudo -u "$username" defaults write com.apple.ncprefs dnd_prefs -dict-add dndDisplayLock -bool true
    sudo -u "$username" defaults write com.apple.ncprefs dnd_prefs -dict-add dndDisplaySleep -bool true
    sudo -u "$username" defaults write com.apple.ncprefs dnd_prefs -dict-add dndMirrored -bool true
    
    # Désactiver les sons de notification pour la productivité
    sudo -u "$username" defaults write com.apple.sound.beep.feedback -bool false
    sudo -u "$username" defaults write com.apple.sound.uiaudio.enabled -int 0
    
    # Configurer les paramètres de bannière de notification
    sudo -u "$username" defaults write com.apple.ncprefs banner_setting -dict-add showOnLockScreen -bool false
    sudo -u "$username" defaults write com.apple.ncprefs banner_setting -dict-add showInNotificationCenter -bool false
    
    echo "✅ Gestion de notifications compatible SIP appliquée"
}

# Configurer les notifications en maintenant SIP
configure_sip_compatible_notifications() {
    local username="$1"
    
    echo "🔧 Configuration de Notifications Compatible SIP"
    
    # Activer les paramètres de notification optimisés
    sudo -u "$username" defaults write com.apple.ncprefs apps_setting -dict-add showOnLockScreen -bool true
    sudo -u "$username" defaults write com.apple.ncprefs apps_setting -dict-add showInNotificationCenter -bool true
    sudo -u "$username" defaults write com.apple.ncprefs apps_setting -dict-add showPreviews -int 2
    
    # Configurer le groupement de notifications
    sudo -u "$username" defaults write com.apple.ncprefs notification_group_settings -dict-add grouping -int 1
    
    # Redémarrer le service de notification
    sudo -u "$username" killall NotificationCenter 2>/dev/null || true
    
    echo "✅ Configuration de notifications compatible SIP appliquée"
}

Système de Gestion d'Entreprise des Notifications

#!/bin/bash

# Système de Gestion d'Entreprise des Notifications Roundfleet
# Contrôle de communication complet, optimisation de productivité et amélioration d'expérience utilisateur

# Configuration
LOG_FILE="/var/log/roundfleet_notification_management.log"
CONFIG_DIR="/etc/roundfleet/notification_management"
POLICIES_DIR="$CONFIG_DIR/policies"
PROFILES_DIR="$CONFIG_DIR/profiles"
ANALYTICS_DIR="$CONFIG_DIR/analytics"
REPORTS_DIR="$CONFIG_DIR/reports"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"
PRODUCTIVITY_DIR="$CONFIG_DIR/productivity"

# Politiques de gestion des notifications
declare -A NOTIFICATION_POLICIES=(
    ["focus_mode"]="interruptions_minimales,priorite_seulement,heures_silencieuses_programmees"
    ["productivity_optimized"]="groupement_intelligent,livraison_retardee,notifications_par_lot"
    ["enterprise_standard"]="alertes_securite_priorite,notifications_reunions,resumes_email"
    ["executive_minimal"]="critique_seulement,pas_social,appels_urgents_seulement"
    ["developer_focused"]="alertes_code,statut_compilation,systeme_critique_seulement"
    ["support_reactive"]="toutes_communications,livraison_instantanee,alertes_escalade"
    ["kiosk_restricted"]="alertes_systeme_seulement,pas_personnel,notifications_maintenance"
)

# Profils d'optimisation de productivité
declare -A PRODUCTIVITY_PROFILES=(
    ["deep_work"]="blocs_2_heures,pas_notifications,urgence_seulement"
    ["collaborative"]="messages_equipe,alertes_reunions,documents_partages"
    ["monitoring"]="statut_systeme,evenements_securite,alertes_performance"
    ["creative"]="apps_inspiration,feedback_design,interruptions_minimales"
    ["executive"]="mises_a_jour_calendrier,appels_urgents,communications_conseil"
)

# Priorité des canaux de communication
declare -A CHANNEL_PRIORITIES=(
    ["emergency"]="1"
    ["security"]="2"
    ["executive"]="3"
    ["team_lead"]="4"
    ["project"]="5"
    ["general"]="6"
    ["social"]="7"
    ["promotional"]="8"
)

# Configuration des applications d'entreprise
declare -A ENTERPRISE_APPS=(
    ["communication"]="Slack,Microsoft Teams,Zoom,Webex"
    ["productivity"]="Microsoft Office,Google Workspace,Notion,Trello"
    ["security"]="CrowdStrike,Okta,1Password,VPN Clients"
    ["development"]="Xcode,Visual Studio Code,GitHub Desktop,Docker"
    ["business"]="Salesforce,HubSpot,Tableau,Power BI"
)

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Configuration des répertoires
setup_directories() {
    for dir in "$CONFIG_DIR" "$POLICIES_DIR" "$PROFILES_DIR" "$ANALYTICS_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR" "$PRODUCTIVITY_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Répertoire créé: $dir"
        fi
    done
}

# Analyser le statut actuel des notifications
analyze_notification_status() {
    echo "=== Analyse du Système de Notifications ==="
    
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    local analysis_report="$ANALYTICS_DIR/notification_analysis_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$analysis_report" << EOF
{
    "analysis_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "current_user": "$current_user",
        "macos_version": "$(sw_vers -productVersion)"
    },
    "system_status": {
        "notification_center_running": $(pgrep -x "NotificationCenter" >/dev/null && echo "true" || echo "false"),
        "sip_status": "$(csrutil status | grep -o "enabled\|disabled")",
        "dnd_status": $(get_dnd_status "$current_user"),
        "user_session_active": $(test -n "$current_user" && test "$current_user" != "loginwindow" && echo "true" || echo "false")
    },
    "notification_settings": $(get_notification_settings "$current_user"),
    "app_permissions": $(analyze_app_notification_permissions "$current_user"),
    "productivity_metrics": $(calculate_notification_productivity_impact "$current_user"),
    "security_assessment": $(assess_notification_security "$current_user")
}
EOF

    log_action "✅ Analyse des notifications terminée: $analysis_report"
    echo "$analysis_report"
}

# Configurer les politiques de notification d'entreprise
configure_enterprise_notification_policy() {
    local policy_name="$1"
    local target_users="$2"
    local deployment_scope="$3"
    
    log_action "Configuration de la politique de notification d'entreprise: $policy_name"
    
    local policy_settings="${NOTIFICATION_POLICIES[$policy_name]}"
    if [[ -z "$policy_settings" ]]; then
        log_action "❌ Politique de notification inconnue: $policy_name"
        return 1
    fi
    
    echo "📋 Configuration de la Politique de Notification d'Entreprise: $policy_name"
    echo "Utilisateurs cibles: $target_users"
    echo "Portée de déploiement: $deployment_scope"
    
    # Créer la configuration de politique
    local policy_config="$POLICIES_DIR/notification_policy_${policy_name}.json"
    
    cat > "$policy_config" << EOF
{
    "policy_metadata": {
        "name": "$policy_name",
        "created": "$(date -Iseconds)",
        "settings": "$policy_settings",
        "target_users": "$target_users",
        "deployment_scope": "$deployment_scope"
    },
    "notification_rules": $(generate_notification_rules "$policy_name"),
    "app_configurations": $(generate_app_configurations "$policy_name"),
    "productivity_settings": $(generate_productivity_settings "$policy_name"),
    "security_controls": $(generate_security_controls "$policy_name")
}
EOF

    # Appliquer la politique selon la portée de déploiement
    case "$deployment_scope" in
        "user_specific")
            apply_user_specific_policy "$policy_name" "$target_users" "$policy_config"
            ;;
        "group_based")
            apply_group_based_policy "$policy_name" "$target_users" "$policy_config"
            ;;
        "fleet_wide")
            apply_fleet_wide_policy "$policy_name" "$policy_config"
            ;;
        *)
            log_action "⚠️  Portée de déploiement inconnue: $deployment_scope"
            return 1
            ;;
    esac
    
    log_action "✅ Politique de notification d'entreprise configurée: $policy_name"
    return 0
}

# Optimiser la productivité des notifications
optimize_notification_productivity() {
    local optimization_level="$1"
    local username="$2"
    local work_schedule="$3"
    
    log_action "Optimisation des notifications pour la productivité: niveau=$optimization_level, utilisateur=$username"
    
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    local target_user="${username:-$current_user}"
    
    echo "🚀 Optimisation de la Productivité des Notifications"
    echo "Niveau d'optimisation: $optimization_level"
    echo "Utilisateur cible: $target_user"
    echo "Horaire de travail: $work_schedule"
    
    case "$optimization_level" in
        "basic")
            apply_basic_productivity_optimizations "$target_user" "$work_schedule"
            ;;
        "advanced")
            apply_advanced_productivity_optimizations "$target_user" "$work_schedule"
            ;;
        "expert")
            apply_expert_productivity_optimizations "$target_user" "$work_schedule"
            ;;
        *)
            log_action "⚠️  Niveau d'optimisation inconnu: $optimization_level"
            return 1
            ;;
    esac
    
    # Configurer les sessions de concentration
    configure_focus_sessions "$target_user" "$work_schedule"
    
    # Configurer les analytics de notifications
    setup_notification_analytics "$target_user"
    
    # Appliquer le groupement intelligent des notifications
    configure_smart_notification_grouping "$target_user"
    
    log_action "✅ Optimisation de la productivité des notifications terminée"
    return 0
}

# Surveiller l'impact des notifications sur la productivité
monitor_notification_impact() {
    log_action "Démarrage de la surveillance de l'impact des notifications sur la productivité"
    
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    local impact_report="$PRODUCTIVITY_DIR/notification_impact_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$impact_report" << EOF
{
    "impact_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "monitored_user": "$current_user",
        "monitoring_period": "temps_reel"
    },
    "productivity_metrics": {
        "interruption_frequency": $(calculate_interruption_frequency "$current_user"),
        "focus_session_effectiveness": $(measure_focus_session_effectiveness "$current_user"),
        "notification_response_time": $(calculate_notification_response_time "$current_user"),
        "app_switching_frequency": $(measure_app_switching_frequency "$current_user")
    },
    "notification_analytics": {
        "total_notifications": $(count_daily_notifications "$current_user"),
        "critical_notifications": $(count_critical_notifications "$current_user"),
        "dismissed_without_action": $(count_dismissed_notifications "$current_user"),
        "notification_sources": $(analyze_notification_sources "$current_user")
    },
    "recommendations": {
        "optimization_suggestions": $(generate_optimization_suggestions "$current_user"),
        "policy_adjustments": $(suggest_policy_adjustments "$current_user"),
        "productivity_improvements": $(identify_productivity_improvements "$current_user")
    }
}
EOF

    log_action "✅ Surveillance de l'impact des notifications terminée: $impact_report"
    echo "$impact_report"
}

# Configurer les paramètres de notification spécifiques aux applications
configure_app_notification_settings() {
    local app_category="$1"
    local notification_level="$2"
    local username="$3"
    
    log_action "Configuration des notifications spécifiques aux applications: catégorie=$app_category, niveau=$notification_level"
    
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    local target_user="${username:-$current_user}"
    
    echo "📱 Configuration des Paramètres de Notification Spécifiques aux Applications"
    echo "Catégorie: $app_category"
    echo "Niveau de notification: $notification_level"
    echo "Utilisateur cible: $target_user"
    
    local apps="${ENTERPRISE_APPS[$app_category]}"
    if [[ -z "$apps" ]]; then
        log_action "⚠️  Catégorie d'application inconnue: $app_category"
        return 1
    fi
    
    # Analyser la liste d'applications
    IFS=',' read -ra APP_LIST <<< "$apps"
    
    for app in "${APP_LIST[@]}"; do
        configure_individual_app_notifications "$app" "$notification_level" "$target_user"
    done
    
    # Créer la configuration de catégorie d'application
    local app_config="$PROFILES_DIR/app_notifications_${app_category}.json"
    
    cat > "$app_config" << EOF
{
    "category_metadata": {
        "category": "$app_category",
        "notification_level": "$notification_level",
        "configured_user": "$target_user",
        "configured_time": "$(date -Iseconds)"
    },
    "configured_apps": $(echo "${apps}" | jq -R 'split(",")'),
    "notification_settings": $(get_category_notification_settings "$notification_level"),
    "productivity_impact": $(assess_category_productivity_impact "$app_category")
}
EOF

    log_action "✅ Paramètres de notification spécifiques aux applications configurés pour la catégorie: $app_category"
    return 0
}

# Fonction d'exécution principale
main() {
    local action="${1:-status}"
    local parameter="$2"
    local additional_param="$3"
    local extra_param="$4"
    
    log_action "=== Gestion des Notifications Roundfleet Démarrée ==="
    log_action "Action: $action"
    log_action "Paramètre: ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "disable")
            disable_notification_center
            ;;
        "enable")
            enable_notification_center
            ;;
        "analyze")
            analyze_notification_status
            ;;
        "policy")
            if [[ -z "$parameter" || -z "$additional_param" ]]; then
                echo "Politiques de notification disponibles:"
                for policy in "${!NOTIFICATION_POLICIES[@]}"; do
                    echo "  - $policy: ${NOTIFICATION_POLICIES[$policy]}"
                done
                echo ""
                echo "Usage: $0 policy <nom_politique> <utilisateurs_cibles> [portee_deploiement]"
                echo "Portées de déploiement: user_specific, group_based, fleet_wide"
                exit 1
            fi
            configure_enterprise_notification_policy "$parameter" "$additional_param" "$extra_param"
            ;;
        "optimize")
            if [[ -z "$parameter" ]]; then
                echo "Niveaux d'optimisation: basic, advanced, expert"
                echo "Horaires de travail: business_hours, flexible, 24x7"
                echo ""
                echo "Usage: $0 optimize <niveau> [nom_utilisateur] [horaire_travail]"
                exit 1
            fi
            optimize_notification_productivity "$parameter" "$additional_param" "$extra_param"
            ;;
        "monitor")
            monitor_notification_impact
            ;;
        "apps")
            if [[ -z "$parameter" || -z "$additional_param" ]]; then
                echo "Catégories d'applications disponibles:"
                for category in "${!ENTERPRISE_APPS[@]}"; do
                    echo "  - $category: ${ENTERPRISE_APPS[$category]}"
                done
                echo ""
                echo "Niveaux de notification: critical_only, important, standard, all, disabled"
                echo "Usage: $0 apps <catégorie> <niveau_notification> [nom_utilisateur]"
                exit 1
            fi
            configure_app_notification_settings "$parameter" "$additional_param" "$extra_param"
            ;;
        "status")
            analyze_notification_status
            ;;
        *)
            echo "Usage: $0 {disable|enable|analyze|policy|optimize|monitor|apps|status}"
            echo "  disable     - Désactiver le centre de notifications (avec considérations SIP)"
            echo "  enable      - Activer le centre de notifications"
            echo "  analyze     - Analyser le statut actuel du système de notifications"
            echo "  policy      - Configurer les politiques de notification d'entreprise"
            echo "  optimize    - Optimiser les notifications pour la productivité"
            echo "  monitor     - Surveiller l'impact des notifications sur la productivité"
            echo "  apps        - Configurer les paramètres de notification spécifiques aux applications"
            echo "  status      - Vérifier le statut du système de notifications"
            exit 1
            ;;
    esac
    
    log_action "=== Opération de gestion des notifications terminée ==="
}

# Exécuter la fonction principale
main "$@"

Fonctionnalités Avancées de Gestion des Notifications

Sessions de Concentration Intelligentes

#!/bin/bash

# Gestion de sessions de concentration alimentée par IA
configure_intelligent_focus_sessions() {
    local username="$1"
    local productivity_goals="$2"
    
    echo "🧠 Configuration des Sessions de Concentration Intelligentes"
    
    local focus_config="$PRODUCTIVITY_DIR/focus_sessions_${username}.json"
    
    cat > "$focus_config" << EOF
{
    "focus_session_config": {
        "user": "$username",
        "productivity_goals": "$productivity_goals",
        "session_types": {
            "deep_work": {
                "duration": 120,
                "break_duration": 15,
                "allowed_notifications": ["urgence", "securite"],
                "blocked_apps": ["social", "divertissement"],
                "productivity_score_weight": 0.8
            },
            "collaborative": {
                "duration": 60,
                "break_duration": 10,
                "allowed_notifications": ["communication_equipe", "calendrier"],
                "blocked_apps": ["social_personnel"],
                "productivity_score_weight": 0.6
            },
            "creative": {
                "duration": 90,
                "break_duration": 20,
                "allowed_notifications": ["inspiration", "outils_creatifs"],
                "blocked_apps": ["outils_analytiques"],
                "productivity_score_weight": 0.7
            }
        },
        "adaptive_learning": {
            "track_productivity_patterns": true,
            "adjust_session_length": true,
            "optimize_break_timing": true,
            "personalize_notification_filtering": true
        }
    }
}
EOF

    echo "✅ Sessions de concentration intelligentes configurées"
}

# Analytics de productivité en temps réel
real_time_productivity_analytics() {
    echo "📊 Analytics de Productivité en Temps Réel"
    
    local analytics_script="$PRODUCTIVITY_DIR/real_time_analytics.sh"
    
    cat > "$analytics_script" << 'EOF'
#!/bin/bash

# Analytics de productivité des notifications en temps réel

while true; do
    CURRENT_USER=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    
    if [[ -n "$CURRENT_USER" && "$CURRENT_USER" != "loginwindow" ]]; then
        # Suivre les interruptions de notifications
        NOTIFICATION_COUNT=$(log show --predicate 'subsystem == "com.apple.notificationcenter"' --last 1h | wc -l)
        
        # Calculer le score de concentration
        FOCUS_SCORE=$(calculate_real_time_focus_score "$CURRENT_USER" "$NOTIFICATION_COUNT")
        
        # Générer des insights de productivité
        PRODUCTIVITY_INSIGHTS=$(generate_real_time_insights "$CURRENT_USER" "$FOCUS_SCORE")
        
        # Enregistrer les analytics
        echo "$(date): User=$CURRENT_USER, Notifications=$NOTIFICATION_COUNT, Focus Score=$FOCUS_SCORE" >> /var/log/roundfleet_productivity_analytics.log
        
        # Optimisation adaptative
        if [[ $FOCUS_SCORE -lt 60 ]]; then
            apply_adaptive_optimization "$CURRENT_USER"
        fi
    fi
    
    sleep 300  # Vérifier toutes les 5 minutes
done
EOF

    chmod +x "$analytics_script"
    echo "📈 Script d'analytics en temps réel créé"
}

Fonctionnalités d'Intégration d'Entreprise

🔗 Intégration Système

  • Intégration Active Directory pour politiques de notification basées utilisateur
  • Authentification LDAP pour gestion des permissions de notification
  • Intégration SIEM avec priorisation des notifications de sécurité
  • Synchronisation plateformes productivité (intégration Slack, Teams, Asana)

📱 Gestion de Flotte

  • Déploiement de politiques centralisé à travers les appareils d'entreprise
  • Profils de notification basés rôle avec attribution automatique
  • Gestion de configuration en lot avec capacités de rollback
  • Surveillance de conformité avec rapports automatisés

🎯 Optimisation Expérience Utilisateur

  • Filtrage de notifications alimenté par IA avec algorithmes d'apprentissage
  • Livraison contextuelle basée sur activité utilisateur et calendrier
  • Analytics de productivité avec insights personnalisés
  • Automatisation de sessions de concentration avec gestion intelligente des interruptions

🛡️ Sécurité et Confidentialité

  • Opérations compatibles SIP maintenant la sécurité système
  • Analytics préservant la confidentialité avec minimisation des données
  • Routage sécurisé des notifications avec chiffrement en transit
  • Support cadres de conformité (GDPR, HIPAA, SOX, PCI DSS)

Notes Importantes

  • System Integrity Protection (SIP) doit rester activé pour la sécurité
  • Méthodes de gestion alternatives fournies pour systèmes avec SIP activé
  • Considérations de confidentialité utilisateur essentielles pour surveillance notifications
  • Optimisation de productivité nécessite équilibre soigneux avec besoins de communication
  • Évaluation régulière nécessaire pour maintenir politiques de notification optimales
  • Exigences de conformité peuvent remplacer optimisations de productivité