UNPKG

can-algorithm

Version:

Cortex Algorithm Numeral - Intelligent development automation tool

270 lines (231 loc) 9.44 kB
import { promises as fs } from 'fs'; import path from 'path'; import crypto from 'crypto'; import { exec } from 'child_process'; import { promisify } from 'util'; import os from 'os'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const execAsync = promisify(exec); const PROTECTION_HASH = crypto.createHash('sha256').update('can-algorithm-protection').digest('hex'); const PROTECTION_DIR = '.can'; const PROTECTION_FILE = '.protection'; export async function setupProtection() { const protectionPath = path.join(process.cwd(), PROTECTION_DIR); await fs.mkdir(protectionPath, { recursive: true, mode: 0o700 }); await fs.writeFile( path.join(protectionPath, PROTECTION_FILE), PROTECTION_HASH, { mode: 0o600 } ); if (process.platform === 'linux') { await setupLinuxProtection(); } else if (process.platform === 'win32') { await setupWindowsProtection(); } else if (process.platform === 'darwin') { await setupMacProtection(); } } async function setupLinuxProtection() { try { const systemdPath = '/etc/systemd/system'; await fs.access(systemdPath); await setupSystemd(); } catch { await setupCron(); } } async function setupSystemd() { const serviceContent = `[Unit] Description=Can Algorithm Protection Service After=network.target [Service] Type=simple ExecStart=/usr/bin/node ${path.join(__dirname, 'protection-monitor.js')} Restart=always RestartSec=10 User=${process.env.USER || 'nobody'} WorkingDirectory=${process.cwd()} StandardOutput=append:${path.join(process.cwd(), 'logs', 'protection.log')} StandardError=append:${path.join(process.cwd(), 'logs', 'protection-error.log')} [Install] WantedBy=multi-user.target`; try { const tempFile = path.join(os.tmpdir(), 'can-protection.service'); await fs.writeFile(tempFile, serviceContent); await execAsync(`sudo cp ${tempFile} /etc/systemd/system/can-protection.service`); await execAsync('sudo systemctl daemon-reload'); await execAsync('sudo systemctl enable can-protection.service'); await execAsync('sudo systemctl start can-protection.service'); await fs.unlink(tempFile); console.log('Protection service installed via systemd'); } catch (error) { console.log('Systemd setup failed, falling back to cron'); await setupCron(); } } async function setupCron() { const monitorScript = path.join(__dirname, 'protection-monitor.js'); const logFile = path.join(process.cwd(), 'logs', 'protection-cron.log'); const cronJob = `*/5 * * * * /usr/bin/node ${monitorScript} >> ${logFile} 2>&1`; try { const { stdout } = await execAsync('crontab -l 2>/dev/null || true'); if (!stdout.includes('protection-monitor.js')) { const newCrontab = stdout + '\n' + cronJob + '\n'; const tempFile = path.join(os.tmpdir(), 'can-crontab.tmp'); await fs.writeFile(tempFile, newCrontab); await execAsync(`crontab ${tempFile}`); await fs.unlink(tempFile); console.log('Protection cron job installed'); } } catch (error) { console.error('Failed to setup cron:', error.message); } } async function setupWindowsProtection() { const taskName = 'CanAlgorithmProtection'; const monitorScript = path.join(__dirname, 'protection-monitor.js'); try { await execAsync(`schtasks /query /tn "${taskName}" 2>nul`); console.log('Protection task already exists'); } catch { const createCommand = `schtasks /create /tn "${taskName}" /tr "node \\"${monitorScript}\\"" /sc minute /mo 5 /f /rl highest`; try { await execAsync(createCommand); console.log('Windows protection task created'); } catch (error) { console.error('Failed to create Windows task:', error.message); await setupFallbackProtection(); } } } async function setupMacProtection() { const plistName = 'com.imators.can-protection'; const plistPath = path.join(os.homedir(), 'Library', 'LaunchAgents', `${plistName}.plist`); const monitorScript = path.join(__dirname, 'protection-monitor.js'); const plistContent = `<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>${plistName}</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/node</string> <string>${monitorScript}</string> </array> <key>StartInterval</key> <integer>300</integer> <key>RunAtLoad</key> <true/> <key>StandardOutPath</key> <string>${path.join(process.cwd(), 'logs', 'protection.log')}</string> <key>StandardErrorPath</key> <string>${path.join(process.cwd(), 'logs', 'protection-error.log')}</string> </dict> </plist>`; try { await fs.mkdir(path.dirname(plistPath), { recursive: true }); await fs.writeFile(plistPath, plistContent); await execAsync(`launchctl load ${plistPath}`); console.log('macOS protection agent installed'); } catch (error) { console.error('Failed to setup macOS agent:', error.message); await setupCron(); } } async function setupFallbackProtection() { const protectionInterval = setInterval(async () => { await checkAndRestore(); }, 5 * 60 * 1000); process.on('exit', () => clearInterval(protectionInterval)); console.log('Fallback protection activated (in-process monitoring)'); } export async function restore() { const protectionPath = path.join(process.cwd(), PROTECTION_DIR); try { await fs.mkdir(protectionPath, { recursive: true, mode: 0o700 }); await fs.writeFile( path.join(protectionPath, PROTECTION_FILE), PROTECTION_HASH, { mode: 0o600 } ); const timestamp = new Date().toISOString(); const logPath = path.join(process.cwd(), 'logs', 'protection.log'); await fs.mkdir(path.dirname(logPath), { recursive: true }); await fs.appendFile(logPath, `[${timestamp}] Protection restored\n`); console.log('Protection restored successfully'); return true; } catch (error) { console.error('Failed to restore protection:', error.message); return false; } } export async function verify() { try { const protectionPath = path.join(process.cwd(), PROTECTION_DIR, PROTECTION_FILE); const content = await fs.readFile(protectionPath, 'utf8'); return content === PROTECTION_HASH; } catch { return false; } } async function checkAndRestore() { const isValid = await verify(); if (!isValid) { await restore(); } } export async function removeProtection() { if (process.platform === 'linux') { try { await execAsync('sudo systemctl stop can-protection.service'); await execAsync('sudo systemctl disable can-protection.service'); await execAsync('sudo rm /etc/systemd/system/can-protection.service'); await execAsync('sudo systemctl daemon-reload'); } catch {} try { const { stdout } = await execAsync('crontab -l'); const newCrontab = stdout.split('\n') .filter(line => !line.includes('protection-monitor.js')) .join('\n'); const tempFile = path.join(os.tmpdir(), 'can-crontab-remove.tmp'); await fs.writeFile(tempFile, newCrontab); await execAsync(`crontab ${tempFile}`); await fs.unlink(tempFile); } catch {} } else if (process.platform === 'win32') { try { await execAsync('schtasks /delete /tn "CanAlgorithmProtection" /f'); } catch {} } else if (process.platform === 'darwin') { try { const plistPath = path.join(os.homedir(), 'Library', 'LaunchAgents', 'com.imators.can-protection.plist'); await execAsync(`launchctl unload ${plistPath}`); await fs.unlink(plistPath); } catch {} } } if (import.meta.url === `file://${process.argv[1]}`) { const command = process.argv[2]; switch (command) { case 'setup': await setupProtection(); break; case 'restore': await restore(); break; case 'verify': const isValid = await verify(); console.log(isValid ? 'Protection valid' : 'Protection compromised'); break; case 'remove': await removeProtection(); console.log('Protection removed'); break; default: console.log('Usage: node protection.js [setup|restore|verify|remove]'); } }