Adapted the server implementation to more reusable object, added more permission control. Resolved gh-230 by adding the full shtp integration

This commit is contained in:
Llewellyn van der Merwe 2018-02-19 14:52:08 +02:00
parent e857614608
commit 17195cd059
No known key found for this signature in database
GPG Key ID: CAD7B16D27AF28C5
9 changed files with 444 additions and 164 deletions

View File

@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env
+ *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)
+ *Name*: [Component Builder](http://joomlacomponentbuilder.com)
+ *First Build*: 30th April, 2015
+ *Last Build*: 17th February, 2018
+ *Last Build*: 19th February, 2018
+ *Version*: 2.6.15
+ *Copyright*: Copyright (C) 2015. All Rights Reserved
+ *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
+ *Line count*: **181747**
+ *Line count*: **182099**
+ *Field count*: **1639**
+ *File count*: **1167**
+ *Folder count*: **188**

View File

@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env
+ *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)
+ *Name*: [Component Builder](http://joomlacomponentbuilder.com)
+ *First Build*: 30th April, 2015
+ *Last Build*: 17th February, 2018
+ *Last Build*: 19th February, 2018
+ *Version*: 2.6.15
+ *Copyright*: Copyright (C) 2015. All Rights Reserved
+ *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
+ *Line count*: **181747**
+ *Line count*: **182099**
+ *Field count*: **1639**
+ *File count*: **1167**
+ *Folder count*: **188**

View File

@ -321,27 +321,29 @@ class Compiler extends Infusion
// use FTP
if ($this->componentData->update_server_protocol == 1)
{
// Get the basic encription.
$basickey = ComponentbuilderHelper::getCryptKey('basic');
// Get the encription object.
$basic = new FOFEncryptAes($basickey, 128);
if (!empty($this->componentData->update_server) && $basickey && !is_numeric($this->componentData->update_server) && $this->componentData->update_server === base64_encode(base64_decode($this->componentData->update_server, true)))
// get server details
if ($ftp = ComponentbuilderHelper::getServer((int) $this->componentData->update_server, 1))
{
// basic decript data update_server.
$this->componentData->update_server = rtrim($basic->decryptString($this->componentData->update_server), "\0");
// now move the file
if (!$ftp->store($xml_update_server_path, null))
{
$this->app->enqueueMessage(JText::sprintf('The <b>%s</b> file could not be moved to <b>%s</b> server.', $this->updateServerFileName . '.xml', $$ftp->remote_server_name[(int) $this->componentData->update_server]), 'Error');
}
// remove the local file
JFile::delete($xml_update_server_path);
// close the connection
$ftp->quit();
}
// now move the file
$this->moveFileToFtpServer($xml_update_server_path, $this->componentData->update_server);
}
// use SFTP
elseif ($this->componentData->update_server_protocol == 2)
{
if ($sftp = ComponentbuilderHelper::getSftp((int) $this->componentData->update_server))
if ($sftp = ComponentbuilderHelper::getServer((int) $this->componentData->update_server, 2))
{
// now move the file
if (!$sftp->put($sftp->remote_server_path . $this->updateServerFileName . '.xml', ComponentbuilderHelper::getFileContents($xml_update_server_path, null)))
if (!$sftp->put($sftp->remote_server_path[(int) $this->componentData->update_server] . $this->updateServerFileName . '.xml', ComponentbuilderHelper::getFileContents($xml_update_server_path, null)))
{
$this->app->enqueueMessage(JText::sprintf('The <b>%s</b> file could not be moved to <b>%s</b> path on <b>%s</b> server.', $this->updateServerFileName . '.xml', $sftp->remote_server_path, $sftp->remote_server_name), 'Error');
$this->app->enqueueMessage(JText::sprintf('The <b>%s</b> file could not be moved to <b>%s</b> path on <b>%s</b> server.', $this->updateServerFileName . '.xml', $sftp->remote_server_path[(int) $this->componentData->update_server], $sftp->remote_server_name[(int) $this->componentData->update_server]), 'Error');
}
// remove the local file
JFile::delete($xml_update_server_path);
@ -520,27 +522,26 @@ class Compiler extends Infusion
// use FTP
if ($this->componentData->sales_server_protocol == 1)
{
// Get the basic encription.
$basickey = ComponentbuilderHelper::getCryptKey('basic');
// Get the encription object.
$basic = new FOFEncryptAes($basickey, 128);
if (!empty($this->componentData->sales_server) && $basickey && !is_numeric($this->componentData->sales_server) && $this->componentData->sales_server === base64_encode(base64_decode($this->componentData->sales_server, true)))
if ($ftp = ComponentbuilderHelper::getServer((int) $this->componentData->sales_server, 1))
{
// basic decript data sales_server.
$this->componentData->sales_server = rtrim($basic->decryptString($this->componentData->sales_server), "\0");
// now move the file
if (!$ftp->store($xml_update_server_path, $this->componentSalesName . '.zip'))
{
$this->app->enqueueMessage(JText::sprintf('The <b>%s</b> file could not be moved to <b>%s</b> server.', $this->componentSalesName . '.zip', $ftp->remote_server_name[(int) $this->componentData->sales_server]), 'Error');
}
// close the connection
$ftp->quit();
}
// now move the file
$this->moveFileToFtpServer($this->filepath, $this->componentData->sales_server, $this->componentSalesName . '.zip', false);
}
// use SFTP
elseif ($this->componentData->sales_server_protocol == 2)
{
if ($sftp = ComponentbuilderHelper::getSftp((int) $this->componentData->sales_server))
if ($sftp = ComponentbuilderHelper::getServer((int) $this->componentData->sales_server, 2))
{
// now move the file
if (!$sftp->put($sftp->remote_server_path . $this->componentSalesName . '.zip', ComponentbuilderHelper::getFileContents($this->filepath, null)))
if (!$sftp->put($sftp->remote_server_path[(int) $this->componentData->sales_server] . $this->componentSalesName . '.zip', ComponentbuilderHelper::getFileContents($this->filepath, null)))
{
$this->app->enqueueMessage(JText::sprintf('The <b>%s</b> file could not be moved to <b>%s</b> path on <b>%s</b> server.', $this->componentSalesName . '.zip', $sftp->remote_server_path, $sftp->remote_server_name), 'Error');
$this->app->enqueueMessage(JText::sprintf('The <b>%s</b> file could not be moved to <b>%s</b> path on <b>%s</b> server.', $this->componentSalesName . '.zip', $sftp->remote_server_path[(int) $this->componentData->sales_server], $sftp->remote_server_name[(int) $this->componentData->sales_server]), 'Error');
}
}
}
@ -555,74 +556,6 @@ class Compiler extends Infusion
return false;
}
private function moveFileToFtpServer($localPath, $clientInput, $remote = null, $removeLocal = true)
{
// get the ftp opbject
$ftp = $this->getFTP($clientInput);
// chack if we are conected
if ($ftp instanceof JClientFtp && $ftp->isConnected())
{
// move the file
if ($ftp->store($localPath, $remote))
{
// if moved then remove the file from repository
if ($removeLocal)
{
JFile::delete($localPath);
}
}
// at the end close the conection
$ftp->quit();
}
}
private function getFTP($clientInput)
{
$s1GnAtnr3 = md5($clientInput);
if (isset($this->FTP[$s1GnAtnr3]) && $this->FTP[$s1GnAtnr3] instanceof JClientFtp)
{
// return the FTP instance
return $this->FTP[$s1GnAtnr3];
}
else
{
// make sure we have a string and it is not default or empty
if (ComponentbuilderHelper::checkString($clientInput))
{
// turn into variables
parse_str($clientInput); // because of this I am using strand variable naming to avoid any collisions.
// set options
if (isset($options) && ComponentbuilderHelper::checkArray($options))
{
foreach ($options as $o__p0t1on => $vAln3)
{
if ('timeout' === $o__p0t1on)
{
$options[$o__p0t1on] = (int) $vAln3;
}
if ('type' === $o__p0t1on)
{
$options[$o__p0t1on] = (string) $vAln3;
}
}
}
else
{
$options = array();
}
// get ftp object
if (isset($host) && $host != 'HOSTNAME' && isset($port) && $port != 'PORT_INT' && isset($username) && $username != 'user@name.com' && isset($password) && $password != 'password')
{
// load for reuse
$this->FTP[$s1GnAtnr3] = JClientFtp::getInstance($host, $port, $options, $username, $password);
// return the FTP instance
return $this->FTP[$s1GnAtnr3];
}
}
}
return false;
}
protected function addCustomCode()
{
// reset all these

View File

@ -1160,11 +1160,6 @@ class Get
{
// get the server protocol
$component->{$server.'_protocol'} = ComponentbuilderHelper::getVar('server', (int) $component->{$server}, 'id', 'protocol');
// load the FTP
if (1 == $component->{$server.'_protocol'})
{
$component->{$server} = ComponentbuilderHelper::getVar('server', (int) $component->{$server}, 'id', 'signature');
}
}
else
{

View File

@ -1954,39 +1954,76 @@ abstract class ComponentbuilderHelper
}
/**
* the SFTP object
* the SFTP objects
**/
protected static $sftp = array();
/**
* the FTP objects
**/
protected static $ftp = array();
/**
* get the server object
*
* @param int $serverID The server local id to use
* @param int $protocol The server protocol to use
* @param string $permission The permission validation area
*
* @return object on success server object
**/
public static function getServer($serverID, $protocol, $permission = 'core.export')
{
// return the server object
switch ($protocol)
{
case 1: // FTP
return self::getFtp($serverID, $permission);
break;
case 2: // SFTP
return self::getSftp($serverID, $permission);
break;
}
return false;
}
/**
* get the sftp object
*
* @param int $serverID The server local id to use
* @param int $serverID The server local id to use
* @param string $permission The permission validation area
*
* @return object on success with sftp power
**/
public static function getSftp($serverID)
public static function getSftp($serverID, $permission = 'core.export')
{
// check if it was already set
if (!self::checkObject(self::$sftp[$serverID]))
// check if we have a server with that id
if ($server = self::getServerDetails($serverID, 2, $permission))
{
// check if we have a server with that id
if ($server = self::getServerDetails($serverID, 2))
// check if it was already set
if (!isset(self::$sftp[$server->cache]) || !self::checkObject(self::$sftp[$server->cache]))
{
// make sure we have the composer classes loaded
self::composerAutoload();
// make sure we have the phpseclib classes
if (!class_exists('\phpseclib\Net\SFTP'))
{
// class not in place so send out error
JFactory::getApplication()->enqueueMessage(JText::_('COM_COMPONENTBUILDER_THE_BPHPSECLIBNETSFTPB_LIBRARYCLASS_IS_NOT_AVAILABLE_THIS_LIBRARYCLASS_SHOULD_HAVE_BEEN_ADDED_TO_YOUR_ADMINHELPERSVENDOR_FOLDER_OF_JCB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO'), 'Error');
return false;
}
// insure the port is set
$server->port = (isset($server->port) && is_int($server->port) && $server->port > 0) ? $server->port : 22;
// open the connection
self::$sftp[$serverID] = new phpseclib\Net\SFTP($server->host, $server->port);
self::$sftp[$server->cache] = new phpseclib\Net\SFTP($server->host, $server->port);
// now login based on authentication type
switch($server->authentication)
{
case 1: // password
// now login
if (!self::$sftp[$serverID]->login($server->username, $server->password))
if (!self::$sftp[$server->cache]->login($server->username, $server->password))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_AND_PASSWORD_ARE_CORRECT', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
break;
@ -2001,12 +2038,14 @@ abstract class ComponentbuilderHelper
if (!$rsa->loadKey(self::getFileContents($server->private, null)))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
// now login
if (!self::$sftp[$serverID]->login($server->username, $rsa))
if (!self::$sftp[$server->cache]->login($server->username, $rsa))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_AND_PRIVATE_KEY_FILE_ARE_CORRECT', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
break;
@ -2021,54 +2060,166 @@ abstract class ComponentbuilderHelper
if (!$rsa->loadKey(self::getFileContents($server->private, null)))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
// now login
if (!self::$sftp[$serverID]->login($server->username, $server->password, $rsa))
if (!self::$sftp[$server->cache]->login($server->username, $server->password, $rsa))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_PASSWORD_AND_PRIVATE_KEY_FILE_ARE_CORRECT', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
break;
}
// set some defaults
self::$sftp[$serverID]->remote_server_name = $server->name;
self::$sftp[$serverID]->remote_server_path = (self::checkString($server->path) && $server->path !== '/') ? $server->path : '';
}
else
// only continue if object is set
if (isset(self::$sftp[$server->cache]) && self::checkObject(self::$sftp[$server->cache]))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BSB_COULD_NOT_BE_RETRIEVED', $serverID), 'Error');
return false;
// set the unique buckets
if (!isset(self::$sftp[$server->cache]->remote_server_name))
{
self::$sftp[$server->cache]->remote_server_name = array();
self::$sftp[$server->cache]->remote_server_path = array();
}
// always set the name and remote server path
self::$sftp[$server->cache]->remote_server_name[$serverID] = $server->name;
self::$sftp[$server->cache]->remote_server_path[$serverID] = (self::checkString($server->path) && $server->path !== '/') ? $server->path : '';
// return the sftp object
return self::$sftp[$server->cache];
}
}
// return the sftp object
return self::$sftp[$serverID];
return false;
}
/**
* get the JClientFtp object
*
* @param int $serverID The server local id to use
* @param string $permission The permission validation area
*
* @return object on success with ftp power
**/
public static function getFtp($serverID, $permission)
{
// check if we have a server with that id
if ($server = self::getServerDetails($serverID, 1, $permission))
{
// check if we already have the server instance
if (isset(self::$ftp[$server->cache]) && self::$ftp[$server->cache] instanceof JClientFtp)
{
// always set the name and remote server path
self::$ftp[$server->cache]->remote_server_name[$serverID] = $server->name;
// if still connected we are ready to go
if (self::$ftp[$server->cache]->isConnected())
{
// return the FTP instance
return self::$ftp[$server->cache];
}
// check if we can reinitialise the server
if (self::$ftp[$server->cache]->reinit())
{
// return the FTP instance
return self::$ftp[$server->cache];
}
}
// make sure we have a string and it is not default or empty
if (self::checkString($server->signature))
{
// turn into variables
parse_str($server->signature); // because of this I am using strange variable naming to avoid any collisions.
// set options
if (isset($options) && self::checkArray($options))
{
foreach ($options as $o__p0t1on => $vAln3)
{
if ('timeout' === $o__p0t1on)
{
$options[$o__p0t1on] = (int) $vAln3;
}
if ('type' === $o__p0t1on)
{
$options[$o__p0t1on] = (string) $vAln3;
}
}
}
else
{
$options = array();
}
// get ftp object
if (isset($host) && $host != 'HOSTNAME' && isset($port) && $port != 'PORT_INT' && isset($username) && $username != 'user@name.com' && isset($password) && $password != 'password')
{
// load for reuse
self::$ftp[$server->cache] = JClientFtp::getInstance($host, $port, $options, $username, $password);
}
else
{
// load error to indicate signature was in error
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_FTP_SIGNATURE_FOR_BSB_WAS_NOT_WELL_FORMED_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS', $server->name), 'Error');
return false;
}
// check if we are connected
if (self::$ftp[$server->cache] instanceof JClientFtp && self::$ftp[$server->cache]->isConnected())
{
// set the unique buckets
if (!isset(self::$ftp[$server->cache]->remote_server_name))
{
self::$ftp[$server->cache]->remote_server_name = array();
}
// always set the name and remote server path
self::$ftp[$server->cache]->remote_server_name[$serverID] = $server->name;
// return the FTP instance
return self::$ftp[$server->cache];
}
// reset since we have no connection
unset(self::$ftp[$server->cache]);
}
// load error to indicate signature was in error
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_FTP_CONNECTION_FOR_BSB_COULD_NOT_BE_MADE_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS', $server->name), 'Error');
}
return false;
}
/**
* get the server details
*
* @param int $serverID The server local id to use
* @param int $protocol The server protocol to use
* @param int $serverID The server local id to use
* @param int $protocol The server protocol to use
* @param string $permission The permission validation area
*
* @return array on success with sftp server details
* @return object on success with server details
**/
protected static function getServerDetails($serverID, $protocol = 2)
public static function getServerDetails($serverID, $protocol = 2, $permission = 'core.export')
{
if (is_int($serverID) && is_int($serverID))
// check if this user has permission to access items
if (!JFactory::getUser()->authorise($permission, 'com_componentbuilder'))
{
// set message to inform the user that permission was denied
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_DENIEDB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO', self::safeString($permission, 'w')), 'Error');
return false;
}
// now insure we have correct values
if (is_int($serverID) && is_int($protocol))
{
// Get a db connection
$db = JFactory::getDbo();
// start the query
$query = $db->getQuery(true);
// select based to protocal
// select based to protocol
if (2 == $protocol)
{
// SFTP
$query->select($db->quoteName(array('name','authentication','username','host','password','path','port','private','secret')));
// cache builder
$cache = array('authentication','username','host','password','port','private','secret');
}
else
{
// FTP
$query->select($db->quoteName(array('name','signature')));
// cache builder
$cache = array('signature');
}
$query->from($db->quoteName('#__componentbuilder_server'));
$query->where($db->quoteName('id') . ' = ' . (int) $serverID);
@ -2082,21 +2233,42 @@ abstract class ComponentbuilderHelper
$basickey = self::getCryptKey('basic');
// Get the encryption object.
$basic = new FOFEncryptAes($basickey, 128);
// start cache keys
$keys = array();
// unlock the needed fields
foreach($server as $name => $value)
foreach($server as $name => &$value)
{
if ($name !== 'name' && !empty($server->{$name}) && $basickey && !is_numeric($server->{$name}) && $server->{$name} === base64_encode(base64_decode($server->{$name}, true)))
// unlock the needed fields
if ($name !== 'name' && !empty($value) && $basickey && !is_numeric($value) && $value === base64_encode(base64_decode($value, true)))
{
// basic decrypt of data
$server->{$name} = rtrim($basic->decryptString($server->{$name}), "\0");
$value = rtrim($basic->decryptString($value), "\0");
}
// build cache (keys) for lower connection latency
if (in_array($name, $cache))
{
$keys[] = $value;
}
}
// check if cache keys were found
if (self::checkArray($keys))
{
// now set cache
$server->cache = md5(implode('', $keys));
}
else
{
// default is ID
$server->cache = $serverID;
}
// return the server details
return $server;
}
}
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BID_SB_COULD_NOT_BE_RETRIEVED', $serverID), 'Error');
return false;
}
}
/**
* Load the Component xml manifest.
**/

