Version 4.7.0

This commit is contained in:
Neo committed 2025-12-19 16:00:35 -08:00
1 parent 517a5e1f70
commit 8ba7d43898
1933 files changed
+65613 -11332

No files matched your search

+1 -1
View File
@@ -549,7 +549,7 @@ class Convert
}
/* If we have moved the only row from $batch to $nextbatch, then process that now */
if ( \count( $nextBatch ) and ! \count( $batch ) )
if ( \is_array( $batch ) and \count( $nextBatch ) and ! \count( $batch ) )
{
$batch = $nextBatch;
$nextBatch = array();
+1 -1
View File
@@ -183,7 +183,7 @@ class Db extends \mysqli
* @see <a href="http://uk1.php.net/manual/en/mysqli.query.php">mysqli::query</a>
* @throws \IPS\Db\Exception
*/
public function query( $query )
public function query( string $query, int $result_mode = MYSQLI_STORE_RESULT )
{
/* Should we return the query instead of executing it? */
if( $this->returnQuery === TRUE )
+1 -1
View File
@@ -3,7 +3,7 @@
Nulled by IPBMafia.ru
Buy license at https://www.invisionpower.com/buy/self-hosted
================================================================
IPS 4.6.0 (106107)
IPS 4.7.0 (107014)
=============================[NOTE]=============================
Invision Community End User License Agreement
+1 -1
View File
@@ -1,4 +1,4 @@
<ips:template parameters="$name, $value, $required, $unlimited, $range, $min, $max, $step, $decimals, $unlimitedLang, $disabled=FALSE, $suffix, $toggles" />
<ips:template parameters="$name, $value, $required, $unlimited, $range, $min, $max, $step, $decimals, $unlimitedLang, $disabled=FALSE, $suffix='', $toggles=array()" />
<input
type="{{if $range}}range{{else}}number{{endif}}"
name="{$name}"
+1 -1
View File
@@ -1,4 +1,4 @@
<ips:template parameters="$name, $type, $value, $required, $maxlength=NULL, $size=NULL, $disabled=FALSE, $autoComplete=NULL, $placeholder" />
<ips:template parameters="$name, $type, $value, $required, $maxlength=NULL, $size=NULL, $disabled=FALSE, $autoComplete=NULL, $placeholder=NULL" />
<input
type="{$type}"
name="{$name}"
@@ -74,6 +74,7 @@
<h1 class='ipsType_pageTitle' id='elInstaller_welcome'>{lang="welcome_banner"}</h1>
<p class='ipsType_normal ipsType_light'>
{{if $initError}}
{lang="beforestart" sprintf="$path"}
{{else}}
{lang="beforestarto"}
@@ -89,6 +90,9 @@
{{endif}}
<p style="text-align: right; margin:10px">Nulled by IPBMafia.ru</p>
</main>
<div class="ipsType_center ipsType_light ipsPad_double">
{lang="server_ip"} {expression="$_SERVER['SERVER_ADDR'] ?? ( $_SERVER['LOCAL_ADDR'] ?? 'unavailable' )"}
</div>
</div>
</body>
</html>
+1
View File
@@ -198,6 +198,7 @@ $lang = array(
'admin' => "Admin",
'beforestart' => "Before we can begin, please rename conf_global.dist.php to conf_global.php in %s and ensure it is writable (usually CHMOD 0777).",
'beforestarto' => "This process will install your software for you. Be sure you have your license key and MySQL database details to hand.",
'server_ip' => "IP: ",
'install_guide' => "Install Guide",
+208 -5
View File
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<title>Invision Community Update Extractor</title>
<style type='text/css'>body{font-family:BlinkMacSystemFont, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.ipsProgressBar{width:50%;margin:auto;height:26px;overflow:hidden;background:rgb(237, 242, 247);background-image:linear-gradient(to bottom,rgba(23, 126, 201,0.1),rgba(23, 126, 201,0.1));border-radius:4px;}.ipsProgressBar_animated .ipsProgressBar_progress{background-color:rgb(23, 126, 201);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px;animation:progress-bar-stripes 2s linear infinite}.ipsProgressBar_progress{display:flex;align-items:center;width:0;height:100%;font-size:12px;color:#ffffff;text-align:right;background:rgb(23, 126, 201);position:relative;white-space:nowrap;line-height:26px;text-indent:6px;padding-right:2px;}.ipsProgressBar>span:first-child{padding-left:7px;}.ipsProgressBar_progress[data-progress]:after{top:0;color:#fff;content:attr(data-progress);display:block;right:5px;}</style>
<style type='text/css'>body{font-family:BlinkMacSystemFont, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.ipsProgressBar{width:50%;margin:auto;height:26px;overflow:hidden;background:rgb(237, 242, 247);background-image:linear-gradient(to bottom,rgba(23, 126, 201,0.1),rgba(23, 126, 201,0.1));border-radius:4px;}.ipsProgressBar_animated .ipsProgressBar_progress{background-color:rgb(23, 126, 201);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px;animation:progress-bar-stripes 2s linear infinite}.ipsProgressBar_progress{display:flex;align-items:center;width:0;height:100%;font-size:12px;color:#ffffff;text-align:right;background:rgb(23, 126, 201);position:relative;white-space:nowrap;line-height:26px;text-indent:6px;padding-right:2px;}.ipsProgressBar>span:first-child{padding-left:7px;}.ipsProgressBar_progress[data-progress]:after{top:0;color:#fff;content:attr(data-progress);display:block;right:5px;}@media (prefers-color-scheme: dark) { body{ background-color: rgb(45, 49, 57); } }</style>
</head>
<body style="margin:0">
<?php
@@ -26,7 +26,7 @@ if ( file_exists( "../../constants.php" ) )
{
require "../../constants.php";
}
foreach ( array( 'FOLDER_PERMISSION_NO_WRITE' => 0755, 'FILE_PERMISSION_NO_WRITE' => 0644, 'IPS_FILE_PERMISSION' => 0666, 'TEMP_DIRECTORY' => sys_get_temp_dir() ) as $k => $v )
foreach ( [ 'FOLDER_PERMISSION_NO_WRITE' => 0755, 'FILE_PERMISSION_NO_WRITE' => 0644, 'IPS_FILE_PERMISSION' => 0666, 'TEMP_DIRECTORY' => sys_get_temp_dir(), 'TEXT_ENCRYPTION_KEY' => NULL ] as $k => $v )
{
if ( !\defined( $k ) )
{
@@ -80,6 +80,16 @@ class Extractor
* @brief SFTP Directory
*/
private $sftpDir;
/**
* @brief Database connection
*/
public $db;
/**
* @brief Database prefix
*/
public $dbPrefix;
/**
* Constructor
@@ -109,7 +119,8 @@ class Extractor
{
require "../../conf_global.php";
$db = new mysqli( $INFO['sql_host'], $INFO['sql_user'], $INFO['sql_pass'], $INFO['sql_database'], !empty( $INFO['sql_port'] ) ? $INFO['sql_port'] : null, !empty( $INFO['sql_socket'] ) ? $INFO['sql_socket'] : null );
$this->db = new mysqli( $INFO['sql_host'], $INFO['sql_user'], $INFO['sql_pass'], $INFO['sql_database'], !empty( $INFO['sql_port'] ) ? $INFO['sql_port'] : null, !empty( $INFO['sql_socket'] ) ? $INFO['sql_socket'] : null );
$this->dbPrefix = $INFO['sql_tbl_prefix'] ?? '';
/* If the connection failed, do not continue */
if( $error = mysqli_connect_error() )
@@ -118,7 +129,7 @@ class Extractor
}
/* Check that there is an upgrade in progress */
$query = $db->query( "SELECT conf_value FROM {$INFO['sql_tbl_prefix']}core_sys_conf_settings WHERE conf_key='setup_in_progress'" );
$query = $this->db->query( "SELECT conf_value FROM {$this->dbPrefix}core_sys_conf_settings WHERE conf_key='setup_in_progress'" );
if( !$query )
{
return FALSE;
@@ -378,6 +389,176 @@ class Extractor
}
}
/**
* Encrypted - code from \IPS\Text\Encrypt
*/
class Encrypt
{
/**
* Get Key
*
* @return void
*/
public static function key()
{
require "../../conf_global.php";
return \TEXT_ENCRYPTION_KEY ?: md5( $INFO['sql_pass'] . $INFO['sql_database'] );
}
/**
* @brief Cipher
*/
public $cipher;
/**
* @brief IV
*/
protected $iv = NULL;
/**
* @brief Tag
*/
protected $tag = NULL;
/**
* @brief Hash of cipher
*/
protected $hmac = NULL;
/**
* From plaintext
*
* @param string $plaintext Plaintext
* @return static
*/
public static function fromPlaintext( $plaintext )
{
$obj = new static;
/* Try to use OpenSSL if it's available... */
if ( \function_exists( 'openssl_get_cipher_methods' ) )
{
/* If GCM is available (PHP 7.1+), use that as if provides authenticated encryption natively */
if ( \in_array( 'aes-128-gcm', openssl_get_cipher_methods() ) )
{
$obj->iv = openssl_random_pseudo_bytes( openssl_cipher_iv_length( 'aes-128-gcm' ) );
$obj->cipher = openssl_encrypt( $plaintext, 'aes-128-gcm', static::key(), 0, $obj->iv, $obj->tag );
return $obj;
}
/* Otherwise, use CBC and store the hash so we can do our own authentication when decrypting */
elseif ( \in_array( 'aes-128-cbc', openssl_get_cipher_methods() ) )
{
$obj->iv = openssl_random_pseudo_bytes( openssl_cipher_iv_length( 'aes-128-cbc' ) );
$obj->cipher = openssl_encrypt( $plaintext, 'aes-128-cbc', static::key(), OPENSSL_RAW_DATA, $obj->iv );
$obj->hmac = hash_hmac( 'sha256', $obj->cipher, static::key(), TRUE );
return $obj;
}
}
/* If we're still here, fallback to the PHP library */
require_once '../../system/3rd_party/AES/AES.php';
$obj->cipher = \AesCtr::encrypt( $plaintext, static::key(), 256 );
return $obj;
}
/**
* From plaintext
*
* @param string $cipher Cipher
* @param string|null $iv The IV, or if null, will use the PHP library rather than built-in openssl_*() methods
* @param string|null $tag The tag if using AES-128-GCM
* @param string|null $hash The hash if using AES-128-CBC
* @return static
*/
public static function fromCipher( $cipher, $iv = NULL, $tag = NULL, $hash = NULL )
{
$obj = new static;
$obj->cipher = $cipher;
$obj->iv = $iv;
$obj->tag = $tag;
$obj->hmac = $hash;
return $obj;
}
/**
* From tag
*
* @param string $tag Tag
* @return static
*/
public static function fromTag( $tag )
{
if ( preg_match( '/^\[\!AES128GCM\[(.+?)\]\[(.+?)\]\[(.+?)\]\]/', $tag, $matches ) )
{
return static::fromCipher( $matches[1], hex2bin( $matches[2] ), hex2bin( $matches[3] ) );
}
elseif ( preg_match( '/^\[\!AES128CBC\[(.+?)\]\]/', $tag, $matches ) )
{
$cipher = base64_decode( $matches[1] );
$ivLength = openssl_cipher_iv_length('aes-128-cbc');
return static::fromCipher( \substr( $cipher, $ivLength + 32 ), \substr( $cipher, 0, $ivLength ), NULL, \substr( $cipher, $ivLength, 32 ) );
}
elseif ( preg_match( '/^\[\!AES\[(.+?)\]\]/', $tag, $matches ) )
{
return static::fromCipher( $matches[1] );
}
else
{
return static::fromPlaintext( $tag );
}
}
/**
* Wrap in a tag to use later with fromTag
*
* @return string
*/
public function tag()
{
if ( $this->tag )
{
return '[!AES128GCM[' . $this->cipher . '][' . bin2hex( $this->iv ) . '][' . bin2hex( $this->tag ) . ']]';
}
elseif ( $this->hmac )
{
return '[!AES128CBC[' . base64_encode( $this->iv . $this->hmac . $this->cipher ) . ']]';
}
else
{
return '[!AES[' . $this->cipher . ']]';
}
}
/**
* Decript
*
* @return string
*/
public function decrypt()
{
if ( $this->tag )
{
return openssl_decrypt( $this->cipher, 'aes-128-gcm', static::key(), 0, $this->iv, $this->tag );
}
elseif ( $this->hmac )
{
$decrypted = openssl_decrypt( $this->cipher, 'aes-128-cbc', static::key(), OPENSSL_RAW_DATA, $this->iv );
if ( hash_equals( $this->hmac, hash_hmac( 'sha256', $this->cipher, static::key(), TRUE ) ) )
{
return $decrypted;
}
return '';
}
else
{
require_once '../../system/3rd_party/AES/AES.php';
return \AesCtr::decrypt( $this->cipher, static::key(), 256 );
}
}
}
/**
* Function to write a log file to disk
*
@@ -432,7 +613,29 @@ try
/* Establish an FTP connection if necessary */
if ( $_GET['ftp'] )
{
$extractor->connectToFtp( $_GET['ftp'] );
/* Get encrypted FTP credentials */
$query = $extractor->db->query( "SELECT conf_value FROM " . $extractor->dbPrefix . "core_sys_conf_settings WHERE conf_key='upgrade_ftp_details'" );
if( !$query )
{
throw new \RuntimeException('Cannot find (S)FTP credentials');
}
$ftpCredentials = $query->fetch_assoc()['conf_value'];
if( empty( $ftpCredentials ) )
{
throw new \RuntimeException('Cannot load (S)FTP credentials');
}
if ( \substr( $ftpCredentials, 0, 5 ) === '[!AES' )
{
$decodedFtpDetails = Encrypt::fromTag( $ftpCredentials )->decrypt();
}
else
{
$decodedFtpDetails = Encrypt::fromCipher( $ftpCredentials )->decrypt();
}
$extractor->connectToFtp( json_decode( $decodedFtpDetails, TRUE ) );
}
/* Extract a batch of files */
+1 -1
View File
@@ -1,4 +1,4 @@
<ips:template parameters="$name, $value, $required, $unlimited, $range, $min, $max, $step, $decimals, $unlimitedLang, $disabled=FALSE, $suffix, $toggles" />
<ips:template parameters="$name, $value, $required, $unlimited, $range, $min, $max, $step, $decimals, $unlimitedLang, $disabled=FALSE, $suffix='', $toggles=array()" />
<input
type="{{if $range}}range{{else}}number{{endif}}"
name="{$name}"
+1 -1
View File
@@ -1,4 +1,4 @@
<ips:template parameters="$name, $type, $value, $required, $maxlength=NULL, $size=NULL, $disabled=FALSE, $autoComplete=NULL, $placeholder" />
<ips:template parameters="$name, $type, $value, $required, $maxlength=NULL, $size=NULL, $disabled=FALSE, $autoComplete=NULL, $placeholder=NULL" />
<input
type="{$type}"
name="{$name}"