#!/usr/bin/php
<?php
//error_reporting(0);
include('config.php');

/***
 * Main program - Don't edit below
 */
echo "·▄▄▄▄▄▌        .▄▄ · .▄▄ · \n▐▄▄·██•  ▪     ▐█ ▀. ▐█ ▀. \n██▪ ██▪   ▄█▀▄ ▄▀▀▀█▄▄▀▀▀█▄\n██▌.▐█▌▐▌▐█▌.▐▌▐█▄▪▐█▐█▄▪▐█\n▀▀▀ .▀▀▀  ▀█▄▀▪ ▀▀▀▀  ▀▀▀▀ \n";

foreach (glob("classes/*.php") as $filename)
    include $filename;

$definitions = new \Clapp\CommandLineArgumentDefinition(
    array(
        "help|h"            => "Shows help message",
        "path|p=s"          => "/path/to/jsons/"
    )
);

$filter = new \Clapp\CommandArgumentFilter($definitions, $argv);

if ($filter->getParam('h') === true || $argc < 2) {
	echo "The JSON prettyfier\n\n";
    fwrite(STDERR, $definitions->getUsage());
    exit(0);
} 

if(!file_exists($vulnDB."/floss.csv"))
    die("[!] floss.csv not found, is config.php correct?\n");

// create the CSV array
$csv = array();
$file = fopen($vulnDB."/floss.csv", 'r');
while (($result = fgetcsv($file)) !== false){
    $csv[] = $result;
}
fclose($file);

// see if doc exists 
if ($filter->getParam("path") == false)
	die("[-] no path set\n");

// load vdb vulns
$vdbVulns = getDirContents($vulnDB, '/\.json$/');
foreach($vdbVulns as $h => $i){ // remove begining of vdb path (keeps clean)
    $vdbVulns[$h] = str_replace($vulnDB, "", $i);
}
echo "VDB: ".sizeof($vdbVulns).", ";

// get all vulns
$vuln = array();
$files = glob($filter->getParam("path")."*.json");
foreach($files as $finding){
    $vuln[]['orig'] = str_replace(".json", "", str_replace($filter->getParam("path"), "", $finding));
}

echo "Vulns: ".sizeof($vuln)."\n";

// check for existing
foreach($vuln as $key => $finding){
    foreach($vdbVulns as $issue){
        $title = substr($issue, strrpos($issue, '/') + 1);
        if($finding['orig'].".json" == $title){
            $vuln[$key]['new'] = $issue;
            //echo $finding['orig']." -> ".$issue."\n"; // DEBUG
        }
    }
}

// check for pattern match in floss.csv
foreach($csv as $finding){
    foreach($vuln as $key => $issue){
        if(fnmatch($finding[0], $issue['orig'])){
            $vuln[$key]['new'] = $finding[1];
            //echo $issue['orig']." -> ".$finding[1]."\n"; // DEBUG
        }
    }
}

//print_r($vuln); // DEBUG

$flossFolder = substr($filter->getParam("path"), 0, strrpos( $filter->getParam("path"), '/') )."/flossed";
if(!file_exists($flossFolder."/")){
    mkdir($flossFolder."/");
    echo "[+] created directory $flossFolder/\n";
}
$checkFolder = substr($filter->getParam("path"), 0, strrpos( $filter->getParam("path"), '/') )."/to_check";
if(!file_exists($checkFolder."/")){
    mkdir($checkFolder."/");
    echo "[+] created directory $checkFolder/\n";
}

$flossed = 0;
$flossArr = array();
$fp = fopen($filter->getParam("path")."flossed/".date("d-m-Y_H-i-s").".log", "wb");
foreach($vuln as $key => $finding){
    if(isset($finding['new'])){

        $content = $finding['orig']." -> ".$finding['new']."\n"; // log changes
        fwrite($fp,$content);

        rename($filter->getParam("path").$finding['orig'].".json",$filter->getParam("path")."flossed/".$finding['orig'].".json");
        if($finding['new'] != "-del-"){
            $title = substr($finding['new'], strrpos($finding['new'], '/') + 1);
            copy($vulnDB.$finding['new'], $filter->getParam("path").$title);
            $flossArr[] = $finding['new'];
        }
        $flossed++;
    }else{
        rename($filter->getParam("path").$finding['orig'].".json",$filter->getParam("path")."to_check/".$finding['orig'].".json");
    }
}
fclose($fp);

$flossedInto = sizeof(array_unique($flossArr));
$left = sizeof($vuln)-$flossed;
echo "Flossed: ".$flossed." -> ".$flossedInto."\n";
echo "To Check: ".$left."\n";
echo "________________________________________________
|                                               |
|Please (on VDB) either add a rule to floss.csv |
|or create a new vulnerability for each .json   |
|in /to_check to help the team and make         |
|reporting easier for everyone!                 |
|_______________________________________________|\n";


function getDirContents($dir, $filter = '', &$results = array()) {
    $files = scandir($dir);

    foreach($files as $key => $value){
        $path = realpath($dir.DIRECTORY_SEPARATOR.$value); 

        if(!is_dir($path)) {
            if(empty($filter) || preg_match($filter, $path)) $results[] = $path;
        } elseif($value != "." && $value != "..") {
            getDirContents($path, $filter, $results);
        }
    }

    return $results;
} 