View File

@ -6133,6 +6133,7 @@ COM_COMPONENTBUILDER_THERE_ARE_NO_OUT_OF_DATE_SNIPPETS_AT_THIS_TIME="There are n
COM_COMPONENTBUILDER_THERE_ARE_NO_SNIPPETS_TO_UPDATE_AT_THIS_TIME="There are no snippets to update at this time"
COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_IF_THIS_CONTINUES_PLEASE_INFORM_YOUR_SYSTEM_ADMINISTRATOR_OF_A_TYPE_ERROR_IN_THE_FIELDS_DISPLAY_REQUEST="There has been an error, if this continues please inform your system administrator of a type error in the fields display request!"
COM_COMPONENTBUILDER_THERE_WAS_A_PROBLEM_BNO_VIEW_OR_ID_FOUND_IN_SESSION_OR_VIEW_NOT_ALLOWED_TO_ACCESS_AREAB_WE_COULD_NOT_LOAD_ANY_LINKED_TO_VALUES_PLEASE_INFORM_YOUR_SYSTEM_ADMINISTRATOR="There was a problem, <b>no view or id found in session or view not allowed to access area</b>, we could not load any linked to values. Please inform your system administrator!"
COM_COMPONENTBUILDER_THE_BPHPSECLIBNETSFTPB_LIBRARYCLASS_IS_NOT_AVAILABLE_THIS_LIBRARYCLASS_SHOULD_HAVE_BEEN_ADDED_TO_YOUR_ADMINHELPERSVENDOR_FOLDER_OF_JCB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="The <b>phpseclib\NET\SFTP</b> library\class is not available! This library\class should have been added to your admin/helpers/vendor folder of JCB. Please contact your system administrator for more info"
COM_COMPONENTBUILDER_THE_BSB_LIBRARY_CAN_NOT_BE_DELETED_OR_THINGS_WILL_BREAK="The <b>%s</b> library can not be deleted, or things will break."
COM_COMPONENTBUILDER_THE_COMPONENT_ADMIN_VIEWS="The component admin views"
COM_COMPONENTBUILDER_THE_COMPONENT_CONFIG="The component config"
@ -6143,6 +6144,8 @@ COM_COMPONENTBUILDER_THE_COMPONENT_FILES_FOLDERS="The component files & folders"
COM_COMPONENTBUILDER_THE_COMPONENT_MYSQL_TWEAKS="The component mysql tweaks"
COM_COMPONENTBUILDER_THE_COMPONENT_SITE_VIEWS="The component site views"
COM_COMPONENTBUILDER_THE_COMPONENT_UPDATES="The component updates"
COM_COMPONENTBUILDER_THE_FTP_CONNECTION_FOR_BSB_COULD_NOT_BE_MADE_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS="The FTP connection for <b>%s</b> could not be made. Please check your signature details!"
COM_COMPONENTBUILDER_THE_FTP_SIGNATURE_FOR_BSB_WAS_NOT_WELL_FORMED_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS="The FTP signature for <b>%s</b> was not well formed, please check your signature details!"
COM_COMPONENTBUILDER_THE_KEY_OF_THIS_PACKAGE="The key of this package."
COM_COMPONENTBUILDER_THE_LIBRARY_CONFIG_FIELDS="The library config fields"
COM_COMPONENTBUILDER_THE_LIBRARY_FILES_FOLDERS_URLS="The library files, folders & URLs"
@ -6156,7 +6159,7 @@ COM_COMPONENTBUILDER_THE_PACKAGE_KEY_IS_S="The package key is: %s"
COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER="The private key file could not be loaded/found for <b>%s</b> server!"
COM_COMPONENTBUILDER_THE_README_IS_LOADING="The readme is loading"
COM_COMPONENTBUILDER_THE_SEARCH_FOR_THE_SNIPPETS_ARE_CASE_SENSITIVE_SO_IF_YOU_CHANGED_THE_LOCAL_BNAMESB_OF_EITHER_OR_THE_BSNIPPET_LIBRARY_OR_SNIPPET_TYPESB_IN_ANY_SMALL_WAY_THE_SYSTEM_WILL_NOT_BE_ABLE_TO_CONNECT_YOUR_LOCAL_SNIPPETS_WITH_THOSE_IN_THE_COMMUNITY_REPOSITORY_SO_WE_STRONGLY_ADVICE_TO_BKEEP_TO_THE_COMMUNITY_NAMINGB_TO_AVOID_MISMATCHING_THAT_WILL_IN_TURN_CAUSE_DUPLICATION_SO_IF_YOU_CHANGED_ANY_NAMES_JUST_CHANGE_THEM_BACK_AND_ALL_WILL_AGAIN_WORK_AS_EXPECTED="The search for the snippets are case sensitive so if you changed the local <b>names</b> of either or the <b>snippet, library or snippet types</b> in any small way, the system will not be able to connect your local snippets with those in the community repository. So we strongly advice to <b>keep to the community naming</b> to avoid mismatching, that will in turn cause duplication. So if you changed any names, just change them back and all will again work as expected."
COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BSB_COULD_NOT_BE_RETRIEVED="The server details for <b>(%s)</b> could not be retrieved!"
COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BID_SB_COULD_NOT_BE_RETRIEVED="The server details for <b>(ID: %s)</b> could not be retrieved!"
COM_COMPONENTBUILDER_THE_SNIPPETS_WERE_SUCCESSFULLY_EXPORTED="The Snippets Were Successfully Exported!"
COM_COMPONENTBUILDER_THE_SNIPPET_WAS_SUCCESSFULLY_EXPORTED="The Snippet Was Successfully Exported!"
COM_COMPONENTBUILDER_THE_WIKI_IS_LOADING="The wiki is loading"
@ -6207,6 +6210,7 @@ COM_COMPONENTBUILDER_YES="Yes"
COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEYBR_WITHOUT_THIS_KEY_IT_WILL_TAKE_THE_CURRENT_TECHNOLOGY_WITH_A_BRUTE_FORCE_ATTACK_METHOD_MORE_THEN_A_HREFHTTPRANDOMIZECOMHOWLONGTOHACKPASS_TARGET_BLANK_TITLEHOW_LONG_TO_HACK_PASSSEVEN_HUNDRED_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZEROA_YEARS_TO_CRACK_THEORETICALLY="Your data is encrypted with a AES 128 bit encryption using the above 32 character key.<br />Without this key it will take the current technology with a brute force attack method more then <a href="http://random-ize.com/how-long-to-hack-pass/" target="_blank" title="How long to hack pass">700 000 000 000 000 000 000 000 000 000 000</a> years to crack theoretically."
COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY_WITHOUT_THIS_KEY_IT_WILL_TAKE_THE_CURRENT_TECHNOLOGY_WITH_A_BRUTE_FORCE_ATTACK_METHOD_MORE_THEN_A_HREFHTTPRANDOMIZECOMHOWLONGTOHACKPASS_TARGET_BLANK_TITLEHOW_LONG_TO_HACK_PASSSEVEN_HUNDRED_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZEROA_YEARS_TO_CRACK_THEORETICALLY_UNLESS_THEY_HAVE_THIS_KEY_ABOVE_SO_DO_KEEP_IT_SAFE="Your data is encrypted with a AES 128 bit encryption using the above 32 character key. Without this key it will take the current technology with a brute force attack method more then <a href="http://random-ize.com/how-long-to-hack-pass/" target="_blank" title="How long to hack pass">700 000 000 000 000 000 000 000 000 000 000</a> years to crack theoretically. Unless they have this key above, so do keep it safe."
COM_COMPONENTBUILDER_YOU_CAN_NOW_SELECT_THE_COMPONENT_BZIPB_PACKAGE_YOU_WOULD_LIKE_TO_IMPORTBR_SMALLPLEASE_NOTE_THAT_SMART_COMPONENT_IMPORT_ONLY_WORKS_WITH_THE_FOLLOWING_FORMAT_BZIPBSMALL="You can now select the component <b>zip</b> package you would like to import.<br /><small>Please note that smart component import only works with the following format: <b>(.zip)</b></small>"
COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_DENIEDB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="You do not have permission to access the server details (<b>%s - denied</b>), please contact your system administrator for more info."
COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_IMPORT_A_COMPONENT_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to import a component, please contact your system administrator for more help."
COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_SHARE_THE_SNIPPETS_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to share the snippets, please contact your system administrator for more help."
COM_COMPONENTBUILDER_YOU_HAVE_S_S_ADDING_MORE_THEN_FIFTY_S_IS_CONSIDERED_BAD_PRACTICE="You have %s %s. Adding more then 50 %s is considered bad practice."

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.2" method="upgrade">
<name>COM_COMPONENTBUILDER</name>
<creationDate>17th February, 2018</creationDate>
<creationDate>19th February, 2018</creationDate>
<author>Llewellyn van der Merwe</author>
<authorEmail>llewellyn@joomlacomponentbuilder.com</authorEmail>
<authorUrl>http://joomlacomponentbuilder.com</authorUrl>

