iono Documentation - Local License Keys
Introduction
iono is designed to integrate into your product to allow it to communicate with your installation of iono when installed on the customer's server. This communication allows the license to be verified and enables features such as hostname/IP restrictions and expiration dates.
Communication between the customer's installed product and your copy of iono is required and because of this, connection related problems often arise. These can be firewalls blocking connections or your server being busy or down. The local license key integration method is designed to try and solve as many of these problems as possible.
How it works
The other integration methods available with iono are pasted into your product code and communicate with your copy of iono every time the code is executed. This allows real time licensing so changes such as suspending a license are seen immediately. However, this means that your server is handling a lot of license requests which can become quite a lot if you have many customers. Also, if your server is down, the license request fails.
In contrast, the local license keys method contacts your copy of iono only once and saves the license data to a local key file. On subsequent executions, the data is read for this local file instead of from your server. This makes the licensing much faster performance wise and removes the point of failure that is your server. This key file expires after a certain period of time (15 days by default) after which the data is requested again from your server to update to any changes.
Binding Restrictions
If the license restrictions for the license key being used are blank then the license will be automatically bound to the IP/hostname currently being accessed.
Disadvantages
The main and only real disadvantage of this integration method is that the license data is not real time. This means that if you suspend a license then the data on the customer's server won't be refreshed for at most, 15 days (by default). The other disadvantage is that this method is more complex to integrate than the others, but this guide should take you through the steps required.
Integration
The local license keys method is implemented using a PHP class. This class is generated for your by your iono installation and you then need to interact with the class as you would with any other PHP class. This does require some PHP knowledge but this guide will take you through as much as possible.
Generate Class
You need to first generate your keys class through the iono admin interface:
- Click on the Integration link from the iono admin control panel main menu
- The page will change to an integration type selection screen. Choose the Licensing Integration option by clicking on the button underneath the header and description.
- Click the Continue button under the "Local License Key (Recommended Method)" header
Generated Code
You are provided with 2 text fields which contain the full PHP class that implements the local license keys functionality. One of these uses fsock and the other uses cURL for the method of communication.
- fsock (link) - The socket functions are available in PHP by default and are most likely to be available to your customers. However, some systems have them disabled for security reasons.
- cURL (link) - This is a different method of communication through PHP over the internet and is often much faster and more efficient than the PHP fsock functions. However, it is not available by default in PHP and must be manually compiled in. Whilst this is the best option, it may not be available to your customers.
In a future release we will provide code which includes both of these methods and determines whether cURL is available to use, and if not falls back on fsock. Track this feature in our tracker here.
Once you have decided which option to use, you need to copy and paste the code into your product. Since this is a PHP class, you can place it within its own file and include the file into your code in an appropriate place. The class can go anywhere so long as it is available to create an object from - you do not need to make any changes to the generated code itself. See the PHP manual on include() for more details.
Using iono_keys
Since the code is class based, you need to create a new object. The constructor performs all the licensing processes as soon as you create the object so all you need to do is access a class property (called result) which contains an integer representing the status of the license.
<?php // iono generated iono_keys licensing class goes here $key_string = 'key string here'; $remote_auth = 'remote auth here'; $licensing = new iono_keys($key_string, $remote_auth); ?>
This snippet of code firstly includes the iono_keys class generated by iono from a separate file - you would simply copy and paste this into the code at the top. It then defines 2 variables:
- $key_string (string) - This is the unique license key string provided for every license a customer purchases. It can be viewed by the customer when viewing their license and also when viewing a license through the admin.
- $remote_auth (string) - This is also a unique string generated for every iono installation. You can find it in the Settings section of your iono admin panel. It is very important that it remains secret as it is used to secure the local license key against tampering.
Once called, if the key file does not exist then it will be created with the data obtained from your iono installation for that license. If it does exist then it will be read. The key file does not need to exist beforehand - if it doesn't, then the code will automatically create it.
Other options
The constructor for the iono_keys class takes a further two parameters which further control how the function works. These are $key_location and $key_age.
- $key_location (string) - By default the license data is written to a file called key.php in the relative location to where the constructor was called. So if your code is in a directory called files/ in a file called licensing.php (files/licensing.php) then the key will be created in that directory as files/key.php. By providing a different path here, you can have the key created in a different location.
- $key_age (integer) - This defines the expiry time of the local key file in seconds and defaults to 15 days (1296000 seconds). Specifying a lower value will cause the key file to be refreshed sooner.
Using these additional options is simple:
<?php // iono generated iono_keys licensing class goes here $key_string = 'key string here'; $remote_auth = 'remote auth here'; $key_location = 'key/key.php'; $key_age = 86400; // 1 day $licensing = new iono_keys($key_string, $remote_auth, $key_location, $key_age); ?>
This code will cause the key file to be created within a location called key/key.php and the key file will expire every day. If you wanted to keep the default location and just alter the time, then you would provide the value key.php for the $key_location variable.
<?php // iono generated iono_keys licensing class goes here $key_string = 'key string here'; $remote_auth = 'remote auth here'; $key_location = 'key.php'; // Keeps the default value $key_age = 86400; // 1 day $licensing = new iono_keys($key_string, $remote_auth, $key_location, $key_age); ?>
iono_keys Prototype
The official constructor prototype is:
iono_keys (string $license_key, string $remote_auth, [string $key_location = 'key.php'], [int $key_age = 1296000])
Detailed information about the PHP OOP system can be found in the PHP manual.
Processing the result
The above code handles the core part of the licensing but you still need to process the result of this. That code will not output anything to the user - you must do that yourself.
Once called, the class will have a non-empty property called $result. This contains an integer value which you use to show an error message, or not as the case may be. The potential values are:
- 0 - Unable to read key - The key file exists but could not be opened. This is solved by ensuring the web server can read and write to the key location.
- 1 - Everything is OK
- 2 - SHA1 hash incorrect - The key file is hashed using the remote_auth value. If the hash does not match the file then it may have been tampered with.
- 3 - MD5 hash incorrect - Same as above, but with a different hashing method
- 4 - License key does not match key string in key file
- 5 - License has expired
- 6 - Host name does not match key file - The host name currently being used does not match the one in the license.
- 7 - IP does not match key file - The host name currently being used does not match the one in the license.
- 8 - License disabled
- 9 - License suspended
- 10 - Unable to open file for writing - The key file could not be created. This is solved by ensuring the web server can read and write to the key parent directory.
- 11 - Unable to write to file - The key file exists but could not be written to. This is solved by ensuring the web server can read and write to the key location.
- 12 - Unable to communicate with iono - Could not communicate with your copy of iono, possibly due to firewall or connection problems
You can force the refresh of a license file in the event that you have modified in in iono by deleting the key file. The code will automatically recreate it with fresh data.
Example code to actually display the results is shown below:
<?php
// iono generated iono_keys licensing class goes here
$key_string = 'key string here';
$remote_auth = 'remote auth here';
$key_location = 'key/key.php';
$key_age = 86400; // 1 day
$licensing = new iono_keys($key_string, $remote_auth, $key_location, $key_age);
switch ($licensing->result)
{
case 0:
die('Unable to read key');
break;
case 1:
// Everything is fine so we don't need to do anything
break;
case 2:
die('SHA1 hash incorrect');
break;
case 3:
die('MD5 hash incorrect');
break;
case 4:
die('License key does not match key string in key file');
break;
case 5:
die('License has expired');
break;
case 6:
die('Host name does not match key file');
break;
case 7:
die('IP does not match key file');
break;
case 8:
die('License disabled');
break;
case 9:
die('License suspended');
break;
case 10:
die('Unable to open file for writing');
break;
case 11:
die('Unable to write to file');
break;
case 12:
die('Unable to communicate with iono');
break;
}
?>
This code will process the result and if there is an error, halt the execution of the script and display an error. The idea is that this code will go before any other output so that in the event of a license error, the product stops working.
The code is also very simple - you may want to assign the error messages to a variable instead and show a much friendlier error message within your own templates.
License Data
You may wish to show the license details to the customer within your product which you can do by calling the iono_keys method get_data. This returns an array of the license data which you can then display as you wish. The data returned includes:
- license_key - The full license key string for this license, also showed in the iono web interface
- expiry - The UNIX timestamp of the expiry date/time for this license
- hostname - The hostname that the license is bound to
- ip - The IP address that the license is bound to
- timestamp - The UNIX timestamp of the date/time that the local key file was generated on the user's server.
You would call this function like so
$license = $licensing->get_data();
Assuming you have already created the licensing object as described above, the $license variable would be an array containing the data above. You can use the PHP date() function to format the output of the UNIX timestamp.
FAQ
Where is the best place to put this code?
The iono_keys class can be located anywhere within the licensing code like in the examples above or you could include it in a separate file. The actual code that interacts with the class can also go anywhere but we recommend that you place it in some file that is essential to the functioning of your product. In the case of iono, we place this code in the admin.php file so whenever you access the admin panel, it checks the license. This means that if the license becomes invalid, the admin cannot use iono but customers are unaffected.
Do I need to encode the licensing code?
Yes. If you do not encode then it is very easy to simply remove the licensing aspect. Equally, your auth string will be publicly viewable which compromises the licensing aspects of your iono installation.
How do I collect the user's license key string?
In the code above the key string is hard coded to a variable. In real life, you would more likely have it stored in a config file or in the database and retrieve it from there when calling the licensing code. In iono, we collect the string during the installation process and then store it in a config file which is then read.
What format is the key string in?
See the licensing overview for details.
Can I restrict features based on the license key?
Yes, see the licensing overview for details.
Do you offer integration assistance?
Yes we do. This is charged at £65.00 GBP for basic integration with your product. Contact us for details.