summaryrefslogtreecommitdiff
path: root/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php')
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php524
1 files changed, 524 insertions, 0 deletions
diff --git a/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php b/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php
new file mode 100644
index 00000000..2a3f71ca
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php
@@ -0,0 +1,524 @@
+<?php
+
+/*
+ * $Id: 96af59b9cbecaf7f146dffab1d0b5a806a56b47f $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Produce license files using Zeng Guard.
+ * The task can produce a license file from the given
+ * license properties or it can use a template.
+ *
+ * @author Petr Rybak <petr@rynawe.net>
+ * @version $Id: 96af59b9cbecaf7f146dffab1d0b5a806a56b47f $
+ * @package phing.tasks.ext.zendguard
+ * @since 2.4.3
+ */
+class ZendGuardLicenseTask extends Task
+{
+ protected $zendsignCommand;
+ private $tmpLicensePath;
+
+ /**
+ * TASK PROPERTIES
+ *
+ * See http://static.zend.com/topics/Zend-Guard-User-Guidev5x.pdf
+ * for more information on how to use ZendGuard
+ *
+ */
+ /**
+ * Path to Zend Guard zendenc_sign executable
+ *
+ * @var string
+ */
+ protected $zendsignPath;
+ /**
+ * Path to private key that will be used to sign the license
+ *
+ * @var string
+ */
+ protected $privateKeyPath;
+ /**
+ * Where to store the signed license file
+ *
+ * @var string
+ */
+ protected $outputFile;
+ /**
+ * Path to license template. If specified all
+ * license properties will be ignored and the
+ * template will be used to generate the file.
+ *
+ * @var string
+ */
+ protected $licenseTemplate;
+ /**
+ * The name assigned to Product. This must be the same name used when encoding
+ * the PHP files.
+ *
+ * REQUIRED
+ *
+ * @var string
+ */
+ protected $productName;
+ /**
+ * The Name of the Registered owner of the license.
+ *
+ * REQUIRED
+ *
+ * @var string
+ */
+ protected $registeredTo;
+ /**
+ * Expiration date of the license. Used if the license is issued with a date restriction.
+ * Possible values:
+ * - 'Never', '0' or false: the license won't expire
+ * - A Date in format DD-MM-YYYY to set expiration for that date
+ * - Relative date supported by the PHP strtotime function (e.g. +1 month)
+ *
+ * REQUIRED
+ *
+ * @var string
+ */
+ protected $expires;
+ /**
+ * Limits the use of the license to IP addresses that fall within specification. Supports
+ * wildcards for any of the IP place holders, as well as the two types of net masks
+ * (filters).
+ * Netmask pair An IP a.b.c.d, and a netmask w.x.y.z. (That is., 10.1.0.0/255.255.0.0),
+ * where the binary of mask is applied to filter IP addresses.
+ * ip/nnn (similar to a CIDR specification) This mask consists of nnn high-order 1 bits.
+ * (That is, 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0). Instead of spelling out
+ * the bits of the subnet mask, this mask notation is simply listed as the number of 1s
+ * bits that start the mask. Rather than writing the address and subnet mask as
+ * 192.60.128.0/255.255.252.0 the network address would be written simply as:
+ * 192.60.128.0/22 which indicates starting address of the network and number of 1s
+ * bits (22) in the network portion of the address. The mask in binary is
+ * (11111111.11111111.11111100.00000000).
+ *
+ * OPTIONAL
+ *
+ * Example (Wildcard):
+ * IP-Range = 10.1.*.*
+ * Example (Net Mask):
+ * IP-Range = 10.1.0.0/255.255.0.0
+ * Example (Net Mask):
+ * IP-Range = 10.1.0.0/16
+ *
+ * @var string
+ */
+ protected $ipRange;
+ /**
+ * Coded string (Zend Host ID) used to lock the license to a specific hardware. The
+ * Zend Host ID obtained from the machine where the encoded files and license are
+ * to be installed. The Zend Host ID code can be obtained by using the zendid utility.
+ * For more details, see Getting the Zend Host ID.
+ *
+ * REQUIRED if Hardware-Locked is set equal to YES.
+ * Meaningless if Hardware-Locked is set equal to NO.
+ *
+ * User semicolon to enter more than one Host-ID
+ *
+ * Example:
+ * Host-ID = H:MFM43-Q9CXC-B9EDX-GWYSU;H:MFM43-Q9CXC-B9EDX-GWYTY
+ *
+ * @var string
+ */
+ protected $hostID;
+ /**
+ * Option that indicates if the license will be locked to a specific machine
+ * using the Zend Host ID code(s). If set to YES, the Host-ID is required.
+ *
+ * OPTIONAL
+ *
+ * @var bool
+ */
+ protected $hardwareLocked;
+ /**
+ * Semi-colon separated user defined values that will be part of the license. These values
+ * CANNOT be modified after the license is produced. Modification
+ * would invalidate the license.
+ *
+ * OPTIONAL
+ * Example:
+ * Tea=Mint Flavor;Coffee=Arabica
+ *
+ * @var string
+ */
+ protected $userDefinedValues;
+ /**
+ * Semi-colon separated user defined x-values that will be part of the license. These values
+ * CAN be modified after the license is produced. Modification
+ * won't invalidate the license.
+ *
+ * OPTIONAL
+ * Example:
+ * Tea=Mint Flavor;Coffee=Arabica
+ *
+ * @var string
+ */
+ protected $xUserDefinedValues;
+
+
+ public function setLicenseTemplate($value)
+ {
+ $this->licenseTemplate = $value;
+ }
+
+ public function setProductName($productName)
+ {
+ $this->productName = $productName;
+ }
+
+ public function setRegisteredTo($registeredTo)
+ {
+ $this->registeredTo = $registeredTo;
+ }
+
+ /**
+ * Process the expires property. If the value is
+ * empty (false, '', ...) it will set the value to 'Never'
+ * Otherwise it will run the value through strtotime so relative
+ * date and time notation can be used (e.g. +1 month)
+ *
+ * @param mixed $expires
+ *
+ * @return string
+ */
+ public function setExpires($expires)
+ {
+ // process the expires value
+ if (false === $expires || '0' === $expires || strtolower($expires) == 'never' || '' === $expires) {
+ $this->expires = 'Never';
+ } else {
+ $time = strtotime($expires);
+ if (!$time) {
+ throw new BuildException("Unsupported expires format: " . $expires);
+ }
+ $this->expires = date('d-M-Y', $time);
+ }
+ }
+
+ public function setIpRange($iprange)
+ {
+ $this->ipRange = $iprange;
+ }
+
+ public function setHostID($hostID)
+ {
+ $this->hostID = $hostID;
+ }
+
+ public function setHardwareLocked($hardwareLocked)
+ {
+ $this->hardwareLocked = (bool) $hardwareLocked;
+ }
+
+ public function setUserDefinedValues($userDefinedValues)
+ {
+ $this->userDefinedValues = $userDefinedValues;
+ }
+
+ public function setXUserDefinedValues($xUserDefinedValues)
+ {
+ $this->xUserDefinedValues = $xUserDefinedValues;
+ }
+
+ public function setZendsignPath($zendsignPath)
+ {
+ $this->zendsignPath = $zendsignPath;
+ }
+
+ public function setPrivateKeyPath($privateKeyPath)
+ {
+ $this->privateKeyPath = $privateKeyPath;
+ }
+
+ public function setOutputFile($outputFile)
+ {
+ $this->outputFile = $outputFile;
+ }
+
+ /**
+ * Verifies that the configuration is correct
+ *
+ * @throws BuildException
+ */
+ protected function verifyConfiguration()
+ {
+ // Check that the zend encoder path is specified
+ if (empty($this->zendsignPath)) {
+ throw new BuildException("Zendenc_sign path must be specified");
+ }
+ // verify that the zend encoder binary exists
+ if (!file_exists($this->zendsignPath)) {
+ throw new BuildException("Zendenc_sign not found on path " . $this->zendsignPath);
+ }
+
+ // verify that the private key path is defined
+ if (empty($this->privateKeyPath)) {
+ throw new BuildException("You must define privateKeyPath.");
+ }
+ // verify that the private key file is readable
+ if (!is_readable($this->privateKeyPath)) {
+ throw new BuildException("Private key file is not readable: " . $this->privateKeyPath);
+ }
+
+ // if template is passed, verify that it is readable
+ if (!empty($this->licenseTemplate)) {
+ if (!is_readable($this->licenseTemplate)) {
+ throw new BuildException("License template file is not readable " . $this->licenseTemplate);
+ }
+ }
+
+ // check that output file path is defined
+ if (empty($this->outputFile)) {
+ throw new BuildException("Path where to store the result file needs to be defined in outputFile property");
+ }
+
+ // if license template is NOT provided check that all required parameters are defined
+ if (empty($this->licenseTemplate)) {
+
+ // check productName
+ if (empty($this->productName)) {
+ throw new BuildException("Property must be defined: productName");
+ }
+
+ // check expires
+ if (null === $this->expires) {
+ throw new BuildException("Property must be defined: expires");
+ }
+
+ // check registeredTo
+ if (empty($this->registeredTo)) {
+ throw new BuildException("Property must be defined: registeredTo");
+ }
+
+ // check hardwareLocked
+ if (null === $this->hardwareLocked) {
+ throw new BuildException("Property must be defined: hardwareLocked");
+ }
+
+ // if hardwareLocked is set to true, check that Host-ID is set
+ if ($this->hardwareLocked) {
+ if (empty($this->hostID)) {
+ throw new BuildException("If you set hardwareLocked to true hostID must be provided");
+ }
+ }
+ }
+ }
+
+ /**
+ * Do the work
+ *
+ * @throws BuildException
+ */
+ public function main()
+ {
+ try {
+ $this->verifyConfiguration();
+
+ $this->generateLicense();
+ } catch (Exception $e) {
+ // remove the license temp file if it was created
+ $this->cleanupTmpFiles();
+
+ throw $e;
+ }
+ $this->cleanupTmpFiles();
+ }
+
+ /**
+ * If temporary license file was created during the process
+ * this will remove it
+ *
+ * @return void
+ */
+ private function cleanupTmpFiles()
+ {
+ if (!empty($this->tmpLicensePath) && file_exists($this->tmpLicensePath)) {
+ $this->log("Deleting temporary license template " . $this->tmpLicensePath, Project::MSG_VERBOSE);
+
+ unlink($this->tmpLicensePath);
+ }
+ }
+
+ /**
+ * Prepares and returns the command that will be
+ * used to create the license.
+ *
+ * @return string
+ */
+ protected function prepareSignCommand()
+ {
+ $command = $this->zendsignPath;
+
+ // add license path
+ $command .= ' ' . $this->getLicenseTemplatePath();
+
+ // add result file path
+ $command .= ' ' . $this->outputFile;
+
+ // add key path
+ $command .= ' ' . $this->privateKeyPath;
+
+
+ $this->zendsignCommand = $command;
+
+ return $command;
+ }
+
+ /**
+ * Checks if the license template path is defined
+ * and returns it.
+ * If it the license template path is not defined
+ * it will generate a temporary template file and
+ * provide it as a template.
+ *
+ * @return string
+ */
+ protected function getLicenseTemplatePath()
+ {
+ if (!empty($this->licenseTemplate)) {
+ return $this->licenseTemplate;
+ } else {
+ return $this->generateLicenseTemplate();
+ }
+ }
+
+ /**
+ * Creates the signed license at the defined output path
+ *
+ * @return void
+ */
+ protected function generateLicense()
+ {
+ $command = $this->prepareSignCommand() . ' 2>&1';
+
+ $this->log('Creating license at ' . $this->outputFile);
+
+ $this->log('Running: ' . $command, Project::MSG_VERBOSE);
+ $tmp = exec($command, $output, $return_var);
+
+ // Check for exit value 1. Zendenc_sign command for some reason
+ // returns 0 in case of failure and 1 in case of success...
+ if ($return_var !== 1) {
+ throw new BuildException("Creating license failed. \n\nZendenc_sign msg:\n" . join("\n", $output) . "\n\n");
+ }
+ }
+
+ /**
+ * It will generate a temporary license template
+ * based on the properties defined.
+ *
+ * @return string Path of the temporary license template file
+ */
+ protected function generateLicenseTemplate()
+ {
+ $this->tmpLicensePath = tempnam(sys_get_temp_dir(), 'zendlicense');
+
+ $this->log("Creating temporary license template " . $this->tmpLicensePath, Project::MSG_VERBOSE);
+ if (file_put_contents($this->tmpLicensePath, $this->generateLicenseTemplateContent()) === false) {
+ throw new BuildException("Unable to create temporary template license file: " . $this->tmpLicensePath);
+ }
+
+ return $this->tmpLicensePath;
+ }
+
+ /**
+ * Generates license template content based
+ * on the defined parameters
+ *
+ * @return string
+ */
+ protected function generateLicenseTemplateContent()
+ {
+ $contentArr = array();
+
+ // Product Name
+ $contentArr[] = array('Product-Name', $this->productName);
+ // Registered to
+ $contentArr[] = array('Registered-To', $this->registeredTo);
+ // Hardware locked
+ $contentArr[] = array('Hardware-Locked', ($this->hardwareLocked ? 'Yes' : 'No'));
+
+ // Expires
+ $contentArr[] = array('Expires', $this->expires);
+
+ // IP-Range
+ if (!empty($this->ipRange)) {
+ $contentArr[] = array('IP-Range', $this->ipRange);
+ }
+ // Host-ID
+ if (!empty($this->hostID)) {
+ foreach (explode(';', $this->hostID) as $hostID) {
+ $contentArr[] = array('Host-ID', $hostID);
+ }
+ } else {
+ $contentArr[] = array('Host-ID', 'Not-Locked');
+ }
+
+ // parse user defined fields
+ if (!empty($this->userDefinedValues)) {
+ $this->parseAndAddUserDefinedValues($this->userDefinedValues, $contentArr);
+ }
+ // parse user defined x-fields
+ if (!empty($this->xUserDefinedValues)) {
+ $this->parseAndAddUserDefinedValues($this->xUserDefinedValues, $contentArr, 'X-');
+ }
+
+ // merge all the values
+ $content = '';
+ foreach ($contentArr as $valuePair) {
+
+ list($key, $value) = $valuePair;
+
+ $content .= $key . " = " . $value . "\n";
+ }
+
+ return $content;
+ }
+
+ /**
+ * Parse the given string in format like key1=value1;key2=value2;... and
+ * converts it to array
+ * (key1=>value1, key2=value2, ...)
+ *
+ * @param stirng $valueString Semi-colon separated value pairs
+ * @param array $valueArray Array to which the values will be added
+ * @param string $keyPrefix Prefix to use when adding the key
+ *
+ * @return void
+ */
+ protected function parseAndAddUserDefinedValues($valueString, array &$valueArray, $keyPrefix = '',
+ $pairSeparator = ';')
+ {
+ // explode the valueString (semicolon)
+ $valuePairs = explode($pairSeparator, $valueString);
+ if (!empty($valuePairs)) {
+ foreach ($valuePairs as $valuePair) {
+ list($key, $value) = explode('=', $valuePair, 2);
+
+ // add pair into the valueArray
+ $valueArray[] = array($keyPrefix . $key, $value);
+ }
+ }
+ }
+
+}