<?php
/*
Important Note:
	When typing in passwords through a web browser, make sure the URL always starts with HTTPS.
	Otherwise the passwords are transmitted in plain text over the network and this defeats the purpose of encrypting the files.
*/
class custom_crypt {
	//var $disabled = true; //remove this line to enable the plugin
	function init() {
		$pathToAESCrypt = 'H:/apps/tools/aescrypt.exe'; //and set the path here

		$this->config = array(
			'encrypt_command' => $pathToAESCrypt.' -e -p [%pass%] [%filePath%]',
			'decrypt_command' => $pathToAESCrypt.' -d -p [%pass%] [%filePath%]',
			'encrypted_file_extension' => 'aes',
			'debug' => false,
			'localeSection' => 'Custom Actions: File Encryption'
		);
		$this->JSconfig = array(
			'title' => $this->getString('AES File Encryption'),
			'iconCls' => 'fa fa-fw fa-lock',
			'requiredUserPerms' => array('upload', 'alter'),
			'fn' => 'FR.customActions.crypt.run()'
		);
	}
	function getString($s) {
		global $locale, $str;
		return $str->safeJS($locale->get($s, $this->config['localeSection']));
	}
	function run() {
		global $locale, $fm, $log, $users, $str;
		if (!$users->userPerms->checkPerms("upload") || !$users->userPerms->checkPerms("download")) {
			jsonFeedback(false, $locale->get("The user doesn't have permission to use this function!", $this->config['localeSection']));
		} else {
			$deleteSrc = ($str->fromHTML($_POST['deleteSrc']) == 1 ? true : false);
			if (is_file($this->data['filePath'])) {
				$extension = $fm->getExtension($this->data['fileName']);
				session_write_close();
				if ($extension == $this->config['encrypted_file_extension']) {
					$targetFileName = str_replace(".".$this->config['encrypted_file_extension'], "", $this->data['fileName']);
					$targetPath = gluePath($this->data['path'], $targetFileName);
					if (!file_exists($targetPath)) {
						$rs = $this->decrypt();
						if ($rs) {
							if ($deleteSrc) {
								$this->deleteSource();
							}
							$log->add(false, "file_decrypted", array(
								"relative_path" => $this->data['relativePath'],
								"to_relative_path" => gluePath($fm->dirname($this->data['relativePath']), $targetFileName),
								"full_path" => $this->data['filePath'],
								"to_full_path" => $targetPath,
								"method" => "AES"
							), $this->data['filePath']);
							jsonFeedback(true, $locale->get("The selected file was successfully decrypted.", $this->config['localeSection']));
						} else {
							jsonFeedback(false, $locale->get("Failed to decrypt the selected file!", $this->config['localeSection']));
						}
					} else {
						jsonFeedback(false, $locale->get("A file named \"%1\" already exists!", $this->config['localeSection'], array($targetFileName)));
					}
				} else {
					$targetFileName = $this->data['fileName'].".".$this->config['encrypted_file_extension'];
					$targetPath = gluePath($this->data['path'], $targetFileName);
					if (!file_exists($targetPath)) {
						$rs = $this->encrypt();
						if ($rs) {
							if ($deleteSrc) {
								$this->deleteSource();
							}
							$log->add(false, "file_encrypted", array(
								"relative_path" => $this->data['relativePath'],
								"to_relative_path" => gluePath($fm->dirname($this->data['relativePath']), $targetFileName),
								"full_path" => $this->data['filePath'],
								"to_full_path" => $targetPath,
								"method" => "AES"
							), $this->data['filePath']);
							jsonFeedback(true, $locale->get("The selected file was successfully encrypted.", $this->config['localeSection']));
						} else {
							jsonFeedback(false, $locale->get("Failed to encrypt the selected file!", $this->config['localeSection']));
						}
					} else {
						jsonFeedback(false, $locale->get("A file named \"%1\" already exists!", $this->config['localeSection'], array($targetFileName)));
					}
				}
			} else {
				jsonFeedback(false, $locale->get("The selected file was not found!", $this->config['localeSection']));
			}
		}
	}
	function JSinclude() {
		include(gluePath($this->path, "include.js.php"));
	}
	function encrypt() {
		$cmd = $this->parseCmd($this->config['encrypt_command']);
		return $this->runCmd($cmd);
	}
	function decrypt() {
		$cmd = $this->parseCmd($this->config['decrypt_command']);
		return $this->runCmd($cmd);
	}
	function parseCmd($cmd) {
		global $str;
		return str_replace(
			array("[%pass%]", "[%filePath%]"), 
			array($this->escapeshellarg($str->fromHTML($_POST['pass'])), $this->escapeshellarg($this->data['filePath'])),
		$cmd);
	}
	function escapeshellarg($s) {
		return '"'.addslashes($s).'"';
	}
	function deleteSource() {
		global $myfiles, $fm;
		return $myfiles->deleteFile($fm->dirname($this->data['relativePath']), $this->data['fileName'], $permanent = false);
	}
	function runCmd($cmd) {
		@exec($cmd, $return_text, $return_code);
		if ($return_code != 0) {
			if ($this->config['debug']) {
				echo " * command: ".$cmd."<br>";
				echo " * returned code: ".$return_code."<br>";
				echo " * returned text: "; print_r($return_text);
				flush();
			}
			return false;
		} else {
			return true;
		}
	}
}
