smartantivirus/ts/classes.smartantivirus.ts
2025-01-10 03:09:32 +01:00

103 lines
3.0 KiB
TypeScript

import * as plugins from './plugins.js';
import * as paths from './paths.js';
import { exec } from 'child_process';
import net from 'net';
import { promisify } from 'util';
const execAsync = promisify(exec);
export class ClamAvService {
private host: string;
private port: number;
constructor(host: string = '127.0.0.1', port: number = 3310) {
this.host = host;
this.port = port;
}
/**
* Scans an in-memory Buffer using ClamAV daemon's INSTREAM command.
*/
public async scanBuffer(buffer: Buffer): Promise<{ isInfected: boolean; reason?: string }> {
return new Promise((resolve, reject) => {
const client = new net.Socket();
client.connect(this.port, this.host, () => {
console.log('Connected to ClamAV daemon');
client.write('zINSTREAM\0'); // Start the INSTREAM command
const chunkSize = 1024;
let offset = 0;
// Send data in chunks
while (offset < buffer.length) {
const chunk = buffer.slice(offset, offset + chunkSize);
console.log('Sending chunk:', chunk.toString('utf8'));
const sizeBuf = Buffer.alloc(4);
sizeBuf.writeUInt32BE(chunk.length, 0);
client.write(sizeBuf);
client.write(chunk);
offset += chunkSize;
}
// Send end-of-stream signal
const endOfStream = Buffer.alloc(4);
endOfStream.writeUInt32BE(0, 0);
console.log('Sending end-of-stream signal');
client.write(endOfStream);
});
client.on('data', (data) => {
const response = data.toString();
console.log('Raw Response from ClamAV:', response);
const isInfected = response.includes('FOUND');
const reason = isInfected ? response.split('FOUND')[0].trim() : undefined;
resolve({ isInfected, reason });
client.end();
});
client.on('error', (err) => {
console.error('Error communicating with ClamAV:', err);
reject(err);
});
client.on('close', () => {
console.log('Connection to ClamAV daemon closed');
});
});
}
/**
* Scans a string by converting it to a Buffer and using scanBuffer.
*/
public async scanString(input: string): Promise<{ isInfected: boolean; reason?: string }> {
console.log('Scanning string:', input); // Debug the input string
const buffer = Buffer.from(input, 'utf8');
console.log('Converted buffer:', buffer.toString('utf8')); // Debug the converted buffer
return this.scanBuffer(buffer);
}
/**
* Verifies the ClamAV daemon is reachable.
*/
public async verifyConnection(): Promise<boolean> {
return new Promise((resolve, reject) => {
const client = new net.Socket();
client.connect(this.port, this.host, () => {
console.log('Successfully connected to ClamAV daemon');
client.end();
resolve(true);
});
client.on('error', (err) => {
console.error('Failed to connect to ClamAV daemon:', err);
reject(err);
});
});
}
}