Merge branch 'master' into pr-exceed_upload_limit_msg

Conflicts:
	apps/files/templates/index.php
	apps/files_sharing/templates/public.php
This commit is contained in:
Pellaeon Lin 2014-01-30 22:50:20 +08:00
commit 099b71c712
860 changed files with 38402 additions and 14086 deletions

View File

@ -26,7 +26,7 @@ RewriteRule ^.well-known/carddav /remote.php/carddav/ [R]
RewriteRule ^.well-known/caldav /remote.php/caldav/ [R]
RewriteRule ^apps/calendar/caldav.php remote.php/caldav/ [QSA,L]
RewriteRule ^apps/contacts/carddav.php remote.php/carddav/ [QSA,L]
RewriteRule ^apps/([^/]*)/(.*\.(css|php))$ index.php?app=$1&getfile=$2 [QSA,L]
RewriteRule ^apps/([^/]*)/(.*\.(php))$ index.php?app=$1&getfile=$2 [QSA,L]
RewriteRule ^remote/(.*) remote.php [QSA,L]
</IfModule>
<IfModule mod_mime.c>
@ -38,3 +38,6 @@ DirectoryIndex index.php index.html
</IfModule>
AddDefaultCharset utf-8
Options -Indexes
<IfModule pagespeed_module>
ModPagespeed Off
</IfModule>

@ -1 +1 @@
Subproject commit 42efd966284debadf83b761367e529bc45f806d6
Subproject commit 7c2c94c904c2721763e97d5bafd115f863080a60

View File

@ -53,13 +53,22 @@ $result = array(
);
if(trim($filename) === '') {
$result['data'] = array('message' => $l10n->t('File name cannot be empty.'));
$result['data'] = array('message' => (string)$l10n->t('File name cannot be empty.'));
OCP\JSON::error($result);
exit();
}
if(strpos($filename, '/') !== false) {
$result['data'] = array('message' => $l10n->t('File name must not contain "/". Please choose a different name.'));
$result['data'] = array('message' => (string)$l10n->t('File name must not contain "/". Please choose a different name.'));
OCP\JSON::error($result);
exit();
}
if (!\OC\Files\Filesystem::file_exists($dir . '/')) {
$result['data'] = array('message' => (string)$l10n->t(
'The target folder has been moved or deleted.'),
'code' => 'targetnotfound'
);
OCP\JSON::error($result);
exit();
}
@ -68,7 +77,7 @@ if(strpos($filename, '/') !== false) {
$target = $dir.'/'.$filename;
if (\OC\Files\Filesystem::file_exists($target)) {
$result['data'] = array('message' => $l10n->t(
$result['data'] = array('message' => (string)$l10n->t(
'The name %s is already used in the folder %s. Please choose a different name.',
array($filename, $dir))
);
@ -78,20 +87,32 @@ if (\OC\Files\Filesystem::file_exists($target)) {
if($source) {
if(substr($source, 0, 8)!='https://' and substr($source, 0, 7)!='http://') {
OCP\JSON::error(array('data' => array( 'message' => $l10n->t('Not a valid source') )));
OCP\JSON::error(array('data' => array('message' => $l10n->t('Not a valid source'))));
exit();
}
if (!ini_get('allow_url_fopen')) {
$eventSource->send('error', array('message' => $l10n->t('Server is not allowed to open URLs, please check the server configuration')));
$eventSource->close();
exit();
}
$ctx = stream_context_create(null, array('notification' =>'progress'));
$sourceStream=fopen($source, 'rb', false, $ctx);
$result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream);
$sourceStream=@fopen($source, 'rb', false, $ctx);
$result = 0;
if (is_resource($sourceStream)) {
$result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream);
}
if($result) {
$meta = \OC\Files\Filesystem::getFileInfo($target);
$mime=$meta['mimetype'];
$id = $meta['fileid'];
$eventSource->send('success', array('mime'=>$mime, 'size'=>\OC\Files\Filesystem::filesize($target), 'id' => $id, 'etag' => $meta['etag']));
$eventSource->send('success', array('mime' => $mime, 'size' => \OC\Files\Filesystem::filesize($target), 'id' => $id, 'etag' => $meta['etag']));
} else {
$eventSource->send('error', $l10n->t('Error while downloading %s to %s', array($source, $target)));
$eventSource->send('error', array('message' => $l10n->t('Error while downloading %s to %s', array($source, $target))));
}
if (is_resource($sourceStream)) {
fclose($sourceStream);
}
$eventSource->close();
exit();

View File

@ -29,6 +29,15 @@ if(strpos($foldername, '/') !== false) {
exit();
}
if (!\OC\Files\Filesystem::file_exists($dir . '/')) {
$result['data'] = array('message' => (string)$l10n->t(
'The target folder has been moved or deleted.'),
'code' => 'targetnotfound'
);
OCP\JSON::error($result);
exit();
}
//TODO why is stripslashes used on foldername here but not in newfile.php?
$target = $dir . '/' . stripslashes($foldername);

View File

@ -8,6 +8,7 @@ OCP\JSON::setContentTypeHeader('text/plain');
// If no token is sent along, rely on login only
$allowedPermissions = OCP\PERMISSION_ALL;
$errorCode = null;
$l = OC_L10N::get('files');
if (empty($_POST['dirToken'])) {
@ -34,6 +35,7 @@ if (empty($_POST['dirToken'])) {
// resolve reshares
$rootLinkItem = OCP\Share::resolveReShare($linkItem);
OCP\JSON::checkUserExists($rootLinkItem['uid_owner']);
// Setup FS with owner
OC_Util::tearDownFS();
OC_Util::setupFS($rootLinkItem['uid_owner']);
@ -124,7 +126,8 @@ if (strpos($dir, '..') === false) {
$meta = \OC\Files\Filesystem::getFileInfo($target);
if ($meta === false) {
$error = $l->t('Upload failed. Could not get file info.');
$error = $l->t('The target folder has been moved or deleted.');
$errorCode = 'targetnotfound';
} else {
$result[] = array('status' => 'success',
'mime' => $meta['mimetype'],
@ -176,5 +179,5 @@ if ($error === false) {
OCP\JSON::encodedPrint($result);
exit();
} else {
OCP\JSON::error(array(array('data' => array_merge(array('message' => $error), $storageStats))));
OCP\JSON::error(array(array('data' => array_merge(array('message' => $error, 'code' => $errorCode), $storageStats))));
}

View File

@ -52,6 +52,7 @@ $server->addPlugin(new OC_Connector_Sabre_FilesPlugin());
$server->addPlugin(new OC_Connector_Sabre_AbortedUploadDetectionPlugin());
$server->addPlugin(new OC_Connector_Sabre_QuotaPlugin());
$server->addPlugin(new OC_Connector_Sabre_MaintenancePlugin());
$server->addPlugin(new OC_Connector_Sabre_ExceptionLoggerPlugin('webdav'));
// And off we go!
$server->exec();

View File

@ -3,7 +3,7 @@
See the COPYING-README file. */
/* FILE MENU */
.actions { padding:.3em; height:2em; width: 100%; }
.actions { padding:5px; height:32px; width: 100%; }
.actions input, .actions button, .actions .button { margin:0; float:left; }
.actions .button a { color: #555; }
.actions .button a:hover, .actions .button a:active { color: #333; }
@ -33,9 +33,9 @@
#new>ul {
display: none;
position: fixed;
min-width: 7em;
min-width: 112px;
z-index: 10;
padding: .5em;
padding: 8px;
padding-bottom: 0;
margin-top: 14px;
margin-left: -1px;
@ -46,7 +46,7 @@
border-top-left-radius: 0;
box-shadow:0 2px 7px rgba(170,170,170,.4);
}
#new>ul>li { height:36px; margin:.3em; padding-left:3em; padding-bottom:0.1em;
#new>ul>li { height:36px; margin:5px; padding-left:48px; padding-bottom:2px;
background-repeat:no-repeat; cursor:pointer; }
#new>ul>li>p { cursor:pointer; padding-top: 7px; padding-bottom: 7px;}
@ -65,10 +65,15 @@
top: 44px;
width: 100%;
}
#filestable, #controls {
min-width: 680px;
/* make sure there's enough room for the file actions */
#body-user #filestable {
min-width: 750px;
}
#filestable tbody tr { background-color:#fff; height:2.5em; }
#body-user #controls {
min-width: 600px;
}
#filestable tbody tr { background-color:#fff; height:40px; }
#filestable tbody tr:hover, tbody tr:active {
background-color: rgb(240,240,240);
}
@ -83,7 +88,7 @@ span.extension, span.uploading, td.date { color:#999; }
span.extension { text-transform:lowercase; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter:alpha(opacity=70); opacity:.7; -webkit-transition:opacity 300ms; -moz-transition:opacity 300ms; -o-transition:opacity 300ms; transition:opacity 300ms; }
tr:hover span.extension { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; color:#777; }
table tr.mouseOver td { background-color:#eee; }
table th { height:2em; padding:0 .5em; color:#999; }
table th { height:24px; padding:0 8px; color:#999; }
table th .name {
position: absolute;
left: 55px;
@ -98,7 +103,7 @@ table td {
}
table th#headerName {
position: relative;
width: 100em; /* not really sure why this works better than 100% … table styling */
width: 9999px; /* not really sure why this works better than 100% … table styling */
padding: 0;
}
#headerName-container {
@ -106,15 +111,15 @@ table th#headerName {
height: 50px;
}
table th#headerSize, table td.filesize {
min-width: 3em;
padding: 0 1em;
min-width: 48px;
padding: 0 16px;
text-align: right;
}
table th#headerDate, table td.date {
-moz-box-sizing: border-box;
box-sizing: border-box;
position: relative;
min-width: 11em;
min-width: 176px;
}
/* Multiselect bar */
@ -140,9 +145,9 @@ table.multiselect thead th {
}
table.multiselect #headerName {
position: relative;
width: 100%;
width: 9999px; /* when we use 100%, the styling breaks on mobile … table styling */
}
table td.selection, table th.selection, table td.fileaction { width:2em; text-align:center; }
table td.selection, table th.selection, table td.fileaction { width:32px; text-align:center; }
table td.filename a.name {
position:relative; /* Firefox needs to explicitly have this default set … */
-moz-box-sizing: border-box;
@ -160,8 +165,8 @@ table td.filename input.filename {
margin-left: 2px;
cursor: text;
}
table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:.2em .5em .5em .3em; }
table td.filename .nametext, .uploadtext, .modified { float:left; padding:.3em 0; }
table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:3px 8px 8px 3px; }
table td.filename .nametext, .uploadtext, .modified { float:left; padding:14px 0; }
#modified {
position: absolute;
@ -181,8 +186,8 @@ table td.filename .nametext {
text-overflow: ellipsis;
max-width: 800px;
}
table td.filename .uploadtext { font-weight:normal; margin-left:.5em; }
table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; }
table td.filename .uploadtext { font-weight:normal; margin-left:8px; }
table td.filename form { font-size:14px; margin-left:48px; margin-right:48px; }
.ie8 input[type="checkbox"]{
padding: 0;
@ -217,6 +222,11 @@ table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; }
width: 50px;
z-index: 5;
}
#fileList tr td.filename>input[type="checkbox"]{
/* sometimes checkbox height is bigger (KDE/Qt), so setting to absolute
* to prevent it to increase the height */
position: absolute;
}
#fileList tr td.filename>input[type="checkbox"] + label {
left: 0;
}
@ -237,7 +247,7 @@ table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; }
#fileList tr td.filename a.name label {
position: absolute;
width: 100%;
width: 80%;
height: 50px;
}
@ -250,11 +260,11 @@ table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; }
right: 0;
}
#fileList img.move2trash { display:inline; margin:-.5em 0; padding:1em .5em 1em .5em !important; float:right; }
#fileList img.move2trash { display:inline; margin:-8px 0; padding:16px 8px 16px 8px !important; float:right; }
#fileList a.action.delete {
position: absolute;
right: 0;
padding: 9px 14px 19px !important;
padding: 28px 14px 19px !important;
}
a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; }
@ -272,13 +282,13 @@ a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; }
}
.selectedActions a img {
position:relative;
top:.3em;
top:5px;
}
#fileList a.action {
display: inline;
margin: -.5em 0;
margin: -8px 0;
padding: 18px 8px !important;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);

View File

@ -5,7 +5,7 @@
height: 36px;
width: 39px;
padding: 0 !important; /* override default control bar button padding */
margin-left: .2em;
margin-left: 3px;
overflow: hidden;
vertical-align: top;
}
@ -18,9 +18,6 @@
margin: -5px -3px;
cursor: pointer;
z-index: 10;
background-image: url('%webroot%/core/img/actions/upload.svg');
background-repeat: no-repeat;
background-position: center;
opacity: .65;
}
.file_upload_target { display:none; }
@ -33,7 +30,7 @@
height: 44px;
margin: -5px -3px;
padding: 0;
font-size: 1em;
font-size: 16px;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0;
z-index: 20;
cursor: pointer;
@ -119,11 +116,6 @@
.oc-dialog .fileexists .conflict input[type='checkbox'] {
float: left;
}
.oc-dialog .fileexists .toggle {
background-image: url('%webroot%/core/img/actions/triangle-e.png');
width: 16px;
height: 16px;
}
.oc-dialog .fileexists #allfileslabel {
float:right;
}

View File

@ -37,12 +37,7 @@ if(!\OC\Files\Filesystem::file_exists($filename)) {
$ftype=\OC\Files\Filesystem::getMimeType( $filename );
header('Content-Type:'.$ftype);
if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) {
header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' );
} else {
header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode( basename($filename) )
. '; filename="' . rawurlencode( basename($filename) ) . '"' );
}
OCP\Response::setContentDispositionHeader(basename($filename), 'attachment');
OCP\Response::disableCaching();
header('Content-Length: '.\OC\Files\Filesystem::filesize($filename));

View File

@ -63,7 +63,6 @@ $files = array();
$user = OC_User::getUser();
if (\OC\Files\Cache\Upgrade::needUpgrade($user)) { //dont load anything if we need to upgrade the cache
$needUpgrade = true;
$freeSpace = 0;
} else {
if ($isIE8){
// after the redirect above, the URL will have a format
@ -77,7 +76,6 @@ if (\OC\Files\Cache\Upgrade::needUpgrade($user)) { //dont load anything if we ne
else{
$files = \OCA\Files\Helper::getFiles($dir);
}
$freeSpace = \OC\Files\Filesystem::free_space($dir);
$needUpgrade = false;
}

View File

@ -222,6 +222,14 @@ $(document).ready(function() {
//examine file
var file = data.files[0];
try {
// FIXME: not so elegant... need to refactor that method to return a value
Files.isFileNameValid(file.name);
}
catch (errorMessage) {
data.textStatus = 'invalidcharacters';
data.errorThrown = errorMessage;
}
if (file.type === '' && file.size === 4096) {
data.textStatus = 'dirorzero';
@ -319,6 +327,13 @@ $(document).ready(function() {
} else {
// HTTP connection problem
OC.Notification.show(data.errorThrown);
if (data.result) {
var result = JSON.parse(data.result);
if (result && result[0] && result[0].data && result[0].data.code === 'targetnotfound') {
// abort upload of next files if any
OC.Upload.cancelUploads();
}
}
}
//hide notification after 10 sec
setTimeout(function() {
@ -617,7 +632,7 @@ $(document).ready(function() {
if (result.status === 'success') {
var date=new Date();
FileList.addDir(name, 0, date, hidden);
var tr=$('tr[data-file="'+name+'"]');
var tr = FileList.findFileEl(name);
tr.attr('data-id', result.data.id);
} else {
OC.dialogs.alert(result.data.message, t('core', 'Could not create folder'));
@ -659,7 +674,7 @@ $(document).ready(function() {
$('#uploadprogressbar').fadeOut();
var date = new Date();
FileList.addFile(localName, size, date, false, hidden);
var tr = $('tr[data-file="'+localName+'"]');
var tr = FileList.findFileEl(localName);
tr.data('mime', mime).data('id', id);
tr.attr('data-id', id);
var path = $('#dir').val()+'/'+localName;
@ -670,7 +685,12 @@ $(document).ready(function() {
});
eventSource.listen('error',function(error) {
$('#uploadprogressbar').fadeOut();
alert(error);
var message = (error && error.message) || t('core', 'Error fetching URL');
OC.Notification.show(message);
//hide notification after 10 sec
setTimeout(function() {
OC.Notification.hide();
}, 10000);
});
break;
}

View File

@ -71,7 +71,7 @@ var FileActions = {
FileActions.currentFile = parent;
var actions = FileActions.get(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions());
var file = FileActions.getCurrentFile();
if ($('tr[data-file="'+file+'"]').data('renaming')) {
if (FileList.findFileEl(file).data('renaming')) {
return;
}
@ -103,9 +103,9 @@ var FileActions = {
}
var html = '<a href="#" class="action" data-action="' + name + '">';
if (img) {
html += '<img class ="svg" src="' + img + '" /> ';
html += '<img class ="svg" src="' + img + '" />';
}
html += t('files', name) + '</a>';
html += '<span> ' + t('files', name) + '</span></a>';
var element = $(html);
element.data('action', name);
@ -173,7 +173,10 @@ $(document).ready(function () {
FileActions.register(downloadScope, 'Download', OC.PERMISSION_READ, function () {
return OC.imagePath('core', 'actions/download');
}, function (filename) {
window.location = OC.filePath('files', 'ajax', 'download.php') + '?files=' + encodeURIComponent(filename) + '&dir=' + encodeURIComponent($('#dir').val());
var url = FileList.getDownloadUrl(filename);
if (url) {
OC.redirect(url);
}
});
}
$('#fileList tr').each(function () {

View File

@ -6,6 +6,13 @@ var FileList={
$(this).attr('data-file',decodeURIComponent($(this).attr('data-file')));
});
},
/**
* Returns the tr element for a given file name
*/
findFileEl: function(fileName){
// use filterAttr to avoid escaping issues
return $('#fileList tr').filterAttr('data-file', fileName);
},
update:function(fileListHtml) {
var $fileList = $('#fileList');
$fileList.empty().html(fileListHtml);
@ -20,6 +27,8 @@ var FileList={
Files.setupDragAndDrop();
}
FileList.updateFileSummary();
procesSelection();
$fileList.trigger(jQuery.Event("updated"));
},
createRow:function(type, name, iconurl, linktarget, size, lastModified, permissions) {
@ -292,8 +301,12 @@ var FileList={
$('#filestable').toggleClass('hidden', show);
},
remove:function(name){
$('tr').filterAttr('data-file',name).find('td.filename').draggable('destroy');
$('tr').filterAttr('data-file',name).remove();
var fileEl = FileList.findFileEl(name);
if (fileEl.data('permissions') & OC.PERMISSION_DELETE) {
// file is only draggable when delete permissions are set
fileEl.find('td.filename').draggable('destroy');
}
fileEl.remove();
FileList.updateFileSummary();
if ( ! $('tr[data-file]').exists() ) {
$('#emptycontent').removeClass('hidden');
@ -334,7 +347,7 @@ var FileList={
FileList.updateFileSummary();
},
loadingDone:function(name, id) {
var mime, tr = $('tr[data-file="'+name+'"]');
var mime, tr = FileList.findFileEl(name);
tr.data('loading', false);
mime = tr.data('mime');
tr.attr('data-mime', mime);
@ -347,12 +360,12 @@ var FileList={
}, null, null, tr.attr('data-etag'));
tr.find('td.filename').draggable(dragOptions);
},
isLoading:function(name) {
return $('tr[data-file="'+name+'"]').data('loading');
isLoading:function(file) {
return FileList.findFileEl(file).data('loading');
},
rename:function(oldname) {
var tr, td, input, form;
tr = $('tr[data-file="'+oldname+'"]');
tr = FileList.findFileEl(oldname);
tr.data('renaming',true);
td = tr.children('td.filename');
input = $('<input type="text" class="filename"/>').val(oldname);
@ -500,14 +513,16 @@ var FileList={
form.trigger('submit');
});
},
inList:function(filename) {
return $('#fileList tr[data-file="'+filename+'"]').length;
inList:function(file) {
return FileList.findFileEl(file).length;
},
replace:function(oldName, newName, isNewFile) {
// Finish any existing actions
$('tr[data-file="'+oldName+'"]').hide();
$('tr[data-file="'+newName+'"]').hide();
var tr = $('tr[data-file="'+oldName+'"]').clone();
var oldFileEl = FileList.findFileEl(oldName);
var newFileEl = FileList.findFileEl(newName);
oldFileEl.hide();
newFileEl.hide();
var tr = oldFileEl.clone();
tr.attr('data-replace', 'true');
tr.attr('data-file', newName);
var td = tr.children('td.filename');
@ -559,7 +574,7 @@ var FileList={
files=[files];
}
for (var i=0; i<files.length; i++) {
var deleteAction = $('tr[data-file="'+files[i]+'"]').children("td.date").children(".action.delete");
var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete");
deleteAction.removeClass('delete-icon').addClass('progress-icon');
}
// Finish any existing actions
@ -573,7 +588,7 @@ var FileList={
function(result) {
if (result.status === 'success') {
$.each(files,function(index,file) {
var files = $('tr[data-file="'+file+'"]');
var files = FileList.findFileEl(file);
files.remove();
files.find('input[type="checkbox"]').removeAttr('checked');
files.removeClass('selected');
@ -595,7 +610,7 @@ var FileList={
OC.Notification.hide();
}, 10000);
$.each(files,function(index,file) {
var deleteAction = $('tr[data-file="' + file + '"] .action.delete');
var deleteAction = FileList.findFileEl(file).find('.action.delete');
deleteAction.removeClass('progress-icon').addClass('delete-icon');
});
}
@ -737,7 +752,7 @@ var FileList={
},
scrollTo:function(file) {
//scroll to and highlight preselected file
var $scrolltorow = $('tr[data-file="'+file+'"]');
var $scrolltorow = FileList.findFileEl(file);
if ($scrolltorow.exists()) {
$scrolltorow.addClass('searchresult');
$(window).scrollTop($scrolltorow.position().top);
@ -765,6 +780,20 @@ var FileList={
$('#fileList tr.searchresult').each(function(i,e) {
$(e).removeClass("searchresult");
});
},
/**
* Returns the download URL of the given file
* @param filename file name of the file
* @param dir optional directory in which the file name is, defaults to the current directory
*/
getDownloadUrl: function(filename, dir) {
var params = {
files: filename,
dir: dir || FileList.getCurrentDirectory(),
download: null
};
return OC.filePath('files', 'ajax', 'download.php') + '?' + OC.buildQueryString(params);
}
};
@ -949,7 +978,7 @@ $(document).ready(function() {
$('#notification').on('click', '.undo', function() {
if (FileList.deleteFiles) {
$.each(FileList.deleteFiles,function(index,file) {
$('tr[data-file="'+file+'"]').show();
FileList.findFileEl(file).show();
});
FileList.deleteCanceled=true;
FileList.deleteFiles=null;
@ -959,10 +988,10 @@ $(document).ready(function() {
FileList.deleteCanceled = false;
FileList.deleteFiles = [FileList.replaceOldName];
} else {
$('tr[data-file="'+FileList.replaceOldName+'"]').show();
FileList.findFileEl(FileList.replaceOldName).show();
}
$('tr[data-replace="true"').remove();
$('tr[data-file="'+FileList.replaceNewName+'"]').show();
FileList.findFileEl(FileList.replaceNewName).show();
FileList.replaceCanceled = true;
FileList.replaceOldName = null;
FileList.replaceNewName = null;
@ -977,7 +1006,8 @@ $(document).ready(function() {
});
});
$('#notification:first-child').on('click', '.suggest', function() {
$('tr[data-file="'+$('#notification > span').attr('data-oldName')+'"]').show();
var file = $('#notification > span').attr('data-oldName');
FileList.findFileEl(file).show();
OC.Notification.hide();
});
$('#notification:first-child').on('click', '.cancel', function() {

View File

@ -283,7 +283,7 @@ $(document).ready(function() {
procesSelection();
} else {
var filename=$(this).parent().parent().attr('data-file');
var tr=$('tr[data-file="'+filename+'"]');
var tr = FileList.findFileEl(filename);
var renaming=tr.data('renaming');
if (!renaming && !FileList.isLoading(filename)) {
FileActions.currentFile = $(this).parent();
@ -494,7 +494,7 @@ var createDragShadow = function(event) {
var dir=$('#dir').val();
$(selectedFiles).each(function(i,elem) {
var newtr = $('<tr/>').attr('data-dir', dir).attr('data-filename', elem.name);
var newtr = $('<tr/>').attr('data-dir', dir).attr('data-filename', elem.name).attr('data-origin', elem.origin);
newtr.append($('<td/>').addClass('filename').text(elem.name));
newtr.append($('<td/>').addClass('size').text(humanFileSize(elem.size)));
tbody.append(newtr);
@ -512,13 +512,30 @@ var createDragShadow = function(event) {
};
//options for file drag/drop
//start&stop handlers needs some cleaning up
var dragOptions={
revert: 'invalid', revertDuration: 300,
opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: 24, top: 18 },
helper: createDragShadow, cursor: 'move',
stop: function(event, ui) {
$('#fileList tr td.filename').addClass('ui-draggable');
}
start: function(event, ui){
var $selectedFiles = $('td.filename input:checkbox:checked');
if($selectedFiles.length > 1){
$selectedFiles.parents('tr').fadeTo(250, 0.2);
}
else{
$(this).fadeTo(250, 0.2);
}
},
stop: function(event, ui) {
var $selectedFiles = $('td.filename input:checkbox:checked');
if($selectedFiles.length > 1){
$selectedFiles.parents('tr').fadeTo(250, 1);
}
else{
$(this).fadeTo(250, 1);
}
$('#fileList tr td.filename').addClass('ui-draggable');
}
};
// sane browsers support using the distance option
if ( $('html.ie').length === 0) {
@ -526,6 +543,7 @@ if ( $('html.ie').length === 0) {
}
var folderDropOptions={
hoverClass: "canDrop",
drop: function( event, ui ) {
//don't allow moving a file into a selected folder
if ($(event.target).parents('tr').find('td input:first').prop('checked') === true) {
@ -538,14 +556,21 @@ var folderDropOptions={
$(files).each(function(i,row) {
var dir = $(row).data('dir');
var file = $(row).data('filename');
//slapdash selector, tracking down our original element that the clone budded off of.
var origin = $('tr[data-id=' + $(row).data('origin') + ']');
var td = origin.children('td.filename');
var oldBackgroundImage = td.css('background-image');
td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
$.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: dir+'/'+target }, function(result) {
if (result) {
if (result.status === 'success') {
//recalculate folder size
var oldSize = $('#fileList tr[data-file="'+target+'"]').data('size');
var newSize = oldSize + $('#fileList tr[data-file="'+file+'"]').data('size');
$('#fileList tr[data-file="'+target+'"]').data('size', newSize);
$('#fileList tr[data-file="'+target+'"]').find('td.filesize').text(humanFileSize(newSize));
var oldFile = FileList.findFileEl(target);
var newFile = FileList.findFileEl(file);
var oldSize = oldFile.data('size');
var newSize = oldSize + newFile.data('size');
oldFile.data('size', newSize);
oldFile.find('td.filesize').text(humanFileSize(newSize));
FileList.remove(file);
procesSelection();
@ -558,6 +583,7 @@ var folderDropOptions={
} else {
OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error'));
}
td.css('background-image', oldBackgroundImage);
});
});
},
@ -582,6 +608,11 @@ var crumbDropOptions={
$(files).each(function(i,row) {
var dir = $(row).data('dir');
var file = $(row).data('filename');
//slapdash selector, tracking down our original element that the clone budded off of.
var origin = $('tr[data-id=' + $(row).data('origin') + ']');
var td = origin.children('td.filename');
var oldBackgroundImage = td.css('background-image');
td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
$.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: target }, function(result) {
if (result) {
if (result.status === 'success') {
@ -596,6 +627,7 @@ var crumbDropOptions={
} else {
OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error'));
}
td.css('background-image', oldBackgroundImage);
});
});
},
@ -611,11 +643,12 @@ function procesSelection() {
return el.type==='dir';
});
if (selectedFiles.length === 0 && selectedFolders.length === 0) {
$('#headerName>span.name').text(t('files','Name'));
$('#headerName span.name').text(t('files','Name'));
$('#headerSize').text(t('files','Size'));
$('#modified').text(t('files','Modified'));
$('table').removeClass('multiselect');
$('.selectedActions').hide();
$('#select_all').removeAttr('checked');
}
else {
$('.selectedActions').show();
@ -661,7 +694,8 @@ function getSelectedFilesTrash(property) {
mime:$(element).data('mime'),
type:$(element).data('type'),
size:$(element).data('size'),
etag:$(element).data('etag')
etag:$(element).data('etag'),
origin: $(element).data('id')
};
if (property) {
files.push(file[property]);
@ -718,7 +752,7 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
console.warn('Files.lazyLoadPreview(): missing etag argument');
}
if ( $('#publicUploadButtonMock').length ) {
if ( $('#isPublic').length ) {
urlSpec.t = $('#dirToken').val();
previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec);
} else {
@ -739,7 +773,7 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
}
function getUniqueName(name) {
if ($('tr[data-file="'+name+'"]').exists()) {
if (FileList.findFileEl(name).exists()) {
var parts=name.split('.');
var extension = "";
if (parts.length > 1) {
@ -781,3 +815,4 @@ function onClickBreadcrumb(e) {
FileList.changeDirectory(decodeURIComponent($targetDir));
}
}

7
apps/files/l10n/ak.php Normal file
View File

@ -0,0 +1,7 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("",""),
"_Uploading %n file_::_Uploading %n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=n > 1;";

7
apps/files/l10n/az.php Normal file
View File

@ -0,0 +1,7 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array(""),
"_%n file_::_%n files_" => array(""),
"_Uploading %n file_::_Uploading %n files_" => array("")
);
$PLURAL_FORMS = "nplurals=1; plural=0;";

View File

@ -2,6 +2,7 @@
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("","","",""),
"_%n file_::_%n files_" => array("","","",""),
"_Uploading %n file_::_Uploading %n files_" => array("","","","")
"_Uploading %n file_::_Uploading %n files_" => array("","","",""),
"Error" => "Памылка"
);
$PLURAL_FORMS = "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Název souboru nesmí obsahovat \"/\". Vyberte prosím jiné jméno.",
"The name %s is already used in the folder %s. Please choose a different name." => "Název %s ve složce %s již existuje. Vyberte prosím jiné jméno.",
"Not a valid source" => "Neplatný zdroj",
"Server is not allowed to open URLs, please check the server configuration" => "Server není oprávněn otevírat adresy URL. Ověřte, prosím, konfiguraci serveru.",
"Error while downloading %s to %s" => "Chyba při stahování %s do %s",
"Error when creating the file" => "Chyba při vytváření souboru",
"Folder name cannot be empty." => "Název složky nemůže být prázdný.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} již existuje",
"Could not create file" => "Nepodařilo se vytvořit soubor",
"Could not create folder" => "Nepodařilo se vytvořit složku",
"Error fetching URL" => "Chyba při načítání URL",
"Share" => "Sdílet",
"Delete permanently" => "Trvale odstranit",
"Rename" => "Přejmenovat",

View File

@ -3,6 +3,15 @@ $TRANSLATIONS = array(
"Could not move %s - File with this name already exists" => "Kunne ikke flytte %s - der findes allerede en fil med dette navn",
"Could not move %s" => "Kunne ikke flytte %s",
"File name cannot be empty." => "Filnavnet kan ikke stå tomt.",
"File name must not contain \"/\". Please choose a different name." => "Filnavnet må ikke indeholde \"/\". Vælg venligst et andet navn.",
"The name %s is already used in the folder %s. Please choose a different name." => "Navnet %s er allerede i brug i mappen %s. Vælg venligst et andet navn.",
"Not a valid source" => "Ikke en gyldig kilde",
"Server is not allowed to open URLs, please check the server configuration" => "Server har ikke tilladelse til at åbne URL'er. Kontroller venligst serverens indstillinger",
"Error while downloading %s to %s" => "Fejl ved hentning af %s til %s",
"Error when creating the file" => "Fejl ved oprettelse af fil",
"Folder name cannot be empty." => "Mappenavnet kan ikke være tomt.",
"Folder name must not contain \"/\". Please choose a different name." => "Mappenavnet må ikke indeholde \"/\". Vælg venligst et andet navn.",
"Error when creating the folder" => "Fejl ved oprettelse af mappen",
"Unable to set upload directory." => "Ude af stand til at vælge upload mappe.",
"Invalid Token" => "Ugyldig Token ",
"No file was uploaded. Unknown error" => "Ingen fil blev uploadet. Ukendt fejl.",
@ -23,13 +32,20 @@ $TRANSLATIONS = array(
"Upload cancelled." => "Upload afbrudt.",
"Could not get result from server." => "Kunne ikke hente resultat fra server.",
"File upload is in progress. Leaving the page now will cancel the upload." => "Fil upload kører. Hvis du forlader siden nu, vil uploadet blive annuleret.",
"URL cannot be empty" => "URL kan ikke være tom",
"In the home folder 'Shared' is a reserved filename" => "Navnet 'Shared' er reserveret i hjemmemappen.",
"{new_name} already exists" => "{new_name} eksisterer allerede",
"Could not create file" => "Kunne ikke oprette fil",
"Could not create folder" => "Kunne ikke oprette mappe",
"Error fetching URL" => "Fejl ved URL",
"Share" => "Del",
"Delete permanently" => "Slet permanent",
"Rename" => "Omdøb",
"Pending" => "Afventer",
"Could not rename file" => "Kunne ikke omdøbe filen",
"replaced {new_name} with {old_name}" => "erstattede {new_name} med {old_name}",
"undo" => "fortryd",
"Error deleting file." => "Fejl ved sletnign af fil.",
"_%n folder_::_%n folders_" => array("%n mappe","%n mapper"),
"_%n file_::_%n files_" => array("%n fil","%n filer"),
"{dirs} and {files}" => "{dirs} og {files}",
@ -38,6 +54,8 @@ $TRANSLATIONS = array(
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldigt navn, '\\', '/', '<', '>', ':' | '?', '\"', '', og '*' er ikke tilladt.",
"Your storage is full, files can not be updated or synced anymore!" => "Din opbevaringsplads er fyldt op, filer kan ikke opdateres eller synkroniseres længere!",
"Your storage is almost full ({usedSpacePercent}%)" => "Din opbevaringsplads er næsten fyldt op ({usedSpacePercent}%)",
"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Krypteringsprogrammet er aktiveret, men din nøgle er ikke igangsat. Log venligst ud og ind igen.",
"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Ugyldig privat nøgle for krypteringsprogrammet. Opdater venligst dit kodeord for den private nøgle i dine personlige indstillinger. Det kræves for at få adgang til dine krypterede filer.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Krypteringen blev deaktiveret, men dine filer er stadig krypteret. Gå venligst til dine personlige indstillinger for at dekryptere dine filer. ",
"Your download is being prepared. This might take some time if the files are big." => "Dit download forberedes. Dette kan tage lidt tid ved større filer.",
"Error moving file" => "Fejl ved flytning af fil",
@ -45,6 +63,7 @@ $TRANSLATIONS = array(
"Name" => "Navn",
"Size" => "Størrelse",
"Modified" => "Ændret",
"Invalid folder name. Usage of 'Shared' is reserved." => "Ugyldig mappenavn. 'Shared' er reserveret.",
"%s could not be renamed" => "%s kunne ikke omdøbes",
"Upload" => "Upload",
"File handling" => "Filhåndtering",
@ -56,12 +75,14 @@ $TRANSLATIONS = array(
"Maximum input size for ZIP files" => "Maksimal størrelse på ZIP filer",
"Save" => "Gem",
"New" => "Ny",
"New text file" => "Ny tekstfil",
"Text file" => "Tekstfil",
"New folder" => "Ny Mappe",
"Folder" => "Mappe",
"From link" => "Fra link",
"Deleted files" => "Slettede filer",
"Cancel upload" => "Fortryd upload",
"You dont have permission to upload or create files here" => "Du har ikke tilladelse til at uploade eller oprette filer her",
"Nothing in here. Upload something!" => "Her er tomt. Upload noget!",
"Download" => "Download",
"Delete" => "Slet",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Der Dateiname darf kein \"/\" enthalten. Bitte wähle einen anderen Namen.",
"The name %s is already used in the folder %s. Please choose a different name." => "Der Name %s wird bereits im Ordner %s benutzt. Bitte wähle einen anderen Namen.",
"Not a valid source" => "Keine gültige Quelle",
"Server is not allowed to open URLs, please check the server configuration" => "Dem Server ist das Öffnen von URLs nicht erlaubt, bitte die Serverkonfiguration prüfen",
"Error while downloading %s to %s" => "Fehler beim Herunterladen von %s nach %s",
"Error when creating the file" => "Fehler beim Erstellen der Datei",
"Folder name cannot be empty." => "Der Ordner-Name darf nicht leer sein.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} existiert bereits",
"Could not create file" => "Die Datei konnte nicht erstellt werden",
"Could not create folder" => "Der Ordner konnte nicht erstellt werden",
"Error fetching URL" => "Fehler beim Abrufen der URL",
"Share" => "Teilen",
"Delete permanently" => "Endgültig löschen",
"Rename" => "Umbenennen",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Der Dateiname darf kein \"/\" enthalten. Bitte wählen Sie einen anderen Namen.",
"The name %s is already used in the folder %s. Please choose a different name." => "Der Name %s wird bereits im Ordner %s benutzt. Bitte wählen Sie einen anderen Namen.",
"Not a valid source" => "Keine gültige Quelle",
"Server is not allowed to open URLs, please check the server configuration" => "Dem Server ist das Öffnen von URLs nicht erlaubt, bitte die Serverkonfiguration prüfen",
"Error while downloading %s to %s" => "Fehler beim Herunterladen von %s nach %s",
"Error when creating the file" => "Fehler beim Erstellen der Datei",
"Folder name cannot be empty." => "Der Ordner-Name darf nicht leer sein.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} existiert bereits",
"Could not create file" => "Die Datei konnte nicht erstellt werden",
"Could not create folder" => "Der Ordner konnte nicht erstellt werden",
"Error fetching URL" => "Fehler beim Abrufen der URL",
"Share" => "Teilen",
"Delete permanently" => "Endgültig löschen",
"Rename" => "Umbenennen",

View File

@ -3,6 +3,15 @@ $TRANSLATIONS = array(
"Could not move %s - File with this name already exists" => "Αδυναμία μετακίνησης του %s - υπάρχει ήδη αρχείο με αυτό το όνομα",
"Could not move %s" => "Αδυναμία μετακίνησης του %s",
"File name cannot be empty." => "Το όνομα αρχείου δεν μπορεί να είναι κενό.",
"File name must not contain \"/\". Please choose a different name." => "Το όνομα αρχείου δεν μπορεί να περιέχει \"/\". Παρακαλώ επιλέξτε ένα διαφορετικό όνομα. ",
"The name %s is already used in the folder %s. Please choose a different name." => "Το όνομα %s χρησιμοποιείτε ήδη στον φάκελο %s. Παρακαλώ επιλέξτε ένα άλλο όνομα.",
"Not a valid source" => "Μη έγκυρη πηγή",
"Server is not allowed to open URLs, please check the server configuration" => "Ο διακομιστής δεν επιτρέπεται να ανοίγει URL, παρακαλώ ελέγξτε τις ρυθμίσεις του διακομιστή",
"Error while downloading %s to %s" => "Σφάλμα κατά τη λήψη του %s στο %s",
"Error when creating the file" => "Σφάλμα κατά τη δημιουργία του αρχείου",
"Folder name cannot be empty." => "Το όνομα φακέλου δεν μπορεί να είναι κενό.",
"Folder name must not contain \"/\". Please choose a different name." => "Το όνομα φακέλου δεν μπορεί να περιέχει \"/\". Παρακαλώ επιλέξτε ένα διαφορετικό όνομα. ",
"Error when creating the folder" => "Σφάλμα δημιουργίας φακέλου",
"Unable to set upload directory." => "Αδυναμία ορισμού καταλόγου αποστολής.",
"Invalid Token" => "Μη έγκυρο Token",
"No file was uploaded. Unknown error" => "Δεν ανέβηκε κάποιο αρχείο. Άγνωστο σφάλμα",
@ -14,25 +23,39 @@ $TRANSLATIONS = array(
"Missing a temporary folder" => "Λείπει ο προσωρινός φάκελος",
"Failed to write to disk" => "Αποτυχία εγγραφής στο δίσκο",
"Not enough storage available" => "Μη επαρκής διαθέσιμος αποθηκευτικός χώρος",
"Upload failed. Could not get file info." => "Η φόρτωση απέτυχε. Αδυναμία λήψης πληροφοριών αρχείων.",
"Upload failed. Could not find uploaded file" => "Η φόρτωση απέτυχε. Αδυναμία εύρεσης αρχείου προς φόρτωση.",
"Invalid directory." => "Μη έγκυρος φάκελος.",
"Files" => "Αρχεία",
"Unable to upload {filename} as it is a directory or has 0 bytes" => "Αδυναμία φόρτωσης {filename} καθώς είναι κατάλογος αρχείων ή έχει 0 bytes",
"Not enough space available" => "Δεν υπάρχει αρκετός διαθέσιμος χώρος",
"Upload cancelled." => "Η αποστολή ακυρώθηκε.",
"Could not get result from server." => "Αδυναμία λήψης αποτελέσματος από το διακομιστή.",
"File upload is in progress. Leaving the page now will cancel the upload." => "Η αποστολή του αρχείου βρίσκεται σε εξέλιξη. Το κλείσιμο της σελίδας θα ακυρώσει την αποστολή.",
"URL cannot be empty" => "Η URL δεν πρέπει να είναι κενή",
"In the home folder 'Shared' is a reserved filename" => "Στον αρχικό φάκελο το όνομα 'Shared' διατηρείται από το σύστημα",
"{new_name} already exists" => "{new_name} υπάρχει ήδη",
"Could not create file" => "Αδυναμία δημιουργίας αρχείου",
"Could not create folder" => "Αδυναμία δημιουργίας φακέλου",
"Error fetching URL" => "Σφάλμα φόρτωσης URL",
"Share" => "Διαμοιρασμός",
"Delete permanently" => "Μόνιμη διαγραφή",
"Rename" => "Μετονομασία",
"Pending" => "Εκκρεμεί",
"Could not rename file" => "Αδυναμία μετονομασίας αρχείου",
"replaced {new_name} with {old_name}" => "αντικαταστάθηκε το {new_name} με {old_name}",
"undo" => "αναίρεση",
"Error deleting file." => "Σφάλμα διαγραφής αρχείου.",
"_%n folder_::_%n folders_" => array("%n φάκελος","%n φάκελοι"),
"_%n file_::_%n files_" => array("%n αρχείο","%n αρχεία"),
"{dirs} and {files}" => "{Κατάλογοι αρχείων} και {αρχεία}",
"_Uploading %n file_::_Uploading %n files_" => array("Ανέβασμα %n αρχείου","Ανέβασμα %n αρχείων"),
"'.' is an invalid file name." => "'.' είναι μη έγκυρο όνομα αρχείου.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Μη έγκυρο όνομα, '\\', '/', '<', '>', ':', '\"', '|', '?' και '*' δεν επιτρέπονται.",
"Your storage is full, files can not be updated or synced anymore!" => "Ο αποθηκευτικός σας χώρος είναι γεμάτος, τα αρχεία δεν μπορούν να ενημερωθούν ή να συγχρονιστούν πια!",
"Your storage is almost full ({usedSpacePercent}%)" => "Ο αποθηκευτικός χώρος είναι σχεδόν γεμάτος ({usedSpacePercent}%)",
"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Η εφαρμογή κρυπτογράφησης είναι ενεργοποιημένη αλλά τα κλειδιά σας δεν έχουν καταγραφεί, παρακαλώ αποσυνδεθείτε και επανασυνδεθείτε.",
"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Άκυρο προσωπικό κλειδί για την εφαρμογή κρυπτογράφησης. Παρακαλώ ενημερώστε τον κωδικό του προσωπικού κλειδίου σας στις προσωπικές ρυθμίσεις για να επανακτήσετε πρόσβαση στα κρυπτογραφημένα σας αρχεία.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Η κρυπτογράφηση απενεργοποιήθηκε, αλλά τα αρχεία σας είναι ακόμα κρυπτογραφημένα. Παρακαλούμε απενεργοποιήσετε την κρυπτογράφηση αρχείων από τις προσωπικές σας ρυθμίσεις",
"Your download is being prepared. This might take some time if the files are big." => "Η λήψη προετοιμάζεται. Αυτό μπορεί να πάρει ώρα εάν τα αρχεία έχουν μεγάλο μέγεθος.",
"Error moving file" => "Σφάλμα κατά τη μετακίνηση του αρχείου",
@ -40,6 +63,7 @@ $TRANSLATIONS = array(
"Name" => "Όνομα",
"Size" => "Μέγεθος",
"Modified" => "Τροποποιήθηκε",
"Invalid folder name. Usage of 'Shared' is reserved." => "Άκυρο όνομα φακέλου. Η χρήση του 'Shared' διατηρείται από το σύστημα.",
"%s could not be renamed" => "Αδυναμία μετονομασίας του %s",
"Upload" => "Μεταφόρτωση",
"File handling" => "Διαχείριση αρχείων",
@ -51,12 +75,14 @@ $TRANSLATIONS = array(
"Maximum input size for ZIP files" => "Μέγιστο μέγεθος για αρχεία ZIP",
"Save" => "Αποθήκευση",
"New" => "Νέο",
"New text file" => "Νέο αρχείο κειμένου",
"Text file" => "Αρχείο κειμένου",
"New folder" => "Νέος κατάλογος",
"Folder" => "Φάκελος",
"From link" => "Από σύνδεσμο",
"Deleted files" => "Διαγραμμένα αρχεία",
"Cancel upload" => "Ακύρωση αποστολής",
"You dont have permission to upload or create files here" => "Δεν έχετε δικαιώματα φόρτωσης ή δημιουργίας αρχείων εδώ",
"Nothing in here. Upload something!" => "Δεν υπάρχει τίποτα εδώ. Ανεβάστε κάτι!",
"Download" => "Λήψη",
"Delete" => "Διαγραφή",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "File name must not contain \"/\". Please choose a different name.",
"The name %s is already used in the folder %s. Please choose a different name." => "The name %s is already used in the folder %s. Please choose a different name.",
"Not a valid source" => "Not a valid source",
"Server is not allowed to open URLs, please check the server configuration" => "Server is not allowed to open URLs, please check the server configuration",
"Error while downloading %s to %s" => "Error whilst downloading %s to %s",
"Error when creating the file" => "Error when creating the file",
"Folder name cannot be empty." => "Folder name cannot be empty.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} already exists",
"Could not create file" => "Could not create file",
"Could not create folder" => "Could not create folder",
"Error fetching URL" => "Error fetching URL",
"Share" => "Share",
"Delete permanently" => "Delete permanently",
"Rename" => "Rename",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "El nombre del archivo, NO puede contener el simbolo\"/\", por favor elija un nombre diferente.",
"The name %s is already used in the folder %s. Please choose a different name." => "El nombre %s ya está en uso por la carpeta %s. Por favor elija uno diferente.",
"Not a valid source" => "No es un origen válido",
"Server is not allowed to open URLs, please check the server configuration" => "El servidor no puede acceder URLs; revise la configuración del servidor.",
"Error while downloading %s to %s" => "Error mientras se descargaba %s a %s",
"Error when creating the file" => "Error al crear el archivo",
"Folder name cannot be empty." => "El nombre de la carpeta no puede estar vacío.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} ya existe",
"Could not create file" => "No se pudo crear el archivo",
"Could not create folder" => "No se pudo crear la carpeta",
"Error fetching URL" => "Error al descargar URL.",
"Share" => "Compartir",
"Delete permanently" => "Eliminar permanentemente",
"Rename" => "Renombrar",

View File

@ -0,0 +1,9 @@
<?php
$TRANSLATIONS = array(
"Files" => "Archivos",
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("",""),
"_Uploading %n file_::_Uploading %n files_" => array("",""),
"Upload" => "Subir"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@ -1,7 +1,95 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("",""),
"_Uploading %n file_::_Uploading %n files_" => array("","")
"Could not move %s - File with this name already exists" => "No se pudo mover %s - Ya existe un archivo con ese nombre.",
"Could not move %s" => "No se pudo mover %s",
"File name cannot be empty." => "El nombre de archivo no puede estar vacío.",
"File name must not contain \"/\". Please choose a different name." => "El nombre del archivo, NO puede contener el simbolo\"/\", por favor elija un nombre diferente.",
"The name %s is already used in the folder %s. Please choose a different name." => "El nombre %s ya está en uso por la carpeta %s. Por favor elija uno diferente.",
"Not a valid source" => "No es un origen válido",
"Server is not allowed to open URLs, please check the server configuration" => "El servidor no puede acceder URLs; revise la configuración del servidor.",
"Error while downloading %s to %s" => "Error mientras se descargaba %s a %s",
"Error when creating the file" => "Error al crear el archivo",
"Folder name cannot be empty." => "El nombre de la carpeta no puede estar vacío.",
"Folder name must not contain \"/\". Please choose a different name." => "El nombre de la carpeta, NO puede contener el simbolo\"/\", por favor elija un nombre diferente.",
"Error when creating the folder" => "Error al crear la carpeta.",
"Unable to set upload directory." => "Incapaz de crear directorio de subida.",
"Invalid Token" => "Token Inválido",
"No file was uploaded. Unknown error" => "No se subió ningún archivo. Error desconocido",
"There is no error, the file uploaded with success" => "No hubo ningún problema, el archivo se subió con éxito",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "El archivo subido sobrepasa la directiva 'upload_max_filesize' en php.ini:",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El archivo subido sobrepasa la directiva 'MAX_FILE_SIZE' especificada en el formulario HTML",
"The uploaded file was only partially uploaded" => "El archivo subido fue sólo subido parcialmente",
"No file was uploaded" => "No se subió ningún archivo",
"Missing a temporary folder" => "Falta la carpeta temporal",
"Failed to write to disk" => "Falló al escribir al disco",
"Not enough storage available" => "No hay suficiente espacio disponible",
"Upload failed. Could not get file info." => "Actualización fallida. No se pudo obtener información del archivo.",
"Upload failed. Could not find uploaded file" => "Actualización fallida. No se pudo encontrar el archivo subido",
"Invalid directory." => "Directorio inválido.",
"Files" => "Archivos",
"Unable to upload {filename} as it is a directory or has 0 bytes" => "No ha sido posible subir {filename} porque es un directorio o tiene 0 bytes",
"Not enough space available" => "No hay suficiente espacio disponible",
"Upload cancelled." => "Subida cancelada.",
"Could not get result from server." => "No se pudo obtener respuesta del servidor.",
"File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Si sale de la página ahora, la subida será cancelada.",
"URL cannot be empty" => "La dirección URL no puede estar vacía",
"In the home folder 'Shared' is a reserved filename" => "En la carpeta de inicio, 'Shared' es un nombre reservado",
"{new_name} already exists" => "{new_name} ya existe",
"Could not create file" => "No se pudo crear el archivo",
"Could not create folder" => "No se pudo crear la carpeta",
"Error fetching URL" => "Error al descargar URL.",
"Share" => "Compartir",
"Delete permanently" => "Eliminar permanentemente",
"Rename" => "Renombrar",
"Pending" => "Pendiente",
"Could not rename file" => "No se pudo renombrar el archivo",
"replaced {new_name} with {old_name}" => "reemplazado {new_name} con {old_name}",
"undo" => "deshacer",
"Error deleting file." => "Error borrando el archivo.",
"_%n folder_::_%n folders_" => array("%n carpeta","%n carpetas"),
"_%n file_::_%n files_" => array("%n archivo","%n archivos"),
"{dirs} and {files}" => "{dirs} y {files}",
"_Uploading %n file_::_Uploading %n files_" => array("Subiendo %n archivo","Subiendo %n archivos"),
"'.' is an invalid file name." => "'.' no es un nombre de archivo válido.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nombre inválido, los caracteres \"\\\", \"/\", \"<\", \">\", \":\", \"\", \"|\" \"?\" y \"*\" no están permitidos ",
"Your storage is full, files can not be updated or synced anymore!" => "Su almacenamiento está lleno, ¡los archivos no se actualizarán ni sincronizarán más!",
"Your storage is almost full ({usedSpacePercent}%)" => "Su almacenamiento está casi lleno ({usedSpacePercent}%)",
"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "La aplicación de crifrado está habilitada pero tus claves no han sido inicializadas, por favor, cierra la sesión y vuelva a iniciarla de nuevo.",
"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "La clave privada no es válida para la aplicación de cifrado. Por favor, actualiza la contraseña de tu clave privada en tus ajustes personales para recuperar el acceso a tus archivos cifrados.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "El cifrado ha sido deshabilitado pero tus archivos permanecen cifrados. Por favor, ve a tus ajustes personales para descifrar tus archivos.",
"Your download is being prepared. This might take some time if the files are big." => "Su descarga está siendo preparada. Esto podría tardar algo de tiempo si los archivos son grandes.",
"Error moving file" => "Error moviendo archivo",
"Error" => "Error",
"Name" => "Nombre",
"Size" => "Tamaño",
"Modified" => "Modificado",
"Invalid folder name. Usage of 'Shared' is reserved." => "Nombre de carpeta inválido. El uso de \"Shared\" esta reservado.",
"%s could not be renamed" => "%s no pudo ser renombrado",
"Upload" => "Subir",
"File handling" => "Administración de archivos",
"Maximum upload size" => "Tamaño máximo de subida",
"max. possible: " => "máx. posible:",
"Needed for multi-file and folder downloads." => "Necesario para multi-archivo y descarga de carpetas",
"Enable ZIP-download" => "Habilitar descarga en ZIP",
"0 is unlimited" => "0 significa ilimitado",
"Maximum input size for ZIP files" => "Tamaño máximo para archivos ZIP de entrada",
"Save" => "Guardar",
"New" => "Nuevo",
"New text file" => "Nuevo archivo de texto",
"Text file" => "Archivo de texto",
"New folder" => "Nueva carpeta",
"Folder" => "Carpeta",
"From link" => "Desde enlace",
"Deleted files" => "Archivos eliminados",
"Cancel upload" => "Cancelar subida",
"You dont have permission to upload or create files here" => "No tienes permisos para subir o crear archivos aquí.",
"Nothing in here. Upload something!" => "No hay nada aquí. ¡Suba algo!",
"Download" => "Descargar",
"Delete" => "Eliminar",
"Upload too large" => "Subida demasido grande",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los archivos que estás intentando subir sobrepasan el tamaño máximo permitido en este servidor.",
"Files are being scanned, please wait." => "Los archivos están siendo escaneados, por favor espere.",
"Current scanning" => "Escaneo actual",
"Upgrading filesystem cache..." => "Actualizando caché del sistema de archivos..."
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Faili nimi ei tohi sisaldada \"/\". Palun vali mõni teine nimi.",
"The name %s is already used in the folder %s. Please choose a different name." => "Nimi %s on juba kasutusel kataloogis %s. Palun vali mõni teine nimi.",
"Not a valid source" => "Pole korrektne lähteallikas",
"Server is not allowed to open URLs, please check the server configuration" => "Server ei võimalda URL-ide avamist, palun kontrolli serveri seadistust",
"Error while downloading %s to %s" => "Viga %s allalaadimisel %s",
"Error when creating the file" => "Viga faili loomisel",
"Folder name cannot be empty." => "Kataloogi nimi ei saa olla tühi.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} on juba olemas",
"Could not create file" => "Ei suuda luua faili",
"Could not create folder" => "Ei suuda luua kataloogi",
"Error fetching URL" => "Viga URL-i haaramisel",
"Share" => "Jaga",
"Delete permanently" => "Kustuta jäädavalt",
"Rename" => "Nimeta ümber",

View File

@ -3,6 +3,14 @@ $TRANSLATIONS = array(
"Could not move %s - File with this name already exists" => "Ezin da %s mugitu - Izen hau duen fitxategia dagoeneko existitzen da",
"Could not move %s" => "Ezin dira fitxategiak mugitu %s",
"File name cannot be empty." => "Fitxategi izena ezin da hutsa izan.",
"File name must not contain \"/\". Please choose a different name." => "Fitxategi izenak ezin du \"/\" izan. Mesedez hautatu beste izen bat.",
"The name %s is already used in the folder %s. Please choose a different name." => "%s izena dagoeneko erabilita dago %s karpetan. Mesdez hautatu izen ezberdina.",
"Not a valid source" => "Ez da jatorri baliogarria",
"Error while downloading %s to %s" => "Errorea %s %sra deskargatzerakoan",
"Error when creating the file" => "Errorea fitxategia sortzerakoan",
"Folder name cannot be empty." => "Karpeta izena ezin da hutsa izan.",
"Folder name must not contain \"/\". Please choose a different name." => "Karpeta izenak ezin du \"/\" izan. Mesedez hautatu beste izen bat.",
"Error when creating the folder" => "Errorea karpeta sortzerakoan",
"Unable to set upload directory." => "Ezin da igoera direktorioa ezarri.",
"Invalid Token" => "Lekuko baliogabea",
"No file was uploaded. Unknown error" => "Ez da fitxategirik igo. Errore ezezaguna",
@ -23,13 +31,19 @@ $TRANSLATIONS = array(
"Upload cancelled." => "Igoera ezeztatuta",
"Could not get result from server." => "Ezin da zerbitzaritik emaitzik lortu",
"File upload is in progress. Leaving the page now will cancel the upload." => "Fitxategien igoera martxan da. Orria orain uzteak igoera ezeztatutko du.",
"URL cannot be empty" => "URLa ezin da hutsik egon",
"In the home folder 'Shared' is a reserved filename" => "Etxeko (home) karpetan 'Shared' erreserbatutako fitxategi izena da",
"{new_name} already exists" => "{new_name} dagoeneko existitzen da",
"Could not create file" => "Ezin izan da fitxategia sortu",
"Could not create folder" => "Ezin izan da karpeta sortu",
"Share" => "Elkarbanatu",
"Delete permanently" => "Ezabatu betirako",
"Rename" => "Berrizendatu",
"Pending" => "Zain",
"Could not rename file" => "Ezin izan da fitxategia berrizendatu",
"replaced {new_name} with {old_name}" => " {new_name}-k {old_name} ordezkatu du",
"undo" => "desegin",
"Error deleting file." => "Errorea fitxategia ezabatzerakoan.",
"_%n folder_::_%n folders_" => array("karpeta %n","%n karpeta"),
"_%n file_::_%n files_" => array("fitxategi %n","%n fitxategi"),
"{dirs} and {files}" => "{dirs} eta {files}",
@ -47,6 +61,7 @@ $TRANSLATIONS = array(
"Name" => "Izena",
"Size" => "Tamaina",
"Modified" => "Aldatuta",
"Invalid folder name. Usage of 'Shared' is reserved." => "Baliogabeako karpeta izena. 'Shared' izena erreserbatuta dago.",
"%s could not be renamed" => "%s ezin da berrizendatu",
"Upload" => "Igo",
"File handling" => "Fitxategien kudeaketa",
@ -58,12 +73,14 @@ $TRANSLATIONS = array(
"Maximum input size for ZIP files" => "ZIP fitxategien gehienezko tamaina",
"Save" => "Gorde",
"New" => "Berria",
"New text file" => "Testu fitxategi berria",
"Text file" => "Testu fitxategia",
"New folder" => "Karpeta berria",
"Folder" => "Karpeta",
"From link" => "Estekatik",
"Deleted files" => "Ezabatutako fitxategiak",
"Cancel upload" => "Ezeztatu igoera",
"You dont have permission to upload or create files here" => "Ez duzu fitxategiak hona igotzeko edo hemen sortzeko baimenik",
"Nothing in here. Upload something!" => "Ez dago ezer. Igo zerbait!",
"Download" => "Deskargatu",
"Delete" => "Ezabatu",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Tiedoston nimessä ei saa olla merkkiä \"/\". Valitse toinen nimi.",
"The name %s is already used in the folder %s. Please choose a different name." => "Nimi %s on jo käytössä kansiossa %s. Valitse toinen nimi.",
"Not a valid source" => "Virheellinen lähde",
"Server is not allowed to open URLs, please check the server configuration" => "Palvelimen ei ole lupa avata verkko-osoitteita. Tarkista palvelimen asetukset",
"Error while downloading %s to %s" => "Virhe ladatessa kohdetta %s sijaintiin %s",
"Error when creating the file" => "Virhe tiedostoa luotaessa",
"Folder name cannot be empty." => "Kansion nimi ei voi olla tyhjä.",
@ -32,6 +33,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} on jo olemassa",
"Could not create file" => "Tiedoston luominen epäonnistui",
"Could not create folder" => "Kansion luominen epäonnistui",
"Error fetching URL" => "Virhe noutaessa verkko-osoitetta",
"Share" => "Jaa",
"Delete permanently" => "Poista pysyvästi",
"Rename" => "Nimeä uudelleen",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Le nom de fichier ne doit pas contenir \"/\". Merci de choisir un nom différent.",
"The name %s is already used in the folder %s. Please choose a different name." => "Le nom %s est déjà utilisé dans le dossier %s. Merci de choisir un nom différent.",
"Not a valid source" => "La source n'est pas valide",
"Server is not allowed to open URLs, please check the server configuration" => "Le serveur n'est pas autorisé à ouvrir des URL, veuillez vérifier la configuration du serveur",
"Error while downloading %s to %s" => "Erreur pendant le téléchargement de %s à %s",
"Error when creating the file" => "Erreur pendant la création du fichier",
"Folder name cannot be empty." => "Le nom de dossier ne peux pas être vide.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} existe déjà",
"Could not create file" => "Impossible de créer le fichier",
"Could not create folder" => "Impossible de créer le dossier",
"Error fetching URL" => "Erreur d'accès à l'URL",
"Share" => "Partager",
"Delete permanently" => "Supprimer de façon définitive",
"Rename" => "Renommer",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "O nome do ficheiro non pode conter «/». Escolla outro nome.",
"The name %s is already used in the folder %s. Please choose a different name." => "Xa existe o nome %s no cartafol %s. Escolla outro nome.",
"Not a valid source" => "Esta orixe non é correcta",
"Server is not allowed to open URLs, please check the server configuration" => "O servidor non ten permisos para abrir os enderezos URL, comprobe a configuración do servidor",
"Error while downloading %s to %s" => "Produciuse un erro ao descargar %s en %s",
"Error when creating the file" => "Produciuse un erro ao crear o ficheiro",
"Folder name cannot be empty." => "O nome de cartafol non pode estar baleiro.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "Xa existe un {new_name}",
"Could not create file" => "Non foi posíbel crear o ficheiro",
"Could not create folder" => "Non foi posíbel crear o cartafol",
"Error fetching URL" => "Produciuse un erro ao obter o URL",
"Share" => "Compartir",
"Delete permanently" => "Eliminar permanentemente",
"Rename" => "Renomear",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Az állomány neve nem tartalmazhatja a \"/\" karaktert. Kérem válasszon másik nevet!",
"The name %s is already used in the folder %s. Please choose a different name." => "A %s név már létezik a %s mappában. Kérem válasszon másik nevet!",
"Not a valid source" => "A kiinduló állomány érvénytelen",
"Server is not allowed to open URLs, please check the server configuration" => "A kiszolgálón nincs engedélyezve URL-ek megnyitása, kérem ellenőrizze a beállításokat",
"Error while downloading %s to %s" => "Hiba történt miközben %s-t letöltöttük %s-be",
"Error when creating the file" => "Hiba történt az állomány létrehozásakor",
"Folder name cannot be empty." => "A mappa neve nem maradhat kitöltetlenül",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} már létezik",
"Could not create file" => "Az állomány nem hozható létre",
"Could not create folder" => "A mappa nem hozható létre",
"Error fetching URL" => "A megadott URL-ről nem sikerül adatokat kapni",
"Share" => "Megosztás",
"Delete permanently" => "Végleges törlés",
"Rename" => "Átnevezés",
@ -43,6 +45,7 @@ $TRANSLATIONS = array(
"Could not rename file" => "Az állomány nem nevezhető át",
"replaced {new_name} with {old_name}" => "{new_name} fájlt kicseréltük ezzel: {old_name}",
"undo" => "visszavonás",
"Error deleting file." => "Hiba a file törlése közben.",
"_%n folder_::_%n folders_" => array("%n mappa","%n mappa"),
"_%n file_::_%n files_" => array("%n állomány","%n állomány"),
"{dirs} and {files}" => "{dirs} és {files}",
@ -72,6 +75,7 @@ $TRANSLATIONS = array(
"Maximum input size for ZIP files" => "ZIP-fájlok maximális kiindulási mérete",
"Save" => "Mentés",
"New" => "Új",
"New text file" => "Új szöveges file",
"Text file" => "Szövegfájl",
"New folder" => "Új mappa",
"Folder" => "Mappa",

View File

@ -3,6 +3,16 @@ $TRANSLATIONS = array(
"Could not move %s - File with this name already exists" => "Tidak dapat memindahkan %s - Berkas dengan nama ini sudah ada",
"Could not move %s" => "Tidak dapat memindahkan %s",
"File name cannot be empty." => "Nama berkas tidak boleh kosong.",
"File name must not contain \"/\". Please choose a different name." => "Nama berkas tidak boleh mengandung \"/\". Silakan pilih nama yang berbeda.",
"The name %s is already used in the folder %s. Please choose a different name." => "Nama %s sudah digunakan dalam folder %s. Silakan pilih nama yang berbeda.",
"Not a valid source" => "Sumber tidak sah",
"Error while downloading %s to %s" => "Galat saat mengunduh %s ke %s",
"Error when creating the file" => "Galat saat membuat berkas",
"Folder name cannot be empty." => "Nama folder tidak bolh kosong.",
"Folder name must not contain \"/\". Please choose a different name." => "Nama folder tidak boleh mengandung \"/\". Silakan pilih nama yang berbeda.",
"Error when creating the folder" => "Galat saat membuat folder",
"Unable to set upload directory." => "Tidak dapat mengatur folder unggah",
"Invalid Token" => "Token tidak sah",
"No file was uploaded. Unknown error" => "Tidak ada berkas yang diunggah. Galat tidak dikenal.",
"There is no error, the file uploaded with success" => "Tidak ada galat, berkas sukses diunggah",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Berkas yang diunggah melampaui direktif upload_max_filesize pada php.ini",
@ -12,30 +22,47 @@ $TRANSLATIONS = array(
"Missing a temporary folder" => "Folder sementara tidak ada",
"Failed to write to disk" => "Gagal menulis ke disk",
"Not enough storage available" => "Ruang penyimpanan tidak mencukupi",
"Upload failed. Could not get file info." => "Unggah gagal. Tidak mendapatkan informasi berkas.",
"Upload failed. Could not find uploaded file" => "Unggah gagal. Tidak menemukan berkas yang akan diunggah",
"Invalid directory." => "Direktori tidak valid.",
"Files" => "Berkas",
"Unable to upload {filename} as it is a directory or has 0 bytes" => "Tidak dapat mengunggah {filename} karena ini sebuah direktori atau memiliki ukuran 0 byte",
"Not enough space available" => "Ruang penyimpanan tidak mencukupi",
"Upload cancelled." => "Pengunggahan dibatalkan.",
"Could not get result from server." => "Tidak mendapatkan hasil dari server.",
"File upload is in progress. Leaving the page now will cancel the upload." => "Berkas sedang diunggah. Meninggalkan halaman ini akan membatalkan proses.",
"URL cannot be empty" => "URL tidak boleh kosong",
"In the home folder 'Shared' is a reserved filename" => "Pada folder home, 'Shared' adalah nama berkas yang sudah digunakan",
"{new_name} already exists" => "{new_name} sudah ada",
"Could not create file" => "Tidak dapat membuat berkas",
"Could not create folder" => "Tidak dapat membuat folder",
"Share" => "Bagikan",
"Delete permanently" => "Hapus secara permanen",
"Rename" => "Ubah nama",
"Pending" => "Menunggu",
"Could not rename file" => "Tidak dapat mengubah nama berkas",
"replaced {new_name} with {old_name}" => "mengganti {new_name} dengan {old_name}",
"undo" => "urungkan",
"_%n folder_::_%n folders_" => array(""),
"_%n file_::_%n files_" => array(""),
"_Uploading %n file_::_Uploading %n files_" => array(""),
"Error deleting file." => "Galat saat menghapus berkas.",
"_%n folder_::_%n folders_" => array("%n folder"),
"_%n file_::_%n files_" => array("%n berkas"),
"{dirs} and {files}" => "{dirs} dan {files}",
"_Uploading %n file_::_Uploading %n files_" => array("Mengunggah %n berkas"),
"'.' is an invalid file name." => "'.' bukan nama berkas yang valid.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nama tidak valid, karakter '\\', '/', '<', '>', ':', '\"', '|', '?' dan '*' tidak diizinkan.",
"Your storage is full, files can not be updated or synced anymore!" => "Ruang penyimpanan Anda penuh, berkas tidak dapat diperbarui atau disinkronkan lagi!",
"Your storage is almost full ({usedSpacePercent}%)" => "Ruang penyimpanan hampir penuh ({usedSpacePercent}%)",
"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Aplikasi Enskripsi telah diaktifkan tetapi kunci tidak diinisialisasi, silakan log-out dan log-in lagi",
"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Kunci privat tidak sah untuk Aplikasi Enskripsi. Silakan perbarui sandi kunci privat anda pada pengaturan pribadi untuk memulihkan akses ke berkas anda yang dienskripsi.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Enskripi telah dinonaktifkan tetapi berkas anda tetap dienskripsi. Silakan menuju ke pengaturan pribadi untuk deskrip berkas anda.",
"Your download is being prepared. This might take some time if the files are big." => "Unduhan Anda sedang disiapkan. Prosesnya dapat berlangsung agak lama jika ukuran berkasnya besar.",
"Error moving file" => "Galat saat memindahkan berkas",
"Error" => "Galat",
"Name" => "Nama",
"Size" => "Ukuran",
"Modified" => "Dimodifikasi",
"Invalid folder name. Usage of 'Shared' is reserved." => "Nama folder tidak sah. Menggunakan 'Shared' sudah digunakan.",
"%s could not be renamed" => "%s tidak dapat diubah nama",
"Upload" => "Unggah",
"File handling" => "Penanganan berkas",
"Maximum upload size" => "Ukuran pengunggahan maksimum",
@ -46,12 +73,14 @@ $TRANSLATIONS = array(
"Maximum input size for ZIP files" => "Ukuran masukan maksimum untuk berkas ZIP",
"Save" => "Simpan",
"New" => "Baru",
"New text file" => "Berkas teks baru",
"Text file" => "Berkas teks",
"New folder" => "Map baru",
"Folder" => "Folder",
"From link" => "Dari tautan",
"Deleted files" => "Berkas yang dihapus",
"Cancel upload" => "Batal pengunggahan",
"You dont have permission to upload or create files here" => "Anda tidak memiliki akses untuk mengunggah atau membuat berkas disini",
"Nothing in here. Upload something!" => "Tidak ada apa-apa di sini. Unggah sesuatu!",
"Download" => "Unduh",
"Delete" => "Hapus",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Il nome del file non può contenere il carattere \"/\". Scegli un nome diverso.",
"The name %s is already used in the folder %s. Please choose a different name." => "Il nome %s è attualmente in uso nella cartella %s. Scegli un nome diverso.",
"Not a valid source" => "Non è una sorgente valida",
"Server is not allowed to open URLs, please check the server configuration" => "Al server non è permesso aprire URL, controlla la configurazione del server",
"Error while downloading %s to %s" => "Errore durante lo scaricamento di %s su %s",
"Error when creating the file" => "Errore durante la creazione del file",
"Folder name cannot be empty." => "Il nome della cartella non può essere vuoto.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} esiste già",
"Could not create file" => "Impossibile creare il file",
"Could not create folder" => "Impossibile creare la cartella",
"Error fetching URL" => "Errore durante il recupero dello URL",
"Share" => "Condividi",
"Delete permanently" => "Elimina definitivamente",
"Rename" => "Rinomina",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "ファイル名には \"/\" を含めることはできません。別の名前を選択してください。",
"The name %s is already used in the folder %s. Please choose a different name." => "%s はフォルダ %s ないですでに使われています。別の名前を選択してください。",
"Not a valid source" => "有効なソースではありません",
"Server is not allowed to open URLs, please check the server configuration" => "サーバーは、URLを開くことは許されません。サーバーの設定をチェックしてください。",
"Error while downloading %s to %s" => "%s から %s へのダウンロードエラー",
"Error when creating the file" => "ファイルの生成エラー",
"Folder name cannot be empty." => "フォルダ名は空にできません",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} はすでに存在しています",
"Could not create file" => "ファイルを作成できませんでした",
"Could not create folder" => "フォルダを作成できませんでした",
"Error fetching URL" => "URL取得エラー",
"Share" => "共有",
"Delete permanently" => "完全に削除する",
"Rename" => "名前の変更",
@ -73,6 +75,7 @@ $TRANSLATIONS = array(
"Maximum input size for ZIP files" => "ZIPファイルへの最大入力サイズ",
"Save" => "保存",
"New" => "新規作成",
"New text file" => "新規のテキストファイル作成",
"Text file" => "テキストファイル",
"New folder" => "新しいフォルダ",
"Folder" => "フォルダ",

View File

@ -1,11 +1,20 @@
<?php
$TRANSLATIONS = array(
"Could not move %s - File with this name already exists" => "%s 항목을 이동시키지 못하였음 - 파일 이름이 이미 존재함",
"Could not move %s" => "%s 항목을 이딩시키지 못하였",
"Could not move %s - File with this name already exists" => "항목 %s을(를) 이동시킬 수 없음 - 같은 이름의 파일이 이미 존재함",
"Could not move %s" => "항목 %s을(를) 이동시킬 수 없",
"File name cannot be empty." => "파일 이름이 비어 있을 수 없습니다.",
"Unable to set upload directory." => "업로드 디렉터리를 정할수 없습니다",
"File name must not contain \"/\". Please choose a different name." => "파일 이름에는 \"/\"가 들어갈 수 없습니다. 다른 이름을 사용하십시오.",
"The name %s is already used in the folder %s. Please choose a different name." => "이름 %s이(가) 폴더 %s에서 이미 사용 중입니다. 다른 이름을 사용하십시오.",
"Not a valid source" => "올바르지 않은 원본",
"Server is not allowed to open URLs, please check the server configuration" => "서버에서 URL을 열 수 없습니다. 서버 설정을 확인하십시오",
"Error while downloading %s to %s" => "%s을(를) %s(으)로 다운로드하는 중 오류 발생",
"Error when creating the file" => "파일 생성 중 오류 발생",
"Folder name cannot be empty." => "폴더 이름이 비어있을 수 없습니다.",
"Folder name must not contain \"/\". Please choose a different name." => "폴더 이름에는 \"/\"가 들어갈 수 없습니다. 다른 이름을 사용하십시오.",
"Error when creating the folder" => "폴더 생성 중 오류 발생",
"Unable to set upload directory." => "업로드 디렉터리를 설정할 수 없습니다.",
"Invalid Token" => "잘못된 토큰",
"No file was uploaded. Unknown error" => "파일이 업로드되지 않았습니다. 알 수 없는 오류입니다",
"No file was uploaded. Unknown error" => "파일이 업로드 되지 않았습니다. 알 수 없는 오류입니다",
"There is no error, the file uploaded with success" => "파일 업로드에 성공하였습니다.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "업로드한 파일이 php.ini의 upload_max_filesize보다 큽니다:",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "업로드한 파일 크기가 HTML 폼의 MAX_FILE_SIZE보다 큼",
@ -14,38 +23,48 @@ $TRANSLATIONS = array(
"Missing a temporary folder" => "임시 폴더가 없음",
"Failed to write to disk" => "디스크에 쓰지 못했습니다",
"Not enough storage available" => "저장소가 용량이 충분하지 않습니다.",
"Upload failed. Could not get file info." => "업로드에 실패했습니다. 파일 정보를 가져올수 없습니다.",
"Upload failed. Could not find uploaded file" => "업로드에 실패했습니다. 업로드할 파일을 찾을수 없습니다",
"Upload failed. Could not get file info." => "업로드에 실패했습니다. 파일 정보를 가져올 수 없습니다.",
"Upload failed. Could not find uploaded file" => "업로드에 실패했습니다. 업로드할 파일을 찾을 수 없습니다",
"Invalid directory." => "올바르지 않은 디렉터리입니다.",
"Files" => "파일",
"Unable to upload {filename} as it is a directory or has 0 bytes" => "{filename}을 업로드 할수 없습니다. 폴더이거나 0 바이트 파일입니다.",
"Unable to upload {filename} as it is a directory or has 0 bytes" => "{filename}을(를) 업로드할 수 없습니다. 폴더이거나 0 바이트 파일입니다.",
"Not enough space available" => "여유 공간이 부족합니다",
"Upload cancelled." => "업로드가 취소되었습니다.",
"Could not get result from server." => "서버에서 결과를 가져올수 없습니다.",
"Could not get result from server." => "서버에서 결과를 가져올 수 없습니다.",
"File upload is in progress. Leaving the page now will cancel the upload." => "파일 업로드가 진행 중입니다. 이 페이지를 벗어나면 업로드가 취소됩니다.",
"URL cannot be empty" => "URL이 비어있을 수 없음",
"In the home folder 'Shared' is a reserved filename" => "'공유됨'은 홈 폴더의 예약된 파일 이름임",
"{new_name} already exists" => "{new_name}이(가) 이미 존재함",
"Could not create file" => "파일을 만들 수 없음",
"Could not create folder" => "폴더를 만들 수 없음",
"Error fetching URL" => "URL을 가져올 수 없음",
"Share" => "공유",
"Delete permanently" => "영원히 삭제",
"Delete permanently" => "히 삭제",
"Rename" => "이름 바꾸기",
"Pending" => "대기 중",
"Could not rename file" => "이름을 변경할 수 없음",
"replaced {new_name} with {old_name}" => "{old_name}이(가) {new_name}(으)로 대체됨",
"undo" => "되돌리기",
"_%n folder_::_%n folders_" => array("폴더 %n"),
"_%n file_::_%n files_" => array("파일 %n 개"),
"undo" => "실행 취소",
"Error deleting file." => "파일 삭제 오류.",
"_%n folder_::_%n folders_" => array("폴더 %n개"),
"_%n file_::_%n files_" => array("파일 %n개"),
"{dirs} and {files}" => "{dirs} 그리고 {files}",
"_Uploading %n file_::_Uploading %n files_" => array("%n 의 파일을 업로드중"),
"'.' is an invalid file name." => "'.' 는 올바르지 않은 파일 이름 입니다.",
"_Uploading %n file_::_Uploading %n files_" => array("파일 %n개 업로드 "),
"'.' is an invalid file name." => "'.' 는 올바르지 않은 파일 이름입니다.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "폴더 이름이 올바르지 않습니다. 이름에 문자 '\\', '/', '<', '>', ':', '\"', '|', '? ', '*'는 사용할 수 없습니다.",
"Your storage is full, files can not be updated or synced anymore!" => "저장 공간이 가득 찼습니다. 파일을 업데이트하거나 동기화할 수 없습니다!",
"Your storage is almost full ({usedSpacePercent}%)" => "저장 공간이 거의 가득 찼습니다 ({usedSpacePercent}%)",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "암호화는 해제되어 있지만, 파일은 아직 암호화 되어 있습니다. 개인 설저에 가셔서 암호를 해제하십시오",
"Your download is being prepared. This might take some time if the files are big." => "다운로드가 준비 중입니다. 파일 크기가 크다면 시간이 오래 걸릴 수도 있습니다.",
"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "암호화 앱이 활성화되어 있지만 키가 초기화되지 않았습니다. 로그아웃한 후 다시 로그인하십시오",
"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "암호화 앱의 개인 키가 잘못되었습니다. 암호화된 파일에 다시 접근하려면 개인 설정에서 개인 키 암호를 업데이트해야 합니다.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "암호화는 해제되어 있지만, 파일은 아직 암호화되어 있습니다. 개인 설정에서 파일을 복호화하십시오.",
"Your download is being prepared. This might take some time if the files are big." => "다운로드 준비 중입니다. 파일 크기가 크면 시간이 오래 걸릴 수도 있습니다.",
"Error moving file" => "파일 이동 오류",
"Error" => "오류",
"Name" => "이름",
"Size" => "크기",
"Modified" => "수정됨",
"%s could not be renamed" => "%s 의 이름을 변경할수 없습니다",
"Invalid folder name. Usage of 'Shared' is reserved." => "폴더 이름이 잘못되었습니다. '공유됨'은 예약된 폴더 이름입니다.",
"%s could not be renamed" => "%s의 이름을 변경할 수 없습니다",
"Upload" => "업로드",
"File handling" => "파일 처리",
"Maximum upload size" => "최대 업로드 크기",
@ -56,12 +75,14 @@ $TRANSLATIONS = array(
"Maximum input size for ZIP files" => "ZIP 파일 최대 크기",
"Save" => "저장",
"New" => "새로 만들기",
"New text file" => "새 텍스트 파일",
"Text file" => "텍스트 파일",
"New folder" => "새 폴더",
"Folder" => "폴더",
"From link" => "링크에서",
"Deleted files" => "파일 삭제됨",
"Deleted files" => "삭제된 파일",
"Cancel upload" => "업로드 취소",
"You dont have permission to upload or create files here" => "여기에 파일을 업로드하거나 만들 권한이 없습니다",
"Nothing in here. Upload something!" => "내용이 없습니다. 업로드할 수 있습니다!",
"Download" => "다운로드",
"Delete" => "삭제",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "De bestandsnaam mag geen \"/\" bevatten. Kies een andere naam.",
"The name %s is already used in the folder %s. Please choose a different name." => "De naam %s bestaat al in map %s. Kies een andere naam.",
"Not a valid source" => "Geen geldige bron",
"Server is not allowed to open URLs, please check the server configuration" => "Server mag geen URS's openen, controleer de server configuratie",
"Error while downloading %s to %s" => "Fout bij downloaden %s naar %s",
"Error when creating the file" => "Fout bij creëren bestand",
"Folder name cannot be empty." => "Mapnaam mag niet leeg zijn.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} bestaat al",
"Could not create file" => "Kon bestand niet creëren",
"Could not create folder" => "Kon niet creëren map",
"Error fetching URL" => "Fout bij ophalen URL",
"Share" => "Delen",
"Delete permanently" => "Verwijder definitief",
"Rename" => "Hernoem",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Nazwa pliku nie może zawierać \"/\". Proszę wybrać inną nazwę.",
"The name %s is already used in the folder %s. Please choose a different name." => "Nazwa %s jest już używana w folderze %s. Proszę wybrać inną nazwę.",
"Not a valid source" => "Niepoprawne źródło",
"Server is not allowed to open URLs, please check the server configuration" => "Serwer nie mógł otworzyć adresów URL, należy sprawdzić konfigurację serwera",
"Error while downloading %s to %s" => "Błąd podczas pobierania %s do %S",
"Error when creating the file" => "Błąd przy tworzeniu pliku",
"Folder name cannot be empty." => "Nazwa folderu nie może być pusta.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} już istnieje",
"Could not create file" => "Nie można utworzyć pliku",
"Could not create folder" => "Nie można utworzyć folderu",
"Error fetching URL" => "Błąd przy pobieraniu adresu URL",
"Share" => "Udostępnij",
"Delete permanently" => "Trwale usuń",
"Rename" => "Zmień nazwę",
@ -43,9 +45,10 @@ $TRANSLATIONS = array(
"Could not rename file" => "Nie można zmienić nazwy pliku",
"replaced {new_name} with {old_name}" => "zastąpiono {new_name} przez {old_name}",
"undo" => "cofnij",
"Error deleting file." => "Błąd podczas usuwania pliku",
"_%n folder_::_%n folders_" => array("%n katalog","%n katalogi","%n katalogów"),
"_%n file_::_%n files_" => array("%n plik","%n pliki","%n plików"),
"{dirs} and {files}" => "{katalogi} and {pliki}",
"{dirs} and {files}" => "{dirs} and {files}",
"_Uploading %n file_::_Uploading %n files_" => array("Wysyłanie %n pliku","Wysyłanie %n plików","Wysyłanie %n plików"),
"'.' is an invalid file name." => "„.” jest nieprawidłową nazwą pliku.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nieprawidłowa nazwa. Znaki '\\', '/', '<', '>', ':', '\"', '|', '?' oraz '*' są niedozwolone.",
@ -72,6 +75,7 @@ $TRANSLATIONS = array(
"Maximum input size for ZIP files" => "Maksymalna wielkość pliku wejściowego ZIP ",
"Save" => "Zapisz",
"New" => "Nowy",
"New text file" => "Nowy plik tekstowy",
"Text file" => "Plik tekstowy",
"New folder" => "Nowy folder",
"Folder" => "Folder",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "O nome do arquivo não deve conter \"/\". Por favor, escolha um nome diferente.",
"The name %s is already used in the folder %s. Please choose a different name." => "O nome %s já é usado na pasta %s. Por favor, escolha um nome diferente.",
"Not a valid source" => "Não é uma fonte válida",
"Server is not allowed to open URLs, please check the server configuration" => "Não é permitido ao servidor abrir URLs, por favor verificar a configuração do servidor.",
"Error while downloading %s to %s" => "Erro ao baixar %s para %s",
"Error when creating the file" => "Erro ao criar o arquivo",
"Folder name cannot be empty." => "O nome da pasta não pode estar vazio.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} já existe",
"Could not create file" => "Não foi possível criar o arquivo",
"Could not create folder" => "Não foi possível criar a pasta",
"Error fetching URL" => "Erro ao buscar URL",
"Share" => "Compartilhar",
"Delete permanently" => "Excluir permanentemente",
"Rename" => "Renomear",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Имя файла не должно содержать символ \"/\". Пожалуйста, выберите другое имя.",
"The name %s is already used in the folder %s. Please choose a different name." => "Имя %s уже используется в папке %s. Пожалуйста выберите другое имя.",
"Not a valid source" => "Неправильный источник",
"Server is not allowed to open URLs, please check the server configuration" => "Сервер не позволяет открывать URL-адреса, пожалуйста, проверьте настройки сервера",
"Error while downloading %s to %s" => "Ошибка при загрузке %s в %s",
"Error when creating the file" => "Ошибка при создании файла",
"Folder name cannot be empty." => "Имя папки не может быть пустым.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} уже существует",
"Could not create file" => "Не удалось создать файл",
"Could not create folder" => "Не удалось создать папку",
"Error fetching URL" => "Ошибка получения URL",
"Share" => "Открыть доступ",
"Delete permanently" => "Удалено навсегда",
"Rename" => "Переименовать",

View File

@ -1,20 +0,0 @@
<?php
$TRANSLATIONS = array(
"File name cannot be empty." => "Имя файла не может быть пустым.",
"Files" => "Файлы",
"Share" => "Сделать общим",
"Rename" => "Переименовать",
"_%n folder_::_%n folders_" => array("","",""),
"_%n file_::_%n files_" => array("","",""),
"_Uploading %n file_::_Uploading %n files_" => array("","",""),
"'.' is an invalid file name." => "'.' является неверным именем файла.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Некорректное имя, '\\', '/', '<', '>', ':', '\"', '|', '?' и '*' не допустимы.",
"Error" => "Ошибка",
"Size" => "Размер",
"Upload" => "Загрузка",
"Save" => "Сохранить",
"Cancel upload" => "Отмена загрузки",
"Download" => "Загрузка",
"Delete" => "Удалить"
);
$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";

View File

@ -1,7 +1,11 @@
<?php
$TRANSLATIONS = array(
"Share" => "Zdieľať",
"_%n folder_::_%n folders_" => array("","",""),
"_%n file_::_%n files_" => array("","",""),
"_Uploading %n file_::_Uploading %n files_" => array("","","")
"_Uploading %n file_::_Uploading %n files_" => array("","",""),
"Save" => "Uložiť",
"Download" => "Stiahnuť",
"Delete" => "Odstrániť"
);
$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;";

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Ime datoteke ne sme vsebovati znaka \"/\". Določiti je treba drugo ime.",
"The name %s is already used in the folder %s. Please choose a different name." => "Ime %s je že v mapi %s že v uporabi. Izbrati je treba drugo ime.",
"Not a valid source" => "Vir ni veljaven",
"Server is not allowed to open URLs, please check the server configuration" => "Odpiranje naslovov URL preko strežnika ni dovoljeno. Preverite nastavitve strežnika.",
"Error while downloading %s to %s" => "Napaka med prejemanjem %s v mapo %s",
"Error when creating the file" => "Napaka med ustvarjanjem datoteke",
"Folder name cannot be empty." => "Ime mape ne more biti prazna vrednost.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} že obstaja",
"Could not create file" => "Ni mogoče ustvariti datoteke",
"Could not create folder" => "Ni mogoče ustvariti mape",
"Error fetching URL" => "Napaka pridobivanja naslova URL",
"Share" => "Souporaba",
"Delete permanently" => "Izbriši dokončno",
"Rename" => "Preimenuj",

View File

@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"File name must not contain \"/\". Please choose a different name." => "Dosya adı \"/\" içermemelidir. Lütfen farklı bir isim seçin.",
"The name %s is already used in the folder %s. Please choose a different name." => "%s ismi zaten %s klasöründe kullanılıyor. Lütfen farklı bir isim seçin.",
"Not a valid source" => "Geçerli bir kaynak değil",
"Server is not allowed to open URLs, please check the server configuration" => "Sunucunun adresleri açma izi yok, lütfen sunucu yapılandırmasını denetleyin",
"Error while downloading %s to %s" => "%s, %s içine indirilirken hata",
"Error when creating the file" => "Dosya oluşturulurken hata",
"Folder name cannot be empty." => "Klasör adı boş olamaz.",
@ -36,6 +37,7 @@ $TRANSLATIONS = array(
"{new_name} already exists" => "{new_name} zaten mevcut",
"Could not create file" => "Dosya oluşturulamadı",
"Could not create folder" => "Klasör oluşturulamadı",
"Error fetching URL" => "Adres getirilirken hata",
"Share" => "Paylaş",
"Delete permanently" => "Kalıcı olarak sil",
"Rename" => "İsim değiştir.",
@ -50,11 +52,11 @@ $TRANSLATIONS = array(
"_Uploading %n file_::_Uploading %n files_" => array("%n dosya yükleniyor","%n dosya yükleniyor"),
"'.' is an invalid file name." => "'.' geçersiz bir dosya adı.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Geçersiz isim, '\\', '/', '<', '>', ':', '\"', '|', '?' ve '*' karakterlerine izin verilmemektedir.",
"Your storage is full, files can not be updated or synced anymore!" => "Depolama alanınız dolu, artık dosyalar güncellenmeyecek yada senkronizasyon edilmeyecek.",
"Your storage is full, files can not be updated or synced anymore!" => "Depolama alanınız dolu, artık dosyalar güncellenmeyecek veya eşitlenmeyecek.",
"Your storage is almost full ({usedSpacePercent}%)" => "Depolama alanınız neredeyse dolu ({usedSpacePercent}%)",
"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Şifreleme Uygulaması etkin ancak anahtarlarınız başlatılmamış. Lütfen oturumu kapatıp yeniden açın",
"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Şifreleme Uygulaması için geçersiz özel anahtar. Lütfen şifreli dosyalarınıza erişimi tekrar kazanabilmek için kişisel ayarlarınızdan özel anahtar parolanızı güncelleyin.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Şifreleme işlemi durduruldu ancak dosyalarınız şifreli. Dosyalarınızın şifresini kaldırmak için lütfen kişisel ayarlar kısmına geçiniz.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Şifreleme işlemi durduruldu ancak dosyalarınız şifreli. Dosyalarınızın şifresini kaldırmak için lütfen kişisel ayarlar kısmına geçin.",
"Your download is being prepared. This might take some time if the files are big." => "İndirmeniz hazırlanıyor. Dosya büyük ise biraz zaman alabilir.",
"Error moving file" => "Dosya taşıma hatası",
"Error" => "Hata",
@ -64,13 +66,13 @@ $TRANSLATIONS = array(
"Invalid folder name. Usage of 'Shared' is reserved." => "Geçersiz dizin adı. 'Shared' ismi ayrılmıştır.",
"%s could not be renamed" => "%s yeniden adlandırılamadı",
"Upload" => "Yükle",
"File handling" => "Dosya taşıma",
"File handling" => "Dosya işlemleri",
"Maximum upload size" => "Maksimum yükleme boyutu",
"max. possible: " => "mümkün olan en fazla: ",
"Needed for multi-file and folder downloads." => "Çoklu dosya ve dizin indirmesi için gerekli.",
"Enable ZIP-download" => "ZIP indirmeyi aktif et",
"Enable ZIP-download" => "ZIP indirmeyi etkinleştir",
"0 is unlimited" => "0 limitsiz demektir",
"Maximum input size for ZIP files" => "ZIP dosyaları için en fazla girdi sayısı",
"Maximum input size for ZIP files" => "ZIP dosyaları için en fazla girdi boyutu",
"Save" => "Kaydet",
"New" => "Yeni",
"New text file" => "Yeni metin dosyası",

7
apps/files/l10n/ur.php Normal file
View File

@ -0,0 +1,7 @@
<?php
$TRANSLATIONS = array(
"_%n folder_::_%n folders_" => array("",""),
"_%n file_::_%n files_" => array("",""),
"_Uploading %n file_::_Uploading %n files_" => array("","")
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@ -59,6 +59,13 @@ class App {
$result['data'] = array(
'message' => $this->l10n->t("Invalid folder name. Usage of 'Shared' is reserved.")
);
// rename to non-existing folder is denied
} else if (!$this->view->file_exists($dir)) {
$result['data'] = array('message' => (string)$this->l10n->t(
'The target folder has been moved or deleted.',
array($dir)),
'code' => 'targetnotfound'
);
// rename to existing file is denied
} else if ($this->view->file_exists($dir . '/' . $newname)) {
@ -83,14 +90,17 @@ class App {
else {
$meta['type'] = 'file';
}
// these need to be set for determineIcon()
$meta['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($meta['mimetype']);
$meta['directory'] = $dir;
$fileinfo = array(
'id' => $meta['fileid'],
'mime' => $meta['mimetype'],
'size' => $meta['size'],
'etag' => $meta['etag'],
'directory' => $dir,
'directory' => $meta['directory'],
'name' => $newname,
'isPreviewAvailable' => \OC::$server->getPreviewManager()->isMimeSupported($meta['mimetype']),
'isPreviewAvailable' => $meta['isPreviewAvailable'],
'icon' => \OCA\Files\Helper::determineIcon($meta)
);
$result['success'] = true;

View File

@ -5,7 +5,7 @@
<h2><?php p($l->t('File handling')); ?></h2>
<?php if($_['uploadChangable']):?>
<label for="maxUploadSize"><?php p($l->t( 'Maximum upload size' )); ?> </label>
<input name='maxUploadSize' id="maxUploadSize" value='<?php p($_['uploadMaxFilesize']) ?>'/>
<input type="text" name='maxUploadSize' id="maxUploadSize" value='<?php p($_['uploadMaxFilesize']) ?>'/>
<?php if($_['displayMaxPossibleUploadSize']):?>
(<?php p($l->t('max. possible: ')); p($_['maxPossibleUploadSize']) ?>)
<?php endif;?>

View File

@ -1,6 +1,7 @@
<div id="controls">
<?php print_unescaped($_['breadcrumb']); ?>
<div class="actions creatable <?php if (!$_['isCreatable']):?>hidden<?php endif; ?>">
<?php if(!isset($_['dirToken'])):?>
<div id="new" class="button">
<a><?php p($l->t('New'));?></a>
<ul>
@ -12,6 +13,7 @@
data-type='web'><p><?php p($l->t('From link'));?></p></li>
</ul>
</div>
<?php endif;?>
<div id="upload" class="button"
title="<?php p($l->t('Upload') . ' max. '.$_['uploadMaxHumanFilesize']) ?>">
<?php if($_['uploadMaxFilesize'] >= 0):?>
@ -19,15 +21,19 @@
<?php endif;?>
<input type="hidden" id="upload_limit" value="<?php p($_['uploadLimit']) ?>">
<input type="hidden" id="free_space" value="<?php p($_['freeSpace']) ?>">
<?php if(isset($_['dirToken'])):?>
<input type="hidden" id="publicUploadRequestToken" name="requesttoken" value="<?php p($_['requesttoken']) ?>" />
<input type="hidden" id="dirToken" name="dirToken" value="<?php p($_['dirToken']) ?>" />
<?php endif;?>
<input type="hidden" class="max_human_file_size"
value="(max <?php p($_['uploadMaxHumanFilesize']); ?>)">
<input type="hidden" name="dir" value="<?php p($_['dir']) ?>" id="dir">
<input type="file" id="file_upload_start" name='files[]'
data-url="<?php print_unescaped(OCP\Util::linkTo('files', 'ajax/upload.php')); ?>" />
<a href="#" class="svg"></a>
<a href="#" class="svg icon icon-upload"></a>
</div>
<?php if ($_['trash']): ?>
<input id="trash" type="button" value="<?php p($l->t('Deleted files'));?>" class="button" <?php $_['trashEmpty'] ? p('disabled') : '' ?>></input>
<input id="trash" type="button" value="<?php p($l->t('Deleted files'));?>" class="button" <?php $_['trashEmpty'] ? p('disabled') : '' ?> />
<?php endif; ?>
<div id="uploadprogresswrapper">
<div id="uploadprogressbar"></div>
@ -45,7 +51,7 @@
<div id="emptycontent" <?php if (!$_['emptyContent']):?>class="hidden"<?php endif; ?>><?php p($l->t('Nothing in here. Upload something!'))?></div>
<input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>"></input>
<input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>" />
<table id="filestable" data-allow-public-upload="<?php p($_['publicUploadEnabled'])?>" data-preview-x="36" data-preview-y="36">
<thead>

View File

@ -1,10 +1,12 @@
<?php if(count($_["breadcrumb"])):?>
<div class="crumb" data-dir=''>
<a href="<?php print_unescaped($_['baseURL']); ?>">
<div class="crumb <?php if(!count($_["breadcrumb"])) p('last');?>" data-dir=''>
<a href="<?php print_unescaped($_['baseURL']); ?>">
<?php if(isset($_['rootBreadCrumb'])):
echo $_['rootBreadCrumb'];
else:?>
<img src="<?php print_unescaped(OCP\image_path('core', 'places/home.svg'));?>" class="svg" />
</a>
</div>
<?php endif;?>
<?php endif;?>
</a>
</div>
<?php for($i=0; $i<count($_["breadcrumb"]); $i++):
$crumb = $_["breadcrumb"][$i];
$dir = \OCP\Util::encodePath($crumb["dir"]); ?>

View File

@ -18,7 +18,7 @@ $totalsize = 0; ?>
data-size="<?php p($file['size']);?>"
data-etag="<?php p($file['etag']);?>"
data-permissions="<?php p($file['permissions']); ?>">
<?php if($file['isPreviewAvailable']): ?>
<?php if(isset($file['isPreviewAvailable']) and $file['isPreviewAvailable']): ?>
<td class="filename svg preview-icon"
<?php else: ?>
<td class="filename svg"

View File

@ -38,7 +38,7 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
$l10nMock->expects($this->any())
->method('t')
->will($this->returnArgument(0));
$viewMock = $this->getMock('\OC\Files\View', array('rename', 'normalizePath', 'getFileInfo'), array(), '', false);
$viewMock = $this->getMock('\OC\Files\View', array('rename', 'normalizePath', 'getFileInfo', 'file_exists'), array(), '', false);
$viewMock->expects($this->any())
->method('normalizePath')
->will($this->returnArgument(0));
@ -63,6 +63,11 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
$oldname = 'Shared';
$newname = 'new_name';
$this->viewMock->expects($this->at(0))
->method('file_exists')
->with('/')
->will($this->returnValue(true));
$result = $this->files->rename($dir, $oldname, $newname);
$expected = array(
'success' => false,
@ -80,6 +85,11 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
$oldname = 'Shared';
$newname = 'new_name';
$this->viewMock->expects($this->at(0))
->method('file_exists')
->with('/test')
->will($this->returnValue(true));
$this->viewMock->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array(
@ -129,6 +139,11 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
$oldname = 'oldname';
$newname = 'newname';
$this->viewMock->expects($this->at(0))
->method('file_exists')
->with('/')
->will($this->returnValue(true));
$this->viewMock->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array(
@ -141,7 +156,6 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
'name' => 'new_name',
)));
$result = $this->files->rename($dir, $oldname, $newname);
$this->assertTrue($result['success']);
@ -154,4 +168,35 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
$this->assertEquals(\OC_Helper::mimetypeIcon('dir'), $result['data']['icon']);
$this->assertFalse($result['data']['isPreviewAvailable']);
}
/**
* Test rename inside a folder that doesn't exist any more
*/
function testRenameInNonExistingFolder() {
$dir = '/unexist';
$oldname = 'oldname';
$newname = 'newname';
$this->viewMock->expects($this->at(0))
->method('file_exists')
->with('/unexist')
->will($this->returnValue(false));
$this->viewMock->expects($this->any())
->method('getFileInfo')
->will($this->returnValue(array(
'fileid' => 123,
'type' => 'dir',
'mimetype' => 'httpd/unix-directory',
'size' => 18,
'etag' => 'abcdef',
'directory' => '/unexist',
'name' => 'new_name',
)));
$result = $this->files->rename($dir, $oldname, $newname);
$this->assertFalse($result['success']);
$this->assertEquals('targetnotfound', $result['data']['code']);
}
}

View File

@ -0,0 +1,61 @@
/**
* ownCloud
*
* @author Vincent Petry
* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
describe('FileActions tests', function() {
beforeEach(function() {
// init horrible parameters
var $body = $('body');
$body.append('<input type="hidden" id="dir" value="/subdir"></input>');
$body.append('<input type="hidden" id="permissions" value="31"></input>');
// dummy files table
$filesTable = $body.append('<table id="filestable"></table>');
});
afterEach(function() {
$('#dir, #permissions, #filestable').remove();
});
it('calling display() sets file actions', function() {
// note: download_url is actually the link target, not the actual download URL...
var $tr = FileList.addFile('testName.txt', 1234, new Date(), false, false, {download_url: 'test/download/url'});
// no actions before call
expect($tr.find('.action[data-action=Download]').length).toEqual(0);
expect($tr.find('.action[data-action=Rename]').length).toEqual(0);
expect($tr.find('.action.delete').length).toEqual(0);
FileActions.display($tr.find('td.filename'), true);
// actions defined after cal
expect($tr.find('.action[data-action=Download]').length).toEqual(1);
expect($tr.find('.action[data-action=Rename]').length).toEqual(1);
expect($tr.find('.action.delete').length).toEqual(1);
});
it('redirects to download URL when clicking download', function() {
var redirectStub = sinon.stub(OC, 'redirect');
// note: download_url is actually the link target, not the actual download URL...
var $tr = FileList.addFile('test download File.txt', 1234, new Date(), false, false, {download_url: 'test/download/url'});
FileActions.display($tr.find('td.filename'), true);
$tr.find('.action[data-action=Download]').click();
expect(redirectStub.calledOnce).toEqual(true);
expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?files=test%20download%20File.txt&dir=%2Fsubdir&download');
redirectStub.restore();
});
});

View File

@ -0,0 +1,63 @@
/**
* ownCloud
*
* @author Vincent Petry
* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
describe('FileList tests', function() {
beforeEach(function() {
// init horrible parameters
var $body = $('body');
$body.append('<input type="hidden" id="dir" value="/subdir"></input>');
$body.append('<input type="hidden" id="permissions" value="31"></input>');
// dummy files table
$body.append('<table id="filestable"></table>');
});
afterEach(function() {
$('#dir, #permissions, #filestable').remove();
});
it('generates file element with correct attributes when calling addFile', function() {
var lastMod = new Date(10000);
// note: download_url is actually the link target, not the actual download URL...
var $tr = FileList.addFile('testName.txt', 1234, lastMod, false, false, {download_url: 'test/download/url'});
expect($tr).toBeDefined();
expect($tr[0].tagName.toLowerCase()).toEqual('tr');
expect($tr.find('a:first').attr('href')).toEqual('test/download/url');
expect($tr.attr('data-type')).toEqual('file');
expect($tr.attr('data-file')).toEqual('testName.txt');
expect($tr.attr('data-size')).toEqual('1234');
expect($tr.attr('data-permissions')).toEqual('31');
//expect($tr.attr('data-mime')).toEqual('plain/text');
});
it('generates dir element with correct attributes when calling addDir', function() {
var lastMod = new Date(10000);
var $tr = FileList.addDir('testFolder', 1234, lastMod, false);
expect($tr).toBeDefined();
expect($tr[0].tagName.toLowerCase()).toEqual('tr');
expect($tr.attr('data-type')).toEqual('dir');
expect($tr.attr('data-file')).toEqual('testFolder');
expect($tr.attr('data-size')).toEqual('1234');
expect($tr.attr('data-permissions')).toEqual('31');
//expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
});
it('returns correct download URL', function() {
expect(FileList.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?files=some%20file.txt&dir=%2Fsubdir&download');
expect(FileList.getDownloadUrl('some file.txt', '/anotherpath/abc')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?files=some%20file.txt&dir=%2Fanotherpath%2Fabc&download');
});
});

View File

@ -0,0 +1,81 @@
/**
* ownCloud
*
* @author Vincent Petry
* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
describe('Files tests', function() {
describe('File name validation', function() {
it('Validates correct file names', function() {
var fileNames = [
'boringname',
'something.with.extension',
'now with spaces',
'.a',
'..a',
'.dotfile',
'single\'quote',
' spaces before',
'spaces after ',
'allowed chars including the crazy ones $%&_-^@!,()[]{}=;#',
'汉字也能用',
'und Ümläüte sind auch willkommen'
];
for ( var i = 0; i < fileNames.length; i++ ) {
try {
expect(Files.isFileNameValid(fileNames[i])).toEqual(true);
}
catch (e) {
fail();
}
}
});
it('Detects invalid file names', function() {
var fileNames = [
'',
' ',
'.',
'..',
'back\\slash',
'sl/ash',
'lt<lt',
'gt>gt',
'col:on',
'double"quote',
'pi|pe',
'dont?ask?questions?',
'super*star',
'new\nline',
' ..',
'.. ',
'. ',
' .'
];
for ( var i = 0; i < fileNames.length; i++ ) {
var threwException = false;
try {
Files.isFileNameValid(fileNames[i]);
fail();
}
catch (e) {
threwException = true;
}
expect(threwException).toEqual(true);
}
});
});
});

View File

@ -6,6 +6,7 @@ if (OC::$CLI) {
if (count($argv) === 2) {
$file = $argv[1];
list(, $user) = explode('/', $file);
OCP\JSON::checkUserExists($owner);
OC_Util::setupFS($user);
$view = new \OC\Files\View('');
/**

View File

@ -2,11 +2,15 @@
<info>
<id>files_encryption</id>
<name>Encryption</name>
<description>The new ownCloud 5 files encryption system. After the app was enabled you need to re-login to initialize your encryption keys.</description>
<description>The ownCloud files encryption system provides server side-encryption. After the app was enabled you need to re-login to initialize your encryption keys.</description>
<licence>AGPL</licence>
<author>Sam Tuke, Bjoern Schiessle, Florin Peter</author>
<require>4</require>
<shipped>true</shipped>
<documentation>
<user>http://doc.owncloud.org/server/6.0/user_manual/files/encryption.html</user>
<admin>http://doc.owncloud.org/server/6.0/admin_manual/configuration/configuration_encryption.html</admin>
</documentation>
<rememberlogin>false</rememberlogin>
<types>
<filesystem/>

View File

@ -30,6 +30,9 @@ use OC\Files\Filesystem;
*/
class Hooks {
// file for which we want to rename the keys after the rename operation was successful
private static $renamedFiles = array();
/**
* @brief Startup encryption backend upon user login
* @note This method should never be called for users using client side encryption
@ -479,6 +482,18 @@ class Hooks {
}
}
/**
* @brief mark file as renamed so that we know the original source after the file was renamed
* @param array $params with the old path and the new path
*/
public static function preRename($params) {
$util = new Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']);
self::$renamedFiles[$params['oldpath']] = array(
'uid' => $ownerOld,
'path' => $pathOld);
}
/**
* @brief after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing
* @param array with oldpath and newpath
@ -501,19 +516,32 @@ class Hooks {
$userId = \OCP\User::getUser();
$util = new Util($view, $userId);
// Format paths to be relative to user files dir
if ($util->isSystemWideMountPoint($params['oldpath'])) {
$baseDir = 'files_encryption/';
$oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath'];
if (isset(self::$renamedFiles[$params['oldpath']]['uid']) &&
isset(self::$renamedFiles[$params['oldpath']]['path'])) {
$ownerOld = self::$renamedFiles[$params['oldpath']]['uid'];
$pathOld = self::$renamedFiles[$params['oldpath']]['path'];
} else {
$baseDir = $userId . '/' . 'files_encryption/';
$oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath'];
\OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::ERROR);
return false;
}
if ($util->isSystemWideMountPoint($params['newpath'])) {
$newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath'];
list($ownerNew, $pathNew) = $util->getUidAndFilename($params['newpath']);
// Format paths to be relative to user files dir
if ($util->isSystemWideMountPoint($pathOld)) {
$oldKeyfilePath = 'files_encryption/keyfiles/' . $pathOld;
$oldShareKeyPath = 'files_encryption/share-keys/' . $pathOld;
} else {
$newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath'];
$oldKeyfilePath = $ownerOld . '/' . 'files_encryption/keyfiles/' . $pathOld;
$oldShareKeyPath = $ownerOld . '/' . 'files_encryption/share-keys/' . $pathOld;
}
if ($util->isSystemWideMountPoint($pathNew)) {
$newKeyfilePath = 'files_encryption/keyfiles/' . $pathNew;
$newShareKeyPath = 'files_encryption/share-keys/' . $pathNew;
} else {
$newKeyfilePath = $ownerNew . '/files_encryption/keyfiles/' . $pathNew;
$newShareKeyPath = $ownerNew . '/files_encryption/share-keys/' . $pathNew;
}
// add key ext if this is not an folder
@ -522,11 +550,11 @@ class Hooks {
$newKeyfilePath .= '.key';
// handle share-keys
$localKeyPath = $view->getLocalFile($baseDir . 'share-keys/' . $params['oldpath']);
$localKeyPath = $view->getLocalFile($oldShareKeyPath);
$escapedPath = Helper::escapeGlobPattern($localKeyPath);
$matches = glob($escapedPath . '*.shareKey');
foreach ($matches as $src) {
$dst = \OC\Files\Filesystem::normalizePath(str_replace($params['oldpath'], $params['newpath'], $src));
$dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src));
// create destination folder if not exists
if (!file_exists(dirname($dst))) {
@ -538,15 +566,13 @@ class Hooks {
} else {
// handle share-keys folders
$oldShareKeyfilePath = $baseDir . 'share-keys/' . $params['oldpath'];
$newShareKeyfilePath = $baseDir . 'share-keys/' . $params['newpath'];
// create destination folder if not exists
if (!$view->file_exists(dirname($newShareKeyfilePath))) {
$view->mkdir(dirname($newShareKeyfilePath), 0750, true);
if (!$view->file_exists(dirname($newShareKeyPath))) {
$view->mkdir(dirname($newShareKeyPath), 0750, true);
}
$view->rename($oldShareKeyfilePath, $newShareKeyfilePath);
$view->rename($oldShareKeyPath, $newShareKeyPath);
}
// Rename keyfile so it isn't orphaned
@ -561,18 +587,17 @@ class Hooks {
}
// build the path to the file
$newPath = '/' . $userId . '/files' . $params['newpath'];
$newPathRelative = $params['newpath'];
$newPath = '/' . $ownerNew . '/files' . $pathNew;
if ($util->fixFileSize($newPath)) {
// get sharing app state
$sharingEnabled = \OCP\Share::isEnabled();
// get users
$usersSharing = $util->getSharingUsersArray($sharingEnabled, $newPathRelative);
$usersSharing = $util->getSharingUsersArray($sharingEnabled, $pathNew);
// update sharing-keys
$util->setSharedFileKeyfiles($session, $usersSharing, $newPathRelative);
$util->setSharedFileKeyfiles($session, $usersSharing, $pathNew);
}
\OC_FileProxy::$enabled = $proxyStatus;

View File

@ -8,19 +8,27 @@ $TRANSLATIONS = array(
"Could not change the password. Maybe the old password was not correct." => "Kunne ikke ændre kodeordet. Måske var det gamle kodeord ikke korrekt.",
"Private key password successfully updated." => "Privat nøgle kodeord succesfuldt opdateret.",
"Could not update the private key password. Maybe the old password was not correct." => "Kunne ikke opdatere det private nøgle kodeord-. Måske var det gamle kodeord forkert.",
"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Krypteringsprogrammet er ikke igangsat. Det kan skyldes at krypteringsprogrammet er blevet genaktiveret under din session. Prøv at logge ud og ind igen for at aktivere krypteringsprogrammet. ",
"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Din private nøgle er ikke gyldig. Sandsynligvis er dit kodeord blevet ændret uden for %s (f.eks dit firmas adressebog). Du kan opdatere din private nøglekode i dine personlige indstillinger for at genskabe adgang til dine krypterede filer.",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Kan ikke kryptere denne fil, sandsynligvis fordi felen er delt. Bed venligst filens ejer om at dele den med dig på ny.",
"Unknown error please check your system settings or contact your administrator" => "Ukendt fejl. Kontroller venligst dit system eller kontakt din administrator",
"Missing requirements." => "Manglende betingelser.",
"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Sørg for at PHP 5.3.3 eller nyere er installeret og at OpenSSL sammen med PHP-udvidelsen er aktiveret og korrekt konfigureret. Indtil videre er krypteringsprogrammet deaktiveret.",
"Following users are not set up for encryption:" => "Følgende brugere er ikke sat op til kryptering:",
"Initial encryption started... This can take some time. Please wait." => "Førstegangskryptering er påbegyndt... Dette kan tage nogen tid. Vent venligst.",
"Saving..." => "Gemmer...",
"Go directly to your " => "Gå direkte til din ",
"personal settings" => "Personlige indstillinger",
"Encryption" => "Kryptering",
"Enable recovery key (allow to recover users files in case of password loss):" => "Aktiver gendannelsesnøgle (Tillad gendannelse af brugerfiler i tilfælde af tab af kodeord):",
"Recovery key password" => "Gendannelsesnøgle kodeord",
"Repeat Recovery key password" => "Gentag gendannelse af nøglekoden",
"Enabled" => "Aktiveret",
"Disabled" => "Deaktiveret",
"Change recovery key password:" => "Skift gendannelsesnøgle kodeord:",
"Old Recovery key password" => "Gammel Gendannelsesnøgle kodeord",
"New Recovery key password" => "Ny Gendannelsesnøgle kodeord",
"Repeat New Recovery key password" => "Gentag dannelse af ny gendannaleses nøglekode",
"Change Password" => "Skift Kodeord",
"Your private key password no longer match your log-in password:" => "Dit private nøgle kodeord stemmer ikke længere overens med dit login kodeord:",
"Set your old private key password to your current log-in password." => "Sæt dit gamle private nøgle kodeord til at være dit nuværende login kodeord. ",

View File

@ -8,20 +8,30 @@ $TRANSLATIONS = array(
"Could not change the password. Maybe the old password was not correct." => "Αποτυχία αλλαγής κωδικού ίσως ο παλιός κωδικός να μην ήταν σωστός.",
"Private key password successfully updated." => "Το Προσωπικό κλειδί πρόσβασης ενημερώθηκε επιτυχώς",
"Could not update the private key password. Maybe the old password was not correct." => "Αποτυχία ενημέρωσης του κωδικού για το προσωπικό κλειδί. Ενδεχομένως ο παλιός κωδικός δεν ήταν σωστός.",
"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Η εφαρμογή κρυπτογράφησης δεν έχει εκκινήσει! Ίσως η εφαρμογή κρυπτογράφησης επανενεργοποιήθηκε κατά τη διάρκεια της τρέχουσας σύνδεσής σας. Παρακαλώ προσπαθήστε να αποσυνδεθείτε και να ξανασυνδεθείτε για να εκκινήσετε την εφαρμογή κρυπτογράφησης.",
"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Το προσωπικό σας κλειδί δεν είναι έγκυρο! Πιθανόν ο κωδικός σας να άλλαξε έξω από το %s (π.χ. τη λίστα διευθύνσεων της εταιρείας σας). Μπορείτε να ενημερώσετε το προσωπικό σας κλειδί επαναφοράς κωδικού στις προσωπικές σας ρυθμίσεις για να επανακτήσετε πρόσβαση στα κρυπτογραφημένα σας αρχεία.",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Δεν ήταν δυνατό να αποκρυπτογραφηθεί αυτό το αρχείο, πιθανόν πρόκειται για κοινόχρηστο αρχείο. Παρακαλώ ζητήστε από τον ιδιοκτήτη του αρχείου να το ξαναμοιραστεί μαζί σας.",
"Unknown error please check your system settings or contact your administrator" => "Άγνωστο σφάλμα, παρακαλώ ελέγξτε τις ρυθμίσεις συστήματος ή επικοινωνήστε με τον διαχειριστή σας ",
"Missing requirements." => "Προαπαιτούμενα που απουσιάζουν.",
"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Παρακαλώ επιβεβαιώστε ότι η PHP 5.3.3 ή νεότερη είναι εγκατεστημένη και ότι το OpenSSL μαζί με το PHP extension είναι ενεργοποιήμένο και έχει ρυθμιστεί σωστά. Προς το παρόν, η εφαρμογή κρυπτογράφησης είναι απενεργοποιημένη.",
"Following users are not set up for encryption:" => "Οι κάτωθι χρήστες δεν έχουν ρυθμιστεί για κρυπογράφηση:",
"Initial encryption started... This can take some time. Please wait." => "Η αρχική κρυπτογράφηση άρχισε... Αυτό μπορεί να πάρει κάποια ώρα. Παρακαλώ περιμένετε.",
"Saving..." => "Γίνεται αποθήκευση...",
"Go directly to your " => "Πηγαίνε απευθείας στο ",
"personal settings" => "προσωπικές ρυθμίσεις",
"Encryption" => "Κρυπτογράφηση",
"Enable recovery key (allow to recover users files in case of password loss):" => "Ενεργοποίηση κλειδιού ανάκτησης (επιτρέψτε την ανάκτηση αρχείων χρηστών σε περίπτωση απώλειας κωδικού):",
"Recovery key password" => "Επαναφορά κωδικού κλειδιού",
"Repeat Recovery key password" => "Επαναλάβετε το κλειδί επαναφοράς κωδικού",
"Enabled" => "Ενεργοποιημένο",
"Disabled" => "Απενεργοποιημένο",
"Change recovery key password:" => "Αλλαγή κλειδιού επαναφοράς κωδικού:",
"Old Recovery key password" => "Παλιό κλειδί επαναφοράς κωδικού",
"New Recovery key password" => "Νέο κλειδί επαναφοράς κωδικού",
"Repeat New Recovery key password" => "Επαναλάβετε νέο κλειδί επαναφοράς κωδικού",
"Change Password" => "Αλλαγή Κωδικού Πρόσβασης",
"Your private key password no longer match your log-in password:" => "Ο κωδικός του προσωπικού κλειδιού δεν ταιριάζει πλέον με τον κωδικό σύνδεσής σας:",
"Set your old private key password to your current log-in password." => "Ορίστε το παλιό σας προσωπικό κλειδί ως τον τρέχων κωδικό πρόσβασης.",
" If you don't remember your old password you can ask your administrator to recover your files." => "Εάν δεν θυμάστε τον παλιό σας κωδικό μπορείτε να ζητήσετε από τον διαχειριστή σας να επανακτήσει τα αρχεία σας.",
"Old log-in password" => "Παλαιό συνθηματικό εισόδου",
"Current log-in password" => "Τρέχον συνθηματικό πρόσβασης",

View File

@ -0,0 +1,44 @@
<?php
$TRANSLATIONS = array(
"Recovery key successfully enabled" => "Se ha habilitado la recuperación de archivos",
"Could not enable recovery key. Please check your recovery key password!" => "No se pudo habilitar la clave de recuperación. Por favor compruebe su contraseña.",
"Recovery key successfully disabled" => "Clave de recuperación deshabilitada",
"Could not disable recovery key. Please check your recovery key password!" => "No se pudo deshabilitar la clave de recuperación. Por favor compruebe su contraseña!",
"Password successfully changed." => "Su contraseña ha sido cambiada",
"Could not change the password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Compruebe que la contraseña actual sea correcta.",
"Private key password successfully updated." => "Contraseña de clave privada actualizada con éxito.",
"Could not update the private key password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Puede que la contraseña antigua no sea correcta.",
"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "¡La aplicación de cifrado no ha sido inicializada! Quizá fue restablecida durante tu sesión. Por favor intenta cerrar la sesión y volver a iniciarla para inicializar la aplicación de cifrado.",
"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "¡Su clave privada no es válida! Tal vez su contraseña ha sido cambiada desde fuera. de %s (Ej:Su directorio corporativo). Puede actualizar la contraseña de su clave privada en sus opciones personales para recuperar el acceso a sus archivos.",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "No fue posible descifrar este archivo, probablemente se trate de un archivo compartido. Solicite al propietario del mismo que vuelva a compartirlo con usted.",
"Unknown error please check your system settings or contact your administrator" => "Error desconocido. Verifique la configuración de su sistema o póngase en contacto con su administrador",
"Missing requirements." => "Requisitos incompletos.",
"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, asegúrese de que PHP 5.3.3 o posterior está instalado y que la extensión OpenSSL de PHP está habilitada y configurada correctamente. Por el momento, la aplicación de cifrado ha sido deshabilitada.",
"Following users are not set up for encryption:" => "Los siguientes usuarios no han sido configurados para el cifrado:",
"Initial encryption started... This can take some time. Please wait." => "Encriptación iniciada... Esto puede tomar un tiempo. Por favor espere.",
"Saving..." => "Guardando...",
"Go directly to your " => "Ir directamente a su",
"personal settings" => "opciones personales",
"Encryption" => "Cifrado",
"Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar la clave de recuperación (permite recuperar los archivos del usuario en caso de pérdida de la contraseña);",
"Recovery key password" => "Contraseña de clave de recuperación",
"Repeat Recovery key password" => "Repite la contraseña de clave de recuperación",
"Enabled" => "Habilitar",
"Disabled" => "Deshabilitado",
"Change recovery key password:" => "Cambiar la contraseña de la clave de recuperación",
"Old Recovery key password" => "Antigua clave de recuperación",
"New Recovery key password" => "Nueva clave de recuperación",
"Repeat New Recovery key password" => "Repetir la nueva clave de recuperación",
"Change Password" => "Cambiar contraseña",
"Your private key password no longer match your log-in password:" => "Su contraseña de clave privada ya no coincide con su contraseña de acceso:",
"Set your old private key password to your current log-in password." => "Establecer la contraseña de su antigua clave privada a su contraseña actual de acceso.",
" If you don't remember your old password you can ask your administrator to recover your files." => "Si no recuerda su antigua contraseña puede pedir a su administrador que le recupere sus archivos.",
"Old log-in password" => "Contraseña de acceso antigua",
"Current log-in password" => "Contraseña de acceso actual",
"Update Private Key Password" => "Actualizar Contraseña de Clave Privada",
"Enable password recovery:" => "Habilitar la recuperación de contraseña:",
"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Habilitar esta opción le permitirá volver a tener acceso a sus archivos cifrados en caso de pérdida de contraseña",
"File recovery settings updated" => "Opciones de recuperación de archivos actualizada",
"Could not update file recovery" => "No se pudo actualizar la recuperación de archivos"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@ -1,18 +1,44 @@
<?php
$TRANSLATIONS = array(
"Recovery key successfully disabled" => "Visszaállítási kulcs sikeresen kikapcsolva",
"Password successfully changed." => "Jelszó sikeresen megváltoztatva.",
"Recovery key successfully enabled" => "A helyreállítási kulcs sikeresen bekapcsolva",
"Could not enable recovery key. Please check your recovery key password!" => "A helyreállítási kulcsot nem lehetett engedélyezni. Ellenőrizze a helyreállítási kulcsa jelszavát!",
"Recovery key successfully disabled" => "A helyreállítási kulcs sikeresen kikapcsolva",
"Could not disable recovery key. Please check your recovery key password!" => "A helyreállítási kulcsot nem lehetett kikapcsolni. Ellenőrizze a helyreállítási kulcsa jelszavát!",
"Password successfully changed." => "A jelszót sikeresen megváltoztattuk.",
"Could not change the password. Maybe the old password was not correct." => "A jelszót nem lehet megváltoztatni! Lehet, hogy hibás volt a régi jelszó.",
"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Kérlek győződj meg arról, hogy PHP 5.3.3 vagy annál frissebb van telepítve, valamint a PHP-hez tartozó OpenSSL bővítmény be van-e kapcsolva és az helyesen van-e konfigurálva! Ki lett kapcsolva ideiglenesen a titkosító alkalmazás.",
"Private key password successfully updated." => "A személyes kulcsának jelszava frissítésre került.",
"Could not update the private key password. Maybe the old password was not correct." => "A személyes kulcsa jelszavát nem lehetett frissíteni. Lehet, hogy hibás volt a régi jelszó.",
"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "A titkosítási modul nincs elindítva! Talán a munkafolyamat közben került engedélyezésre. Kérjük jelentkezzen ki majd ismét jelentkezzen be, hogy a titkosítási modul megfelelően elinduljon!",
"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Az állományok titkosításához használt titkos kulcsa érvénytelen. Valószínűleg a %s rendszeren kívül változtatta meg a jelszavát (pl. a munkahelyi címtárban). A személyes beállításoknál frissítheti a titkos kulcsát, hogy ismét elérhesse a titkosított állományait.",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Az állományt nem sikerült dekódolni, valószínűleg ez egy megosztott fájl. Kérje meg az állomány tulajdonosát, hogy újra ossza meg Önnel ezt az állományt!",
"Unknown error please check your system settings or contact your administrator" => "Ismeretlen hiba. Ellenőrizze a rendszer beállításait vagy forduljon a rendszergazdához!",
"Missing requirements." => "Hiányzó követelmények.",
"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Kérem gondoskodjon arról, hogy PHP 5.3.3 vagy annál frissebb legyen telepítve, továbbá az OpenSSL a megfelelő PHP-bővítménnyel együtt rendelkezésre álljon és helyesen legyen konfigurálva! A titkosító modul egyelőre kikapcsolásra került.",
"Following users are not set up for encryption:" => "A következő felhasználók nem állították be a titkosítást:",
"Initial encryption started... This can take some time. Please wait." => "A titkosítási folyamat megkezdődött... Ez hosszabb ideig is eltarthat. Kérem várjon.",
"Saving..." => "Mentés...",
"Go directly to your " => "Ugrás ide:",
"personal settings" => "személyes beállítások",
"Encryption" => "Titkosítás",
"Enable recovery key (allow to recover users files in case of password loss):" => "A helyreállítási kulcs beállítása (lehetővé teszi a felhasználók állományainak visszaállítását, ha elfelejtik a jelszavukat):",
"Recovery key password" => "A helyreállítási kulcs jelszava",
"Repeat Recovery key password" => "Ismételje meg a helyreállítási kulcs jelszavát",
"Enabled" => "Bekapcsolva",
"Disabled" => "Kikapcsolva",
"Change recovery key password:" => "A helyreállítási kulcs jelszavának módosítása:",
"Old Recovery key password" => "Régi Helyreállítási Kulcs Jelszava",
"New Recovery key password" => "Új Helyreállítási kulcs jelszava",
"Repeat New Recovery key password" => "Ismételje meg az új helyreállítási kulcs jelszavát",
"Change Password" => "Jelszó megváltoztatása",
"Your private key password no longer match your log-in password:" => "A személyes kulcs jelszava mostantól nem azonos a belépési jelszavával:",
"Set your old private key password to your current log-in password." => "Állítsuk be a személyes kulcs jelszavát a jelenlegi bejelentkezési jelszavunkra.",
" If you don't remember your old password you can ask your administrator to recover your files." => "Ha nem emlékszik a régi jelszavára akkor megkérheti a rendszergazdát, hogy állítsa vissza az állományait.",
"Old log-in password" => "Régi bejelentkezési jelszó",
"Current log-in password" => "Jelenlegi bejelentkezési jelszó",
"Update Private Key Password" => "Privát kulcs jelszó frissítése",
"Enable password recovery:" => "Jelszó-visszaállítás bekapcsolása"
"Update Private Key Password" => "A személyest kulcs jelszó frissítése",
"Enable password recovery:" => "Jelszó-visszaállítás bekapcsolása",
"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Ez az opció lehetővé teszi, hogy a titkosított állományok tartalmát visszanyerjük abban az esetben, ha elfelejti a jelszavát",
"File recovery settings updated" => "A fájlhelyreállítási beállítások frissültek",
"Could not update file recovery" => "A fájlhelyreállítás nem frissíthető"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";

View File

@ -1,6 +1,41 @@
<?php
$TRANSLATIONS = array(
"Recovery key successfully enabled" => "Kunci pemulihan berhasil diaktifkan",
"Could not enable recovery key. Please check your recovery key password!" => "Tidak dapat mengaktifkan kunci pemulihan. Silakan periksa sandi kunci pemulihan Anda!",
"Recovery key successfully disabled" => "Kunci pemulihan berhasil dinonaktifkan",
"Could not disable recovery key. Please check your recovery key password!" => "Tidak dapat menonaktifkan kunci pemulihan. Silakan periksa sandi kunci pemulihan Anda!",
"Password successfully changed." => "Sandi berhasil diubah",
"Could not change the password. Maybe the old password was not correct." => "Tidak dapat mengubah sandi. Kemungkinan sandi lama yang dimasukkan salah.",
"Private key password successfully updated." => "Sandi kunci privat berhasil diperbarui.",
"Could not update the private key password. Maybe the old password was not correct." => "Tidak dapat memperbarui sandi kunci privat. Kemungkinan sandi lama yang Anda masukkan salah.",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Tidak dapat mendekripsi berkas ini, mungkin ini adalah berkas bersama. Silakan meminta pemilik berkas ini untuk membagikan kembali dengan Anda.",
"Unknown error please check your system settings or contact your administrator" => "Kesalahan tak dikenal, silakan periksa pengaturan sistem Anda atau hubungi admin.",
"Missing requirements." => "Persyaratan yang hilang.",
"Following users are not set up for encryption:" => "Pengguna berikut belum diatur untuk enkripsi:",
"Initial encryption started... This can take some time. Please wait." => "Inisial enskripsi dijalankan... Ini dapat memakan waktu. Silakan tunggu.",
"Saving..." => "Menyimpan...",
"Encryption" => "Enkripsi"
"Go directly to your " => "Langsung ke anda",
"personal settings" => "pengaturan pribadi",
"Encryption" => "Enkripsi",
"Enable recovery key (allow to recover users files in case of password loss):" => "Aktifkan kunci pemulihan (memungkinkan pengguna untuk memulihkan berkas dalam kasus kehilangan sandi):",
"Recovery key password" => "Sandi kunci pemulihan",
"Repeat Recovery key password" => "Ulangi sandi kunci Pemulihan",
"Enabled" => "Diaktifkan",
"Disabled" => "Dinonaktifkan",
"Change recovery key password:" => "Ubah sandi kunci pemulihan:",
"Old Recovery key password" => "Sandi kunci Pemulihan Lama",
"New Recovery key password" => "Sandi kunci Pemulihan Baru",
"Repeat New Recovery key password" => "Ulangi sandi kunci Pemulihan baru",
"Change Password" => "Ubah sandi",
"Your private key password no longer match your log-in password:" => "Sandi kunci privat Anda tidak lagi cocok dengan sandi masuk:",
"Set your old private key password to your current log-in password." => "Atur sandi kunci privat lama Anda sebagai sandi masuk Anda saat ini.",
" If you don't remember your old password you can ask your administrator to recover your files." => "Jika Anda tidak ingat sandi lama, Anda dapat meminta administrator Anda untuk memulihkan berkas.",
"Old log-in password" => "Sandi masuk yang lama",
"Current log-in password" => "Sandi masuk saat ini",
"Update Private Key Password" => "Perbarui Sandi Kunci Privat",
"Enable password recovery:" => "Aktifkan sandi pemulihan:",
"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Mengaktifkan opsi ini memungkinkan Anda untuk mendapatkan kembali akses ke berkas terenkripsi Anda dalam kasus kehilangan sandi",
"File recovery settings updated" => "Pengaturan pemulihan berkas diperbarui",
"Could not update file recovery" => "Tidak dapat memperbarui pemulihan berkas"
);
$PLURAL_FORMS = "nplurals=1; plural=0;";

View File

@ -1,26 +1,44 @@
<?php
$TRANSLATIONS = array(
"Recovery key successfully enabled" => "복구키가 성공적으로 활성화 되었습니다",
"Could not enable recovery key. Please check your recovery key password!" => "복구키를 활성화 할수 없습니다. 복구키의 비밀번호를 확인해주세요!",
"Recovery key successfully disabled" => "복구키가 성공적으로 비활성화 되었습니다",
"Could not disable recovery key. Please check your recovery key password!" => "복구키를 비활성화 할수 없습니다. 복구키의 비밀번호를 확인해주세요!",
"Recovery key successfully enabled" => "복구 키가 성공적으로 활성화되었습니다",
"Could not enable recovery key. Please check your recovery key password!" => "복구 키를 활성화 할 수 없습니다. 복구 키의 암호를 확인해 주세요!",
"Recovery key successfully disabled" => "복구 키가 성공적으로 비활성화 되었습니다",
"Could not disable recovery key. Please check your recovery key password!" => "복구 키를 비활성화 할 수 없습니다. 복구 키의 암호를 확인해주세요!",
"Password successfully changed." => "암호가 성공적으로 변경되었습니다",
"Could not change the password. Maybe the old password was not correct." => "암호를 변경할수 없습니다. 아마도 예전 암호가 정확하지 않은것 같습니다.",
"Private key password successfully updated." => "개인키 암호가 성공적으로 업데이트 됨.",
"Could not change the password. Maybe the old password was not correct." => "암호를 변경할 수 없습니다. 예전 암호가 정확하지 않은 것 같습니다.",
"Private key password successfully updated." => "개인 키 암호가 성공적으로 업데이트 됨.",
"Could not update the private key password. Maybe the old password was not correct." => "개인 키 암호를 업데이트할 수 없습니다. 이전 암호가 올바르지 않은 것 같습니다.",
"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "암호화 앱이 초기화되지 않았습니다! 암호화 앱이 다시 활성화된 것 같습니다. 암호화 앱을 초기화하려면 로그아웃했다 다시 로그인하십시오.",
"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "개인 키가 올바르지 않습니다! 암호가 %s(예: 회사 디렉터리) 외부에서 변경된 것 같습니다. 암호화된 파일에 다시 접근하려면 개인 설정에서 개인 키 암호를 수정하십시오.",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "이 파일을 복호화할 수 없습니다. 공유된 파일일 수도 있습니다. 파일 소유자에게 공유를 다시 요청하십시오.",
"Unknown error please check your system settings or contact your administrator" => "알 수 없는 오류. 시스템 설정을 확인하거나 관리자에게 문의하십시오.",
"Missing requirements." => "요구 사항이 부족합니다.",
"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "PHP 5.3.3 이상 설치 여부, PHP의 OpenSSL 확장 기능 활성화 및 설정 여부를 확인하십시오. 암호화 앱이 비활성화 되었습니다.",
"Following users are not set up for encryption:" => "다음 사용자는 암호화를 사용할 수 없습니다:",
"Initial encryption started... This can take some time. Please wait." => "초기 암호화가 시작되었습니다... 시간이 걸릴 수도 있으니 기다려 주십시오.",
"Saving..." => "저장 중...",
"Go directly to your " => "다음으로 바로 가기: ",
"personal settings" => "개인 설정",
"Encryption" => "암호화",
"Recovery key password" => "키 비밀번호 복구",
"Enable recovery key (allow to recover users files in case of password loss):" => "복구 키 사용 (암호를 잊었을 때 파일을 복구할 수 있도록 함):",
"Recovery key password" => "복구 키 암호",
"Repeat Recovery key password" => "복구 키 암호 재입력",
"Enabled" => "활성화",
"Disabled" => "비활성화",
"Change recovery key password:" => "복구 키 비밀번호 변경",
"Old Recovery key password" => "예전 복구 키 비밀번호",
"New Recovery key password" => "새 복구 키 비밀번호",
"Change recovery key password:" => "복구 키 암호 변경:",
"Old Recovery key password" => "이전 복구 키 암호",
"New Recovery key password" => "새 복구 키 암호",
"Repeat New Recovery key password" => "새 복구 키 암호 재입력",
"Change Password" => "암호 변경",
"Old log-in password" => "예전 로그인 암호",
"Your private key password no longer match your log-in password:" => "개인 키 암호와 로그인 암호가 일치하지 않습니다:",
"Set your old private key password to your current log-in password." => "이전 개인 키 암호를 현재 로그인 암호로 설정하십시오.",
" If you don't remember your old password you can ask your administrator to recover your files." => " 이전 암호가 기억나지 않으면 시스템 관리자에게 파일 복구를 요청하십시오.",
"Old log-in password" => "이전 로그인 암호",
"Current log-in password" => "현재 로그인 암호",
"Update Private Key Password" => "개인 키 암호 업데이트",
"Enable password recovery:" => "암호 복구 사용:",
"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "이 옵션을 사용하면 암호를 잊었을 때 암호화된 파일에 다시 접근할 수 있습니다",
"File recovery settings updated" => "파일 복구 설정 업데이트됨",
"Could not update file recovery" => "파일 복구를 업데이트 할수 없습니다"
"Could not update file recovery" => "파일 복구를 업데이트 수 없습니다"
);
$PLURAL_FORMS = "nplurals=1; plural=0;";

View File

@ -15,6 +15,7 @@ $TRANSLATIONS = array(
"Missing requirements." => "Brak wymagań.",
"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Proszę upewnić się, że PHP 5.3.3 lub nowszy jest zainstalowany i że OpenSSL oraz rozszerzenie PHP jest włączone i poprawnie skonfigurowane. Obecnie szyfrowanie aplikacji zostało wyłączone.",
"Following users are not set up for encryption:" => "Następujący użytkownicy nie mają skonfigurowanego szyfrowania:",
"Initial encryption started... This can take some time. Please wait." => "Rozpoczęto szyfrowanie... To może chwilę potrwać. Proszę czekać.",
"Saving..." => "Zapisywanie...",
"Go directly to your " => "Przejdź bezpośrednio do",
"personal settings" => "Ustawienia osobiste",

View File

@ -29,6 +29,8 @@ namespace OCA\Encryption;
*/
class Helper {
private static $tmpFileMapping; // Map tmp files to files in data/user/files
/**
* @brief register share related hooks
*
@ -59,6 +61,7 @@ class Helper {
*/
public static function registerFilesystemHooks() {
\OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Encryption\Hooks', 'preRename');
\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename');
}
@ -274,7 +277,7 @@ class Helper {
$split = explode('/', $trimmed);
// it is not a file relative to data/user/files
if (count($split) < 2 || $split[1] !== 'files') {
if (count($split) < 2 || ($split[1] !== 'files' && $split[1] !== 'cache')) {
return false;
}
@ -423,5 +426,27 @@ class Helper {
public static function escapeGlobPattern($path) {
return preg_replace('/(\*|\?|\[)/', '[$1]', $path);
}
/**
* @brief remember from which file the tmp file (getLocalFile() call) was created
* @param string $tmpFile path of tmp file
* @param string $originalFile path of the original file relative to data/
*/
public static function addTmpFileToMapper($tmpFile, $originalFile) {
self::$tmpFileMapping[$tmpFile] = $originalFile;
}
/**
* @brief get the path of the original file
* @param string $tmpFile path of the tmp file
* @return mixed path of the original file or false
*/
public static function getPathFromTmpFile($tmpFile) {
if (isset(self::$tmpFileMapping[$tmpFile])) {
return self::$tmpFileMapping[$tmpFile];
}
return false;
}
}

View File

@ -37,6 +37,7 @@ namespace OCA\Encryption;
class Proxy extends \OC_FileProxy {
private static $blackList = null; //mimetypes blacklisted from encryption
private static $unencryptedSizes = array(); // remember unencrypted size
/**
* Check if a file requires encryption
@ -114,6 +115,13 @@ class Proxy extends \OC_FileProxy {
// get encrypted content
$data = $view->file_get_contents($tmpPath);
// store new unenecrypted size so that it can be updated
// in the post proxy
$tmpFileInfo = $view->getFileInfo($tmpPath);
if ( isset($tmpFileInfo['size']) ) {
self::$unencryptedSizes[\OC_Filesystem::normalizePath($path)] = $tmpFileInfo['size'];
}
// remove our temp file
$view->deleteAll('/' . \OCP\User::getUser() . '/cache/' . $cacheFolder);
@ -127,6 +135,24 @@ class Proxy extends \OC_FileProxy {
}
/**
* @brief update file cache with the new unencrypted size after file was written
* @param string $path
* @param mixed $result
* @return mixed
*/
public function postFile_put_contents($path, $result) {
$normalizedPath = \OC_Filesystem::normalizePath($path);
if ( isset(self::$unencryptedSizes[$normalizedPath]) ) {
$view = new \OC_FilesystemView('/');
$view->putFileInfo($normalizedPath,
array('encrypted' => true, 'encrypted_size' => self::$unencryptedSizes[$normalizedPath]));
unset(self::$unencryptedSizes[$normalizedPath]);
}
return $result;
}
/**
* @param string $path Path of file from which has been read
* @param string $data Data that has been read from file
@ -182,8 +208,11 @@ class Proxy extends \OC_FileProxy {
*/
public function preUnlink($path) {
// let the trashbin handle this
if (\OCP\App::isEnabled('files_trashbin')) {
$relPath = Helper::stripUserFilesPath($path);
// skip this method if the trash bin is enabled or if we delete a file
// outside of /data/user/files
if (\OCP\App::isEnabled('files_trashbin') || $relPath === false) {
return true;
}
@ -197,10 +226,7 @@ class Proxy extends \OC_FileProxy {
$util = new Util($view, $userId);
// get relative path
$relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
list($owner, $ownerPath) = $util->getUidAndFilename($relativePath);
list($owner, $ownerPath) = $util->getUidAndFilename($relPath);
// Delete keyfile & shareKey so it isn't orphaned
if (!Keymanager::deleteFileKey($view, $ownerPath)) {
@ -246,8 +272,8 @@ class Proxy extends \OC_FileProxy {
// split the path parts
$pathParts = explode('/', $path);
// FIXME: handling for /userId/cache used by webdav for chunking. The cache chunks are NOT encrypted
if (isset($pathParts[2]) && $pathParts[2] === 'cache') {
// don't try to encrypt/decrypt cache chunks or files in the trash bin
if (isset($pathParts[2]) && ($pathParts[2] === 'cache' || $pathParts[2] === 'files_trashbin')) {
return $result;
}

View File

@ -64,6 +64,9 @@ class Stream {
private $publicKey;
private $encKeyfile;
private $newFile; // helper var, we only need to write the keyfile for new files
private $isLocalTmpFile = false; // do we operate on a local tmp file
private $localTmpFile; // path of local tmp file
/**
* @var \OC\Files\View
*/
@ -91,13 +94,18 @@ class Stream {
$this->rootView = new \OC_FilesystemView('/');
}
$this->session = new \OCA\Encryption\Session($this->rootView);
$this->privateKey = $this->session->getPrivateKey();
// rawPath is relative to the data directory
$this->rawPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
$normalizedPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
if ($originalFile = Helper::getPathFromTmpFile($normalizedPath)) {
$this->rawPath = $originalFile;
$this->isLocalTmpFile = true;
$this->localTmpFile = $normalizedPath;
} else {
$this->rawPath = $normalizedPath;
}
$this->userId = Helper::getUser($this->rawPath);
@ -141,10 +149,14 @@ class Stream {
\OCA\Encryption\Helper::redirectToErrorPage($this->session);
}
$this->size = $this->rootView->filesize($this->rawPath, $mode);
$this->size = $this->rootView->filesize($this->rawPath);
}
$this->handle = $this->rootView->fopen($this->rawPath, $mode);
if ($this->isLocalTmpFile) {
$this->handle = fopen($this->localTmpFile, $mode);
} else {
$this->handle = $this->rootView->fopen($this->rawPath, $mode);
}
\OC_FileProxy::$enabled = $proxyStatus;
@ -163,15 +175,26 @@ class Stream {
}
/**
* @brief Returns the current position of the file pointer
* @return int position of the file pointer
*/
public function stream_tell() {
return ftell($this->handle);
}
/**
* @param $offset
* @param int $whence
* @return bool true if fseek was successful, otherwise false
*/
public function stream_seek($offset, $whence = SEEK_SET) {
$this->flush();
fseek($this->handle, $offset, $whence);
// this wrapper needs to return "true" for success.
// the fseek call itself returns 0 on succeess
return !fseek($this->handle, $offset, $whence);
}
@ -477,7 +500,7 @@ class Stream {
if ($this->privateKey === false) {
// cleanup
if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb') {
if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && !$this->isLocalTmpFile) {
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
@ -498,6 +521,7 @@ class Stream {
if (
$this->meta['mode'] !== 'r' &&
$this->meta['mode'] !== 'rb' &&
$this->isLocalTmpFile === false &&
$this->size > 0 &&
$this->unencryptedSize > 0
) {

View File

@ -2,9 +2,10 @@
/**
* ownCloud
*
* @author Sam Tuke, Frank Karlitschek
* @author Sam Tuke, Frank Karlitschek, Bjoern Schiessle
* @copyright 2012 Sam Tuke <samtuke@owncloud.com>,
* Frank Karlitschek <frank@owncloud.org>
* Frank Karlitschek <frank@owncloud.org>,
* Bjoern Schiessle <schiessle@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -241,11 +242,9 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if ($result->numRows() > 0) {
$row = $result->fetchRow();
if (isset($row['recovery_enabled'])) {
$recoveryEnabled[] = $row['recovery_enabled'];
}
$row = $result->fetchRow();
if ($row && isset($row['recovery_enabled'])) {
$recoveryEnabled[] = $row['recovery_enabled'];
}
}
@ -289,7 +288,7 @@ class Util {
$sql = 'UPDATE `*PREFIX*encryption` SET `recovery_enabled` = ? WHERE `uid` = ?';
$args = array(
$enabled,
$enabled ? '1' : '0',
$this->userId
);
@ -414,49 +413,6 @@ class Util {
}
/**
* @brief Fetch the last lines of a file efficiently
* @note Safe to use on large files; does not read entire file to memory
* @note Derivative of http://tekkie.flashbit.net/php/tail-functionality-in-php
*/
public function tail($filename, $numLines) {
\OC_FileProxy::$enabled = false;
$text = '';
$pos = -1;
$handle = $this->view->fopen($filename, 'r');
while ($numLines > 0) {
--$pos;
if (fseek($handle, $pos, SEEK_END) !== 0) {
rewind($handle);
$numLines = 0;
} elseif (fgetc($handle) === "\n") {
--$numLines;
}
$block_size = (-$pos) % 8192;
if ($block_size === 0 || $numLines === 0) {
$text = fread($handle, ($block_size === 0 ? 8192 : $block_size)) . $text;
}
}
fclose($handle);
\OC_FileProxy::$enabled = true;
return $text;
}
/**
* @brief Check if a given path identifies an encrypted file
* @param string $path
@ -464,20 +420,36 @@ class Util {
*/
public function isEncryptedPath($path) {
$relPath = Helper::getPathToRealFile($path);
// Disable encryption proxy so data retrieved is in its
// original form
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
if ($relPath === false) {
$relPath = Helper::stripUserFilesPath($path);
// we only need 24 byte from the last chunk
$data = '';
$handle = $this->view->fopen($path, 'r');
if (is_resource($handle)) {
// suppress fseek warining, we handle the case that fseek doesn't
// work in the else branch
if (@fseek($handle, -24, SEEK_END) === 0) {
$data = fgets($handle);
} else {
// if fseek failed on the storage we create a local copy from the file
// and read this one
fclose($handle);
$localFile = $this->view->getLocalFile($path);
$handle = fopen($localFile, 'r');
if (is_resource($handle) && fseek($handle, -24, SEEK_END) === 0) {
$data = fgets($handle);
}
}
fclose($handle);
}
$fileKey = Keymanager::getFileKey($this->view, $this, $relPath);
if ($fileKey === false) {
return false;
}
return true;
// re-enable proxy
\OC_FileProxy::$enabled = $proxyStatus;
return Crypt::isCatfileContent($data);
}
/**
@ -523,7 +495,20 @@ class Util {
$lastChunckPos = ($lastChunkNr * 8192);
// seek to end
fseek($stream, $lastChunckPos);
if (@fseek($stream, $lastChunckPos) === -1) {
// storage doesn't support fseek, we need a local copy
fclose($stream);
$localFile = $this->view->getLocalFile($path);
Helper::addTmpFileToMapper($localFile, $path);
$stream = fopen('crypt://' . $localFile, "r");
if (fseek($stream, $lastChunckPos) === -1) {
// if fseek also fails on the local storage, than
// there is nothing we can do
fclose($stream);
\OCP\Util::writeLog('Encryption library', 'couldn\'t determine size of "' . $path, \OCP\Util::ERROR);
return $result;
}
}
// get the content of the last chunk
$lastChunkContent = fread($stream, $lastChunkSize);
@ -985,8 +970,8 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if ($result->numRows() > 0) {
$row = $result->fetchRow();
$row = $result->fetchRow();
if ($row) {
$path = substr($row['path'], strlen('files'));
}
}
@ -1266,11 +1251,9 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if ($result->numRows() > 0) {
$row = $result->fetchRow();
if (isset($row['migration_status'])) {
$migrationStatus[] = $row['migration_status'];
}
$row = $result->fetchRow();
if ($row && isset($row['migration_status'])) {
$migrationStatus[] = $row['migration_status'];
}
}
@ -1378,59 +1361,32 @@ class Util {
}
}
/**
* @brief go recursively through a dir and collect all files and sub files.
* @param string $dir relative to the users files folder
* @return array with list of files relative to the users files folder
*/
public function getAllFiles($dir) {
$result = array();
$dirList = array($dir);
$content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath(
$this->userFilesDir . '/' . $dir));
// handling for re shared folders
$pathSplit = explode('/', $dir);
foreach ($content as $c) {
$sharedPart = $pathSplit[sizeof($pathSplit) - 1];
$targetPathSplit = array_reverse(explode('/', $c['path']));
$path = '';
// rebuild path
foreach ($targetPathSplit as $pathPart) {
if ($pathPart !== $sharedPart) {
$path = '/' . $pathPart . $path;
while ($dirList) {
$dir = array_pop($dirList);
$content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath(
$this->userFilesDir . '/' . $dir));
foreach ($content as $c) {
$usersPath = isset($c['usersPath']) ? $c['usersPath'] : $c['path'];
if ($c['type'] === 'dir') {
$dirList[] = substr($usersPath, strlen("files"));
} else {
break;
$result[] = substr($usersPath, strlen("files"));
}
}
$path = $dir . $path;
if ($c['type'] === 'dir') {
$result = array_merge($result, $this->getAllFiles($path));
} else {
$result[] = $path;
}
}
return $result;
}
/**
@ -1450,9 +1406,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if ($result->numRows() > 0) {
$row = $result->fetchRow();
}
$row = $result->fetchRow();
}
return $row;
@ -1476,9 +1430,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if ($result->numRows() > 0) {
$row = $result->fetchRow();
}
$row = $result->fetchRow();
}
return $row;
@ -1497,18 +1449,16 @@ class Util {
$result = $query->execute(array($id));
$source = array();
$source = null;
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if ($result->numRows() > 0) {
$source = $result->fetchRow();
}
$source = $result->fetchRow();
}
$fileOwner = false;
if (isset($source['parent'])) {
if ($source && isset($source['parent'])) {
$parent = $source['parent'];
@ -1518,16 +1468,14 @@ class Util {
$result = $query->execute(array($parent));
$item = array();
$item = null;
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if ($result->numRows() > 0) {
$item = $result->fetchRow();
}
$item = $result->fetchRow();
}
if (isset($item['parent'])) {
if ($item && isset($item['parent'])) {
$parent = $item['parent'];

View File

@ -155,7 +155,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/
function testSymmetricStreamEncryptShortFileContent() {
$filename = 'tmp-' . time() . '.test';
$filename = 'tmp-' . uniqid() . '.test';
$util = new Encryption\Util(new \OC_FilesystemView(), $this->userId);
@ -214,7 +214,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
function testSymmetricStreamEncryptLongFileContent() {
// Generate a a random filename
$filename = 'tmp-' . time() . '.test';
$filename = 'tmp-' . uniqid() . '.test';
$util = new Encryption\Util(new \OC_FilesystemView(), $this->userId);
@ -297,7 +297,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/
function testSymmetricStreamDecryptShortFileContent() {
$filename = 'tmp-' . time();
$filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///'. $this->userId . '/files/' . $filename, $this->dataShort);
@ -327,7 +327,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/
function testSymmetricStreamDecryptLongFileContent() {
$filename = 'tmp-' . time();
$filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong);
@ -418,7 +418,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/
function testRenameFile() {
$filename = 'tmp-' . time();
$filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong);
@ -431,7 +431,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$this->assertEquals($this->dataLong, $decrypt);
$newFilename = 'tmp-new-' . time();
$newFilename = 'tmp-new-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
$view->rename($filename, $newFilename);
@ -449,7 +449,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/
function testMoveFileIntoFolder() {
$filename = 'tmp-' . time();
$filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong);
@ -462,8 +462,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$this->assertEquals($this->dataLong, $decrypt);
$newFolder = '/newfolder' . time();
$newFilename = 'tmp-new-' . time();
$newFolder = '/newfolder' . uniqid();
$newFilename = 'tmp-new-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
$view->mkdir($newFolder);
$view->rename($filename, $newFolder . '/' . $newFilename);
@ -484,8 +484,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$view = new \OC\Files\View('/' . $this->userId . '/files');
$filename = '/tmp-' . time();
$folder = '/folder' . time();
$filename = '/tmp-' . uniqid();
$folder = '/folder' . uniqid();
$view->mkdir($folder);
@ -500,7 +500,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$this->assertEquals($this->dataLong, $decrypt);
$newFolder = '/newfolder/subfolder' . time();
$newFolder = '/newfolder/subfolder' . uniqid();
$view->mkdir('/newfolder');
$view->rename($folder, $newFolder);
@ -519,7 +519,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @medium
*/
function testChangePassphrase() {
$filename = 'tmp-' . time();
$filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong);
@ -557,7 +557,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/
function testViewFilePutAndGetContents() {
$filename = '/tmp-' . time();
$filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper
@ -590,7 +590,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @large
*/
function testTouchExistingFile() {
$filename = '/tmp-' . time();
$filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper
@ -614,7 +614,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @medium
*/
function testTouchFile() {
$filename = '/tmp-' . time();
$filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
$view->touch($filename);
@ -638,7 +638,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @medium
*/
function testFopenFile() {
$filename = '/tmp-' . time();
$filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper

View File

@ -8,6 +8,7 @@
require_once __DIR__ . '/../lib/helper.php';
require_once __DIR__ . '/util.php';
use OCA\Encryption;
@ -16,6 +17,18 @@ use OCA\Encryption;
*/
class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase {
const TEST_ENCRYPTION_HELPER_USER1 = "test-helper-user1";
public static function setUpBeforeClass() {
// create test user
\Test_Encryption_Util::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1, true);
}
public static function tearDownAfterClass() {
// cleanup test user
\OC_User::deleteUser(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1);
}
/**
* @medium
*/
@ -64,4 +77,28 @@ class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase {
$this->assertEquals($relativePath, Encryption\Helper::getPathToRealFile($cachePath));
}
function testGetUser() {
$path1 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/files/foo/bar.txt";
$path2 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/cache/foo/bar.txt";
$path3 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/thumbnails/foo";
$path4 ="/" . "/" . self::TEST_ENCRYPTION_HELPER_USER1;
// if we are logged-in every path should return the currently logged-in user
$this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path3));
// now log out
\Test_Encryption_Util::logoutHelper();
// now we should only get the user from /user/files and user/cache paths
$this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path1));
$this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path2));
$this->assertFalse(Encryption\Helper::getUser($path3));
$this->assertFalse(Encryption\Helper::getUser($path4));
// Log-in again
\Test_Encryption_Util::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1);
}
}

View File

@ -143,7 +143,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
$key = $this->randomKey;
$file = 'unittest-' . time() . '.txt';
$file = 'unittest-' . uniqid() . '.txt';
$util = new Encryption\Util($this->view, $this->userId);
@ -196,7 +196,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
function testRecursiveDelShareKeys() {
// generate filename
$filename = '/tmp-' . time() . '.txt';
$filename = '/tmp-' . uniqid() . '.txt';
// create folder structure
$this->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files/folder1');

View File

@ -44,8 +44,10 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase {
/**
* @var \OC_FilesystemView
*/
public $view;
public $view; // view in /data/user/files
public $rootView; // view on /data/user
public $data;
public $filename;
public static function setUpBeforeClass() {
// reset backend
@ -74,9 +76,12 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase {
// init filesystem view
$this->view = new \OC_FilesystemView('/'. \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '/files');
$this->rootView = new \OC_FilesystemView('/'. \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 );
// init short data
$this->data = 'hats';
$this->filename = 'enc_proxy_tests-' . uniqid() . '.txt';
}
public static function tearDownAfterClass() {
@ -90,21 +95,71 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase {
*/
function testPostFileSize() {
// generate filename
$filename = 'tmp-' . time() . '.txt';
$this->view->file_put_contents($filename, $this->data);
$this->view->file_put_contents($this->filename, $this->data);
\OC_FileProxy::$enabled = false;
$unencryptedSize = $this->view->filesize($filename);
$unencryptedSize = $this->view->filesize($this->filename);
\OC_FileProxy::$enabled = true;
$encryptedSize = $this->view->filesize($filename);
$encryptedSize = $this->view->filesize($this->filename);
$this->assertTrue($encryptedSize !== $unencryptedSize);
// cleanup
$this->view->unlink($this->filename);
}
function testPreUnlinkWithoutTrash() {
// remember files_trashbin state
$stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
// we want to tests with app files_trashbin enabled
\OC_App::disable('files_trashbin');
$this->view->file_put_contents($this->filename, $this->data);
// create a dummy file that we can delete something outside of data/user/files
$this->rootView->file_put_contents("dummy.txt", $this->data);
// check if all keys are generated
$this->assertTrue($this->rootView->file_exists(
'/files_encryption/share-keys/'
. $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey'));
$this->assertTrue($this->rootView->file_exists(
'/files_encryption/keyfiles/' . $this->filename . '.key'));
// delete dummy file outside of data/user/files
$this->rootView->unlink("dummy.txt");
// all keys should still exist
$this->assertTrue($this->rootView->file_exists(
'/files_encryption/share-keys/'
. $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey'));
$this->assertTrue($this->rootView->file_exists(
'/files_encryption/keyfiles/' . $this->filename . '.key'));
// delete the file in data/user/files
$this->view->unlink($this->filename);
// now also the keys should be gone
$this->assertFalse($this->rootView->file_exists(
'/files_encryption/share-keys/'
. $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey'));
$this->assertFalse($this->rootView->file_exists(
'/files_encryption/keyfiles/' . $this->filename . '.key'));
if ($stateFilesTrashbin) {
OC_App::enable('files_trashbin');
}
else {
OC_App::disable('files_trashbin');
}
}
}

View File

@ -649,9 +649,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
* @large
*/
function testRecoveryFile() {
$this->markTestIncomplete(
'No idea what\'s wrong here, this works perfectly in real-world. removeRecoveryKeys(\'/\') L709 removes correctly the keys, but for some reasons afterwards also the top-level folder "share-keys" is gone...'
);
// login as admin
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
@ -754,13 +752,13 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
* @large
*/
function testRecoveryForUser() {
$this->markTestIncomplete(
'This test drives Jenkins crazy - "Cannot modify header information - headers already sent" - line 811'
);
// login as admin
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
\OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
$result = \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
$this->assertTrue($result);
$recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
// login as user2
@ -771,6 +769,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
// enable recovery for admin
$this->assertTrue($util->setRecoveryForUser(1));
// add recovery keys for existing files (e.g. the auto-generated welcome.txt)
$util->addRecoveryKeys();
// create folder structure
$this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1);
$this->view->mkdir(
@ -809,6 +810,10 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
// change password
\OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test', 'test123');
$params = array('uid' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2,
'password' => 'test',
'recoveryPassword' => 'test123');
\OCA\Encryption\Hooks::setPassphrase($params);
// login as user2
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, false, 'test');
@ -823,8 +828,8 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
$this->assertEquals($this->dataShort, $retrievedCryptedFile2);
// cleanup
$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1);
$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->filename);
$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1);
$this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename);
// check if share key for user and recovery exists
$this->assertFalse($this->view->file_exists(
@ -889,8 +894,8 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
} catch (Exception $e) {
$this->assertEquals(0, strpos($e->getMessage(), "Following users are not set up for encryption"));
}
// login as admin
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);

View File

@ -99,7 +99,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
}
function testStreamOptions() {
$filename = '/tmp-' . time();
$filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper
@ -122,7 +122,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
}
function testStreamSetBlocking() {
$filename = '/tmp-' . time();
$filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper
@ -144,7 +144,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
* @medium
*/
function testStreamSetTimeout() {
$filename = '/tmp-' . time();
$filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper
@ -163,7 +163,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
}
function testStreamSetWriteBuffer() {
$filename = '/tmp-' . time();
$filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper
@ -180,4 +180,43 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
// tear down
$view->unlink($filename);
}
/**
* @medium
* @brief test if stream wrapper can read files outside from the data folder
*/
function testStreamFromLocalFile() {
$filename = '/' . $this->userId . '/files/' . 'tmp-' . uniqid().'.txt';
$tmpFilename = "/tmp/" . uniqid() . ".txt";
// write an encrypted file
$cryptedFile = $this->view->file_put_contents($filename, $this->dataShort);
// Test that data was successfully written
$this->assertTrue(is_int($cryptedFile));
// create a copy outside of the data folder in /tmp
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$encryptedContent = $this->view->file_get_contents($filename);
\OC_FileProxy::$enabled = $proxyStatus;
file_put_contents($tmpFilename, $encryptedContent);
\OCA\Encryption\Helper::addTmpFileToMapper($tmpFilename, $filename);
// try to read the file from /tmp
$handle = fopen("crypt://".$tmpFilename, "r");
$contentFromTmpFile = stream_get_contents($handle);
// check if it was successful
$this->assertEquals($this->dataShort, $contentFromTmpFile);
// clean up
unlink($tmpFilename);
$this->view->unlink($filename);
}
}

View File

@ -119,7 +119,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase {
function testDeleteFile() {
// generate filename
$filename = 'tmp-' . time() . '.txt';
$filename = 'tmp-' . uniqid() . '.txt';
// save file with content
$cryptedFile = file_put_contents('crypt:///' .\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort);
@ -223,7 +223,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase {
function testPermanentDeleteFile() {
// generate filename
$filename = 'tmp-' . time() . '.txt';
$filename = 'tmp-' . uniqid() . '.txt';
// save file with content
$cryptedFile = file_put_contents('crypt:///' .$this->userId. '/files/' . $filename, $this->dataShort);

View File

@ -132,6 +132,41 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
}
/**
* @medium
* @brief test detection of encrypted files
*/
function testIsEncryptedPath() {
$util = new Encryption\Util($this->view, $this->userId);
self::loginHelper($this->userId);
$unencryptedFile = '/tmpUnencrypted-' . uniqid() . '.txt';
$encryptedFile = '/tmpEncrypted-' . uniqid() . '.txt';
// Disable encryption proxy to write a unencrypted file
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$this->view->file_put_contents($this->userId . '/files/' . $unencryptedFile, $this->dataShort);
// Re-enable proxy - our work is done
\OC_FileProxy::$enabled = $proxyStatus;
// write a encrypted file
$this->view->file_put_contents($this->userId . '/files/' . $encryptedFile, $this->dataShort);
// test if both files are detected correctly
$this->assertFalse($util->isEncryptedPath($this->userId . '/files/' . $unencryptedFile));
$this->assertTrue($util->isEncryptedPath($this->userId . '/files/' . $encryptedFile));
// cleanup
$this->view->unlink($this->userId . '/files/' . $unencryptedFile, $this->dataShort);
$this->view->unlink($this->userId . '/files/' . $encryptedFile, $this->dataShort);
}
/**
* @medium
* @brief test setup of encryption directories
@ -219,7 +254,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
\OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
$filename = '/tmp-' . time() . '.test';
$filename = '/tmp-' . uniqid() . '.test';
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
@ -247,7 +282,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
function testGetFileSize() {
\Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
$filename = 'tmp-' . time();
$filename = 'tmp-' . uniqid();
$externalFilename = '/' . $this->userId . '/files/' . $filename;
// Test for 0 byte files
@ -283,7 +318,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
function testEncryptAll() {
$filename = "/encryptAll" . time() . ".txt";
$filename = "/encryptAll" . uniqid() . ".txt";
$util = new Encryption\Util($this->view, $this->userId);
// disable encryption to upload a unencrypted file
@ -315,7 +350,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
function testDecryptAll() {
$filename = "/decryptAll" . time() . ".txt";
$filename = "/decryptAll" . uniqid() . ".txt";
$util = new Encryption\Util($this->view, $this->userId);
$this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort);
@ -416,6 +451,12 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
OCA\Encryption\Hooks::login($params);
}
public static function logoutHelper() {
\OC_Util::tearDownFS();
\OC_User::setUserId('');
\OC\Files\Filesystem::tearDown();
}
/**
* helper function to set migration status to the right value
* to be able to test the migration path

View File

@ -113,7 +113,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase {
function testWebdavPUT() {
// generate filename
$filename = '/tmp-' . time() . '.txt';
$filename = '/tmp-' . uniqid() . '.txt';
// set server vars
$_SERVER['REQUEST_METHOD'] = 'OPTIONS';

View File

@ -1,3 +1,5 @@
phpseclib Lead Developer: TerraFrost (Jim Wigginton)
phpseclib Developers: monnerat (Patrick Monnerat)
phpseclib Developers: monnerat (Patrick Monnerat)
bantu (Andreas Fischer)
petrich (Hans-Jürgen Petrich)

View File

@ -4,9 +4,9 @@
MIT-licensed pure-PHP implementations of an arbitrary-precision integer
arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
AES, SSH-1, SSH-2, SFTP, and X.509
AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
* [Download (0.3.1)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.1.zip/download)
* [Download (0.3.5)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.5.zip/download)
* [Browse Git](https://github.com/phpseclib/phpseclib)
* [Documentation](http://phpseclib.sourceforge.net/)
* [Support](http://www.frostjedi.com/phpbb/viewforum.php?f=46)

View File

@ -43,6 +43,14 @@
"File": "phpseclib/",
"Math": "phpseclib/",
"Net": "phpseclib/"
},
"files": [
"phpseclib/Crypt/Random.php"
]
},
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
}
}

View File

@ -4,13 +4,13 @@
/**
* Pure-PHP implementation of AES.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
* {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
* it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}
* it'll be null-padded to 192-bits and 192 bits will be the key length until {@link Crypt_AES::setKey() setKey()}
* is called, again, at which point, it'll be recalculated.
*
* Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
@ -42,10 +42,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -59,7 +59,6 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMVIII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $
* @link http://phpseclib.sourceforge.net
*/
@ -67,7 +66,7 @@
* Include Crypt_Rijndael
*/
if (!class_exists('Crypt_Rijndael')) {
require_once 'Rijndael.php';
require_once('Rijndael.php');
}
/**#@+
@ -82,31 +81,31 @@ if (!class_exists('Crypt_Rijndael')) {
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_AES_MODE_CTR', -1);
define('CRYPT_AES_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_AES_MODE_ECB', 1);
define('CRYPT_AES_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_AES_MODE_CBC', 2);
define('CRYPT_AES_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_AES_MODE_CFB', 3);
define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_AES_MODE_OFB', 4);
define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**#@+
@ -116,11 +115,11 @@ define('CRYPT_AES_MODE_OFB', 4);
/**
* Toggles the internal implementation
*/
define('CRYPT_AES_MODE_INTERNAL', 1);
define('CRYPT_AES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_AES_MODE_MCRYPT', 2);
define('CRYPT_AES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**
@ -133,195 +132,41 @@ define('CRYPT_AES_MODE_MCRYPT', 2);
*/
class Crypt_AES extends Crypt_Rijndael {
/**
* mcrypt resource for encryption
* The namespace used by the cipher for its constants.
*
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
*
* @see Crypt_AES::encrypt()
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $enmcrypt;
/**
* mcrypt resource for decryption
*
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
*
* @see Crypt_AES::decrypt()
* @var String
* @access private
*/
var $demcrypt;
/**
* mcrypt resource for CFB mode
*
* @see Crypt_AES::encrypt()
* @see Crypt_AES::decrypt()
* @var String
* @access private
*/
var $ecb;
/**
* The SubByte S-Box
*
* @see Crypt_AES::_encryptBlock()
* @var Array
* @access intern
*/
var $sbox = array(
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
);
/**
* The inverse SubByte S-Box
*
* @see Crypt_AES::_decryptBlock()
* @var Array
* @access intern
*/
var $isbox = array(
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
);
var $const_namespace = 'AES';
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
* CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC. If not explictly set, CRYPT_AES_MODE_CBC will be used.
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_AES_MODE_ECB
*
* - CRYPT_AES_MODE_CBC
*
* - CRYPT_AES_MODE_CTR
*
* - CRYPT_AES_MODE_CFB
*
* - CRYPT_AES_MODE_OFB
*
* If not explictly set, CRYPT_AES_MODE_CBC will be used.
*
* @see Crypt_Rijndael::Crypt_Rijndael()
* @see Crypt_Base::Crypt_Base()
* @param optional Integer $mode
* @return Crypt_AES
* @access public
*/
function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
{
if ( !defined('CRYPT_AES_MODE') ) {
switch (true) {
case extension_loaded('mcrypt') && in_array('rijndael-128', mcrypt_list_algorithms()):
define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
break;
default:
define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
}
}
switch ( CRYPT_AES_MODE ) {
case CRYPT_AES_MODE_MCRYPT:
switch ($mode) {
case CRYPT_AES_MODE_ECB:
$this->paddable = true;
$this->mode = MCRYPT_MODE_ECB;
break;
case CRYPT_AES_MODE_CTR:
// ctr doesn't have a constant associated with it even though it appears to be fairly widely
// supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to
// include a compatibility layer. the layer has been implemented but, for now, is commented out.
$this->mode = 'ctr';
//$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
break;
case CRYPT_AES_MODE_CFB:
$this->mode = 'ncfb';
break;
case CRYPT_AES_MODE_OFB:
$this->mode = MCRYPT_MODE_NOFB;
break;
case CRYPT_AES_MODE_CBC:
default:
$this->paddable = true;
$this->mode = MCRYPT_MODE_CBC;
}
break;
default:
switch ($mode) {
case CRYPT_AES_MODE_ECB:
$this->paddable = true;
$this->mode = CRYPT_RIJNDAEL_MODE_ECB;
break;
case CRYPT_AES_MODE_CTR:
$this->mode = CRYPT_RIJNDAEL_MODE_CTR;
break;
case CRYPT_AES_MODE_CFB:
$this->mode = CRYPT_RIJNDAEL_MODE_CFB;
break;
case CRYPT_AES_MODE_OFB:
$this->mode = CRYPT_RIJNDAEL_MODE_OFB;
break;
case CRYPT_AES_MODE_CBC:
default:
$this->paddable = true;
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
}
}
if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
parent::Crypt_Rijndael($this->mode);
}
}
/**
* Extended Crypt_Rijndael::_setup()
*
* Optimizing the key schedule arrays ($w, $dw) for _encryptBlock() and _decryptBlock() after Crypt_Rijndael::_setup()
*
* @see Crypt_Rijndael::_setup()
* @access private
*/
function _setup()
{
if (!$this->changed) {
return;
}
$this->w = $this->dw = array();
parent::_setup();
$this->dw = array_reverse($this->dw);
$w = array_pop($this->w);
$dw = array_pop($this->dw);
foreach ($this->w as $r => $wr) {
foreach ($wr as $c => $wc) {
$w[] = $wc;
$dw[] = $this->dw[$r][$c];
}
}
$this->w = $w;
$this->dw = $dw;
parent::Crypt_Rijndael($mode);
}
/**
@ -329,6 +174,7 @@ class Crypt_AES extends Crypt_Rijndael {
*
* Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
*
* @see Crypt_Rijndael::setBlockLength()
* @access public
* @param Integer $length
*/
@ -336,610 +182,6 @@ class Crypt_AES extends Crypt_Rijndael {
{
return;
}
/**
* Sets the initialization vector. (optional)
*
* SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used. If not explictly set, it'll be assumed
* to be all zero's.
*
* @access public
* @param String $iv
*/
function setIV($iv)
{
parent::setIV($iv);
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
$this->changed = true;
}
}
/**
* Encrypts a message.
*
* $plaintext will be padded with up to 16 additional bytes. Other AES implementations may or may not pad in the
* same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
* URL:
*
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
*
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
* strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
* length.
*
* @see Crypt_AES::decrypt()
* @access public
* @param String $plaintext
*/
function encrypt($plaintext)
{
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
$this->_mcryptSetup();
// re: http://phpseclib.sourceforge.net/cfb-demo.phps
// using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
// rewritten CFB implementation the above outputs the same thing twice.
if ($this->mode == 'ncfb' && $this->continuousBuffer) {
$iv = &$this->encryptIV;
$pos = &$this->enbuffer['pos'];
$len = strlen($plaintext);
$ciphertext = '';
$i = 0;
if ($pos) {
$orig_pos = $pos;
$max = 16 - $pos;
if ($len >= $max) {
$i = $max;
$len-= $max;
$pos = 0;
} else {
$i = $len;
$pos+= $len;
$len = 0;
}
$ciphertext = substr($iv, $orig_pos) ^ $plaintext;
$iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
$this->enbuffer['enmcrypt_init'] = true;
}
if ($len >= 16) {
if ($this->enbuffer['enmcrypt_init'] === false || $len > 280) {
if ($this->enbuffer['enmcrypt_init'] === true) {
mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
$this->enbuffer['enmcrypt_init'] = false;
}
$ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 16));
$iv = substr($ciphertext, -16);
$len%= 16;
} else {
while ($len >= 16) {
$iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 16);
$ciphertext.= $iv;
$len-= 16;
$i+= 16;
}
}
}
if ($len) {
$iv = mcrypt_generic($this->ecb, $iv);
$block = $iv ^ substr($plaintext, -$len);
$iv = substr_replace($iv, $block, 0, $len);
$ciphertext.= $block;
$pos = $len;
}
return $ciphertext;
}
if ($this->paddable) {
$plaintext = $this->_pad($plaintext);
}
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
if (!$this->continuousBuffer) {
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
}
return $ciphertext;
}
return parent::encrypt($plaintext);
}
/**
* Decrypts a message.
*
* If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
*
* @see Crypt_AES::encrypt()
* @access public
* @param String $ciphertext
*/
function decrypt($ciphertext)
{
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
$this->_mcryptSetup();
if ($this->mode == 'ncfb' && $this->continuousBuffer) {
$iv = &$this->decryptIV;
$pos = &$this->debuffer['pos'];
$len = strlen($ciphertext);
$plaintext = '';
$i = 0;
if ($pos) {
$orig_pos = $pos;
$max = 16 - $pos;
if ($len >= $max) {
$i = $max;
$len-= $max;
$pos = 0;
} else {
$i = $len;
$pos+= $len;
$len = 0;
}
// ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
$plaintext = substr($iv, $orig_pos) ^ $ciphertext;
$iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
}
if ($len >= 16) {
$cb = substr($ciphertext, $i, $len - $len % 16);
$plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
$iv = substr($cb, -16);
$len%= 16;
}
if ($len) {
$iv = mcrypt_generic($this->ecb, $iv);
$plaintext.= $iv ^ substr($ciphertext, -$len);
$iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
$pos = $len;
}
return $plaintext;
}
if ($this->paddable) {
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
}
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
if (!$this->continuousBuffer) {
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
}
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
}
return parent::decrypt($ciphertext);
}
/**
* Setup mcrypt
*
* Validates all the variables.
*
* @access private
*/
function _mcryptSetup()
{
if (!$this->changed) {
return;
}
if (!$this->explicit_key_length) {
// this just copied from Crypt_Rijndael::_setup()
$length = strlen($this->key) >> 2;
if ($length > 8) {
$length = 8;
} else if ($length < 4) {
$length = 4;
}
$this->Nk = $length;
$this->key_size = $length << 2;
}
switch ($this->Nk) {
case 4: // 128
$this->key_size = 16;
break;
case 5: // 160
case 6: // 192
$this->key_size = 24;
break;
case 7: // 224
case 8: // 256
$this->key_size = 32;
}
$this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
if (!isset($this->enmcrypt)) {
$mode = $this->mode;
//$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
$this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
$this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
if ($mode == 'ncfb') {
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
}
} // else should mcrypt_generic_deinit be called?
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
if ($this->mode == 'ncfb') {
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
}
$this->changed = false;
}
/**
* Encrypts a block
*
* Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
*
* @see Crypt_Rijndael::_encryptBlock()
* @access private
* @param String $in
* @return String
*/
function _encryptBlock($in)
{
$state = unpack('N*', $in);
$sbox = $this->sbox;
$w = $this->w;
$t0 = $this->t0;
$t1 = $this->t1;
$t2 = $this->t2;
$t3 = $this->t3;
// addRoundKey
$s0 = $state[1] ^ $w[4];
$s1 = $state[2] ^ $w[5];
$s2 = $state[3] ^ $w[6];
$s3 = $state[4] ^ $w[7];
// shiftRows + subWord + mixColumns + addRoundKey
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[8];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[9];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[10];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[11];
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[12];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[13];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[14];
$s3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[15];
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[16];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[17];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[18];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[19];
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[20];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[21];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[22];
$s3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[23];
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[24];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[25];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[26];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[27];
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[28];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[29];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[30];
$s3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[31];
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[32];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[33];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[34];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[35];
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[36];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[37];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[38];
$s3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[39];
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[40];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[41];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[42];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[43];
switch ($this->Nr) {
case 10:
break;
case 14:
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[44];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[45];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[46];
$s3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[47];
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[48];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[49];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[50];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[51];
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[52];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[53];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[54];
$s3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[55];
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[56];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[57];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[58];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[59];
break;
case 12:
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[44];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[45];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[46];
$s3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[47];
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[48];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[49];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[50];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[51];
break;
case 13:
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[44];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[45];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[46];
$s3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[47];
$e0 = $t0[($s0 >> 24) & 0xff] ^ $t1[($s1 >> 16) & 0xff] ^ $t2[($s2 >> 8) & 0xff] ^ $t3[$s3 & 0xff] ^ $w[48];
$e1 = $t0[($s1 >> 24) & 0xff] ^ $t1[($s2 >> 16) & 0xff] ^ $t2[($s3 >> 8) & 0xff] ^ $t3[$s0 & 0xff] ^ $w[49];
$e2 = $t0[($s2 >> 24) & 0xff] ^ $t1[($s3 >> 16) & 0xff] ^ $t2[($s0 >> 8) & 0xff] ^ $t3[$s1 & 0xff] ^ $w[50];
$e3 = $t0[($s3 >> 24) & 0xff] ^ $t1[($s0 >> 16) & 0xff] ^ $t2[($s1 >> 8) & 0xff] ^ $t3[$s2 & 0xff] ^ $w[51];
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[52];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[53];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[54];
$e3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[55];
// Note: Here we skip $s3 but using $e3
$e0 = $s0;
$e1 = $s1;
$e2 = $s2;
// $e3 = $s3;
break;
default: // 11
$s0 = $t0[($e0 >> 24) & 0xff] ^ $t1[($e1 >> 16) & 0xff] ^ $t2[($e2 >> 8) & 0xff] ^ $t3[$e3 & 0xff] ^ $w[44];
$s1 = $t0[($e1 >> 24) & 0xff] ^ $t1[($e2 >> 16) & 0xff] ^ $t2[($e3 >> 8) & 0xff] ^ $t3[$e0 & 0xff] ^ $w[45];
$s2 = $t0[($e2 >> 24) & 0xff] ^ $t1[($e3 >> 16) & 0xff] ^ $t2[($e0 >> 8) & 0xff] ^ $t3[$e1 & 0xff] ^ $w[46];
$e3 = $t0[($e3 >> 24) & 0xff] ^ $t1[($e0 >> 16) & 0xff] ^ $t2[($e1 >> 8) & 0xff] ^ $t3[$e2 & 0xff] ^ $w[47];
// Note: Here we skip $s3 but using $e3
$e0 = $s0;
$e1 = $s1;
$e2 = $s2;
// $e3 = $s3;
}
// subWord
$e0 = $sbox[$e0 & 0xff] | ($sbox[($e0 >> 8) & 0xff] << 8) | ($sbox[($e0 >> 16) & 0xff] << 16) | ($sbox[($e0 >> 24) & 0xff] << 24);
$e1 = $sbox[$e1 & 0xff] | ($sbox[($e1 >> 8) & 0xff] << 8) | ($sbox[($e1 >> 16) & 0xff] << 16) | ($sbox[($e1 >> 24) & 0xff] << 24);
$e2 = $sbox[$e2 & 0xff] | ($sbox[($e2 >> 8) & 0xff] << 8) | ($sbox[($e2 >> 16) & 0xff] << 16) | ($sbox[($e2 >> 24) & 0xff] << 24);
$e3 = $sbox[$e3 & 0xff] | ($sbox[($e3 >> 8) & 0xff] << 8) | ($sbox[($e3 >> 16) & 0xff] << 16) | ($sbox[($e3 >> 24) & 0xff] << 24);
// shiftRows + addRoundKey
return pack('N*',
($e0 & 0xFF000000) ^ ($e1 & 0x00FF0000) ^ ($e2 & 0x0000FF00) ^ ($e3 & 0x000000FF) ^ $w[0],
($e1 & 0xFF000000) ^ ($e2 & 0x00FF0000) ^ ($e3 & 0x0000FF00) ^ ($e0 & 0x000000FF) ^ $w[1],
($e2 & 0xFF000000) ^ ($e3 & 0x00FF0000) ^ ($e0 & 0x0000FF00) ^ ($e1 & 0x000000FF) ^ $w[2],
($e3 & 0xFF000000) ^ ($e0 & 0x00FF0000) ^ ($e1 & 0x0000FF00) ^ ($e2 & 0x000000FF) ^ $w[3]
);
}
/**
* Decrypts a block
*
* Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
*
* @see Crypt_Rijndael::_decryptBlock()
* @access private
* @param String $in
* @return String
*/
function _decryptBlock($in)
{
$state = unpack('N*', $in);
$sbox = $this->isbox;
$dw = $this->dw;
$dt0 = $this->dt0;
$dt1 = $this->dt1;
$dt2 = $this->dt2;
$dt3 = $this->dt3;
// addRoundKey
$s0 = $state[1] ^ $dw[4];
$s1 = $state[2] ^ $dw[5];
$s2 = $state[3] ^ $dw[6];
$s3 = $state[4] ^ $dw[7];
// invShiftRows + invSubBytes + invMixColumns + addRoundKey
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[8];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[9];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[10];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[11];
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[12];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[13];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[14];
$s3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[15];
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[16];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[17];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[18];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[19];
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[20];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[21];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[22];
$s3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[23];
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[24];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[25];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[26];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[27];
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[28];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[29];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[30];
$s3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[31];
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[32];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[33];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[34];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[35];
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[36];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[37];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[38];
$s3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[39];
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[40];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[41];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[42];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[43];
switch ($this->Nr) {
case 10:
break;
case 14:
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[44];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[45];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[46];
$s3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[47];
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[48];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[49];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[50];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[51];
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[52];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[53];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[54];
$s3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[55];
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[56];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[57];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[58];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[59];
break;
case 12:
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[44];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[45];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[46];
$s3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[47];
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[48];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[49];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[50];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[51];
break;
case 13:
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[44];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[45];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[46];
$s3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[47];
$e0 = $dt0[($s0 >> 24) & 0xff] ^ $dt1[($s3 >> 16) & 0xff] ^ $dt2[($s2 >> 8) & 0xff] ^ $dt3[$s1 & 0xff] ^ $dw[48];
$e1 = $dt0[($s1 >> 24) & 0xff] ^ $dt1[($s0 >> 16) & 0xff] ^ $dt2[($s3 >> 8) & 0xff] ^ $dt3[$s2 & 0xff] ^ $dw[49];
$e2 = $dt0[($s2 >> 24) & 0xff] ^ $dt1[($s1 >> 16) & 0xff] ^ $dt2[($s0 >> 8) & 0xff] ^ $dt3[$s3 & 0xff] ^ $dw[50];
$e3 = $dt0[($s3 >> 24) & 0xff] ^ $dt1[($s2 >> 16) & 0xff] ^ $dt2[($s1 >> 8) & 0xff] ^ $dt3[$s0 & 0xff] ^ $dw[51];
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[52];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[53];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[54];
$e3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[55];
// Note: Here we skip $s3 but using $e3
$e0 = $s0;
$e1 = $s1;
$e2 = $s2;
// $e3 = $s3;
break;
default: // 11
$s0 = $dt0[($e0 >> 24) & 0xff] ^ $dt1[($e3 >> 16) & 0xff] ^ $dt2[($e2 >> 8) & 0xff] ^ $dt3[$e1 & 0xff] ^ $dw[44];
$s1 = $dt0[($e1 >> 24) & 0xff] ^ $dt1[($e0 >> 16) & 0xff] ^ $dt2[($e3 >> 8) & 0xff] ^ $dt3[$e2 & 0xff] ^ $dw[45];
$s2 = $dt0[($e2 >> 24) & 0xff] ^ $dt1[($e1 >> 16) & 0xff] ^ $dt2[($e0 >> 8) & 0xff] ^ $dt3[$e3 & 0xff] ^ $dw[46];
$e3 = $dt0[($e3 >> 24) & 0xff] ^ $dt1[($e2 >> 16) & 0xff] ^ $dt2[($e1 >> 8) & 0xff] ^ $dt3[$e0 & 0xff] ^ $dw[47];
// Note: Here we skip $s3 but using $e3
$e0 = $s0;
$e1 = $s1;
$e2 = $s2;
// $e3 = $s3;
}
// invSubWord
$e0 = $sbox[$e0 & 0xff] | ($sbox[($e0 >> 8) & 0xff] << 8) | ($sbox[($e0 >> 16) & 0xff] << 16) | ($sbox[($e0 >> 24) & 0xff] << 24);
$e1 = $sbox[$e1 & 0xff] | ($sbox[($e1 >> 8) & 0xff] << 8) | ($sbox[($e1 >> 16) & 0xff] << 16) | ($sbox[($e1 >> 24) & 0xff] << 24);
$e2 = $sbox[$e2 & 0xff] | ($sbox[($e2 >> 8) & 0xff] << 8) | ($sbox[($e2 >> 16) & 0xff] << 16) | ($sbox[($e2 >> 24) & 0xff] << 24);
$e3 = $sbox[$e3 & 0xff] | ($sbox[($e3 >> 8) & 0xff] << 8) | ($sbox[($e3 >> 16) & 0xff] << 16) | ($sbox[($e3 >> 24) & 0xff] << 24);
// invShiftRows + addRoundKey
return pack('N*',
($e0 & 0xFF000000) ^ ($e3 & 0x00FF0000) ^ ($e2 & 0x0000FF00) ^ ($e1 & 0x000000FF) ^ $dw[0],
($e1 & 0xFF000000) ^ ($e0 & 0x00FF0000) ^ ($e3 & 0x0000FF00) ^ ($e2 & 0x000000FF) ^ $dw[1],
($e2 & 0xFF000000) ^ ($e1 & 0x00FF0000) ^ ($e0 & 0x0000FF00) ^ ($e3 & 0x000000FF) ^ $dw[2],
($e3 & 0xFF000000) ^ ($e2 & 0x00FF0000) ^ ($e1 & 0x0000FF00) ^ ($e0 & 0x000000FF) ^ $dw[3]
);
}
/**
* Treat consecutive "packets" as if they are a continuous buffer.
*
* The default behavior.
*
* @see Crypt_Rijndael::disableContinuousBuffer()
* @access public
*/
function enableContinuousBuffer()
{
parent::enableContinuousBuffer();
if (CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT) {
$this->enbuffer['enmcrypt_init'] = true;
$this->debuffer['demcrypt_init'] = true;
}
}
/**
* Treat consecutive packets as if they are a discontinuous buffer.
*
* The default behavior.
*
* @see Crypt_Rijndael::enableContinuousBuffer()
* @access public
*/
function disableContinuousBuffer()
{
parent::disableContinuousBuffer();
if (CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT) {
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
}
}
}
// vim: ts=4:sw=4:et:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,678 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Pure-PHP implementation of Blowfish.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://en.wikipedia.org/wiki/Blowfish_(cipher) Wikipedia description of Blowfish}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include('Crypt/Blowfish.php');
*
* $blowfish = new Crypt_Blowfish();
*
* $blowfish->setKey('12345678901234567890123456789012');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $blowfish->decrypt($blowfish->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Blowfish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright MMVII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 1.0
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
require_once('Base.php');
}
/**#@+
* @access public
* @see Crypt_Blowfish::encrypt()
* @see Crypt_Blowfish::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_BLOWFISH_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_BLOWFISH_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_BLOWFISH_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**#@+
* @access private
* @see Crypt_Blowfish::Crypt_Blowfish()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_BLOWFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_BLOWFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**
* Pure-PHP implementation of Blowfish.
*
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @version 1.0
* @access public
* @package Crypt_Blowfish
*/
class Crypt_Blowfish extends Crypt_Base {
/**
* Block Length of the cipher
*
* @see Crypt_Base::block_size
* @var Integer
* @access private
*/
var $block_size = 8;
/**
* The default password key_size used by setPassword()
*
* @see Crypt_Base::password_key_size
* @see Crypt_Base::setPassword()
* @var Integer
* @access private
*/
var $password_key_size = 56;
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'BLOWFISH';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'blowfish';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var Integer
* @access private
*/
var $cfb_init_len = 500;
/**
* The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
*
* S-Box 1
*
* @access private
* @var array
*/
var $sbox0 = array (
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
);
/**
* S-Box 1
*
* @access private
* @var array
*/
var $sbox1 = array(
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
);
/**
* S-Box 2
*
* @access private
* @var array
*/
var $sbox2 = array(
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
);
/**
* S-Box 3
*
* @access private
* @var array
*/
var $sbox3 = array(
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
);
/**
* P-Array consists of 18 32-bit subkeys
*
* @var array $parray
* @access private
*/
var $parray = array(
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
);
/**
* The BCTX-working Array
*
* Holds the expanded key [p] and the key-depended s-boxes [sb]
*
* @var array $bctx
* @access private
*/
var $bctx;
/**
* Holds the last used key
*
* @var Array
* @access private
*/
var $kl;
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_BLOWFISH_MODE_ECB
*
* - CRYPT_BLOWFISH_MODE_CBC
*
* - CRYPT_BLOWFISH_MODE_CTR
*
* - CRYPT_BLOWFISH_MODE_CFB
*
* - CRYPT_BLOWFISH_MODE_OFB
*
* If not explictly set, CRYPT_BLOWFISH_MODE_CBC will be used.
*
* @see Crypt_Base::Crypt_Base()
* @param optional Integer $mode
* @access public
*/
function Crypt_Blowfish($mode = CRYPT_BLOWFISH_MODE_CBC)
{
parent::Crypt_Base($mode);
}
/**
* Sets the key.
*
* Keys can be of any length. Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
* If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
* with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
*
* If the key is more than 448-bits, we trim the excess bits.
*
* If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
*
* @access public
* @see Crypt_Base::setKey()
* @param String $key
*/
function setKey($key)
{
$keylength = strlen($key);
if (!$keylength) {
$key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
}
elseif ($keylength > 56) {
$key = substr($key, 0, 56);
}
parent::setKey($key);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
// already expanded
return;
}
$this->kl = array('key' => $this->key);
/* key-expanding p[] and S-Box building sb[] */
$this->bctx = array(
'p' => array(),
'sb' => array(
$this->sbox0,
$this->sbox1,
$this->sbox2,
$this->sbox3
)
);
// unpack binary string in unsigned chars
$key = array_values(unpack('C*', $this->key));
$keyl = count($key);
for ($j = 0, $i = 0; $i < 18; ++$i) {
// xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
for ($data = 0, $k = 0; $k < 4; ++$k) {
$data = ($data << 8) | $key[$j];
if (++$j >= $keyl) {
$j = 0;
}
}
$this->bctx['p'][] = $this->parray[$i] ^ $data;
}
// encrypt the zero-string, replace P1 and P2 with the encrypted data,
// encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
$data = "\0\0\0\0\0\0\0\0";
for ($i = 0; $i < 18; $i += 2) {
list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
$this->bctx['p'][$i ] = $l;
$this->bctx['p'][$i + 1] = $r;
}
for ($i = 0; $i < 4; ++$i) {
for ($j = 0; $j < 256; $j += 2) {
list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
$this->bctx['sb'][$i][$j ] = $l;
$this->bctx['sb'][$i][$j + 1] = $r;
}
}
}
/**
* Encrypts a block
*
* @access private
* @param String $in
* @return String
*/
function _encryptBlock($in)
{
$p = $this->bctx["p"];
// extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower
$sb_0 = $this->bctx["sb"][0];
$sb_1 = $this->bctx["sb"][1];
$sb_2 = $this->bctx["sb"][2];
$sb_3 = $this->bctx["sb"][3];
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
for ($i = 0; $i < 16; $i+= 2) {
$l^= $p[$i];
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= $p[$i + 1];
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
}
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
}
/**
* Decrypts a block
*
* @access private
* @param String $in
* @return String
*/
function _decryptBlock($in)
{
$p = $this->bctx["p"];
$sb_0 = $this->bctx["sb"][0];
$sb_1 = $this->bctx["sb"][1];
$sb_2 = $this->bctx["sb"][2];
$sb_3 = $this->bctx["sb"][3];
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
for ($i = 17; $i > 2; $i-= 2) {
$l^= $p[$i];
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= $p[$i - 1];
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
}
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10);
switch (true) {
case $gen_hi_opt_code:
$code_hash = md5(str_pad("Crypt_Blowfish, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
$code_hash = "Crypt_Blowfish, {$this->mode}";
}
if (!isset($lambda_functions[$code_hash])) {
switch (true) {
case $gen_hi_opt_code:
$p = $this->bctx['p'];
$init_crypt = '
static $sb_0, $sb_1, $sb_2, $sb_3;
if (!$sb_0) {
$sb_0 = $self->bctx["sb"][0];
$sb_1 = $self->bctx["sb"][1];
$sb_2 = $self->bctx["sb"][2];
$sb_3 = $self->bctx["sb"][3];
}
';
break;
default:
$p = array();
for ($i = 0; $i < 18; ++$i) {
$p[] = '$p_' . $i;
}
$init_crypt = '
list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"];
list(' . implode(',', $p) . ') = $self->bctx["p"];
';
}
// Generating encrypt code:
$encrypt_block = '
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
';
for ($i = 0; $i < 16; $i+= 2) {
$encrypt_block.= '
$l^= ' . $p[$i] . ';
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= ' . $p[$i + 1] . ';
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
';
}
$encrypt_block.= '
$in = pack("N*",
$r ^ ' . $p[17] . ',
$l ^ ' . $p[16] . '
);
';
// Generating decrypt code:
$decrypt_block = '
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
';
for ($i = 17; $i > 2; $i-= 2) {
$decrypt_block.= '
$l^= ' . $p[$i] . ';
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= ' . $p[$i - 1] . ';
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
';
}
$decrypt_block.= '
$in = pack("N*",
$r ^ ' . $p[0] . ',
$l ^ ' . $p[1] . '
);
';
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'init_encrypt' => '',
'init_decrypt' => '',
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
$this->inline_crypt = $lambda_functions[$code_hash];
}
}
// vim: ts=4:sw=4:et:
// vim6: fdl=1:

File diff suppressed because it is too large Load Diff

View File

@ -52,7 +52,6 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMVII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
* @link http://phpseclib.sourceforge.net
*/
@ -83,6 +82,15 @@ define('CRYPT_HASH_MODE_HASH', 3);
* @package Crypt_Hash
*/
class Crypt_Hash {
/**
* Hash Parameter
*
* @see Crypt_Hash::setHash()
* @var Integer
* @access private
*/
var $hashParam;
/**
* Byte-length of compression blocks / key (Internal HMAC)
*
@ -168,13 +176,26 @@ class Crypt_Hash {
* Keys can be of any length.
*
* @access public
* @param String $key
* @param optional String $key
*/
function setKey($key = false)
{
$this->key = $key;
}
/**
* Gets the hash function.
*
* As set by the constructor or by the setHash() method.
*
* @access public
* @return String
*/
function getHash()
{
return $this->hashParam;
}
/**
* Sets the hash function.
*
@ -183,7 +204,7 @@ class Crypt_Hash {
*/
function setHash($hash)
{
$hash = strtolower($hash);
$this->hashParam = $hash = strtolower($hash);
switch ($hash) {
case 'md5-96':
case 'sha1-96':
@ -350,7 +371,7 @@ class Crypt_Hash {
* Wrapper for MD5
*
* @access private
* @param String $text
* @param String $m
*/
function _md5($m)
{
@ -361,7 +382,7 @@ class Crypt_Hash {
* Wrapper for SHA1
*
* @access private
* @param String $text
* @param String $m
*/
function _sha1($m)
{
@ -374,7 +395,7 @@ class Crypt_Hash {
* See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
*
* @access private
* @param String $text
* @param String $m
*/
function _md2($m)
{
@ -450,7 +471,7 @@ class Crypt_Hash {
* See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
*
* @access private
* @param String $text
* @param String $m
*/
function _sha256($m)
{
@ -555,7 +576,7 @@ class Crypt_Hash {
* Pure-PHP implementation of SHA384 and SHA512
*
* @access private
* @param String $text
* @param String $m
*/
function _sha512($m)
{
@ -784,9 +805,8 @@ class Crypt_Hash {
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
* possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
*
* @param String $string
* @param optional Integer $index
* @return String
* @param Integer $...
* @return Integer
* @see _sha256()
* @access private
*/

View File

@ -0,0 +1,656 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Pure-PHP implementation of RC2.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://tools.ietf.org/html/rfc2268}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include('Crypt/RC2.php');
*
* $rc2 = new Crypt_RC2();
*
* $rc2->setKey('abcdefgh');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $rc2->decrypt($rc2->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_RC2
* @author Patrick Monnerat <pm@datasphere.ch>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
require_once('Base.php');
}
/**#@+
* @access public
* @see Crypt_RC2::encrypt()
* @see Crypt_RC2::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_RC2_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_RC2_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_RC2_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**#@+
* @access private
* @see Crypt_RC2::Crypt_RC2()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_RC2_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_RC2_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**
* Pure-PHP implementation of RC2.
*
* @version 0.1.1
* @access public
* @package Crypt_RC2
*/
class Crypt_RC2 extends Crypt_Base {
/**
* Block Length of the cipher
*
* @see Crypt_Base::block_size
* @var Integer
* @access private
*/
var $block_size = 8;
/**
* The Key
*
* @see Crypt_Base::key
* @see setKey()
* @var String
* @access private
*/
var $key = "\0";
/**
* The default password key_size used by setPassword()
*
* @see Crypt_Base::password_key_size
* @see Crypt_Base::setPassword()
* @var Integer
* @access private
*/
var $password_key_size = 16; // = 128 bits
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'RC2';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'rc2';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var Integer
* @access private
*/
var $cfb_init_len = 500;
/**
* The key length in bits.
*
* @see Crypt_RC2::setKeyLength()
* @see Crypt_RC2::setKey()
* @var Integer
* @access private
* @internal Should be in range [1..1024].
* @internal Changing this value after setting the key has no effect.
*/
var $default_key_length = 1024;
/**
* The Key Schedule
*
* @see Crypt_RC2::_setupKey()
* @var Array
* @access private
*/
var $keys;
/**
* Key expansion randomization table.
* Twice the same 256-value sequence to save a modulus in key expansion.
*
* @see Crypt_RC2::setKey()
* @var Array
* @access private
*/
var $pitable = array(
0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD,
0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
);
/**
* Inverse key expansion randomization table.
*
* @see Crypt_RC2::setKey()
* @var Array
* @access private
*/
var $invpitable = array(
0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66,
0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4,
0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20,
0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53,
0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68,
0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B,
0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12,
0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB,
0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3,
0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26,
0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67,
0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB,
0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC,
0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60,
0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7,
0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD,
0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24,
0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31,
0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE,
0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99,
0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C,
0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA,
0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35,
0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61,
0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72,
0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3,
0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F,
0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9,
0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77,
0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75,
0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87,
0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
);
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_RC2_MODE_ECB
*
* - CRYPT_RC2_MODE_CBC
*
* - CRYPT_RC2_MODE_CTR
*
* - CRYPT_RC2_MODE_CFB
*
* - CRYPT_RC2_MODE_OFB
*
* If not explictly set, CRYPT_RC2_MODE_CBC will be used.
*
* @see Crypt_Base::Crypt_Base()
* @param optional Integer $mode
* @access public
*/
function Crypt_RC2($mode = CRYPT_RC2_MODE_CBC)
{
parent::Crypt_Base($mode);
$this->setKey('');
}
/**
* Sets the key length
*
* Valid key lengths are 1 to 1024.
* Calling this function after setting the key has no effect until the next
* Crypt_RC2::setKey() call.
*
* @access public
* @param Integer $length in bits
*/
function setKeyLength($length)
{
if ($length >= 1 && $length <= 1024) {
$this->default_key_length = $length;
}
}
/**
* Sets the key.
*
* Keys can be of any length. RC2, itself, uses 1 to 1024 bit keys (eg.
* strlen($key) <= 128), however, we only use the first 128 bytes if $key
* has more then 128 bytes in it, and set $key to a single null byte if
* it is empty.
*
* If the key is not explicitly set, it'll be assumed to be a single
* null byte.
*
* @see Crypt_Base::setKey()
* @access public
* @param String $key
* @param Integer $t1 optional Effective key length in bits.
*/
function setKey($key, $t1 = 0)
{
if ($t1 <= 0) {
$t1 = $this->default_key_length;
} else if ($t1 > 1024) {
$t1 = 1024;
}
// Key byte count should be 1..128.
$key = strlen($key) ? substr($key, 0, 128): "\x00";
$t = strlen($key);
// The mcrypt RC2 implementation only supports effective key length
// of 1024 bits. It is however possible to handle effective key
// lengths in range 1..1024 by expanding the key and applying
// inverse pitable mapping to the first byte before submitting it
// to mcrypt.
// Key expansion.
$l = array_values(unpack('C*', $key));
$t8 = ($t1 + 7) >> 3;
$tm = 0xFF >> (8 * $t8 - $t1);
// Expand key.
$pitable = $this->pitable;
for ($i = $t; $i < 128; $i++) {
$l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]];
}
$i = 128 - $t8;
$l[$i] = $pitable[$l[$i] & $tm];
while ($i--) {
$l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]];
}
// Prepare the key for mcrypt.
$l[0] = $this->invpitable[$l[0]];
array_unshift($l, 'C*');
parent::setKey(call_user_func_array('pack', $l));
}
/**
* Encrypts a block
*
* @see Crypt_Base::_encryptBlock()
* @see Crypt_Base::encrypt()
* @access private
* @param String $in
* @return String
*/
function _encryptBlock($in)
{
list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
$keys = $this->keys;
$limit = 20;
$actions = array($limit => 44, 44 => 64);
$j = 0;
for (;;) {
// Mixing round.
$r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
$r0 |= $r0 >> 16;
$r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
$r1 |= $r1 >> 16;
$r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
$r2 |= $r2 >> 16;
$r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
$r3 |= $r3 >> 16;
if ($j == $limit) {
if ($limit == 64) {
break;
}
// Mashing round.
$r0 += $keys[$r3 & 0x3F];
$r1 += $keys[$r0 & 0x3F];
$r2 += $keys[$r1 & 0x3F];
$r3 += $keys[$r2 & 0x3F];
$limit = $actions[$limit];
}
}
return pack('vvvv', $r0, $r1, $r2, $r3);
}
/**
* Decrypts a block
*
* @see Crypt_Base::_decryptBlock()
* @see Crypt_Base::decrypt()
* @access private
* @param String $in
* @return String
*/
function _decryptBlock($in)
{
list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
$keys = $this->keys;
$limit = 44;
$actions = array($limit => 20, 20 => 0);
$j = 64;
for (;;) {
// R-mixing round.
$r3 = ($r3 | ($r3 << 16)) >> 5;
$r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
$r2 = ($r2 | ($r2 << 16)) >> 3;
$r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
$r1 = ($r1 | ($r1 << 16)) >> 2;
$r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
$r0 = ($r0 | ($r0 << 16)) >> 1;
$r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
if ($j == $limit) {
if (!$limit) {
break;
}
// R-mashing round.
$r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
$r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
$r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
$r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;
$limit = $actions[$limit];
}
}
return pack('vvvv', $r0, $r1, $r2, $r3);
}
/**
* Creates the key schedule
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
// Key has already been expanded in Crypt_RC2::setKey():
// Only the first value must be altered.
$l = unpack('Ca/Cb/v*', $this->key);
array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8));
unset($l['a']);
unset($l['b']);
$this->keys = $l;
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions = &Crypt_RC2::_getLambdaFunctions();
// The first 10 generated $lambda_functions will use the $keys hardcoded as integers
// for the mixing rounds, for better inline crypt performance [~20% faster].
// But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
$keys = $this->keys;
if (count($lambda_functions) >= 10) {
foreach ($this->keys as $k => $v) {
$keys[$k] = '$keys[' . $k . ']';
}
}
$code_hash = md5(str_pad("Crypt_RC2, {$this->mode}, ", 32, "\0") . implode(',', $keys));
// Is there a re-usable $lambda_functions in there?
// If not, we have to create it.
if (!isset($lambda_functions[$code_hash])) {
// Init code for both, encrypt and decrypt.
$init_crypt = '$keys = $self->keys;';
// $in is the current 8 bytes block which has to be en/decrypt
$encrypt_block = $decrypt_block = '
$in = unpack("v4", $in);
$r0 = $in[1];
$r1 = $in[2];
$r2 = $in[3];
$r3 = $in[4];
';
// Create code for encryption.
$limit = 20;
$actions = array($limit => 44, 44 => 64);
$j = 0;
for (;;) {
// Mixing round.
$encrypt_block .= '
$r0 = (($r0 + ' . $keys[$j++] . ' +
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
$r0 |= $r0 >> 16;
$r1 = (($r1 + ' . $keys[$j++] . ' +
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
$r1 |= $r1 >> 16;
$r2 = (($r2 + ' . $keys[$j++] . ' +
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
$r2 |= $r2 >> 16;
$r3 = (($r3 + ' . $keys[$j++] . ' +
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
$r3 |= $r3 >> 16;';
if ($j == $limit) {
if ($limit == 64) {
break;
}
// Mashing round.
$encrypt_block .= '
$r0 += $keys[$r3 & 0x3F];
$r1 += $keys[$r0 & 0x3F];
$r2 += $keys[$r1 & 0x3F];
$r3 += $keys[$r2 & 0x3F];';
$limit = $actions[$limit];
}
}
$encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
// Create code for decryption.
$limit = 44;
$actions = array($limit => 20, 20 => 0);
$j = 64;
for (;;) {
// R-mixing round.
$decrypt_block .= '
$r3 = ($r3 | ($r3 << 16)) >> 5;
$r3 = ($r3 - ' . $keys[--$j] . ' -
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
$r2 = ($r2 | ($r2 << 16)) >> 3;
$r2 = ($r2 - ' . $keys[--$j] . ' -
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
$r1 = ($r1 | ($r1 << 16)) >> 2;
$r1 = ($r1 - ' . $keys[--$j] . ' -
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
$r0 = ($r0 | ($r0 << 16)) >> 1;
$r0 = ($r0 - ' . $keys[--$j] . ' -
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
if ($j == $limit) {
if (!$limit) {
break;
}
// R-mashing round.
$decrypt_block .= '
$r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
$r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
$r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
$r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
$limit = $actions[$limit];
}
}
$decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
// Creates the inline-crypt function
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
// Set the inline-crypt function as callback in: $this->inline_crypt
$this->inline_crypt = $lambda_functions[$code_hash];
}
}
// vim: ts=4:sw=4:et:
// vim6: fdl=1:

View File

@ -14,7 +14,7 @@
* - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
*
* RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
* ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.
* ARCFOUR or ARC4 because RC4 is how it is referred to in the SSH1 specification.
*
* Here's a short example of how to use this library:
* <code>
@ -41,10 +41,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -58,10 +58,18 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMVII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
require_once('Base.php');
}
/**#@+
* @access private
* @see Crypt_RC4::Crypt_RC4()
@ -69,11 +77,11 @@
/**
* Toggles the internal implementation
*/
define('CRYPT_RC4_MODE_INTERNAL', 1);
define('CRYPT_RC4_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_RC4_MODE_MCRYPT', 2);
define('CRYPT_RC4_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**#@+
@ -92,7 +100,57 @@ define('CRYPT_RC4_DECRYPT', 1);
* @access public
* @package Crypt_RC4
*/
class Crypt_RC4 {
class Crypt_RC4 extends Crypt_Base {
/**
* Block Length of the cipher
*
* RC4 is a stream cipher
* so we the block_size to 0
*
* @see Crypt_Base::block_size
* @var Integer
* @access private
*/
var $block_size = 0;
/**
* The default password key_size used by setPassword()
*
* @see Crypt_Base::password_key_size
* @see Crypt_Base::setPassword()
* @var Integer
* @access private
*/
var $password_key_size = 128; // = 1024 bits
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'RC4';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'arcfour';
/**
* Holds whether performance-optimized $inline_crypt() can/should be used.
*
* @see Crypt_Base::inline_crypt
* @var mixed
* @access private
*/
var $use_inline_crypt = false; // currently not available
/**
* The Key
*
@ -103,190 +161,26 @@ class Crypt_RC4 {
var $key = "\0";
/**
* The Key Stream for encryption
*
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
* The Key Stream for decryption and encryption
*
* @see Crypt_RC4::setKey()
* @var Array
* @access private
*/
var $encryptStream = false;
/**
* The Key Stream for decryption
*
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
*
* @see Crypt_RC4::setKey()
* @var Array
* @access private
*/
var $decryptStream = false;
/**
* The $i and $j indexes for encryption
*
* @see Crypt_RC4::_crypt()
* @var Integer
* @access private
*/
var $encryptIndex = 0;
/**
* The $i and $j indexes for decryption
*
* @see Crypt_RC4::_crypt()
* @var Integer
* @access private
*/
var $decryptIndex = 0;
/**
* The Encryption Algorithm
*
* Only used if CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT. Only possible values are MCRYPT_RC4 or MCRYPT_ARCFOUR.
*
* @see Crypt_RC4::Crypt_RC4()
* @var Integer
* @access private
*/
var $mode;
/**
* Continuous Buffer status
*
* @see Crypt_RC4::enableContinuousBuffer()
* @var Boolean
* @access private
*/
var $continuousBuffer = false;
var $stream;
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* @see Crypt_Base::Crypt_Base()
* @return Crypt_RC4
* @access public
*/
function Crypt_RC4()
{
if ( !defined('CRYPT_RC4_MODE') ) {
switch (true) {
case extension_loaded('mcrypt') && (defined('MCRYPT_ARCFOUR') || defined('MCRYPT_RC4')) && in_array('arcfour', mcrypt_list_algorithms()):
define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_MCRYPT);
break;
default:
define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_INTERNAL);
}
}
switch ( CRYPT_RC4_MODE ) {
case CRYPT_RC4_MODE_MCRYPT:
switch (true) {
case defined('MCRYPT_ARCFOUR'):
$this->mode = MCRYPT_ARCFOUR;
break;
case defined('MCRYPT_RC4');
$this->mode = MCRYPT_RC4;
}
$this->encryptStream = mcrypt_module_open($this->mode, '', MCRYPT_MODE_STREAM, '');
$this->decryptStream = mcrypt_module_open($this->mode, '', MCRYPT_MODE_STREAM, '');
}
}
/**
* Sets the key.
*
* Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
* be used. If no key is explicitly set, it'll be assumed to be a single null byte.
*
* @access public
* @param String $key
*/
function setKey($key)
{
$this->key = $key;
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
mcrypt_generic_init($this->encryptStream, $this->key, '');
mcrypt_generic_init($this->decryptStream, $this->key, '');
return;
}
$keyLength = strlen($key);
$keyStream = array();
for ($i = 0; $i < 256; $i++) {
$keyStream[$i] = $i;
}
$j = 0;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
$temp = $keyStream[$i];
$keyStream[$i] = $keyStream[$j];
$keyStream[$j] = $temp;
}
$this->encryptIndex = $this->decryptIndex = array(0, 0);
$this->encryptStream = $this->decryptStream = $keyStream;
}
/**
* Sets the password.
*
* Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
* {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
* $hash, $salt, $count, $dkLen
*
* @param String $password
* @param optional String $method
* @access public
*/
function setPassword($password, $method = 'pbkdf2')
{
$key = '';
switch ($method) {
default: // 'pbkdf2'
list(, , $hash, $salt, $count) = func_get_args();
if (!isset($hash)) {
$hash = 'sha1';
}
// WPA and WPA2 use the SSID as the salt
if (!isset($salt)) {
$salt = 'phpseclib/salt';
}
// RFC2898#section-4.2 uses 1,000 iterations by default
// WPA and WPA2 use 4,096.
if (!isset($count)) {
$count = 1000;
}
if (!isset($dkLen)) {
$dkLen = 128;
}
if (!class_exists('Crypt_Hash')) {
require_once('Crypt/Hash.php');
}
$i = 1;
while (strlen($key) < $dkLen) {
//$dk.= $this->_pbkdf($password, $salt, $count, $i++);
$hmac = new Crypt_Hash();
$hmac->setHash($hash);
$hmac->setKey($password);
$f = $u = $hmac->hash($salt . pack('N', $i++));
for ($j = 2; $j <= $count; $j++) {
$u = $hmac->hash($u);
$f^= $u;
}
$key.= $f;
}
}
$this->setKey(substr($key, 0, $dkLen));
parent::Crypt_Base(CRYPT_MODE_STREAM);
}
/**
@ -312,15 +206,35 @@ class Crypt_RC4 {
{
}
/**
* Sets the key.
*
* Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
* be used. If no key is explicitly set, it'll be assumed to be a single null byte.
*
* @access public
* @see Crypt_Base::setKey()
* @param String $key
*/
function setKey($key)
{
parent::setKey(substr($key, 0, 256));
}
/**
* Encrypts a message.
*
* @see Crypt_Base::decrypt()
* @see Crypt_RC4::_crypt()
* @access public
* @param String $plaintext
* @return String $ciphertext
*/
function encrypt($plaintext)
{
if ($this->engine == CRYPT_MODE_MCRYPT) {
return parent::encrypt($plaintext);
}
return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
}
@ -330,15 +244,51 @@ class Crypt_RC4 {
* $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
* Atleast if the continuous buffer is disabled.
*
* @see Crypt_Base::encrypt()
* @see Crypt_RC4::_crypt()
* @access public
* @param String $ciphertext
* @return String $plaintext
*/
function decrypt($ciphertext)
{
if ($this->engine == CRYPT_MODE_MCRYPT) {
return parent::decrypt($ciphertext);
}
return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
$key = $this->key;
$keyLength = strlen($key);
$keyStream = array();
for ($i = 0; $i < 256; $i++) {
$keyStream[$i] = $i;
}
$j = 0;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
$temp = $keyStream[$i];
$keyStream[$i] = $keyStream[$j];
$keyStream[$j] = $temp;
}
$this->stream = array();
$this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array(
0, // index $i
0, // index $j
$keyStream
);
}
/**
* Encrypts or decrypts a message.
*
@ -347,173 +297,41 @@ class Crypt_RC4 {
* @access private
* @param String $text
* @param Integer $mode
* @return String $text
*/
function _crypt($text, $mode)
{
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
$keyStream = $mode == CRYPT_RC4_ENCRYPT ? 'encryptStream' : 'decryptStream';
if (!$this->continuousBuffer) {
mcrypt_generic_init($this->$keyStream, $this->key, '');
}
return mcrypt_generic($this->$keyStream, $text);
}
if ($this->encryptStream === false) {
$this->setKey($this->key);
}
switch ($mode) {
case CRYPT_RC4_ENCRYPT:
$keyStream = $this->encryptStream;
list($i, $j) = $this->encryptIndex;
break;
case CRYPT_RC4_DECRYPT:
$keyStream = $this->decryptStream;
list($i, $j) = $this->decryptIndex;
}
$newText = '';
for ($k = 0; $k < strlen($text); $k++) {
$i = ($i + 1) & 255;
$j = ($j + $keyStream[$i]) & 255;
$temp = $keyStream[$i];
$keyStream[$i] = $keyStream[$j];
$keyStream[$j] = $temp;
$temp = $keyStream[($keyStream[$i] + $keyStream[$j]) & 255];
$newText.= chr(ord($text[$k]) ^ $temp);
if ($this->changed) {
$this->_setup();
$this->changed = false;
}
$stream = &$this->stream[$mode];
if ($this->continuousBuffer) {
switch ($mode) {
case CRYPT_RC4_ENCRYPT:
$this->encryptStream = $keyStream;
$this->encryptIndex = array($i, $j);
break;
case CRYPT_RC4_DECRYPT:
$this->decryptStream = $keyStream;
$this->decryptIndex = array($i, $j);
}
$i = &$stream[0];
$j = &$stream[1];
$keyStream = &$stream[2];
} else {
$i = $stream[0];
$j = $stream[1];
$keyStream = $stream[2];
}
return $newText;
}
$len = strlen($text);
for ($k = 0; $k < $len; ++$k) {
$i = ($i + 1) & 255;
$ksi = $keyStream[$i];
$j = ($j + $ksi) & 255;
$ksj = $keyStream[$j];
/**
* Treat consecutive "packets" as if they are a continuous buffer.
*
* Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
* will yield different outputs:
*
* <code>
* echo $rc4->encrypt(substr($plaintext, 0, 8));
* echo $rc4->encrypt(substr($plaintext, 8, 8));
* </code>
* <code>
* echo $rc4->encrypt($plaintext);
* </code>
*
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
* another, as demonstrated with the following:
*
* <code>
* $rc4->encrypt(substr($plaintext, 0, 8));
* echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
* </code>
* <code>
* echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
* </code>
*
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
*
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
* however, they are also less intuitive and more likely to cause you problems.
*
* @see Crypt_RC4::disableContinuousBuffer()
* @access public
*/
function enableContinuousBuffer()
{
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
mcrypt_generic_init($this->encryptStream, $this->key, '');
mcrypt_generic_init($this->decryptStream, $this->key, '');
$keyStream[$i] = $ksj;
$keyStream[$j] = $ksi;
$text[$k] = chr(ord($text[$k]) ^ $keyStream[($ksj + $ksi) & 255]);
}
$this->continuousBuffer = true;
}
/**
* Treat consecutive packets as if they are a discontinuous buffer.
*
* The default behavior.
*
* @see Crypt_RC4::enableContinuousBuffer()
* @access public
*/
function disableContinuousBuffer()
{
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_INTERNAL ) {
$this->encryptIndex = $this->decryptIndex = array(0, 0);
$this->encryptStream = $this->decryptStream = false;
}
$this->continuousBuffer = false;
}
/**
* Dummy function.
*
* Since RC4 is a stream cipher and not a block cipher, no padding is necessary. The only reason this function is
* included is so that you can switch between a block cipher and a stream cipher transparently.
*
* @see Crypt_RC4::disablePadding()
* @access public
*/
function enablePadding()
{
}
/**
* Dummy function.
*
* @see Crypt_RC4::enablePadding()
* @access public
*/
function disablePadding()
{
}
/**
* Class destructor.
*
* Will be called, automatically, if you're using PHP5. If you're using PHP4, call it yourself. Only really
* needs to be called if mcrypt is being used.
*
* @access public
*/
function __destruct()
{
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
$this->_closeMCrypt();
}
}
/**
* Properly close the MCrypt objects.
*
* @access prviate
*/
function _closeMCrypt()
{
mcrypt_module_close($this->encryptStream);
mcrypt_module_close($this->decryptStream);
return $text;
}
}
// vim: ts=4:sw=4:et:
// vim6: fdl=1:
// vim6: fdl=1:

View File

@ -65,17 +65,9 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMIX Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id: RSA.php,v 1.19 2010/09/12 21:58:54 terrafrost Exp $
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Math_BigInteger
*/
if (!class_exists('Math_BigInteger')) {
require_once('Math/BigInteger.php');
}
/**
* Include Crypt_Random
*/
@ -83,15 +75,15 @@ if (!class_exists('Math_BigInteger')) {
// will trigger a call to __autoload() if you're wanting to auto-load classes
// call function_exists() a second time to stop the require_once from being called outside
// of the auto loader
if (!function_exists('crypt_random_string') && !class_exists('Crypt_Random') && !function_exists('crypt_random_string')) {
require_once('Crypt/Random.php');
if (!function_exists('crypt_random_string')) {
require_once('Random.php');
}
/**
* Include Crypt_Hash
*/
if (!class_exists('Crypt_Hash')) {
require_once('Crypt/Hash.php');
require_once('Hash.php');
}
/**#@+
@ -181,7 +173,6 @@ define('CRYPT_RSA_MODE_OPENSSL', 2);
*/
define('CRYPT_RSA_OPENSSL_CONFIG', dirname(__FILE__) . '/../openssl.cnf');
/**#@+
* @access public
* @see Crypt_RSA::createKey()
@ -449,6 +440,14 @@ class Crypt_RSA {
*/
var $configFile;
/**
* Public key comment field.
*
* @var String
* @access private
*/
var $comment = 'phpseclib-generated-key';
/**
* The constructor
*
@ -461,22 +460,54 @@ class Crypt_RSA {
*/
function Crypt_RSA()
{
if (!class_exists('Math_BigInteger')) {
require_once('Math/BigInteger.php');
}
$this->configFile = CRYPT_RSA_OPENSSL_CONFIG;
if ( !defined('CRYPT_RSA_MODE') ) {
switch (true) {
case extension_loaded('openssl') && version_compare(PHP_VERSION, '4.2.0', '>='):
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_OPENSSL);
// 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
// can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either.
if ( defined('MATH_BIGINTEGER_OPENSSL_DISABLE') ) {
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
}
switch ( !defined('CRYPT_RSA_MODE') ) { // ie. only run this if the above didn't set CRYPT_RSA_MODE already
case extension_loaded('openssl') && version_compare(PHP_VERSION, '4.2.0', '>=') && file_exists($this->configFile):
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
ob_start();
phpinfo();
$content = ob_get_contents();
ob_end_clean();
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
$versions = array();
if (!empty($matches[1])) {
for ($i = 0; $i < count($matches[1]); $i++) {
$versions[$matches[1][$i]] = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
}
}
// it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
switch (true) {
case !isset($versions['Header']):
case !isset($versions['Library']):
case $versions['Header'] == $versions['Library']:
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_OPENSSL);
break;
default:
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
}
break;
default:
case true:
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
}
}
if (!defined('CRYPT_RSA_COMMENT')) {
define('CRYPT_RSA_COMMENT', 'phpseclib-generated-key');
}
$this->zero = new Math_BigInteger();
$this->one = new Math_BigInteger(1);
@ -642,12 +673,12 @@ class Crypt_RSA {
$exponents[$i] = $e->modInverse($temp);
}
list($lcm) = $lcm['top']->divide($lcm['bottom']);
$gcd = $lcm->gcd($e);
list($temp) = $lcm['top']->divide($lcm['bottom']);
$gcd = $temp->gcd($e);
$i0 = 1;
} while (!$gcd->equals($this->one));
$d = $e->modInverse($lcm);
$d = $e->modInverse($temp);
$coefficients[2] = $primes[2]->modInverse($primes[1]);
@ -720,16 +751,16 @@ class Crypt_RSA {
$key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
$encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
$key.= $encryption;
$key.= "\r\nComment: " . CRYPT_RSA_COMMENT . "\r\n";
$key.= "\r\nComment: " . $this->comment . "\r\n";
$public = pack('Na*Na*Na*',
strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']
);
$source = pack('Na*Na*Na*Na*',
strlen('ssh-rsa'), 'ssh-rsa', strlen($encryption), $encryption,
strlen(CRYPT_RSA_COMMENT), CRYPT_RSA_COMMENT, strlen($public), $public
strlen($this->comment), $this->comment, strlen($public), $public
);
$public = base64_encode($public);
$key.= "Public-Lines: " . ((strlen($public) + 32) >> 6) . "\r\n";
$key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
$key.= chunk_split($public, 64);
$private = pack('Na*Na*Na*Na*',
strlen($raw['privateExponent']), $raw['privateExponent'], strlen($raw['prime1']), $raw['prime1'],
@ -760,7 +791,7 @@ class Crypt_RSA {
}
$private = base64_encode($private);
$key.= 'Private-Lines: ' . ((strlen($private) + 32) >> 6) . "\r\n";
$key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
$key.= chunk_split($private, 64);
if (!class_exists('Crypt_Hash')) {
require_once('Crypt/Hash.php');
@ -853,7 +884,7 @@ class Crypt_RSA {
// mpint e
// mpint n
$RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
$RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . CRYPT_RSA_COMMENT;
$RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $this->comment;
return $RSAPublicKey;
default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW or CRYPT_RSA_PUBLIC_FORMAT_PKCS1
@ -960,13 +991,19 @@ class Crypt_RSA {
if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
$iv = pack('H*', trim($matches[2]));
$symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key
$symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
$symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8)));
$ciphertext = preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-| #s', '', $key);
$ciphertext = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $ciphertext) ? base64_decode($ciphertext) : false;
if ($ciphertext === false) {
$ciphertext = $key;
}
switch ($matches[1]) {
case 'AES-256-CBC':
if (!class_exists('Crypt_AES')) {
require_once('Crypt/AES.php');
}
$crypto = new Crypt_AES();
break;
case 'AES-128-CBC':
if (!class_exists('Crypt_AES')) {
require_once('Crypt/AES.php');
@ -984,6 +1021,7 @@ class Crypt_RSA {
if (!class_exists('Crypt_TripleDES')) {
require_once('Crypt/TripleDES.php');
}
$symkey = substr($symkey, 0, 24);
$crypto = new Crypt_TripleDES();
break;
case 'DES-CBC':
@ -1121,11 +1159,15 @@ class Crypt_RSA {
return $components;
case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
$key = base64_decode(preg_replace('#^ssh-rsa | .+$#', '', $key));
$parts = explode(' ', $key, 3);
$key = isset($parts[1]) ? base64_decode($parts[1]) : false;
if ($key === false) {
return false;
}
$comment = isset($parts[2]) ? $parts[2] : false;
$cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa";
if (strlen($key) <= 4) {
@ -1147,12 +1189,14 @@ class Crypt_RSA {
$realModulus = new Math_BigInteger($this->_string_shift($key, $length), -256);
return strlen($key) ? false : array(
'modulus' => $realModulus,
'publicExponent' => $modulus
'publicExponent' => $modulus,
'comment' => $comment
);
} else {
return strlen($key) ? false : array(
'modulus' => $modulus,
'publicExponent' => $publicExponent
'publicExponent' => $publicExponent,
'comment' => $comment
);
}
// http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
@ -1180,6 +1224,7 @@ class Crypt_RSA {
return false;
}
$encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
$comment = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
$publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
$public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
@ -1297,9 +1342,6 @@ class Crypt_RSA {
break;
case 'D':
$this->current = &$this->components['privateExponent'];
break;
default:
unset($this->current);
}
$this->current = '';
}
@ -1315,11 +1357,10 @@ class Crypt_RSA {
*/
function _stop_element_handler($parser, $name)
{
//$name = strtoupper($name);
if ($name == 'RSAKEYVALUE') {
return;
if (isset($this->current)) {
$this->current = new Math_BigInteger(base64_decode($this->current), 256);
unset($this->current);
}
$this->current = new Math_BigInteger(base64_decode($this->current), 256);
}
/**
@ -1350,6 +1391,53 @@ class Crypt_RSA {
*/
function loadKey($key, $type = false)
{
if (is_object($key) && strtolower(get_class($key)) == 'crypt_rsa') {
$this->privateKeyFormat = $key->privateKeyFormat;
$this->publicKeyFormat = $key->publicKeyFormat;
$this->k = $key->k;
$this->hLen = $key->hLen;
$this->sLen = $key->sLen;
$this->mgfHLen = $key->mgfHLen;
$this->encryptionMode = $key->encryptionMode;
$this->signatureMode = $key->signatureMode;
$this->password = $key->password;
$this->configFile = $key->configFile;
$this->comment = $key->comment;
if (is_object($key->hash)) {
$this->hash = new Crypt_Hash($key->hash->getHash());
}
if (is_object($key->mgfHash)) {
$this->mgfHash = new Crypt_Hash($key->mgfHash->getHash());
}
if (is_object($key->modulus)) {
$this->modulus = $key->modulus->copy();
}
if (is_object($key->exponent)) {
$this->exponent = $key->exponent->copy();
}
if (is_object($key->publicExponent)) {
$this->publicExponent = $key->publicExponent->copy();
}
$this->primes = array();
$this->exponents = array();
$this->coefficients = array();
foreach ($this->primes as $prime) {
$this->primes[] = $prime->copy();
}
foreach ($this->exponents as $exponent) {
$this->exponents[] = $exponent->copy();
}
foreach ($this->coefficients as $coefficient) {
$this->coefficients[] = $coefficient->copy();
}
return true;
}
if ($type === false) {
$types = array(
CRYPT_RSA_PUBLIC_FORMAT_RAW,
@ -1373,6 +1461,9 @@ class Crypt_RSA {
return false;
}
if (isset($components['comment']) && $components['comment'] !== false) {
$this->comment = $components['comment'];
}
$this->modulus = $components['modulus'];
$this->k = strlen($this->modulus->toBytes());
$this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];
@ -1428,6 +1519,11 @@ class Crypt_RSA {
*/
function setPublicKey($key = false, $type = false)
{
// if a public key has already been loaded return false
if (!empty($this->publicExponent)) {
return false;
}
if ($key === false && !empty($this->modulus)) {
$this->publicExponent = $this->exponent;
return true;
@ -1552,6 +1648,18 @@ class Crypt_RSA {
return $key !== false ? $key : '';
}
/**
* __clone() magic method
*
* @access public
*/
function __clone()
{
$key = new Crypt_RSA();
$key->loadKey($this);
return $key;
}
/**
* Generates the smallest and largest numbers requiring $bits bits
*
@ -1582,7 +1690,7 @@ class Crypt_RSA {
* DER-decode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 § 8.1.3} for more information.
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param String $string
@ -1603,7 +1711,7 @@ class Crypt_RSA {
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 § 8.1.3} for more information.
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param Integer $length
@ -1872,7 +1980,7 @@ class Crypt_RSA {
*
* Protects against a particular type of timing attack described.
*
* See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Dont use MessageDigest.isEquals)}
* See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)}
*
* Thanks for the heads up singpolyma!
*
@ -2135,6 +2243,7 @@ class Crypt_RSA {
}
// EME-PKCS1-v1_5 encoding
$psLen = $this->k - $mLen - 3;
$ps = '';
while (strlen($ps) != $psLen) {
@ -2142,7 +2251,14 @@ class Crypt_RSA {
$temp = str_replace("\x00", '', $temp);
$ps.= $temp;
}
$em = chr(0) . chr(2) . $ps . chr(0) . $m;
$type = 2;
// see the comments of _rsaes_pkcs1_v1_5_decrypt() to understand why this is being done
if (defined('CRYPT_RSA_PKCS15_COMPAT') && (!isset($this->publicExponent) || $this->exponent !== $this->publicExponent)) {
$type = 1;
// "The padding string PS shall consist of k-3-||D|| octets. ... for block type 01, they shall have value FF"
$ps = str_repeat("\xFF", $psLen);
}
$em = chr(0) . chr($type) . $ps . chr(0) . $m;
// RSA encryption
$m = $this->_os2ip($em);
@ -2515,6 +2631,28 @@ class Crypt_RSA {
$this->signatureMode = $mode;
}
/**
* Set public key comment.
*
* @access public
* @param String $comment
*/
function setComment($comment)
{
$this->comment = $comment;
}
/**
* Get public key comment.
*
* @access public
* @return String
*/
function getComment()
{
return $this->comment;
}
/**
* Encryption
*

View File

@ -21,10 +21,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -38,10 +38,16 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMVII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id: Random.php,v 1.9 2010/04/24 06:40:48 terrafrost Exp $
* @link http://phpseclib.sourceforge.net
*/
/**
* "Is Windows" test
*
* @access private
*/
define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
/**
* Generate a random string.
*
@ -53,9 +59,9 @@
* @return String
* @access public
*/
function crypt_random_string($length) {
// PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
if ((PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
function crypt_random_string($length)
{
if (CRYPT_RANDOM_IS_WINDOWS) {
// method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
// ie. class_alias is a function that was introduced in PHP 5.3
if (function_exists('mcrypt_create_iv') && function_exists('class_alias')) {
@ -143,7 +149,7 @@ function crypt_random_string($length) {
serialize($_POST) .
serialize($_GET) .
serialize($_COOKIE) .
serialize($_GLOBAL) .
serialize($GLOBALS) .
serialize($_SESSION) .
serialize($_OLD_SESSION)
));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,924 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Pure-PHP implementation of Twofish.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include('Crypt/Twofish.php');
*
* $twofish = new Crypt_Twofish();
*
* $twofish->setKey('12345678901234567890123456789012');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $twofish->decrypt($twofish->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Twofish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright MMVII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 1.0
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
require_once('Base.php');
}
/**#@+
* @access public
* @see Crypt_Twofish::encrypt()
* @see Crypt_Twofish::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_TWOFISH_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_TWOFISH_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_TWOFISH_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**#@+
* @access private
* @see Crypt_Twofish::Crypt_Twofish()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_TWOFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_TWOFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**
* Pure-PHP implementation of Twofish.
*
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @version 1.0
* @access public
* @package Crypt_Twofish
*/
class Crypt_Twofish extends Crypt_Base {
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'TWOFISH';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'twofish';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var Integer
* @access private
*/
var $cfb_init_len = 800;
/**
* Q-Table
*
* @var Array
* @access private
*/
var $q0 = array (
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
);
/**
* Q-Table
*
* @var Array
* @access private
*/
var $q1 = array (
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
);
/**
* M-Table
*
* @var Array
* @access private
*/
var $m0 = array (
0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
);
/**
* M-Table
*
* @var Array
* @access private
*/
var $m1 = array (
0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
);
/**
* M-Table
*
* @var Array
* @access private
*/
var $m2 = array (
0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
);
/**
* M-Table
*
* @var Array
* @access private
*/
var $m3 = array (
0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
);
/**
* The Key Schedule Array
*
* @var Array
* @access private
*/
var $K = array();
/**
* The Key depended S-Table 0
*
* @var Array
* @access private
*/
var $S0 = array();
/**
* The Key depended S-Table 1
*
* @var Array
* @access private
*/
var $S1 = array();
/**
* The Key depended S-Table 2
*
* @var Array
* @access private
*/
var $S2 = array();
/**
* The Key depended S-Table 3
*
* @var Array
* @access private
*/
var $S3 = array();
/**
* Holds the last used key
*
* @var Array
* @access private
*/
var $kl;
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_TWOFISH_MODE_ECB
*
* - CRYPT_TWOFISH_MODE_CBC
*
* - CRYPT_TWOFISH_MODE_CTR
*
* - CRYPT_TWOFISH_MODE_CFB
*
* - CRYPT_TWOFISH_MODE_OFB
*
* If not explictly set, CRYPT_TWOFISH_MODE_CBC will be used.
*
* @see Crypt_Base::Crypt_Base()
* @param optional Integer $mode
* @access public
*/
function Crypt_Twofish($mode = CRYPT_TWOFISH_MODE_CBC)
{
parent::Crypt_Base($mode);
}
/**
* Sets the key.
*
* Keys can be of any length. Twofish, itself, requires the use of a key that's 128, 192 or 256-bits long.
* If the key is less than 256-bits we round the length up to the closest valid key length,
* padding $key with null bytes. If the key is more than 256-bits, we trim the excess bits.
*
* If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
*
* @access public
* @see Crypt_Base::setKey()
* @param String $key
*/
function setKey($key)
{
$keylength = strlen($key);
switch (true) {
case $keylength <= 16:
$key = str_pad($key, 16, "\0");
break;
case $keylength <= 24:
$key = str_pad($key, 24, "\0");
break;
case $keylength < 32:
$key = str_pad($key, 32, "\0");
break;
case $keylength > 32:
$key = substr($key, 0, 32);
}
parent::setKey($key);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
// already expanded
return;
}
$this->kl = array('key' => $this->key);
/* Key expanding and generating the key-depended s-boxes */
$le_longs = unpack('V*', $this->key);
$key = unpack('C*', $this->key);
$m0 = $this->m0;
$m1 = $this->m1;
$m2 = $this->m2;
$m3 = $this->m3;
$q0 = $this->q0;
$q1 = $this->q1;
$K = $S0 = $S1 = $S2 = $S3 = array();
switch (strlen($this->key)) {
case 16:
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
$A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
$m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
$m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
$m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$K[] = $A+= $B;
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
}
break;
case 24:
list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
$A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
$m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
$m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
$m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$K[] = $A+= $B;
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
}
break;
default: // 32
list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
$A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
$m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
$m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
$m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$K[] = $A+= $B;
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
}
}
$this->K = $K;
$this->S0 = $S0;
$this->S1 = $S1;
$this->S2 = $S2;
$this->S3 = $S3;
}
/**
* _mdsrem function using by the twofish cipher algorithm
*
* @access private
* @param String $A
* @param String $B
* @return Array
*/
function _mdsrem($A, $B)
{
// No gain by unrolling this loop.
for ($i = 0; $i < 8; ++$i) {
// Get most significant coefficient.
$t = 0xff & ($B >> 24);
// Shift the others up.
$B = ($B << 8) | (0xff & ($A >> 24));
$A<<= 8;
$u = $t << 1;
// Subtract the modular polynomial on overflow.
if ($t & 0x80) {
$u^= 0x14d;
}
// Remove t * (a * x^2 + 1).
$B ^= $t ^ ($u << 16);
// Form u = a*t + t/a = t*(a + 1/a).
$u^= 0x7fffffff & ($t >> 1);
// Add the modular polynomial on underflow.
if ($t & 0x01) $u^= 0xa6 ;
// Remove t * (a + 1/a) * (x^3 + x).
$B^= ($u << 24) | ($u << 8);
}
return array(
0xff & $B >> 24,
0xff & $B >> 16,
0xff & $B >> 8,
0xff & $B);
}
/**
* Encrypts a block
*
* @access private
* @param String $in
* @return String
*/
function _encryptBlock($in)
{
$S0 = $this->S0;
$S1 = $this->S1;
$S2 = $this->S2;
$S3 = $this->S3;
$K = $this->K;
$in = unpack("V4", $in);
$R0 = $K[0] ^ $in[1];
$R1 = $K[1] ^ $in[2];
$R2 = $K[2] ^ $in[3];
$R3 = $K[3] ^ $in[4];
$ki = 7;
while ($ki < 39) {
$t0 = $S0[ $R0 & 0xff] ^
$S1[($R0 >> 8) & 0xff] ^
$S2[($R0 >> 16) & 0xff] ^
$S3[($R0 >> 24) & 0xff];
$t1 = $S0[($R1 >> 24) & 0xff] ^
$S1[ $R1 & 0xff] ^
$S2[($R1 >> 8) & 0xff] ^
$S3[($R1 >> 16) & 0xff];
$R2^= $t0 + $t1 + $K[++$ki];
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
$t0 = $S0[ $R2 & 0xff] ^
$S1[($R2 >> 8) & 0xff] ^
$S2[($R2 >> 16) & 0xff] ^
$S3[($R2 >> 24) & 0xff];
$t1 = $S0[($R3 >> 24) & 0xff] ^
$S1[ $R3 & 0xff] ^
$S2[($R3 >> 8) & 0xff] ^
$S3[($R3 >> 16) & 0xff];
$R0^= ($t0 + $t1 + $K[++$ki]);
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
}
return pack("V4", $K[4] ^ $R2,
$K[5] ^ $R3,
$K[6] ^ $R0,
$K[7] ^ $R1);
}
/**
* Decrypts a block
*
* @access private
* @param String $in
* @return String
*/
function _decryptBlock($in)
{
$S0 = $this->S0;
$S1 = $this->S1;
$S2 = $this->S2;
$S3 = $this->S3;
$K = $this->K;
$in = unpack("V4", $in);
$R0 = $K[4] ^ $in[1];
$R1 = $K[5] ^ $in[2];
$R2 = $K[6] ^ $in[3];
$R3 = $K[7] ^ $in[4];
$ki = 40;
while ($ki > 8) {
$t0 = $S0[$R0 & 0xff] ^
$S1[$R0 >> 8 & 0xff] ^
$S2[$R0 >> 16 & 0xff] ^
$S3[$R0 >> 24 & 0xff];
$t1 = $S0[$R1 >> 24 & 0xff] ^
$S1[$R1 & 0xff] ^
$S2[$R1 >> 8 & 0xff] ^
$S3[$R1 >> 16 & 0xff];
$R3^= $t0 + ($t1 << 1) + $K[--$ki];
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K[--$ki]);
$t0 = $S0[$R2 & 0xff] ^
$S1[$R2 >> 8 & 0xff] ^
$S2[$R2 >> 16 & 0xff] ^
$S3[$R2 >> 24 & 0xff];
$t1 = $S0[$R3 >> 24 & 0xff] ^
$S1[$R3 & 0xff] ^
$S2[$R3 >> 8 & 0xff] ^
$S3[$R3 >> 16 & 0xff];
$R1^= $t0 + ($t1 << 1) + $K[--$ki];
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
}
return pack("V4", $K[0] ^ $R2,
$K[1] ^ $R3,
$K[2] ^ $R0,
$K[3] ^ $R1);
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
// Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
switch (true) {
case $gen_hi_opt_code:
$code_hash = md5(str_pad("Crypt_Twofish, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
$code_hash = "Crypt_Twofish, {$this->mode}";
}
if (!isset($lambda_functions[$code_hash])) {
switch (true) {
case $gen_hi_opt_code:
$K = $this->K;
$init_crypt = '
static $S0, $S1, $S2, $S3;
if (!$S0) {
for ($i = 0; $i < 256; ++$i) {
$S0[] = (int)$self->S0[$i];
$S1[] = (int)$self->S1[$i];
$S2[] = (int)$self->S2[$i];
$S3[] = (int)$self->S3[$i];
}
}
';
break;
default:
$K = array();
for ($i = 0; $i < 40; ++$i) {
$K[] = '$K_' . $i;
}
$init_crypt = '
$S0 = $self->S0;
$S1 = $self->S1;
$S2 = $self->S2;
$S3 = $self->S3;
list(' . implode(',', $K) . ') = $self->K;
';
}
// Generating encrypt code:
$encrypt_block = '
$in = unpack("V4", $in);
$R0 = '.$K[0].' ^ $in[1];
$R1 = '.$K[1].' ^ $in[2];
$R2 = '.$K[2].' ^ $in[3];
$R3 = '.$K[3].' ^ $in[4];
';
for ($ki = 7, $i = 0; $i < 8; ++$i) {
$encrypt_block.= '
$t0 = $S0[ $R0 & 0xff] ^
$S1[($R0 >> 8) & 0xff] ^
$S2[($R0 >> 16) & 0xff] ^
$S3[($R0 >> 24) & 0xff];
$t1 = $S0[($R1 >> 24) & 0xff] ^
$S1[ $R1 & 0xff] ^
$S2[($R1 >> 8) & 0xff] ^
$S3[($R1 >> 16) & 0xff];
$R2^= ($t0 + $t1 + '.$K[++$ki].');
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
$t0 = $S0[ $R2 & 0xff] ^
$S1[($R2 >> 8) & 0xff] ^
$S2[($R2 >> 16) & 0xff] ^
$S3[($R2 >> 24) & 0xff];
$t1 = $S0[($R3 >> 24) & 0xff] ^
$S1[ $R3 & 0xff] ^
$S2[($R3 >> 8) & 0xff] ^
$S3[($R3 >> 16) & 0xff];
$R0^= ($t0 + $t1 + '.$K[++$ki].');
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
';
}
$encrypt_block.= '
$in = pack("V4", '.$K[4].' ^ $R2,
'.$K[5].' ^ $R3,
'.$K[6].' ^ $R0,
'.$K[7].' ^ $R1);
';
// Generating decrypt code:
$decrypt_block = '
$in = unpack("V4", $in);
$R0 = '.$K[4].' ^ $in[1];
$R1 = '.$K[5].' ^ $in[2];
$R2 = '.$K[6].' ^ $in[3];
$R3 = '.$K[7].' ^ $in[4];
';
for ($ki = 40, $i = 0; $i < 8; ++$i) {
$decrypt_block.= '
$t0 = $S0[$R0 & 0xff] ^
$S1[$R0 >> 8 & 0xff] ^
$S2[$R0 >> 16 & 0xff] ^
$S3[$R0 >> 24 & 0xff];
$t1 = $S0[$R1 >> 24 & 0xff] ^
$S1[$R1 & 0xff] ^
$S2[$R1 >> 8 & 0xff] ^
$S3[$R1 >> 16 & 0xff];
$R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
$t0 = $S0[$R2 & 0xff] ^
$S1[$R2 >> 8 & 0xff] ^
$S2[$R2 >> 16 & 0xff] ^
$S3[$R2 >> 24 & 0xff];
$t1 = $S0[$R3 >> 24 & 0xff] ^
$S1[$R3 & 0xff] ^
$S2[$R3 >> 8 & 0xff] ^
$S3[$R3 >> 16 & 0xff];
$R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
';
}
$decrypt_block.= '
$in = pack("V4", '.$K[0].' ^ $R2,
'.$K[1].' ^ $R3,
'.$K[2].' ^ $R0,
'.$K[3].' ^ $R1);
';
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'init_encrypt' => '',
'init_decrypt' => '',
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
$this->inline_crypt = $lambda_functions[$code_hash];
}
}
// vim: ts=4:sw=4:et:
// vim6: fdl=1:

View File

@ -34,8 +34,7 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMXII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id$
* @link htp://phpseclib.sourceforge.net
* @link http://phpseclib.sourceforge.net
*/
/**
@ -298,12 +297,12 @@ class File_ANSI {
}
// http://ascii-table.com/ansi-escape-sequences-vt-100.php
switch ($this->ansi) {
case "\x1B[H":
case "\x1B[H": // Move cursor to upper left corner
$this->old_x = $this->x;
$this->old_y = $this->y;
$this->x = $this->y = 0;
break;
case "\x1B[J":
case "\x1B[J": // Clear screen from cursor down
$this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
$this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));
@ -314,36 +313,45 @@ class File_ANSI {
array_shift($this->history);
array_shift($this->history_attrs);
}
case "\x1B[K":
case "\x1B[K": // Clear screen from cursor right
$this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
array_splice($this->attrs[$this->y], $this->x + 1);
break;
case "\x1B[2K": // Clear entire line
$this->screen[$this->y] = str_repeat(' ', $this->x);
$this->attrs[$this->y] = $this->attr_row;
break;
case "\x1B[?1h": // set cursor key to application
case "\x1B[?25h": // show the cursor
break;
case "\x1BE": // Move to next line
$this->_newLine();
$this->x = 0;
break;
default:
switch (true) {
case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match):
case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
$this->old_x = $this->x;
$this->old_y = $this->y;
$this->x = $match[2] - 1;
$this->y = $match[1] - 1;
break;
case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match):
case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
$this->old_x = $this->x;
$x = $match[1] - 1;
break;
case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
break;
case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match):
case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
$mods = explode(';', $match[1]);
foreach ($mods as $mod) {
switch ($mod) {
case 0:
case 0: // Turn off character attributes
$this->attrs[$this->y][$this->x] = '';
if ($this->bold) $this->attrs[$this->y][$this->x].= '</b>';
if ($this->underline) $this->attrs[$this->y][$this->x].= '</underline>';
if ($this->underline) $this->attrs[$this->y][$this->x].= '</u>';
if ($this->blink) $this->attrs[$this->y][$this->x].= '</blink>';
if ($this->color) $this->attrs[$this->y][$this->x].= '</span>';
@ -355,25 +363,25 @@ class File_ANSI {
$this->bold = $this->underline = $this->blink = $this->color = $this->reverse = false;
break;
case 1:
case 1: // Turn bold mode on
if (!$this->bold) {
$this->attrs[$this->y][$this->x] = '<b>';
$this->bold = true;
}
break;
case 4:
case 4: // Turn underline mode on
if (!$this->underline) {
$this->attrs[$this->y][$this->x] = '<u>';
$this->underline = true;
}
break;
case 5:
case 5: // Turn blinking mode on
if (!$this->blink) {
$this->attrs[$this->y][$this->x] = '<blink>';
$this->blink = true;
}
break;
case 7:
case 7: // Turn reverse video on
$this->reverse = !$this->reverse;
$temp = $this->background;
$this->background = $this->foreground;
@ -384,7 +392,7 @@ class File_ANSI {
}
$this->color = true;
break;
default:
default: // set colors
//$front = $this->reverse ? &$this->background : &$this->foreground;
$front = &$this->{ $this->reverse ? 'background' : 'foreground' };
//$back = $this->reverse ? &$this->foreground : &$this->background;
@ -424,7 +432,7 @@ class File_ANSI {
}
break;
default:
echo "{$this->ansi} unsupported\r\n";
user_error("{$this->ansi} unsupported\r\n");
}
}
$this->ansi = '';
@ -436,25 +444,7 @@ class File_ANSI {
$this->x = 0;
break;
case "\n":
//if ($this->y < $this->max_y) {
// $this->y++;
//}
while ($this->y >= $this->max_y) {
$this->history = array_merge($this->history, array(array_shift($this->screen)));
$this->screen[] = '';
$this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
$this->attrs[] = $this->attr_row;
if (count($this->history) >= $this->max_history) {
array_shift($this->history);
array_shift($this->history_attrs);
}
$this->y--;
}
$this->y++;
$this->_newLine();
break;
case "\x0F": // shift
break;
@ -479,6 +469,36 @@ class File_ANSI {
}
}
/**
* Add a new line
*
* Also update the $this->screen and $this->history buffers
*
* @access private
*/
function _newLine()
{
//if ($this->y < $this->max_y) {
// $this->y++;
//}
while ($this->y >= $this->max_y) {
$this->history = array_merge($this->history, array(array_shift($this->screen)));
$this->screen[] = '';
$this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
$this->attrs[] = $this->attr_row;
if (count($this->history) >= $this->max_history) {
array_shift($this->history);
array_shift($this->history_attrs);
}
$this->y--;
}
$this->y++;
}
/**
* Returns the current screen without preformating
*
@ -537,4 +557,4 @@ class File_ANSI {
return '<pre style="color: white; background: black" width="' . ($this->max_x + 1) . '">' . $scrollback . '</pre>';
}
}
}

View File

@ -37,17 +37,9 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMXII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id$
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Math_BigInteger
*/
if (!class_exists('Math_BigInteger')) {
require_once('Math/BigInteger.php');
}
/**#@+
* Tag Classes
*
@ -249,6 +241,22 @@ class File_ASN1 {
FILE_ASN1_TYPE_VISIBLE_STRING => 1,
);
/**
* Default Constructor.
*
* @access public
*/
function File_ASN1()
{
static $static_init = null;
if (!$static_init) {
$static_init = true;
if (!class_exists('Math_BigInteger')) {
require_once('Math/BigInteger.php');
}
}
}
/**
* Parse BER-encoding
*
@ -304,12 +312,12 @@ class File_ASN1 {
} while ( $loop );
}
// Length, as discussed in § 8.1.3 of X.690-0207.pdf#page=13
// Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13
$length = ord($this->_string_shift($encoded));
$start++;
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
// immediately available." -- § 8.1.3.2.c
// immediately available." -- paragraph 8.1.3.2.c
//if ( !$constructed ) {
// return false;
//}
@ -319,11 +327,15 @@ class File_ASN1 {
// support it up to four.
$length&= 0x7F;
$temp = $this->_string_shift($encoded, $length);
// tags of indefinite length don't really have a header length; this length includes the tag
$current+= array('headerlength' => $length + 2);
$start+= $length;
extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)));
} else {
$current+= array('headerlength' => 2);
}
// End-of-content, see §§ 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.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;
}
@ -349,6 +361,7 @@ class File_ASN1 {
'content' => $constructed ? $this->_decode_ber($content, $start) : $content,
'length' => $length + $start - $current['start']
) + $current;
$start+= $length;
continue 2;
}
@ -357,7 +370,7 @@ class File_ASN1 {
// decode UNIVERSAL tags
switch ($tag) {
case FILE_ASN1_TYPE_BOOLEAN:
// "The contents octets shall consist of a single octet." -- § 8.2.1
// "The contents octets shall consist of a single octet." -- paragraph 8.2.1
//if (strlen($content) != 1) {
// return false;
//}
@ -410,7 +423,7 @@ class File_ASN1 {
}
break;
case FILE_ASN1_TYPE_NULL:
// "The contents octets shall not contain any octets." -- § 8.8.2
// "The contents octets shall not contain any octets." -- paragraph 8.8.2
//if (strlen($content)) {
// return false;
//}
@ -441,7 +454,7 @@ class File_ASN1 {
/* Each character string type shall be encoded as if it had been declared:
[UNIVERSAL x] IMPLICIT OCTET STRING
-- X.690-0207.pdf#page=23 (§ 8.21.3)
-- X.690-0207.pdf#page=23 (paragraph 8.21.3)
Per that, we're not going to do any validation. If there are any illegal characters in the string,
we don't really care */
@ -487,12 +500,15 @@ class File_ASN1 {
*
* Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format.
*
* "Special" mappings may be applied on a per tag-name basis via $special.
*
* @param Array $decoded
* @param Array $mapping
* @param Array $special
* @return Array
* @access public
*/
function asn1map($decoded, $mapping)
function asn1map($decoded, $mapping, $special = array())
{
if (isset($mapping['explicit'])) {
$decoded = $decoded['content'][0];
@ -506,7 +522,7 @@ class File_ASN1 {
}
$inmap = $this->ANYmap[$intype];
if (is_string($inmap)) {
return array($inmap => $this->asn1map($decoded, array('type' => $intype) + $mapping));
return array($inmap => $this->asn1map($decoded, array('type' => $intype) + $mapping, $special));
}
break;
case $mapping['type'] == FILE_ASN1_TYPE_CHOICE:
@ -514,15 +530,18 @@ class File_ASN1 {
switch (true) {
case isset($option['constant']) && $option['constant'] == $decoded['constant']:
case !isset($option['constant']) && $option['type'] == $decoded['type']:
$value = $this->asn1map($decoded, $option);
$value = $this->asn1map($decoded, $option, $special);
break;
case !isset($option['constant']) && $option['type'] == FILE_ASN1_TYPE_CHOICE:
$v = $this->asn1map($decoded, $option);
$v = $this->asn1map($decoded, $option, $special);
if (isset($v)) {
$value = $v;
}
}
if (isset($value)) {
if (isset($special[$key])) {
$value = call_user_func($special[$key], $value);
}
return array($key => $value);
}
}
@ -547,7 +566,7 @@ class File_ASN1 {
if (isset($mapping['min']) && isset($mapping['max'])) {
$child = $mapping['children'];
foreach ($decoded['content'] as $content) {
if (($map[] = $this->asn1map($content, $child)) === NULL) {
if (($map[] = $this->asn1map($content, $child, $special)) === NULL) {
return NULL;
}
}
@ -591,12 +610,15 @@ class File_ASN1 {
if ($maymatch) {
// Attempt submapping.
$candidate = $this->asn1map($temp, $child);
$candidate = $this->asn1map($temp, $child, $special);
$maymatch = $candidate !== NULL;
}
if ($maymatch) {
// Got the match: use it.
if (isset($special[$key])) {
$candidate = call_user_func($special[$key], $candidate);
}
$map[$key] = $candidate;
$i++;
} elseif (isset($child['default'])) {
@ -617,7 +639,7 @@ class File_ASN1 {
if (isset($mapping['min']) && isset($mapping['max'])) {
$child = $mapping['children'];
foreach ($decoded['content'] as $content) {
if (($map[] = $this->asn1map($content, $child)) === NULL) {
if (($map[] = $this->asn1map($content, $child, $special)) === NULL) {
return NULL;
}
}
@ -660,7 +682,7 @@ class File_ASN1 {
if ($maymatch) {
// Attempt submapping.
$candidate = $this->asn1map($temp, $child);
$candidate = $this->asn1map($temp, $child, $special);
$maymatch = $candidate !== NULL;
}
@ -669,6 +691,9 @@ class File_ASN1 {
}
// Got the match: use it.
if (isset($special[$key])) {
$candidate = call_user_func($special[$key], $candidate);
}
$map[$key] = $candidate;
break;
}
@ -761,18 +786,30 @@ class File_ASN1 {
* DER-encodes an ASN.1 semantic mapping ($mapping). Some libraries would probably call this function
* an ASN.1 compiler.
*
* "Special" mappings can be applied via $special.
*
* @param String $source
* @param String $mapping
* @param Integer $idx
* @return String
* @access public
*/
function encodeDER($source, $mapping)
function encodeDER($source, $mapping, $special = array())
{
$this->location = array();
return $this->_encode_der($source, $mapping);
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)
*
@ -782,7 +819,7 @@ class File_ASN1 {
* @return String
* @access private
*/
function _encode_der($source, $mapping, $idx = NULL)
function _encode_der($source, $mapping, $idx = NULL, $special = array())
{
if (is_object($source) && strtolower(get_class($source)) == 'file_asn1_element') {
return $source->element;
@ -794,6 +831,9 @@ class File_ASN1 {
}
if (isset($idx)) {
if (isset($special[$idx])) {
$source = call_user_func($special[$idx], $source);
}
$this->location[] = $idx;
}
@ -810,7 +850,7 @@ class File_ASN1 {
$child = $mapping['children'];
foreach ($source as $content) {
$temp = $this->_encode_der($content, $child);
$temp = $this->_encode_der($content, $child, NULL, $special);
if ($temp === false) {
return false;
}
@ -827,7 +867,7 @@ class File_ASN1 {
continue;
}
$temp = $this->_encode_der($source[$key], $child, $key);
$temp = $this->_encode_der($source[$key], $child, $key, $special);
if ($temp === false) {
return false;
}
@ -868,7 +908,7 @@ class File_ASN1 {
continue;
}
$temp = $this->_encode_der($source[$key], $child, $key);
$temp = $this->_encode_der($source[$key], $child, $key, $special);
if ($temp === false) {
return false;
}
@ -914,6 +954,9 @@ class File_ASN1 {
$value = new Math_BigInteger($value);
$value = $value->toBytes(true);
}
if (!strlen($value)) {
$value = chr(0);
}
break;
case FILE_ASN1_TYPE_UTC_TIME:
case FILE_ASN1_TYPE_GENERALIZED_TIME:
@ -987,19 +1030,19 @@ class File_ASN1 {
switch (true) {
case !isset($source):
return $this->_encode_der(NULL, array('type' => FILE_ASN1_TYPE_NULL) + $mapping);
return $this->_encode_der(NULL, array('type' => FILE_ASN1_TYPE_NULL) + $mapping, NULL, $special);
case is_int($source):
case is_object($source) && strtolower(get_class($source)) == 'math_biginteger':
return $this->_encode_der($source, array('type' => FILE_ASN1_TYPE_INTEGER) + $mapping);
return $this->_encode_der($source, array('type' => FILE_ASN1_TYPE_INTEGER) + $mapping, NULL, $special);
case is_float($source):
return $this->_encode_der($source, array('type' => FILE_ASN1_TYPE_REAL) + $mapping);
return $this->_encode_der($source, array('type' => FILE_ASN1_TYPE_REAL) + $mapping, NULL, $special);
case is_bool($source):
return $this->_encode_der($source, array('type' => FILE_ASN1_TYPE_BOOLEAN) + $mapping);
return $this->_encode_der($source, array('type' => FILE_ASN1_TYPE_BOOLEAN) + $mapping, NULL, $special);
case is_array($source) && count($source) == 1:
$typename = implode('', array_keys($source));
$outtype = array_search($typename, $this->ANYmap, true);
if ($outtype !== false) {
return $this->_encode_der($source[$typename], array('type' => $outtype) + $mapping);
return $this->_encode_der($source[$typename], array('type' => $outtype) + $mapping, NULL, $special);
}
}
@ -1015,7 +1058,7 @@ class File_ASN1 {
user_error('No filters defined for ' . implode('/', $loc));
return false;
}
return $this->_encode_der($source, $filters + $mapping);
return $this->_encode_der($source, $filters + $mapping, NULL, $special);
case FILE_ASN1_TYPE_NULL:
$value = '';
break;
@ -1055,7 +1098,7 @@ class File_ASN1 {
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 § 8.1.3} for more information.
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param Integer $length

View File

@ -40,22 +40,22 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMXII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id$
* @link htp://phpseclib.sourceforge.net
* @link http://phpseclib.sourceforge.net
*/
/**
* Include File_ASN1
*/
if (!class_exists('File_ASN1')) {
require_once('File/ASN1.php');
require_once('ASN1.php');
}
/**
* Flag to only accept signatures signed by certificate authorities
*
* Not really used anymore but retained all the same to suppress E_NOTICEs from old installs
*
* @access public
* @see File_X509::validateSignature()
*/
define('FILE_X509_VALIDATE_SIGNATURE_BY_CA', 1);
@ -306,6 +306,10 @@ class File_X509 {
*/
function File_X509()
{
if (!class_exists('Math_BigInteger')) {
require_once('Math/BigInteger.php');
}
// Explicitly Tagged Module, 1988 Syntax
// http://tools.ietf.org/html/rfc5280#appendix-A.1
@ -1436,18 +1440,7 @@ class File_X509 {
$asn1 = new File_ASN1();
/*
X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them above and beyond the ceritificate. ie.
some may have the following preceeding the -----BEGIN CERTIFICATE----- line:
subject=/O=organization/OU=org unit/CN=common name
issuer=/O=organization/CN=common name
*/
$temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $cert);
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
if ($temp != false) {
$cert = $temp;
}
$cert = $this->_extractBER($cert);
if ($cert === false) {
$this->currentCert = false;
@ -1569,7 +1562,7 @@ class File_X509 {
corresponding to the extension type identified by extnID */
$map = $this->_getMapping($id);
if (!is_bool($map)) {
$mapped = $asn1->asn1map($decoded[0], $map);
$mapped = $asn1->asn1map($decoded[0], $map, array('iPAddress' => array($this, '_decodeIP')));
$value = $mapped === false ? $decoded[0] : $mapped;
if ($id == 'id-ce-certificatePolicies') {
@ -1651,7 +1644,7 @@ class File_X509 {
unset($extensions[$i]);
}
} else {
$temp = $asn1->encodeDER($value, $map);
$temp = $asn1->encodeDER($value, $map, array('iPAddress' => array($this, '_encodeIP')));
$value = base64_encode($temp);
}
}
@ -2001,16 +1994,19 @@ class File_X509 {
* Works on X.509 certs, CSR's and CRL's.
* Returns true if the signature is verified, false if it is not correct or NULL on error
*
* By default returns false for self-signed certs. Call validateSignature(false) to make this support
* self-signed.
*
* The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}.
*
* @param Integer $options optional
* @param Boolean $caonly optional
* @access public
* @return Mixed
*/
function validateSignature($options = 0)
function validateSignature($caonly = true)
{
if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
return 0;
return NULL;
}
/* TODO:
@ -2048,10 +2044,10 @@ class File_X509 {
}
}
}
if (count($this->CAs) == $i && ($options & FILE_X509_VALIDATE_SIGNATURE_BY_CA)) {
if (count($this->CAs) == $i && $caonly) {
return false;
}
} elseif (!isset($signingCert) || ($options & FILE_X509_VALIDATE_SIGNATURE_BY_CA)) {
} elseif (!isset($signingCert) || $caonly) {
return false;
}
return $this->_validateSignature(
@ -2182,6 +2178,36 @@ class File_X509 {
}
}
/**
* Decodes an IP address
*
* Takes in a base64 encoded "blob" and returns a human readable IP address
*
* @param String $ip
* @access private
* @return String
*/
function _decodeIP($ip)
{
$ip = base64_decode($ip);
list(, $ip) = unpack('N', $ip);
return long2ip($ip);
}
/**
* Encodes an IP address
*
* Takes a human readable IP address into a base64-encoded "blob"
*
* @param String $ip
* @access private
* @return String
*/
function _encodeIP($ip)
{
return base64_encode(pack('N', ip2long($ip)));
}
/**
* "Normalizes" a Distinguished Name property
*
@ -2207,7 +2233,7 @@ class File_X509 {
case 'commonname':
case 'cn':
return 'id-at-commonName';
case 'id-at-stateorprovinceName':
case 'id-at-stateorprovincename':
case 'stateorprovincename':
case 'state':
case 'province':
@ -2630,9 +2656,9 @@ class File_X509 {
case !isset($this->currentCert) || !is_array($this->currentCert):
break;
case isset($this->currentCert['tbsCertificate']):
return $this->getDNProp($propname, $this->currentCert['tbsCertificate']['issuer'], $withType);
return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['issuer'], $withType);
case isset($this->currentCert['tbsCertList']):
return $this->getDNProp($propname, $this->currentCert['tbsCertList']['issuer'], $withType);
return $this->getDNProp($propName, $this->currentCert['tbsCertList']['issuer'], $withType);
}
return false;
@ -2656,7 +2682,7 @@ class File_X509 {
case isset($this->currentCert['tbsCertificate']):
return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['subject'], $withType);
case isset($this->currentCert['certificationRequestInfo']):
return $this->getDNProp($propname, $this->currentCert['certificationRequestInfo']['subject'], $withType);
return $this->getDNProp($propName, $this->currentCert['certificationRequestInfo']['subject'], $withType);
}
return false;
@ -2718,6 +2744,7 @@ class File_X509 {
*/
function setPublicKey($key)
{
$key->setPublicKey();
$this->publicKey = $key;
}
@ -2804,11 +2831,7 @@ class File_X509 {
$asn1 = new File_ASN1();
$temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr);
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
if ($temp != false) {
$csr = $temp;
}
$csr = $this->_extractBER($csr);
$orig = $csr;
if ($csr === false) {
@ -2917,51 +2940,51 @@ class File_X509 {
* @access public
* @return Mixed
*/
function loadSPKAC($csr)
function loadSPKAC($spkac)
{
if (is_array($csr) && isset($csr['publicKeyAndChallenge'])) {
if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) {
unset($this->currentCert);
unset($this->currentKeyIdentifier);
unset($this->signatureSubject);
$this->currentCert = $csr;
return $csr;
$this->currentCert = $spkac;
return $spkac;
}
// see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge
$asn1 = new File_ASN1();
$temp = preg_replace('#(?:^[^=]+=)|[\r\n\\\]#', '', $csr);
$temp = preg_replace('#(?:^[^=]+=)|[\r\n\\\]#', '', $spkac);
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
if ($temp != false) {
$csr = $temp;
$spkac = $temp;
}
$orig = $csr;
$orig = $spkac;
if ($csr === false) {
if ($spkac === false) {
$this->currentCert = false;
return false;
}
$asn1->loadOIDs($this->oids);
$decoded = $asn1->decodeBER($csr);
$decoded = $asn1->decodeBER($spkac);
if (empty($decoded)) {
$this->currentCert = false;
return false;
}
$csr = $asn1->asn1map($decoded[0], $this->SignedPublicKeyAndChallenge);
$spkac = $asn1->asn1map($decoded[0], $this->SignedPublicKeyAndChallenge);
if (!isset($csr) || $csr === false) {
if (!isset($spkac) || $spkac === false) {
$this->currentCert = false;
return false;
}
$this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
$algorithm = &$csr['publicKeyAndChallenge']['spki']['algorithm']['algorithm'];
$key = &$csr['publicKeyAndChallenge']['spki']['subjectPublicKey'];
$algorithm = &$spkac['publicKeyAndChallenge']['spki']['algorithm']['algorithm'];
$key = &$spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'];
$key = $this->_reformatKey($algorithm, $key);
switch ($algorithm) {
@ -2978,9 +3001,9 @@ class File_X509 {
}
$this->currentKeyIdentifier = NULL;
$this->currentCert = $csr;
$this->currentCert = $spkac;
return $csr;
return $spkac;
}
/**
@ -3000,11 +3023,7 @@ class File_X509 {
$asn1 = new File_ASN1();
$temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $crl);
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
if ($temp != false) {
$crl = $temp;
}
$crl = $this->_extractBER($crl);
$orig = $crl;
if ($crl === false) {
@ -3209,9 +3228,29 @@ class File_X509 {
$this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier);
}
$altName = array();
if (isset($subject->domains) && count($subject->domains) > 1) {
$this->setExtension('id-ce-subjectAltName',
array_map(array('File_X509', '_dnsName'), $subject->domains));
$altName = array_map(array('File_X509', '_dnsName'), $subject->domains);
}
if (isset($subject->ipAddresses) && count($subject->ipAddresses)) {
// should an IP address appear as the CN if no domain name is specified? idk
//$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1);
$ipAddresses = array();
foreach ($subject->ipAddresses as $ipAddress) {
$encoded = $subject->_ipAddress($ipAddress);
if ($encoded !== false) {
$ipAddresses[] = $encoded;
}
}
if (count($ipAddresses)) {
$altName = array_merge($altName, $ipAddresses);
}
}
if (!empty($altName)) {
$this->setExtension('id-ce-subjectAltName', $altName);
}
if ($this->caFlag) {
@ -4012,12 +4051,29 @@ class File_X509 {
case !is_object($key):
return false;
case strtolower(get_class($key)) == 'file_asn1_element':
// Assume the element is a bitstring-packed key.
$asn1 = new File_ASN1();
$decoded = $asn1->decodeBER($cert);
$decoded = $asn1->decodeBER($key->element);
if (empty($decoded)) {
return false;
}
$key = $asn1->asn1map($decoded[0], array('type' => FILE_ASN1_TYPE_BIT_STRING));
$raw = $asn1->asn1map($decoded[0], array('type' => FILE_ASN1_TYPE_BIT_STRING));
if (empty($raw)) {
return false;
}
$raw = base64_decode($raw);
// If the key is private, compute identifier from its corresponding public key.
if (!class_exists('Crypt_RSA')) {
require_once('Crypt/RSA.php');
}
$key = new Crypt_RSA();
if (!$key->loadKey($raw)) {
return false; // Not an unencrypted RSA key.
}
if ($key->getPrivateKey() !== false) { // If private.
return $this->computeKeyIdentifier($key, $method);
}
$key = $raw; // Is a public key.
break;
case strtolower(get_class($key)) == 'file_x509':
if (isset($key->publicKey)) {
@ -4036,9 +4092,7 @@ class File_X509 {
}
// If in PEM format, convert to binary.
if (preg_match('#^-----BEGIN #', $key)) {
$key = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $key));
}
$key = $this->_extractBER($key);
// Now we have the key string: compute its sha-1 sum.
if (!class_exists('Crypt_Hash')) {
@ -4094,6 +4148,23 @@ class File_X509 {
$this->setDNProp('id-at-commonName', $this->domains[0]);
}
/**
* Set the IP Addresses's which the cert is to be valid for
*
* @access public
* @param String $ipAddress optional
*/
function setIPAddress()
{
$this->ipAddresses = func_get_args();
/*
if (!isset($this->domains)) {
$this->removeDNProp('id-at-commonName');
$this->setDNProp('id-at-commonName', $this->ipAddresses[0]);
}
*/
}
/**
* Helper function to build domain array
*
@ -4106,6 +4177,20 @@ class File_X509 {
return array('dNSName' => $domain);
}
/**
* Helper function to build IP Address array
*
* (IPv6 is not currently supported)
*
* @access private
* @param String $address
* @return Array
*/
function _iPAddress($address)
{
return array('iPAddress' => $address);
}
/**
* Get the index of a revoked certificate.
*
@ -4320,4 +4405,31 @@ class File_X509 {
return false;
}
/**
* Extract raw BER from Base64 encoding
*
* @access private
* @param String $str
* @return String
*/
function _extractBER($str)
{
/*
X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them above and beyond the ceritificate. ie.
some may have the following preceding the -----BEGIN CERTIFICATE----- line:
Bag Attributes
localKeyID: 01 00 00 00
subject=/O=organization/OU=org unit/CN=common name
issuer=/O=organization/CN=common name
*/
$temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1);
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
$temp = preg_replace('#-+[^-]+-+#', '', $temp);
// remove new lines
$temp = str_replace(array("\r", "\n", ' '), '', $temp);
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
return $temp != false ? $temp : $str;
}
}

View File

@ -70,7 +70,6 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMVI Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id: BigInteger.php,v 1.33 2010/03/22 22:32:03 terrafrost Exp $
* @link http://pear.php.net/package/Math_BigInteger
*/
@ -162,16 +161,6 @@ define('MATH_BIGINTEGER_MODE_BCMATH', 2);
define('MATH_BIGINTEGER_MODE_GMP', 3);
/**#@-*/
/**
* The largest digit that may be used in addition / subtraction
*
* (we do pow(2, 52) instead of using 4503599627370496, directly, because some PHP installations
* will truncate 4503599627370496)
*
* @access private
*/
define('MATH_BIGINTEGER_MAX_DIGIT52', pow(2, 52));
/**
* Karatsuba Cutoff
*
@ -232,7 +221,7 @@ class Math_BigInteger {
var $bitmask = false;
/**
* Mode independant value used for serialization.
* Mode independent value used for serialization.
*
* If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for
* a variable that'll be serializable regardless of whether or not extensions are being used. Unlike $this->value,
@ -246,20 +235,20 @@ class Math_BigInteger {
var $hex;
/**
* Converts base-2, base-10, base-16, and binary strings (eg. base-256) to BigIntegers.
* Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers.
*
* If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
* two's compliment. The sole exception to this is -10, which is treated the same as 10 is.
*
* Here's an example:
* <code>
* <?php
* &lt;?php
* include('Math/BigInteger.php');
*
* $a = new Math_BigInteger('0x32', 16); // 50 in base-16
*
* echo $a->toString(); // outputs 50
* ?>
* ?&gt;
* </code>
*
* @param optional $x base-10 number or base-$base number if $base set.
@ -283,7 +272,64 @@ class Math_BigInteger {
}
if (function_exists('openssl_public_encrypt') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
ob_start();
phpinfo();
$content = ob_get_contents();
ob_end_clean();
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
$versions = array();
if (!empty($matches[1])) {
for ($i = 0; $i < count($matches[1]); $i++) {
$versions[$matches[1][$i]] = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
}
}
// it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
switch (true) {
case !isset($versions['Header']):
case !isset($versions['Library']):
case $versions['Header'] == $versions['Library']:
define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
break;
default:
define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
}
}
if (!defined('PHP_INT_SIZE')) {
define('PHP_INT_SIZE', 4);
}
if (!defined('MATH_BIGINTEGER_BASE') && MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_INTERNAL) {
switch (PHP_INT_SIZE) {
case 8: // use 64-bit integers if int size is 8 bytes
define('MATH_BIGINTEGER_BASE', 31);
define('MATH_BIGINTEGER_BASE_FULL', 0x80000000);
define('MATH_BIGINTEGER_MAX_DIGIT', 0x7FFFFFFF);
define('MATH_BIGINTEGER_MSB', 0x40000000);
// 10**9 is the closest we can get to 2**31 without passing it
define('MATH_BIGINTEGER_MAX10', 1000000000);
define('MATH_BIGINTEGER_MAX10_LEN', 9);
// the largest digit that may be used in addition / subtraction
define('MATH_BIGINTEGER_MAX_DIGIT2', pow(2, 62));
break;
//case 4: // use 64-bit floats if int size is 4 bytes
default:
define('MATH_BIGINTEGER_BASE', 26);
define('MATH_BIGINTEGER_BASE_FULL', 0x4000000);
define('MATH_BIGINTEGER_MAX_DIGIT', 0x3FFFFFF);
define('MATH_BIGINTEGER_MSB', 0x2000000);
// 10**7 is the closest to 2**26 without passing it
define('MATH_BIGINTEGER_MAX10', 10000000);
define('MATH_BIGINTEGER_MAX10_LEN', 7);
// the largest digit that may be used in addition / subtraction
// we do pow(2, 52) instead of using 4503599627370496 directly because some
// PHP installations will truncate 4503599627370496.
define('MATH_BIGINTEGER_MAX_DIGIT2', pow(2, 52));
}
}
switch ( MATH_BIGINTEGER_MODE ) {
@ -338,7 +384,7 @@ class Math_BigInteger {
// converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb)
default:
while (strlen($x)) {
$this->value[] = $this->_bytes2int($this->_base256_rshift($x, 26));
$this->value[] = $this->_bytes2int($this->_base256_rshift($x, MATH_BIGINTEGER_BASE));
}
}
@ -390,7 +436,10 @@ class Math_BigInteger {
break;
case 10:
case -10:
$x = preg_replace('#^(-?[0-9]*).*#', '$1', $x);
// (?<!^)(?:-).*: find any -'s that aren't at the beginning and then any characters that follow that
// (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
// [^-0-9].*: find any non-numeric characters and then any characters that follow that
$x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
switch ( MATH_BIGINTEGER_MODE ) {
case MATH_BIGINTEGER_MODE_GMP:
@ -399,26 +448,24 @@ class Math_BigInteger {
case MATH_BIGINTEGER_MODE_BCMATH:
// explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different
// results then doing it on '-1' does (modInverse does $x[0])
$this->value = (string) $x;
$this->value = $x === '-' ? '0' : (string) $x;
break;
default:
$temp = new Math_BigInteger();
// array(10000000) is 10**7 in base-2**26. 10**7 is the closest to 2**26 we can get without passing it.
$multiplier = new Math_BigInteger();
$multiplier->value = array(10000000);
$multiplier->value = array(MATH_BIGINTEGER_MAX10);
if ($x[0] == '-') {
$this->is_negative = true;
$x = substr($x, 1);
}
$x = str_pad($x, strlen($x) + (6 * strlen($x)) % 7, 0, STR_PAD_LEFT);
$x = str_pad($x, strlen($x) + ((MATH_BIGINTEGER_MAX10_LEN - 1) * strlen($x)) % MATH_BIGINTEGER_MAX10_LEN, 0, STR_PAD_LEFT);
while (strlen($x)) {
$temp = $temp->multiply($multiplier);
$temp = $temp->add(new Math_BigInteger($this->_int2bytes(substr($x, 0, 7)), 256));
$x = substr($x, 7);
$temp = $temp->add(new Math_BigInteger($this->_int2bytes(substr($x, 0, MATH_BIGINTEGER_MAX10_LEN)), 256));
$x = substr($x, MATH_BIGINTEGER_MAX10_LEN);
}
$this->value = $temp->value;
@ -543,7 +590,7 @@ class Math_BigInteger {
$temp = $this->copy();
for ($i = count($temp->value) - 2; $i >= 0; --$i) {
$temp->_base256_lshift($result, 26);
$temp->_base256_lshift($result, MATH_BIGINTEGER_BASE);
$result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT);
}
@ -659,11 +706,11 @@ class Math_BigInteger {
$temp->is_negative = false;
$divisor = new Math_BigInteger();
$divisor->value = array(10000000); // eg. 10**7
$divisor->value = array(MATH_BIGINTEGER_MAX10);
$result = '';
while (count($temp->value)) {
list($temp, $mod) = $temp->divide($divisor);
$result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', 7, '0', STR_PAD_LEFT) . $result;
$result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', MATH_BIGINTEGER_MAX10_LEN, '0', STR_PAD_LEFT) . $result;
}
$result = ltrim($result, '0');
if (empty($result)) {
@ -874,25 +921,25 @@ class Math_BigInteger {
$carry = 0;
for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
$sum = $x_value[$j] * 0x4000000 + $x_value[$i] + $y_value[$j] * 0x4000000 + $y_value[$i] + $carry;
$carry = $sum >= MATH_BIGINTEGER_MAX_DIGIT52; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
$sum = $carry ? $sum - MATH_BIGINTEGER_MAX_DIGIT52 : $sum;
$sum = $x_value[$j] * MATH_BIGINTEGER_BASE_FULL + $x_value[$i] + $y_value[$j] * MATH_BIGINTEGER_BASE_FULL + $y_value[$i] + $carry;
$carry = $sum >= MATH_BIGINTEGER_MAX_DIGIT2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
$sum = $carry ? $sum - MATH_BIGINTEGER_MAX_DIGIT2 : $sum;
$temp = (int) ($sum / 0x4000000);
$temp = (int) ($sum / MATH_BIGINTEGER_BASE_FULL);
$value[$i] = (int) ($sum - 0x4000000 * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)
$value[$i] = (int) ($sum - MATH_BIGINTEGER_BASE_FULL * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)
$value[$j] = $temp;
}
if ($j == $size) { // ie. if $y_size is odd
$sum = $x_value[$i] + $y_value[$i] + $carry;
$carry = $sum >= 0x4000000;
$value[$i] = $carry ? $sum - 0x4000000 : $sum;
$carry = $sum >= MATH_BIGINTEGER_BASE_FULL;
$value[$i] = $carry ? $sum - MATH_BIGINTEGER_BASE_FULL : $sum;
++$i; // ie. let $i = $j since we've just done $value[$i]
}
if ($carry) {
for (; $value[$i] == 0x3FFFFFF; ++$i) {
for (; $value[$i] == MATH_BIGINTEGER_MAX_DIGIT; ++$i) {
$value[$i] = 0;
}
++$value[$i];
@ -1010,26 +1057,26 @@ class Math_BigInteger {
$carry = 0;
for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) {
$sum = $x_value[$j] * 0x4000000 + $x_value[$i] - $y_value[$j] * 0x4000000 - $y_value[$i] - $carry;
$sum = $x_value[$j] * MATH_BIGINTEGER_BASE_FULL + $x_value[$i] - $y_value[$j] * MATH_BIGINTEGER_BASE_FULL - $y_value[$i] - $carry;
$carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
$sum = $carry ? $sum + MATH_BIGINTEGER_MAX_DIGIT52 : $sum;
$sum = $carry ? $sum + MATH_BIGINTEGER_MAX_DIGIT2 : $sum;
$temp = (int) ($sum / 0x4000000);
$temp = (int) ($sum / MATH_BIGINTEGER_BASE_FULL);
$x_value[$i] = (int) ($sum - 0x4000000 * $temp);
$x_value[$i] = (int) ($sum - MATH_BIGINTEGER_BASE_FULL * $temp);
$x_value[$j] = $temp;
}
if ($j == $y_size) { // ie. if $y_size is odd
$sum = $x_value[$i] - $y_value[$i] - $carry;
$carry = $sum < 0;
$x_value[$i] = $carry ? $sum + 0x4000000 : $sum;
$x_value[$i] = $carry ? $sum + MATH_BIGINTEGER_BASE_FULL : $sum;
++$i;
}
if ($carry) {
for (; !$x_value[$i]; ++$i) {
$x_value[$i] = 0x3FFFFFF;
$x_value[$i] = MATH_BIGINTEGER_MAX_DIGIT;
}
--$x_value[$i];
}
@ -1162,8 +1209,8 @@ class Math_BigInteger {
for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0
$temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
$carry = (int) ($temp / 0x4000000);
$product_value[$j] = (int) ($temp - 0x4000000 * $carry);
$carry = (int) ($temp / MATH_BIGINTEGER_BASE_FULL);
$product_value[$j] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
}
$product_value[$j] = $carry;
@ -1175,8 +1222,8 @@ class Math_BigInteger {
for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {
$temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
$carry = (int) ($temp / 0x4000000);
$product_value[$k] = (int) ($temp - 0x4000000 * $carry);
$carry = (int) ($temp / MATH_BIGINTEGER_BASE_FULL);
$product_value[$k] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
}
$product_value[$k] = $carry;
@ -1263,14 +1310,14 @@ class Math_BigInteger {
$i2 = $i << 1;
$temp = $square_value[$i2] + $value[$i] * $value[$i];
$carry = (int) ($temp / 0x4000000);
$square_value[$i2] = (int) ($temp - 0x4000000 * $carry);
$carry = (int) ($temp / MATH_BIGINTEGER_BASE_FULL);
$square_value[$i2] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
// note how we start from $i+1 instead of 0 as we do in multiplication.
for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {
$temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;
$carry = (int) ($temp / 0x4000000);
$square_value[$k] = (int) ($temp - 0x4000000 * $carry);
$carry = (int) ($temp / MATH_BIGINTEGER_BASE_FULL);
$square_value[$k] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
}
// the following line can yield values larger 2**15. at this point, PHP should switch
@ -1418,7 +1465,7 @@ class Math_BigInteger {
// normalize $x and $y as described in HAC 14.23 / 14.24
$msb = $y->value[count($y->value) - 1];
for ($shift = 0; !($msb & 0x2000000); ++$shift) {
for ($shift = 0; !($msb & MATH_BIGINTEGER_MSB); ++$shift) {
$msb <<= 1;
}
$x->_lshift($shift);
@ -1465,10 +1512,10 @@ class Math_BigInteger {
$q_index = $i - $y_max - 1;
if ($x_window[0] == $y_window[0]) {
$quotient_value[$q_index] = 0x3FFFFFF;
$quotient_value[$q_index] = MATH_BIGINTEGER_MAX_DIGIT;
} else {
$quotient_value[$q_index] = (int) (
($x_window[0] * 0x4000000 + $x_window[1])
($x_window[0] * MATH_BIGINTEGER_BASE_FULL + $x_window[1])
/
$y_window[0]
);
@ -1536,7 +1583,7 @@ class Math_BigInteger {
$result = array();
for ($i = count($dividend) - 1; $i >= 0; --$i) {
$temp = 0x4000000 * $carry + $dividend[$i];
$temp = MATH_BIGINTEGER_BASE_FULL * $carry + $dividend[$i];
$result[$i] = (int) ($temp / $divisor);
$carry = (int) ($temp - $divisor * $result[$i]);
}
@ -1754,7 +1801,7 @@ class Math_BigInteger {
$e_length = count($e_value) - 1;
$e_bits = decbin($e_value[$e_length]);
for ($i = $e_length - 1; $i >= 0; --$i) {
$e_bits.= str_pad(decbin($e_value[$i]), 26, '0', STR_PAD_LEFT);
$e_bits.= str_pad(decbin($e_value[$i]), MATH_BIGINTEGER_BASE, '0', STR_PAD_LEFT);
}
$e_length = strlen($e_bits);
@ -2089,7 +2136,7 @@ class Math_BigInteger {
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[] = 1;
$result = $this->_add($result, false, $corrector, false);
$result = $this->_add($result, false, $corrector_value, false);
$result = $result[MATH_BIGINTEGER_VALUE];
}
@ -2112,6 +2159,7 @@ class Math_BigInteger {
* @param Boolean $x_negative
* @param Array $y_value
* @param Boolean $y_negative
* @param Integer $stop
* @return Array
* @access private
*/
@ -2148,8 +2196,8 @@ class Math_BigInteger {
for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i
$temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
$carry = (int) ($temp / 0x4000000);
$product_value[$j] = (int) ($temp - 0x4000000 * $carry);
$carry = (int) ($temp / MATH_BIGINTEGER_BASE_FULL);
$product_value[$j] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
}
if ($j < $stop) {
@ -2164,8 +2212,8 @@ class Math_BigInteger {
for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {
$temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
$carry = (int) ($temp / 0x4000000);
$product_value[$k] = (int) ($temp - 0x4000000 * $carry);
$carry = (int) ($temp / MATH_BIGINTEGER_BASE_FULL);
$product_value[$k] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
}
if ($k < $stop) {
@ -2213,7 +2261,7 @@ class Math_BigInteger {
for ($i = 0; $i < $k; ++$i) {
$temp = $result[MATH_BIGINTEGER_VALUE][$i] * $cache[MATH_BIGINTEGER_DATA][$key];
$temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));
$temp = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * ((int) ($temp / MATH_BIGINTEGER_BASE_FULL)));
$temp = $this->_regularMultiply(array($temp), $n);
$temp = array_merge($this->_array_repeat(0, $i), $temp);
$result = $this->_add($result[MATH_BIGINTEGER_VALUE], false, $temp, false);
@ -2265,9 +2313,9 @@ class Math_BigInteger {
$a = array(MATH_BIGINTEGER_VALUE => $this->_array_repeat(0, $n + 1));
for ($i = 0; $i < $n; ++$i) {
$temp = $a[MATH_BIGINTEGER_VALUE][0] + $x[$i] * $y[0];
$temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));
$temp = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * ((int) ($temp / MATH_BIGINTEGER_BASE_FULL)));
$temp = $temp * $cache[MATH_BIGINTEGER_DATA][$key];
$temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));
$temp = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * ((int) ($temp / MATH_BIGINTEGER_BASE_FULL)));
$temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false);
$a = $this->_add($a[MATH_BIGINTEGER_VALUE], false, $temp[MATH_BIGINTEGER_VALUE], false);
$a[MATH_BIGINTEGER_VALUE] = array_slice($a[MATH_BIGINTEGER_VALUE], 1);
@ -2325,15 +2373,15 @@ class Math_BigInteger {
* @param Array $x
* @return Integer
*/
function _modInverse67108864($x) // 2**26 == 67108864
function _modInverse67108864($x) // 2**26 == 67,108,864
{
$x = -$x[0];
$result = $x & 0x3; // x**-1 mod 2**2
$result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4
$result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8
$result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16
$result = fmod($result * (2 - fmod($x * $result, 0x4000000)), 0x4000000); // x**-1 mod 2**26
return $result & 0x3FFFFFF;
$result = fmod($result * (2 - fmod($x * $result, MATH_BIGINTEGER_BASE_FULL)), MATH_BIGINTEGER_BASE_FULL); // x**-1 mod 2**26
return $result & MATH_BIGINTEGER_MAX_DIGIT;
}
/**
@ -2402,12 +2450,12 @@ class Math_BigInteger {
}
/**
* Calculates the greatest common divisor and Bézout's identity.
* Calculates the greatest common divisor and Bezout's identity.
*
* Say you have 693 and 609. The GCD is 21. Bézout's identity states that there exist integers x and y such that
* Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that
* 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which
* combination is returned is dependant upon which mode is in use. See
* {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bézout's identity - Wikipedia} for more information.
* {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information.
*
* Here's an example:
* <code>
@ -2604,8 +2652,8 @@ class Math_BigInteger {
*
* Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y).
*
* @param Math_BigInteger $x
* @return Integer < 0 if $this is less than $x; > 0 if $this is greater than $x, and 0 if they are equal.
* @param Math_BigInteger $y
* @return Integer < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
* @access public
* @see equals()
* @internal Could return $this->subtract($x), but that's not as fast as what we do do.
@ -2684,9 +2732,8 @@ class Math_BigInteger {
* Some bitwise operations give different results depending on the precision being used. Examples include left
* shift, not, and rotates.
*
* @param Math_BigInteger $x
* @param Integer $bits
* @access public
* @return Math_BigInteger
*/
function setPrecision($bits)
{
@ -2736,7 +2783,7 @@ class Math_BigInteger {
$result->value = array_slice($result->value, 0, $length);
for ($i = 0; $i < $length; ++$i) {
$result->value[$i] = $result->value[$i] & $x->value[$i];
$result->value[$i]&= $x->value[$i];
}
return $this->_normalize($result);
@ -2772,11 +2819,11 @@ class Math_BigInteger {
$length = max(count($this->value), count($x->value));
$result = $this->copy();
$result->value = array_pad($result->value, 0, $length);
$x->value = array_pad($x->value, 0, $length);
$result->value = array_pad($result->value, $length, 0);
$x->value = array_pad($x->value, $length, 0);
for ($i = 0; $i < $length; ++$i) {
$result->value[$i] = $this->value[$i] | $x->value[$i];
$result->value[$i]|= $x->value[$i];
}
return $this->_normalize($result);
@ -2812,11 +2859,11 @@ class Math_BigInteger {
$length = max(count($this->value), count($x->value));
$result = $this->copy();
$result->value = array_pad($result->value, 0, $length);
$x->value = array_pad($x->value, 0, $length);
$result->value = array_pad($result->value, $length, 0);
$x->value = array_pad($x->value, $length, 0);
for ($i = 0; $i < $length; ++$i) {
$result->value[$i] = $this->value[$i] ^ $x->value[$i];
$result->value[$i]^= $x->value[$i];
}
return $this->_normalize($result);
@ -3004,6 +3051,37 @@ class Math_BigInteger {
{
}
/**
* Generates a random BigInteger
*
* Byte length is equal to $length. Uses crypt_random if it's loaded and mt_rand if it's not.
*
* @param Integer $length
* @return Math_BigInteger
* @access private
*/
function _random_number_helper($size)
{
$crypt_random = function_exists('crypt_random_string') || (!class_exists('Crypt_Random') && function_exists('crypt_random_string'));
if ($crypt_random) {
$random = crypt_random_string($size);
} else {
$random = '';
if ($size & 1) {
$random.= chr(mt_rand(0, 255));
}
$blocks = $size >> 1;
for ($i = 0; $i < $blocks; ++$i) {
// mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
$random.= pack('n', mt_rand(0, 0xFFFF));
}
}
return new Math_BigInteger($random, 256);
}
/**
* Generate a random number
*
@ -3033,48 +3111,45 @@ class Math_BigInteger {
$min = $temp;
}
$generator = $this->generator;
$max = $max->subtract($min);
$max = ltrim($max->toBytes(), chr(0));
$size = strlen($max) - 1;
$crypt_random = function_exists('crypt_random_string') || (!class_exists('Crypt_Random') && function_exists('crypt_random_string'));
if ($crypt_random) {
$random = crypt_random_string($size);
} else {
$random = '';
if ($size & 1) {
$random.= chr(mt_rand(0, 255));
}
$blocks = $size >> 1;
for ($i = 0; $i < $blocks; ++$i) {
// mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
$random.= pack('n', mt_rand(0, 0xFFFF));
}
static $one;
if (!isset($one)) {
$one = new Math_BigInteger(1);
}
$fragment = new Math_BigInteger($random, 256);
$leading = $fragment->compare(new Math_BigInteger(substr($max, 1), 256)) > 0 ?
ord($max[0]) - 1 : ord($max[0]);
$max = $max->subtract($min->subtract($one));
$size = strlen(ltrim($max->toBytes(), chr(0)));
if (!$crypt_random) {
$msb = chr(mt_rand(0, $leading));
} else {
$cutoff = floor(0xFF / $leading) * $leading;
while (true) {
$msb = ord(crypt_random_string(1));
if ($msb <= $cutoff) {
$msb%= $leading;
break;
}
}
$msb = chr($msb);
/*
doing $random % $max doesn't work because some numbers will be more likely to occur than others.
eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145
would produce 5 whereas the only value of random that could produce 139 would be 139. ie.
not all numbers would be equally likely. some would be more likely than others.
creating a whole new random number until you find one that is within the range doesn't work
because, for sufficiently small ranges, the likelihood that you'd get a number within that range
would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability
would be pretty high that $random would be greater than $max.
phpseclib works around this using the technique described here:
http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string
*/
$random_max = new Math_BigInteger(chr(1) . str_repeat("\0", $size), 256);
$random = $this->_random_number_helper($size);
list($max_multiple) = $random_max->divide($max);
$max_multiple = $max_multiple->multiply($max);
while ($random->compare($max_multiple) >= 0) {
$random = $random->subtract($max_multiple);
$random_max = $random_max->subtract($max_multiple);
$random = $random->bitwise_leftShift(8);
$random = $random->add($this->_random_number_helper(1));
$random_max = $random_max->bitwise_leftShift(8);
list($max_multiple) = $random_max->divide($max);
$max_multiple = $max_multiple->multiply($max);
}
$random = new Math_BigInteger($msb . $random, 256);
list(, $random) = $random->divide($max);
return $this->_normalize($random->add($min));
}
@ -3094,10 +3169,18 @@ class Math_BigInteger {
*/
function randomPrime($min = false, $max = false, $timeout = false)
{
if ($min === false) {
$min = new Math_BigInteger(0);
}
if ($max === false) {
$max = new Math_BigInteger(0x7FFFFFFF);
}
$compare = $max->compare($min);
if (!$compare) {
return $min;
return $min->isPrime() ? $min : false;
} else if ($compare < 0) {
// if $min is bigger then $max, swap $min and $max
$temp = $max;
@ -3105,36 +3188,6 @@ class Math_BigInteger {
$min = $temp;
}
// gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP && function_exists('gmp_nextprime') ) {
// we don't rely on Math_BigInteger::random()'s min / max when gmp_nextprime() is being used since this function
// does its own checks on $max / $min when gmp_nextprime() is used. When gmp_nextprime() is not used, however,
// the same $max / $min checks are not performed.
if ($min === false) {
$min = new Math_BigInteger(0);
}
if ($max === false) {
$max = new Math_BigInteger(0x7FFFFFFF);
}
$x = $this->random($min, $max);
$x->value = gmp_nextprime($x->value);
if ($x->compare($max) <= 0) {
return $x;
}
$x->value = gmp_nextprime($min->value);
if ($x->compare($max) <= 0) {
return $x;
}
return false;
}
static $one, $two;
if (!isset($one)) {
$one = new Math_BigInteger(1);
@ -3144,6 +3197,23 @@ class Math_BigInteger {
$start = time();
$x = $this->random($min, $max);
// gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP && function_exists('gmp_nextprime') ) {
$p = new Math_BigInteger();
$p->value = gmp_nextprime($x->value);
if ($p->compare($max) <= 0) {
return $p;
}
if (!$min->equals($x)) {
$x = $x->subtract($one);
}
return $x->randomPrime($min, $x);
}
if ($x->equals($two)) {
return $x;
}
@ -3375,16 +3445,16 @@ class Math_BigInteger {
return;
}
$num_digits = (int) ($shift / 26);
$shift %= 26;
$num_digits = (int) ($shift / MATH_BIGINTEGER_BASE);
$shift %= MATH_BIGINTEGER_BASE;
$shift = 1 << $shift;
$carry = 0;
for ($i = 0; $i < count($this->value); ++$i) {
$temp = $this->value[$i] * $shift + $carry;
$carry = (int) ($temp / 0x4000000);
$this->value[$i] = (int) ($temp - $carry * 0x4000000);
$carry = (int) ($temp / MATH_BIGINTEGER_BASE_FULL);
$this->value[$i] = (int) ($temp - $carry * MATH_BIGINTEGER_BASE_FULL);
}
if ( $carry ) {
@ -3410,9 +3480,9 @@ class Math_BigInteger {
return;
}
$num_digits = (int) ($shift / 26);
$shift %= 26;
$carry_shift = 26 - $shift;
$num_digits = (int) ($shift / MATH_BIGINTEGER_BASE);
$shift %= MATH_BIGINTEGER_BASE;
$carry_shift = MATH_BIGINTEGER_BASE - $shift;
$carry_mask = (1 << $shift) - 1;
if ( $num_digits ) {
@ -3485,6 +3555,7 @@ class Math_BigInteger {
*
* Removes leading zeros
*
* @param Array $value
* @return Math_BigInteger
* @access private
*/
@ -3630,4 +3701,4 @@ class Math_BigInteger {
$temp = ltrim(pack('N', $length), chr(0));
return pack('Ca*', 0x80 | strlen($temp), $temp);
}
}
}

View File

@ -0,0 +1,362 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Pure-PHP implementation of SCP.
*
* PHP versions 4 and 5
*
* The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include('Net/SCP.php');
* include('Net/SSH2.php');
*
* $ssh = new Net_SSH2('www.domain.tld');
* if (!$ssh->login('username', 'password')) {
* exit('bad login');
* }
* $scp = new Net_SCP($ssh);
* $scp->put('abcd', str_repeat('x', 1024*1024));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net
* @package Net_SCP
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMX Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**#@+
* @access public
* @see Net_SCP::put()
*/
/**
* Reads data from a local file.
*/
define('NET_SCP_LOCAL_FILE', 1);
/**
* Reads data from a string.
*/
define('NET_SCP_STRING', 2);
/**#@-*/
/**#@+
* @access private
* @see Net_SCP::_send()
* @see Net_SCP::_receive()
*/
/**
* SSH1 is being used.
*/
define('NET_SCP_SSH1', 1);
/**
* SSH2 is being used.
*/
define('NET_SCP_SSH2', 2);
/**#@-*/
/**
* Pure-PHP implementations of SCP.
*
* @author Jim Wigginton <terrafrost@php.net>
* @version 0.1.0
* @access public
* @package Net_SCP
*/
class Net_SCP {
/**
* SSH Object
*
* @var Object
* @access private
*/
var $ssh;
/**
* Packet Size
*
* @var Integer
* @access private
*/
var $packet_size;
/**
* Mode
*
* @var Integer
* @access private
*/
var $mode;
/**
* Default Constructor.
*
* Connects to an SSH server
*
* @param String $host
* @param optional Integer $port
* @param optional Integer $timeout
* @return Net_SCP
* @access public
*/
function Net_SCP($ssh)
{
if (!is_object($ssh)) {
return;
}
switch (strtolower(get_class($ssh))) {
case'net_ssh2':
$this->mode = NET_SCP_SSH2;
break;
case 'net_ssh1':
$this->packet_size = 50000;
$this->mode = NET_SCP_SSH1;
break;
default:
return;
}
$this->ssh = $ssh;
}
/**
* Uploads a file to the SCP server.
*
* By default, Net_SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
* So, for example, if you set $data to 'filename.ext' and then do Net_SCP::get(), you will get a file, twelve bytes
* long, containing 'filename.ext' as its contents.
*
* Setting $mode to NET_SCP_LOCAL_FILE will change the above behavior. With NET_SCP_LOCAL_FILE, $remote_file will
* 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.
*
* 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.
*
* @param String $remote_file
* @param String $data
* @param optional Integer $mode
* @param optional Callable $callback
* @return Boolean
* @access public
*/
function put($remote_file, $data, $mode = NET_SCP_STRING, $callback = null)
{
if (!isset($this->ssh)) {
return false;
}
if (!$this->ssh->exec('scp -t ' . $remote_file, false)) { // -t = to
return false;
}
$temp = $this->_receive();
if ($temp !== chr(0)) {
return false;
}
if ($this->mode == NET_SCP_SSH2) {
$this->packet_size = $this->ssh->packet_size_client_to_server[NET_SSH2_CHANNEL_EXEC];
}
$remote_file = basename($remote_file);
if ($mode == NET_SCP_STRING) {
$size = strlen($data);
} else {
if (!is_file($data)) {
user_error("$data is not a valid file", E_USER_NOTICE);
return false;
}
$fp = @fopen($data, 'rb');
if (!$fp) {
fclose($fp);
return false;
}
$size = filesize($data);
}
$this->_send('C0644 ' . $size . ' ' . $remote_file . "\n");
$temp = $this->_receive();
if ($temp !== chr(0)) {
return false;
}
$sent = 0;
while ($sent < $size) {
$temp = $mode & NET_SCP_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size);
$this->_send($temp);
$sent+= strlen($temp);
if (is_callable($callback)) {
$callback($sent);
}
}
$this->_close();
if ($mode != NET_SCP_STRING) {
fclose($fp);
}
return true;
}
/**
* Downloads a file from the SCP server.
*
* Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
* the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the
* operation
*
* @param String $remote_file
* @param optional String $local_file
* @return Mixed
* @access public
*/
function get($remote_file, $local_file = false)
{
if (!isset($this->ssh)) {
return false;
}
if (!$this->ssh->exec('scp -f ' . $remote_file, false)) { // -f = from
return false;
}
$this->_send("\0");
if (!preg_match('#(?<perms>[^ ]+) (?<size>\d+) (?<name>.+)#', rtrim($this->_receive()), $info)) {
return false;
}
$this->_send("\0");
$size = 0;
if ($local_file !== false) {
$fp = @fopen($local_file, 'wb');
if (!$fp) {
return false;
}
}
$content = '';
while ($size < $info['size']) {
$data = $this->_receive();
// SCP usually seems to split stuff out into 16k chunks
$size+= strlen($data);
if ($local_file === false) {
$content.= $data;
} else {
fputs($fp, $data);
}
}
$this->_close();
if ($local_file !== false) {
fclose($fp);
return true;
}
return $content;
}
/**
* Sends a packet to an SSH server
*
* @param String $data
* @access private
*/
function _send($data)
{
switch ($this->mode) {
case NET_SCP_SSH2:
$this->ssh->_send_channel_packet(NET_SSH2_CHANNEL_EXEC, $data);
break;
case NET_SCP_SSH1:
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
$this->ssh->_send_binary_packet($data);
}
}
/**
* Receives a packet from an SSH server
*
* @return String
* @access private
*/
function _receive()
{
switch ($this->mode) {
case NET_SCP_SSH2:
return $this->ssh->_get_channel_packet(NET_SSH2_CHANNEL_EXEC, true);
case NET_SCP_SSH1:
if (!$this->ssh->bitmap) {
return false;
}
while (true) {
$response = $this->ssh->_get_binary_packet();
switch ($response[NET_SSH1_RESPONSE_TYPE]) {
case NET_SSH1_SMSG_STDOUT_DATA:
extract(unpack('Nlength', $response[NET_SSH1_RESPONSE_DATA]));
return $this->ssh->_string_shift($response[NET_SSH1_RESPONSE_DATA], $length);
case NET_SSH1_SMSG_STDERR_DATA:
break;
case NET_SSH1_SMSG_EXITSTATUS:
$this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION));
fclose($this->ssh->fsock);
$this->ssh->bitmap = 0;
return false;
default:
user_error('Unknown packet received', E_USER_NOTICE);
return false;
}
}
}
}
/**
* Closes the connection to an SSH server
*
* @access private
*/
function _close()
{
switch ($this->mode) {
case NET_SCP_SSH2:
$this->ssh->_close_channel(NET_SSH2_CHANNEL_EXEC);
break;
case NET_SCP_SSH1:
$this->ssh->disconnect();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,771 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* SFTP Stream Wrapper
*
* Creates an sftp:// protocol handler that can be used with, for example, fopen(), dir(), etc.
*
* PHP version 5
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net
* @package Net_SFTP_Stream
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMXIII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* SFTP Stream Wrapper
*
* @author Jim Wigginton <terrafrost@php.net>
* @version 0.3.2
* @access public
* @package Net_SFTP_Stream
*/
class Net_SFTP_Stream {
/**
* SFTP instances
*
* Rather than re-create the connection we re-use instances if possible
*
* @var Array
* @access static
*/
static $instances;
/**
* SFTP instance
*
* @var Object
* @access private
*/
var $sftp;
/**
* Path
*
* @var String
* @access private
*/
var $path;
/**
* Mode
*
* @var String
* @access private
*/
var $mode;
/**
* Position
*
* @var Integer
* @access private
*/
var $pos;
/**
* Size
*
* @var Integer
* @access private
*/
var $size;
/**
* Directory entries
*
* @var Array
* @access private
*/
var $entries;
/**
* EOF flag
*
* @var Boolean
* @access private
*/
var $eof;
/**
* Context resource
*
* Technically this needs to be publically accessible so PHP can set it directly
*
* @var Resource
* @access public
*/
var $context;
/**
* Notification callback function
*
* @var Callable
* @access public
*/
var $notification;
/**
* The Constructor
*
* @access public
*/
function Net_SFTP_Stream()
{
if (!class_exists('Net_SFTP')) {
require_once('Net/SFTP.php');
}
}
/**
* Path Parser
*
* Extract a path from a URI and actually connect to an SSH server if appropriate
*
* If "notification" is set as a context parameter the message code for successful login is
* NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE.
*
* @param String $path
* @return String
* @access private
*/
function _parse_path($path)
{
extract(parse_url($path) + array('port' => 22));
if (!isset($host)) {
return false;
}
if (isset($this->context)) {
$context = stream_context_get_params($this->context);
if (isset($context['notification'])) {
$this->notification = $context['notification'];
}
}
if ($host[0] == '$') {
$host = substr($host, 1);
global $$host;
if (!is_object($$host) || get_class($$host) != 'Net_SFTP') {
return false;
}
$this->sftp = $$host;
} else {
if (isset($this->context)) {
$context = stream_context_get_options($this->context);
}
if (isset($context['sftp']['session'])) {
$sftp = $context['sftp']['session'];
}
if (isset($context['sftp']['sftp'])) {
$sftp = $context['sftp']['sftp'];
}
if (isset($sftp) && is_object($sftp) && get_class($sftp) == 'Net_SFTP') {
$this->sftp = $sftp;
return $path;
}
if (isset($context['sftp']['username'])) {
$user = $context['sftp']['username'];
}
if (isset($context['sftp']['password'])) {
$pass = $context['sftp']['password'];
}
if (isset($context['sftp']['privkey']) && is_object($context['sftp']['privkey']) && get_Class($context['sftp']['privkey']) == 'Crypt_RSA') {
$pass = $context['sftp']['privkey'];
}
if (!isset($user) || !isset($pass)) {
return false;
}
// casting $pass to a string is necessary in the event that it's a Crypt_RSA object
if (isset(self::$instances[$host][$port][$user][(string) $pass])) {
$this->sftp = self::$instances[$host][$port][$user][(string) $pass];
} else {
$this->sftp = new Net_SFTP($host, $port);
if (isset($this->notification) && is_callable($this->notification)) {
/* if !is_callable($this->notification) we could do this:
user_error('fopen(): failed to call user notifier', E_USER_WARNING);
the ftp wrapper gives errors like that when the notifier isn't callable.
i've opted not to do that, however, since the ftp wrapper gives the line
on which the fopen occurred as the line number - not the line that the
user_error is on.
*/
call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
if (!$this->sftp->login($user, $pass)) {
call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0);
return false;
}
call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0);
} else {
if (!$this->sftp->login($user, $pass)) {
return false;
}
}
self::$instances[$host][$port][$user][(string) $pass] = $this->sftp;
}
}
return $path;
}
/**
* Opens file or URL
*
* @param String $path
* @param String $mode
* @param Integer $options
* @param String $opened_path
* @return Boolean
* @access public
*/
function _stream_open($path, $mode, $options, &$opened_path)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$this->path = $path;
$this->size = $this->sftp->size($path);
$this->mode = preg_replace('#[bt]$#', '', $mode);
$this->eof = false;
if ($this->size === false) {
if ($this->mode[0] == 'r') {
return false;
}
} else {
switch ($this->mode[0]) {
case 'x':
return false;
case 'w':
case 'c':
$this->sftp->truncate($path, 0);
}
}
$this->pos = $this->mode[0] != 'a' ? 0 : $this->size;
return true;
}
/**
* Read from stream
*
* @param Integer $count
* @return Mixed
* @access public
*/
function _stream_read($count)
{
switch ($this->mode) {
case 'w':
case 'a':
case 'x':
case 'c':
return false;
}
// commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite
//if ($this->pos >= $this->size) {
// $this->eof = true;
// return false;
//}
$result = $this->sftp->get($this->path, false, $this->pos, $count);
if (isset($this->notification) && is_callable($this->notification)) {
if ($result === false) {
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
return 0;
}
// seems that PHP calls stream_read in 8k chunks
call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size);
}
if (empty($result)) { // ie. false or empty string
$this->eof = true;
return false;
}
$this->pos+= strlen($result);
return $result;
}
/**
* Write to stream
*
* @param String $data
* @return Mixed
* @access public
*/
function _stream_write($data)
{
switch ($this->mode) {
case 'r':
return false;
}
$result = $this->sftp->put($this->path, $data, NET_SFTP_STRING, $this->pos);
if (isset($this->notification) && is_callable($this->notification)) {
if (!$result) {
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
return 0;
}
// seems that PHP splits up strings into 8k blocks before calling stream_write
call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data));
}
if ($result === false) {
return false;
}
$this->pos+= strlen($data);
if ($this->pos > $this->size) {
$this->size = $this->pos;
}
$this->eof = false;
return strlen($data);
}
/**
* Retrieve the current position of a stream
*
* @return Integer
* @access public
*/
function _stream_tell()
{
return $this->pos;
}
/**
* Tests for end-of-file on a file pointer
*
* In my testing there are four classes functions that normally effect the pointer:
* fseek, fputs / fwrite, fgets / fread and ftruncate.
*
* Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof()
* will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof()
* will return false. do fread($fp, 1) and feof() will then return true.
*
* @return Boolean
* @access public
*/
function _stream_eof()
{
return $this->eof;
}
/**
* Seeks to specific location in a stream
*
* @param Integer $offset
* @param Integer $whence
* @return Boolean
* @access public
*/
function _stream_seek($offset, $whence)
{
switch ($whence) {
case SEEK_SET:
if ($offset >= $this->size || $offset < 0) {
return false;
}
break;
case SEEK_CUR:
$offset+= $this->pos;
break;
case SEEK_END:
$offset+= $this->size;
}
$this->pos = $offset;
$this->eof = false;
return true;
}
/**
* Change stream options
*
* @param String $path
* @param Integer $option
* @param Mixed $var
* @return Boolean
* @access public
*/
function _stream_metadata($path, $option, $var)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
// stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined
// see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246
// and https://github.com/php/php-src/blob/master/main/php_streams.h#L592
switch ($option) {
case 1: // PHP_STREAM_META_TOUCH
return $this->sftp->touch($path, $var[0], $var[1]);
case 2: // PHP_STREAM_OWNER_NAME
case 3: // PHP_STREAM_GROUP_NAME
return false;
case 4: // PHP_STREAM_META_OWNER
return $this->sftp->chown($path, $var);
case 5: // PHP_STREAM_META_GROUP
return $this->sftp->chgrp($path, $var);
case 6: // PHP_STREAM_META_ACCESS
return $this->sftp->chmod($path, $var) !== false;
}
}
/**
* Retrieve the underlaying resource
*
* @param Integer $cast_as
* @return Resource
* @access public
*/
function _stream_cast($cast_as)
{
return $this->sftp->fsock;
}
/**
* Advisory file locking
*
* @param Integer $operation
* @return Boolean
* @access public
*/
function _stream_lock($operation)
{
return false;
}
/**
* Renames a file or directory
*
* Attempts to rename oldname to newname, moving it between directories if necessary.
* If newname exists, it will be overwritten. This is a departure from what Net_SFTP
* does.
*
* @param String $path_from
* @param String $path_to
* @return Boolean
* @access public
*/
function _rename($path_from, $path_to)
{
$path1 = parse_url($path_from);
$path2 = parse_url($path_to);
unset($path1['path'], $path2['path']);
if ($path1 != $path2) {
return false;
}
$path_from = $this->_parse_path($path_from);
$path_to = parse_url($path_to);
if ($path_from == false) {
return false;
}
$path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2
// "It is an error if there already exists a file with the name specified by newpath."
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5
if (!$this->sftp->rename($path_from, $path_to)) {
if ($this->sftp->stat($path_to)) {
return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to);
}
return false;
}
return true;
}
/**
* Open directory handle
*
* The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and
* removed in 5.4 I'm just going to ignore it
*
* @param String $path
* @param Integer $options
* @return Boolean
* @access public
*/
function _dir_opendir($path, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$this->pos = 0;
$this->entries = $this->sftp->nlist($path);
return $this->entries !== false;
}
/**
* Read entry from directory handle
*
* @return Mixed
* @access public
*/
function _dir_readdir()
{
if (isset($this->entries[$this->pos])) {
return $this->entries[$this->pos++];
}
return false;
}
/**
* Rewind directory handle
*
* @return Boolean
* @access public
*/
function _dir_rewinddir()
{
$this->pos = 0;
return true;
}
/**
* Close directory handle
*
* @return Boolean
* @access public
*/
function _dir_closedir()
{
return true;
}
/**
* Create a directory
*
* Only valid $options is STREAM_MKDIR_RECURSIVE
*
* @param String $path
* @param Integer $mode
* @param Integer $options
* @return Boolean
* @access public
*/
function _mkdir($path, $mode, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE);
}
/**
* Removes a directory
*
* Only valid $options is STREAM_MKDIR_RECURSIVE per <http://php.net/streamwrapper.rmdir>, however,
* <http://php.net/rmdir> does not have a $recursive parameter as mkdir() does so I don't know how
* STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as
* $options. What does 8 correspond to?
*
* @param String $path
* @param Integer $mode
* @param Integer $options
* @return Boolean
* @access public
*/
function _rmdir($path, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->rmdir($path);
}
/**
* Flushes the output
*
* See <http://php.net/fflush>. Always returns true because Net_SFTP doesn't cache stuff before writing
*
* @return Boolean
* @access public
*/
function _stream_flush()
{
return true;
}
/**
* Retrieve information about a file resource
*
* @return Mixed
* @access public
*/
function _stream_stat()
{
$results = $this->sftp->stat($this->path);
if ($results === false) {
return false;
}
return $results;
}
/**
* Delete a file
*
* @param String $path
* @return Boolean
* @access public
*/
function _unlink($path)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->delete($path, false);
}
/**
* Retrieve information about a file
*
* Ignores the STREAM_URL_STAT_QUIET flag because the entirety of Net_SFTP_Stream is quiet by default
* might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll
* cross that bridge when and if it's reached
*
* @param String $path
* @param Integer $flags
* @return Mixed
* @access public
*/
function _url_stat($path, $flags)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path);
if ($results === false) {
return false;
}
return $results;
}
/**
* Truncate stream
*
* @param Integer $new_size
* @return Boolean
* @access public
*/
function _stream_truncate($new_size)
{
if (!$this->sftp->truncate($this->path, $new_size)) {
return false;
}
$this->eof = false;
$this->size = $new_size;
return true;
}
/**
* Change stream options
*
* STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't.
* The other two aren't supported because of limitations in Net_SFTP.
*
* @param Integer $option
* @param Integer $arg1
* @param Integer $arg2
* @return Boolean
* @access public
*/
function _stream_set_option($option, $arg1, $arg2)
{
return false;
}
/**
* Close an resource
*
* @access public
*/
function _stream_close()
{
}
/**
* __call Magic Method
*
* When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you.
* Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function
* lets you figure that out.
*
* If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not
* NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method.
*
* @param String
* @param Array
* @return Mixed
* @access public
*/
function __call($name, $arguments)
{
if (defined('NET_SFTP_STREAM_LOGGING')) {
echo $name . '(';
$last = count($arguments) - 1;
foreach ($arguments as $i => $argument) {
var_export($argument);
if ($i != $last) {
echo ',';
}
}
echo ")\r\n";
}
$name = '_' . $name;
if (!method_exists($this, $name)) {
return false;
}
return call_user_func_array(array($this, $name), $arguments);
}
}
if (function_exists('stream_wrapper_register')) {
stream_wrapper_register('sftp', 'Net_SFTP_Stream');
}

View File

@ -62,56 +62,9 @@
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMVII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version $Id: SSH1.php,v 1.15 2010/03/22 22:01:38 terrafrost Exp $
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Math_BigInteger
*
* Used to do RSA encryption.
*/
if (!class_exists('Math_BigInteger')) {
require_once('Math/BigInteger.php');
}
/**
* Include Crypt_Null
*/
//require_once('Crypt/Null.php');
/**
* Include Crypt_DES
*/
if (!class_exists('Crypt_DES')) {
require_once('Crypt/DES.php');
}
/**
* Include Crypt_TripleDES
*/
if (!class_exists('Crypt_TripleDES')) {
require_once('Crypt/TripleDES.php');
}
/**
* Include Crypt_RC4
*/
if (!class_exists('Crypt_RC4')) {
require_once('Crypt/RC4.php');
}
/**
* Include Crypt_Random
*/
// the class_exists() will only be called if the crypt_random_string function hasn't been defined and
// will trigger a call to __autoload() if you're wanting to auto-load classes
// call function_exists() a second time to stop the require_once from being called outside
// of the auto loader
if (!function_exists('crypt_random_string') && !class_exists('Crypt_Random') && !function_exists('crypt_random_string')) {
require_once('Crypt/Random.php');
}
/**#@+
* Encryption Methods
*
@ -495,6 +448,19 @@ class Net_SSH1 {
*/
function Net_SSH1($host, $port = 22, $timeout = 10, $cipher = NET_SSH1_CIPHER_3DES)
{
if (!class_exists('Math_BigInteger')) {
require_once('Math/BigInteger.php');
}
// Include Crypt_Random
// the class_exists() will only be called if the crypt_random_string function hasn't been defined and
// will trigger a call to __autoload() if you're wanting to auto-load classes
// call function_exists() a second time to stop the require_once from being called outside
// of the auto loader
if (!function_exists('crypt_random_string') && !class_exists('Crypt_Random') && !function_exists('crypt_random_string')) {
require_once('Crypt/Random.php');
}
$this->protocol_flags = array(
1 => 'NET_SSH1_MSG_DISCONNECT',
2 => 'NET_SSH1_SMSG_PUBLIC_KEY',
@ -636,18 +602,27 @@ class Net_SSH1 {
// $this->crypto = new Crypt_Null();
// break;
case NET_SSH1_CIPHER_DES:
if (!class_exists('Crypt_DES')) {
require_once('Crypt/DES.php');
}
$this->crypto = new Crypt_DES();
$this->crypto->disablePadding();
$this->crypto->enableContinuousBuffer();
$this->crypto->setKey(substr($session_key, 0, 8));
break;
case NET_SSH1_CIPHER_3DES:
if (!class_exists('Crypt_TripleDES')) {
require_once('Crypt/TripleDES.php');
}
$this->crypto = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC);
$this->crypto->disablePadding();
$this->crypto->enableContinuousBuffer();
$this->crypto->setKey(substr($session_key, 0, 24));
break;
//case NET_SSH1_CIPHER_RC4:
// if (!class_exists('Crypt_RC4')) {
// require_once('Crypt/RC4.php');
// }
// $this->crypto = new Crypt_RC4();
// $this->crypto->enableContinuousBuffer();
// $this->crypto->setKey(substr($session_key, 0, 16));
@ -935,7 +910,7 @@ class Net_SSH1 {
* Returns the output of an interactive shell when no more output is available.
*
* Requires PHP 4.3.0 or later due to the use of the stream_select() function. If you see stuff like
* "", you're seeing ANSI escape codes. According to
* "^[[00m", you're seeing ANSI escape codes. According to
* {@link http://support.microsoft.com/kb/101875 How to Enable ANSI.SYS in a Command Window}, "Windows NT
* does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user,
* there's not going to be much recourse.
@ -1574,4 +1549,4 @@ class Net_SSH1 {
fputs($this->realtime_log_file, $entry);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More