View File

@ -1020,39 +1020,76 @@ abstract class ComponentbuilderHelper
}
/**
* the SFTP object
* the SFTP objects
**/
protected static $sftp = array();
/**
* the FTP objects
**/
protected static $ftp = array();
/**
* get the server object
*
* @param int $serverID The server local id to use
* @param int $protocol The server protocol to use
* @param string $permission The permission validation area
*
* @return object on success server object
**/
public static function getServer($serverID, $protocol, $permission = 'core.export')
{
// return the server object
switch ($protocol)
{
case 1: // FTP
return self::getFtp($serverID, $permission);
break;
case 2: // SFTP
return self::getSftp($serverID, $permission);
break;
}
return false;
}
/**
* get the sftp object
*
* @param int $serverID The server local id to use
* @param int $serverID The server local id to use
* @param string $permission The permission validation area
*
* @return object on success with sftp power
**/
public static function getSftp($serverID)
public static function getSftp($serverID, $permission = 'core.export')
{
// check if it was already set
if (!self::checkObject(self::$sftp[$serverID]))
// check if we have a server with that id
if ($server = self::getServerDetails($serverID, 2, $permission))
{
// check if we have a server with that id
if ($server = self::getServerDetails($serverID, 2))
// check if it was already set
if (!isset(self::$sftp[$server->cache]) || !self::checkObject(self::$sftp[$server->cache]))
{
// make sure we have the composer classes loaded
self::composerAutoload();
// make sure we have the phpseclib classes
if (!class_exists('\phpseclib\Net\SFTP'))
{
// class not in place so send out error
JFactory::getApplication()->enqueueMessage(JText::_('COM_COMPONENTBUILDER_THE_BPHPSECLIBNETSFTPB_LIBRARYCLASS_IS_NOT_AVAILABLE_THIS_LIBRARYCLASS_SHOULD_HAVE_BEEN_ADDED_TO_YOUR_ADMINHELPERSVENDOR_FOLDER_OF_JCB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO'), 'Error');
return false;
}
// insure the port is set
$server->port = (isset($server->port) && is_int($server->port) && $server->port > 0) ? $server->port : 22;
// open the connection
self::$sftp[$serverID] = new phpseclib\Net\SFTP($server->host, $server->port);
self::$sftp[$server->cache] = new phpseclib\Net\SFTP($server->host, $server->port);
// now login based on authentication type
switch($server->authentication)
{
case 1: // password
// now login
if (!self::$sftp[$serverID]->login($server->username, $server->password))
if (!self::$sftp[$server->cache]->login($server->username, $server->password))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_AND_PASSWORD_ARE_CORRECT', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
break;
@ -1067,12 +1104,14 @@ abstract class ComponentbuilderHelper
if (!$rsa->loadKey(self::getFileContents($server->private, null)))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
// now login
if (!self::$sftp[$serverID]->login($server->username, $rsa))
if (!self::$sftp[$server->cache]->login($server->username, $rsa))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_AND_PRIVATE_KEY_FILE_ARE_CORRECT', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
break;
@ -1087,54 +1126,166 @@ abstract class ComponentbuilderHelper
if (!$rsa->loadKey(self::getFileContents($server->private, null)))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
// now login
if (!self::$sftp[$serverID]->login($server->username, $server->password, $rsa))
if (!self::$sftp[$server->cache]->login($server->username, $server->password, $rsa))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_PASSWORD_AND_PRIVATE_KEY_FILE_ARE_CORRECT', $server->name), 'Error');
unset(self::$sftp[$server->cache]);
return false;
}
break;
}
// set some defaults
self::$sftp[$serverID]->remote_server_name = $server->name;
self::$sftp[$serverID]->remote_server_path = (self::checkString($server->path) && $server->path !== '/') ? $server->path : '';
}
else
// only continue if object is set
if (isset(self::$sftp[$server->cache]) && self::checkObject(self::$sftp[$server->cache]))
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BSB_COULD_NOT_BE_RETRIEVED', $serverID), 'Error');
return false;
// set the unique buckets
if (!isset(self::$sftp[$server->cache]->remote_server_name))
{
self::$sftp[$server->cache]->remote_server_name = array();
self::$sftp[$server->cache]->remote_server_path = array();
}
// always set the name and remote server path
self::$sftp[$server->cache]->remote_server_name[$serverID] = $server->name;
self::$sftp[$server->cache]->remote_server_path[$serverID] = (self::checkString($server->path) && $server->path !== '/') ? $server->path : '';
// return the sftp object
return self::$sftp[$server->cache];
}
}
// return the sftp object
return self::$sftp[$serverID];
return false;
}
/**
* get the JClientFtp object
*
* @param int $serverID The server local id to use
* @param string $permission The permission validation area
*
* @return object on success with ftp power
**/
public static function getFtp($serverID, $permission)
{
// check if we have a server with that id
if ($server = self::getServerDetails($serverID, 1, $permission))
{
// check if we already have the server instance
if (isset(self::$ftp[$server->cache]) && self::$ftp[$server->cache] instanceof JClientFtp)
{
// always set the name and remote server path
self::$ftp[$server->cache]->remote_server_name[$serverID] = $server->name;
// if still connected we are ready to go
if (self::$ftp[$server->cache]->isConnected())
{
// return the FTP instance
return self::$ftp[$server->cache];
}
// check if we can reinitialise the server
if (self::$ftp[$server->cache]->reinit())
{
// return the FTP instance
return self::$ftp[$server->cache];
}
}
// make sure we have a string and it is not default or empty
if (self::checkString($server->signature))
{
// turn into variables
parse_str($server->signature); // because of this I am using strange variable naming to avoid any collisions.
// set options
if (isset($options) && self::checkArray($options))
{
foreach ($options as $o__p0t1on => $vAln3)
{
if ('timeout' === $o__p0t1on)
{
$options[$o__p0t1on] = (int) $vAln3;
}
if ('type' === $o__p0t1on)
{
$options[$o__p0t1on] = (string) $vAln3;
}
}
}
else
{
$options = array();
}
// get ftp object
if (isset($host) && $host != 'HOSTNAME' && isset($port) && $port != 'PORT_INT' && isset($username) && $username != 'user@name.com' && isset($password) && $password != 'password')
{
// load for reuse
self::$ftp[$server->cache] = JClientFtp::getInstance($host, $port, $options, $username, $password);
}
else
{
// load error to indicate signature was in error
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_FTP_SIGNATURE_FOR_BSB_WAS_NOT_WELL_FORMED_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS', $server->name), 'Error');
return false;
}
// check if we are connected
if (self::$ftp[$server->cache] instanceof JClientFtp && self::$ftp[$server->cache]->isConnected())
{
// set the unique buckets
if (!isset(self::$ftp[$server->cache]->remote_server_name))
{
self::$ftp[$server->cache]->remote_server_name = array();
}
// always set the name and remote server path
self::$ftp[$server->cache]->remote_server_name[$serverID] = $server->name;
// return the FTP instance
return self::$ftp[$server->cache];
}
// reset since we have no connection
unset(self::$ftp[$server->cache]);
}
// load error to indicate signature was in error
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_FTP_CONNECTION_FOR_BSB_COULD_NOT_BE_MADE_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS', $server->name), 'Error');
}
return false;
}
/**
* get the server details
*
* @param int $serverID The server local id to use
* @param int $protocol The server protocol to use
* @param int $serverID The server local id to use
* @param int $protocol The server protocol to use
* @param string $permission The permission validation area
*
* @return array on success with sftp server details
* @return object on success with server details
**/
protected static function getServerDetails($serverID, $protocol = 2)
public static function getServerDetails($serverID, $protocol = 2, $permission = 'core.export')
{
if (is_int($serverID) && is_int($serverID))
// check if this user has permission to access items
if (!JFactory::getUser()->authorise($permission, 'com_componentbuilder'))
{
// set message to inform the user that permission was denied
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_DENIEDB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO', self::safeString($permission, 'w')), 'Error');
return false;
}
// now insure we have correct values
if (is_int($serverID) && is_int($protocol))
{
// Get a db connection
$db = JFactory::getDbo();
// start the query
$query = $db->getQuery(true);
// select based to protocal
// select based to protocol
if (2 == $protocol)
{
// SFTP
$query->select($db->quoteName(array('name','authentication','username','host','password','path','port','private','secret')));
// cache builder
$cache = array('authentication','username','host','password','port','private','secret');
}
else
{
// FTP
$query->select($db->quoteName(array('name','signature')));
// cache builder
$cache = array('signature');
}
$query->from($db->quoteName('#__componentbuilder_server'));
$query->where($db->quoteName('id') . ' = ' . (int) $serverID);
@ -1148,21 +1299,42 @@ abstract class ComponentbuilderHelper
$basickey = self::getCryptKey('basic');
// Get the encryption object.
$basic = new FOFEncryptAes($basickey, 128);
// start cache keys
$keys = array();
// unlock the needed fields
foreach($server as $name => $value)
foreach($server as $name => &$value)
{
if ($name !== 'name' && !empty($server->{$name}) && $basickey && !is_numeric($server->{$name}) && $server->{$name} === base64_encode(base64_decode($server->{$name}, true)))
// unlock the needed fields
if ($name !== 'name' && !empty($value) && $basickey && !is_numeric($value) && $value === base64_encode(base64_decode($value, true)))
{
// basic decrypt of data
$server->{$name} = rtrim($basic->decryptString($server->{$name}), "\0");
$value = rtrim($basic->decryptString($value), "\0");
}
// build cache (keys) for lower connection latency
if (in_array($name, $cache))
{
$keys[] = $value;
}
}
// check if cache keys were found
if (self::checkArray($keys))
{
// now set cache
$server->cache = md5(implode('', $keys));
}
else
{
// default is ID
$server->cache = $serverID;
}
// return the server details
return $server;
}
}
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BID_SB_COULD_NOT_BE_RETRIEVED', $serverID), 'Error');
return false;
}
}
public static function jsonToString($value, $sperator = ", ", $table = null)
{

View File

@ -37,18 +37,22 @@ COM_COMPONENTBUILDER_SINCE_THE_OWNER_DETAILS_ARE_DISPLAYED_DURING_BIMPORT_PROCES
COM_COMPONENTBUILDER_SINCE_THE_OWNER_DETAILS_ARE_DISPLAYED_DURING_IMPORT_PROCESS_BEFORE_ADDING_THE_KEY_THIS_WAY_IF_THE_USERDEV_DOES_NOT_HAVE_THE_KEY_THEY_CAN_SEE_WHERE_TO_GET_IT="Since the owner details are displayed during import process before adding the key, this way if the user/dev does not have the key they can see where to get it."
COM_COMPONENTBUILDER_THAT_MEANS_ANYONE_WHO_HAS_THIS_PACKAGE_CAN_INSTALL_IT_INTO_JCB_TO_ADD_AN_EXPORT_KEY_SIMPLY_OPEN_THE_COMPONENT_GO_TO_THE_TAB_CALLED_BSETTINGSB_BOTTOM_RIGHT_THERE_IS_A_FIELD_CALLED_BEXPORT_KEYB="That means anyone who has this package can install it into JCB. To add an export key simply open the component, go to the tab called <b>settings</b>, bottom right there is a field called <b>Export Key</b>."
COM_COMPONENTBUILDER_THAT_MEANS_ANYONE_WHO_HAS_THIS_PACKAGE_CAN_INSTALL_IT_INTO_JCB_TO_ADD_AN_EXPORT_KEY_SIMPLY_OPEN_THE_COMPONENT_GO_TO_THE_TAB_CALLED_SETTINGS_BOTTOM_RIGHT_THERE_IS_A_FIELD_CALLED_EXPORT_KEY="That means anyone who has this package can install it into JCB. To add an export key simply open the component, go to the tab called settings, bottom right there is a field called Export Key."
COM_COMPONENTBUILDER_THE_BPHPSECLIBNETSFTPB_LIBRARYCLASS_IS_NOT_AVAILABLE_THIS_LIBRARYCLASS_SHOULD_HAVE_BEEN_ADDED_TO_YOUR_ADMINHELPERSVENDOR_FOLDER_OF_JCB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="The <b>phpseclib\NET\SFTP</b> library\class is not available! This library\class should have been added to your admin/helpers/vendor folder of JCB. Please contact your system administrator for more info"
COM_COMPONENTBUILDER_THE_FTP_CONNECTION_FOR_BSB_COULD_NOT_BE_MADE_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS="The FTP connection for <b>%s</b> could not be made. Please check your signature details!"
COM_COMPONENTBUILDER_THE_FTP_SIGNATURE_FOR_BSB_WAS_NOT_WELL_FORMED_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS="The FTP signature for <b>%s</b> was not well formed, please check your signature details!"
COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_AND_PASSWORD_ARE_CORRECT="The login to <b>%s</b> has failed, please check that your username and password are correct!"
COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_AND_PRIVATE_KEY_FILE_ARE_CORRECT="The login to <b>%s</b> has failed, please check that your username and private key file are correct!"
COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_USERNAME_PASSWORD_AND_PRIVATE_KEY_FILE_ARE_CORRECT="The login to <b>%s</b> has failed, please check that your username, password and private key file are correct!"
COM_COMPONENTBUILDER_THE_PACKAGE_KEY_IS_CODESCODE="The package key is: <code>%s</code>"
COM_COMPONENTBUILDER_THE_PACKAGE_KEY_IS_S="The package key is: %s"
COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER="The private key file could not be loaded/found for <b>%s</b> server!"
COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BSB_COULD_NOT_BE_RETRIEVED="The server details for <b>(%s)</b> could not be retrieved!"
COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BID_SB_COULD_NOT_BE_RETRIEVED="The server details for <b>(ID: %s)</b> could not be retrieved!"
COM_COMPONENTBUILDER_THIS_PACKAGE_HAS_NO_KEY="This package has no key."
COM_COMPONENTBUILDER_TO_CHANGE_THE_PACKAGE_OWNER_DEFAULTS_OPEN_THE_BJCB_GLOBAL_OPTIONSB_GO_TO_THE_BCOMPANYB_TAB_AND_ADD_THE_CORRECT_COMPANY_DETAILS_THERE="To change the package owner defaults. Open the <b>JCB Global Options</b>, go to the <b>Company</b> tab and add the correct company details there."
COM_COMPONENTBUILDER_TO_CHANGE_THE_PACKAGE_OWNER_DEFAULTS_OPEN_THE_JCB_GLOBAL_OPTIONS_GO_TO_THE_COMPANY_TAB_AND_ADD_THE_CORRECT_COMPANY_DETAILS_THERE="To change the package owner defaults. Open the JCB Global Options, go to the Company tab and add the correct company details there."
COM_COMPONENTBUILDER_WEBSITE_S="Website: %s"
COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY_WITHOUT_THIS_KEY_IT_WILL_TAKE_THE_CURRENT_TECHNOLOGY_WITH_A_BRUTE_FORCE_ATTACK_METHOD_MORE_THEN_A_HREFHTTPRANDOMIZECOMHOWLONGTOHACKPASS_TARGET_BLANK_TITLEHOW_LONG_TO_HACK_PASSSEVEN_HUNDRED_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZEROA_YEARS_TO_CRACK_THEORETICALLY_UNLESS_THEY_HAVE_THIS_KEY_ABOVE_SO_DO_KEEP_IT_SAFE="Your data is encrypted with a AES 128 bit encryption using the above 32 character key. Without this key it will take the current technology with a brute force attack method more then <a href="http://random-ize.com/how-long-to-hack-pass/" target="_blank" title="How long to hack pass">700 000 000 000 000 000 000 000 000 000 000</a> years to crack theoretically. Unless they have this key above, so do keep it safe."
COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_DENIEDB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="You do not have permission to access the server details (<b>%s - denied</b>), please contact your system administrator for more info."
COM_COMPONENTBUILDER_YOU_SHOULD_ADD_THE_CORRECT_OWNER_DETAILS="You should add the correct owner details."
COM_CONTENT_FIELD_MODIFIED_DESC="The last date this item was modified."
JGLOBAL_FIELD_ID_DESC="Record number in the database."