mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Added Allow/Disallow multiple identities
This commit is contained in:
parent
28d93f70ae
commit
2f482a6288
49 changed files with 32740 additions and 32243 deletions
|
|
@ -16,7 +16,7 @@ It's not recommended to use in production environment.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
RainLoop Webmail (**Community edition**) is released under
|
**RainLoop Webmail (Community edition)** is released under
|
||||||
**GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (AGPL)**.
|
**GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (AGPL)**.
|
||||||
http://www.gnu.org/licenses/agpl-3.0.html
|
http://www.gnu.org/licenses/agpl-3.0.html
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,6 @@
|
||||||
{
|
{
|
||||||
var
|
var
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
sStartupUrl = Utils.pString(Settings.settingsGet('StartupUrl')),
|
|
||||||
sCustomLogoutLink = Utils.pString(Settings.settingsGet('CustomLogoutLink')),
|
sCustomLogoutLink = Utils.pString(Settings.settingsGet('CustomLogoutLink')),
|
||||||
bInIframe = !!Settings.settingsGet('InIframe')
|
bInIframe = !!Settings.settingsGet('InIframe')
|
||||||
;
|
;
|
||||||
|
|
@ -235,7 +234,6 @@
|
||||||
|
|
||||||
if (bLogout)
|
if (bLogout)
|
||||||
{
|
{
|
||||||
sStartupUrl = '';
|
|
||||||
this.clearClientSideToken();
|
this.clearClientSideToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,11 +242,6 @@
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bAdmin)
|
|
||||||
{
|
|
||||||
sStartupUrl = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
sCustomLogoutLink = sCustomLogoutLink || (bAdmin ? Links.rootAdmin() : Links.rootUser());
|
sCustomLogoutLink = sCustomLogoutLink || (bAdmin ? Links.rootAdmin() : Links.rootUser());
|
||||||
|
|
||||||
if (bLogout && window.location.href !== sCustomLogoutLink)
|
if (bLogout && window.location.href !== sCustomLogoutLink)
|
||||||
|
|
@ -267,7 +260,7 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
kn.routeOff();
|
kn.routeOff();
|
||||||
kn.setHash(Links.root(sStartupUrl), true);
|
kn.setHash(Links.root(), true);
|
||||||
kn.routeOff();
|
kn.routeOff();
|
||||||
|
|
||||||
_.delay(function () {
|
_.delay(function () {
|
||||||
|
|
|
||||||
|
|
@ -1273,6 +1273,7 @@
|
||||||
self = this,
|
self = this,
|
||||||
$LAB = require('$LAB'),
|
$LAB = require('$LAB'),
|
||||||
sJsHash = Settings.settingsGet('JsHash'),
|
sJsHash = Settings.settingsGet('JsHash'),
|
||||||
|
sStartupUrl = Utils.pString(Settings.settingsGet('StartupUrl')),
|
||||||
iContactsSyncInterval = Utils.pInt(Settings.settingsGet('ContactsSyncInterval')),
|
iContactsSyncInterval = Utils.pInt(Settings.settingsGet('ContactsSyncInterval')),
|
||||||
bGoogle = Settings.settingsGet('AllowGoogleSocial'),
|
bGoogle = Settings.settingsGet('AllowGoogleSocial'),
|
||||||
bFacebook = Settings.settingsGet('AllowFacebookSocial'),
|
bFacebook = Settings.settingsGet('AllowFacebookSocial'),
|
||||||
|
|
@ -1314,6 +1315,13 @@
|
||||||
|
|
||||||
if (bValue)
|
if (bValue)
|
||||||
{
|
{
|
||||||
|
if ('' !== sStartupUrl)
|
||||||
|
{
|
||||||
|
kn.routeOff();
|
||||||
|
kn.setHash(Links.root(sStartupUrl), true);
|
||||||
|
kn.routeOn();
|
||||||
|
}
|
||||||
|
|
||||||
if ($LAB && window.crypto && window.crypto.getRandomValues && Settings.capa(Enums.Capa.OpenPGP))
|
if ($LAB && window.crypto && window.crypto.getRandomValues && Settings.capa(Enums.Capa.OpenPGP))
|
||||||
{
|
{
|
||||||
var fOpenpgpCallback = function (openpgp) {
|
var fOpenpgpCallback = function (openpgp) {
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,8 @@
|
||||||
'AttachmentThumbnails': 'ATTACHMENT_THUMBNAILS',
|
'AttachmentThumbnails': 'ATTACHMENT_THUMBNAILS',
|
||||||
'Templates': 'TEMPLATES',
|
'Templates': 'TEMPLATES',
|
||||||
'AutoLogout': 'AUTOLOGOUT',
|
'AutoLogout': 'AUTOLOGOUT',
|
||||||
'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS'
|
'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS',
|
||||||
|
'Identities': 'IDENTITIES'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,12 @@
|
||||||
'SettingsContacts', 'SETTINGS_LABELS/LABEL_CONTACTS_NAME', 'contacts');
|
'SettingsContacts', 'SETTINGS_LABELS/LABEL_CONTACTS_NAME', 'contacts');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Settings.capa(Enums.Capa.AdditionalAccounts) || Settings.capa(Enums.Capa.Identities))
|
||||||
|
{
|
||||||
kn.addSettingsViewModel(require('Settings/User/Accounts'), 'SettingsAccounts',
|
kn.addSettingsViewModel(require('Settings/User/Accounts'), 'SettingsAccounts',
|
||||||
Settings.capa(Enums.Capa.AdditionalAccounts) ?
|
Settings.capa(Enums.Capa.AdditionalAccounts) ?
|
||||||
'SETTINGS_LABELS/LABEL_ACCOUNTS_NAME' : 'SETTINGS_LABELS/LABEL_IDENTITIES_NAME', 'accounts');
|
'SETTINGS_LABELS/LABEL_ACCOUNTS_NAME' : 'SETTINGS_LABELS/LABEL_IDENTITIES_NAME', 'accounts');
|
||||||
|
}
|
||||||
|
|
||||||
if (Settings.capa(Enums.Capa.Sieve))
|
if (Settings.capa(Enums.Capa.Sieve))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
this.capaUserBackground = CapaAdminStore.userBackground;
|
this.capaUserBackground = CapaAdminStore.userBackground;
|
||||||
this.capaGravatar = CapaAdminStore.gravatar;
|
this.capaGravatar = CapaAdminStore.gravatar;
|
||||||
this.capaAdditionalAccounts = CapaAdminStore.additionalAccounts;
|
this.capaAdditionalAccounts = CapaAdminStore.additionalAccounts;
|
||||||
|
this.capaIdentities = CapaAdminStore.identities;
|
||||||
this.capaAttachmentThumbnails = CapaAdminStore.attachmentThumbnails;
|
this.capaAttachmentThumbnails = CapaAdminStore.attachmentThumbnails;
|
||||||
this.capaTemplates = CapaAdminStore.templates;
|
this.capaTemplates = CapaAdminStore.templates;
|
||||||
|
|
||||||
|
|
@ -136,6 +137,12 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.capaIdentities.subscribe(function (bValue) {
|
||||||
|
Remote.saveAdminConfig(null, {
|
||||||
|
'CapaIdentities': bValue ? '1' : '0'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
self.capaTemplates.subscribe(function (bValue) {
|
self.capaTemplates.subscribe(function (bValue) {
|
||||||
Remote.saveAdminConfig(null, {
|
Remote.saveAdminConfig(null, {
|
||||||
'CapaTemplates': bValue ? '1' : '0'
|
'CapaTemplates': bValue ? '1' : '0'
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
function AccountsUserSettings()
|
function AccountsUserSettings()
|
||||||
{
|
{
|
||||||
this.allowAdditionalAccount = Settings.capa(Enums.Capa.AdditionalAccounts);
|
this.allowAdditionalAccount = Settings.capa(Enums.Capa.AdditionalAccounts);
|
||||||
this.allowIdentities = true;
|
this.allowIdentities = Settings.capa(Enums.Capa.Identities);;
|
||||||
|
|
||||||
this.accounts = AccountStore.accounts;
|
this.accounts = AccountStore.accounts;
|
||||||
this.identities = IdentityStore.identities;
|
this.identities = IdentityStore.identities;
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,12 @@
|
||||||
AppStore = require('Stores/User/App'),
|
AppStore = require('Stores/User/App'),
|
||||||
LanguageStore = require('Stores/Language'),
|
LanguageStore = require('Stores/Language'),
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
|
IdentityStore = require('Stores/User/Identity'),
|
||||||
NotificationStore = require('Stores/User/Notification'),
|
NotificationStore = require('Stores/User/Notification'),
|
||||||
MessageStore = require('Stores/User/Message'),
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
|
Settings = require('Storage/Settings'),
|
||||||
|
|
||||||
Remote = require('Remote/User/Ajax')
|
Remote = require('Remote/User/Ajax')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -62,6 +65,20 @@
|
||||||
|
|
||||||
this.isAnimationSupported = Globals.bAnimationSupported;
|
this.isAnimationSupported = Globals.bAnimationSupported;
|
||||||
|
|
||||||
|
this.identities = IdentityStore.identities;
|
||||||
|
|
||||||
|
this.identityMain = ko.computed(function () {
|
||||||
|
var aList = this.identities();
|
||||||
|
return Utils.isArray(aList) ? _.find(aList, function (oItem) {
|
||||||
|
return oItem && '' === oItem.id() ? true : false;
|
||||||
|
}) : null;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.identityMainDesc = ko.computed(function () {
|
||||||
|
var oIdentity = this.identityMain();
|
||||||
|
return oIdentity ? oIdentity.formattedName() : '---';
|
||||||
|
}, this);
|
||||||
|
|
||||||
this.editorDefaultTypes = ko.computed(function () {
|
this.editorDefaultTypes = ko.computed(function () {
|
||||||
Translator.trigger();
|
Translator.trigger();
|
||||||
return [
|
return [
|
||||||
|
|
@ -82,6 +99,15 @@
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GeneralUserSettings.prototype.editMainIdentity = function ()
|
||||||
|
{
|
||||||
|
var oIdentity = this.identityMain();
|
||||||
|
if (oIdentity)
|
||||||
|
{
|
||||||
|
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Identity'), [oIdentity]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
GeneralUserSettings.prototype.testSoundNotification = function ()
|
GeneralUserSettings.prototype.testSoundNotification = function ()
|
||||||
{
|
{
|
||||||
NotificationStore.playSoundNotification(true);
|
NotificationStore.playSoundNotification(true);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
function CapaAdminStore()
|
function CapaAdminStore()
|
||||||
{
|
{
|
||||||
this.additionalAccounts = ko.observable(false);
|
this.additionalAccounts = ko.observable(false);
|
||||||
|
this.identities = ko.observable(false);
|
||||||
this.gravatar = ko.observable(false);
|
this.gravatar = ko.observable(false);
|
||||||
this.attachmentThumbnails = ko.observable(false);
|
this.attachmentThumbnails = ko.observable(false);
|
||||||
this.sieve = ko.observable(false);
|
this.sieve = ko.observable(false);
|
||||||
|
|
@ -32,6 +33,7 @@
|
||||||
CapaAdminStore.prototype.populate = function()
|
CapaAdminStore.prototype.populate = function()
|
||||||
{
|
{
|
||||||
this.additionalAccounts(Settings.capa(Enums.Capa.AdditionalAccounts));
|
this.additionalAccounts(Settings.capa(Enums.Capa.AdditionalAccounts));
|
||||||
|
this.identities(Settings.capa(Enums.Capa.Identities));
|
||||||
this.gravatar(Settings.capa(Enums.Capa.Gravatar));
|
this.gravatar(Settings.capa(Enums.Capa.Gravatar));
|
||||||
this.attachmentThumbnails(Settings.capa(Enums.Capa.AttachmentThumbnails));
|
this.attachmentThumbnails(Settings.capa(Enums.Capa.AttachmentThumbnails));
|
||||||
this.sieve(Settings.capa(Enums.Capa.Sieve));
|
this.sieve(Settings.capa(Enums.Capa.Sieve));
|
||||||
|
|
|
||||||
|
|
@ -899,6 +899,20 @@ END;
|
||||||
return $sResult;
|
return $sResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sDomain
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function GetClearDomainName($sDomain)
|
||||||
|
{
|
||||||
|
$sResultDomain = \preg_replace(
|
||||||
|
'/^(webmail|email|mail|www|imap4|pop3|imap|pop|demo|client|ssl|secure)\./i',
|
||||||
|
'', $sDomain);
|
||||||
|
|
||||||
|
return false === \strpos($sResultDomain, '.') ? $sDomain : $sResultDomain;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sFileName
|
* @param string $sFileName
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -194,9 +194,8 @@ class Actions
|
||||||
*/
|
*/
|
||||||
public function GetShortLifeSpecAuthToken($iLife = 60)
|
public function GetShortLifeSpecAuthToken($iLife = 60)
|
||||||
{
|
{
|
||||||
$sToken = $this->getAuthToken();
|
$aAccountHash = \RainLoop\Utils::DecodeKeyValues($this->getLocalAuthToken());
|
||||||
$aAccountHash = \RainLoop\Utils::DecodeKeyValues($sToken);
|
if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && \is_array($aAccountHash))
|
||||||
if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && is_array($aAccountHash))
|
|
||||||
{
|
{
|
||||||
$aAccountHash[10] = \time() + $iLife;
|
$aAccountHash[10] = \time() + $iLife;
|
||||||
return \RainLoop\Utils::EncodeKeyValues($aAccountHash);
|
return \RainLoop\Utils::EncodeKeyValues($aAccountHash);
|
||||||
|
|
@ -458,6 +457,18 @@ class Actions
|
||||||
$this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $sLine);
|
$this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $sLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (false !== \strpos($sLine, '{request:domain}'))
|
||||||
|
{
|
||||||
|
$sLine = \str_replace('{request:domain}',
|
||||||
|
$this->Http()->GetHost(false, true, true), $sLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false !== \strpos($sLine, '{request:domain-clear}'))
|
||||||
|
{
|
||||||
|
$sLine = \str_replace('{request:domain-clear}',
|
||||||
|
\MailSo\Base\Utils::GetClearDomainName($this->Http()->GetHost(false, true, true)), $sLine);
|
||||||
|
}
|
||||||
|
|
||||||
$sLine = \preg_replace('/\{request:([^}]*)\}/i', 'request', $sLine);
|
$sLine = \preg_replace('/\{request:([^}]*)\}/i', 'request', $sLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -489,8 +500,12 @@ class Actions
|
||||||
{
|
{
|
||||||
$sEmail = $oAccount->Email();
|
$sEmail = $oAccount->Email();
|
||||||
$sLine = \str_replace('{user:email}', $sEmail, $sLine);
|
$sLine = \str_replace('{user:email}', $sEmail, $sLine);
|
||||||
$sLine = \str_replace('{user:login}', \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail), $sLine);
|
$sLine = \str_replace('{user:login}',
|
||||||
$sLine = \str_replace('{user:domain}', \MailSo\Base\Utils::GetDomainFromEmail($sEmail), $sLine);
|
\MailSo\Base\Utils::GetAccountNameFromEmail($sEmail), $sLine);
|
||||||
|
$sLine = \str_replace('{user:domain}',
|
||||||
|
\MailSo\Base\Utils::GetDomainFromEmail($sEmail), $sLine);
|
||||||
|
$sLine = \str_replace('{user:domain-clear}',
|
||||||
|
\MailSo\Base\Utils::GetClearDomainName(\MailSo\Base\Utils::GetDomainFromEmail($sEmail)), $sLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -552,7 +567,7 @@ class Actions
|
||||||
{
|
{
|
||||||
if ($oAccount)
|
if ($oAccount)
|
||||||
{
|
{
|
||||||
$sSpecAuthToken = '_'.$oAccount->GetAuthToken();
|
$sSpecAuthToken = '_'.$oAccount->GetAuthTokenQ();
|
||||||
|
|
||||||
$this->SetSpecAuthToken($sSpecAuthToken);
|
$this->SetSpecAuthToken($sSpecAuthToken);
|
||||||
\RainLoop\Utils::SetCookie(self::AUTH_SPEC_TOKEN_KEY, $sSpecAuthToken, 0, '/', null, null, true);
|
\RainLoop\Utils::SetCookie(self::AUTH_SPEC_TOKEN_KEY, $sSpecAuthToken, 0, '/', null, null, true);
|
||||||
|
|
@ -560,7 +575,7 @@ class Actions
|
||||||
if ($oAccount->SignMe() && 0 < \strlen($oAccount->SignMeToken()))
|
if ($oAccount->SignMe() && 0 < \strlen($oAccount->SignMeToken()))
|
||||||
{
|
{
|
||||||
\RainLoop\Utils::SetCookie(self::AUTH_SIGN_ME_TOKEN_KEY,
|
\RainLoop\Utils::SetCookie(self::AUTH_SIGN_ME_TOKEN_KEY,
|
||||||
\RainLoop\Utils::EncodeKeyValues(array(
|
\RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
'e' => $oAccount->Email(),
|
'e' => $oAccount->Email(),
|
||||||
't' => $oAccount->SignMeToken()
|
't' => $oAccount->SignMeToken()
|
||||||
)),
|
)),
|
||||||
|
|
@ -569,9 +584,9 @@ class Actions
|
||||||
$this->StorageProvider()->Put($oAccount,
|
$this->StorageProvider()->Put($oAccount,
|
||||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||||
'sign_me',
|
'sign_me',
|
||||||
\RainLoop\Utils::EncodeKeyValues(array(
|
\RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
'Time' => \time(),
|
'Time' => \time(),
|
||||||
'AuthToken' => $oAccount->GetAuthToken(),
|
'AuthToken' => $oAccount->GetAuthTokenQ(),
|
||||||
'SignMetToken' => $oAccount->SignMeToken()
|
'SignMetToken' => $oAccount->SignMeToken()
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|
@ -618,7 +633,7 @@ class Actions
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function getAuthToken()
|
private function getLocalAuthToken()
|
||||||
{
|
{
|
||||||
$sToken = $this->GetSpecAuthToken();
|
$sToken = $this->GetSpecAuthToken();
|
||||||
return !empty($sToken) && '_' === \substr($sToken, 0, 1) ? \substr($sToken, 1) : '';
|
return !empty($sToken) && '_' === \substr($sToken, 0, 1) ? \substr($sToken, 1) : '';
|
||||||
|
|
@ -637,7 +652,7 @@ class Actions
|
||||||
*/
|
*/
|
||||||
public function ClearAdminAuthToken()
|
public function ClearAdminAuthToken()
|
||||||
{
|
{
|
||||||
$aAdminHash = \RainLoop\Utils::DecodeKeyValues($this->getAdminAuthToken());
|
$aAdminHash = \RainLoop\Utils::DecodeKeyValuesQ($this->getAdminAuthToken());
|
||||||
if (
|
if (
|
||||||
!empty($aAdminHash[0]) && !empty($aAdminHash[1]) && !empty($aAdminHash[2]) &&
|
!empty($aAdminHash[0]) && !empty($aAdminHash[1]) && !empty($aAdminHash[2]) &&
|
||||||
'token' === $aAdminHash[0] && \md5(APP_SALT) === $aAdminHash[1]
|
'token' === $aAdminHash[0] && \md5(APP_SALT) === $aAdminHash[1]
|
||||||
|
|
@ -1085,7 +1100,7 @@ class Actions
|
||||||
$sRand = '';
|
$sRand = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '' === $sRand ? '' : \RainLoop\Utils::EncodeKeyValues(array('token', \md5(APP_SALT), $sRand));
|
return '' === $sRand ? '' : \RainLoop\Utils::EncodeKeyValuesQ(array('token', \md5(APP_SALT), $sRand));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1098,7 +1113,7 @@ class Actions
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
if ($this->Config()->Get('security', 'allow_admin_panel', true))
|
if ($this->Config()->Get('security', 'allow_admin_panel', true))
|
||||||
{
|
{
|
||||||
$aAdminHash = \RainLoop\Utils::DecodeKeyValues($this->getAdminAuthToken());
|
$aAdminHash = \RainLoop\Utils::DecodeKeyValuesQ($this->getAdminAuthToken());
|
||||||
if (!empty($aAdminHash[0]) && !empty($aAdminHash[1]) && !empty($aAdminHash[2]) &&
|
if (!empty($aAdminHash[0]) && !empty($aAdminHash[1]) && !empty($aAdminHash[2]) &&
|
||||||
'token' === $aAdminHash[0] && \md5(APP_SALT) === $aAdminHash[1] &&
|
'token' === $aAdminHash[0] && \md5(APP_SALT) === $aAdminHash[1] &&
|
||||||
'' !== $this->Cacher(null, true)->Get(\RainLoop\KeyPathHelper::SessionAdminKey($aAdminHash[2]), '')
|
'' !== $this->Cacher(null, true)->Get(\RainLoop\KeyPathHelper::SessionAdminKey($aAdminHash[2]), '')
|
||||||
|
|
@ -1124,7 +1139,7 @@ class Actions
|
||||||
if (!empty($sTo))
|
if (!empty($sTo))
|
||||||
{
|
{
|
||||||
\RainLoop\Utils::SetCookie(self::AUTH_MAILTO_TOKEN_KEY,
|
\RainLoop\Utils::SetCookie(self::AUTH_MAILTO_TOKEN_KEY,
|
||||||
\RainLoop\Utils::EncodeKeyValues(array(
|
\RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
'Time' => \microtime(true),
|
'Time' => \microtime(true),
|
||||||
'MailTo' => 'MailTo',
|
'MailTo' => 'MailTo',
|
||||||
'To' => $sTo
|
'To' => $sTo
|
||||||
|
|
@ -1177,16 +1192,17 @@ class Actions
|
||||||
* @param string $sToken
|
* @param string $sToken
|
||||||
* @param bool $bThrowExceptionOnFalse = true
|
* @param bool $bThrowExceptionOnFalse = true
|
||||||
* @param bool $bValidateShortToken = true
|
* @param bool $bValidateShortToken = true
|
||||||
|
* @param bool $bQ = false
|
||||||
*
|
*
|
||||||
* @return \RainLoop\Model\Account|bool
|
* @return \RainLoop\Model\Account|bool
|
||||||
* @throws \RainLoop\Exceptions\ClientException
|
* @throws \RainLoop\Exceptions\ClientException
|
||||||
*/
|
*/
|
||||||
public function GetAccountFromCustomToken($sToken, $bThrowExceptionOnFalse = true, $bValidateShortToken = true)
|
public function GetAccountFromCustomToken($sToken, $bThrowExceptionOnFalse = true, $bValidateShortToken = true, $bQ = false)
|
||||||
{
|
{
|
||||||
$oResult = false;
|
$oResult = false;
|
||||||
if (!empty($sToken))
|
if (!empty($sToken))
|
||||||
{
|
{
|
||||||
$aAccountHash = \RainLoop\Utils::DecodeKeyValues($sToken);
|
$aAccountHash = $bQ ? \RainLoop\Utils::DecodeKeyValuesQ($sToken) : \RainLoop\Utils::DecodeKeyValues($sToken);
|
||||||
if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && // simple token validation
|
if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && // simple token validation
|
||||||
8 <= \count($aAccountHash) && // length checking
|
8 <= \count($aAccountHash) && // length checking
|
||||||
!empty($aAccountHash[7]) && // does short token exist
|
!empty($aAccountHash[7]) && // does short token exist
|
||||||
|
|
@ -1236,7 +1252,7 @@ class Actions
|
||||||
$sSignMeToken = \RainLoop\Utils::GetCookie(\RainLoop\Actions::AUTH_SIGN_ME_TOKEN_KEY, '');
|
$sSignMeToken = \RainLoop\Utils::GetCookie(\RainLoop\Actions::AUTH_SIGN_ME_TOKEN_KEY, '');
|
||||||
if (!empty($sSignMeToken))
|
if (!empty($sSignMeToken))
|
||||||
{
|
{
|
||||||
$aTokenData = \RainLoop\Utils::DecodeKeyValues($sSignMeToken);
|
$aTokenData = \RainLoop\Utils::DecodeKeyValuesQ($sSignMeToken);
|
||||||
if (\is_array($aTokenData) && !empty($aTokenData['e']) && !empty($aTokenData['t']))
|
if (\is_array($aTokenData) && !empty($aTokenData['e']) && !empty($aTokenData['t']))
|
||||||
{
|
{
|
||||||
$sTokenSettings = $this->StorageProvider()->Get($aTokenData['e'],
|
$sTokenSettings = $this->StorageProvider()->Get($aTokenData['e'],
|
||||||
|
|
@ -1246,13 +1262,13 @@ class Actions
|
||||||
|
|
||||||
if (!empty($sTokenSettings))
|
if (!empty($sTokenSettings))
|
||||||
{
|
{
|
||||||
$aSignMeData = \RainLoop\Utils::DecodeKeyValues($sTokenSettings);
|
$aSignMeData = \RainLoop\Utils::DecodeKeyValuesQ($sTokenSettings);
|
||||||
if (\is_array($aSignMeData) &&
|
if (\is_array($aSignMeData) &&
|
||||||
!empty($aSignMeData['AuthToken']) &&
|
!empty($aSignMeData['AuthToken']) &&
|
||||||
!empty($aSignMeData['SignMetToken']) &&
|
!empty($aSignMeData['SignMetToken']) &&
|
||||||
$aSignMeData['SignMetToken'] === $aTokenData['t'])
|
$aSignMeData['SignMetToken'] === $aTokenData['t'])
|
||||||
{
|
{
|
||||||
$oAccount = $this->GetAccountFromCustomToken($aSignMeData['AuthToken'], false, false);
|
$oAccount = $this->GetAccountFromCustomToken($aSignMeData['AuthToken'], false, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1273,7 +1289,7 @@ class Actions
|
||||||
*/
|
*/
|
||||||
public function getAccountFromToken($bThrowExceptionOnFalse = true)
|
public function getAccountFromToken($bThrowExceptionOnFalse = true)
|
||||||
{
|
{
|
||||||
return $this->GetAccountFromCustomToken($this->getAuthToken(), $bThrowExceptionOnFalse);
|
return $this->GetAccountFromCustomToken($this->getLocalAuthToken(), $bThrowExceptionOnFalse, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1467,9 +1483,10 @@ class Actions
|
||||||
if (null !== $sToken)
|
if (null !== $sToken)
|
||||||
{
|
{
|
||||||
\RainLoop\Utils::ClearCookie(self::AUTH_MAILTO_TOKEN_KEY);
|
\RainLoop\Utils::ClearCookie(self::AUTH_MAILTO_TOKEN_KEY);
|
||||||
$mMailToData = \RainLoop\Utils::DecodeKeyValues($sToken);
|
|
||||||
if (\is_array($mMailToData) && !empty($mMailToData['MailTo']) && 'MailTo' === $mMailToData['MailTo'] &&
|
$mMailToData = \RainLoop\Utils::DecodeKeyValuesQ($sToken);
|
||||||
!empty($mMailToData['To']))
|
if (\is_array($mMailToData) && !empty($mMailToData['MailTo']) &&
|
||||||
|
'MailTo' === $mMailToData['MailTo'] && !empty($mMailToData['To']))
|
||||||
{
|
{
|
||||||
$aResult['MailToEmail'] = $mMailToData['To'];
|
$aResult['MailToEmail'] = $mMailToData['To'];
|
||||||
}
|
}
|
||||||
|
|
@ -1496,6 +1513,8 @@ class Actions
|
||||||
$aResult['WelcomePageUrl'] = '';
|
$aResult['WelcomePageUrl'] = '';
|
||||||
$aResult['WelcomePageDisplay'] = '';
|
$aResult['WelcomePageDisplay'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$aResult['StartupUrl'] = $this->compileLogParams($aResult['StartupUrl'], $oAccount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1509,6 +1528,8 @@ class Actions
|
||||||
|
|
||||||
$aResult['WelcomePageUrl'] = '';
|
$aResult['WelcomePageUrl'] = '';
|
||||||
$aResult['WelcomePageDisplay'] = '';
|
$aResult['WelcomePageDisplay'] = '';
|
||||||
|
|
||||||
|
$aResult['StartupUrl'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false);
|
$aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false);
|
||||||
|
|
@ -2109,51 +2130,27 @@ class Actions
|
||||||
*/
|
*/
|
||||||
private function clientRsaDecryptHelper($sEncryptedData)
|
private function clientRsaDecryptHelper($sEncryptedData)
|
||||||
{
|
{
|
||||||
$aMatch = array();
|
// $aMatch = array();
|
||||||
if ('rsa:xxx:' === substr($sEncryptedData, 0, 8) && $this->Config()->Get('security', 'use_rsa_encryption', false))
|
// if ('rsa:xxx:' === \substr($sEncryptedData, 0, 8) && $this->Config()->Get('security', 'use_rsa_encryption', false))
|
||||||
{
|
// {
|
||||||
$oLogger = $this->Logger();
|
// $oLogger = $this->Logger();
|
||||||
$oLogger->Write('Trying to decode encrypted data', \MailSo\Log\Enumerations\Type::INFO, 'RSA');
|
// $oLogger->Write('Trying to decode encrypted data', \MailSo\Log\Enumerations\Type::INFO, 'RSA');
|
||||||
|
// $oLogger->HideErrorNotices(true);
|
||||||
$sPrivateKey = file_exists(APP_PRIVATE_DATA.'rsa/private') ?
|
//
|
||||||
\file_get_contents(APP_PRIVATE_DATA.'rsa/private') : '';
|
// $sData = \trim(\substr($sEncryptedData, 8));
|
||||||
|
// $sData = \RainLoop\Utils::DecryptStringRSA(\base64_decode($sData));
|
||||||
if (!empty($sPrivateKey))
|
//
|
||||||
{
|
// if (false !== $sData && \preg_match('/^[a-z0-9]{32}:(.+):[a-z0-9]{32}$/', $sData, $aMatch) && isset($aMatch[1]))
|
||||||
$sData = \trim(\substr($sEncryptedData, 8));
|
// {
|
||||||
|
// $sEncryptedData = $aMatch[1];
|
||||||
if (!\class_exists('Crypt_RSA'))
|
// }
|
||||||
{
|
// else
|
||||||
\set_include_path(\get_include_path().PATH_SEPARATOR.APP_VERSION_ROOT_PATH.'app/libraries/phpseclib');
|
// {
|
||||||
include_once 'Crypt/RSA.php';
|
// $oLogger->Write('Invalid decrypted data', \MailSo\Log\Enumerations\Type::WARNING, 'RSA');
|
||||||
\defined('CRYPT_RSA_MODE') || \define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
// }
|
||||||
}
|
//
|
||||||
|
// $oLogger->HideErrorNotices(false);
|
||||||
$oLogger->HideErrorNotices(true);
|
// }
|
||||||
|
|
||||||
$oRsa = new \Crypt_RSA();
|
|
||||||
$oRsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
|
|
||||||
$oRsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
|
|
||||||
$oRsa->setPrivateKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
|
|
||||||
$oRsa->loadKey($sPrivateKey, CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
|
|
||||||
|
|
||||||
$sData = $oRsa->decrypt(\base64_decode($sData));
|
|
||||||
if (\preg_match('/^[a-z0-9]{32}:(.+):[a-z0-9]{32}$/', $sData, $aMatch) && isset($aMatch[1]))
|
|
||||||
{
|
|
||||||
$sEncryptedData = $aMatch[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$oLogger->Write('Invalid decrypted data', \MailSo\Log\Enumerations\Type::WARNING, 'RSA');
|
|
||||||
}
|
|
||||||
|
|
||||||
$oLogger->HideErrorNotices(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$oLogger->Write('Private key is not found', \MailSo\Log\Enumerations\Type::WARNING, 'RSA');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $sEncryptedData;
|
return $sEncryptedData;
|
||||||
}
|
}
|
||||||
|
|
@ -2290,6 +2287,7 @@ class Actions
|
||||||
1 < \count($aOrder['Accounts']))
|
1 < \count($aOrder['Accounts']))
|
||||||
{
|
{
|
||||||
$aAccounts = \array_merge(\array_flip($aOrder['Accounts']), $aAccounts);
|
$aAccounts = \array_merge(\array_flip($aOrder['Accounts']), $aAccounts);
|
||||||
|
|
||||||
$aAccounts = \array_filter($aAccounts, function ($sHash) {
|
$aAccounts = \array_filter($aAccounts, function ($sHash) {
|
||||||
return 5 < \strlen($sHash);
|
return 5 < \strlen($sHash);
|
||||||
});
|
});
|
||||||
|
|
@ -2390,10 +2388,11 @@ class Actions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \RainLoop\Model\Account $oAccount
|
* @param \RainLoop\Model\Account $oAccount
|
||||||
|
* @param bool $bAllowIdentities = false
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function GetIdentities($oAccount)
|
public function GetIdentities($oAccount, $bAllowIdentities = false)
|
||||||
{
|
{
|
||||||
$aIdentities = array();
|
$aIdentities = array();
|
||||||
if ($oAccount)
|
if ($oAccount)
|
||||||
|
|
@ -2421,14 +2420,14 @@ class Actions
|
||||||
|
|
||||||
if ($oItem && $oItem->Validate())
|
if ($oItem && $oItem->Validate())
|
||||||
{
|
{
|
||||||
if ('' === $oItem->Id())
|
if ($oItem->IsAccountIdentities())
|
||||||
{
|
{
|
||||||
$oItem->SetEmail($oAccount->Email());
|
$oItem->SetEmail($oAccount->Email());
|
||||||
$bHasAccountIdentity = true;
|
$bHasAccountIdentity = true;
|
||||||
|
|
||||||
\array_unshift($aIdentities, $oItem);
|
\array_push($aIdentities, $oItem);
|
||||||
}
|
}
|
||||||
else
|
else if ($bAllowIdentities)
|
||||||
{
|
{
|
||||||
\array_push($aIdentities, $oItem);
|
\array_push($aIdentities, $oItem);
|
||||||
}
|
}
|
||||||
|
|
@ -2442,7 +2441,7 @@ class Actions
|
||||||
\RainLoop\Model\Identity::NewInstanceFromAccount($oAccount));
|
\RainLoop\Model\Identity::NewInstanceFromAccount($oAccount));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 < \count($aIdentities))
|
if (1 < \count($aIdentities) && $bAllowIdentities)
|
||||||
{
|
{
|
||||||
$sOrder = $this->StorageProvider()->Get($oAccount,
|
$sOrder = $this->StorageProvider()->Get($oAccount,
|
||||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||||
|
|
@ -2454,8 +2453,16 @@ class Actions
|
||||||
1 < \count($aOrder['Identities']))
|
1 < \count($aOrder['Identities']))
|
||||||
{
|
{
|
||||||
$aList = $aOrder['Identities'];
|
$aList = $aOrder['Identities'];
|
||||||
|
foreach ($aList as $iIndex => $sItem)
|
||||||
|
{
|
||||||
|
if ('' === $sItem)
|
||||||
|
{
|
||||||
|
$aList[$iIndex] = '---';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
\usort($aIdentities, function ($a, $b) use ($aList) {
|
\usort($aIdentities, function ($a, $b) use ($aList) {
|
||||||
return \array_search($a->Id(), $aList) < \array_search($b->Id(), $aList) ? -1 : 1;
|
return \array_search($a->Id(true), $aList) < \array_search($b->Id(true), $aList) ? -1 : 1;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2527,14 +2534,20 @@ class Actions
|
||||||
/**
|
/**
|
||||||
* @param \RainLoop\Model\Account $oAccount
|
* @param \RainLoop\Model\Account $oAccount
|
||||||
* @param array $aIdentities = array()
|
* @param array $aIdentities = array()
|
||||||
|
* @param bool $bAllowIdentities = false
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function SetIdentities($oAccount, $aIdentities = array())
|
public function SetIdentities($oAccount, $aIdentities = array(), $bAllowIdentities = false)
|
||||||
{
|
{
|
||||||
$aResult = array();
|
$aResult = array();
|
||||||
foreach ($aIdentities as $oItem)
|
foreach ($aIdentities as $oItem)
|
||||||
{
|
{
|
||||||
|
if (!$bAllowIdentities && $oItem && !$oItem->IsAccountIdentities())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$aResult[] = $oItem->ToSimpleJSON(false);
|
$aResult[] = $oItem->ToSimpleJSON(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2675,7 +2688,7 @@ class Actions
|
||||||
$oNewAccount->SetParentEmail($sParentEmail);
|
$oNewAccount->SetParentEmail($sParentEmail);
|
||||||
|
|
||||||
$aAccounts[$oNewAccount->Email()] = $oNewAccount->GetAuthToken();
|
$aAccounts[$oNewAccount->Email()] = $oNewAccount->GetAuthToken();
|
||||||
if (0 === \strlen($oAccount->ParentEmail()))
|
if (!$oAccount->IsAdditionalAccount())
|
||||||
{
|
{
|
||||||
$aAccounts[$oAccount->Email()] = $oAccount->GetAuthToken();
|
$aAccounts[$oAccount->Email()] = $oAccount->GetAuthToken();
|
||||||
}
|
}
|
||||||
|
|
@ -2824,7 +2837,7 @@ class Actions
|
||||||
$mResult = array(
|
$mResult = array(
|
||||||
'Files' => array(array(
|
'Files' => array(array(
|
||||||
'FileName' => 'attachments.zip',
|
'FileName' => 'attachments.zip',
|
||||||
'Hash' => \RainLoop\Utils::EncodeKeyValues(array(
|
'Hash' => \RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
'V' => APP_VERSION,
|
'V' => APP_VERSION,
|
||||||
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
||||||
'FileName' => 'attachments.zip',
|
'FileName' => 'attachments.zip',
|
||||||
|
|
@ -2912,7 +2925,7 @@ class Actions
|
||||||
{
|
{
|
||||||
$mResult['Files'][] = array(
|
$mResult['Files'][] = array(
|
||||||
'FileName' => isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat',
|
'FileName' => isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat',
|
||||||
'Hash' => \RainLoop\Utils::EncodeKeyValues($aItem)
|
'Hash' => \RainLoop\Utils::EncodeKeyValuesQ($aItem)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2943,20 +2956,34 @@ class Actions
|
||||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidInputArgument);
|
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidInputArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
$aIdentitiesForSave = array();
|
$aIdentities = $this->GetIdentities($oAccount,
|
||||||
|
$this->GetCapa(false, \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount));
|
||||||
|
|
||||||
$aIdentities = $this->GetIdentities($oAccount);
|
$bAdded = false;
|
||||||
|
$aIdentitiesForSave = array();
|
||||||
foreach ($aIdentities as $oItem)
|
foreach ($aIdentities as $oItem)
|
||||||
{
|
{
|
||||||
if ($oItem && $oItem->Id() !== $oIdentity->Id())
|
if ($oItem)
|
||||||
|
{
|
||||||
|
if ($oItem->Id() === $oIdentity->Id())
|
||||||
|
{
|
||||||
|
$aIdentitiesForSave[] = $oIdentity;
|
||||||
|
$bAdded = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
$aIdentitiesForSave[] = $oItem;
|
$aIdentitiesForSave[] = $oItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$bAdded)
|
||||||
|
{
|
||||||
$aIdentitiesForSave[] = $oIdentity;
|
$aIdentitiesForSave[] = $oIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aIdentitiesForSave));
|
return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aIdentitiesForSave,
|
||||||
|
$this->GetCapa(false, \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2968,6 +2995,11 @@ class Actions
|
||||||
{
|
{
|
||||||
$oAccount = $this->getAccountFromToken();
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
|
||||||
|
if (!$this->GetCapa(false, \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount))
|
||||||
|
{
|
||||||
|
return $this->FalseResponse(__FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
$sId = \trim($this->GetActionParam('IdToDelete', ''));
|
$sId = \trim($this->GetActionParam('IdToDelete', ''));
|
||||||
if (empty($sId))
|
if (empty($sId))
|
||||||
{
|
{
|
||||||
|
|
@ -2975,7 +3007,7 @@ class Actions
|
||||||
}
|
}
|
||||||
|
|
||||||
$aNew = array();
|
$aNew = array();
|
||||||
$aIdentities = $this->GetIdentities($oAccount);
|
$aIdentities = $this->GetIdentities($oAccount, $this->GetCapa(false, \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount));
|
||||||
foreach ($aIdentities as $oItem)
|
foreach ($aIdentities as $oItem)
|
||||||
{
|
{
|
||||||
if ($oItem && $sId !== $oItem->Id())
|
if ($oItem && $sId !== $oItem->Id())
|
||||||
|
|
@ -2984,7 +3016,8 @@ class Actions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aNew));
|
return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aNew,
|
||||||
|
$this->GetCapa(false, \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3110,7 +3143,7 @@ class Actions
|
||||||
$aAccounts = $this->GetActionParam('Accounts', null);
|
$aAccounts = $this->GetActionParam('Accounts', null);
|
||||||
$aIdentities = $this->GetActionParam('Identities', null);
|
$aIdentities = $this->GetActionParam('Identities', null);
|
||||||
|
|
||||||
if (!\is_array($aAccounts) || !\is_array($aIdentities))
|
if (!\is_array($aAccounts) && !\is_array($aIdentities))
|
||||||
{
|
{
|
||||||
return $this->FalseResponse(__FUNCTION__);
|
return $this->FalseResponse(__FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
@ -3118,8 +3151,8 @@ class Actions
|
||||||
return $this->DefaultResponse(__FUNCTION__, $this->StorageProvider()->Put($oAccount,
|
return $this->DefaultResponse(__FUNCTION__, $this->StorageProvider()->Put($oAccount,
|
||||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, 'accounts_identities_order',
|
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, 'accounts_identities_order',
|
||||||
\json_encode(array(
|
\json_encode(array(
|
||||||
'Accounts' => $aAccounts,
|
'Accounts' => \is_array($aAccounts) ? $aAccounts : array(),
|
||||||
'Identities' => $aIdentities
|
'Identities' => \is_array($aIdentities) ? $aIdentities : array()
|
||||||
))
|
))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -3134,6 +3167,7 @@ class Actions
|
||||||
$oAccount = $this->getAccountFromToken();
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
|
||||||
$mAccounts = false;
|
$mAccounts = false;
|
||||||
|
|
||||||
if ($this->GetCapa(false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount))
|
if ($this->GetCapa(false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount))
|
||||||
{
|
{
|
||||||
$mAccounts = $this->GetAccounts($oAccount);
|
$mAccounts = $this->GetAccounts($oAccount);
|
||||||
|
|
@ -3147,7 +3181,8 @@ class Actions
|
||||||
|
|
||||||
return $this->DefaultResponse(__FUNCTION__, array(
|
return $this->DefaultResponse(__FUNCTION__, array(
|
||||||
'Accounts' => $mAccounts,
|
'Accounts' => $mAccounts,
|
||||||
'Identities' => $this->GetIdentities($oAccount)
|
'Identities' => $this->GetIdentities($oAccount,
|
||||||
|
$this->GetCapa(false, \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3448,6 +3483,9 @@ class Actions
|
||||||
case \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS:
|
case \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS:
|
||||||
$this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_additional_accounts', 'bool');
|
$this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_additional_accounts', 'bool');
|
||||||
break;
|
break;
|
||||||
|
case \RainLoop\Enumerations\Capa::IDENTITIES:
|
||||||
|
$this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_additional_identities', 'bool');
|
||||||
|
break;
|
||||||
case \RainLoop\Enumerations\Capa::TEMPLATES:
|
case \RainLoop\Enumerations\Capa::TEMPLATES:
|
||||||
$this->setConfigFromParams($oConfig, $sParamName, 'capa', 'templates', 'bool');
|
$this->setConfigFromParams($oConfig, $sParamName, 'capa', 'templates', 'bool');
|
||||||
break;
|
break;
|
||||||
|
|
@ -3560,6 +3598,7 @@ class Actions
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->setCapaFromParams($oConfig, 'CapaAdditionalAccounts', \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS);
|
$this->setCapaFromParams($oConfig, 'CapaAdditionalAccounts', \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS);
|
||||||
|
$this->setCapaFromParams($oConfig, 'CapaIdentities', \RainLoop\Enumerations\Capa::IDENTITIES);
|
||||||
$this->setCapaFromParams($oConfig, 'CapaTemplates', \RainLoop\Enumerations\Capa::TEMPLATES);
|
$this->setCapaFromParams($oConfig, 'CapaTemplates', \RainLoop\Enumerations\Capa::TEMPLATES);
|
||||||
$this->setCapaFromParams($oConfig, 'CapaTwoFactorAuth', \RainLoop\Enumerations\Capa::TWO_FACTOR);
|
$this->setCapaFromParams($oConfig, 'CapaTwoFactorAuth', \RainLoop\Enumerations\Capa::TWO_FACTOR);
|
||||||
$this->setCapaFromParams($oConfig, 'CapaTwoFactorAuthForce', \RainLoop\Enumerations\Capa::TWO_FACTOR_FORCE);
|
$this->setCapaFromParams($oConfig, 'CapaTwoFactorAuthForce', \RainLoop\Enumerations\Capa::TWO_FACTOR_FORCE);
|
||||||
|
|
@ -7128,19 +7167,19 @@ class Actions
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$aAttachments = $this->GetActionParam('Attachments', array());
|
$aAttachments = $this->GetActionParam('Attachments', array());
|
||||||
if (is_array($aAttachments) && 0 < count($aAttachments))
|
if (\is_array($aAttachments) && 0 < \count($aAttachments))
|
||||||
{
|
{
|
||||||
$mResult = array();
|
$mResult = array();
|
||||||
foreach ($aAttachments as $sAttachment)
|
foreach ($aAttachments as $sAttachment)
|
||||||
{
|
{
|
||||||
$aValues = \RainLoop\Utils::DecodeKeyValues($sAttachment);
|
$aValues = \RainLoop\Utils::DecodeKeyValuesQ($sAttachment);
|
||||||
if (is_array($aValues))
|
if (\is_array($aValues))
|
||||||
{
|
{
|
||||||
$sFolder = isset($aValues['Folder']) ? $aValues['Folder'] : '';
|
$sFolder = isset($aValues['Folder']) ? $aValues['Folder'] : '';
|
||||||
$iUid = (int) isset($aValues['Uid']) ? $aValues['Uid'] : 0;
|
$iUid = (int) isset($aValues['Uid']) ? $aValues['Uid'] : 0;
|
||||||
$sMimeIndex = (string) isset($aValues['MimeIndex']) ? $aValues['MimeIndex'] : '';
|
$sMimeIndex = (string) isset($aValues['MimeIndex']) ? $aValues['MimeIndex'] : '';
|
||||||
|
|
||||||
$sTempName = md5($sAttachment);
|
$sTempName = \md5($sAttachment);
|
||||||
if (!$this->FilesProvider()->FileExists($oAccount, $sTempName))
|
if (!$this->FilesProvider()->FileExists($oAccount, $sTempName))
|
||||||
{
|
{
|
||||||
$this->MailClient()->MessageMimeStream(
|
$this->MailClient()->MessageMimeStream(
|
||||||
|
|
@ -7738,7 +7777,7 @@ class Actions
|
||||||
$aParams = $this->GetActionParam('Params', null);
|
$aParams = $this->GetActionParam('Params', null);
|
||||||
$this->Http()->ServerNoCache();
|
$this->Http()->ServerNoCache();
|
||||||
|
|
||||||
$aData = \RainLoop\Utils::DecodeKeyValues($sRawKey);
|
$aData = \RainLoop\Utils::DecodeKeyValuesQ($sRawKey);
|
||||||
if (isset($aParams[0], $aParams[1], $aParams[2]) &&
|
if (isset($aParams[0], $aParams[1], $aParams[2]) &&
|
||||||
'Raw' === $aParams[0] && 'FramedView' === $aParams[2] && isset($aData['Framed']) && $aData['Framed'] && $aData['FileName'])
|
'Raw' === $aParams[0] && 'FramedView' === $aParams[2] && isset($aData['Framed']) && $aData['Framed'] && $aData['FileName'])
|
||||||
{
|
{
|
||||||
|
|
@ -7842,6 +7881,11 @@ class Actions
|
||||||
$aResult[] = \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS;
|
$aResult[] = \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($oConfig->Get('webmail', 'allow_additional_identities', false))
|
||||||
|
{
|
||||||
|
$aResult[] = \RainLoop\Enumerations\Capa::IDENTITIES;
|
||||||
|
}
|
||||||
|
|
||||||
if ($oConfig->Get('security', 'allow_two_factor_auth', false) &&
|
if ($oConfig->Get('security', 'allow_two_factor_auth', false) &&
|
||||||
($bAdmin || ($oAccount && !$oAccount->IsAdditionalAccount())))
|
($bAdmin || ($oAccount && !$oAccount->IsAdditionalAccount())))
|
||||||
{
|
{
|
||||||
|
|
@ -8399,7 +8443,7 @@ class Actions
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
if (!empty($sRawKey))
|
if (!empty($sRawKey))
|
||||||
{
|
{
|
||||||
$aValues = \RainLoop\Utils::DecodeKeyValues($sRawKey);
|
$aValues = \RainLoop\Utils::DecodeKeyValuesQ($sRawKey);
|
||||||
if (is_array($aValues))
|
if (is_array($aValues))
|
||||||
{
|
{
|
||||||
$bResult = $aValues;
|
$bResult = $aValues;
|
||||||
|
|
@ -9205,7 +9249,7 @@ class Actions
|
||||||
|
|
||||||
$sSubject = $mResult['Subject'];
|
$sSubject = $mResult['Subject'];
|
||||||
$mResult['Hash'] = \md5($mResult['Folder'].$mResult['Uid']);
|
$mResult['Hash'] = \md5($mResult['Folder'].$mResult['Uid']);
|
||||||
$mResult['RequestHash'] = \RainLoop\Utils::EncodeKeyValues(array(
|
$mResult['RequestHash'] = \RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
'V' => APP_VERSION,
|
'V' => APP_VERSION,
|
||||||
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
||||||
'Folder' => $mResult['Folder'],
|
'Folder' => $mResult['Folder'],
|
||||||
|
|
@ -9270,7 +9314,7 @@ class Actions
|
||||||
if (!!$this->Config()->Get('labs', 'use_local_proxy_for_external_images', false))
|
if (!!$this->Config()->Get('labs', 'use_local_proxy_for_external_images', false))
|
||||||
{
|
{
|
||||||
$fAdditionalExternalFilter = function ($sUrl) {
|
$fAdditionalExternalFilter = function ($sUrl) {
|
||||||
return './?/ProxyExternal/'.\RainLoop\Utils::EncodeKeyValues(array(
|
return './?/ProxyExternal/'.\RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
'Rnd' => \md5(\microtime(true)),
|
'Rnd' => \md5(\microtime(true)),
|
||||||
'Token' => \RainLoop\Utils::GetConnectionToken(),
|
'Token' => \RainLoop\Utils::GetConnectionToken(),
|
||||||
'Url' => $sUrl
|
'Url' => $sUrl
|
||||||
|
|
@ -9421,7 +9465,7 @@ class Actions
|
||||||
$mResult['IsThumbnail'] = $this->isFileHasThumbnail($mResult['FileName']);
|
$mResult['IsThumbnail'] = $this->isFileHasThumbnail($mResult['FileName']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$mResult['Download'] = \RainLoop\Utils::EncodeKeyValues(array(
|
$mResult['Download'] = \RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
'V' => APP_VERSION,
|
'V' => APP_VERSION,
|
||||||
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
||||||
'Folder' => $mResult['Folder'],
|
'Folder' => $mResult['Folder'],
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,8 @@ class Api
|
||||||
{
|
{
|
||||||
$sSsoHash = \MailSo\Base\Utils::Sha1Rand($sEmail.$sPassword);
|
$sSsoHash = \MailSo\Base\Utils::Sha1Rand($sEmail.$sPassword);
|
||||||
|
|
||||||
return \RainLoop\Api::Actions()->Cacher()->Set(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash), \RainLoop\Utils::EncodeKeyValues(array(
|
return \RainLoop\Api::Actions()->Cacher()->Set(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash),
|
||||||
|
\RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
'Email' => $sEmail,
|
'Email' => $sEmail,
|
||||||
'Password' => $sPassword,
|
'Password' => $sPassword,
|
||||||
'AdditionalOptions' => $aAdditionalOptions,
|
'AdditionalOptions' => $aAdditionalOptions,
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ class Application extends \RainLoop\Config\AbstractConfig
|
||||||
'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
|
'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
|
||||||
|
|
||||||
'allow_additional_accounts' => array(true, ''),
|
'allow_additional_accounts' => array(true, ''),
|
||||||
|
'allow_additional_identities' => array(true, ''),
|
||||||
|
|
||||||
'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
|
'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ class Capa
|
||||||
const FILTERS = 'FILTERS';
|
const FILTERS = 'FILTERS';
|
||||||
const ATTACHMENT_THUMBNAILS = 'ATTACHMENT_THUMBNAILS';
|
const ATTACHMENT_THUMBNAILS = 'ATTACHMENT_THUMBNAILS';
|
||||||
const ADDITIONAL_ACCOUNTS = 'ADDITIONAL_ACCOUNTS';
|
const ADDITIONAL_ACCOUNTS = 'ADDITIONAL_ACCOUNTS';
|
||||||
|
const IDENTITIES = 'IDENTITIES';
|
||||||
const TEMPLATES = 'TEMPLATES';
|
const TEMPLATES = 'TEMPLATES';
|
||||||
const AUTOLOGOUT = 'AUTOLOGOUT';
|
const AUTOLOGOUT = 'AUTOLOGOUT';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -366,6 +366,26 @@ class Account extends \RainLoop\Account // for backward compatibility
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetAuthTokenQ()
|
||||||
|
{
|
||||||
|
return \RainLoop\Utils::EncodeKeyValuesQ(array(
|
||||||
|
'token', // 0
|
||||||
|
$this->sEmail, // 1
|
||||||
|
$this->sLogin, // 2
|
||||||
|
$this->sPassword, // 3
|
||||||
|
\RainLoop\Utils::Fingerprint(), // 4
|
||||||
|
$this->sSignMeToken, // 5
|
||||||
|
$this->sParentEmail, // 6
|
||||||
|
\RainLoop\Utils::GetShortToken(), // 7
|
||||||
|
$this->sProxyAuthUser, // 8
|
||||||
|
$this->sProxyAuthPassword, // 9
|
||||||
|
0 // 10 // timelife
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \RainLoop\Plugins\Manager $oPlugins
|
* @param \RainLoop\Plugins\Manager $oPlugins
|
||||||
* @param \MailSo\Mail\MailClient $oMailClient
|
* @param \MailSo\Mail\MailClient $oMailClient
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,13 @@ class Identity
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param bool $bFillOnEmpty = false
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function Id()
|
public function Id($bFillOnEmpty = false)
|
||||||
{
|
{
|
||||||
return $this->sId;
|
return $bFillOnEmpty ? ('' === $this->sId ? '---' : $this->sId) : $this->sId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -192,4 +194,12 @@ class Identity
|
||||||
{
|
{
|
||||||
return !empty($this->sEmail);
|
return !empty($this->sEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function IsAccountIdentities()
|
||||||
|
{
|
||||||
|
return '' === $this->Id();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -429,7 +429,7 @@ class ServiceActions
|
||||||
{
|
{
|
||||||
$this->oActions->verifyCacheByKey($sData);
|
$this->oActions->verifyCacheByKey($sData);
|
||||||
|
|
||||||
$aData = \RainLoop\Utils::DecodeKeyValues($sData);
|
$aData = \RainLoop\Utils::DecodeKeyValuesQ($sData);
|
||||||
if (\is_array($aData) && !empty($aData['Token']) && !empty($aData['Url']) && $aData['Token'] === \RainLoop\Utils::GetConnectionToken())
|
if (\is_array($aData) && !empty($aData['Token']) && !empty($aData['Url']) && $aData['Token'] === \RainLoop\Utils::GetConnectionToken())
|
||||||
{
|
{
|
||||||
$iCode = 404;
|
$iCode = 404;
|
||||||
|
|
@ -892,7 +892,7 @@ class ServiceActions
|
||||||
$sSsoSubData = $this->Cacher()->Get(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash));
|
$sSsoSubData = $this->Cacher()->Get(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash));
|
||||||
if (!empty($sSsoSubData))
|
if (!empty($sSsoSubData))
|
||||||
{
|
{
|
||||||
$mData = \RainLoop\Utils::DecodeKeyValues($sSsoSubData);
|
$mData = \RainLoop\Utils::DecodeKeyValuesQ($sSsoSubData);
|
||||||
$this->Cacher()->Delete(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash));
|
$this->Cacher()->Delete(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash));
|
||||||
|
|
||||||
if (\is_array($mData) && !empty($mData['Email']) && isset($mData['Password'], $mData['Time']) &&
|
if (\is_array($mData) && !empty($mData['Email']) && isset($mData['Password'], $mData['Time']) &&
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,10 @@ class Utils
|
||||||
{
|
{
|
||||||
static $Cookies = null;
|
static $Cookies = null;
|
||||||
|
|
||||||
|
static $RSA = null;
|
||||||
|
|
||||||
|
static $RsaKey = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
@ -31,6 +35,145 @@ class Utils
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Crypt_RSA|null
|
||||||
|
*/
|
||||||
|
static public function CryptRSA()
|
||||||
|
{
|
||||||
|
if (null === \RainLoop\Utils::$RSA)
|
||||||
|
{
|
||||||
|
if (!\defined('_phpseclib_'))
|
||||||
|
{
|
||||||
|
\set_include_path(\get_include_path().PATH_SEPARATOR.APP_VERSION_ROOT_PATH.'app/libraries/phpseclib');
|
||||||
|
define('_phpseclib_', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\class_exists('Crypt_RSA'))
|
||||||
|
{
|
||||||
|
include_once 'Crypt/RSA.php';
|
||||||
|
\defined('CRYPT_RSA_MODE') || \define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\class_exists('Crypt_RSA'))
|
||||||
|
{
|
||||||
|
$oRsa = new \Crypt_RSA();
|
||||||
|
|
||||||
|
$oRsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
|
||||||
|
$oRsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
|
||||||
|
$oRsa->setPrivateKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
|
||||||
|
|
||||||
|
$sPrivateKey = \file_exists(APP_PRIVATE_DATA.'rsa/private') ?
|
||||||
|
\file_get_contents(APP_PRIVATE_DATA.'rsa/private') : '';
|
||||||
|
|
||||||
|
if (!empty($sPrivateKey))
|
||||||
|
{
|
||||||
|
$oRsa->loadKey($sPrivateKey, CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
|
||||||
|
$oRsa->loadKey($oRsa->getPublicKey(), CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
|
||||||
|
|
||||||
|
\RainLoop\Utils::$RSA = $oRsa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return \RainLoop\Utils::$RSA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function RsaPrivateKey()
|
||||||
|
{
|
||||||
|
if (!empty(\RainLoop\Utils::$RsaKey))
|
||||||
|
{
|
||||||
|
return \RainLoop\Utils::$RsaKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
\RainLoop\Utils::$RsaKey = \file_exists(APP_PRIVATE_DATA.'rsa/private') ?
|
||||||
|
\file_get_contents(APP_PRIVATE_DATA.'rsa/private') : '';
|
||||||
|
|
||||||
|
\RainLoop\Utils::$RsaKey = \is_string(\RainLoop\Utils::$RsaKey) ? \RainLoop\Utils::$RsaKey : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sString
|
||||||
|
* @param string $sKey = ''
|
||||||
|
*
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
static public function EncryptStringRSA($sString, $sKey = '')
|
||||||
|
{
|
||||||
|
$sResult = '';
|
||||||
|
$sKey = \md5($sKey);
|
||||||
|
|
||||||
|
$sPrivateKey = \RainLoop\Utils::RsaPrivateKey();
|
||||||
|
if (!empty($sPrivateKey))
|
||||||
|
{
|
||||||
|
$oPrivKey = \openssl_pkey_get_private($sPrivateKey);
|
||||||
|
$oKeyDetails = \openssl_pkey_get_details($oPrivKey);
|
||||||
|
|
||||||
|
if (!empty($oKeyDetails['key']) && !empty($oKeyDetails['bits']))
|
||||||
|
{
|
||||||
|
$oPubKey = \openssl_pkey_get_public($oKeyDetails['key']);
|
||||||
|
|
||||||
|
$iC = (($oKeyDetails['bits'] / 8) - 15);
|
||||||
|
$aString = \str_split($sString, $iC);
|
||||||
|
|
||||||
|
foreach ($aString as $iIndex => $sLine)
|
||||||
|
{
|
||||||
|
$sEncrypted = '';
|
||||||
|
\openssl_public_encrypt($sLine, $sEncrypted, $oPubKey);
|
||||||
|
$aString[$iIndex] = $sEncrypted;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aString[] = $sKey;
|
||||||
|
$sResult = @\serialize($aString);
|
||||||
|
|
||||||
|
\openssl_free_key($oPubKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
\openssl_free_key($oPrivKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sString
|
||||||
|
* @param string $sKey = ''
|
||||||
|
*
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
static public function DecryptStringRSA($sString, $sKey = '')
|
||||||
|
{
|
||||||
|
$sResult = '';
|
||||||
|
$sKey = \md5($sKey);
|
||||||
|
|
||||||
|
$sPrivateKey = \RainLoop\Utils::RsaPrivateKey();
|
||||||
|
if (!empty($sPrivateKey) && !empty($sString))
|
||||||
|
{
|
||||||
|
$oPrivKey = \openssl_pkey_get_private($sPrivateKey);
|
||||||
|
|
||||||
|
$aString = @\unserialize($sString);
|
||||||
|
if (\is_array($aString))
|
||||||
|
{
|
||||||
|
if ($sKey === \array_pop($aString))
|
||||||
|
{
|
||||||
|
foreach ($aString as $iIndex => $sLine)
|
||||||
|
{
|
||||||
|
$sDecrypted = '';
|
||||||
|
\openssl_private_decrypt($sLine, $sDecrypted, $oPrivKey);
|
||||||
|
$aString[$iIndex] = $sDecrypted;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sResult = \implode('', $aString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\openssl_free_key($oPrivKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sResult;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sString
|
* @param string $sString
|
||||||
|
|
@ -54,6 +197,42 @@ class Utils
|
||||||
return \MailSo\Base\Crypt::XxteaDecrypt($sEncriptedString, $sKey);
|
return \MailSo\Base\Crypt::XxteaDecrypt($sEncriptedString, $sKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sString
|
||||||
|
* @param string $sKey
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function EncryptStringQ($sString, $sKey)
|
||||||
|
{
|
||||||
|
// if (\MailSo\Base\Utils::FunctionExistsAndEnabled('openssl_pkey_get_private'))
|
||||||
|
// {
|
||||||
|
// return \RainLoop\Utils::EncryptStringRSA($sString,
|
||||||
|
// $sKey.'Q'.\RainLoop\Utils::GetShortToken());
|
||||||
|
// }
|
||||||
|
|
||||||
|
return \MailSo\Base\Crypt::XxteaEncrypt($sString,
|
||||||
|
$sKey.'Q'.\RainLoop\Utils::GetShortToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sEncriptedString
|
||||||
|
* @param string $sKey
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function DecryptStringQ($sEncriptedString, $sKey)
|
||||||
|
{
|
||||||
|
// if (\MailSo\Base\Utils::FunctionExistsAndEnabled('openssl_pkey_get_private'))
|
||||||
|
// {
|
||||||
|
// return \RainLoop\Utils::DecryptStringRSA($sEncriptedString,
|
||||||
|
// $sKey.'Q'.\RainLoop\Utils::GetShortToken());
|
||||||
|
// }
|
||||||
|
|
||||||
|
return \MailSo\Base\Crypt::XxteaDecrypt($sEncriptedString,
|
||||||
|
$sKey.'Q'.\RainLoop\Utils::GetShortToken());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $aValues
|
* @param array $aValues
|
||||||
* @param string $sCustomKey = ''
|
* @param string $sCustomKey = ''
|
||||||
|
|
@ -63,7 +242,7 @@ class Utils
|
||||||
static public function EncodeKeyValues(array $aValues, $sCustomKey = '')
|
static public function EncodeKeyValues(array $aValues, $sCustomKey = '')
|
||||||
{
|
{
|
||||||
return \MailSo\Base\Utils::UrlSafeBase64Encode(
|
return \MailSo\Base\Utils::UrlSafeBase64Encode(
|
||||||
\RainLoop\Utils::EncryptString(\serialize($aValues), \md5(APP_SALT.$sCustomKey)));
|
\RainLoop\Utils::EncryptString(@\serialize($aValues), \md5(APP_SALT.$sCustomKey)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -74,13 +253,41 @@ class Utils
|
||||||
*/
|
*/
|
||||||
static public function DecodeKeyValues($sEncodedValues, $sCustomKey = '')
|
static public function DecodeKeyValues($sEncodedValues, $sCustomKey = '')
|
||||||
{
|
{
|
||||||
$aResult = \unserialize(
|
$aResult = @\unserialize(
|
||||||
\RainLoop\Utils::DecryptString(
|
\RainLoop\Utils::DecryptString(
|
||||||
\MailSo\Base\Utils::UrlSafeBase64Decode($sEncodedValues), \md5(APP_SALT.$sCustomKey)));
|
\MailSo\Base\Utils::UrlSafeBase64Decode($sEncodedValues), \md5(APP_SALT.$sCustomKey)));
|
||||||
|
|
||||||
return \is_array($aResult) ? $aResult : array();
|
return \is_array($aResult) ? $aResult : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $aValues
|
||||||
|
* @param string $sCustomKey = ''
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function EncodeKeyValuesQ(array $aValues, $sCustomKey = '')
|
||||||
|
{
|
||||||
|
return \MailSo\Base\Utils::UrlSafeBase64Encode(
|
||||||
|
\RainLoop\Utils::EncryptStringQ(
|
||||||
|
@\serialize($aValues), \md5(APP_SALT.$sCustomKey)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sEncodedValues
|
||||||
|
* @param string $sCustomKey = ''
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
static public function DecodeKeyValuesQ($sEncodedValues, $sCustomKey = '')
|
||||||
|
{
|
||||||
|
$aResult = @\unserialize(
|
||||||
|
\RainLoop\Utils::DecryptStringQ(
|
||||||
|
\MailSo\Base\Utils::UrlSafeBase64Decode($sEncodedValues), \md5(APP_SALT.$sCustomKey)));
|
||||||
|
|
||||||
|
return \is_array($aResult) ? $aResult : array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
@ -296,33 +503,33 @@ class Utils
|
||||||
*/
|
*/
|
||||||
public static function GetCookie($sName, $mDefault = null)
|
public static function GetCookie($sName, $mDefault = null)
|
||||||
{
|
{
|
||||||
if (null === self::$Cookies)
|
if (null === \RainLoop\Utils::$Cookies)
|
||||||
{
|
{
|
||||||
self::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
\RainLoop\Utils::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
return isset(self::$Cookies[$sName]) ? self::$Cookies[$sName] : $mDefault;
|
return isset(\RainLoop\Utils::$Cookies[$sName]) ? \RainLoop\Utils::$Cookies[$sName] : $mDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function SetCookie($sName, $sValue = '', $iExpire = 0, $sPath = '/', $sDomain = '', $sSecure = false, $bHttpOnly = false)
|
public static function SetCookie($sName, $sValue = '', $iExpire = 0, $sPath = '/', $sDomain = '', $sSecure = false, $bHttpOnly = false)
|
||||||
{
|
{
|
||||||
if (null === self::$Cookies)
|
if (null === \RainLoop\Utils::$Cookies)
|
||||||
{
|
{
|
||||||
self::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
\RainLoop\Utils::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$Cookies[$sName] = $sValue;
|
\RainLoop\Utils::$Cookies[$sName] = $sValue;
|
||||||
@\setcookie($sName, $sValue, $iExpire, $sPath, $sDomain, $sSecure, $bHttpOnly);
|
@\setcookie($sName, $sValue, $iExpire, $sPath, $sDomain, $sSecure, $bHttpOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function ClearCookie($sName)
|
public static function ClearCookie($sName)
|
||||||
{
|
{
|
||||||
if (null === self::$Cookies)
|
if (null === \RainLoop\Utils::$Cookies)
|
||||||
{
|
{
|
||||||
self::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
\RainLoop\Utils::$Cookies = is_array($_COOKIE) ? $_COOKIE : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
unset(self::$Cookies[$sName]);
|
unset(\RainLoop\Utils::$Cookies[$sName]);
|
||||||
@\setcookie($sName, '', \time() - 3600 * 24 * 30, '/');
|
@\setcookie($sName, '', \time() - 3600 * 24 * 30, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
* @category Crypt
|
* @category Crypt
|
||||||
* @package Crypt_AES
|
* @package Crypt_AES
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVIII Jim Wigginton
|
* @copyright 2008 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -152,4 +152,56 @@ class Crypt_AES extends Crypt_Rijndael
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the key length
|
||||||
|
*
|
||||||
|
* Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
|
||||||
|
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
|
||||||
|
*
|
||||||
|
* @see Crypt_Rijndael:setKeyLength()
|
||||||
|
* @access public
|
||||||
|
* @param Integer $length
|
||||||
|
*/
|
||||||
|
function setKeyLength($length)
|
||||||
|
{
|
||||||
|
switch ($length) {
|
||||||
|
case 160:
|
||||||
|
$length = 192;
|
||||||
|
break;
|
||||||
|
case 224:
|
||||||
|
$length = 256;
|
||||||
|
}
|
||||||
|
parent::setKeyLength($length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the key.
|
||||||
|
*
|
||||||
|
* Rijndael supports five different key lengths, AES only supports three.
|
||||||
|
*
|
||||||
|
* @see Crypt_Rijndael:setKey()
|
||||||
|
* @see setKeyLength()
|
||||||
|
* @access public
|
||||||
|
* @param String $key
|
||||||
|
*/
|
||||||
|
function setKey($key)
|
||||||
|
{
|
||||||
|
parent::setKey($key);
|
||||||
|
|
||||||
|
if (!$this->explicit_key_length) {
|
||||||
|
$length = strlen($key);
|
||||||
|
switch (true) {
|
||||||
|
case $length <= 16:
|
||||||
|
$this->key_size = 16;
|
||||||
|
break;
|
||||||
|
case $length <= 24:
|
||||||
|
$this->key_size = 24;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->key_size = 32;
|
||||||
|
}
|
||||||
|
$this->_setupEngine();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
* @package Crypt_Base
|
* @package Crypt_Base
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
* @package Crypt_Blowfish
|
* @package Crypt_Blowfish
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
* @category Crypt
|
* @category Crypt
|
||||||
* @package Crypt_DES
|
* @package Crypt_DES
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
*
|
*
|
||||||
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
|
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
|
||||||
*
|
*
|
||||||
* md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
|
* md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
|
||||||
*
|
*
|
||||||
* If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
|
* If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
|
||||||
* the hash. If no valid algorithm is provided, sha1 will be used.
|
* the hash. If no valid algorithm is provided, sha1 will be used.
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
* @category Crypt
|
* @category Crypt
|
||||||
* @package Crypt_Hash
|
* @package Crypt_Hash
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -207,6 +207,9 @@ class Crypt_Hash
|
||||||
switch ($hash) {
|
switch ($hash) {
|
||||||
case 'md5-96':
|
case 'md5-96':
|
||||||
case 'sha1-96':
|
case 'sha1-96':
|
||||||
|
case 'sha256-96':
|
||||||
|
case 'sha512-96':
|
||||||
|
$hash = substr($hash, 0, -3);
|
||||||
$this->l = 12; // 96 / 8 = 12
|
$this->l = 12; // 96 / 8 = 12
|
||||||
break;
|
break;
|
||||||
case 'md2':
|
case 'md2':
|
||||||
|
|
@ -243,14 +246,12 @@ class Crypt_Hash
|
||||||
case CRYPT_HASH_MODE_MHASH:
|
case CRYPT_HASH_MODE_MHASH:
|
||||||
switch ($hash) {
|
switch ($hash) {
|
||||||
case 'md5':
|
case 'md5':
|
||||||
case 'md5-96':
|
|
||||||
$this->hash = MHASH_MD5;
|
$this->hash = MHASH_MD5;
|
||||||
break;
|
break;
|
||||||
case 'sha256':
|
case 'sha256':
|
||||||
$this->hash = MHASH_SHA256;
|
$this->hash = MHASH_SHA256;
|
||||||
break;
|
break;
|
||||||
case 'sha1':
|
case 'sha1':
|
||||||
case 'sha1-96':
|
|
||||||
default:
|
default:
|
||||||
$this->hash = MHASH_SHA1;
|
$this->hash = MHASH_SHA1;
|
||||||
}
|
}
|
||||||
|
|
@ -258,7 +259,6 @@ class Crypt_Hash
|
||||||
case CRYPT_HASH_MODE_HASH:
|
case CRYPT_HASH_MODE_HASH:
|
||||||
switch ($hash) {
|
switch ($hash) {
|
||||||
case 'md5':
|
case 'md5':
|
||||||
case 'md5-96':
|
|
||||||
$this->hash = 'md5';
|
$this->hash = 'md5';
|
||||||
return;
|
return;
|
||||||
case 'md2':
|
case 'md2':
|
||||||
|
|
@ -268,7 +268,6 @@ class Crypt_Hash
|
||||||
$this->hash = $hash;
|
$this->hash = $hash;
|
||||||
return;
|
return;
|
||||||
case 'sha1':
|
case 'sha1':
|
||||||
case 'sha1-96':
|
|
||||||
default:
|
default:
|
||||||
$this->hash = 'sha1';
|
$this->hash = 'sha1';
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +280,6 @@ class Crypt_Hash
|
||||||
$this->hash = array($this, '_md2');
|
$this->hash = array($this, '_md2');
|
||||||
break;
|
break;
|
||||||
case 'md5':
|
case 'md5':
|
||||||
case 'md5-96':
|
|
||||||
$this->b = 64;
|
$this->b = 64;
|
||||||
$this->hash = array($this, '_md5');
|
$this->hash = array($this, '_md5');
|
||||||
break;
|
break;
|
||||||
|
|
@ -295,7 +293,6 @@ class Crypt_Hash
|
||||||
$this->hash = array($this, '_sha512');
|
$this->hash = array($this, '_sha512');
|
||||||
break;
|
break;
|
||||||
case 'sha1':
|
case 'sha1':
|
||||||
case 'sha1-96':
|
|
||||||
default:
|
default:
|
||||||
$this->b = 64;
|
$this->b = 64;
|
||||||
$this->hash = array($this, '_sha1');
|
$this->hash = array($this, '_sha1');
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
* @category Crypt
|
* @category Crypt
|
||||||
* @package Crypt_RC4
|
* @package Crypt_RC4
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
* @category Crypt
|
* @category Crypt
|
||||||
* @package Crypt_RSA
|
* @package Crypt_RSA
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMIX Jim Wigginton
|
* @copyright 2009 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -493,14 +493,13 @@ class Crypt_RSA
|
||||||
$this->configFile = CRYPT_RSA_OPENSSL_CONFIG;
|
$this->configFile = CRYPT_RSA_OPENSSL_CONFIG;
|
||||||
|
|
||||||
if ( !defined('CRYPT_RSA_MODE') ) {
|
if ( !defined('CRYPT_RSA_MODE') ) {
|
||||||
|
switch (true) {
|
||||||
// Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
|
// Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
|
||||||
// Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
|
// Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
|
||||||
// can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either.
|
// can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either.
|
||||||
if ( defined('MATH_BIGINTEGER_OPENSSL_DISABLE') ) {
|
case defined('MATH_BIGINTEGER_OPENSSL_DISABLE'):
|
||||||
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
||||||
}
|
break;
|
||||||
|
|
||||||
switch ( !defined('CRYPT_RSA_MODE') ) { // ie. only run this if the above didn't set CRYPT_RSA_MODE already
|
|
||||||
// openssl_pkey_get_details - which is used in the only place Crypt/RSA.php uses OpenSSL - was introduced in PHP 5.2.0
|
// openssl_pkey_get_details - which is used in the only place Crypt/RSA.php uses OpenSSL - was introduced in PHP 5.2.0
|
||||||
case !function_exists('openssl_pkey_get_details'):
|
case !function_exists('openssl_pkey_get_details'):
|
||||||
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
||||||
|
|
@ -517,7 +516,14 @@ class Crypt_RSA
|
||||||
$versions = array();
|
$versions = array();
|
||||||
if (!empty($matches[1])) {
|
if (!empty($matches[1])) {
|
||||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||||
$versions[$matches[1][$i]] = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
||||||
|
|
||||||
|
// Remove letter part in OpenSSL version
|
||||||
|
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
||||||
|
$versions[$matches[1][$i]] = $fullVersion;
|
||||||
|
} else {
|
||||||
|
$versions[$matches[1][$i]] = $m[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -533,7 +539,7 @@ class Crypt_RSA
|
||||||
define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
|
define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case true:
|
default:
|
||||||
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -743,17 +749,18 @@ class Crypt_RSA
|
||||||
*/
|
*/
|
||||||
function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
|
function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
|
||||||
{
|
{
|
||||||
|
$signed = $this->privateKeyFormat != CRYPT_RSA_PRIVATE_FORMAT_XML;
|
||||||
$num_primes = count($primes);
|
$num_primes = count($primes);
|
||||||
$raw = array(
|
$raw = array(
|
||||||
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
||||||
'modulus' => $n->toBytes(true),
|
'modulus' => $n->toBytes($signed),
|
||||||
'publicExponent' => $e->toBytes(true),
|
'publicExponent' => $e->toBytes($signed),
|
||||||
'privateExponent' => $d->toBytes(true),
|
'privateExponent' => $d->toBytes($signed),
|
||||||
'prime1' => $primes[1]->toBytes(true),
|
'prime1' => $primes[1]->toBytes($signed),
|
||||||
'prime2' => $primes[2]->toBytes(true),
|
'prime2' => $primes[2]->toBytes($signed),
|
||||||
'exponent1' => $exponents[1]->toBytes(true),
|
'exponent1' => $exponents[1]->toBytes($signed),
|
||||||
'exponent2' => $exponents[2]->toBytes(true),
|
'exponent2' => $exponents[2]->toBytes($signed),
|
||||||
'coefficient' => $coefficients[2]->toBytes(true)
|
'coefficient' => $coefficients[2]->toBytes($signed)
|
||||||
);
|
);
|
||||||
|
|
||||||
// if the format in question does not support multi-prime rsa and multi-prime rsa was used,
|
// if the format in question does not support multi-prime rsa and multi-prime rsa was used,
|
||||||
|
|
@ -942,8 +949,10 @@ class Crypt_RSA
|
||||||
*/
|
*/
|
||||||
function _convertPublicKey($n, $e)
|
function _convertPublicKey($n, $e)
|
||||||
{
|
{
|
||||||
$modulus = $n->toBytes(true);
|
$signed = $this->publicKeyFormat != CRYPT_RSA_PUBLIC_FORMAT_XML;
|
||||||
$publicExponent = $e->toBytes(true);
|
|
||||||
|
$modulus = $n->toBytes($signed);
|
||||||
|
$publicExponent = $e->toBytes($signed);
|
||||||
|
|
||||||
switch ($this->publicKeyFormat) {
|
switch ($this->publicKeyFormat) {
|
||||||
case CRYPT_RSA_PUBLIC_FORMAT_RAW:
|
case CRYPT_RSA_PUBLIC_FORMAT_RAW:
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
* @category Crypt
|
* @category Crypt
|
||||||
* @package Crypt_Random
|
* @package Crypt_Random
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@
|
||||||
* @category Crypt
|
* @category Crypt
|
||||||
* @package Crypt_Rijndael
|
* @package Crypt_Rijndael
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVIII Jim Wigginton
|
* @copyright 2008 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -702,9 +702,15 @@ class Crypt_Rijndael extends Crypt_Base
|
||||||
case $length <= 16:
|
case $length <= 16:
|
||||||
$this->key_size = 16;
|
$this->key_size = 16;
|
||||||
break;
|
break;
|
||||||
|
case $length <= 20:
|
||||||
|
$this->key_size = 20;
|
||||||
|
break;
|
||||||
case $length <= 24:
|
case $length <= 24:
|
||||||
$this->key_size = 24;
|
$this->key_size = 24;
|
||||||
break;
|
break;
|
||||||
|
case $length <= 28:
|
||||||
|
$this->key_size = 28;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$this->key_size = 32;
|
$this->key_size = 32;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
* @category Crypt
|
* @category Crypt
|
||||||
* @package Crypt_TripleDES
|
* @package Crypt_TripleDES
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
* @package Crypt_Twofish
|
* @package Crypt_Twofish
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
* @category File
|
* @category File
|
||||||
* @package File_ANSI
|
* @package File_ANSI
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMXII Jim Wigginton
|
* @copyright 2012 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
* @category File
|
* @category File
|
||||||
* @package File_ASN1
|
* @package File_ASN1
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMXII Jim Wigginton
|
* @copyright 2012 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -272,7 +272,8 @@ class File_ASN1
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->encoded = $encoded;
|
$this->encoded = $encoded;
|
||||||
return $this->_decode_ber($encoded);
|
// encapsulate in an array for BC with the old decodeBER
|
||||||
|
return array($this->_decode_ber($encoded));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -287,11 +288,8 @@ class File_ASN1
|
||||||
* @return Array
|
* @return Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _decode_ber(&$encoded, $start = 0)
|
function _decode_ber($encoded, $start = 0)
|
||||||
{
|
{
|
||||||
$decoded = array();
|
|
||||||
|
|
||||||
while ( strlen($encoded) ) {
|
|
||||||
$current = array('start' => $start);
|
$current = array('start' => $start);
|
||||||
|
|
||||||
$type = ord($this->_string_shift($encoded));
|
$type = ord($this->_string_shift($encoded));
|
||||||
|
|
@ -317,16 +315,13 @@ class File_ASN1
|
||||||
if ( $length == 0x80 ) { // indefinite length
|
if ( $length == 0x80 ) { // indefinite length
|
||||||
// "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all
|
// "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all
|
||||||
// immediately available." -- paragraph 8.1.3.2.c
|
// immediately available." -- paragraph 8.1.3.2.c
|
||||||
//if ( !$constructed ) {
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
$length = strlen($encoded);
|
$length = strlen($encoded);
|
||||||
} elseif ( $length & 0x80 ) { // definite length, long form
|
} elseif ( $length & 0x80 ) { // definite length, long form
|
||||||
// technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only
|
// technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only
|
||||||
// support it up to four.
|
// support it up to four.
|
||||||
$length&= 0x7F;
|
$length&= 0x7F;
|
||||||
$temp = $this->_string_shift($encoded, $length);
|
$temp = $this->_string_shift($encoded, $length);
|
||||||
// tags of indefinite length don't really have a header length; this length includes the tag
|
// tags of indefinte length don't really have a header length; this length includes the tag
|
||||||
$current+= array('headerlength' => $length + 2);
|
$current+= array('headerlength' => $length + 2);
|
||||||
$start+= $length;
|
$start+= $length;
|
||||||
extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)));
|
extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)));
|
||||||
|
|
@ -334,12 +329,10 @@ class File_ASN1
|
||||||
$current+= array('headerlength' => 2);
|
$current+= array('headerlength' => 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// End-of-content, see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2
|
|
||||||
if (!$type && !$length) {
|
|
||||||
return $decoded;
|
|
||||||
}
|
|
||||||
$content = $this->_string_shift($encoded, $length);
|
$content = $this->_string_shift($encoded, $length);
|
||||||
|
|
||||||
|
// at this point $length can be overwritten. it's only accurate for definite length things as is
|
||||||
|
|
||||||
/* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1
|
/* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1
|
||||||
built-in types. It defines an application-independent data type that must be distinguishable from all other
|
built-in types. It defines an application-independent data type that must be distinguishable from all other
|
||||||
data types. The other three classes are user defined. The APPLICATION class distinguishes data types that
|
data types. The other three classes are user defined. The APPLICATION class distinguishes data types that
|
||||||
|
|
@ -354,14 +347,36 @@ class File_ASN1
|
||||||
case FILE_ASN1_CLASS_APPLICATION:
|
case FILE_ASN1_CLASS_APPLICATION:
|
||||||
case FILE_ASN1_CLASS_PRIVATE:
|
case FILE_ASN1_CLASS_PRIVATE:
|
||||||
case FILE_ASN1_CLASS_CONTEXT_SPECIFIC:
|
case FILE_ASN1_CLASS_CONTEXT_SPECIFIC:
|
||||||
$decoded[] = array(
|
if (!$constructed) {
|
||||||
|
return array(
|
||||||
'type' => $class,
|
'type' => $class,
|
||||||
'constant' => $tag,
|
'constant' => $tag,
|
||||||
'content' => $constructed ? $this->_decode_ber($content, $start) : $content,
|
'content' => $content,
|
||||||
'length' => $length + $start - $current['start']
|
'length' => $length + $start - $current['start']
|
||||||
) + $current;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$newcontent = array();
|
||||||
|
if (strlen($content)) {
|
||||||
|
$newcontent = $this->_decode_ber($content, $start);
|
||||||
|
$length = $newcontent['length'];
|
||||||
|
if (substr($content, $length, 2) == "\0\0") {
|
||||||
|
$length+= 2;
|
||||||
|
}
|
||||||
$start+= $length;
|
$start+= $length;
|
||||||
continue 2;
|
$newcontent = array($newcontent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'type' => $class,
|
||||||
|
'constant' => $tag,
|
||||||
|
// the array encapsulation is for BC with the old format
|
||||||
|
'content' => $newcontent,
|
||||||
|
// the only time when $content['headerlength'] isn't defined is when the length is indefinite.
|
||||||
|
// the absence of $content['headerlength'] is how we know if something is indefinite or not.
|
||||||
|
// technically, it could be defined to be 2 and then another indicator could be used but whatever.
|
||||||
|
'length' => $start - $current['start']
|
||||||
|
) + $current;
|
||||||
}
|
}
|
||||||
|
|
||||||
$current+= array('type' => $tag);
|
$current+= array('type' => $tag);
|
||||||
|
|
@ -409,16 +424,21 @@ class File_ASN1
|
||||||
if (!$constructed) {
|
if (!$constructed) {
|
||||||
$current['content'] = $content;
|
$current['content'] = $content;
|
||||||
} else {
|
} else {
|
||||||
$temp = $this->_decode_ber($content, $start);
|
$current['content'] = '';
|
||||||
$length-= strlen($content);
|
$length = 0;
|
||||||
for ($i = 0, $size = count($temp); $i < $size; $i++) {
|
while (substr($content, 0, 2) != "\0\0") {
|
||||||
|
$temp = $this->_decode_ber($content, $length + $start);
|
||||||
|
$this->_string_shift($content, $temp['length']);
|
||||||
// all subtags should be octet strings
|
// all subtags should be octet strings
|
||||||
//if ($temp[$i]['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
|
//if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
|
||||||
// return false;
|
// return false;
|
||||||
//}
|
//}
|
||||||
$current['content'].= $temp[$i]['content'];
|
$current['content'].= $temp['content'];
|
||||||
|
$length+= $temp['length'];
|
||||||
|
}
|
||||||
|
if (substr($content, 0, 2) == "\0\0") {
|
||||||
|
$length+= 2; // +2 for the EOC
|
||||||
}
|
}
|
||||||
// $length =
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FILE_ASN1_TYPE_NULL:
|
case FILE_ASN1_TYPE_NULL:
|
||||||
|
|
@ -429,7 +449,20 @@ class File_ASN1
|
||||||
break;
|
break;
|
||||||
case FILE_ASN1_TYPE_SEQUENCE:
|
case FILE_ASN1_TYPE_SEQUENCE:
|
||||||
case FILE_ASN1_TYPE_SET:
|
case FILE_ASN1_TYPE_SET:
|
||||||
$current['content'] = $this->_decode_ber($content, $start);
|
$offset = 0;
|
||||||
|
$current['content'] = array();
|
||||||
|
while (strlen($content)) {
|
||||||
|
// if indefinite length construction was used and we have an end-of-content string next
|
||||||
|
// see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2
|
||||||
|
if (!isset($current['headerlength']) && substr($content, 0, 2) == "\0\0") {
|
||||||
|
$length = $offset + 2; // +2 for the EOC
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
$temp = $this->_decode_ber($content, $start + $offset);
|
||||||
|
$this->_string_shift($content, $temp['length']);
|
||||||
|
$current['content'][] = $temp;
|
||||||
|
$offset+= $temp['length'];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
|
case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
|
||||||
$temp = ord($this->_string_shift($content));
|
$temp = ord($this->_string_shift($content));
|
||||||
|
|
@ -484,18 +517,16 @@ class File_ASN1
|
||||||
case FILE_ASN1_TYPE_GENERALIZED_TIME:
|
case FILE_ASN1_TYPE_GENERALIZED_TIME:
|
||||||
$current['content'] = $this->_decodeTime($content, $tag);
|
$current['content'] = $this->_decodeTime($content, $tag);
|
||||||
default:
|
default:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$start+= $length;
|
$start+= $length;
|
||||||
$decoded[] = $current + array('length' => $start - $current['start']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $decoded;
|
// ie. length is the length of the full TLV encoding - it's not just the length of the value
|
||||||
|
return $current + array('length' => $start - $current['start']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ASN.1 Decode
|
* ASN.1 Map
|
||||||
*
|
*
|
||||||
* Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format.
|
* Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format.
|
||||||
*
|
*
|
||||||
|
|
@ -805,16 +836,6 @@ class File_ASN1
|
||||||
return $this->_encode_der($source, $mapping, null, $special);
|
return $this->_encode_der($source, $mapping, null, $special);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ASN.1 Encode (Helper function)
|
|
||||||
*
|
|
||||||
* @param String $source
|
|
||||||
* @param Array $mapping
|
|
||||||
* @param Integer $idx
|
|
||||||
* @param Array $special
|
|
||||||
* @return String
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
/**
|
/**
|
||||||
* ASN.1 Encode (Helper function)
|
* ASN.1 Encode (Helper function)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
* @category File
|
* @category File
|
||||||
* @package File_X509
|
* @package File_X509
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMXII Jim Wigginton
|
* @copyright 2012 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
* @category Math
|
* @category Math
|
||||||
* @package Math_BigInteger
|
* @package Math_BigInteger
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVI Jim Wigginton
|
* @copyright 2006 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://pear.php.net/package/Math_BigInteger
|
* @link http://pear.php.net/package/Math_BigInteger
|
||||||
*/
|
*/
|
||||||
|
|
@ -278,7 +278,14 @@ class Math_BigInteger
|
||||||
$versions = array();
|
$versions = array();
|
||||||
if (!empty($matches[1])) {
|
if (!empty($matches[1])) {
|
||||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||||
$versions[$matches[1][$i]] = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
||||||
|
|
||||||
|
// Remove letter part in OpenSSL version
|
||||||
|
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
||||||
|
$versions[$matches[1][$i]] = $fullVersion;
|
||||||
|
} else {
|
||||||
|
$versions[$matches[1][$i]] = $m[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,7 +336,10 @@ class Math_BigInteger
|
||||||
|
|
||||||
switch ( MATH_BIGINTEGER_MODE ) {
|
switch ( MATH_BIGINTEGER_MODE ) {
|
||||||
case MATH_BIGINTEGER_MODE_GMP:
|
case MATH_BIGINTEGER_MODE_GMP:
|
||||||
if (is_resource($x) && get_resource_type($x) == 'GMP integer') {
|
switch (true) {
|
||||||
|
case is_resource($x) && get_resource_type($x) == 'GMP integer':
|
||||||
|
// PHP 5.6 switched GMP from using resources to objects
|
||||||
|
case is_object($x) && get_class($x) == 'GMP':
|
||||||
$this->value = $x;
|
$this->value = $x;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -912,7 +922,7 @@ class Math_BigInteger
|
||||||
$value = $x_value;
|
$value = $x_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
$value[] = 0; // just in case the carry adds an extra digit
|
$value[count($value)] = 0; // just in case the carry adds an extra digit
|
||||||
|
|
||||||
$carry = 0;
|
$carry = 0;
|
||||||
for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
|
for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
|
||||||
|
|
@ -2134,7 +2144,7 @@ class Math_BigInteger
|
||||||
|
|
||||||
if ($this->_compare($result, false, $temp[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_SIGN]) < 0) {
|
if ($this->_compare($result, false, $temp[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_SIGN]) < 0) {
|
||||||
$corrector_value = $this->_array_repeat(0, $n_length + 1);
|
$corrector_value = $this->_array_repeat(0, $n_length + 1);
|
||||||
$corrector_value[] = 1;
|
$corrector_value[count($corrector_value)] = 1;
|
||||||
$result = $this->_add($result, false, $corrector_value, false);
|
$result = $this->_add($result, false, $corrector_value, false);
|
||||||
$result = $result[MATH_BIGINTEGER_VALUE];
|
$result = $result[MATH_BIGINTEGER_VALUE];
|
||||||
}
|
}
|
||||||
|
|
@ -2904,7 +2914,7 @@ class Math_BigInteger
|
||||||
$leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3);
|
$leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3);
|
||||||
$this->_base256_lshift($leading_ones, $current_bits);
|
$this->_base256_lshift($leading_ones, $current_bits);
|
||||||
|
|
||||||
$temp = str_pad($temp, ceil($this->bits / 8), chr(0), STR_PAD_LEFT);
|
$temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT);
|
||||||
|
|
||||||
return $this->_normalize(new Math_BigInteger($leading_ones | $temp, 256));
|
return $this->_normalize(new Math_BigInteger($leading_ones | $temp, 256));
|
||||||
}
|
}
|
||||||
|
|
@ -3479,7 +3489,7 @@ class Math_BigInteger
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $carry ) {
|
if ( $carry ) {
|
||||||
$this->value[] = $carry;
|
$this->value[count($this->value)] = $carry;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($num_digits--) {
|
while ($num_digits--) {
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
* @category Net
|
* @category Net
|
||||||
* @package Net_SCP
|
* @package Net_SCP
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMX Jim Wigginton
|
* @copyright 2010 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -170,7 +170,7 @@ class Net_SCP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->ssh->exec('scp -t "' . $remote_file . '"', false)) { // -t = to
|
if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,7 +195,6 @@ class Net_SCP
|
||||||
|
|
||||||
$fp = @fopen($data, 'rb');
|
$fp = @fopen($data, 'rb');
|
||||||
if (!$fp) {
|
if (!$fp) {
|
||||||
fclose($fp);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$size = filesize($data);
|
$size = filesize($data);
|
||||||
|
|
@ -245,7 +244,7 @@ class Net_SCP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->ssh->exec('scp -f "' . $remote_file . '"', false)) { // -f = from
|
if (!$this->ssh->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
* @category Net
|
* @category Net
|
||||||
* @package Net_SFTP
|
* @package Net_SFTP
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMIX Jim Wigginton
|
* @copyright 2009 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -1061,12 +1061,14 @@ class Net_SFTP extends Net_SSH2
|
||||||
$dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
|
$dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
|
||||||
|
|
||||||
$temp = &$this->stat_cache;
|
$temp = &$this->stat_cache;
|
||||||
foreach ($dirs as $dir) {
|
$max = count($dirs) - 1;
|
||||||
|
foreach ($dirs as $i=>$dir) {
|
||||||
if (!isset($temp[$dir])) {
|
if (!isset($temp[$dir])) {
|
||||||
$temp[$dir] = array();
|
$temp[$dir] = array();
|
||||||
}
|
}
|
||||||
if ($dir == end($dirs)) {
|
if ($i === $max) {
|
||||||
$temp[$dir] = $value;
|
$temp[$dir] = $value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
$temp = &$temp[$dir];
|
$temp = &$temp[$dir];
|
||||||
}
|
}
|
||||||
|
|
@ -1084,8 +1086,9 @@ class Net_SFTP extends Net_SSH2
|
||||||
$dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
|
$dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
|
||||||
|
|
||||||
$temp = &$this->stat_cache;
|
$temp = &$this->stat_cache;
|
||||||
foreach ($dirs as $dir) {
|
$max = count($dirs) - 1;
|
||||||
if ($dir == end($dirs)) {
|
foreach ($dirs as $i=>$dir) {
|
||||||
|
if ($i === $max) {
|
||||||
unset($temp[$dir]);
|
unset($temp[$dir]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1501,7 +1504,7 @@ class Net_SFTP extends Net_SSH2
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$entries = $this->_list($path, true, false);
|
$entries = $this->_list($path, true);
|
||||||
|
|
||||||
if ($entries === false) {
|
if ($entries === false) {
|
||||||
return $this->_setstat($path, $attr, false);
|
return $this->_setstat($path, $attr, false);
|
||||||
|
|
@ -1513,11 +1516,8 @@ class Net_SFTP extends Net_SSH2
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unset($entries['.'], $entries['..']);
|
||||||
foreach ($entries as $filename=>$props) {
|
foreach ($entries as $filename=>$props) {
|
||||||
if ($filename == '.' || $filename == '..') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($props['type'])) {
|
if (!isset($props['type'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1757,6 +1757,8 @@ class Net_SFTP extends Net_SSH2
|
||||||
* contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
|
* contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
|
||||||
* large $remote_file will be, as well.
|
* large $remote_file will be, as well.
|
||||||
*
|
*
|
||||||
|
* If $data is a resource then it'll be used as a resource instead.
|
||||||
|
*
|
||||||
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
|
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
|
||||||
* care of that, yourself.
|
* care of that, yourself.
|
||||||
*
|
*
|
||||||
|
|
@ -1778,7 +1780,7 @@ class Net_SFTP extends Net_SSH2
|
||||||
* Setting $local_start to > 0 or $mode | NET_SFTP_RESUME_START doesn't do anything unless $mode | NET_SFTP_LOCAL_FILE.
|
* Setting $local_start to > 0 or $mode | NET_SFTP_RESUME_START doesn't do anything unless $mode | NET_SFTP_LOCAL_FILE.
|
||||||
*
|
*
|
||||||
* @param String $remote_file
|
* @param String $remote_file
|
||||||
* @param String $data
|
* @param String|resource $data
|
||||||
* @param optional Integer $mode
|
* @param optional Integer $mode
|
||||||
* @param optional Integer $start
|
* @param optional Integer $start
|
||||||
* @param optional Integer $local_start
|
* @param optional Integer $local_start
|
||||||
|
|
@ -1834,7 +1836,12 @@ class Net_SFTP extends Net_SSH2
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
||||||
if ($mode & NET_SFTP_LOCAL_FILE) {
|
switch (true) {
|
||||||
|
case is_resource($data):
|
||||||
|
$mode = $mode & ~NET_SFTP_LOCAL_FILE;
|
||||||
|
$fp = $data;
|
||||||
|
break;
|
||||||
|
case $mode & NET_SFTP_LOCAL_FILE:
|
||||||
if (!is_file($data)) {
|
if (!is_file($data)) {
|
||||||
user_error("$data is not a valid file");
|
user_error("$data is not a valid file");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1843,7 +1850,11 @@ class Net_SFTP extends Net_SSH2
|
||||||
if (!$fp) {
|
if (!$fp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$size = filesize($data);
|
}
|
||||||
|
|
||||||
|
if (isset($fp)) {
|
||||||
|
$stat = fstat($fp);
|
||||||
|
$size = $stat['size'];
|
||||||
|
|
||||||
if ($local_start >= 0) {
|
if ($local_start >= 0) {
|
||||||
fseek($fp, $local_start);
|
fseek($fp, $local_start);
|
||||||
|
|
@ -1864,11 +1875,13 @@ class Net_SFTP extends Net_SSH2
|
||||||
$sftp_packet_size-= strlen($handle) + 25;
|
$sftp_packet_size-= strlen($handle) + 25;
|
||||||
$i = 0;
|
$i = 0;
|
||||||
while ($sent < $size) {
|
while ($sent < $size) {
|
||||||
$temp = $mode & NET_SFTP_LOCAL_FILE ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
|
$temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
|
||||||
$subtemp = $offset + $sent;
|
$subtemp = $offset + $sent;
|
||||||
$packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
|
$packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
|
||||||
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
|
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
|
||||||
|
if ($mode & NET_SFTP_LOCAL_FILE) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$sent+= strlen($temp);
|
$sent+= strlen($temp);
|
||||||
|
|
@ -2003,6 +2016,12 @@ class Net_SFTP extends Net_SSH2
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_resource($local_file)) {
|
||||||
|
$fp = $local_file;
|
||||||
|
$stat = fstat($fp);
|
||||||
|
$res_offset = $stat['size'];
|
||||||
|
} else {
|
||||||
|
$res_offset = 0;
|
||||||
if ($local_file !== false) {
|
if ($local_file !== false) {
|
||||||
$fp = fopen($local_file, 'wb');
|
$fp = fopen($local_file, 'wb');
|
||||||
if (!$fp) {
|
if (!$fp) {
|
||||||
|
|
@ -2011,13 +2030,16 @@ class Net_SFTP extends Net_SSH2
|
||||||
} else {
|
} else {
|
||||||
$content = '';
|
$content = '';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fclose_check = $local_file !== false && !is_resource($local_file);
|
||||||
|
|
||||||
$start = $offset;
|
$start = $offset;
|
||||||
$size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length;
|
$size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length;
|
||||||
while (true) {
|
while (true) {
|
||||||
$packet = pack('Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, $size);
|
$packet = pack('Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, $size);
|
||||||
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
|
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
|
||||||
if ($local_file !== false) {
|
if ($fclose_check) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2040,7 +2062,7 @@ class Net_SFTP extends Net_SSH2
|
||||||
break 2;
|
break 2;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
|
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
|
||||||
if ($local_file !== false) {
|
if ($fclose_check) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2055,11 +2077,11 @@ class Net_SFTP extends Net_SSH2
|
||||||
if ($local_file === false) {
|
if ($local_file === false) {
|
||||||
$content = substr($content, 0, $length);
|
$content = substr($content, 0, $length);
|
||||||
} else {
|
} else {
|
||||||
ftruncate($fp, $length);
|
ftruncate($fp, $length + $res_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($local_file !== false) {
|
if ($fclose_check) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2135,7 +2157,7 @@ class Net_SFTP extends Net_SSH2
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$entries = $this->_list($path, true, false);
|
$entries = $this->_list($path, true);
|
||||||
|
|
||||||
// normally $entries would have at least . and .. but it might not if the directories
|
// normally $entries would have at least . and .. but it might not if the directories
|
||||||
// permissions didn't allow reading
|
// permissions didn't allow reading
|
||||||
|
|
@ -2143,11 +2165,8 @@ class Net_SFTP extends Net_SSH2
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unset($entries['.'], $entries['..']);
|
||||||
foreach ($entries as $filename=>$props) {
|
foreach ($entries as $filename=>$props) {
|
||||||
if ($filename == '.' || $filename == '..') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($props['type'])) {
|
if (!isset($props['type'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2205,7 +2224,7 @@ class Net_SFTP extends Net_SSH2
|
||||||
$result = $this->_query_stat_cache($path);
|
$result = $this->_query_stat_cache($path);
|
||||||
|
|
||||||
if (isset($result)) {
|
if (isset($result)) {
|
||||||
// return true if $result is an array or if it's int(1)
|
// return true if $result is an array or if it's an stdClass object
|
||||||
return $result !== false;
|
return $result !== false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2348,7 +2367,7 @@ class Net_SFTP extends Net_SSH2
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case NET_SFTP_BLOCK_DEVICE: return 'block';
|
case NET_SFTP_TYPE_BLOCK_DEVICE: return 'block';
|
||||||
case NET_SFTP_TYPE_CHAR_DEVICE: return 'char';
|
case NET_SFTP_TYPE_CHAR_DEVICE: return 'char';
|
||||||
case NET_SFTP_TYPE_DIRECTORY: return 'dir';
|
case NET_SFTP_TYPE_DIRECTORY: return 'dir';
|
||||||
case NET_SFTP_TYPE_FIFO: return 'fifo';
|
case NET_SFTP_TYPE_FIFO: return 'fifo';
|
||||||
|
|
@ -2454,14 +2473,13 @@ class Net_SFTP extends Net_SSH2
|
||||||
foreach ($this->attributes as $key => $value) {
|
foreach ($this->attributes as $key => $value) {
|
||||||
switch ($flags & $key) {
|
switch ($flags & $key) {
|
||||||
case NET_SFTP_ATTR_SIZE: // 0x00000001
|
case NET_SFTP_ATTR_SIZE: // 0x00000001
|
||||||
// size is represented by a 64-bit integer, so we perhaps ought to be doing the following:
|
// The size attribute is defined as an unsigned 64-bit integer.
|
||||||
// $attr['size'] = new Math_BigInteger($this->_string_shift($response, 8), 256);
|
// The following will use floats on 32-bit platforms, if necessary.
|
||||||
// of course, you shouldn't be using Net_SFTP to transfer files that are in excess of 4GB
|
// As can be seen in the BigInteger class, floats are generally
|
||||||
// (0xFFFFFFFF bytes), anyway. as such, we'll just represent all file sizes that are bigger than
|
// IEEE 754 binary64 "double precision" on such platforms and
|
||||||
// 4GB as being 4GB.
|
// as such can represent integers of at least 2^50 without loss
|
||||||
extract(unpack('Nupper/Nsize', $this->_string_shift($response, 8)));
|
// of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB.
|
||||||
$attr['size'] = $upper ? 4294967296 * $upper : 0;
|
$attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8)));
|
||||||
$attr['size']+= $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;
|
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
|
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
|
||||||
$attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));
|
$attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));
|
||||||
|
|
@ -2521,7 +2539,7 @@ class Net_SFTP extends Net_SSH2
|
||||||
case 0020000: // character special
|
case 0020000: // character special
|
||||||
return NET_SFTP_TYPE_CHAR_DEVICE;
|
return NET_SFTP_TYPE_CHAR_DEVICE;
|
||||||
case 0060000: // block special
|
case 0060000: // block special
|
||||||
return NET_SFTP_BLOCK_DEVICE;
|
return NET_SFTP_TYPE_BLOCK_DEVICE;
|
||||||
case 0140000: // socket
|
case 0140000: // socket
|
||||||
return NET_SFTP_TYPE_SOCKET;
|
return NET_SFTP_TYPE_SOCKET;
|
||||||
case 0160000: // whiteout
|
case 0160000: // whiteout
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
* @category Net
|
* @category Net
|
||||||
* @package Net_SFTP_Stream
|
* @package Net_SFTP_Stream
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMXIII Jim Wigginton
|
* @copyright 2013 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -48,7 +48,6 @@ class Net_SFTP_Stream
|
||||||
* Rather than re-create the connection we re-use instances if possible
|
* Rather than re-create the connection we re-use instances if possible
|
||||||
*
|
*
|
||||||
* @var Array
|
* @var Array
|
||||||
* @access static
|
|
||||||
*/
|
*/
|
||||||
static $instances;
|
static $instances;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
* @category Net
|
* @category Net
|
||||||
* @package Net_SSH1
|
* @package Net_SSH1
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -1128,6 +1128,7 @@ class Net_SSH1
|
||||||
|
|
||||||
$padding_length = 8 - ($temp['length'] & 7);
|
$padding_length = 8 - ($temp['length'] & 7);
|
||||||
$length = $temp['length'] + $padding_length;
|
$length = $temp['length'] + $padding_length;
|
||||||
|
$raw = '';
|
||||||
|
|
||||||
while ($length > 0) {
|
while ($length > 0) {
|
||||||
$temp = fread($this->fsock, $length);
|
$temp = fread($this->fsock, $length);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
* @category Net
|
* @category Net
|
||||||
* @package Net_SSH2
|
* @package Net_SSH2
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright 2007 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
@ -77,7 +77,7 @@ define('NET_SSH2_MASK_CONNECTED', 0x00000002);
|
||||||
define('NET_SSH2_MASK_LOGIN_REQ', 0x00000004);
|
define('NET_SSH2_MASK_LOGIN_REQ', 0x00000004);
|
||||||
define('NET_SSH2_MASK_LOGIN', 0x00000008);
|
define('NET_SSH2_MASK_LOGIN', 0x00000008);
|
||||||
define('NET_SSH2_MASK_SHELL', 0x00000010);
|
define('NET_SSH2_MASK_SHELL', 0x00000010);
|
||||||
define('NET_SSH2_MASK_WINDOW_ADJUST', 0X00000020);
|
define('NET_SSH2_MASK_WINDOW_ADJUST', 0x00000020);
|
||||||
/**#@-*/
|
/**#@-*/
|
||||||
|
|
||||||
/**#@+
|
/**#@+
|
||||||
|
|
@ -191,100 +191,100 @@ class Net_SSH2
|
||||||
* Server Identifier
|
* Server Identifier
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getServerIdentification()
|
* @see Net_SSH2::getServerIdentification()
|
||||||
* @var String
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $server_identifier = '';
|
var $server_identifier = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key Exchange Algorithms
|
* Key Exchange Algorithms
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getKexAlgorithims()
|
* @see Net_SSH2::getKexAlgorithims()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $kex_algorithms;
|
var $kex_algorithms = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server Host Key Algorithms
|
* Server Host Key Algorithms
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getServerHostKeyAlgorithms()
|
* @see Net_SSH2::getServerHostKeyAlgorithms()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $server_host_key_algorithms;
|
var $server_host_key_algorithms = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption Algorithms: Client to Server
|
* Encryption Algorithms: Client to Server
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getEncryptionAlgorithmsClient2Server()
|
* @see Net_SSH2::getEncryptionAlgorithmsClient2Server()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $encryption_algorithms_client_to_server;
|
var $encryption_algorithms_client_to_server = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption Algorithms: Server to Client
|
* Encryption Algorithms: Server to Client
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getEncryptionAlgorithmsServer2Client()
|
* @see Net_SSH2::getEncryptionAlgorithmsServer2Client()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $encryption_algorithms_server_to_client;
|
var $encryption_algorithms_server_to_client = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MAC Algorithms: Client to Server
|
* MAC Algorithms: Client to Server
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getMACAlgorithmsClient2Server()
|
* @see Net_SSH2::getMACAlgorithmsClient2Server()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $mac_algorithms_client_to_server;
|
var $mac_algorithms_client_to_server = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MAC Algorithms: Server to Client
|
* MAC Algorithms: Server to Client
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getMACAlgorithmsServer2Client()
|
* @see Net_SSH2::getMACAlgorithmsServer2Client()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $mac_algorithms_server_to_client;
|
var $mac_algorithms_server_to_client = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compression Algorithms: Client to Server
|
* Compression Algorithms: Client to Server
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getCompressionAlgorithmsClient2Server()
|
* @see Net_SSH2::getCompressionAlgorithmsClient2Server()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $compression_algorithms_client_to_server;
|
var $compression_algorithms_client_to_server = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compression Algorithms: Server to Client
|
* Compression Algorithms: Server to Client
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getCompressionAlgorithmsServer2Client()
|
* @see Net_SSH2::getCompressionAlgorithmsServer2Client()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $compression_algorithms_server_to_client;
|
var $compression_algorithms_server_to_client = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Languages: Server to Client
|
* Languages: Server to Client
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getLanguagesServer2Client()
|
* @see Net_SSH2::getLanguagesServer2Client()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $languages_server_to_client;
|
var $languages_server_to_client = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Languages: Client to Server
|
* Languages: Client to Server
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getLanguagesClient2Server()
|
* @see Net_SSH2::getLanguagesClient2Server()
|
||||||
* @var Array
|
* @var mixed false or Array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $languages_client_to_server;
|
var $languages_client_to_server = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Block Size for Server to Client Encryption
|
* Block Size for Server to Client Encryption
|
||||||
|
|
@ -949,6 +949,12 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function _connect()
|
function _connect()
|
||||||
{
|
{
|
||||||
|
if ($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->bitmap |= NET_SSH2_MASK_CONSTRUCTOR;
|
||||||
|
|
||||||
$timeout = $this->connectionTimeout;
|
$timeout = $this->connectionTimeout;
|
||||||
$host = $this->host . ':' . $this->port;
|
$host = $this->host . ':' . $this->port;
|
||||||
|
|
||||||
|
|
@ -965,7 +971,7 @@ class Net_SSH2
|
||||||
$timeout-= $elapsed;
|
$timeout-= $elapsed;
|
||||||
|
|
||||||
if ($timeout <= 0) {
|
if ($timeout <= 0) {
|
||||||
user_error(rtrim("Cannot connect to $host. Timeout error"));
|
user_error("Cannot connect to $host. Timeout error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -978,7 +984,7 @@ class Net_SSH2
|
||||||
// on windows this returns a "Warning: Invalid CRT parameters detected" error
|
// on windows this returns a "Warning: Invalid CRT parameters detected" error
|
||||||
// the !count() is done as a workaround for <https://bugs.php.net/42682>
|
// the !count() is done as a workaround for <https://bugs.php.net/42682>
|
||||||
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
|
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
|
||||||
user_error(rtrim("Cannot connect to $host. Banner timeout"));
|
user_error("Cannot connect to $host. Banner timeout");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1038,7 +1044,7 @@ class Net_SSH2
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->bitmap = NET_SSH2_MASK_CONNECTED;
|
$this->bitmap|= NET_SSH2_MASK_CONNECTED;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1098,7 +1104,7 @@ class Net_SSH2
|
||||||
'arcfour256',
|
'arcfour256',
|
||||||
'arcfour128',
|
'arcfour128',
|
||||||
|
|
||||||
'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
|
//'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
|
||||||
|
|
||||||
// CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
|
// CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
|
||||||
'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
|
'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
|
||||||
|
|
@ -1126,7 +1132,7 @@ class Net_SSH2
|
||||||
'3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
|
'3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
|
||||||
|
|
||||||
'3des-cbc', // REQUIRED three-key 3DES in CBC mode
|
'3des-cbc', // REQUIRED three-key 3DES in CBC mode
|
||||||
'none' // OPTIONAL no encryption; NOT RECOMMENDED
|
//'none' // OPTIONAL no encryption; NOT RECOMMENDED
|
||||||
);
|
);
|
||||||
|
|
||||||
if (phpseclib_resolve_include_path('Crypt/RC4.php') === false) {
|
if (phpseclib_resolve_include_path('Crypt/RC4.php') === false) {
|
||||||
|
|
@ -1163,11 +1169,14 @@ class Net_SSH2
|
||||||
}
|
}
|
||||||
|
|
||||||
$mac_algorithms = array(
|
$mac_algorithms = array(
|
||||||
|
// from <http://www.ietf.org/rfc/rfc6668.txt>:
|
||||||
|
'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32)
|
||||||
|
|
||||||
'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20)
|
'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20)
|
||||||
'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20)
|
'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20)
|
||||||
'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16)
|
'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16)
|
||||||
'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16)
|
'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16)
|
||||||
'none' // OPTIONAL no MAC; NOT RECOMMENDED
|
//'none' // OPTIONAL no MAC; NOT RECOMMENDED
|
||||||
);
|
);
|
||||||
|
|
||||||
static $compression_algorithms = array(
|
static $compression_algorithms = array(
|
||||||
|
|
@ -1692,6 +1701,10 @@ class Net_SSH2
|
||||||
|
|
||||||
$createKeyLength = 0; // ie. $mac_algorithms[$i] == 'none'
|
$createKeyLength = 0; // ie. $mac_algorithms[$i] == 'none'
|
||||||
switch ($mac_algorithms[$i]) {
|
switch ($mac_algorithms[$i]) {
|
||||||
|
case 'hmac-sha2-256':
|
||||||
|
$this->hmac_create = new Crypt_Hash('sha256');
|
||||||
|
$createKeyLength = 32;
|
||||||
|
break;
|
||||||
case 'hmac-sha1':
|
case 'hmac-sha1':
|
||||||
$this->hmac_create = new Crypt_Hash('sha1');
|
$this->hmac_create = new Crypt_Hash('sha1');
|
||||||
$createKeyLength = 20;
|
$createKeyLength = 20;
|
||||||
|
|
@ -1718,6 +1731,11 @@ class Net_SSH2
|
||||||
$checkKeyLength = 0;
|
$checkKeyLength = 0;
|
||||||
$this->hmac_size = 0;
|
$this->hmac_size = 0;
|
||||||
switch ($mac_algorithms[$i]) {
|
switch ($mac_algorithms[$i]) {
|
||||||
|
case 'hmac-sha2-256':
|
||||||
|
$this->hmac_check = new Crypt_Hash('sha256');
|
||||||
|
$checkKeyLength = 32;
|
||||||
|
$this->hmac_size = 32;
|
||||||
|
break;
|
||||||
case 'hmac-sha1':
|
case 'hmac-sha1':
|
||||||
$this->hmac_check = new Crypt_Hash('sha1');
|
$this->hmac_check = new Crypt_Hash('sha1');
|
||||||
$checkKeyLength = 20;
|
$checkKeyLength = 20;
|
||||||
|
|
@ -1799,7 +1817,6 @@ class Net_SSH2
|
||||||
function _login($username)
|
function _login($username)
|
||||||
{
|
{
|
||||||
if (!($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR)) {
|
if (!($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR)) {
|
||||||
$this->bitmap |= NET_SSH2_MASK_CONSTRUCTOR;
|
|
||||||
if (!$this->_connect()) {
|
if (!$this->_connect()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2062,7 +2079,6 @@ class Net_SSH2
|
||||||
|
|
||||||
if (!count($responses) && $num_prompts) {
|
if (!count($responses) && $num_prompts) {
|
||||||
$this->last_interactive_response = $orig;
|
$this->last_interactive_response = $orig;
|
||||||
$this->bitmap |= NET_SSH_MASK_LOGIN_INTERACTIVE;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2245,7 +2261,7 @@ class Net_SSH2
|
||||||
/**
|
/**
|
||||||
* Execute Command
|
* Execute Command
|
||||||
*
|
*
|
||||||
* If $block is set to false then Net_SSH2::_get_channel_packet(NET_SSH2_CHANNEL_EXEC) will need to be called manually.
|
* If $callback is set to false then Net_SSH2::_get_channel_packet(NET_SSH2_CHANNEL_EXEC) will need to be called manually.
|
||||||
* In all likelihood, this is not a feature you want to be taking advantage of.
|
* In all likelihood, this is not a feature you want to be taking advantage of.
|
||||||
*
|
*
|
||||||
* @param String $command
|
* @param String $command
|
||||||
|
|
@ -2654,11 +2670,12 @@ class Net_SSH2
|
||||||
/**
|
/**
|
||||||
* Is the connection still active?
|
* Is the connection still active?
|
||||||
*
|
*
|
||||||
|
* @return boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function isConnected()
|
function isConnected()
|
||||||
{
|
{
|
||||||
return $this->bitmap & NET_SSH2_MASK_LOGIN;
|
return (bool) ($this->bitmap & NET_SSH2_MASK_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2968,7 +2985,7 @@ class Net_SSH2
|
||||||
|
|
||||||
extract(unpack('Ctype/Nchannel', $this->_string_shift($response, 5)));
|
extract(unpack('Ctype/Nchannel', $this->_string_shift($response, 5)));
|
||||||
|
|
||||||
$this->window_size_server_to_client[$channel]-= strlen($response) + 4;
|
$this->window_size_server_to_client[$channel]-= strlen($response);
|
||||||
|
|
||||||
// resize the window, if appropriate
|
// resize the window, if appropriate
|
||||||
if ($this->window_size_server_to_client[$channel] < 0) {
|
if ($this->window_size_server_to_client[$channel] < 0) {
|
||||||
|
|
@ -3258,26 +3275,22 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function _send_channel_packet($client_channel, $data)
|
function _send_channel_packet($client_channel, $data)
|
||||||
{
|
{
|
||||||
|
while (strlen($data)) {
|
||||||
|
if (!$this->window_size_client_to_server[$client_channel]) {
|
||||||
|
$this->bitmap^= NET_SSH2_MASK_WINDOW_ADJUST;
|
||||||
|
// using an invalid channel will let the buffers be built up for the valid channels
|
||||||
|
$this->_get_channel_packet(-1);
|
||||||
|
$this->bitmap^= NET_SSH2_MASK_WINDOW_ADJUST;
|
||||||
|
}
|
||||||
|
|
||||||
/* The maximum amount of data allowed is determined by the maximum
|
/* The maximum amount of data allowed is determined by the maximum
|
||||||
packet size for the channel, and the current window size, whichever
|
packet size for the channel, and the current window size, whichever
|
||||||
is smaller.
|
is smaller.
|
||||||
|
|
||||||
-- http://tools.ietf.org/html/rfc4254#section-5.2 */
|
-- http://tools.ietf.org/html/rfc4254#section-5.2 */
|
||||||
$max_size = min(
|
$max_size = min(
|
||||||
$this->packet_size_client_to_server[$client_channel],
|
$this->packet_size_client_to_server[$client_channel],
|
||||||
$this->window_size_client_to_server[$client_channel]
|
$this->window_size_client_to_server[$client_channel]
|
||||||
) - 4;
|
);
|
||||||
while (strlen($data) > $max_size) {
|
|
||||||
if (!$this->window_size_client_to_server[$client_channel]) {
|
|
||||||
$this->bitmap^= NET_SSH2_MASK_WINDOW_ADJUST;
|
|
||||||
// using an invalid channel will let the buffers be built up for the valid channels
|
|
||||||
$output = $this->_get_channel_packet(-1);
|
|
||||||
$this->bitmap^= NET_SSH2_MASK_WINDOW_ADJUST;
|
|
||||||
$max_size = min(
|
|
||||||
$this->packet_size_client_to_server[$client_channel],
|
|
||||||
$this->window_size_client_to_server[$client_channel]
|
|
||||||
) - 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
$temp = $this->_string_shift($data, $max_size);
|
$temp = $this->_string_shift($data, $max_size);
|
||||||
$packet = pack('CN2a*',
|
$packet = pack('CN2a*',
|
||||||
|
|
@ -3286,27 +3299,13 @@ class Net_SSH2
|
||||||
strlen($temp),
|
strlen($temp),
|
||||||
$temp
|
$temp
|
||||||
);
|
);
|
||||||
|
$this->window_size_client_to_server[$client_channel]-= strlen($temp);
|
||||||
$this->window_size_client_to_server[$client_channel]-= strlen($temp) + 4;
|
|
||||||
|
|
||||||
if (!$this->_send_binary_packet($packet)) {
|
if (!$this->_send_binary_packet($packet)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen($data) >= $this->window_size_client_to_server[$client_channel] - 4) {
|
return true;
|
||||||
$this->bitmap^= NET_SSH2_MASK_WINDOW_ADJUST;
|
|
||||||
$this->_get_channel_packet(-1);
|
|
||||||
$this->bitmap^= NET_SSH2_MASK_WINDOW_ADJUST;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->window_size_client_to_server[$client_channel]-= strlen($data) + 4;
|
|
||||||
|
|
||||||
return $this->_send_binary_packet(pack('CN2a*',
|
|
||||||
NET_SSH2_MSG_CHANNEL_DATA,
|
|
||||||
$this->server_channels[$client_channel],
|
|
||||||
strlen($data),
|
|
||||||
$data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3355,7 +3354,7 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function _disconnect($reason)
|
function _disconnect($reason)
|
||||||
{
|
{
|
||||||
if ($this->bitmap) {
|
if ($this->bitmap & NET_SSH2_MASK_CONNECTED) {
|
||||||
$data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, '');
|
$data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, '');
|
||||||
$this->_send_binary_packet($data);
|
$this->_send_binary_packet($data);
|
||||||
$this->bitmap = 0;
|
$this->bitmap = 0;
|
||||||
|
|
@ -3509,6 +3508,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getServerIdentification()
|
function getServerIdentification()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->server_identifier;
|
return $this->server_identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3520,6 +3521,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getKexAlgorithms()
|
function getKexAlgorithms()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->kex_algorithms;
|
return $this->kex_algorithms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3531,6 +3534,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getServerHostKeyAlgorithms()
|
function getServerHostKeyAlgorithms()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->server_host_key_algorithms;
|
return $this->server_host_key_algorithms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3542,6 +3547,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getEncryptionAlgorithmsClient2Server()
|
function getEncryptionAlgorithmsClient2Server()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->encryption_algorithms_client_to_server;
|
return $this->encryption_algorithms_client_to_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3553,6 +3560,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getEncryptionAlgorithmsServer2Client()
|
function getEncryptionAlgorithmsServer2Client()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->encryption_algorithms_server_to_client;
|
return $this->encryption_algorithms_server_to_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3564,6 +3573,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getMACAlgorithmsClient2Server()
|
function getMACAlgorithmsClient2Server()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->mac_algorithms_client_to_server;
|
return $this->mac_algorithms_client_to_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3575,6 +3586,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getMACAlgorithmsServer2Client()
|
function getMACAlgorithmsServer2Client()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->mac_algorithms_server_to_client;
|
return $this->mac_algorithms_server_to_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3586,6 +3599,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getCompressionAlgorithmsClient2Server()
|
function getCompressionAlgorithmsClient2Server()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->compression_algorithms_client_to_server;
|
return $this->compression_algorithms_client_to_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3597,6 +3612,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getCompressionAlgorithmsServer2Client()
|
function getCompressionAlgorithmsServer2Client()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->compression_algorithms_server_to_client;
|
return $this->compression_algorithms_server_to_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3608,6 +3625,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getLanguagesServer2Client()
|
function getLanguagesServer2Client()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->languages_server_to_client;
|
return $this->languages_server_to_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3619,6 +3638,8 @@ class Net_SSH2
|
||||||
*/
|
*/
|
||||||
function getLanguagesClient2Server()
|
function getLanguagesClient2Server()
|
||||||
{
|
{
|
||||||
|
$this->_connect();
|
||||||
|
|
||||||
return $this->languages_client_to_server;
|
return $this->languages_client_to_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3648,7 +3669,6 @@ class Net_SSH2
|
||||||
function getServerPublicHostKey()
|
function getServerPublicHostKey()
|
||||||
{
|
{
|
||||||
if (!($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR)) {
|
if (!($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR)) {
|
||||||
$this->bitmap |= NET_SSH2_MASK_CONSTRUCTOR;
|
|
||||||
if (!$this->_connect()) {
|
if (!$this->_connect()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -3731,8 +3751,9 @@ class Net_SSH2
|
||||||
$e = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
$e = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
||||||
|
|
||||||
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
||||||
$n = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
$rawN = $this->_string_shift($server_public_host_key, $temp['length']);
|
||||||
$nLength = $temp['length'];
|
$n = new Math_BigInteger($rawN, -256);
|
||||||
|
$nLength = strlen(ltrim($rawN, "\0"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
||||||
|
|
@ -3769,7 +3790,7 @@ class Net_SSH2
|
||||||
$s = $s->toBytes();
|
$s = $s->toBytes();
|
||||||
|
|
||||||
$h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->exchange_hash));
|
$h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->exchange_hash));
|
||||||
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 3 - strlen($h)) . $h;
|
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
|
||||||
|
|
||||||
if ($s != $h) {
|
if ($s != $h) {
|
||||||
user_error('Bad server signature');
|
user_error('Bad server signature');
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
* @category System
|
* @category System
|
||||||
* @package System_SSH_Agent
|
* @package System_SSH_Agent
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMXIV Jim Wigginton
|
* @copyright 2014 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
|
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
* @category System
|
* @category System
|
||||||
* @package System_SSH_Agent
|
* @package System_SSH_Agent
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMXIV Jim Wigginton
|
* @copyright 2014 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
|
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,13 @@
|
||||||
value: capaAdditionalAccounts
|
value: capaAdditionalAccounts
|
||||||
}
|
}
|
||||||
}"></div>
|
}"></div>
|
||||||
|
<div data-bind="component: {
|
||||||
|
name: 'Checkbox',
|
||||||
|
params: {
|
||||||
|
label: 'TAB_GENERAL/LABEL_ALLOW_IDENTITIES',
|
||||||
|
value: capaIdentities
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,20 @@
|
||||||
<div class="legend">
|
<div class="legend">
|
||||||
<span class="i18n i18n-animation" data-i18n="SETTINGS_GENERAL/LEGEND_GENERAL"></span>
|
<span class="i18n i18n-animation" data-i18n="SETTINGS_GENERAL/LEGEND_GENERAL"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">
|
||||||
|
<span class="i18n" data-i18n="SETTINGS_GENERAL/LABEL_IDENTITY"></span>
|
||||||
|
</label>
|
||||||
|
<div class="controls">
|
||||||
|
<div style="display: inline-block; margin-top: 5px">
|
||||||
|
<b data-bind="text: identityMainDesc"></b>
|
||||||
|
|
||||||
|
<span data-bind="click: editMainIdentity" style="cursor: pointer">
|
||||||
|
<i class="icon-cog"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="control-group" data-bind="visible: allowLanguagesOnSettings">
|
<div class="control-group" data-bind="visible: allowLanguagesOnSettings">
|
||||||
<label class="control-label">
|
<label class="control-label">
|
||||||
<span class="i18n" data-i18n="SETTINGS_GENERAL/LABEL_LANGUAGE"></span>
|
<span class="i18n" data-i18n="SETTINGS_GENERAL/LABEL_LANGUAGE"></span>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ LABEL_ALLOW_GRAVATAR = "Gravatar erlauben"
|
||||||
LEGEND_MAIN = "Haupt"
|
LEGEND_MAIN = "Haupt"
|
||||||
LABEL_ATTACHMENT_SIZE_LIMIT = "Größenlimit für Anhänge"
|
LABEL_ATTACHMENT_SIZE_LIMIT = "Größenlimit für Anhänge"
|
||||||
LABEL_ALLOW_ADDITIONAL_ACCOUNTS = "Zusätzliche Konten erlauben"
|
LABEL_ALLOW_ADDITIONAL_ACCOUNTS = "Zusätzliche Konten erlauben"
|
||||||
|
LABEL_ALLOW_IDENTITIES = "Allow multiple identities"
|
||||||
LABEL_ALLOW_TEMPLATES = "Vorlagen erlauben"
|
LABEL_ALLOW_TEMPLATES = "Vorlagen erlauben"
|
||||||
ALERT_WARNING = "Warnung!"
|
ALERT_WARNING = "Warnung!"
|
||||||
HTML_ALERT_WEAK_PASSWORD = "Sie verwenden das Standard-Admin-Passwort.
|
HTML_ALERT_WEAK_PASSWORD = "Sie verwenden das Standard-Admin-Passwort.
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ LABEL_ALLOW_GRAVATAR = "Allow Gravatar"
|
||||||
LEGEND_MAIN = "Main"
|
LEGEND_MAIN = "Main"
|
||||||
LABEL_ATTACHMENT_SIZE_LIMIT = "Attachment size limit"
|
LABEL_ATTACHMENT_SIZE_LIMIT = "Attachment size limit"
|
||||||
LABEL_ALLOW_ADDITIONAL_ACCOUNTS = "Allow additional accounts"
|
LABEL_ALLOW_ADDITIONAL_ACCOUNTS = "Allow additional accounts"
|
||||||
|
LABEL_ALLOW_IDENTITIES = "Allow multiple identities"
|
||||||
LABEL_ALLOW_TEMPLATES = "Allow templates"
|
LABEL_ALLOW_TEMPLATES = "Allow templates"
|
||||||
ALERT_WARNING = "Warning!"
|
ALERT_WARNING = "Warning!"
|
||||||
HTML_ALERT_WEAK_PASSWORD = "You are using the default admin password.
|
HTML_ALERT_WEAK_PASSWORD = "You are using the default admin password.
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ LABEL_ALLOW_GRAVATAR = "Permitir Gravatar"
|
||||||
LEGEND_MAIN = "Principal"
|
LEGEND_MAIN = "Principal"
|
||||||
LABEL_ATTACHMENT_SIZE_LIMIT = "Tamanho limite de anexo"
|
LABEL_ATTACHMENT_SIZE_LIMIT = "Tamanho limite de anexo"
|
||||||
LABEL_ALLOW_ADDITIONAL_ACCOUNTS = "Permitir contas adicionais"
|
LABEL_ALLOW_ADDITIONAL_ACCOUNTS = "Permitir contas adicionais"
|
||||||
|
LABEL_ALLOW_IDENTITIES = "Allow multiple identities"
|
||||||
LABEL_ALLOW_TEMPLATES = "Permitir templates"
|
LABEL_ALLOW_TEMPLATES = "Permitir templates"
|
||||||
ALERT_WARNING = "Aviso!"
|
ALERT_WARNING = "Aviso!"
|
||||||
HTML_ALERT_WEAK_PASSWORD = "Você está usando a senha administrativa padrão.
|
HTML_ALERT_WEAK_PASSWORD = "Você está usando a senha administrativa padrão.
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ LABEL_ALLOW_GRAVATAR = "Разрешить граватары"
|
||||||
LEGEND_MAIN = "Основное"
|
LEGEND_MAIN = "Основное"
|
||||||
LABEL_ATTACHMENT_SIZE_LIMIT = "Предельный размер вложений"
|
LABEL_ATTACHMENT_SIZE_LIMIT = "Предельный размер вложений"
|
||||||
LABEL_ALLOW_ADDITIONAL_ACCOUNTS = "Разрешить дополнительные аккаунты"
|
LABEL_ALLOW_ADDITIONAL_ACCOUNTS = "Разрешить дополнительные аккаунты"
|
||||||
|
LABEL_ALLOW_IDENTITIES = "Разрешить множественные профили"
|
||||||
LABEL_ALLOW_TEMPLATES = "Разрешить шаблоны"
|
LABEL_ALLOW_TEMPLATES = "Разрешить шаблоны"
|
||||||
ALERT_WARNING = "Внимание!"
|
ALERT_WARNING = "Внимание!"
|
||||||
HTML_ALERT_WEAK_PASSWORD = "Вы используете пароль администратора по умолчанию.
|
HTML_ALERT_WEAK_PASSWORD = "Вы используете пароль администратора по умолчанию.
|
||||||
|
|
|
||||||
|
|
@ -481,6 +481,7 @@ AUTOLOGIN_MINUTES_OPTION_NAME = "%MINUTES% minute(s)"
|
||||||
[SETTINGS_GENERAL]
|
[SETTINGS_GENERAL]
|
||||||
LEGEND_GENERAL = "General"
|
LEGEND_GENERAL = "General"
|
||||||
LABEL_LANGUAGE = "Language"
|
LABEL_LANGUAGE = "Language"
|
||||||
|
LABEL_IDENTITY = "Identity"
|
||||||
LABEL_LAYOUT = "Layout"
|
LABEL_LAYOUT = "Layout"
|
||||||
LABEL_LAYOUT_NO_SPLIT = "No Split"
|
LABEL_LAYOUT_NO_SPLIT = "No Split"
|
||||||
LABEL_LAYOUT_VERTICAL_SPLIT = "Vertical Split"
|
LABEL_LAYOUT_VERTICAL_SPLIT = "Vertical Split"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue