From 9282e770f4db5fa670a5d1f9ca16c38aa7e31119 Mon Sep 17 00:00:00 2001 From: Matt Lowe Date: Sat, 16 Nov 2013 16:36:46 +0000 Subject: [PATCH 1/5] Added first version of the IonCube encoder extension task This allows you to encrypt a project prior to pushing it to a server. --- Mage/Task/BuiltIn/Ioncube/EncryptTask.php | 669 ++++++++++++++++++++++ 1 file changed, 669 insertions(+) create mode 100644 Mage/Task/BuiltIn/Ioncube/EncryptTask.php diff --git a/Mage/Task/BuiltIn/Ioncube/EncryptTask.php b/Mage/Task/BuiltIn/Ioncube/EncryptTask.php new file mode 100644 index 0000000..1b6779b --- /dev/null +++ b/Mage/Task/BuiltIn/Ioncube/EncryptTask.php @@ -0,0 +1,669 @@ + + * + */ +namespace Mage\Task\BuiltIn\Ioncube; + +use Mage\Task\AbstractTask; +use Mage\Console; +use Mage\Task\ErrorWithMessageException; +use Mage\Task\ErrorWithMessageException; +use Mage\Task\ErrorWithMessageException; +use Mage\Task\ErrorWithMessageException; +use Mage\Task\ErrorWithMessageException; + +class EncryptTask extends AbstractTask { + /** + * Name of the task + * + * @var string + */ + private $name = 'IonCube Encoder'; + + /** + * Array of default Ioncube + * options + * + * @var array + */ + private $default = array (); + + /** + * Array of YAML Ioncube + * options + * + * @var array + */ + private $yaml = array (); + + /** + * Array of file Ioncube + * options (taken from additional + * external config file if supplied) + * + * @var array + */ + private $file = array (); + + /** + * Source directory as used by + * main scripts + * + * @var string + */ + private $source = ''; + + /** + * Name of tempory folder + * for source code to be moved + * to. + * + * @var string + */ + private $ionSource = ''; + + /** + * How the default/yaml/project + * files interact with each other + * + * @var string + */ + private $ionOverRide = ''; + + /** + * Config options from the + * enviroment config file + * + * @var array + */ + private $mageConfig = array (); + + /** + * Final version of the IonCube + * options, after merging all + * sources together + * + * @var array + */ + private $ionCubeConfig = array (); + + /** + * Default encoder version to use + * for the ioncube encoder + * + * @var string + */ + private $encoder = 'ioncube_encoder54'; + + /** + * Name of tempory IonCube Project + * file, used when running encoder + * + * @var string + */ + private $projectFile = ''; + + /** + * (non-PHPdoc) + * + * @see \Mage\Task\AbstractTask::getName() + */ + public function getName() { + return $this->name; + } + + /** + * (non-PHPdoc) + * + * @see \Mage\Task\AbstractTask::init() + */ + public function init() { + // Get any options specfic to this task + $this->mageConfig = $this->getConfig ()->environmentConfig( 'ioncube' ); + /* + * Get all our IonCube config options + */ + $this->_getAllIonCubeConfigs(); + /* + * get the source code location + */ + $this->source = $this->getConfig ()->deployment ( 'from' ); + /* + * remove trailing slash if present + */ + if (substr ( $this->source, - 1 ) == DIRECTORY_SEPARATOR) { + $this->source = substr ( $this->source, 0, - 1 ); + } + /* + * Set the name of the folder that the un-encrypted + * files will be moved into + */ + $this->ionSource = $this->source . '.raw'; + /* + * set the filename for the ioncube project build file + */ + $this->projectFile = $this->source . '.prj'; + /* + * Check if we have been given an encoder script + * If not then we will just use the default + */ + if (isset ( $this->mageConfig ['encoder'] )) { + $this->encoder = $this->mageConfig ['encoder']; + } + /* + * Check if a differant merge type has been + * supplied, this defines how the 3 differant + * config files will be merged together. + */ + if (isset ( $this->mageConfig ['override'] )) { + $this->ionOverRide = $this->mageConfig ['override']; + } + /* + * now merge all the config options together + */ + $this->ionCubeConfig = $this->mergeConfigFiles (); + } + + /** + * This gets all the Ioncube configs + * Basicly it gets the default options contianed within this script + * It reads any project options from the enviroment.yaml config file + * It reads any additional options from external project file if set + * + * @return void + */ + private function _getAllIonCubeConfigs() + { + + /* + * Get a set of default IonCube options + */ + $this->default = $this->getOptionsDefault (); + /* + * Check if there is a 'project' section, + * if so then get the options from there + */ + if (isset ( $this->mageConfig ['project'] )) { + $this->yaml = $this->getOptionsFromYaml ( $this->mageConfig ['project'] ); + } else { + $this->yaml = array ( + 's' => array (), + 'p' => array () + ); + } + /* + * Check if a seperate projectfile has been specified, and if so + * then read the options from there. + */ + if (isset ( $this->mageConfig ['projectfile'] )) { + $this->file = $this->getOptionsFromFile ( $this->mageConfig ['projectfile'] ); + } else { + $this->file = array ( + 's' => array (), + 'p' => array () + ); + } + } + + + /** + * Encrypt the project + * Steps are as follows : + * Switch our current source dir to the ioncube srouce dir and create new empty dir to encrypt into + * Write the IonCube project file (this is the file that controls IonCube encoder) + * Run IonCube encoder + * Delete the tempory files that we created (so long as we hadn't set 'keeptemp') + * Return the result of the IonCube encoder + * + * @see \Mage\Task\AbstractTask::run() + * + * @return bool + */ + public function run() { + $this->switchSrcToTmp (); + $this->writeProjectFile (); + $result = $this->runIonCube (); + $this->deleteTmpFiles (); + return $result; + } + + /** + * Deletes tempory folder and project file + * if 'keeptemp' is set then skips delete + * process + * + * @throws ErrorWithMessageException If there was a problem with deleting the tempory files + * + * @return void + */ + private function deleteTmpFiles() { + if (isset ( $this->mageConfig ['keeptemp'] )) { + return; + } + $ret1 = $this->runCommandLocal ( 'rm -Rf ' . $this->ionSource, $out1 ); + $ret2 = $this->runCommandLocal ( 'rm ' . $this->projectFile, $out2 ); + if ($ret1 && $ret2) { + return; + } + throw new ErrorWithMessageException ( 'Error deleting temp files :' . $out1 . ' : ' . $out2, 40 ); + } + + /** + * Builds the ioncube command + * and runs it, returning the result + * + * @return bool + */ + private function runIonCube() { + $cli = $this->encoder . ' --project-file ' . $this->projectFile . ' ' . $this->ionSource . DIRECTORY_SEPARATOR.'*'; + $ret = $this->runCommandLocal ( $cli, $out ); + return $ret; + } + + /** + * Write the config options into + * a project file ready for use + * with ioncube cli + * + * @throws ErrorWithMessageException If it cant write the project file + * + * @return void + */ + private function writeProjectFile() { + // array used to build config file into + $out = array (); + // set the project destination + $out [] = '--into ' . $this->source . PHP_EOL; + // output the switches + foreach ( $this->ionCubeConfig ['s'] as $key => $value ) { + if ($value) { + // switch was set to true, so output it + $out [] = '--' . $key . PHP_EOL; + } + } + // output the options + foreach ( $this->ionCubeConfig ['p'] as $key => $value ) { + // check if we have an array of values + if (is_array ( $value )) { + foreach ( $value as $entry ) { + $out [] = '--' . $key . ' "' . $entry . '"' . PHP_EOL; + } + } else { + // ok just a normal single option + if (strlen ( $value ) > 0) { + $out [] = '--' . $key . ' "' . $value . '"' . PHP_EOL; + } + } + } + $ret = file_put_contents ( $this->projectFile, $out ); + if (! $ret) { + // something went wrong + $this->deleteTmpFiles (); + throw new ErrorWithMessageException ( 'Unable to create project file.', 20 ); + } + } + + /** + * This merges the 3 config arrays + * depending on the 'override' option + * + * @return array Final config array + */ + private function mergeConfigFiles() { + /* + * Options are the order the arrays are in + * F - Project File + * Y - YAML config options (enviroment file) + * D - Default options as stored in script + * + * more options could be added to make this a bit more flexable + * @todo I'm sure this could be combined into a loop to make it easier and shorter + * + */ + $s = array (); + $p = array (); + switch (strtolower ( $this->ionOverRide )) { + case 'fyd' : + // FILE / YAML / DEFAULT + $s = array_merge ( $this->file ['s'], $this->yaml ['s'], $this->default ['s'] ); + $p = array_merge ( $this->file ['p'], $this->yaml ['p'], $this->default ['p'] ); + break; + + case 'yfd' : + // YAML / FILE / DEFAULT + $s = array_merge ( $this->yaml ['s'], $this->file ['s'], $this->default ['s'] ); + $p = array_merge ( $this->yaml ['p'], $this->file ['p'], $this->default ['p'] ); + break; + case 'dyf' : + // DEFAULT / YAML / FILE + $s = array_merge ( $this->default ['s'], $this->yaml ['s'], $this->file ['s'] ); + $p = array_merge ( $this->default ['p'], $this->yaml ['p'], $this->file ['p'] ); + break; + case 'd' : + default : + // Use defaults only + $s = $this->default ['s']; + $p = $this->default ['p']; + break; + } + return array ( + 's' => $s, + 'p' => $p + ); + } + + /** + * Switches the original source + * code dir to tempory name + * and recreates orginal dir + * allows encryption to be done + * into source dir, so other functions + * work without changing + * + * @throws ErrorWithMessageException If source dir can't be renamed + * @throws ErrorWithMessageException If original source dir cant be created + * + * @return bool + */ + private function switchSrcToTmp() { + echo "Switching :" . $this->source . " -> "; + echo "To :" . $this->ionSource . "\n"; + $ret = $this->runCommandLocal ( 'mv ' . $this->source . ' ' . $this->ionSource, $out ); + if (! $ret) { + throw new ErrorWithMessageException ( 'Cant create tmp dir :' . $out, $ret ); + } + $ret = $this->runCommandLocal ( 'mkdir -p ' . $this->source, $out ); + if (! $ret) { + throw new ErrorWithMessageException ( 'Cant re-create dir :' . $out, $ret ); + } + return true; + } + + /** + * Reads a set of options taken from the YAML config + * Compares keys against the default ioncube settings + * if a key doesnt appear in the default options, it + * is ignored + * + * return array + */ + private function getOptionsFromYaml($options) { + $s = array (); + $p = array (); + foreach ( $options as $key => $value ) { + if (array_key_exists ( $key, $this->default ['s'] )) { + $s [$key] = true; + } + if (array_key_exists ( $key, $this->default ['p'] )) { + $p [$key] = $value; + } + } + return array ( + 's' => $s, + 'p' => $p + ); + } + + /** + * reads an existing ioncube project + * file. + * + * @return array + */ + private function getOptionsFromFile($fileName) { + $s = array (); + $p = array (); + $fileContents = file_get_contents ( $fileName ); + /* + * split the config file on every occurance of '--' at start of a line + * Adds a PHP_EOL at the start, so we can catch the first '--' + */ + $entrys = explode ( PHP_EOL . '--', PHP_EOL . $fileContents ); + foreach ( $entrys as $line ) { + $line = trim ( $line ); + if ($line != '') { + /* + * get position of first space + * so we can split the options out + */ + $str = strpos ( $line, ' ' ); + if ($str === false) { + /* + * Ok, no spaces found, so take this as a single line + */ + $str = strlen ( $line ); + } + $key = substr ( $line, $str ); + $value = substr ( $line, $str + 1 ); + if ((array_key_exists ( $key, $this->default ['s'] ))) { + /* + * ok this key appears in the switch config + * so store it as a switch + */ + $s [$key] = true; + } + if ((array_key_exists ( $key, $this->default ['p'] ))) { + /* + * Ok this key exists in the parameter section, + * So store it allong with its value + */ + $p [$key] = $this->splitParam ( $value ); + } + } + } + return array ( + 's' => $s, + 'p' => $p + ); + } + + /** + * Takes supplied line and splits it if required + * into an array + * returns ether the array, or a plain + * string. + * Allows options to be spread accross several lines + * + * @param $string String to split + * + * @return mixed + */ + private function splitParam($string) { + $split = explode ( PHP_EOL, $string ); + if ($split === false) { + // nothing found, so return a blank string + return ''; + } + if (count ( $split ) == 1) { + return $split [0]; + } else { + return $split; + } + } + + /** + * returns an array of default ioncube options + * This is also used as a 'filter' for the YAML + * and Config files, if an option hasnt got an + * entry in this list, then it can not be set + * via the VAML or Config files + * + * @return array + */ + private function getOptionsDefault() { + $s = array (); + $p = array (); + // Set the switches + $s ['allow-encoding-into-source'] = false; + + $s ['ascii'] = false; + $s ['binary'] = true; + + $s ['replace-target'] = true; + $s ['merge-target'] = false; + $s ['rename-target'] = false; + $s ['update-target'] = false; + + $s ['only-include-encoded-files'] = false; + + $s ['use-hard-links'] = false; + + $s ['without-keeping-file-perms'] = false; + $s ['without-keeping-file-times'] = false; + $s ['without-keeping-file-owner'] = false; + + $s ['no-short-open-tags'] = false; + + $s ['ignore-strict-warnings'] = false; + $s ['ignore-deprecated-warnings'] = false; + + $s ['without-runtime-loader-support'] = false; + $s ['without-loader-check'] = false; + + $s ['disable-auto-prepend-append'] = true; + + $s ['no-doc-comments'] = true; + + // Now set the params + $p ['encrypt'] [] = '*.tpl.html'; + $p ['encode'] = array (); + $p ['copy'] = array (); + $p ['ignore'] = array ( + '.git', + '.svn', + '.mage', + '.gitignore', + '.gitkeep', + 'nohup.out' + ); + $p ['keep'] = array (); + $p ['obfuscate'] = ''; + $p ['obfuscation-key'] = ''; + $p ['obfuscation-exclusion-file'] = ''; + $p ['expire-in'] = '7d'; + $p ['expire-on'] = ''; + $p ['allowed-server'] = ''; + $p ['with-license'] = 'license.txt'; + $p ['passphrase'] = ''; + $p ['license-check'] = ''; + $p ['apply-file-user'] = ''; + $p ['apply-file-group'] = ''; + $p ['register-autoglobal'] = array (); + $p ['message-if-no-loader'] = ''; + $p ['action-if-no-loader'] = ''; + $p ['loader-path'] = ''; + $p ['preamble-file'] = ''; + $p ['add-comment'] = array (); + $p ['add-comments'] = ''; + $p ['loader-event'] = array (); + $p ['callback-file'] = ''; + $p ['property'] = ''; + $p ['propertys'] = ''; + $p ['include-if-property'] = array (); + $p ['optimise'] = 'max'; + $p ['shell-script-line'] = ''; + $p ['min-loader-version'] = ''; + + return array ( + 's' => $s, + 'p' => $p + ); + } +} +/** + * + * Example evirmonment YAML file : + * +#master +deployment: + user: marl + from: ./ + to: /var/www/test1 + source: + type: git + repository: git@bitbucket.org:myuser/myproject.git + from: master + ioncube: test + +releases: + enabled: true + symlink: current + directory: releases +hosts: + - localhost +tasks: + pre-deploy: + - ioncube/encrypt + on-deply: + post-deploy: + + ioncube: + override: dyf + keeptemp: + encoder: ioncube_encoder54 + projfile: project.prj + project: + replace-target: + binary: + ignore-deprecated-warnings: + ignore-strict-warnings: + ignore: + - _* + - templates_c/* + - *~ + - database.md + - specs/ + - composer.json + - README.md + - .git/ + - .project + - .settings/ + - .buildpath + message-if-no-loader: "System error No Loader" + passphrase: "My really secure passphrase" + encrypt: + - templates/* + add-comment: + - 'Comment 1' + - 'Comment 2' + - "(c) ACTweb 2013" + - "Draft Version" + + loader-event: + - corrupt-file=Corupted files + - expired-file=System needs updated + - no-permissions=Not allowed on this server + - clock-skew=Time incorect + - license-not-found=License not installed + - license-corrupt=Something wrong with your license + - license-expired=Out of time + - license-property-invalid=Invalid license data + - license-header-invalid=Files corupted + - license-server-invalid=Server problem + - unauth-including-file=Sorry these files can only be used within defined software + - unauth-included-file=Crtical Software Error + - unauth-append-prepend-file=System can not be used with PHP Prepend/Append set + + */ From 5fe1fdc168a15756e8642c1234946acdacf5fc97 Mon Sep 17 00:00:00 2001 From: Matt Lowe Date: Thu, 21 Nov 2013 14:11:45 +0000 Subject: [PATCH 2/5] adding new 'check encryption' function, to check that all files have been encrypted/encoded, and prompt user to confirm if the deploy should continue if any files are found to not be encoded. TEST - DO NOT USE! --- Mage/Task/BuiltIn/Ioncube/EncryptTask.php | 155 +++++++++++++++++++++- 1 file changed, 148 insertions(+), 7 deletions(-) diff --git a/Mage/Task/BuiltIn/Ioncube/EncryptTask.php b/Mage/Task/BuiltIn/Ioncube/EncryptTask.php index 1b6779b..baca28d 100644 --- a/Mage/Task/BuiltIn/Ioncube/EncryptTask.php +++ b/Mage/Task/BuiltIn/Ioncube/EncryptTask.php @@ -14,6 +14,9 @@ * in rsync and other tasks to operate * on the encrypted files. * + * IonCube PHP Encoder can be downloaded from + * http://www.actweb.info/ioncube.html + * * Example enviroment.yaml file at end * * @todo add support for creating license files. @@ -29,10 +32,6 @@ namespace Mage\Task\BuiltIn\Ioncube; use Mage\Task\AbstractTask; use Mage\Console; use Mage\Task\ErrorWithMessageException; -use Mage\Task\ErrorWithMessageException; -use Mage\Task\ErrorWithMessageException; -use Mage\Task\ErrorWithMessageException; -use Mage\Task\ErrorWithMessageException; class EncryptTask extends AbstractTask { /** @@ -125,6 +124,33 @@ class EncryptTask extends AbstractTask { */ private $projectFile = ''; + /** + * If true then run a check on + * all files after encoding and + * report which ones are not encoded + * if any are found to not be encoded + * then prompt if we should continue + * with the process + * If not then clean up the temp files + * and exit with cancled code. + * + * @var bool + */ + private $checkEncoding = false; + + /** + * List of file extensions to exclude + * from encrypted/encoded test + * + * @var array + */ + private $ignoreExtens = array( + 'jpg', + 'jpeg', + 'png', + 'js', + ); + /** * (non-PHPdoc) * @@ -142,6 +168,8 @@ class EncryptTask extends AbstractTask { public function init() { // Get any options specfic to this task $this->mageConfig = $this->getConfig ()->environmentConfig( 'ioncube' ); + var_dump($this->mageConfig); + exit; /* * Get all our IonCube config options */ @@ -180,6 +208,22 @@ class EncryptTask extends AbstractTask { if (isset ( $this->mageConfig ['override'] )) { $this->ionOverRide = $this->mageConfig ['override']; } + /* + * Check if we have been asked to + * confirm all encodings + */ + if (isset ( $this->mageConfig ['checkencoding'])) { + $this->checkEncoding=true; + } + /* + * Check if we have been passed any extra + * file extensions to exclude from + * encrypt/encode file check + * + */ + if (isset ( $this->mageConfig ['ignoreextens'])) { + $this->ignoreExtens=array_merge($this->ignoreExtens, $this->mageConfig['ignoreextens']); + } /* * now merge all the config options together */ @@ -245,10 +289,106 @@ class EncryptTask extends AbstractTask { $this->switchSrcToTmp (); $this->writeProjectFile (); $result = $this->runIonCube (); + exit; + echo "Encoding result :".($result ? 'True' : 'False')."\n"; + if (($this->checkEncoding) && ($this->checkEncoding())) { + $result=true; + } $this->deleteTmpFiles (); + exit; return $result; } + /** + * Runs through all files in the encoded + * folders and lists any that are not + * encoded. If any are found then prompt + * user to continue or quit. + * If user quites, then clean out encoded + * files, and return true to indicate error + * + * @return bool + */ + private function checkEncoding() { + $src = $this->source; + $ask=false; + $rit = new RecursiveDirectoryIterator ( $src ); + foreach ( new RecursiveIteratorIterator ( $rit ) as $filename => $cur ) { + $exten=pathinfo($filename, PATHINFO_EXTENSION); + if (!array_key_exists($strtolower($exten), $this->ignoreExtens)) { + // ok, this extension needs to be checked + if ($this->checkFile($filename)) { + // file was encrypted/encoded + } else { + // file was not encrypted/encoded + echo "File :".$filename." -> Was not encrypted\n"; + $ask=true; + } + } + } + if ($ask) { + // ok lets ask the user if they want to procede + echo "\n\nDo you wish to procede (y/N):"; + $key=strtolower($this->inKey(array('y', 'Y', 'N', 'n', ''))); + if ($key!='y') { + return true; + } + } + return false; + } + + /** + * This simply wiats for a single + * key press, and returns it + * + * @param array $vals Array of posible key presses + * + * @return string + */ + private function inKey($vals) { + $inKey = ""; + While(!in_array($inKey,$vals)) { + $inKey = trim(`read -s -n1 valu;echo \$valu`); + } + return $inKey; + } + + /** + * This will take the passed file and try to + * work out if it is an encoded/encrypted + * ioncube file. + * It dosent test the file exten, as it + * expects the calling method to have done + * that before. + * + * @param string $filename Filename, with path, to check + * + * @return boolean True if file was encoded/encrypted + */ + private function checkFileCoding($filename) { + // check to see if this is an encrypted file + $ioncube = ioncube_read_file ( $filename, $ioncubeType ); + if (is_int ( $ioncube )) { + // we got an error from ioncube, so its encrypted + return true; + } + // read first line of file + $f = fopen ( $filename, 'r' ); + $line = trim ( fgets ( $f, 32 ) ); + fclose ( $f ); + // if first line is longer than 30, then this isnt a php file + if (strlen ( $line ) > 30) { + return false; + } + // if first line starts 'source . " -> "; - echo "To :" . $this->ionSource . "\n"; + echo "\nSwitching :" . $this->source . " -> To :" . $this->ionSource."\n"; $ret = $this->runCommandLocal ( 'mv ' . $this->source . ' ' . $this->ionSource, $out ); if (! $ret) { throw new ErrorWithMessageException ( 'Cant create tmp dir :' . $out, $ret ); @@ -596,6 +735,8 @@ class EncryptTask extends AbstractTask { * * Example evirmonment YAML file : * + */ +$example=<< Date: Fri, 22 Nov 2013 13:03:37 +0000 Subject: [PATCH 3/5] Added method to allow checking the source code once IonCube has run for any un-encoded/encrypted files. This checks against an array of file extens (used mainly to exclude images and javascript etc.) It also checks against an array of paths/filenames. These 2 should maybe be combined into a single array? If any files are found to not be encoded and havnt been excluded, then user is prompted to confirm they wish to proced. This is designed as a last confirmation that you have encoded all the files that you need, and are not about to push unsecured files to a server. --- Mage/Task/BuiltIn/Ioncube/EncryptTask.php | 145 +++++++++++++++------- 1 file changed, 101 insertions(+), 44 deletions(-) diff --git a/Mage/Task/BuiltIn/Ioncube/EncryptTask.php b/Mage/Task/BuiltIn/Ioncube/EncryptTask.php index baca28d..f3edb7d 100644 --- a/Mage/Task/BuiltIn/Ioncube/EncryptTask.php +++ b/Mage/Task/BuiltIn/Ioncube/EncryptTask.php @@ -144,12 +144,18 @@ class EncryptTask extends AbstractTask { * * @var array */ - private $ignoreExtens = array( - 'jpg', - 'jpeg', - 'png', - 'js', - ); + private $checkIgnoreExtens = array(); + + /** + * List of paths to exclude from + * encrypted/encoded test + * Paths must begin with '/' + * and are all relative to the + * project root + * + * @var array + */ + private $checkIgnorePaths = array(); /** * (non-PHPdoc) @@ -166,10 +172,22 @@ class EncryptTask extends AbstractTask { * @see \Mage\Task\AbstractTask::init() */ public function init() { + // Set the default extensions to ignore + $this->checkIgnoreExtens = array ( + 'jpg', + 'jpeg', + 'png', + 'js', + 'gif', + 'css', + 'ttf', + 'svg', + 'map', + 'ico', + + ); // Get any options specfic to this task - $this->mageConfig = $this->getConfig ()->environmentConfig( 'ioncube' ); - var_dump($this->mageConfig); - exit; + $this->mageConfig = $this->getConfig()->environmentConfig( 'ioncube' ); /* * Get all our IonCube config options */ @@ -221,9 +239,21 @@ class EncryptTask extends AbstractTask { * encrypt/encode file check * */ - if (isset ( $this->mageConfig ['ignoreextens'])) { - $this->ignoreExtens=array_merge($this->ignoreExtens, $this->mageConfig['ignoreextens']); + if (isset ( $this->mageConfig ['checkignoreextens'])) { + $this->checkIgnoreExtens=array_merge($this->ignoreExtens, $this->mageConfig['ignoreextens']); } + + /* + * Check if we have been passed any extra + * file paths/files to exclude from + * encrypt/encode file check + * + */ + if (isset ( $this->mageConfig ['checkignorepaths'])) { + $this->checkIgnorePaths=array_merge($this->checkIgnorePaths, $this->mageConfig['checkignorepaths']); + } + + /* * now merge all the config options together */ @@ -289,13 +319,16 @@ class EncryptTask extends AbstractTask { $this->switchSrcToTmp (); $this->writeProjectFile (); $result = $this->runIonCube (); - exit; - echo "Encoding result :".($result ? 'True' : 'False')."\n"; - if (($this->checkEncoding) && ($this->checkEncoding())) { - $result=true; + Console::output("Encoding result :".($result ? 'OK' : 'Bad!')."\n", 0, 2); + if (!$result) { + $this->deleteTmpFiles (); + throw new ErrorWithMessageException('Ioncube failed to encode your project :'.$result); + } + if (($this->checkEncoding) && (!$this->checkEncoding())) { + $this->deleteTmpFiles(); + throw new ErrorWithMessageException('Operation canceled by user.'); } $this->deleteTmpFiles (); - exit; return $result; } @@ -311,46 +344,67 @@ class EncryptTask extends AbstractTask { */ private function checkEncoding() { $src = $this->source; - $ask=false; - $rit = new RecursiveDirectoryIterator ( $src ); - foreach ( new RecursiveIteratorIterator ( $rit ) as $filename => $cur ) { - $exten=pathinfo($filename, PATHINFO_EXTENSION); - if (!array_key_exists($strtolower($exten), $this->ignoreExtens)) { - // ok, this extension needs to be checked - if ($this->checkFile($filename)) { - // file was encrypted/encoded - } else { - // file was not encrypted/encoded - echo "File :".$filename." -> Was not encrypted\n"; - $ask=true; + // $ask holds flag to indicate we need to prompt the end user + $ask = false; + // scan through the directory + $rit = new \RecursiveDirectoryIterator ( $src ); + foreach ( new \RecursiveIteratorIterator ( $rit ) as $filename => $cur ) { + // get the 'base dir' for the project, eg. relative to the temp folder + $srcFileName = (str_replace ( $this->source, '', $filename )); + /* + * Scan through the ignor directorys array + * and if it matches the current path/filename + * then mark the file to be skipped from testing + */ + $skip = false; + foreach ( $this->checkIgnorePaths as $path ) { + if (fnmatch ( $path, $srcFileName )) { + $skip = true; + } + } + // check if we should test this file + if (! $skip) { + // get the file exten for this file and compare to our fileexten exclude array + $exten = pathinfo ( $filename, PATHINFO_EXTENSION ); + if (! in_array ( strtolower ( $exten ), $this->checkIgnoreExtens )) { + // ok, this extension needs to be checked + if ($this->checkFileCoding ( $filename )) { + // file was encrypted/encoded + } else { + // file was not encrypted/encoded + Console::output("File :" . $srcFileName . " -> Was not encrypted", 0, 1); + $ask = true; + } } } } if ($ask) { // ok lets ask the user if they want to procede - echo "\n\nDo you wish to procede (y/N):"; - $key=strtolower($this->inKey(array('y', 'Y', 'N', 'n', ''))); - if ($key!='y') { - return true; + Console::output("\n\nDo you wish to procede (y/N):", 0, 0); + if (! $this->promptYn ()) { + return false; } } - return false; + + return true; } /** - * This simply wiats for a single - * key press, and returns it + * This simply for user to enter + * 'y' or 'Y' and press enter, if + * a single 'y' is not entered then + * false is returned, otherwise + * true is returned. * - * @param array $vals Array of posible key presses - * - * @return string + * @return bool True if 'y' pressed */ - private function inKey($vals) { - $inKey = ""; - While(!in_array($inKey,$vals)) { - $inKey = trim(`read -s -n1 valu;echo \$valu`); + private function promptYn() { + $handle = fopen ("php://stdin","r"); + $line = strtolower(fgets($handle)); + if(trim($line) != 'y'){ + return false; } - return $inKey; + return true; } /** @@ -402,11 +456,14 @@ class EncryptTask extends AbstractTask { if (isset ( $this->mageConfig ['keeptemp'] )) { return; } + Console::log('Deleting tempory files :', 0); $ret1 = $this->runCommandLocal ( 'rm -Rf ' . $this->ionSource, $out1 ); $ret2 = $this->runCommandLocal ( 'rm ' . $this->projectFile, $out2 ); if ($ret1 && $ret2) { + Console::log('OK',0); return; } + Console::log('Failed!', 1); throw new ErrorWithMessageException ( 'Error deleting temp files :' . $out1 . ' : ' . $out2, 40 ); } @@ -528,7 +585,7 @@ class EncryptTask extends AbstractTask { * @return bool */ private function switchSrcToTmp() { - echo "\nSwitching :" . $this->source . " -> To :" . $this->ionSource."\n"; + //echo "\nSwitching :" . $this->source . " -> To :" . $this->ionSource."\n"; $ret = $this->runCommandLocal ( 'mv ' . $this->source . ' ' . $this->ionSource, $out ); if (! $ret) { throw new ErrorWithMessageException ( 'Cant create tmp dir :' . $out, $ret ); From f864fa7b8e20dad71d7b5265feff83041ec8424a Mon Sep 17 00:00:00 2001 From: Matt Lowe Date: Fri, 22 Nov 2013 13:06:31 +0000 Subject: [PATCH 4/5] updated sample config file at end of script --- Mage/Task/BuiltIn/Ioncube/EncryptTask.php | 109 +++++++++++----------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/Mage/Task/BuiltIn/Ioncube/EncryptTask.php b/Mage/Task/BuiltIn/Ioncube/EncryptTask.php index f3edb7d..37323a7 100644 --- a/Mage/Task/BuiltIn/Ioncube/EncryptTask.php +++ b/Mage/Task/BuiltIn/Ioncube/EncryptTask.php @@ -456,14 +456,12 @@ class EncryptTask extends AbstractTask { if (isset ( $this->mageConfig ['keeptemp'] )) { return; } - Console::log('Deleting tempory files :', 0); - $ret1 = $this->runCommandLocal ( 'rm -Rf ' . $this->ionSource, $out1 ); - $ret2 = $this->runCommandLocal ( 'rm ' . $this->projectFile, $out2 ); + Console::log('Deleting tempory files :', 1); + $ret1 = Console::executeCommand ( 'rm -Rf ' . $this->ionSource, $out1 ); + $ret2 = Console::executeCommand ( 'rm ' . $this->projectFile, $out2 ); if ($ret1 && $ret2) { - Console::log('OK',0); return; } - Console::log('Failed!', 1); throw new ErrorWithMessageException ( 'Error deleting temp files :' . $out1 . ' : ' . $out2, 40 ); } @@ -475,7 +473,7 @@ class EncryptTask extends AbstractTask { */ private function runIonCube() { $cli = $this->encoder . ' --project-file ' . $this->projectFile . ' ' . $this->ionSource . DIRECTORY_SEPARATOR.'*'; - $ret = $this->runCommandLocal ( $cli, $out ); + $ret = Console::executeCommand ( $cli, $out ); return $ret; } @@ -586,11 +584,11 @@ class EncryptTask extends AbstractTask { */ private function switchSrcToTmp() { //echo "\nSwitching :" . $this->source . " -> To :" . $this->ionSource."\n"; - $ret = $this->runCommandLocal ( 'mv ' . $this->source . ' ' . $this->ionSource, $out ); + $ret = Console::executeCommand ( 'mv ' . $this->source . ' ' . $this->ionSource, $out ); if (! $ret) { throw new ErrorWithMessageException ( 'Cant create tmp dir :' . $out, $ret ); } - $ret = $this->runCommandLocal ( 'mkdir -p ' . $this->source, $out ); + $ret = Console::executeCommand ( 'mkdir -p ' . $this->source, $out ); if (! $ret) { throw new ErrorWithMessageException ( 'Cant re-create dir :' . $out, $ret ); } @@ -817,51 +815,56 @@ tasks: on-deply: post-deploy: - ioncube: - override: dyf - keeptemp: - encoder: ioncube_encoder54 - projfile: project.prj - project: - replace-target: - binary: - ignore-deprecated-warnings: - ignore-strict-warnings: - ignore: - - _* - - templates_c/* - - *~ - - database.md - - specs/ - - composer.json - - README.md - - .git/ - - .project - - .settings/ - - .buildpath - message-if-no-loader: "System error No Loader" - passphrase: "My really secure passphrase" - encrypt: - - templates/* - add-comment: - - 'Comment 1' - - 'Comment 2' - - "(c) ACTweb 2013" - - "Draft Version" +ioncube: + override: dyf + keeptemp: + encoder: ioncube_encoder54 + checkencoding: true + checkignorepaths: + -/public/js/* + -/public/css/* + + projfile: project.prj + project: + replace-target: + binary: + ignore-deprecated-warnings: + ignore-strict-warnings: + ignore: + - _* + - templates_c/* + - *~ + - database.md + - specs/ + - composer.json + - README.md + - .git/ + - .project + - .settings/ + - .buildpath + message-if-no-loader: "System error No Loader" + passphrase: "My really secure passphrase" + encrypt: + - templates/* + add-comment: + - 'Comment 1' + - 'Comment 2' + - "(c) ACTweb 2013" + - "Draft Version" - loader-event: - - corrupt-file=Corupted files - - expired-file=System needs updated - - no-permissions=Not allowed on this server - - clock-skew=Time incorect - - license-not-found=License not installed - - license-corrupt=Something wrong with your license - - license-expired=Out of time - - license-property-invalid=Invalid license data - - license-header-invalid=Files corupted - - license-server-invalid=Server problem - - unauth-including-file=Sorry these files can only be used within defined software - - unauth-included-file=Crtical Software Error - - unauth-append-prepend-file=System can not be used with PHP Prepend/Append set + loader-event: + - corrupt-file=Corupted files + - expired-file=System needs updated + - no-permissions=Not allowed on this server + - clock-skew=Time incorect + - license-not-found=License not installed + - license-corrupt=Something wrong with your license + - license-expired=Out of time + - license-property-invalid=Invalid license data + - license-header-invalid=Files corupted + - license-server-invalid=Server problem + - unauth-including-file=Sorry these files can only be used within defined software + - unauth-included-file=Crtical Software Error + - unauth-append-prepend-file=System can not be used with PHP Prepend/Append set EOEXAMPLE; From 379d3ce1b71df883ae8ff24fbbdb76e87c69c153 Mon Sep 17 00:00:00 2001 From: Matt Lowe Date: Sun, 1 Dec 2013 10:22:09 +0000 Subject: [PATCH 5/5] syncing local to remote for backup --- version | 1 + 1 file changed, 1 insertion(+) create mode 100644 version diff --git a/version b/version new file mode 100644 index 0000000..8a9ecc2 --- /dev/null +++ b/version @@ -0,0 +1 @@ +0.0.1 \ No newline at end of file