#!/usr/bin/env python3 """ Chat Bash Executor - Safe, limited bash command execution Only allows read-only system status commands """ import subprocess import time from typing import Dict class ChatBashExecutor: """Execute safe read-only bash commands for chat interface""" # Whitelist of allowed commands (read-only only) ALLOWED_COMMANDS = { 'uptime': 'uptime', 'load': 'cat /proc/loadavg', 'disk': 'df -h /', 'memory': 'free -h', 'services': 'systemctl --no-pager list-units --type=service --all', 'active_services': 'systemctl --no-pager list-units --type=service --state=running', 'failed_services': 'systemctl --no-pager list-units --type=service --state=failed', 'ps': 'ps aux | head -20', 'docker_ps': 'docker ps', 'docker_stats': 'docker stats --no-stream', 'nginx_status': 'systemctl --no-pager status nginx', 'date': 'date', 'hostname': 'hostname', 'whoami': 'whoami', 'pwd': 'pwd', 'ls_home': 'ls -lah /home/admin | head -20', 'du_home': 'du -sh /home/admin/* 2>/dev/null | sort -h', } def __init__(self, timeout_ms: int = 300): """Initialize with execution timeout""" self.timeout_ms = timeout_ms self.timeout_seconds = timeout_ms / 1000.0 def execute(self, command_name: str) -> Dict: """Execute a whitelisted command""" if command_name not in self.ALLOWED_COMMANDS: return { 'error': f'Command "{command_name}" not allowed', 'allowed_commands': list(self.ALLOWED_COMMANDS.keys()) } command = self.ALLOWED_COMMANDS[command_name] try: start_time = time.time() result = subprocess.run( command, shell=True, capture_output=True, text=True, timeout=self.timeout_seconds ) execution_time_ms = (time.time() - start_time) * 1000 return { 'command': command_name, 'success': result.returncode == 0, 'output': result.stdout.strip(), 'error': result.stderr.strip() if result.stderr else None, 'exit_code': result.returncode, 'execution_time_ms': round(execution_time_ms, 2) } except subprocess.TimeoutExpired: return { 'command': command_name, 'error': f'Command timed out after {self.timeout_ms}ms', 'success': False } except Exception as e: return { 'command': command_name, 'error': str(e), 'success': False } def system_status(self) -> Dict: """Quick system status summary""" status = { 'timestamp': time.time(), 'components': {} } for check_name in ['uptime', 'load', 'disk', 'memory']: result = self.execute(check_name) status['components'][check_name] = { 'success': result.get('success', False), 'output': result.get('output', '')[:200] # First 200 chars } return status def list_allowed_commands(self) -> Dict: """List all allowed commands""" return { 'allowed_commands': [ {'name': name, 'description': cmd} for name, cmd in self.ALLOWED_COMMANDS.items() ], 'count': len(self.ALLOWED_COMMANDS), 'timeout_ms': self.timeout_ms } if __name__ == '__main__': import json executor = ChatBashExecutor() print("System Status:") print(json.dumps(executor.system_status(), indent=2, default=str)) print() print("Uptime:") print(json.dumps(executor.execute('uptime'), indent=2))