#!/usr/bin/php
<?php

/*
 * VNag - Nagios Framework for PHP
 * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
 * Licensed under the terms of the Apache 2.0 license
 *
 * Revision 2018-11-06
 */

// Generate keypair with:
//	openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:8192
//	openssl rsa -pubout -in private.pem -out public.pem

if ($argc < 2) {
	die("Syntax: $argv[0] file1 [file2 ...]\n");
}

if (!file_exists(__DIR__.'/private.pem')) {
	echo "Key private.pem not found\n";
}

for ($i=1; $i<$argc; $i++) {
	$file = $argv[$i];

	$cont = file_get_contents($file);
	$original = $cont;

	if (strpos($cont, '<?php') === false) {
		echo "Not a PHP file: $file\n";
		continue;
	}

	$naked = preg_replace('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', '', $cont);

	$hash = hash("sha256", $naked.basename($file));

	$pkeyid = @openssl_pkey_get_private('file://'.__DIR__.'/private.pem');
	openssl_sign($hash, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
	openssl_free_key($pkeyid);

	if (!$signature) {
		echo "ERROR: $file\n";
		continue;
	}

	$sign_line = '<?php /* <ViaThinkSoftSignature>'."\n".split_equal_length(base64_encode($signature),65).'</ViaThinkSoftSignature> */ ?>';

	// We have to put the signature at the beginning, because we don't know if the end of the file lacks a PHP closing tag
	if (substr($cont,0,2) === '#!') {
		// Preserve shebang
		$shebang_pos = strpos($naked, "\n");
		$shebang = substr($naked, 0, $shebang_pos);
		$rest = substr($naked, $shebang_pos+1);
		$cont = $shebang."\n".$sign_line."\n".$rest;
	} else {
		$cont = $sign_line."\n".$naked;
	}

	if ($cont != $original) {
		echo "Signed: $file\n";
		file_put_contents($file, $cont);
	} else {
		echo "Already signed: $file\n";
	}
}

# ---

function split_equal_length($data, $width=65) {
	$out = '';
	for ($i=0; $i<strlen($data); $i+=$width) {
		$out .= substr($data, $i, $width)."\n";
	}
	return $out;
}

