mirror of https://github.com/keeweb/keeweb.git
chore: adjustments to tasks.grunt.virustotal
This commit is contained in:
parent
a90f01d9b3
commit
1f081efd39
|
@ -5,7 +5,7 @@ module.exports = function (grunt) {
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const fetch = require('node-fetch');
|
const got = require('got');
|
||||||
const FormData = require('form-data');
|
const FormData = require('form-data');
|
||||||
|
|
||||||
Promise.all(
|
Promise.all(
|
||||||
|
@ -16,6 +16,16 @@ module.exports = function (grunt) {
|
||||||
)
|
)
|
||||||
).then(done);
|
).then(done);
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert to a more suitable time
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formatMilliseconds(ms) {
|
||||||
|
const m = Math.floor(ms / 60000);
|
||||||
|
const s = ((ms % 60000) / 1000).toFixed(0);
|
||||||
|
return m + 'm ' + (s < 10 ? '0' : '') + s + 's';
|
||||||
|
}
|
||||||
|
|
||||||
async function checkFile(opt, file) {
|
async function checkFile(opt, file) {
|
||||||
grunt.log.writeln(`Uploading to VirusTotal: ${file}...`);
|
grunt.log.writeln(`Uploading to VirusTotal: ${file}...`);
|
||||||
|
|
||||||
|
@ -31,63 +41,67 @@ module.exports = function (grunt) {
|
||||||
|
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append('file', fileData, fileName);
|
form.append('file', fileData, fileName);
|
||||||
const fileUploadResp = await fetch('https://www.virustotal.com/api/v3/files', {
|
|
||||||
|
const fileUploadResp = await got('https://www.virustotal.com/api/v3/files', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers,
|
headers,
|
||||||
body: form
|
body: form
|
||||||
});
|
}).json();
|
||||||
const fileUploadRespData = await fileUploadResp.json();
|
|
||||||
if (fileUploadRespData.error) {
|
if (fileUploadResp.error) {
|
||||||
const errStr = JSON.stringify(fileUploadRespData.error);
|
const errStr = JSON.stringify(fileUploadResp.error);
|
||||||
throw new Error(`File upload error: ${errStr}`);
|
throw new Error(`File upload error: ${errStr}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = fileUploadRespData.data.id;
|
const id = fileUploadResp.data.id;
|
||||||
if (!id) {
|
if (!id) {
|
||||||
throw new Error('File upload error: empty id');
|
throw new Error('File upload error: empty id');
|
||||||
}
|
}
|
||||||
|
|
||||||
grunt.log.writeln(`Uploaded ${file} to VirusTotal, id: ${id}`);
|
grunt.log.writeln(`\nUploaded ${file} to VirusTotal, id: ${id}`.grey.bold);
|
||||||
|
|
||||||
let elapsed;
|
let elapsed;
|
||||||
do {
|
do {
|
||||||
const checkResp = await fetch(`https://www.virustotal.com/api/v3/analyses/${id}`, {
|
const checkResp = await fetch(`https://www.virustotal.com/api/v3/analyses/${id}`, {
|
||||||
headers
|
headers
|
||||||
});
|
});
|
||||||
|
|
||||||
const checkRespData = await checkResp.json();
|
const checkRespData = await checkResp.json();
|
||||||
if (checkRespData.error) {
|
if (checkRespData.error) {
|
||||||
const errStr = JSON.stringify(checkRespData.error);
|
const errStr = JSON.stringify(checkRespData.error);
|
||||||
throw new Error(`File check error: ${errStr}`);
|
throw new Error(`File check error: ${errStr}`.red.bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { attributes } = checkRespData.data;
|
const { attributes } = checkRespData.data;
|
||||||
if (attributes.status === 'completed') {
|
if (attributes.status === 'completed') {
|
||||||
const { stats } = attributes;
|
const { stats } = attributes;
|
||||||
if (stats.malicious > 0) {
|
if (stats.malicious > 0) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`File ${file} reported as malicious ${stats.malicious} time(s)`
|
`File ${file} reported as malicious ${stats.malicious} time(s)`.yellow.bold
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (stats.suspicious > 0) {
|
if (stats.suspicious > 0) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`File ${file} reported as malicious ${stats.suspicious} time(s)`
|
`File ${file} reported as malicious ${stats.suspicious} time(s)`.red.bold
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const statsStr = Object.entries(stats)
|
const statsStr = Object.entries(stats)
|
||||||
.map(([k, v]) => `${k}=${v}`)
|
.map(([k, v]) => `${k}=${v}`)
|
||||||
.join(', ');
|
.join(', ');
|
||||||
grunt.log.writeln(`VirusTotal check OK: ${file}, stats:`, statsStr);
|
grunt.log.writeln(`VirusTotal Check OK: ${file}, stats:`.green.bold, statsStr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsed = Date.now() - timeStarted;
|
elapsed = Date.now() - timeStarted;
|
||||||
|
const elapsedHuman = formatMilliseconds(elapsed);
|
||||||
grunt.log.writeln(
|
grunt.log.writeln(
|
||||||
`VirusTotal check status: ${attributes.status}, elapsed ${elapsed}ms`
|
`VirusTotal Status: ${attributes.status}, ${elapsedHuman}`.grey.bold
|
||||||
);
|
);
|
||||||
|
|
||||||
await wait(interval);
|
await wait(interval);
|
||||||
} while (elapsed < timeout);
|
} while (elapsed < timeout);
|
||||||
|
|
||||||
throw new Error(`Timed out after ${timeout}ms`);
|
throw new Error(`VirusTotal timed out after ${timeout}ms`.red.bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wait(ms) {
|
function wait(ms) {
|
||||||
|
|
Loading…
Reference in New Issue