Version Description
Download this release
Release Info
Developer | xcloner |
Plugin | XCloner – Backup and Restore |
Version | 3.0.5 |
Comparing to | |
See all releases |
Code changes from version 3.0.8 to 3.0.5
- admin.cloner.html.php +1083 -1586
- admin.cloner.php +198 -222
- admin.xcloner-backupandrestore.php +0 -5
- classes/error.class.php → administrator/backups/.excl +0 -0
- browser/files_inpage.php +3 -10
- browser/files_xml.php +14 -21
- browser/xmlhttp.js +5 -5
- classes/S3.php +1 -4
- classes/fileRecursion.php +8 -57
- classes/index.html +0 -0
- classes/main.class.php +0 -116
- classes/mysqlBackup.class.php +0 -488
- classes/phpseclib/Crypt/AES.php +0 -594
- classes/phpseclib/Crypt/DES.php +0 -1245
- classes/phpseclib/Crypt/Hash.php +0 -824
- classes/phpseclib/Crypt/RC4.php +0 -505
- classes/phpseclib/Crypt/RSA.php +0 -2356
- classes/phpseclib/Crypt/Random.php +0 -133
- classes/phpseclib/Crypt/Rijndael.php +0 -1424
- classes/phpseclib/Crypt/TripleDES.php +0 -1009
- classes/phpseclib/Math/BigInteger.php +0 -3551
- classes/phpseclib/Net/SFTP.php +0 -1609
- classes/phpseclib/Net/SSH1.php +0 -1408
- classes/phpseclib/Net/SSH2.php +0 -2660
- classes/phpseclib/PHP/Compat/Function/array_fill.php +0 -41
- classes/phpseclib/PHP/Compat/Function/bcpowmod.php +0 -66
- classes/phpseclib/PHP/Compat/Function/str_split.php +0 -59
- cloner.config.php +0 -3
- cloner.cron.php +88 -135
- cloner.functions.php +154 -325
- common.php +17 -45
- css/{start/jquery-ui-1.8.9.custom.css → jquery-ui.css} +316 -319
- css/main.css +6 -90
- css/start/images/ui-bg_flat_55_999999_40x100.png +0 -0
- css/start/images/ui-bg_flat_75_aaaaaa_40x100.png +0 -0
- css/start/images/ui-bg_glass_45_0078ae_1x400.png +0 -0
- css/start/images/ui-bg_glass_55_f8da4e_1x400.png +0 -0
- css/start/images/ui-bg_glass_75_79c9ec_1x400.png +0 -0
- css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png +0 -0
- css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png +0 -0
- css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png +0 -0
- css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- css/start/images/ui-icons_0078ae_256x240.png +0 -0
- css/start/images/ui-icons_056b93_256x240.png +0 -0
- css/start/images/ui-icons_d8e7f3_256x240.png +0 -0
- css/start/images/ui-icons_e0fdff_256x240.png +0 -0
- css/start/images/ui-icons_f5e175_256x240.png +0 -0
- css/start/images/ui-icons_f7a50d_256x240.png +0 -0
- css/start/images/ui-icons_fcd113_256x240.png +0 -0
- css/tabber.css +109 -0
- images/logo.gif +0 -0
- images/logo.png +0 -0
- images/{progressBarLong.gif → progress.gif} +0 -0
- install.xcloner.php +12 -4
- javascript/backup.js +0 -172
- javascript/jquery-ui-1.8.9.custom.min.js +0 -663
admin.cloner.html.php
CHANGED
@@ -31,20 +31,20 @@ class mosTabs{
|
|
31 |
|
32 |
function mosTabs($int){
|
33 |
|
34 |
-
echo "<div
|
35 |
|
36 |
}
|
37 |
|
38 |
function startTab($name, $class){
|
39 |
|
40 |
-
echo "<div
|
41 |
|
42 |
|
43 |
}
|
44 |
|
45 |
function endTab(){
|
46 |
|
47 |
-
echo "</
|
48 |
|
49 |
}
|
50 |
|
@@ -63,16 +63,8 @@ class HTML_cloner {
|
|
63 |
|
64 |
function header(){
|
65 |
|
66 |
-
|
67 |
-
$excl_tasks = array("view", "config","");
|
68 |
|
69 |
-
/*if(!in_array($_REQUEST['task'], $excl_tasks)){
|
70 |
-
$seconds_to_cache = 3600;
|
71 |
-
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
|
72 |
-
@header("Expires: $ts");
|
73 |
-
@header("Pragma: cache");
|
74 |
-
@header("Cache-Control: maxage=$seconds_to_cache");
|
75 |
-
}*/
|
76 |
?>
|
77 |
<html lang="en">
|
78 |
<head>
|
@@ -80,14 +72,16 @@ function header(){
|
|
80 |
<title>XCloner Backup and Restore</title>
|
81 |
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
|
82 |
|
|
|
83 |
<link rel="styleSheet" href="css/dtree.css" type="text/css" />
|
84 |
<link rel="styleSheet" href="css/main.css" type="text/css" />
|
85 |
-
<link rel="styleSheet" href="css/
|
86 |
|
|
|
87 |
<script type="text/javascript" src="javascript/dtree.js"></script>
|
88 |
<script type="text/javascript" src="javascript/main.js"></script>
|
89 |
<script type="text/javascript" src="javascript/jquery-1.4.4.min.js"></script>
|
90 |
-
<script type="text/javascript" src="javascript/jquery-ui
|
91 |
<script type="text/javascript">
|
92 |
|
93 |
/* Optional: Temporarily hide the "tabber" class so it does not "flash"
|
@@ -107,31 +101,23 @@ document.write('<style type="text/css">.tabber{display:none;}<\/style>');
|
|
107 |
|
108 |
<tr><td align='center'>
|
109 |
|
110 |
-
<
|
111 |
-
<table width='100%' bgcolor='white' class="header">
|
112 |
<tr>
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
# Generating the buttons...
|
127 |
-
require_once( "toolbar.cloner.php" );
|
128 |
-
?>
|
129 |
-
</div>
|
130 |
-
</td>
|
131 |
</tr>
|
132 |
</table>
|
133 |
-
</div>
|
134 |
-
|
135 |
<br />
|
136 |
<table width="100%" cellspacing='3' cellpadding="4" >
|
137 |
<tr><td valign='top' width="160" >
|
@@ -206,7 +192,7 @@ document.write(d);
|
|
206 |
<?php
|
207 |
if($_REQUEST['mosmsg']!="")
|
208 |
|
209 |
-
echo "<center><h2>"
|
210 |
|
211 |
}
|
212 |
|
@@ -216,11 +202,9 @@ function footer(){
|
|
216 |
</td></tr></table>
|
217 |
<hr><br /><br />
|
218 |
<center>
|
219 |
-
<p>Powered by <a href='http://www.xcloner.com' target='_blank'>XCloner</a>.
|
220 |
|
221 |
</td></tr></table>
|
222 |
-
<script> $( "#toolbar" ).show(); </script>
|
223 |
-
</body></html>
|
224 |
|
225 |
<?php
|
226 |
|
@@ -234,9 +218,8 @@ function goRefreshHtml($filename, $perm_lines, $excl_manual){
|
|
234 |
$backupFile = $f['basename'];
|
235 |
|
236 |
if (file_exists($filename)) {
|
237 |
-
echo "<
|
238 |
-
echo "
|
239 |
-
|
240 |
$urlReturn = "index2.php?option=com_cloner&lines=" . $perm_lines . "&task=refresh&backup=$backupFile&excl_manual=$excl_manual";
|
241 |
|
242 |
if(!$_CONFIG['refresh_mode']){
|
@@ -247,8 +230,6 @@ function goRefreshHtml($filename, $perm_lines, $excl_manual){
|
|
247 |
|
248 |
}else{
|
249 |
|
250 |
-
echo "<script>var dbbackup = ".intval($_REQUEST['dbbackup']).";</script>";
|
251 |
-
|
252 |
?>
|
253 |
<!--Start ProgressBar-->
|
254 |
<script type="text/javascript">
|
@@ -257,13 +238,6 @@ function goRefreshHtml($filename, $perm_lines, $excl_manual){
|
|
257 |
|
258 |
var globalUrl;
|
259 |
var step = "r1";
|
260 |
-
var count = 0;
|
261 |
-
var counter = 0;
|
262 |
-
var counter_old = 0;
|
263 |
-
var completeSize = 0;
|
264 |
-
var oldBackupName = "";
|
265 |
-
var parts = 0;
|
266 |
-
var oldSize = 0;
|
267 |
|
268 |
$("#progressbar").progressbar({ value: 0 });
|
269 |
|
@@ -272,74 +246,14 @@ function goRefreshHtml($filename, $perm_lines, $excl_manual){
|
|
272 |
//reset state here;
|
273 |
$("#error").show();
|
274 |
$("#errorText").append(status+" -- "+error);
|
275 |
-
$("#errorText").append("<br /><br />JSON url: "+globalUrl);
|
276 |
}});
|
277 |
|
278 |
-
function getSize(bytes, conv){
|
279 |
-
|
280 |
-
return (parseInt(bytes)/parseInt(conv)).toFixed(2);
|
281 |
-
|
282 |
-
}
|
283 |
-
function appendIcon(icon){
|
284 |
-
|
285 |
-
return '<span class="ui-icon ui-icon-'+icon+'" style="float:left;"></span>';
|
286 |
-
|
287 |
-
}
|
288 |
-
|
289 |
-
function xclonerRecurseMYSQL(url){
|
290 |
-
// create database backup
|
291 |
-
globalUrl = url;
|
292 |
-
step = "r1";
|
293 |
-
|
294 |
-
$.getJSON(url, function(json) {
|
295 |
-
|
296 |
-
if(!json){
|
297 |
-
$("#error").show();
|
298 |
-
$("#errorText").text(url);
|
299 |
-
}
|
300 |
-
|
301 |
-
if(json.dumpsize && !json.endDump){
|
302 |
-
$("#mysqlProcess").append(" ("+getSize(json.dumpsize, 1024*1024)+" MB) <br />");
|
303 |
-
}
|
304 |
-
|
305 |
-
if(json.newDump){
|
306 |
-
count++;
|
307 |
-
//$("#mysqlProcess").append(appendIcon("arrowthick-1-e"));
|
308 |
-
if(json.databaseName!="")
|
309 |
-
$("#mysqlProcess").append("<b>["+json.databaseName+"]</b> <span id='db"+count+"'></span> tables ");
|
310 |
-
counter = parseInt(json.startAtLine);
|
311 |
-
|
312 |
-
}else{
|
313 |
-
$("#db"+count).text(json.startAtLine - counter);
|
314 |
-
}
|
315 |
-
|
316 |
-
if(!parseInt(json.finished)){
|
317 |
-
//get next records
|
318 |
-
|
319 |
-
$("#db"+count).text(json.startAtLine - counter);
|
320 |
-
|
321 |
-
recurseUrl = "index2.php?task=recurse_database&nohtml=1&dbbackup_comp="+json.dbbackup_comp+"&dbbackup_drop="+json.dbbackup_drop+"&startAtLine="+json.startAtLine+"&startAtRecord="+json.startAtRecord+"&dumpfile="+json.dumpfile;
|
322 |
-
xclonerRecurseMYSQL(recurseUrl);
|
323 |
-
|
324 |
-
}
|
325 |
-
else{
|
326 |
-
|
327 |
-
$("#fileSystem").show();
|
328 |
-
var recurseUrl="index2.php?task=recurse_files&mode=start&nohtml=1";
|
329 |
-
xclonerRecurseJSON(recurseUrl);
|
330 |
-
|
331 |
-
}
|
332 |
-
|
333 |
-
|
334 |
-
});
|
335 |
-
}
|
336 |
-
|
337 |
function xclonerRecurseJSON(url){
|
338 |
-
|
339 |
$("#result").hide();
|
340 |
|
341 |
globalUrl = url;
|
342 |
-
step = "
|
343 |
|
344 |
$.getJSON(url, function(json) {
|
345 |
|
@@ -358,18 +272,8 @@ function goRefreshHtml($filename, $perm_lines, $excl_manual){
|
|
358 |
}
|
359 |
else{
|
360 |
var size = parseFloat(json.size)/(1024*1024);
|
361 |
-
$("#recurseStatus").text(" done! (Estimated size:"+size.toFixed(2)+"MB)
|
362 |
$("#result").show();
|
363 |
-
|
364 |
-
if(json.overlimit.length > 0){
|
365 |
-
$("#overlimit").show();
|
366 |
-
for(var i=0; i < json.overlimit.length; i++){
|
367 |
-
|
368 |
-
$("#overlimit").append("<span class='oversizedFile'></span>"+json.overlimit[i]+"<br />");
|
369 |
-
|
370 |
-
}
|
371 |
-
}
|
372 |
-
|
373 |
//xclonerGetJSON("<?php echo $urlReturn;?>");
|
374 |
returnUrl = "index2.php?option=com_cloner&lines="+json.tfiles+"&task=refresh&backup=<?php echo $backupFile; ?>&excl_manual=";
|
375 |
xclonerGetJSON(returnUrl);
|
@@ -381,9 +285,9 @@ function goRefreshHtml($filename, $perm_lines, $excl_manual){
|
|
381 |
}
|
382 |
|
383 |
function xclonerGetJSON(url){
|
384 |
-
|
385 |
globalUrl = url;
|
386 |
-
step = "
|
387 |
|
388 |
$.getJSON(url, function(json) {
|
389 |
|
@@ -394,145 +298,62 @@ function goRefreshHtml($filename, $perm_lines, $excl_manual){
|
|
394 |
|
395 |
var percent = parseInt(json.percent);
|
396 |
$("#progressbar").progressbar({ value: percent });
|
397 |
-
$("#backupSize").text(
|
398 |
$("#nFiles").text(json.startf);
|
399 |
$("#percent").text(json.percent);
|
400 |
-
$("#backupName").text(json.backup);
|
401 |
if(!json.finished){
|
402 |
-
|
403 |
-
if(oldBackupName != json.backup){
|
404 |
-
oldBackupName = json.backup;
|
405 |
-
completeSize = completeSize + oldSize;
|
406 |
-
parts++;
|
407 |
-
}else{
|
408 |
-
oldSize = parseInt(json.backupSize);
|
409 |
-
}
|
410 |
-
|
411 |
var url = "index2.php?option="+json.option+"&task="+json.task+"&json="+json.json+"&startf="+json.startf+"&lines="+json.lines+"&backup="+json.backup+"&excl_manual="+json.excl_manual;
|
412 |
xclonerGetJSON(url);
|
413 |
}else{
|
414 |
|
415 |
-
//all done
|
416 |
-
url = "index2.php?task=cleanup&nohtml=1";
|
417 |
-
$.getJSON(url, function(json) {
|
418 |
-
});
|
419 |
-
|
420 |
$("#complete").show();
|
421 |
$("#nFiles").text(json.lines);
|
422 |
-
if(parts > 0){
|
423 |
-
$("#backupParts").show();
|
424 |
-
$("#backupPartsNr").text(parts);
|
425 |
-
}
|
426 |
-
$("#backupFiles").text(json.lines);
|
427 |
-
$("#backupSizeComplete").append(getSize(completeSize+parseInt(json.backupSize), 1024*1024));
|
428 |
-
$("#backupNameC").text(json.backup);
|
429 |
-
$( "#dialog:ui-dialog" ).dialog( "destroy" );
|
430 |
-
$( "#dialog-message" ).dialog({
|
431 |
-
modal: true,
|
432 |
-
width: 600,
|
433 |
-
buttons: {
|
434 |
-
Close: function() {
|
435 |
-
$( this ).dialog( "close" );
|
436 |
-
}
|
437 |
-
}
|
438 |
-
});
|
439 |
|
440 |
-
|
441 |
|
442 |
});
|
443 |
|
444 |
}
|
445 |
|
446 |
-
//Main program here
|
447 |
-
|
448 |
$("#retry").click(function(){
|
449 |
$("#error").hide();
|
450 |
$("#errorText").empty();
|
451 |
if(step == "r1"){
|
452 |
-
xclonerRecurseMYSQL(globalUrl);
|
453 |
-
}
|
454 |
-
else
|
455 |
-
if(step == "r2"){
|
456 |
xclonerRecurseJSON(globalUrl);
|
457 |
}
|
458 |
-
else if(step == "
|
459 |
xclonerGetJSON(globalUrl);
|
460 |
}
|
461 |
});
|
462 |
|
463 |
-
|
464 |
-
|
|
|
465 |
|
466 |
-
if(dbbackup){
|
467 |
-
recurseUrl = "index2.php?task=recurse_database&nohtml=1&dbbackup_comp=<?php echo $_REQUEST['dbbackup_comp']?>&dbbackup_drop=<?php echo $_REQUEST['dbbackup_drop']?>";
|
468 |
-
xclonerRecurseMYSQL(recurseUrl);
|
469 |
-
}else{
|
470 |
-
$("#fileSystem").show();
|
471 |
-
var recurseUrl="index2.php?task=recurse_files&mode=start&nohtml=1";
|
472 |
-
xclonerRecurseJSON(recurseUrl);
|
473 |
-
|
474 |
-
}
|
475 |
|
476 |
});
|
477 |
</script>
|
478 |
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
//lets start the incremental procedure
|
483 |
-
?>
|
484 |
|
485 |
-
<div id="
|
486 |
-
|
487 |
-
|
|
|
488 |
</div>
|
489 |
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
<
|
496 |
-
|
497 |
-
<
|
498 |
-
|
499 |
-
|
500 |
-
</div>
|
501 |
-
|
502 |
-
<div id="result">
|
503 |
-
<br /> <strong>Processing Files:</strong> <span id="percent">0</span>% (<span id="nFiles"></span> files)
|
504 |
-
<br /><br /> <strong>Backup Name: </strong><span id="backupName"></span>
|
505 |
-
<br /><br /> <strong>Backup Size: </strong><span id="backupSize"></span>MB
|
506 |
-
<br /><br /> <div id="progressbar"></div>
|
507 |
-
</div>
|
508 |
-
|
509 |
-
<div id="complete">
|
510 |
-
<br /><h2>Backup completed!</h2>
|
511 |
-
|
512 |
-
<form action="index2.php" name="adminForm" method="post">
|
513 |
-
<input type=hidden name=files[1] value='<?php echo $backupFile?>'>
|
514 |
-
<input type=hidden name=cid[1] value='<?php echo $backupFile?>'>
|
515 |
-
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
516 |
-
<input type="hidden" name="task" value=""/>
|
517 |
-
</form>
|
518 |
-
|
519 |
-
<div id="dialog-message" title="Backup completed">
|
520 |
-
<p>
|
521 |
-
<span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span>
|
522 |
-
<strong>Backup name:</strong> <span id="backupNameC"></span>
|
523 |
-
</p>
|
524 |
-
<p>
|
525 |
-
<span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Backup size:</strong> <span id="backupSizeComplete"></span>MB
|
526 |
-
</p>
|
527 |
-
<p>
|
528 |
-
<span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Number of files:</strong> <span id="backupFiles"></span>
|
529 |
-
</p>
|
530 |
-
<p class="backupParts">
|
531 |
-
<span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Backup Parts:</strong> <span id="backupPartsNr"></span>
|
532 |
-
</p>
|
533 |
-
</div>
|
534 |
-
|
535 |
-
</div>
|
536 |
</div>
|
537 |
|
538 |
<div id="error" style="display:none;">
|
@@ -581,7 +402,7 @@ function path_check($path){
|
|
581 |
}
|
582 |
|
583 |
function _FDefault(){
|
584 |
-
global $_CONFIG
|
585 |
?>
|
586 |
|
587 |
<form action="index2.php" method="post" name="adminForm">
|
@@ -656,29 +477,23 @@ $error = 0;
|
|
656 |
<div class="status">
|
657 |
<span class="mtext">Backup Start Path Check: </span>
|
658 |
<?php
|
659 |
-
|
660 |
-
$stat =
|
661 |
|
662 |
if( $stat['code'] > 0 and $stat['code'] < 3){
|
663 |
echo "<span class='error'>".$stat['message']; $error = 1;
|
664 |
}
|
665 |
else{
|
666 |
echo "<span class='success'>OK";
|
667 |
-
|
668 |
-
@mkdir($_CONFIG[backup_start_path]."/administrator");
|
669 |
-
if(@mkdir($_CONFIG[backup_start_path]."/administrator/backups"))
|
670 |
-
echo "<script>window.location='index2.php'</script";
|
671 |
-
}
|
672 |
-
}
|
673 |
echo " ($_CONFIG[backup_start_path])";
|
674 |
?>
|
675 |
</span></div>
|
676 |
-
|
677 |
<div class="status">
|
678 |
<span class="mtext">Backup Store Path Check: </span>
|
679 |
<?php
|
680 |
|
681 |
-
$stat =
|
682 |
|
683 |
if( $stat['code'] > 0){
|
684 |
echo "<span class='error'>".$stat['message']; $error = 1;
|
@@ -688,14 +503,12 @@ $error = 0;
|
|
688 |
}
|
689 |
echo " ($_CONFIG[backup_store_path])";
|
690 |
?>
|
691 |
-
</span>
|
692 |
-
</div>
|
693 |
-
|
694 |
<div class="status">
|
695 |
<span class="mtext">Temporary Path Check: </span>
|
696 |
<?php
|
697 |
|
698 |
-
$stat =
|
699 |
|
700 |
if( $stat['code'] > 0){
|
701 |
echo "<span class='error'>".$stat['message']; $error = 1;
|
@@ -707,20 +520,6 @@ $error = 0;
|
|
707 |
?>
|
708 |
</span></div>
|
709 |
|
710 |
-
<div class="status">
|
711 |
-
<span class="mtext">Authentication: </span>
|
712 |
-
<?php
|
713 |
-
|
714 |
-
if($_CONFIG['jcpass'] == md5('admin')){
|
715 |
-
echo "<span class='error'>Change default password 'admin'"; $error = 1;
|
716 |
-
}
|
717 |
-
else{
|
718 |
-
echo "<span class='success'>OK";
|
719 |
-
}
|
720 |
-
|
721 |
-
?>
|
722 |
-
</span></div>
|
723 |
-
|
724 |
<div class="status">
|
725 |
<span class="mtext">Backup Ready: </span>
|
726 |
<?php
|
@@ -745,61 +544,30 @@ $error = 0;
|
|
745 |
<?php
|
746 |
}
|
747 |
|
748 |
-
/*The basic
|
749 |
function Login(){
|
750 |
|
751 |
?>
|
752 |
<center><br />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
753 |
|
754 |
-
<script>
|
755 |
-
$(function() {
|
756 |
-
$( "#login" ).button({
|
757 |
-
icons: {
|
758 |
-
primary: "ui-icon-locked"
|
759 |
-
}
|
760 |
-
})
|
761 |
-
$("#login").click(function() {
|
762 |
-
$("#adminForm")[0].submit();
|
763 |
-
return false;
|
764 |
-
})
|
765 |
-
|
766 |
-
$( "#reset" ).button({
|
767 |
-
icons: {
|
768 |
-
primary: "ui-icon-trash"
|
769 |
-
}
|
770 |
-
})
|
771 |
-
$( "#reset" ).click(function() {
|
772 |
-
$("#username").val('');$("#password").val('');
|
773 |
-
return false;
|
774 |
-
});
|
775 |
-
|
776 |
-
});
|
777 |
-
</script>
|
778 |
-
|
779 |
-
|
780 |
-
<div class="loginform">
|
781 |
-
<form action="index2.php" method="post" name="adminForm" id="adminForm">
|
782 |
-
<table class="loginForm">
|
783 |
-
<tr><td align='center'>
|
784 |
-
<table align='center' cellpadding='10' cellspacing='20'>
|
785 |
-
<tr ><td colspan='2' align='center'><b>Authentication Area:</b></td></tr>
|
786 |
-
<tr><td>Username:</td><td><input type='text' size='30' name='username' id='username'></td></tr>
|
787 |
-
<tr><td>Password:</td><td><input type='password' size='30' name='password' id='password'></td></tr>
|
788 |
-
<tr><td> </td><td>
|
789 |
-
<div class="loginform">
|
790 |
-
<button id="login">Login</button>
|
791 |
-
<button id="reset">Reset</button>
|
792 |
|
793 |
|
794 |
-
</div>
|
795 |
-
</td></tr>
|
796 |
-
<tr><td colspan='2'><?php echo LM_LOGIN_TEXT;?></td></tr>
|
797 |
-
</table>
|
798 |
-
</td></tr>
|
799 |
</table>
|
800 |
|
801 |
<input type="hidden" name="option" value="com_cloner" />
|
802 |
-
|
803 |
<input type="hidden" name="boxchecked" value="0" />
|
804 |
<input type="hidden" name="hidemainmenu" value="0" />
|
805 |
|
@@ -812,45 +580,36 @@ function Login(){
|
|
812 |
function Cron(){
|
813 |
global $_CONFIG;
|
814 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
815 |
|
816 |
-
<
|
817 |
-
|
818 |
-
$( "#tabs" ).tabs();
|
819 |
-
});
|
820 |
-
</script>
|
821 |
-
|
822 |
-
<div id="tabs">
|
823 |
-
<ul>
|
824 |
-
<li><a href="#tabs-1"><?php echo LM_CRON_TOP?></a></li>
|
825 |
-
</ul>
|
826 |
-
|
827 |
-
<div id="tabs-1"><p>
|
828 |
-
|
829 |
-
<div class="mainText">
|
830 |
-
<?php echo LM_CRON_SUB?>
|
831 |
-
<br /><br />
|
832 |
-
|
833 |
-
<ul>
|
834 |
-
<li><input type="text" value="/usr/bin/php <?php echo dirname(__FILE__);?>/cloner.cron.php" size="150" /></li>
|
835 |
-
<li><strong>curl http://website/path_to_xcloner_folder/cloner.cron.php</strong></li>
|
836 |
-
<li><strong>wget -q http://website/path_to_xcloner_folder/cloner.cron.php</strong></li>
|
837 |
-
<li><strong>lynx -sourcehttp://website/path_to_xcloner_folder/cloner.cron.php</strong></li>
|
838 |
-
</ul>
|
839 |
-
<br /><br />
|
840 |
-
|
841 |
-
For <b>Running Multiple Crons</b>, you need to first create a custom configuration file in the XCloner Configuration -> Cron tab
|
842 |
-
and then replace "cloner.cron.php" with "cloner.cron.php?config=myconfig.php", only use 'links' or 'lynx' options to run the cronjob
|
843 |
-
<br /><br />
|
844 |
-
|
845 |
-
If you would like to use the <b>php SSH command</b> for running Multiple Crons, you will need to replace
|
846 |
-
the "cloner.cron.php" with <b>"cloner.cron.php myconfig.php"</b> in the command line.
|
847 |
-
<br /><br />
|
848 |
|
849 |
-
|
850 |
-
|
851 |
|
852 |
-
|
853 |
-
</
|
|
|
|
|
854 |
|
855 |
<?php
|
856 |
}
|
@@ -984,37 +743,29 @@ function Translator($option, $lang_arr){
|
|
984 |
global $_CONFIG;
|
985 |
|
986 |
?>
|
987 |
-
<script>
|
988 |
-
$(function() {
|
989 |
-
$( "#toggle" ).button();
|
990 |
-
$( "#toggle" ).click(function() { checkJAll(<?php echo count( $lang_arr ); ?>, "toggle", "cb"); });
|
991 |
-
$( "#checklist" ).buttonset();
|
992 |
-
});
|
993 |
-
</script>
|
994 |
|
995 |
-
|
996 |
-
<div id="checklist">
|
997 |
<table class="adminlist">
|
998 |
<tr>
|
999 |
-
<th align="
|
1000 |
-
<
|
|
|
1001 |
</th>
|
1002 |
<th align="left">
|
1003 |
<?php echo LM_LANG_NAME ?>
|
1004 |
</th>
|
1005 |
</tr>
|
1006 |
-
|
1007 |
<?php
|
|
|
1008 |
for($i=0; $i<sizeof($lang_arr); $i++){
|
1009 |
|
1010 |
?>
|
1011 |
|
1012 |
<tr>
|
1013 |
-
|
1014 |
-
<td
|
1015 |
-
<
|
1016 |
-
|
1017 |
-
<input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $lang_arr[$i] ?>" />
|
1018 |
</td>
|
1019 |
<td align="left" >
|
1020 |
<a href="index2.php?option=<?php echo $option;?>&task=edit_lang&langx=<?php echo $lang_arr[$i];?>"><?php echo ucfirst($lang_arr[$i])?>
|
@@ -1024,7 +775,7 @@ function Translator($option, $lang_arr){
|
|
1024 |
|
1025 |
}
|
1026 |
?>
|
1027 |
-
|
1028 |
<input type="hidden" name="option" value="com_cloner" />
|
1029 |
<input type="hidden" name="task" value="lang" />
|
1030 |
<input type="hidden" name="boxchecked" value="0" />
|
@@ -1040,65 +791,23 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
1040 |
global $baDownloadPath, $_CONFIG;
|
1041 |
|
1042 |
?>
|
1043 |
-
|
1044 |
-
<script type="text/javascript">
|
1045 |
-
|
1046 |
-
$(function() {
|
1047 |
-
$( "#toggle" ).button();
|
1048 |
-
$( "#toggle" ).click(function() { checkJAll(<?php echo (count( $files )); ?>, "toggle", "cb"); });
|
1049 |
-
$( "#checklist" ).buttonset();
|
1050 |
-
|
1051 |
-
$( "#Clone, #Rename, #Delete, #Move" ).unbind("click");
|
1052 |
-
$( "#Clone, #Rename, #Delete, #Move" ).click(function(){
|
1053 |
-
if(!$("input:checked").length){
|
1054 |
-
|
1055 |
-
$( "#error-message" ).dialog({
|
1056 |
-
width: 500,
|
1057 |
-
height: 200,
|
1058 |
-
modal: true,
|
1059 |
-
buttons: {
|
1060 |
-
Ok: function() {
|
1061 |
-
$( this ).dialog( "close" );
|
1062 |
-
}
|
1063 |
-
}
|
1064 |
-
});
|
1065 |
-
|
1066 |
-
return false;
|
1067 |
-
}else{
|
1068 |
-
var action = $(this).attr('id').toLowerCase();
|
1069 |
-
document.adminForm.task.value=action;
|
1070 |
-
document.adminForm.submit();
|
1071 |
-
}
|
1072 |
-
})
|
1073 |
-
|
1074 |
-
|
1075 |
-
})
|
1076 |
-
</script>
|
1077 |
-
|
1078 |
-
<div id="error-message" title="Error" style="display:none;">
|
1079 |
-
<p>
|
1080 |
-
<span class="ui-icon ui-icon-circle-check" style="float:left; margin:0 7px 50px 0;"></span>
|
1081 |
-
Please select at least one backup archive.
|
1082 |
-
</p>
|
1083 |
-
|
1084 |
-
</div>
|
1085 |
-
<div id="checklist">
|
1086 |
<form action="index2.php" method="post" name="adminForm">
|
1087 |
<table class="adminlist">
|
1088 |
<tr>
|
1089 |
-
<th width="
|
1090 |
-
<
|
1091 |
-
|
1092 |
-
<th align="left" width="100px;">
|
1093 |
-
<?php echo LM_COL_DOWNLOAD ?>
|
1094 |
</th>
|
1095 |
-
<th width="
|
1096 |
<?php echo LM_COL_FILENAME ?>
|
1097 |
</th>
|
1098 |
<th align="left" width="10%">
|
|
|
|
|
|
|
1099 |
<?php echo LM_COL_SIZE ?>
|
1100 |
</th>
|
1101 |
-
<th align="left" width="">
|
1102 |
<?php echo LM_COL_DATE ?>
|
1103 |
</th>
|
1104 |
</tr>
|
@@ -1106,28 +815,38 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
1106 |
$k = 0;
|
1107 |
for ($i=0; $i <= (count( $files )-1); $i++) {
|
1108 |
$date = date ("D jS M Y H:i:s (\G\M\T O)", filemtime($path.'/'.$files[$i]));
|
1109 |
-
$url = "index2.php?option=com_cloner&task=download&file=".'/'.urlencode($files[$i]);
|
1110 |
?>
|
1111 |
<tr class="<?php echo "row$k"; ?>">
|
1112 |
-
|
|
|
|
|
1113 |
<td align="center">
|
1114 |
-
|
1115 |
-
|
1116 |
-
<input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $files[$i] ?>" />
|
1117 |
</td>
|
1118 |
-
<td
|
1119 |
-
|
1120 |
-
</td>
|
1121 |
-
<td>
|
1122 |
-
<span class="backup_name"><?php echo $files[$i]; ?></span>
|
1123 |
-
<input type="hidden" id="f<?php echo $i ?>" name="f<?php echo $i ?>" value="<?php echo $files[$i]; ?>" >
|
1124 |
</td>
|
1125 |
-
|
1126 |
<td align="left">
|
1127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1128 |
</td >
|
1129 |
<td align="left">
|
1130 |
-
|
1131 |
</td>
|
1132 |
</tr>
|
1133 |
<?php
|
@@ -1135,7 +854,7 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
1135 |
}
|
1136 |
?>
|
1137 |
</table>
|
1138 |
-
|
1139 |
<input type="hidden" name="option" value="com_cloner" />
|
1140 |
<input type="hidden" name="task" value="" />
|
1141 |
<input type="hidden" name="boxchecked" value="0" />
|
@@ -1149,1091 +868,928 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
1149 |
global $config_file,$_CONFIG, $lang_array, $database, $mosConfig_db;
|
1150 |
?>
|
1151 |
<form name='adminForm' action='index2.php' method='POST'>
|
1152 |
-
|
1153 |
-
<script>
|
1154 |
-
$(function() {
|
1155 |
-
$( "#tabs" ).tabs();
|
1156 |
-
});
|
1157 |
-
|
1158 |
-
$(function() {
|
1159 |
-
$( "#radiog1" ).buttonset();
|
1160 |
-
$( "#radiog2" ).buttonset();
|
1161 |
-
$( "#radiog3" ).buttonset();
|
1162 |
-
$( "#radiog4" ).buttonset();
|
1163 |
-
$( "#radio" ).buttonset();
|
1164 |
-
$( "#radiom" ).buttonset();
|
1165 |
-
$( "#radiob" ).buttonset();
|
1166 |
-
$( "#radioftp" ).buttonset();
|
1167 |
-
$( "#radioftps" ).buttonset();
|
1168 |
-
$( "#radiodebug" ).buttonset();
|
1169 |
-
$( "#radiorefresh" ).buttonset();
|
1170 |
-
$( "#checktar" ).button();
|
1171 |
-
$( "#cron_file_delete_act" ).button();
|
1172 |
-
$( "#cron_sql_drop" ).button();
|
1173 |
-
$( "#cron_amazon_active" ).button();
|
1174 |
-
$( "#cron_amazon_ssl" ).button();
|
1175 |
-
$( "#cron_ftp_delb" ).button();
|
1176 |
-
$( "#checkmysqldump" ).button();
|
1177 |
-
});
|
1178 |
-
</script>
|
1179 |
-
|
1180 |
-
<?php $tabs = new mosTabs(1);?>
|
1181 |
-
<ul>
|
1182 |
-
|
1183 |
-
<li><a href="#tabs-1"><?php echo LM_TAB_GENERAL;?></a></li>
|
1184 |
-
<li><a href="#tabs-2"><?php echo LM_TAB_MYSQL;?></a></li>
|
1185 |
-
<li><a href="#tabs-3"><?php echo LM_TAB_AUTH;?></a></li>
|
1186 |
-
<li><a href="#tabs-4"><?php echo LM_TAB_SYSTEM;?></a></li>
|
1187 |
-
<li><a href="#tabs-5"><?php echo LM_TAB_CRON;?></a></li>
|
1188 |
-
<li><a href="#tabs-6"><?php echo LM_TAB_INFO;?></a></li>
|
1189 |
-
</ul>
|
1190 |
-
|
1191 |
<table class='adminform'>
|
1192 |
<tr><th colspan='2'>
|
1193 |
<?php echo LM_CONFIG_EDIT?> <?php echo $config_file?>
|
1194 |
</th></tr>
|
1195 |
</table>
|
1196 |
<?php
|
1197 |
-
$tabs
|
|
|
1198 |
?>
|
|
|
1199 |
|
1200 |
-
<div id="configtabinside">
|
1201 |
-
|
1202 |
-
<div>
|
1203 |
-
<h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS?></a></h3>
|
1204 |
-
<div><p>
|
1205 |
-
<table class='adminform'>
|
1206 |
-
|
1207 |
-
<tr>
|
1208 |
-
<td>
|
1209 |
-
<?php echo LM_CONFIG_UBPATH?>
|
1210 |
-
</td>
|
1211 |
-
<td>
|
1212 |
-
<input type=text size=100 name='backup_path' value='<?php echo $_CONFIG[backup_path]?>'>
|
1213 |
-
<br /><?php echo LM_CONFIG_UBPATH_SUB?>
|
1214 |
-
</td>
|
1215 |
-
</tr>
|
1216 |
-
|
1217 |
-
<tr>
|
1218 |
-
<td width='250'>
|
1219 |
-
<?php echo LM_CONFIG_BPATH?>
|
1220 |
-
</td>
|
1221 |
-
<td>
|
1222 |
-
<input type=text size=100 name='clonerPath' value='<?php echo $_CONFIG[clonerPath]?>'>
|
1223 |
-
<br /><?php echo LM_CONFIG_BPATH_SUB?>
|
1224 |
-
</td>
|
1225 |
-
</tr>
|
1226 |
-
|
1227 |
-
</table>
|
1228 |
-
</p></div>
|
1229 |
-
</div>
|
1230 |
-
|
1231 |
-
<div>
|
1232 |
-
<h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS_OPTIONS?></a></h3>
|
1233 |
-
<div><p>
|
1234 |
-
<table class='adminform'>
|
1235 |
-
|
1236 |
-
<tr>
|
1237 |
-
<td width='250'>
|
1238 |
-
<?php echo LM_CONFIG_MANUAL_BACKUP;?>
|
1239 |
-
</td>
|
1240 |
-
<td>
|
1241 |
-
<div id="radiog1">
|
1242 |
-
<label for="radiog11"><?php echo LM_YES?></label> <input id="radiog11" type=radio size=50 value=1 name='backup_refresh' <?php if($_CONFIG[backup_refresh]==1) echo 'checked';?>>
|
1243 |
-
<label for="radiog12"><?php echo LM_NO?></label> <input id="radiog12" type=radio size=50 value=0 name='backup_refresh' <?php if($_CONFIG[backup_refresh]==0) echo 'checked';?>>
|
1244 |
-
<br><small><?php echo LM_CONFIG_MANUAL_BACKUP_SUB?></small>
|
1245 |
-
</div>
|
1246 |
-
</td>
|
1247 |
-
</tr>
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
<tr>
|
1252 |
-
<td>
|
1253 |
-
<?php echo LM_CRON_DB_BACKUP?>
|
1254 |
-
</td>
|
1255 |
-
<td>
|
1256 |
-
<div id="radiog3">
|
1257 |
-
<label for="radiog31">Yes</label> <input id="radiog31" type=radio size=50 value=1 name='enable_db_backup' <?php if($_CONFIG[enable_db_backup]==1) echo 'checked';?>>
|
1258 |
-
<label for="radiog32">No</label> <input id="radiog32" type=radio size=50 value=0 name='enable_db_backup' <?php if($_CONFIG[enable_db_backup]==0) echo 'checked';?>>
|
1259 |
-
<br /><?php echo LM_CRON_DB_BACKUP_SUB?>
|
1260 |
-
</div>
|
1261 |
-
|
1262 |
-
</td>
|
1263 |
-
</tr>
|
1264 |
-
|
1265 |
-
<tr>
|
1266 |
-
<td>
|
1267 |
-
<?php echo LM_CONFIG_SYSTEM_MBACKUP?>
|
1268 |
-
</td>
|
1269 |
-
<td>
|
1270 |
-
<div id="radiog4">
|
1271 |
-
<label for="radiog41">Yes</label> <input id="radiog41" type=radio size=50 value=1 name='add_backups_dir' <?php if($_CONFIG[add_backups_dir]==1) echo 'checked';?>>
|
1272 |
-
<label for="radiog42">No</label> <input id="radiog42" type=radio size=50 value=0 name='add_backups_dir' <?php if($_CONFIG[add_backups_dir]==0) echo 'checked';?>>
|
1273 |
-
<br /><?php echo LM_CONFIG_SYSTEM_MBACKUP_SUB?>
|
1274 |
-
</td>
|
1275 |
-
</div>
|
1276 |
-
</tr>
|
1277 |
-
|
1278 |
-
</table>
|
1279 |
-
</p></div>
|
1280 |
-
</div>
|
1281 |
-
|
1282 |
-
<div>
|
1283 |
-
<h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS_SERVER?></a></h3>
|
1284 |
-
<div><p>
|
1285 |
-
<table class='adminform'>
|
1286 |
-
|
1287 |
-
<tr><td width='250'>
|
1288 |
-
<?php echo LM_CONFIG_MEM?>
|
1289 |
-
</td>
|
1290 |
-
<td align='left'>
|
1291 |
-
<table style="width:auto; margin-bottom: 10px;" cellpadding='0' cellspacing='2' border='1'>
|
1292 |
-
<tr bgcolor='#efefef'><td style="width:70px;">
|
1293 |
-
<label for="checktar"><?php echo LM_ACTIVE;?></label> <input type=checkbox id="checktar" value=1 name='mem' <?php if($_CONFIG[mem]==1) echo 'checked';?>>
|
1294 |
-
</td><td align='left'>
|
1295 |
-
|
1296 |
-
<table width='100%' cellpadding='0' cellspacing='0'>
|
1297 |
-
<tr><td>
|
1298 |
-
<?php echo LM_TAR_PATH;?> <br /><input size='50' type=text name=tarpath value='<?php echo $_CONFIG[tarpath]?>'><br />
|
1299 |
-
<?php echo LM_TAR_PATH_SUB;?>
|
1300 |
-
</td></tr>
|
1301 |
-
|
1302 |
-
</table>
|
1303 |
-
|
1304 |
-
|
1305 |
-
</td></tr>
|
1306 |
-
|
1307 |
-
<tr bgcolor='#dedede'><td>
|
1308 |
-
<label for="checkmysqldump"><?php echo LM_ACTIVE?></label> <input id="checkmysqldump" type=checkbox value=1 name='sql_mem' <?php if($_CONFIG[sql_mem]==1) echo 'checked';?>>
|
1309 |
-
</td><td align='left'>
|
1310 |
-
<?php echo LM_MYSQLDUMP_PATH;?> <br /><input type=text size='50' name='sqldump' value='<?php echo $_CONFIG[sqldump]?>'>
|
1311 |
-
|
1312 |
-
</td></tr>
|
1313 |
-
</table>
|
1314 |
-
|
1315 |
-
<?php echo LM_CONFIG_MEM_SUB?>
|
1316 |
-
|
1317 |
-
</td>
|
1318 |
-
</tr>
|
1319 |
-
</table>
|
1320 |
-
</p></div>
|
1321 |
-
</div>
|
1322 |
-
|
1323 |
-
<div>
|
1324 |
-
<h3><a href="#">Public Key Management</a></h3>
|
1325 |
-
<div><p>
|
1326 |
-
<table class='adminForm'>
|
1327 |
-
|
1328 |
-
<tr><td width="250">
|
1329 |
-
Public Key
|
1330 |
-
</td>
|
1331 |
-
<td>
|
1332 |
-
<input type-text size=50 name='license_code' value="<?php echo $_CONFIG[license_code]?>"/>
|
1333 |
-
<br />Use this code in the MultiSite XCloner Manager <a target='_blank' href='http://www.xcloner.com/'>XCloner.com Members area</a>
|
1334 |
-
<br />Leave it empty to disable it
|
1335 |
-
|
1336 |
-
</td>
|
1337 |
-
</tr>
|
1338 |
-
|
1339 |
-
</table>
|
1340 |
-
</p></div>
|
1341 |
-
</div>
|
1342 |
-
|
1343 |
-
</div>
|
1344 |
-
|
1345 |
-
<?php
|
1346 |
-
$tabs->endTab();
|
1347 |
-
$tabs->startTab(LM_TAB_MYSQL,"2");
|
1348 |
-
?>
|
1349 |
-
<div id="configtabinside">
|
1350 |
-
<div>
|
1351 |
-
<h3><a href="#"><?php echo LM_CONFIG_MYSQL?></a></h3>
|
1352 |
-
<div><p>
|
1353 |
-
|
1354 |
-
<table class='adminform'>
|
1355 |
-
|
1356 |
-
<tr>
|
1357 |
-
<td width='250'>
|
1358 |
-
<?php echo LM_CONFIG_MYSQLH?>
|
1359 |
-
</td>
|
1360 |
-
<td>
|
1361 |
-
<input type=text size=50 name='mysql_host' value='<?php echo $_CONFIG[mysql_host]?>'>
|
1362 |
-
<br /><?php echo LM_CONFIG_MYSQLH_SUB?>
|
1363 |
-
</td>
|
1364 |
-
</tr>
|
1365 |
-
|
1366 |
-
<tr>
|
1367 |
-
<td>
|
1368 |
-
<?php echo LM_CONFIG_MYSQLU?>
|
1369 |
-
</td>
|
1370 |
-
<td>
|
1371 |
-
<input type=text size=50 name='mysql_user' value='<?php echo $_CONFIG[mysql_user]?>'>
|
1372 |
-
<br /><?php echo LM_CONFIG_MYSQLU_SUB?>
|
1373 |
-
</td>
|
1374 |
-
</tr>
|
1375 |
-
|
1376 |
-
<tr>
|
1377 |
-
<td>
|
1378 |
-
<?php echo LM_CONFIG_MYSQLP?>
|
1379 |
-
</td>
|
1380 |
-
<td>
|
1381 |
-
<input type=text size=50 name='mysql_pass' value='<?php echo $_CONFIG[mysql_pass]?>'>
|
1382 |
-
<br /><?php echo LM_CONFIG_MYSQLP_SUB?>
|
1383 |
-
</td>
|
1384 |
-
</tr>
|
1385 |
-
|
1386 |
-
<tr>
|
1387 |
-
<td>
|
1388 |
-
<?php echo LM_CONFIG_MYSQLD?>
|
1389 |
-
</td>
|
1390 |
-
<td>
|
1391 |
-
<input type=text size=50 name='mysql_database' value='<?php echo $_CONFIG[mysql_database]?>'>
|
1392 |
-
<br /><?php echo LM_CONFIG_MYSQLD_SUB?>
|
1393 |
-
</td>
|
1394 |
-
</tr>
|
1395 |
-
|
1396 |
-
<tr>
|
1397 |
-
<td width='200'>
|
1398 |
-
<?php echo LM_CONFIG_SYSTEM_MDATABASES?>
|
1399 |
-
</td>
|
1400 |
-
<td>
|
1401 |
-
<div id="radiom">
|
1402 |
-
<label for="radiom1"><?php echo LM_YES?></label> <input id="radiom1" type=radio name='system_mdatabases' value='0' <?php if(abs($_CONFIG[system_mdatabases])==0) echo "checked";?>>
|
1403 |
-
<label for="radiom2"><?php echo LM_NO?></label> <input id="radiom2" type=radio name='system_mdatabases' value='1' <?php if(abs($_CONFIG[system_mdatabases])==1) echo "checked";?>>
|
1404 |
-
<br /> <?php echo LM_CONFIG_SYSTEM_MDATABASES_SUB?>
|
1405 |
-
</div>
|
1406 |
-
</td>
|
1407 |
-
</tr>
|
1408 |
-
|
1409 |
-
</table>
|
1410 |
-
</p></div>
|
1411 |
-
</div>
|
1412 |
-
</div>
|
1413 |
-
<?php
|
1414 |
-
$tabs->endTab();
|
1415 |
-
$tabs->startTab(LM_TAB_AUTH,"3");
|
1416 |
-
?>
|
1417 |
-
<div id="configtabinside">
|
1418 |
-
<div>
|
1419 |
-
<h3><a href="#"><?php echo LM_CONFIG_AUTH?></a></h3>
|
1420 |
-
<div><p>
|
1421 |
-
<table class='adminform'>
|
1422 |
-
<tr>
|
1423 |
-
<td width='250'>
|
1424 |
-
<?php echo LM_CONFIG_AUTH_USER?>
|
1425 |
-
</td>
|
1426 |
-
<td>
|
1427 |
-
<input type=text size=30 name='jcuser' value='<?php echo $_CONFIG[jcuser]?>'>
|
1428 |
-
<br /><?php echo LM_CONFIG_AUTH_USER_SUB?>
|
1429 |
-
</td>
|
1430 |
-
</tr>
|
1431 |
-
|
1432 |
-
<tr>
|
1433 |
-
<td>
|
1434 |
-
<?php echo LM_CONFIG_AUTH_PASS?>
|
1435 |
-
</td>
|
1436 |
-
<td>
|
1437 |
-
<input type=text size=30 name='jcpass' value=''> <?php if($_CONFIG['jcpass'] == md5('admin')) echo "<font color=red>please change the default password 'admin'</font>"?>
|
1438 |
-
<br /><?php echo LM_CONFIG_AUTH_PASS_SUB?>
|
1439 |
-
</td>
|
1440 |
-
</tr>
|
1441 |
-
</table>
|
1442 |
-
</p></div>
|
1443 |
-
</div>
|
1444 |
-
</div>
|
1445 |
-
<?php
|
1446 |
-
$tabs->endTab();
|
1447 |
-
$tabs->startTab(LM_TAB_SYSTEM,"4");
|
1448 |
-
?>
|
1449 |
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
<tr>
|
1456 |
-
<td width='250'>
|
1457 |
-
<?php echo LM_CONFIG_SYSTEM_LANG?>
|
1458 |
-
</td><td>
|
1459 |
-
<select name='select_lang'>
|
1460 |
-
<option value=''><?php echo LM_CONFIG_SYSTEM_LANG_DEFAULT;?></option>
|
1461 |
-
<?php
|
1462 |
-
foreach($lang_array as $value)
|
1463 |
-
if($_CONFIG['select_lang'] == $value)
|
1464 |
-
echo "<option value='$value' selected>$value</option>\n";
|
1465 |
-
else
|
1466 |
-
echo "<option value='$value'>$value</option>\n";
|
1467 |
-
?>
|
1468 |
-
</select>
|
1469 |
-
<br>
|
1470 |
-
<br /><?php echo LM_CONFIG_SYSTEM_LANG_SUB?>
|
1471 |
-
</td></tr>
|
1472 |
-
</table>
|
1473 |
-
</p></div>
|
1474 |
-
</div>
|
1475 |
-
<div>
|
1476 |
-
<h3><a href="#"> <?php echo LM_CONFIG_SYSTEM?></a></h3>
|
1477 |
-
<div><p>
|
1478 |
-
|
1479 |
-
<table class='adminform'>
|
1480 |
-
|
1481 |
-
<tr>
|
1482 |
-
<td width='250'>
|
1483 |
-
<?php echo LM_CONFIG_SYSTEM_FTP?>
|
1484 |
-
</td>
|
1485 |
-
<td>
|
1486 |
-
<div id="radioftp">
|
1487 |
-
<label for="radioftp1">Direct</label><input id="radioftp1" type=radio name='system_ftptransfer' value='0' <?php if(abs($_CONFIG[system_ftptransfer])==0) echo "checked";?>>
|
1488 |
-
<label for="radioftp2">Passive</label><input id="radioftp2" type=radio name='system_ftptransfer' value='1' <?php if(abs($_CONFIG[system_ftptransfer])==1) echo "checked";?>> <br>
|
1489 |
-
<br /><?php echo LM_CONFIG_SYSTEM_FTP_SUB?>
|
1490 |
-
</div>
|
1491 |
-
|
1492 |
-
</td></tr>
|
1493 |
-
<tr><td>
|
1494 |
-
<?php echo LM_FTP_TRANSFER_MORE?>
|
1495 |
-
</td><td>
|
1496 |
-
<div id="radioftps">
|
1497 |
-
<label for="radioftps1">Normal</label><input id="radioftps1" type=radio size=50 value=0 name='secure_ftp' <?php if($_CONFIG[secure_ftp]==0) echo 'checked';?>>
|
1498 |
-
<label for="radioftps2">Secure(SFTP)</label><input id="radioftps2" type=radio size=50 value=1 name='secure_ftp' <?php if($_CONFIG[secure_ftp]==1) echo 'checked';?>>
|
1499 |
-
</td>
|
1500 |
-
</tr>
|
1501 |
-
|
1502 |
-
</table>
|
1503 |
-
</p></div>
|
1504 |
-
</div>
|
1505 |
-
<div>
|
1506 |
-
<h3><a href="#"> <?php echo LM_CONFIG_MANUAL?></a></h3>
|
1507 |
-
<div><p>
|
1508 |
-
|
1509 |
-
<script>
|
1510 |
-
$(function() {
|
1511 |
-
$( "#slider" ).slider({
|
1512 |
-
value:parseInt(<?php echo $_CONFIG[backup_refresh_number];?>),
|
1513 |
-
min: 10,
|
1514 |
-
max: 1000,
|
1515 |
-
step: 10,
|
1516 |
-
slide: function( event, ui ) {
|
1517 |
-
$( "#backup_refresh_number" ).val( ui.value );
|
1518 |
-
}
|
1519 |
-
});
|
1520 |
-
$( "#backup_refresh_number" ).val( $( "#slider" ).slider( "value" ) );
|
1521 |
-
});
|
1522 |
-
$(function() {
|
1523 |
-
$( "#sliderRPS" ).slider({
|
1524 |
-
value:parseInt(<?php echo $_CONFIG[recordsPerSession];?>),
|
1525 |
-
min: 100,
|
1526 |
-
max: 100000,
|
1527 |
-
step: 100,
|
1528 |
-
slide: function( event, ui ) {
|
1529 |
-
$( "#recordsPerSession" ).val( ui.value );
|
1530 |
-
}
|
1531 |
-
});
|
1532 |
-
$( "#recordsPerSession" ).val( $( "#sliderRPS" ).slider( "value" ) );
|
1533 |
-
});
|
1534 |
-
$(function() {
|
1535 |
-
$( "#sliderEFZ" ).slider({
|
1536 |
-
value:parseInt(<?php echo $_CONFIG[excludeFilesSize];?>),
|
1537 |
-
min: -1,
|
1538 |
-
max: 10240,
|
1539 |
-
step: 1,
|
1540 |
-
slide: function( event, ui ) {
|
1541 |
-
$( "#excludeFilesSize" ).val( ui.value );
|
1542 |
-
}
|
1543 |
-
});
|
1544 |
-
$( "#excludeFilesSize" ).val( $( "#sliderEFZ" ).slider( "value" ) );
|
1545 |
-
});
|
1546 |
-
|
1547 |
-
$(function() {
|
1548 |
-
$( "#sliderSBS" ).slider({
|
1549 |
-
value:parseInt(<?php echo $_CONFIG[splitBackupSize];?>),
|
1550 |
-
min: -1,
|
1551 |
-
max: 10000,
|
1552 |
-
step: 1,
|
1553 |
-
slide: function( event, ui ) {
|
1554 |
-
$( "#splitBackupSize" ).val( ui.value );
|
1555 |
-
}
|
1556 |
-
});
|
1557 |
-
$( "#splitBackupSize" ).val( $( "#sliderSBS" ).slider( "value" ) );
|
1558 |
-
});
|
1559 |
-
</script>
|
1560 |
-
|
1561 |
-
<table class='adminform'>
|
1562 |
-
|
1563 |
-
<tr><td width="250">
|
1564 |
-
<?php echo LM_CONFIG_MANUAL_FILES;?>
|
1565 |
-
</td><td>
|
1566 |
-
<div class="sliderContainer">
|
1567 |
-
<div id="slider" style="width:500px;padding:5px 0 0 0;float:left"></div>
|
1568 |
-
<label for="backup_refresh_number"></label>
|
1569 |
-
<input id="backup_refresh_number" type=text size=10 name='backup_refresh_number' value=<?php echo $_CONFIG[backup_refresh_number];?>>
|
1570 |
-
</div>
|
1571 |
-
</td></tr>
|
1572 |
-
|
1573 |
-
<tr><td width="250">
|
1574 |
-
<?php echo LM_CONFIG_DB_RECORDS;?>
|
1575 |
-
</td><td>
|
1576 |
-
<div class="sliderContainer">
|
1577 |
-
<div id="sliderRPS" style="width:500px;padding:5px 0 0 0;float:left;"></div>
|
1578 |
-
<label for="recordsPerSession"></label>
|
1579 |
-
<input id="recordsPerSession" type=text size=10 name='recordsPerSession' value=<?php echo $_CONFIG[recordsPerSession];?>>
|
1580 |
-
</div>
|
1581 |
-
</td></tr>
|
1582 |
-
|
1583 |
-
<tr><td width="250">
|
1584 |
-
<?php echo LM_CONFIG_EXCLUDE_FILES_SIZE;?>
|
1585 |
-
</td><td>
|
1586 |
-
<div class="sliderContainer">
|
1587 |
-
<div id="sliderEFZ" style="width:500px;padding:5px 0 0 0;float:left"></div>
|
1588 |
-
<label for="excludeFilesSize"></label>
|
1589 |
-
<input id="excludeFilesSize" type=text size=10 name='excludeFilesSize' value=<?php echo $_CONFIG[excludeFilesSize];?>> MB
|
1590 |
-
</div>
|
1591 |
-
</td></tr>
|
1592 |
-
|
1593 |
-
<tr><td width="250">
|
1594 |
-
<?php echo LM_CONFIG_SPLIT_BACKUP_SIZE;?>
|
1595 |
-
</td><td>
|
1596 |
-
<div class="sliderContainer">
|
1597 |
-
<div id="sliderSBS" style="width:500px;padding:5px 0 0 0;float:left;"></div>
|
1598 |
-
<label for="splitBackupSize"></label>
|
1599 |
-
<input id="splitBackupSize" type=text size=10 name='splitBackupSize' value=<?php echo $_CONFIG[splitBackupSize];?>> MB
|
1600 |
-
</div>
|
1601 |
-
|
1602 |
-
</td></tr>
|
1603 |
-
|
1604 |
-
<tr><td>
|
1605 |
-
<?php echo LM_CONFIG_MANUAL_REFRESH;?>
|
1606 |
-
</td><td>
|
1607 |
-
<input type=text size=20 name='refresh_time' value=<?php echo $_CONFIG[refresh_time];?>> miliseconds
|
1608 |
-
|
1609 |
-
</td></tr>
|
1610 |
-
|
1611 |
-
<tr>
|
1612 |
-
<td>
|
1613 |
-
<?php echo LM_CRON_COMPRESS?>
|
1614 |
-
</td>
|
1615 |
-
<td>
|
1616 |
-
<div id="radiog2">
|
1617 |
-
<label for="radiog21"><?php echo LM_YES?></label> <input id="radiog21" type=radio size=50 value=1 name='backup_compress' <?php if($_CONFIG[backup_compress]==1) echo 'checked';?>>
|
1618 |
-
<label for="radiog22"><?php echo LM_NO?></label> <input id="radiog22" type=radio size=50 value=0 name='backup_compress' <?php if($_CONFIG[backup_compress]==0) echo 'checked';?>>
|
1619 |
-
<br /> <small>Note: this option might break your backup process if the Manual backup option is also enabled</small>
|
1620 |
-
</div>
|
1621 |
-
</td>
|
1622 |
-
</tr>
|
1623 |
-
|
1624 |
-
<tr><td>
|
1625 |
-
<?php echo LM_REFRESH_MODE?>
|
1626 |
-
</td><td>
|
1627 |
-
<div id="radiorefresh">
|
1628 |
-
<label for="radiorefresh1">Normal</label> <input id="radiorefresh1" type=radio size=50 value=0 name='refresh_mode' <?php if($_CONFIG[refresh_mode]==0) echo 'checked';?>>
|
1629 |
-
<label for="radiorefresh2">AJAX</label> <input id="radiorefresh2" type=radio size=50 value=1 name='refresh_mode' <?php if($_CONFIG[refresh_mode]==1) echo 'checked';?>>
|
1630 |
-
</div>
|
1631 |
-
</td></tr>
|
1632 |
-
|
1633 |
-
<tr><td>
|
1634 |
-
<?php echo LM_DEBUG_MODE?>
|
1635 |
-
</td><td>
|
1636 |
-
<div id="radiodebug">
|
1637 |
-
<label for="radiodebug1">No</label> <input id="radiodebug1" type=radio size=50 value=0 name='debug' <?php if($_CONFIG[debug]==0) echo 'checked';?>>
|
1638 |
-
<label for="radiodebug2">Yes</label> <input id="radiodebug2" type=radio size=50 value=1 name='debug' <?php if($_CONFIG[debug]==1) echo 'checked';?>>
|
1639 |
-
</td></tr>
|
1640 |
-
</table>
|
1641 |
-
|
1642 |
-
</p></div>
|
1643 |
-
</div>
|
1644 |
|
1645 |
-
|
1646 |
-
|
1647 |
-
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
1654 |
-
<div><p>
|
1655 |
-
<table class='adminform'>
|
1656 |
-
|
1657 |
-
<tr>
|
1658 |
-
<td width='250'>
|
1659 |
-
<?php echo LM_CRON_MCRON?>
|
1660 |
-
</td>
|
1661 |
-
<td>
|
1662 |
-
<input type=text size=30 value="<?php echo $_CONFIG[cron_save_as]?>" name='cron_save_as' >.php <br />
|
1663 |
-
<?php echo LM_CRON_MCRON_SUB?>
|
1664 |
-
</td>
|
1665 |
-
</tr>
|
1666 |
-
|
1667 |
-
<tr>
|
1668 |
-
<td>
|
1669 |
-
<?php echo LM_CRON_MCRON_AVAIL?>
|
1670 |
-
</td>
|
1671 |
-
<td>
|
1672 |
-
<?php
|
1673 |
-
|
1674 |
-
if ($handle = @opendir($_CONFIG['multiple_config_dir'])) {
|
1675 |
-
|
1676 |
-
while (false !== ($file = readdir($handle))) {
|
1677 |
-
if( ($file!=".") && ($file!="..") &&($file!="") && (strstr($file, '.php'))){
|
1678 |
-
$fcron = "cloner.cron.php?config=$file";
|
1679 |
-
|
1680 |
-
echo "<b>$fcron</b>";
|
1681 |
-
|
1682 |
-
echo " - <a href='$fcron' target='_blank'>execute cron</a>";
|
1683 |
-
|
1684 |
-
echo " | <a href='index2.php?option=com_cloner&task=cron_delete&fconfig=$file'>delete config</a>";
|
1685 |
-
|
1686 |
-
echo "\n<br />";
|
1687 |
-
}
|
1688 |
-
}
|
1689 |
-
|
1690 |
-
closedir($handle);
|
1691 |
-
}
|
1692 |
-
?>
|
1693 |
-
</td>
|
1694 |
-
</tr>
|
1695 |
-
</table>
|
1696 |
-
</p></div>
|
1697 |
-
</div>
|
1698 |
-
|
1699 |
-
<div>
|
1700 |
-
<h3><a href="#"> <?php echo LM_CRON_SETTINGS?></a></h3>
|
1701 |
-
<div><p>
|
1702 |
-
<table class='adminform'>
|
1703 |
-
|
1704 |
-
<tr>
|
1705 |
-
<td width='250'>
|
1706 |
-
<?php echo LM_CRON_SEMAIL?>
|
1707 |
-
</td>
|
1708 |
-
<td>
|
1709 |
-
<input type=text size=30 value="<?php echo $_CONFIG[cron_logemail]?>" name='cron_logemail' > <br />
|
1710 |
-
<?php echo LM_CRON_SEMAIL_SUB?>
|
1711 |
-
</td>
|
1712 |
-
</tr>
|
1713 |
-
|
1714 |
-
<tr>
|
1715 |
-
<td>
|
1716 |
-
<?php echo LM_CRON_MODE?>
|
1717 |
-
</td>
|
1718 |
-
<td>
|
1719 |
-
|
1720 |
-
<div id="radio">
|
1721 |
-
<input id="radio1" type=radio size=50 value=0 name='cron_send' <?php if($_CONFIG[cron_send]==0) echo 'checked';?>>
|
1722 |
-
<label for="radio1"><?php echo LM_CONFIG_CRON_LOCAL?></label>
|
1723 |
-
<input id="radio2" type=radio size=50 value=1 name='cron_send' <?php if($_CONFIG[cron_send]==1) echo 'checked';?>>
|
1724 |
-
<label for="radio2"><?php echo LM_CONFIG_CRON_REMOTE?></label>
|
1725 |
-
<input id="radio3" type=radio size=50 value=2 name='cron_send' <?php if($_CONFIG[cron_send]==2) echo 'checked';?>>
|
1726 |
-
<label for="radio3"><?php echo LM_CONFIG_CRON_EMAIL?></label>
|
1727 |
-
</div>
|
1728 |
-
<?php echo LM_CRON_MODE_INFO?>
|
1729 |
-
</td>
|
1730 |
-
</tr>
|
1731 |
-
|
1732 |
-
|
1733 |
-
<tr>
|
1734 |
-
<td>
|
1735 |
-
<?php echo LM_CRON_TYPE?>
|
1736 |
-
</td>
|
1737 |
-
<td>
|
1738 |
-
<div id="radiob">
|
1739 |
-
<input id="radiob1" type=radio size=50 value=0 name='cron_btype' <?php if($_CONFIG[cron_btype]==0) echo 'checked';?>>
|
1740 |
-
<label for="radiob1"><?php echo LM_CONFIG_CRON_FULL?></label>
|
1741 |
-
<input id="radiob2" type=radio size=50 value=1 name='cron_btype' <?php if($_CONFIG[cron_btype]==1) echo 'checked';?>>
|
1742 |
-
<label for="radiob2"><?php echo LM_CONFIG_CRON_FILES?></label>
|
1743 |
-
<input id="radiob3" type=radio size=50 value=2 name='cron_btype' <?php if($_CONFIG[cron_btype]==2) echo 'checked';?>>
|
1744 |
-
<label for="radiob3"><?php echo LM_CONFIG_CRON_DATABASE?></label>
|
1745 |
-
<?php echo LM_CRON_TYPE_INFO?>
|
1746 |
-
</div>
|
1747 |
-
</td>
|
1748 |
-
</tr>
|
1749 |
-
|
1750 |
-
<tr>
|
1751 |
-
<td>
|
1752 |
-
<?php echo LM_CRON_BNAME?>
|
1753 |
-
</td>
|
1754 |
-
<td>
|
1755 |
-
<input type=text size=50 value="<?php echo $_CONFIG[cron_bname]?>" name='cron_bname' > <br />
|
1756 |
-
<?php echo LM_CRON_BNAME_SUB?>
|
1757 |
-
</td>
|
1758 |
-
</tr>
|
1759 |
-
|
1760 |
-
|
1761 |
-
<tr>
|
1762 |
-
<td>
|
1763 |
-
<?php echo LM_CRON_IP?>
|
1764 |
-
</td>
|
1765 |
-
<td>
|
1766 |
-
<textarea type=text size=50 name='cron_ip' cols='30' rows='5'><?php echo $_CONFIG[cron_ip]?></textarea> <br />
|
1767 |
-
<?php echo LM_CRON_IP_SUB?>
|
1768 |
-
</td>
|
1769 |
-
</tr>
|
1770 |
-
</table>
|
1771 |
-
</p></div>
|
1772 |
-
</div>
|
1773 |
-
|
1774 |
-
<div>
|
1775 |
-
<h3><a href="#"> <?php echo LM_CRON_FTP_DETAILS?></a></h3>
|
1776 |
-
<div><p>
|
1777 |
-
<table class='adminform'>
|
1778 |
-
|
1779 |
-
<tr>
|
1780 |
-
<td width='250'>
|
1781 |
-
<?php echo LM_CRON_FTP_SERVER?>
|
1782 |
-
</td>
|
1783 |
-
<td>
|
1784 |
-
<input type=text size=50 name='cron_ftp_server' value='<?php echo $_CONFIG[cron_ftp_server]?>'>
|
1785 |
-
</td>
|
1786 |
-
</tr>
|
1787 |
-
<tr>
|
1788 |
-
<td>
|
1789 |
-
<?php echo LM_CRON_FTP_USER?>
|
1790 |
-
</td>
|
1791 |
-
<td>
|
1792 |
-
<input type=text size=50 name='cron_ftp_user' value='<?php echo $_CONFIG[cron_ftp_user]?>'>
|
1793 |
-
</td>
|
1794 |
-
</tr>
|
1795 |
-
<tr>
|
1796 |
-
<td>
|
1797 |
-
<?php echo LM_CRON_FTP_PASS?>
|
1798 |
-
</td>
|
1799 |
-
<td>
|
1800 |
-
<input type=text size=50 name='cron_ftp_pass' value='<?php echo $_CONFIG[cron_ftp_pass]?>'>
|
1801 |
-
</td>
|
1802 |
-
</tr>
|
1803 |
-
<tr>
|
1804 |
-
<td>
|
1805 |
-
<?php echo LM_CRON_FTP_PATH?>
|
1806 |
-
</td>
|
1807 |
-
<td>
|
1808 |
-
<input type=text size=50 name='cron_ftp_path' value='<?php echo $_CONFIG[cron_ftp_path]?>'>
|
1809 |
-
</td>
|
1810 |
-
</tr>
|
1811 |
-
<tr>
|
1812 |
-
<td>
|
1813 |
-
<!--<?php echo LM_CRON_FTP_DELB?>-->
|
1814 |
-
</td>
|
1815 |
-
<td>
|
1816 |
-
<input id="cron_ftp_delb" type=checkbox name='cron_ftp_delb' <?php if($_CONFIG[cron_ftp_delb]==1) echo "checked";?> value='1'>
|
1817 |
-
<label for="cron_ftp_delb"><?php echo LM_CRON_FTP_DELB?></label>
|
1818 |
-
</td>
|
1819 |
-
</tr>
|
1820 |
-
</table>
|
1821 |
-
</p></div>
|
1822 |
-
</div>
|
1823 |
-
|
1824 |
-
<div>
|
1825 |
-
<h3><a href="#"> <?php echo LM_AMAZON_S3?></a></h3>
|
1826 |
-
<div><p>
|
1827 |
-
<table class='adminform'>
|
1828 |
-
|
1829 |
-
<tr>
|
1830 |
-
<td width='250'>
|
1831 |
-
<?php #echo LM_AMAZON_S3_ACTIVATE?>
|
1832 |
-
</td>
|
1833 |
-
<td>
|
1834 |
-
<label for="cron_amazon_active"><?php echo LM_AMAZON_S3_ACTIVATE?></label>
|
1835 |
-
<input id="cron_amazon_active" type=checkbox name='cron_amazon_active' <?php if($_CONFIG[cron_amazon_active]==1) echo "checked";?> value='1'>
|
1836 |
-
|
1837 |
-
<label for="cron_amazon_ssl"><?php echo LM_AMAZON_S3_SSL?></label>
|
1838 |
-
<input id="cron_amazon_ssl" type=checkbox name='cron_amazon_ssl' <?php if($_CONFIG[cron_amazon_ssl]==1) echo "checked";?> value='1'>
|
1839 |
-
</td>
|
1840 |
-
</tr>
|
1841 |
|
1842 |
-
|
1843 |
-
|
1844 |
-
|
1845 |
-
|
1846 |
-
|
1847 |
-
|
1848 |
-
|
1849 |
-
|
|
|
1850 |
|
1851 |
-
<tr>
|
1852 |
-
<td>
|
1853 |
-
<?php echo LM_AMAZON_S3_AWSSECRETKEY;?>
|
1854 |
-
</td>
|
1855 |
-
<td>
|
1856 |
-
<input type=text size=50 name='cron_amazon_awsSecretKey' value="<?php echo $_CONFIG['cron_amazon_awsSecretKey'];?>">
|
1857 |
-
</td>
|
1858 |
-
</tr>
|
1859 |
-
|
1860 |
-
<tr>
|
1861 |
-
<td width='200'>
|
1862 |
-
<?php echo LM_AMAZON_S3_BUCKET;?>
|
1863 |
-
</td>
|
1864 |
-
<td>
|
1865 |
-
<input type=text size=50 name='cron_amazon_bucket' value="<?php echo $_CONFIG['cron_amazon_bucket'];?>">
|
1866 |
-
</td>
|
1867 |
-
</tr>
|
1868 |
|
1869 |
-
|
1870 |
-
|
1871 |
-
|
1872 |
-
|
1873 |
-
|
1874 |
-
<input type=text size=50 name='cron_amazon_dirname' value="<?php echo $_CONFIG['cron_amazon_dirname'];?>">
|
1875 |
-
</td>
|
1876 |
-
</tr>
|
1877 |
-
</tr>
|
1878 |
-
</table>
|
1879 |
-
</p></div>
|
1880 |
-
</div>
|
1881 |
-
|
1882 |
-
<div>
|
1883 |
-
<h3><a href="#"> <?php echo LM_CRON_EMAIL_DETAILS?></a></h3>
|
1884 |
-
<div><p>
|
1885 |
-
<table class='adminform'>
|
1886 |
-
|
1887 |
-
<tr>
|
1888 |
-
<td width="250">
|
1889 |
-
<?php echo LM_CRON_EMAIL_ACCOUNT?>
|
1890 |
-
</td>
|
1891 |
-
<td>
|
1892 |
-
<input type=text size=50 name='cron_email_address' value='<?php echo $_CONFIG[cron_email_address]?>'>
|
1893 |
-
</td>
|
1894 |
-
</tr>
|
1895 |
-
</table>
|
1896 |
-
</p></div>
|
1897 |
-
</div>
|
1898 |
-
|
1899 |
-
<div>
|
1900 |
-
<h3><a href="#"> <?php echo LM_CRON_MYSQL_DETAILS?></a></h3>
|
1901 |
-
<div><p>
|
1902 |
-
<table class='adminform'>
|
1903 |
-
|
1904 |
-
<tr bgcolor='#ffffff'>
|
1905 |
-
<td width='250'>
|
1906 |
-
<?php #echo LM_CRON_MYSQL_DROP?>
|
1907 |
-
</td>
|
1908 |
-
<td>
|
1909 |
-
<label for="cron_sql_drop"><?php echo LM_CRON_MYSQL_DROP?></label>
|
1910 |
-
<input id="cron_sql_drop" type=checkbox name='cron_sql_drop' value='1' <?php if($_CONFIG[cron_sql_drop]) echo "checked";?> >
|
1911 |
-
</td>
|
1912 |
-
</tr>
|
1913 |
-
|
1914 |
-
<?php
|
1915 |
-
if((abs($_CONFIG[system_mdatabases])==0) && ($_CONFIG[enable_db_backup]==1)){
|
1916 |
-
?>
|
1917 |
-
<tr><td valign='top'>
|
1918 |
-
<?php echo LM_DATABASE_INCLUDE_DATABASES?>
|
1919 |
-
</td><td>
|
1920 |
-
<select name='databases_incl[]' MULTIPLE SIZE=5>
|
1921 |
-
<?php
|
1922 |
-
|
1923 |
-
$curent_dbs = explode(",", $_CONFIG['databases_incl_list']);
|
1924 |
-
|
1925 |
-
$query = @mysql_query("SHOW databases");
|
1926 |
-
while($row = @mysql_fetch_array($query)){
|
1927 |
-
|
1928 |
-
$table = $row[0];
|
1929 |
-
|
1930 |
-
if($table != $_CONFIG['mysql_database'])
|
1931 |
-
|
1932 |
-
if(in_array($table, $curent_dbs)){
|
1933 |
-
|
1934 |
-
echo "<option value='".$table."' selected>$table</option>";
|
1935 |
-
|
1936 |
-
}else{
|
1937 |
-
|
1938 |
-
echo "<option value='".$table."'>$table</option>";
|
1939 |
|
1940 |
-
|
1941 |
-
|
1942 |
-
|
1943 |
-
|
1944 |
-
|
1945 |
-
|
1946 |
-
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
</p></div>
|
1951 |
-
</div>
|
1952 |
-
|
1953 |
-
<div>
|
1954 |
-
<h3><a href="#"> <?php echo LM_CRON_DELETE_FILES?></a></h3>
|
1955 |
-
<div><p>
|
1956 |
-
|
1957 |
-
<script>
|
1958 |
-
$(function() {
|
1959 |
-
$( "#slider2" ).slider({
|
1960 |
-
value:parseInt(<?php echo (int)$_CONFIG[cron_file_delete];?>),
|
1961 |
-
min: 0,
|
1962 |
-
max: 100,
|
1963 |
-
step: 1,
|
1964 |
-
slide: function( event, ui ) {
|
1965 |
-
$( "#cron_file_delete" ).val( ui.value );
|
1966 |
-
}
|
1967 |
-
});
|
1968 |
-
$( "#cron_file_delete" ).val( $( "#slider2" ).slider( "value" ) );
|
1969 |
-
});
|
1970 |
-
</script>
|
1971 |
-
|
1972 |
-
<table class='adminform'>
|
1973 |
-
|
1974 |
-
<tr>
|
1975 |
-
<td width='250'>
|
1976 |
-
<?php #echo LM_CRON_DELETE_FILES_SUB_ACTIVE?>
|
1977 |
-
</td>
|
1978 |
-
<td>
|
1979 |
-
<label for="cron_file_delete_act"><?php echo LM_CRON_DELETE_FILES_SUB_ACTIVE?></label>
|
1980 |
-
<input id="cron_file_delete_act" type=checkbox name='cron_file_delete_act' <?php if ($_CONFIG['cron_file_delete_act'] == 1) echo 'checked';?> value='1'>
|
1981 |
-
</td>
|
1982 |
-
</tr>
|
1983 |
-
<tr>
|
1984 |
-
<td>
|
1985 |
-
<?php echo LM_CRON_DELETE_FILES_SUB?>
|
1986 |
-
</td>
|
1987 |
-
<td>
|
1988 |
-
<div id="slider2" style="width:300px;padding-top:5px;"></div>
|
1989 |
-
<br /><label for="cron_file_delete"></label>
|
1990 |
-
<input id="cron_file_delete" size=5 name='cron_file_delete' value='<?php echo $_CONFIG[cron_file_delete]?>'> days:
|
1991 |
-
</td>
|
1992 |
-
</tr>
|
1993 |
-
</table>
|
1994 |
-
|
1995 |
-
<table class='adminform'>
|
1996 |
-
<tr>
|
1997 |
-
<th colspan='2'>
|
1998 |
-
<?php echo LM_CRON_EXCLUDE?>
|
1999 |
-
</th>
|
2000 |
-
</tr>
|
2001 |
-
</tr>
|
2002 |
-
<tr>
|
2003 |
-
<td width='250'>
|
2004 |
-
<?php echo LM_CRON_EXCLUDE_DIR?>
|
2005 |
-
</td>
|
2006 |
-
<td>
|
2007 |
-
<textarea cols=50 rows=5 name='cron_exclude'><?php echo $_CONFIG[cron_exclude]?></textarea>
|
2008 |
-
</td>
|
2009 |
-
</tr>
|
2010 |
-
|
2011 |
-
</table>
|
2012 |
-
</p></div>
|
2013 |
-
</div>
|
2014 |
-
|
2015 |
-
</div>
|
2016 |
-
<?php
|
2017 |
-
$tabs->endTab();
|
2018 |
-
$tabs->startTab(LM_TAB_INFO,"6");
|
2019 |
-
?>
|
2020 |
|
2021 |
-
|
2022 |
-
|
2023 |
-
|
2024 |
-
|
2025 |
-
|
2026 |
-
|
2027 |
-
|
2028 |
-
|
2029 |
-
|
2030 |
-
|
2031 |
-
</td>
|
2032 |
-
<td>
|
2033 |
-
<b><?php
|
2034 |
-
$version = phpversion();
|
2035 |
-
$ver = str_replace(".", "", $version);
|
2036 |
-
$val = (version_compare(PHP_VERSION, '5.2.3') < 0)? $version: "Off";
|
2037 |
-
echo HTML_cloner::get_color($version, $val);
|
2038 |
-
?></b>
|
2039 |
-
<br />
|
2040 |
-
<?php echo LM_CONFIG_INFO_VERSION?>
|
2041 |
-
</td>
|
2042 |
-
</tr>
|
2043 |
-
|
2044 |
-
<tr>
|
2045 |
-
<td>
|
2046 |
-
<?php echo LM_CONFIG_INFO_T_SAFEMODE?>
|
2047 |
-
</td>
|
2048 |
-
<td>
|
2049 |
-
<b><?php $val = (ini_get('safe_mode') != "")? ini_get('safe_mode'):"Off";
|
2050 |
-
echo HTML_cloner::get_color($val, 'On');
|
2051 |
-
?></b>
|
2052 |
-
<br />
|
2053 |
-
<?php echo LM_CONFIG_INFO_SAFEMODE?>
|
2054 |
-
</td>
|
2055 |
-
</tr>
|
2056 |
-
|
2057 |
-
<tr>
|
2058 |
-
<td>
|
2059 |
-
<?php echo LM_CONFIG_INFO_T_MTIME?>
|
2060 |
-
</td>
|
2061 |
-
<td>
|
2062 |
-
<b><?php echo (ini_get('max_execution_time') != "")? ini_get('max_execution_time'):"no value";
|
2063 |
-
|
2064 |
-
?></b>
|
2065 |
-
<br />
|
2066 |
-
<?php echo LM_CONFIG_INFO_TIME?>
|
2067 |
-
</td>
|
2068 |
-
</tr>
|
2069 |
-
|
2070 |
-
<tr>
|
2071 |
-
<td>
|
2072 |
-
<?php echo LM_CONFIG_INFO_T_MEML?>
|
2073 |
-
</td>
|
2074 |
-
<td>
|
2075 |
-
<b><?php echo (ini_get('memory_limit') != "")? ini_get('memory_limit'):"no value";?> </b>
|
2076 |
-
<br />
|
2077 |
-
<?php echo LM_CONFIG_INFO_MEMORY?>
|
2078 |
-
</td>
|
2079 |
-
</tr>
|
2080 |
-
|
2081 |
-
<tr>
|
2082 |
-
<td>
|
2083 |
-
<?php echo LM_CONFIG_INFO_T_BDIR?>
|
2084 |
-
</td>
|
2085 |
-
<td>
|
2086 |
-
<b><?php $val = (ini_get('open_basedir') != "")? ini_get('open_basedir'):"no value";
|
2087 |
-
echo HTML_cloner::get_color($val, '/');
|
2088 |
-
?> </b>
|
2089 |
-
<br />
|
2090 |
-
<?php echo LM_CONFIG_INFO_BASEDIR?>
|
2091 |
-
</td>
|
2092 |
-
</tr>
|
2093 |
-
|
2094 |
-
<tr>
|
2095 |
-
<td>
|
2096 |
-
<?php echo LM_CONFIG_INFO_T_EXEC?>
|
2097 |
-
</td>
|
2098 |
-
<td>
|
2099 |
-
<b><?php
|
2100 |
-
|
2101 |
-
$out = "";
|
2102 |
-
if(function_exists("exec")){
|
2103 |
-
|
2104 |
-
$out = @exec("ls -al");
|
2105 |
-
}
|
2106 |
|
2107 |
-
|
2108 |
-
|
2109 |
-
|
2110 |
-
|
2111 |
-
|
2112 |
-
|
2113 |
-
|
2114 |
-
|
2115 |
-
|
2116 |
-
|
2117 |
-
|
2118 |
-
<h3><a href="#"><?php echo LM_CONFIG_INFO_PATHS?></a></h3>
|
2119 |
-
<div><p>
|
2120 |
-
<table class='adminform'>
|
2121 |
-
|
2122 |
-
<tr>
|
2123 |
-
<td width='250'>
|
2124 |
-
<?php echo LM_CONFIG_INFO_ROOT_BPATH_TMP?>
|
2125 |
-
</td>
|
2126 |
-
<td>
|
2127 |
-
<b><?php $tmp_dir = realpath($_CONFIG['backup_path']."/administrator/backups");
|
2128 |
-
echo (@is_writeable( $tmp_dir ))? $tmp_dir . " is <font color=green>writeable</font>":$tmp_dir. " <font color=red>incorrect or unreadable</font>";?></b>
|
2129 |
-
<br />
|
2130 |
-
<?php echo LM_CONFIG_INFO_ROOT_PATH_TMP_SUB?>
|
2131 |
-
</td>
|
2132 |
-
</tr>
|
2133 |
-
|
2134 |
-
<tr>
|
2135 |
-
<td>
|
2136 |
-
<?php echo LM_CONFIG_INFO_ROOT_BPATH?>
|
2137 |
-
</td>
|
2138 |
-
<td>
|
2139 |
-
<b><?php echo (@is_readable($_CONFIG['backup_path']) )? $_CONFIG['backup_path'] . " is <font color=green>readable</font>":$_CONFIG['backup_path']. " <font color=red>incorrect or unreadable</font>";?></b>
|
2140 |
-
<br />
|
2141 |
-
<?php echo LM_CONFIG_INFO_ROOT_PATH_SUB?>
|
2142 |
-
</td>
|
2143 |
-
</tr>
|
2144 |
-
|
2145 |
-
|
2146 |
-
<tr>
|
2147 |
-
<td>
|
2148 |
-
<?php echo LM_CONFIG_INFO_T_BPATH?>
|
2149 |
-
</td>
|
2150 |
-
<td>
|
2151 |
-
<b><?php echo (@is_writeable($_CONFIG['clonerPath']) )? $_CONFIG['clonerPath'] . " is <font color=green>writeable</font>":$_CONFIG['clonerPath']. " <font color=red>unwriteable</font>";?></b>
|
2152 |
-
<br />
|
2153 |
-
<?php echo LM_CONFIG_INFO_BPATH?>
|
2154 |
-
</td>
|
2155 |
-
</tr>
|
2156 |
-
|
2157 |
-
|
2158 |
-
<tr>
|
2159 |
-
<td>
|
2160 |
-
<?php echo LM_CONFIG_INFO_T_TAR?>
|
2161 |
-
</td>
|
2162 |
-
<td>
|
2163 |
-
<b><?php
|
2164 |
-
if(function_exists('exec')){
|
2165 |
-
$info_tar_path = explode(" ", @exec("whereis tar"));
|
2166 |
-
}
|
2167 |
-
echo ($info_tar_path['1'] != "")? $info_tar_path['1']:"unable to determine";
|
2168 |
-
?> </b>
|
2169 |
-
<br />
|
2170 |
-
<?php echo LM_CONFIG_INFO_TAR?>
|
2171 |
-
</td>
|
2172 |
-
</tr>
|
2173 |
-
|
2174 |
-
|
2175 |
-
<tr>
|
2176 |
-
<td>
|
2177 |
-
<?php echo LM_CONFIG_INFO_T_MSQL?>
|
2178 |
-
</td>
|
2179 |
-
<td>
|
2180 |
-
<b><?php
|
2181 |
-
if(function_exists('exec')){
|
2182 |
-
$info_msql_path = explode(" ", @exec("whereis mysqldump"));
|
2183 |
-
}
|
2184 |
-
echo ($info_msql_path['1'] != "")? $info_msql_path['1']:"unable to determine";
|
2185 |
-
?> </b>
|
2186 |
-
<br />
|
2187 |
-
<?php echo LM_CONFIG_INFO_MSQL?>
|
2188 |
-
</td>
|
2189 |
-
</tr>
|
2190 |
|
2191 |
-
|
2192 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2193 |
|
2194 |
-
|
|
|
|
|
|
|
|
|
2195 |
|
2196 |
-
<?php
|
2197 |
-
$tabs->endTab();
|
2198 |
-
$tabs->endPane();
|
2199 |
-
?>
|
2200 |
-
<input type="hidden" name="option" value="com_cloner" />
|
2201 |
-
<input type="hidden" name="task" value="config" />
|
2202 |
-
<input type="hidden" name='action' value='save'>
|
2203 |
-
</form>
|
2204 |
|
2205 |
-
|
2206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2207 |
|
2208 |
-
|
|
|
|
|
|
|
|
|
2209 |
|
2210 |
-
|
2211 |
-
echo "<span style='color:green'>$val</span>";
|
2212 |
-
else
|
2213 |
-
echo "<span style='color:red'>$val</span>";
|
2214 |
|
2215 |
-
|
2216 |
|
2217 |
-
|
2218 |
-
|
|
|
|
|
2219 |
|
2220 |
-
|
2221 |
-
|
2222 |
-
<script language="javascript" type="text/javascript">
|
2223 |
|
|
|
2224 |
|
2225 |
-
|
2226 |
-
|
2227 |
-
if (pressbutton == 'cancel') {
|
2228 |
-
submitform( pressbutton );
|
2229 |
-
return;
|
2230 |
-
}
|
2231 |
|
2232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2233 |
|
2234 |
-
}
|
2235 |
|
2236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2237 |
var form = document.adminForm;
|
2238 |
form.contact_id.value = id;
|
2239 |
submitform( 'contact' );
|
@@ -2321,48 +1877,23 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2321 |
<form action="index2.php" method="post" name="adminForm">
|
2322 |
<?php
|
2323 |
$tabs = new mosTabs(1);
|
2324 |
-
|
2325 |
-
|
2326 |
-
<script>
|
2327 |
-
$(function() {
|
2328 |
-
$( "#tabs" ).tabs().find( ".ui-tabs-nav" ).sortable({ axis: "x" });
|
2329 |
-
$( "#radio_dbbackup" ).buttonset();
|
2330 |
-
$( "#radio_dbbackup1" ).button( { icons: {primary:'ui-icon-bullet'} } );
|
2331 |
-
$( "#radio_dbbackup2" ).button( { icons: {primary:'ui-icon-bullet'} } );
|
2332 |
-
});
|
2333 |
-
</script>
|
2334 |
-
|
2335 |
-
|
2336 |
-
<ul>
|
2337 |
-
<?php
|
2338 |
-
if($_CONFIG['enable_db_backup']){
|
2339 |
-
?>
|
2340 |
-
<li><a href="#tabs-users-databse-options-tab"><?php echo LM_TAB_G_DATABASE;?></a></li>
|
2341 |
-
<?php }?>
|
2342 |
-
<li><a href="#tabs-users-files-options-tab"><?php echo LM_TAB_G_FILES;?></a></li>
|
2343 |
-
<li><a href="#tabs-users-comments-options-tab"><?php echo LM_TAB_G_COMMENTS;?></a></li>
|
2344 |
-
</ul>
|
2345 |
-
|
2346 |
-
<?php
|
2347 |
-
#$tabs->startPane("BGeneratePane");
|
2348 |
if($_CONFIG['enable_db_backup']){
|
2349 |
$tabs->startTab(LM_TAB_G_DATABASE,"users-databse-options-tab");
|
2350 |
?>
|
2351 |
|
2352 |
-
|
2353 |
<table class="adminform">
|
2354 |
-
|
2355 |
<th colspan=2>
|
2356 |
-
<b><?php
|
2357 |
</th>
|
2358 |
-
</tr
|
2359 |
<tr>
|
2360 |
-
<td>
|
2361 |
-
|
2362 |
-
|
2363 |
-
|
2364 |
-
<input id="radio_dbbackup2" type="checkbox" id="dbbackup_drop" name="dbbackup_drop" value="1" />
|
2365 |
-
</td>
|
2366 |
</tr>
|
2367 |
<tr>
|
2368 |
<td><?php echo "Mysql Compatibility"; ?>
|
@@ -2377,7 +1908,7 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2377 |
<?php echo LM_DATABASE_EXCLUDE_TABLES?>
|
2378 |
</th></tr>
|
2379 |
<tr><td>
|
2380 |
-
<?php echo LM_DATABASE_CURRENT?> <b><?php echo $
|
2381 |
<select name='excltables[]' MULTIPLE SIZE=15>
|
2382 |
<?php
|
2383 |
|
@@ -2406,8 +1937,7 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2406 |
|
2407 |
while($row = mysql_fetch_array($query)){
|
2408 |
|
2409 |
-
|
2410 |
-
echo "<option value='".$row[0]."'>$row[0]</option>";
|
2411 |
|
2412 |
}
|
2413 |
|
@@ -2421,7 +1951,6 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2421 |
?>
|
2422 |
|
2423 |
</table>
|
2424 |
-
</div>
|
2425 |
<?php
|
2426 |
$tabs->endTab();
|
2427 |
}
|
@@ -2435,7 +1964,7 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2435 |
</tr>
|
2436 |
<tr>
|
2437 |
<td>
|
2438 |
-
<input type=text name='bname' value='' size=
|
2439 |
<?php echo LM_BACKUP_NAME_SUB?>
|
2440 |
</td>
|
2441 |
</tr>
|
@@ -2469,15 +1998,6 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2469 |
?>
|
2470 |
|
2471 |
</table>
|
2472 |
-
<?php
|
2473 |
-
$tabs->endTab();
|
2474 |
-
$tabs->startTab(LM_TAB_G_COMMENTS,"users-comments-options-tab");
|
2475 |
-
?>
|
2476 |
-
<div class="mainText">
|
2477 |
-
<h2><?php echo LM_TAB_G_COMMENTS_H2?></h2>
|
2478 |
-
<textarea name="backupComments" rows=20 cols=80></textarea>
|
2479 |
-
<br /><small> <?php echo LM_TAB_G_COMMENTS_NOTE?></small>
|
2480 |
-
</div>
|
2481 |
<?php
|
2482 |
$tabs->endTab();
|
2483 |
$tabs->endPane();
|
@@ -2558,23 +2078,17 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2558 |
|
2559 |
function showHelp( $option ) {
|
2560 |
?>
|
2561 |
-
|
2562 |
-
|
2563 |
-
|
2564 |
-
|
2565 |
-
|
2566 |
-
|
2567 |
-
|
2568 |
-
|
2569 |
-
|
2570 |
-
|
2571 |
-
|
2572 |
-
<div class="mainText">
|
2573 |
-
|
2574 |
-
<?php echo LM_CLONER_ABOUT?>
|
2575 |
-
</div>
|
2576 |
-
</div>
|
2577 |
-
</div>
|
2578 |
<form action="index2.php" name="adminForm" method="post">
|
2579 |
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2580 |
<input type="hidden" name="task" value=""/>
|
@@ -2589,26 +2103,17 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2589 |
|
2590 |
?>
|
2591 |
|
2592 |
-
|
2593 |
-
|
2594 |
-
|
2595 |
-
|
2596 |
-
|
2597 |
-
|
2598 |
-
|
2599 |
-
|
2600 |
-
|
2601 |
-
|
2602 |
-
|
2603 |
-
<table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
|
2604 |
-
<tr>
|
2605 |
-
<td>
|
2606 |
-
<?php echo LM_CLONER_RESTORE?>
|
2607 |
-
</td>
|
2608 |
-
</tr>
|
2609 |
-
</table>
|
2610 |
-
</p></div>
|
2611 |
-
</div>
|
2612 |
<form action="index2.php" name="adminForm" method="post">
|
2613 |
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2614 |
<input type="hidden" name="task" value=""/>
|
@@ -2621,26 +2126,18 @@ function showBackups( &$files, &$sizes, $path, $option ) {
|
|
2621 |
// ----------------------------------------------------------
|
2622 |
|
2623 |
?>
|
2624 |
-
|
2625 |
-
|
2626 |
-
|
2627 |
-
|
2628 |
-
|
2629 |
-
|
2630 |
-
|
2631 |
-
|
2632 |
-
|
2633 |
-
|
2634 |
-
|
2635 |
-
|
2636 |
-
<tr>
|
2637 |
-
<td>
|
2638 |
-
<?echo LM_CLONER_CREDITS?>
|
2639 |
-
</td>
|
2640 |
-
</tr>
|
2641 |
-
</table>
|
2642 |
-
</p></div>
|
2643 |
-
</div>
|
2644 |
<form action="index2.php" name="adminForm" method="post">
|
2645 |
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2646 |
<input type="hidden" name="task" value=""/>
|
31 |
|
32 |
function mosTabs($int){
|
33 |
|
34 |
+
echo "<div class=\"tabber\">";
|
35 |
|
36 |
}
|
37 |
|
38 |
function startTab($name, $class){
|
39 |
|
40 |
+
echo "<div class=\"tabbertab\" title=\"$name\">";
|
41 |
|
42 |
|
43 |
}
|
44 |
|
45 |
function endTab(){
|
46 |
|
47 |
+
echo "</div>";
|
48 |
|
49 |
}
|
50 |
|
63 |
|
64 |
function header(){
|
65 |
|
66 |
+
global $mosConfig_live_site, $task;
|
|
|
67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
?>
|
69 |
<html lang="en">
|
70 |
<head>
|
72 |
<title>XCloner Backup and Restore</title>
|
73 |
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
|
74 |
|
75 |
+
<link rel="stylesheet" href="css/tabber.css" TYPE="text/css" MEDIA="screen">
|
76 |
<link rel="styleSheet" href="css/dtree.css" type="text/css" />
|
77 |
<link rel="styleSheet" href="css/main.css" type="text/css" />
|
78 |
+
<link rel="styleSheet" href="css/jquery-ui.css" type="text/css" />
|
79 |
|
80 |
+
<script type="text/javascript" src="javascript/tabber.js"></script>
|
81 |
<script type="text/javascript" src="javascript/dtree.js"></script>
|
82 |
<script type="text/javascript" src="javascript/main.js"></script>
|
83 |
<script type="text/javascript" src="javascript/jquery-1.4.4.min.js"></script>
|
84 |
+
<script type="text/javascript" src="javascript/jquery-ui.min.js"></script>
|
85 |
<script type="text/javascript">
|
86 |
|
87 |
/* Optional: Temporarily hide the "tabber" class so it does not "flash"
|
101 |
|
102 |
<tr><td align='center'>
|
103 |
|
104 |
+
<table width='100%' border='1' bgcolor='white'>
|
|
|
105 |
<tr>
|
106 |
+
<td width='100%'>
|
107 |
+
<table><tr><td>
|
108 |
+
<img src="images/backup.png" align="middle">
|
109 |
+
</td><td>
|
110 |
+
<h2><?php echo LM_COM_TITLE.$_SERVER['HTTP_HOST']; ?></h2>
|
111 |
+
<h1>Backup and Restore</h1>
|
112 |
+
</td></tr></table>
|
113 |
+
<td>
|
114 |
+
<?php
|
115 |
+
# Generating the buttons...
|
116 |
+
require_once( "toolbar.cloner.php" );
|
117 |
+
?>
|
118 |
+
|
|
|
|
|
|
|
|
|
|
|
119 |
</tr>
|
120 |
</table>
|
|
|
|
|
121 |
<br />
|
122 |
<table width="100%" cellspacing='3' cellpadding="4" >
|
123 |
<tr><td valign='top' width="160" >
|
192 |
<?php
|
193 |
if($_REQUEST['mosmsg']!="")
|
194 |
|
195 |
+
echo "<center><h2>".$_REQUEST['mosmsg']."</h2></center>";
|
196 |
|
197 |
}
|
198 |
|
202 |
</td></tr></table>
|
203 |
<hr><br /><br />
|
204 |
<center>
|
205 |
+
<p>Powered by <a href='http://www.xcloner.com' target='_blank'>XCloner</a>. All rights reserved!</p></center>
|
206 |
|
207 |
</td></tr></table>
|
|
|
|
|
208 |
|
209 |
<?php
|
210 |
|
218 |
$backupFile = $f['basename'];
|
219 |
|
220 |
if (file_exists($filename)) {
|
221 |
+
echo "Backup <strong>$filename</strong> created, we may continue!<br />";
|
222 |
+
//echo "Database backup: ".$databaseResult ."<br />";
|
|
|
223 |
$urlReturn = "index2.php?option=com_cloner&lines=" . $perm_lines . "&task=refresh&backup=$backupFile&excl_manual=$excl_manual";
|
224 |
|
225 |
if(!$_CONFIG['refresh_mode']){
|
230 |
|
231 |
}else{
|
232 |
|
|
|
|
|
233 |
?>
|
234 |
<!--Start ProgressBar-->
|
235 |
<script type="text/javascript">
|
238 |
|
239 |
var globalUrl;
|
240 |
var step = "r1";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
|
242 |
$("#progressbar").progressbar({ value: 0 });
|
243 |
|
246 |
//reset state here;
|
247 |
$("#error").show();
|
248 |
$("#errorText").append(status+" -- "+error);
|
|
|
249 |
}});
|
250 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
function xclonerRecurseJSON(url){
|
252 |
+
|
253 |
$("#result").hide();
|
254 |
|
255 |
globalUrl = url;
|
256 |
+
step = "r1";
|
257 |
|
258 |
$.getJSON(url, function(json) {
|
259 |
|
272 |
}
|
273 |
else{
|
274 |
var size = parseFloat(json.size)/(1024*1024);
|
275 |
+
$("#recurseStatus").text(" done! (Estimated size:"+size.toFixed(2)+"MB)");
|
276 |
$("#result").show();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
//xclonerGetJSON("<?php echo $urlReturn;?>");
|
278 |
returnUrl = "index2.php?option=com_cloner&lines="+json.tfiles+"&task=refresh&backup=<?php echo $backupFile; ?>&excl_manual=";
|
279 |
xclonerGetJSON(returnUrl);
|
285 |
}
|
286 |
|
287 |
function xclonerGetJSON(url){
|
288 |
+
|
289 |
globalUrl = url;
|
290 |
+
step = "r2";
|
291 |
|
292 |
$.getJSON(url, function(json) {
|
293 |
|
298 |
|
299 |
var percent = parseInt(json.percent);
|
300 |
$("#progressbar").progressbar({ value: percent });
|
301 |
+
$("#backupSize").text(json.backupSize);
|
302 |
$("#nFiles").text(json.startf);
|
303 |
$("#percent").text(json.percent);
|
|
|
304 |
if(!json.finished){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
var url = "index2.php?option="+json.option+"&task="+json.task+"&json="+json.json+"&startf="+json.startf+"&lines="+json.lines+"&backup="+json.backup+"&excl_manual="+json.excl_manual;
|
306 |
xclonerGetJSON(url);
|
307 |
}else{
|
308 |
|
|
|
|
|
|
|
|
|
|
|
309 |
$("#complete").show();
|
310 |
$("#nFiles").text(json.lines);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
|
312 |
+
}
|
313 |
|
314 |
});
|
315 |
|
316 |
}
|
317 |
|
|
|
|
|
318 |
$("#retry").click(function(){
|
319 |
$("#error").hide();
|
320 |
$("#errorText").empty();
|
321 |
if(step == "r1"){
|
|
|
|
|
|
|
|
|
322 |
xclonerRecurseJSON(globalUrl);
|
323 |
}
|
324 |
+
else if(step == "r2"){
|
325 |
xclonerGetJSON(globalUrl);
|
326 |
}
|
327 |
});
|
328 |
|
329 |
+
var recurseUrl="index2.php?task=recurse_files&mode=start&nohtml=1";
|
330 |
+
xclonerRecurseJSON(recurseUrl);
|
331 |
+
//xclonerGetJSON("<?php echo $urlReturn;?>");
|
332 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
|
334 |
});
|
335 |
</script>
|
336 |
|
337 |
+
<div id="recurseFiles">
|
338 |
+
<br /><strong>Scanning files system...</strong> <span id="recurseStatus"></span>
|
339 |
+
</div>
|
|
|
|
|
340 |
|
341 |
+
<div id="result">
|
342 |
+
<br /> <strong>Processing Files:</strong> <span id="percent">0</span>% (<span id="nFiles"></span> files)
|
343 |
+
<br /><br /> <strong>Backup Size: </strong><span id="backupSize"></span>
|
344 |
+
<br /><br /> <div id="progressbar"></div>
|
345 |
</div>
|
346 |
|
347 |
+
<div id="complete">
|
348 |
+
<br /><h2>Backup completed!</h2>
|
349 |
+
|
350 |
+
<form action="index2.php" name="adminForm" method="post">
|
351 |
+
<input type=hidden name=files[1] value='<?php echo $backupFile?>'>
|
352 |
+
<input type=hidden name=cid[1] value='<?php echo $backupFile?>'>
|
353 |
+
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
354 |
+
<input type="hidden" name="task" value=""/>
|
355 |
+
</form>
|
356 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
</div>
|
358 |
|
359 |
<div id="error" style="display:none;">
|
402 |
}
|
403 |
|
404 |
function _FDefault(){
|
405 |
+
global $_CONFIG;
|
406 |
?>
|
407 |
|
408 |
<form action="index2.php" method="post" name="adminForm">
|
477 |
<div class="status">
|
478 |
<span class="mtext">Backup Start Path Check: </span>
|
479 |
<?php
|
480 |
+
|
481 |
+
$stat = HTML_cloner::path_check($_CONFIG[backup_start_path]);
|
482 |
|
483 |
if( $stat['code'] > 0 and $stat['code'] < 3){
|
484 |
echo "<span class='error'>".$stat['message']; $error = 1;
|
485 |
}
|
486 |
else{
|
487 |
echo "<span class='success'>OK";
|
488 |
+
}
|
|
|
|
|
|
|
|
|
|
|
489 |
echo " ($_CONFIG[backup_start_path])";
|
490 |
?>
|
491 |
</span></div>
|
|
|
492 |
<div class="status">
|
493 |
<span class="mtext">Backup Store Path Check: </span>
|
494 |
<?php
|
495 |
|
496 |
+
$stat = HTML_cloner::path_check($_CONFIG[backup_store_path]);
|
497 |
|
498 |
if( $stat['code'] > 0){
|
499 |
echo "<span class='error'>".$stat['message']; $error = 1;
|
503 |
}
|
504 |
echo " ($_CONFIG[backup_store_path])";
|
505 |
?>
|
506 |
+
</span></div>
|
|
|
|
|
507 |
<div class="status">
|
508 |
<span class="mtext">Temporary Path Check: </span>
|
509 |
<?php
|
510 |
|
511 |
+
$stat = HTML_cloner::path_check($_CONFIG[temp_dir]);
|
512 |
|
513 |
if( $stat['code'] > 0){
|
514 |
echo "<span class='error'>".$stat['message']; $error = 1;
|
520 |
?>
|
521 |
</span></div>
|
522 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
523 |
<div class="status">
|
524 |
<span class="mtext">Backup Ready: </span>
|
525 |
<?php
|
544 |
<?php
|
545 |
}
|
546 |
|
547 |
+
/*The basic authentification form*/
|
548 |
function Login(){
|
549 |
|
550 |
?>
|
551 |
<center><br />
|
552 |
+
<form action="index2.php" method="post" name="adminForm">
|
553 |
+
<table border='1' ><tr><td align='center'>
|
554 |
+
<table align='center' cellpadding='10' cellspacing='20'>
|
555 |
+
<tr ><td colspan='2' align='center'><b>Authentification Area:</b></td></tr>
|
556 |
+
<tr><td>Username:</td><td><input type='text' size='30' name='username'></td></tr>
|
557 |
+
<tr><td>Password:</td><td><input type='password' size='30' name='password'></td></tr>
|
558 |
+
<tr><td></td><td><input type="submit" value='Login' name="login"> <input type="reset" value='Cancel'></td></tr>
|
559 |
+
|
560 |
+
<tr><td colspan='2'><?php echo LM_LOGIN_TEXT;?></td></tr>
|
561 |
+
|
562 |
+
</table>
|
563 |
+
</td></tr>
|
564 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
565 |
|
566 |
|
|
|
|
|
|
|
|
|
|
|
567 |
</table>
|
568 |
|
569 |
<input type="hidden" name="option" value="com_cloner" />
|
570 |
+
<input type="hidden" name="task" value="dologin" />
|
571 |
<input type="hidden" name="boxchecked" value="0" />
|
572 |
<input type="hidden" name="hidemainmenu" value="0" />
|
573 |
|
580 |
function Cron(){
|
581 |
global $_CONFIG;
|
582 |
?>
|
583 |
+
<table class='adminform'>
|
584 |
+
<tr><th>
|
585 |
+
<?php echo LM_CRON_TOP?>
|
586 |
+
</th></tr>
|
587 |
+
<tr><td>
|
588 |
+
<pre>
|
589 |
+
<?php echo LM_CRON_SUB?>
|
590 |
+
<br /><b>For Joomla:</b>
|
591 |
+
<span style='background: #eeeeee'>
|
592 |
+
/usr/bin/php <?php echo dirname(__FILE__);?>/cloner.cron.php
|
593 |
+
<br />
|
594 |
+
or
|
595 |
+
<br />
|
596 |
+
links http://link_to_xcloner_dir/cloner.cron.php
|
597 |
+
<br />
|
598 |
+
or
|
599 |
+
<br />
|
600 |
+
lynx -source http://link_to_xcloner_dir/cloner.cron.php
|
601 |
+
</span>
|
602 |
|
603 |
+
For <b>Running Multiple Crons</b>, you need to first create a custom configuration file in the XCloner Configuration -> Cron tab
|
604 |
+
and then replace "cloner.cron.php" with "cloner.cron.php?config=myconfig.php", only use 'links' or 'lynx' options to run the cronjob
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
605 |
|
606 |
+
If you would like to use the <b>php SSH command</b> for running Multiple Crons, you will need to replace
|
607 |
+
the "cloner.cron.php" with <b>"cloner.cron.php myconfig.php"</b> in the command line.
|
608 |
|
609 |
+
<?php echo LM_CRON_HELP?>
|
610 |
+
</pre>
|
611 |
+
</td></tr>
|
612 |
+
</table>
|
613 |
|
614 |
<?php
|
615 |
}
|
743 |
global $_CONFIG;
|
744 |
|
745 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
746 |
|
747 |
+
<form action="index2.php" method="post" name="adminForm">
|
|
|
748 |
<table class="adminlist">
|
749 |
<tr>
|
750 |
+
<th width="5" align="left">#</th>
|
751 |
+
<th width="5" align="left">
|
752 |
+
<input type="checkbox" name="toggle" value="" onClick="checkAll(<?php echo count( $lang_arr ); ?>);" />
|
753 |
</th>
|
754 |
<th align="left">
|
755 |
<?php echo LM_LANG_NAME ?>
|
756 |
</th>
|
757 |
</tr>
|
|
|
758 |
<?php
|
759 |
+
|
760 |
for($i=0; $i<sizeof($lang_arr); $i++){
|
761 |
|
762 |
?>
|
763 |
|
764 |
<tr>
|
765 |
+
<td width="5" align="left"><?php echo ($i+1);?></td>
|
766 |
+
<td width="5" align="left">
|
767 |
+
<input type="checkbox" id="cb<?php echo $i ?>" name="cid[<?php echo $i?>]" value="<?php echo $i ?>" onclick="isChecked(this.checked);" />
|
768 |
+
<input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $lang_arr[$i] ?>" onclick="isChecked(this.checked);" />
|
|
|
769 |
</td>
|
770 |
<td align="left" >
|
771 |
<a href="index2.php?option=<?php echo $option;?>&task=edit_lang&langx=<?php echo $lang_arr[$i];?>"><?php echo ucfirst($lang_arr[$i])?>
|
775 |
|
776 |
}
|
777 |
?>
|
778 |
+
|
779 |
<input type="hidden" name="option" value="com_cloner" />
|
780 |
<input type="hidden" name="task" value="lang" />
|
781 |
<input type="hidden" name="boxchecked" value="0" />
|
791 |
global $baDownloadPath, $_CONFIG;
|
792 |
|
793 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
794 |
<form action="index2.php" method="post" name="adminForm">
|
795 |
<table class="adminlist">
|
796 |
<tr>
|
797 |
+
<th width="5">#</th>
|
798 |
+
<th width="5">
|
799 |
+
<input type="checkbox" name="toggle" value="" onClick="checkAll(<?php echo count( $files ); ?>);" />
|
|
|
|
|
800 |
</th>
|
801 |
+
<th width="33%" class="title">
|
802 |
<?php echo LM_COL_FILENAME ?>
|
803 |
</th>
|
804 |
<th align="left" width="10%">
|
805 |
+
<?php echo LM_COL_DOWNLOAD ?>
|
806 |
+
</th>
|
807 |
+
<th align="left" width="10%">
|
808 |
<?php echo LM_COL_SIZE ?>
|
809 |
</th>
|
810 |
+
<th align="left" width="43%">
|
811 |
<?php echo LM_COL_DATE ?>
|
812 |
</th>
|
813 |
</tr>
|
815 |
$k = 0;
|
816 |
for ($i=0; $i <= (count( $files )-1); $i++) {
|
817 |
$date = date ("D jS M Y H:i:s (\G\M\T O)", filemtime($path.'/'.$files[$i]));
|
|
|
818 |
?>
|
819 |
<tr class="<?php echo "row$k"; ?>">
|
820 |
+
<td>
|
821 |
+
<?php echo $i+1; ?>
|
822 |
+
</td>
|
823 |
<td align="center">
|
824 |
+
<input type="checkbox" id="cb<?php echo $i ?>" name="cid[<?php echo $i?>]" value="<?php echo $i ?>" onclick="isChecked(this.checked);" />
|
825 |
+
<input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $files[$i] ?>" onclick="isChecked(this.checked);" />
|
|
|
826 |
</td>
|
827 |
+
<td >
|
828 |
+
<a target='_blank' href="<?php echo "index2.php?option=com_cloner&task=download&file=".'/'.urlencode($files[$i]); ?>"><?php echo $files[$i]; ?></a><input type="hidden" id="f<?php echo $i ?>" name="f<?php echo $i ?>" value="<?php echo $files[$i]; ?>" >
|
|
|
|
|
|
|
|
|
829 |
</td>
|
|
|
830 |
<td align="left">
|
831 |
+
<a target='_blank' href="<?php echo "index2.php?option=com_cloner&task=download&file=".'/'.urlencode($files[$i]); ?>"><img src="images/filesave.png" border="0" alt="<?php echo LM_DOWNLOAD_TITLE ?>" title="<?php echo LM_DOWNLOAD_TITLE ?>"></a></td >
|
832 |
+
<!--<td align="left">
|
833 |
+
<?php
|
834 |
+
|
835 |
+
$userfile = $_CONFIG['baDownloadPath']."/".$files[$i];
|
836 |
+
$localfile = $_CONFIG['clonerPath']."/".$files[$i];
|
837 |
+
if(@file_exists($userfile))
|
838 |
+
echo "<a href=\"index2.php?option=com_cloner&task=action&action=delete&file=$files[$i]\">
|
839 |
+
<img border='0' src='images/tick.png'></a>";
|
840 |
+
else
|
841 |
+
echo "<a href=\"index2.php?option=com_cloner&task=action&action=copy&file=$files[$i]\">
|
842 |
+
<img border='0' src='images/publish_x.png'></a>";
|
843 |
+
?>
|
844 |
+
</td>-->
|
845 |
+
<td align="left">
|
846 |
+
<?php echo $sizes[$i]; ?>
|
847 |
</td >
|
848 |
<td align="left">
|
849 |
+
<?php echo $date; ?>
|
850 |
</td>
|
851 |
</tr>
|
852 |
<?php
|
854 |
}
|
855 |
?>
|
856 |
</table>
|
857 |
+
|
858 |
<input type="hidden" name="option" value="com_cloner" />
|
859 |
<input type="hidden" name="task" value="" />
|
860 |
<input type="hidden" name="boxchecked" value="0" />
|
868 |
global $config_file,$_CONFIG, $lang_array, $database, $mosConfig_db;
|
869 |
?>
|
870 |
<form name='adminForm' action='index2.php' method='POST'>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
871 |
<table class='adminform'>
|
872 |
<tr><th colspan='2'>
|
873 |
<?php echo LM_CONFIG_EDIT?> <?php echo $config_file?>
|
874 |
</th></tr>
|
875 |
</table>
|
876 |
<?php
|
877 |
+
$tabs = new mosTabs(1);
|
878 |
+
$tabs->startTab(LM_TAB_GENERAL,"config-general-tab");
|
879 |
?>
|
880 |
+
<table class='adminform'>
|
881 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
882 |
|
883 |
+
<tr>
|
884 |
+
<th colspan='2'>
|
885 |
+
<?php echo LM_CONFIG_BSETTINGS?>
|
886 |
+
</th>
|
887 |
+
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
888 |
|
889 |
+
<tr>
|
890 |
+
<td>
|
891 |
+
<?php echo LM_CONFIG_UBPATH?>
|
892 |
+
</td>
|
893 |
+
<td>
|
894 |
+
<input type=text size=50 name='backup_path' value='<?php echo $_CONFIG[backup_path]?>'>
|
895 |
+
<br /><?php echo LM_CONFIG_UBPATH_SUB?>
|
896 |
+
</td>
|
897 |
+
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
898 |
|
899 |
+
<tr>
|
900 |
+
<td width='250'>
|
901 |
+
<?php echo LM_CONFIG_BPATH?>
|
902 |
+
</td>
|
903 |
+
<td>
|
904 |
+
<input type=text size=50 name='clonerPath' value='<?php echo $_CONFIG[clonerPath]?>'>
|
905 |
+
<br /><?php echo LM_CONFIG_BPATH_SUB?>
|
906 |
+
</td>
|
907 |
+
</tr>
|
908 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
909 |
|
910 |
+
<tr>
|
911 |
+
<th colspan='2'>
|
912 |
+
<?php echo LM_CONFIG_BSETTINGS_OPTIONS?>
|
913 |
+
</th>
|
914 |
+
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
915 |
|
916 |
+
<tr>
|
917 |
+
<td>
|
918 |
+
<?php echo LM_CONFIG_MANUAL_BACKUP;?>
|
919 |
+
</td>
|
920 |
+
<td>
|
921 |
+
<?php echo LM_YES?> <input type=radio size=50 value=1 name='backup_refresh' <?php if($_CONFIG[backup_refresh]==1) echo 'checked';?>>
|
922 |
+
<?php echo LM_NO?> <input type=radio size=50 value=0 name='backup_refresh' <?php if($_CONFIG[backup_refresh]==0) echo 'checked';?>>
|
923 |
+
<br><small><?php echo LM_CONFIG_MANUAL_BACKUP_SUB?></small>
|
924 |
+
</td>
|
925 |
+
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
926 |
|
927 |
+
<tr>
|
928 |
+
<td>
|
929 |
+
<?php echo LM_CRON_COMPRESS?>
|
930 |
+
</td>
|
931 |
+
<td>
|
932 |
+
<?php echo LM_YES?> <input type=radio size=50 value=1 name='backup_compress' <?php if($_CONFIG[backup_compress]==1) echo 'checked';?>>
|
933 |
+
<?php echo LM_NO?> <input type=radio size=50 value=0 name='backup_compress' <?php if($_CONFIG[backup_compress]==0) echo 'checked';?>>
|
934 |
+
<br /> <small>set it to Yes in order to compress the files into smaller backups</small>
|
935 |
+
</td>
|
936 |
+
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
937 |
|
938 |
+
<tr>
|
939 |
+
<td>
|
940 |
+
<?php echo LM_CRON_DB_BACKUP?>
|
941 |
+
</td>
|
942 |
+
<td>
|
943 |
+
Yes <input type=radio size=50 value=1 name='enable_db_backup' <?php if($_CONFIG[enable_db_backup]==1) echo 'checked';?>>
|
944 |
+
No <input type=radio size=50 value=0 name='enable_db_backup' <?php if($_CONFIG[enable_db_backup]==0) echo 'checked';?>>
|
945 |
+
<br />
|
946 |
+
<?php echo LM_CRON_DB_BACKUP_SUB?>
|
947 |
+
</td>
|
948 |
+
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
949 |
|
950 |
+
<tr>
|
951 |
+
<td>
|
952 |
+
<?php echo LM_CONFIG_SYSTEM_MBACKUP?>
|
953 |
+
</td>
|
954 |
+
<td>
|
955 |
+
Yes <input type=radio size=50 value=1 name='add_backups_dir' <?php if($_CONFIG[add_backups_dir]==1) echo 'checked';?>>
|
956 |
+
No <input type=radio size=50 value=0 name='add_backups_dir' <?php if($_CONFIG[add_backups_dir]==0) echo 'checked';?>>
|
957 |
+
<br />
|
958 |
+
<?php echo LM_CONFIG_SYSTEM_MBACKUP_SUB?>
|
959 |
+
</td>
|
960 |
+
</tr>
|
961 |
|
962 |
+
<tr>
|
963 |
+
<th colspan='2'>
|
964 |
+
<?php echo LM_CONFIG_BSETTINGS_SERVER?>
|
965 |
+
</th>
|
966 |
+
</tr>
|
967 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
968 |
|
969 |
+
<tr >
|
970 |
+
<td>
|
971 |
+
<?php echo LM_CONFIG_MEM?>
|
972 |
+
</td>
|
973 |
+
<td align='left'>
|
974 |
+
<table width='85%' cellpadding='0' cellspacing='2' border='1'>
|
975 |
+
<tr bgcolor='#efefef'><td valign='middle'>
|
976 |
+
<?php echo LM_ACTIVE;?> <input type=checkbox value=1 name='mem' <?php if($_CONFIG[mem]==1) echo 'checked';?>>
|
977 |
+
</td><td align='left'>
|
978 |
|
979 |
+
<table width='100%' cellpadding='0' cellspacing='0'>
|
980 |
+
<tr><td>
|
981 |
+
<?php echo LM_TAR_PATH;?> <br /><input size='50' type=text name=tarpath value='<?php echo $_CONFIG[tarpath]?>'><br />
|
982 |
+
<?php echo LM_TAR_PATH_SUB;?>
|
983 |
+
</td></tr>
|
984 |
|
985 |
+
</table>
|
|
|
|
|
|
|
986 |
|
987 |
+
</td></tr>
|
988 |
|
989 |
+
<tr bgcolor='#dedede'><td>
|
990 |
+
<?php echo LM_ACTIVE?> <input type=checkbox value=1 name='sql_mem' <?php if($_CONFIG[sql_mem]==1) echo 'checked';?>>
|
991 |
+
</td><td align='left'>
|
992 |
+
<?php echo LM_MYSQLDUMP_PATH;?> <br /><input type=text size='50' name='sqldump' value='<?php echo $_CONFIG[sqldump]?>'>
|
993 |
|
994 |
+
</td></tr>
|
995 |
+
</table>
|
|
|
996 |
|
997 |
+
<?php echo LM_CONFIG_MEM_SUB?>
|
998 |
|
999 |
+
</td>
|
1000 |
+
</tr>
|
|
|
|
|
|
|
|
|
1001 |
|
1002 |
+
<tr>
|
1003 |
+
<th colspan='2'>
|
1004 |
+
<?php echo "License Management"?>
|
1005 |
+
</th>
|
1006 |
+
</tr>
|
1007 |
+
<tr>
|
1008 |
+
<td>
|
1009 |
+
<?php echo "License Code - optional*
|
1010 |
+
<br />*only for support purposes"?>
|
1011 |
+
</td>
|
1012 |
+
<td>
|
1013 |
+
<textarea cols=40 rows='7' name='license_code' ><?php echo $_CONFIG[license_code]?></textarea>
|
1014 |
+
<br />Copy/Paste the license code from <a target='_blank' href='http://www.xcloner.com/'>XCloner.com Members area</a>
|
1015 |
+
</td>
|
1016 |
+
</tr>
|
1017 |
|
|
|
1018 |
|
1019 |
+
</table>
|
1020 |
+
<?php
|
1021 |
+
$tabs->endTab();
|
1022 |
+
$tabs->startTab(LM_TAB_MYSQL,"config-mysql-tab");
|
1023 |
+
?>
|
1024 |
+
<table class='adminform'>
|
1025 |
+
|
1026 |
+
|
1027 |
+
<tr>
|
1028 |
+
<th colspan='2'>
|
1029 |
+
<?php echo LM_CONFIG_MYSQL?>
|
1030 |
+
</th>
|
1031 |
+
</tr>
|
1032 |
+
|
1033 |
+
<tr>
|
1034 |
+
<td>
|
1035 |
+
<?php echo LM_CONFIG_MYSQLH?>
|
1036 |
+
</td>
|
1037 |
+
<td>
|
1038 |
+
<input type=text size=50 name='mysql_host' value='<?php echo $_CONFIG[mysql_host]?>'>
|
1039 |
+
<br /><?php echo LM_CONFIG_MYSQLH_SUB?>
|
1040 |
+
</td>
|
1041 |
+
</tr>
|
1042 |
+
|
1043 |
+
<tr>
|
1044 |
+
<td>
|
1045 |
+
<?php echo LM_CONFIG_MYSQLU?>
|
1046 |
+
</td>
|
1047 |
+
<td>
|
1048 |
+
<input type=text size=50 name='mysql_user' value='<?php echo $_CONFIG[mysql_user]?>'>
|
1049 |
+
<br /><?php echo LM_CONFIG_MYSQLU_SUB?>
|
1050 |
+
</td>
|
1051 |
+
</tr>
|
1052 |
+
|
1053 |
+
<tr>
|
1054 |
+
<td>
|
1055 |
+
<?php echo LM_CONFIG_MYSQLP?>
|
1056 |
+
</td>
|
1057 |
+
<td>
|
1058 |
+
<input type=text size=50 name='mysql_pass' value='<?php echo $_CONFIG[mysql_pass]?>'>
|
1059 |
+
<br /><?php echo LM_CONFIG_MYSQLP_SUB?>
|
1060 |
+
</td>
|
1061 |
+
</tr>
|
1062 |
+
|
1063 |
+
<tr>
|
1064 |
+
<td>
|
1065 |
+
<?php echo LM_CONFIG_MYSQLD?>
|
1066 |
+
</td>
|
1067 |
+
<td>
|
1068 |
+
<input type=text size=50 name='mysql_database' value='<?php echo $_CONFIG[mysql_database]?>'>
|
1069 |
+
<br /><?php echo LM_CONFIG_MYSQLD_SUB?>
|
1070 |
+
</td>
|
1071 |
+
</tr>
|
1072 |
+
|
1073 |
+
<tr>
|
1074 |
+
<td width='200'>
|
1075 |
+
<?php echo LM_CONFIG_SYSTEM_MDATABASES?>
|
1076 |
+
</td>
|
1077 |
+
<td>
|
1078 |
+
<?php echo LM_YES?> <input type=radio name='system_mdatabases' value='0' <?php if(abs($_CONFIG[system_mdatabases])==0) echo "checked";?>>
|
1079 |
+
<?php echo LM_NO?> <input type=radio name='system_mdatabases' value='1' <?php if(abs($_CONFIG[system_mdatabases])==1) echo "checked";?>>
|
1080 |
+
<br>
|
1081 |
+
|
1082 |
+
<br /><?php echo LM_CONFIG_SYSTEM_MDATABASES_SUB?>
|
1083 |
+
</td>
|
1084 |
+
</tr>
|
1085 |
+
|
1086 |
+
</table>
|
1087 |
+
<?php
|
1088 |
+
$tabs->endTab();
|
1089 |
+
$tabs->startTab(LM_TAB_AUTH,"config-mysql-tab");
|
1090 |
+
?>
|
1091 |
+
<table class='adminform'>
|
1092 |
+
|
1093 |
+
|
1094 |
+
<tr>
|
1095 |
+
<th colspan='2'>
|
1096 |
+
<?php echo LM_CONFIG_AUTH?>
|
1097 |
+
</th>
|
1098 |
+
</tr>
|
1099 |
+
|
1100 |
+
<tr>
|
1101 |
+
<td>
|
1102 |
+
<?php echo LM_CONFIG_AUTH_USER?>
|
1103 |
+
</td>
|
1104 |
+
<td>
|
1105 |
+
<input type=text size=30 name='jcuser' value='<?php echo $_CONFIG[jcuser]?>'>
|
1106 |
+
<br /><?php echo LM_CONFIG_AUTH_USER_SUB?>
|
1107 |
+
</td>
|
1108 |
+
</tr>
|
1109 |
+
|
1110 |
+
<tr>
|
1111 |
+
<td>
|
1112 |
+
<?php echo LM_CONFIG_AUTH_PASS?>
|
1113 |
+
</td>
|
1114 |
+
<td>
|
1115 |
+
<input type=text size=30 name='jcpass' value=''> <?php if($_CONFIG['jcpass'] == md5('admin')) echo "<font color=red>please change the default password 'admin'</font>"?>
|
1116 |
+
<br /><?php echo LM_CONFIG_AUTH_PASS_SUB?>
|
1117 |
+
</td>
|
1118 |
+
</tr>
|
1119 |
+
|
1120 |
+
|
1121 |
+
</table>
|
1122 |
+
<?php
|
1123 |
+
$tabs->endTab();
|
1124 |
+
$tabs->startTab(LM_TAB_SYSTEM,"config-system-tab");
|
1125 |
+
?>
|
1126 |
+
<table class='adminform'>
|
1127 |
+
<tr>
|
1128 |
+
<th colspan='2'>
|
1129 |
+
<?php echo LM_CONFIG_DISPLAY?>
|
1130 |
+
</th>
|
1131 |
+
</tr>
|
1132 |
+
|
1133 |
+
<tr>
|
1134 |
+
<td width='200'>
|
1135 |
+
<?php echo LM_CONFIG_SYSTEM_LANG?>
|
1136 |
+
</td>
|
1137 |
+
<td>
|
1138 |
+
<select name='select_lang'>
|
1139 |
+
<option value=''><?php echo LM_CONFIG_SYSTEM_LANG_DEFAULT;?></option>
|
1140 |
+
<?php
|
1141 |
+
foreach($lang_array as $value)
|
1142 |
+
if($_CONFIG['select_lang'] == $value)
|
1143 |
+
echo "<option value='$value' selected>$value</option>\n";
|
1144 |
+
else
|
1145 |
+
echo "<option value='$value'>$value</option>\n";
|
1146 |
+
?>
|
1147 |
+
</select>
|
1148 |
+
<br>
|
1149 |
+
<br /><?php echo LM_CONFIG_SYSTEM_LANG_SUB?>
|
1150 |
+
</td>
|
1151 |
+
</tr>
|
1152 |
+
|
1153 |
+
|
1154 |
+
<!--<tr>
|
1155 |
+
<td width='200'>
|
1156 |
+
<?php echo LM_CONFIG_SYSTEM_DOWNLOAD?>
|
1157 |
+
</td>
|
1158 |
+
<td>
|
1159 |
+
<?php echo LM_YES?> <input type=radio name='system_dlink' value='1' <?php if(abs($_CONFIG[system_dlink])==1) echo "checked";?>>
|
1160 |
+
<?php echo LM_NO?> <input type=radio name='system_dlink' value='0' <?php if(abs($_CONFIG[system_dlink])==0) echo "checked";?>>
|
1161 |
+
<br>
|
1162 |
+
|
1163 |
+
<br /><?php echo LM_CONFIG_SYSTEM_DOWNLOAD_SUB?>
|
1164 |
+
</td>
|
1165 |
+
</tr>-->
|
1166 |
+
|
1167 |
+
|
1168 |
+
<tr>
|
1169 |
+
<th colspan='2'>
|
1170 |
+
<?php echo LM_CONFIG_SYSTEM?>
|
1171 |
+
</th>
|
1172 |
+
</tr>
|
1173 |
+
|
1174 |
+
<tr>
|
1175 |
+
<td width='200'>
|
1176 |
+
<?php echo LM_CONFIG_SYSTEM_FTP?>
|
1177 |
+
</td>
|
1178 |
+
<td>
|
1179 |
+
Direct <input type=radio name='system_ftptransfer' value='0' <?php if(abs($_CONFIG[system_ftptransfer])==0) echo "checked";?>>
|
1180 |
+
Passive <input type=radio name='system_ftptransfer' value='1' <?php if(abs($_CONFIG[system_ftptransfer])==1) echo "checked";?>> <br>
|
1181 |
+
|
1182 |
+
<br /><?php echo LM_CONFIG_SYSTEM_FTP_SUB?>
|
1183 |
+
</td>
|
1184 |
+
</tr>
|
1185 |
+
<tr>
|
1186 |
+
<td>
|
1187 |
+
<?php echo LM_FTP_TRANSFER_MORE?>
|
1188 |
+
</td>
|
1189 |
+
<td>
|
1190 |
+
Normal <input type=radio size=50 value=0 name='secure_ftp' <?php if($_CONFIG[secure_ftp]==0) echo 'checked';?>>
|
1191 |
+
Secure <input type=radio size=50 value=1 name='secure_ftp' <?php if($_CONFIG[secure_ftp]==1) echo 'checked';?>>
|
1192 |
+
</td>
|
1193 |
+
</tr>
|
1194 |
+
|
1195 |
+
<th colspan='2'>
|
1196 |
+
<?php echo LM_CONFIG_MANUAL?>
|
1197 |
+
</th>
|
1198 |
+
</tr>
|
1199 |
+
|
1200 |
+
<tr>
|
1201 |
+
<td>
|
1202 |
+
<?php echo LM_CONFIG_MANUAL_FILES;?>
|
1203 |
+
</td>
|
1204 |
+
<td>
|
1205 |
+
<input type=text size=20 name='backup_refresh_number' value=<?php echo $_CONFIG[backup_refresh_number];?>>
|
1206 |
+
|
1207 |
+
</td>
|
1208 |
+
</tr>
|
1209 |
+
|
1210 |
+
<tr>
|
1211 |
+
<td>
|
1212 |
+
<?php echo LM_CONFIG_MANUAL_REFRESH;?>
|
1213 |
+
</td>
|
1214 |
+
<td>
|
1215 |
+
<input type=text size=20 name='refresh_time' value=<?php echo $_CONFIG[refresh_time];?>> seconds
|
1216 |
+
|
1217 |
+
</td>
|
1218 |
+
</tr>
|
1219 |
+
|
1220 |
+
<tr>
|
1221 |
+
<td>
|
1222 |
+
<?php echo LM_REFRESH_MODE?>
|
1223 |
+
</td>
|
1224 |
+
<td>
|
1225 |
+
Normal <input type=radio size=50 value=0 name='refresh_mode' <?php if($_CONFIG[refresh_mode]==0) echo 'checked';?>>
|
1226 |
+
AJAX <input type=radio size=50 value=1 name='refresh_mode' <?php if($_CONFIG[refresh_mode]==1) echo 'checked';?>>
|
1227 |
+
</td>
|
1228 |
+
</tr>
|
1229 |
+
|
1230 |
+
<tr>
|
1231 |
+
<td>
|
1232 |
+
<?php echo LM_DEBUG_MODE?>
|
1233 |
+
</td>
|
1234 |
+
<td>
|
1235 |
+
No <input type=radio size=50 value=0 name='debug' <?php if($_CONFIG[debug]==0) echo 'checked';?>>
|
1236 |
+
Yes <input type=radio size=50 value=1 name='debug' <?php if($_CONFIG[debug]==1) echo 'checked';?>>
|
1237 |
+
</td>
|
1238 |
+
</tr>
|
1239 |
+
|
1240 |
+
</table>
|
1241 |
+
<?php
|
1242 |
+
$tabs->endTab();
|
1243 |
+
$tabs->startTab(LM_TAB_CRON,"config-cron-tab");
|
1244 |
+
?>
|
1245 |
+
<table class='adminform'>
|
1246 |
+
<tr>
|
1247 |
+
<th colspan='2'>
|
1248 |
+
<?php echo LM_CRON_SETTINGS_M?> - all configs are saved in configs/
|
1249 |
+
</th>
|
1250 |
+
</tr>
|
1251 |
+
|
1252 |
+
<tr>
|
1253 |
+
<td>
|
1254 |
+
<?php echo LM_CRON_MCRON?>
|
1255 |
+
</td>
|
1256 |
+
<td>
|
1257 |
+
<input type=text size=30 value="<?php echo $_CONFIG[cron_save_as]?>" name='cron_save_as' >.php <br />
|
1258 |
+
<?php echo LM_CRON_MCRON_SUB?>
|
1259 |
+
</td>
|
1260 |
+
</tr>
|
1261 |
+
|
1262 |
+
<tr>
|
1263 |
+
<td>
|
1264 |
+
<?php echo LM_CRON_MCRON_AVAIL?>
|
1265 |
+
</td>
|
1266 |
+
<td>
|
1267 |
+
<?php
|
1268 |
+
|
1269 |
+
if ($handle = @opendir($_CONFIG['multiple_config_dir'])) {
|
1270 |
+
|
1271 |
+
while (false !== ($file = readdir($handle))) {
|
1272 |
+
if( ($file!=".") && ($file!="..") &&($file!="") && (strstr($file, '.php'))){
|
1273 |
+
$fcron = "cloner.cron.php?config=$file";
|
1274 |
+
|
1275 |
+
echo "<b>$fcron</b>";
|
1276 |
+
|
1277 |
+
echo " - <a href='$fcron' target='_blank'>execute cron</a>";
|
1278 |
+
|
1279 |
+
echo " | <a href='index2.php?option=com_cloner&task=cron_delete&fconfig=$file'>delete config</a>";
|
1280 |
+
|
1281 |
+
echo "\n<br />";
|
1282 |
+
}
|
1283 |
+
}
|
1284 |
+
|
1285 |
+
closedir($handle);
|
1286 |
+
}
|
1287 |
+
?>
|
1288 |
+
</td>
|
1289 |
+
</tr>
|
1290 |
+
|
1291 |
+
<tr>
|
1292 |
+
<th colspan='2'>
|
1293 |
+
<?php echo LM_CRON_SETTINGS?>
|
1294 |
+
</th>
|
1295 |
+
</tr>
|
1296 |
+
|
1297 |
+
<tr>
|
1298 |
+
<td>
|
1299 |
+
<?php echo LM_CRON_SEMAIL?>
|
1300 |
+
</td>
|
1301 |
+
<td>
|
1302 |
+
<input type=text size=30 value="<?php echo $_CONFIG[cron_logemail]?>" name='cron_logemail' > <br />
|
1303 |
+
<?php echo LM_CRON_SEMAIL_SUB?>
|
1304 |
+
</td>
|
1305 |
+
</tr>
|
1306 |
+
|
1307 |
+
<tr>
|
1308 |
+
<td width='200'>
|
1309 |
+
<?php echo LM_CRON_MODE?>
|
1310 |
+
</td>
|
1311 |
+
<td>
|
1312 |
+
<input type=radio size=50 value=0 name='cron_send' <?php if($_CONFIG[cron_send]==0) echo 'checked';?>>
|
1313 |
+
<?php echo LM_CONFIG_CRON_LOCAL?><br />
|
1314 |
+
<input type=radio size=50 value=1 name='cron_send' <?php if($_CONFIG[cron_send]==1) echo 'checked';?>>
|
1315 |
+
<?php echo LM_CONFIG_CRON_REMOTE?><br />
|
1316 |
+
<input type=radio size=50 value=2 name='cron_send' <?php if($_CONFIG[cron_send]==2) echo 'checked';?>>
|
1317 |
+
<?php echo LM_CONFIG_CRON_EMAIL?> <br />
|
1318 |
+
<?php echo LM_CRON_MODE_INFO?>
|
1319 |
+
</td>
|
1320 |
+
</tr>
|
1321 |
+
|
1322 |
+
|
1323 |
+
<tr>
|
1324 |
+
<td>
|
1325 |
+
<?php echo LM_CRON_TYPE?>
|
1326 |
+
</td>
|
1327 |
+
<td>
|
1328 |
+
<input type=radio size=50 value=0 name='cron_btype' <?php if($_CONFIG[cron_btype]==0) echo 'checked';?>>
|
1329 |
+
<?php echo LM_CONFIG_CRON_FULL?> <br />
|
1330 |
+
<input type=radio size=50 value=1 name='cron_btype' <?php if($_CONFIG[cron_btype]==1) echo 'checked';?>>
|
1331 |
+
<?php echo LM_CONFIG_CRON_FILES?><br />
|
1332 |
+
<input type=radio size=50 value=2 name='cron_btype' <?php if($_CONFIG[cron_btype]==2) echo 'checked';?>>
|
1333 |
+
<?php echo LM_CONFIG_CRON_DATABASE?> <br />
|
1334 |
+
<?php echo LM_CRON_TYPE_INFO?>
|
1335 |
+
</td>
|
1336 |
+
</tr>
|
1337 |
+
|
1338 |
+
<tr>
|
1339 |
+
<td>
|
1340 |
+
<?php echo LM_CRON_BNAME?>
|
1341 |
+
</td>
|
1342 |
+
<td>
|
1343 |
+
<input type=text size=50 value="<?php echo $_CONFIG[cron_bname]?>" name='cron_bname' > <br />
|
1344 |
+
<?php echo LM_CRON_BNAME_SUB?>
|
1345 |
+
</td>
|
1346 |
+
</tr>
|
1347 |
+
|
1348 |
+
|
1349 |
+
<tr>
|
1350 |
+
<td>
|
1351 |
+
<?php echo LM_CRON_IP?>
|
1352 |
+
</td>
|
1353 |
+
<td>
|
1354 |
+
<textarea type=text size=50 name='cron_ip' cols='30' rows='5'><?php echo $_CONFIG[cron_ip]?></textarea> <br />
|
1355 |
+
<?php echo LM_CRON_IP_SUB?>
|
1356 |
+
</td>
|
1357 |
+
</tr>
|
1358 |
+
|
1359 |
+
</table>
|
1360 |
+
<table class='adminform'>
|
1361 |
+
<tr>
|
1362 |
+
<th colspan='2'>
|
1363 |
+
<?php echo LM_CRON_FTP_DETAILS?>
|
1364 |
+
</th>
|
1365 |
+
</tr>
|
1366 |
+
</tr>
|
1367 |
+
<tr>
|
1368 |
+
<td width='200'>
|
1369 |
+
<?php echo LM_CRON_FTP_SERVER?>
|
1370 |
+
</td>
|
1371 |
+
<td>
|
1372 |
+
<input type=text size=50 name='cron_ftp_server' value='<?php echo $_CONFIG[cron_ftp_server]?>'>
|
1373 |
+
</td>
|
1374 |
+
</tr>
|
1375 |
+
<tr>
|
1376 |
+
<td>
|
1377 |
+
<?php echo LM_CRON_FTP_USER?>
|
1378 |
+
</td>
|
1379 |
+
<td>
|
1380 |
+
<input type=text size=50 name='cron_ftp_user' value='<?php echo $_CONFIG[cron_ftp_user]?>'>
|
1381 |
+
</td>
|
1382 |
+
</tr>
|
1383 |
+
<tr>
|
1384 |
+
<td>
|
1385 |
+
<?php echo LM_CRON_FTP_PASS?>
|
1386 |
+
</td>
|
1387 |
+
<td>
|
1388 |
+
<input type=text size=50 name='cron_ftp_pass' value='<?php echo $_CONFIG[cron_ftp_pass]?>'>
|
1389 |
+
</td>
|
1390 |
+
</tr>
|
1391 |
+
<tr>
|
1392 |
+
<td>
|
1393 |
+
<?php echo LM_CRON_FTP_PATH?>
|
1394 |
+
</td>
|
1395 |
+
<td>
|
1396 |
+
<input type=text size=50 name='cron_ftp_path' value='<?php echo $_CONFIG[cron_ftp_path]?>'>
|
1397 |
+
</td>
|
1398 |
+
</tr>
|
1399 |
+
<tr>
|
1400 |
+
<td>
|
1401 |
+
<?php echo LM_CRON_FTP_DELB?>
|
1402 |
+
</td>
|
1403 |
+
<td>
|
1404 |
+
<input type=checkbox name='cron_ftp_delb' <?php if($_CONFIG[cron_ftp_delb]==1) echo "checked";?> value='1'>
|
1405 |
+
</td>
|
1406 |
+
</tr>
|
1407 |
+
</table>
|
1408 |
+
|
1409 |
+
<table class='adminform'>
|
1410 |
+
|
1411 |
+
<tr><th colspan=2>
|
1412 |
+
<?php echo LM_AMAZON_S3?>
|
1413 |
+
</th></tr>
|
1414 |
+
<tr>
|
1415 |
+
<td width='200'>
|
1416 |
+
<?php echo LM_AMAZON_S3_ACTIVATE?>
|
1417 |
+
</td>
|
1418 |
+
<td>
|
1419 |
+
<input type=checkbox name='cron_amazon_active' <?php if($_CONFIG[cron_amazon_active]==1) echo "checked";?> value='1'>
|
1420 |
+
</td>
|
1421 |
+
</tr>
|
1422 |
+
|
1423 |
+
<tr>
|
1424 |
+
<td width='200'>
|
1425 |
+
<?php echo LM_AMAZON_S3_AWSACCESSKEY;?>
|
1426 |
+
</td>
|
1427 |
+
<td>
|
1428 |
+
<input type=text size=50 name='cron_amazon_awsAccessKey' value="<?php echo $_CONFIG['cron_amazon_awsAccessKey'];?>">
|
1429 |
+
</td>
|
1430 |
+
</tr>
|
1431 |
+
|
1432 |
+
<tr>
|
1433 |
+
<td width='200'>
|
1434 |
+
<?php echo LM_AMAZON_S3_AWSSECRETKEY;?>
|
1435 |
+
</td>
|
1436 |
+
<td>
|
1437 |
+
<input type=text size=50 name='cron_amazon_awsSecretKey' value="<?php echo $_CONFIG['cron_amazon_awsSecretKey'];?>">
|
1438 |
+
</td>
|
1439 |
+
</tr>
|
1440 |
+
|
1441 |
+
<tr>
|
1442 |
+
<td width='200'>
|
1443 |
+
<?php echo LM_AMAZON_S3_BUCKET;?>
|
1444 |
+
</td>
|
1445 |
+
<td>
|
1446 |
+
<input type=text size=50 name='cron_amazon_bucket' value="<?php echo $_CONFIG['cron_amazon_bucket'];?>">
|
1447 |
+
</td>
|
1448 |
+
</tr>
|
1449 |
+
|
1450 |
+
<tr>
|
1451 |
+
<td width='200'>
|
1452 |
+
<?php echo LM_AMAZON_S3_DIRNAME;?>
|
1453 |
+
</td>
|
1454 |
+
<td>
|
1455 |
+
<input type=text size=50 name='cron_amazon_dirname' value="<?php echo $_CONFIG['cron_amazon_dirname'];?>">
|
1456 |
+
</td>
|
1457 |
+
</tr>
|
1458 |
+
|
1459 |
+
<td>
|
1460 |
+
|
1461 |
+
</td>
|
1462 |
+
</tr>
|
1463 |
+
|
1464 |
+
</table>
|
1465 |
+
|
1466 |
+
|
1467 |
+
<table class='adminform'>
|
1468 |
+
<tr>
|
1469 |
+
<th colspan='2'>
|
1470 |
+
<?php echo LM_CRON_EMAIL_DETAILS?>
|
1471 |
+
</th>
|
1472 |
+
</tr>
|
1473 |
+
</tr>
|
1474 |
+
<tr>
|
1475 |
+
<td width='200'>
|
1476 |
+
<?php echo LM_CRON_EMAIL_ACCOUNT?>
|
1477 |
+
</td>
|
1478 |
+
<td>
|
1479 |
+
<input type=text size=50 name='cron_email_address' value='<?php echo $_CONFIG[cron_email_address]?>'>
|
1480 |
+
</td>
|
1481 |
+
</tr>
|
1482 |
+
|
1483 |
+
|
1484 |
+
</table>
|
1485 |
+
|
1486 |
+
<table class='adminform'>
|
1487 |
+
<tr>
|
1488 |
+
<th colspan='2'>
|
1489 |
+
<?php echo LM_CRON_MYSQL_DETAILS?>
|
1490 |
+
</th>
|
1491 |
+
</tr>
|
1492 |
+
</tr>
|
1493 |
+
<tr bgcolor='#ffffff'>
|
1494 |
+
<td width='200'>
|
1495 |
+
<?php echo LM_CRON_MYSQL_DROP?>
|
1496 |
+
</td>
|
1497 |
+
<td>
|
1498 |
+
<input type=checkbox name='cron_sql_drop' value='1' <?php if($_CONFIG[cron_sql_drop]) echo "checked";?> >
|
1499 |
+
</td>
|
1500 |
+
</tr>
|
1501 |
+
|
1502 |
+
<?php
|
1503 |
+
if((abs($_CONFIG[system_mdatabases])==0) && ($_CONFIG[enable_db_backup]==1)){
|
1504 |
+
?>
|
1505 |
+
<tr><td valign='top'>
|
1506 |
+
<?php echo LM_DATABASE_INCLUDE_DATABASES?>
|
1507 |
+
</td><td>
|
1508 |
+
<select name='databases_incl[]' MULTIPLE SIZE=5>
|
1509 |
+
<?php
|
1510 |
+
|
1511 |
+
$curent_dbs = explode(",", $_CONFIG['databases_incl_list']);
|
1512 |
+
|
1513 |
+
$query = @mysql_query("SHOW databases");
|
1514 |
+
while($row = @mysql_fetch_array($query)){
|
1515 |
+
|
1516 |
+
$table = $row[0];
|
1517 |
+
|
1518 |
+
if($table != $_CONFIG['mysql_database'])
|
1519 |
+
|
1520 |
+
if(in_array($table, $curent_dbs)){
|
1521 |
+
|
1522 |
+
echo "<option value='".$table."' selected>$table</option>";
|
1523 |
+
|
1524 |
+
}else{
|
1525 |
+
|
1526 |
+
echo "<option value='".$table."'>$table</option>";
|
1527 |
+
|
1528 |
+
}
|
1529 |
+
}
|
1530 |
+
?>
|
1531 |
+
</select><br />
|
1532 |
+
<?php echo LM_DATABASE_INCLUDE_DATABASES_SUB?>
|
1533 |
+
</td></tr>
|
1534 |
+
<?php
|
1535 |
+
}
|
1536 |
+
?>
|
1537 |
+
|
1538 |
+
<tr><th colspan=2>
|
1539 |
+
<?php echo LM_CRON_DELETE_FILES?>
|
1540 |
+
</th></tr>
|
1541 |
+
<tr>
|
1542 |
+
<td width='200'>
|
1543 |
+
<?php echo LM_CRON_DELETE_FILES_SUB_ACTIVE?>
|
1544 |
+
</td>
|
1545 |
+
<td>
|
1546 |
+
<input type=checkbox name='cron_file_delete_act' <?php if ($_CONFIG['cron_file_delete_act'] == 1) echo 'checked';?> value='1'>
|
1547 |
+
</td>
|
1548 |
+
</tr>
|
1549 |
+
<tr>
|
1550 |
+
<td width='200'>
|
1551 |
+
<?php echo LM_CRON_DELETE_FILES_SUB?>
|
1552 |
+
</td>
|
1553 |
+
<td>
|
1554 |
+
<input size=5 name='cron_file_delete' value='<?php echo $_CONFIG[cron_file_delete]?>'> days:
|
1555 |
+
</td>
|
1556 |
+
</tr>
|
1557 |
+
</table>
|
1558 |
+
|
1559 |
+
<table class='adminform'>
|
1560 |
+
<tr>
|
1561 |
+
<th colspan='2'>
|
1562 |
+
<?php echo LM_CRON_EXCLUDE?>
|
1563 |
+
</th>
|
1564 |
+
</tr>
|
1565 |
+
</tr>
|
1566 |
+
<tr>
|
1567 |
+
<td width='200'>
|
1568 |
+
<?php echo LM_CRON_EXCLUDE_DIR?>
|
1569 |
+
</td>
|
1570 |
+
<td>
|
1571 |
+
<textarea cols=50 rows=5 name='cron_exclude'><?php echo $_CONFIG[cron_exclude]?></textarea>
|
1572 |
+
</td>
|
1573 |
+
</tr>
|
1574 |
+
|
1575 |
+
</table>
|
1576 |
+
<?php
|
1577 |
+
$tabs->endTab();
|
1578 |
+
$tabs->startTab(LM_TAB_INFO,"config-info-tab");
|
1579 |
+
?>
|
1580 |
+
<table class='adminform'>
|
1581 |
+
<tr>
|
1582 |
+
<th colspan='2'>
|
1583 |
+
<?php echo LM_CONFIG_INFO_PHP?>
|
1584 |
+
</th>
|
1585 |
+
</tr>
|
1586 |
+
|
1587 |
+
<tr>
|
1588 |
+
<td width='200'>
|
1589 |
+
<?php echo LM_CONFIG_INFO_T_VERSION?>
|
1590 |
+
</td>
|
1591 |
+
<td>
|
1592 |
+
<b><?php
|
1593 |
+
$version = phpversion();
|
1594 |
+
$ver = str_replace(".", "", $version);
|
1595 |
+
$val = ($ver < 520)? $version: "Off";
|
1596 |
+
echo HTML_cloner::get_color($version, $val);
|
1597 |
+
?></b>
|
1598 |
+
<br />
|
1599 |
+
<?php echo LM_CONFIG_INFO_VERSION?>
|
1600 |
+
</td>
|
1601 |
+
</tr>
|
1602 |
+
|
1603 |
+
<tr>
|
1604 |
+
<td width='200'>
|
1605 |
+
<?php echo LM_CONFIG_INFO_T_SAFEMODE?>
|
1606 |
+
</td>
|
1607 |
+
<td>
|
1608 |
+
<b><?php $val = (ini_get('safe_mode') != "")? ini_get('safe_mode'):"Off";
|
1609 |
+
echo HTML_cloner::get_color($val, 'On');
|
1610 |
+
?></b>
|
1611 |
+
<br />
|
1612 |
+
<?php echo LM_CONFIG_INFO_SAFEMODE?>
|
1613 |
+
</td>
|
1614 |
+
</tr>
|
1615 |
+
|
1616 |
+
<tr>
|
1617 |
+
<td width='200'>
|
1618 |
+
<?php echo LM_CONFIG_INFO_T_MTIME?>
|
1619 |
+
</td>
|
1620 |
+
<td>
|
1621 |
+
<b><?php echo (ini_get('max_execution_time') != "")? ini_get('max_execution_time'):"no value";
|
1622 |
+
|
1623 |
+
?></b>
|
1624 |
+
<br />
|
1625 |
+
<?php echo LM_CONFIG_INFO_TIME?>
|
1626 |
+
</td>
|
1627 |
+
</tr>
|
1628 |
+
|
1629 |
+
<tr>
|
1630 |
+
<td width='200'>
|
1631 |
+
<?php echo LM_CONFIG_INFO_T_MEML?>
|
1632 |
+
</td>
|
1633 |
+
<td>
|
1634 |
+
<b><?php echo (ini_get('memory_limit') != "")? ini_get('memory_limit'):"no value";?> </b>
|
1635 |
+
<br />
|
1636 |
+
<?php echo LM_CONFIG_INFO_MEMORY?>
|
1637 |
+
</td>
|
1638 |
+
</tr>
|
1639 |
+
|
1640 |
+
<tr>
|
1641 |
+
<td width='200'>
|
1642 |
+
<?php echo LM_CONFIG_INFO_T_BDIR?>
|
1643 |
+
</td>
|
1644 |
+
<td>
|
1645 |
+
<b><?php $val = (ini_get('open_basedir') != "")? ini_get('open_basedir'):"no value";
|
1646 |
+
echo HTML_cloner::get_color($val, '/');
|
1647 |
+
?> </b>
|
1648 |
+
<br />
|
1649 |
+
<?php echo LM_CONFIG_INFO_BASEDIR?>
|
1650 |
+
</td>
|
1651 |
+
</tr>
|
1652 |
+
|
1653 |
+
<tr>
|
1654 |
+
<td width='200'>
|
1655 |
+
<?php echo LM_CONFIG_INFO_T_EXEC?>
|
1656 |
+
</td>
|
1657 |
+
<td>
|
1658 |
+
<b><?php
|
1659 |
+
|
1660 |
+
$out = "";
|
1661 |
+
if(function_exists("exec")){
|
1662 |
+
|
1663 |
+
$out = @exec("ls -al");
|
1664 |
+
}
|
1665 |
+
|
1666 |
+
$val = ($out != "")? "ENABLED":"<font color='red'>DISABLED</font>";
|
1667 |
+
echo HTML_cloner::get_color($val, 'DISABLED');
|
1668 |
+
?> </b>
|
1669 |
+
<br />
|
1670 |
+
<?php echo LM_CONFIG_INFO_EXEC?>
|
1671 |
+
</td>
|
1672 |
+
</tr>
|
1673 |
+
|
1674 |
+
<tr>
|
1675 |
+
<th colspan='2'>
|
1676 |
+
<?php echo LM_CONFIG_INFO_PATHS?>
|
1677 |
+
</td>
|
1678 |
+
<td>
|
1679 |
+
</tr>
|
1680 |
+
|
1681 |
+
<tr>
|
1682 |
+
<td width='200'>
|
1683 |
+
<?php echo LM_CONFIG_INFO_ROOT_BPATH_TMP?>
|
1684 |
+
</td>
|
1685 |
+
<td>
|
1686 |
+
<b><?php $tmp_dir = realpath($_CONFIG['backup_path']."/administrator/backups");
|
1687 |
+
echo (@is_writeable( $tmp_dir ))? $tmp_dir . " is <font color=green>writeable</font>":$tmp_dir. " <font color=red>incorrect or unreadable</font>";?></b>
|
1688 |
+
<br />
|
1689 |
+
<?php echo LM_CONFIG_INFO_ROOT_PATH_TMP_SUB?>
|
1690 |
+
</td>
|
1691 |
+
</tr>
|
1692 |
+
|
1693 |
+
<tr>
|
1694 |
+
<td width='200'>
|
1695 |
+
<?php echo LM_CONFIG_INFO_ROOT_BPATH?>
|
1696 |
+
</td>
|
1697 |
+
<td>
|
1698 |
+
<b><?php echo (@is_readable($_CONFIG['backup_path']) )? $_CONFIG['backup_path'] . " is <font color=green>readable</font>":$_CONFIG['backup_path']. " <font color=red>incorrect or unreadable</font>";?></b>
|
1699 |
+
<br />
|
1700 |
+
<?php echo LM_CONFIG_INFO_ROOT_PATH_SUB?>
|
1701 |
+
</td>
|
1702 |
+
</tr>
|
1703 |
+
|
1704 |
+
|
1705 |
+
<tr>
|
1706 |
+
<td width='200'>
|
1707 |
+
<?php echo LM_CONFIG_INFO_T_BPATH?>
|
1708 |
+
</td>
|
1709 |
+
<td>
|
1710 |
+
<b><?php echo (@is_writeable($_CONFIG['clonerPath']) )? $_CONFIG['clonerPath'] . " is <font color=green>writeable</font>":$_CONFIG['clonerPath']. " <font color=red>unwriteable</font>";?></b>
|
1711 |
+
<br />
|
1712 |
+
<?php echo LM_CONFIG_INFO_BPATH?>
|
1713 |
+
</td>
|
1714 |
+
</tr>
|
1715 |
+
|
1716 |
+
|
1717 |
+
<tr>
|
1718 |
+
<td width='200'>
|
1719 |
+
<?php echo LM_CONFIG_INFO_T_TAR?>
|
1720 |
+
</td>
|
1721 |
+
<td>
|
1722 |
+
<b><?php
|
1723 |
+
if(function_exists('exec')){
|
1724 |
+
$info_tar_path = explode(" ", @exec("whereis tar"));
|
1725 |
+
}
|
1726 |
+
echo ($info_tar_path['1'] != "")? $info_tar_path['1']:"unable to determine";
|
1727 |
+
?> </b>
|
1728 |
+
<br />
|
1729 |
+
<?php echo LM_CONFIG_INFO_TAR?>
|
1730 |
+
</td>
|
1731 |
+
</tr>
|
1732 |
+
|
1733 |
+
|
1734 |
+
<tr>
|
1735 |
+
<td width='200'>
|
1736 |
+
<?php echo LM_CONFIG_INFO_T_MSQL?>
|
1737 |
+
</td>
|
1738 |
+
<td>
|
1739 |
+
<b><?php
|
1740 |
+
if(function_exists('exec')){
|
1741 |
+
$info_msql_path = explode(" ", @exec("whereis mysqldump"));
|
1742 |
+
}
|
1743 |
+
echo ($info_msql_path['1'] != "")? $info_msql_path['1']:"unable to determine";
|
1744 |
+
?> </b>
|
1745 |
+
<br />
|
1746 |
+
<?php echo LM_CONFIG_INFO_MSQL?>
|
1747 |
+
</td>
|
1748 |
+
</tr>
|
1749 |
+
|
1750 |
+
|
1751 |
+
</table>
|
1752 |
+
<?php
|
1753 |
+
$tabs->endTab();
|
1754 |
+
$tabs->endPane();
|
1755 |
+
?>
|
1756 |
+
<input type="hidden" name="option" value="com_cloner" />
|
1757 |
+
<input type="hidden" name="task" value="config" />
|
1758 |
+
<input type="hidden" name='action' value='save'>
|
1759 |
+
</form>
|
1760 |
+
|
1761 |
+
<?php
|
1762 |
+
}
|
1763 |
+
|
1764 |
+
function get_color($val, $comp){
|
1765 |
+
|
1766 |
+
if(!stristr($val, $comp))
|
1767 |
+
echo "<span style='color:green'>$val</span>";
|
1768 |
+
else
|
1769 |
+
echo "<span style='color:red'>$val</span>";
|
1770 |
+
|
1771 |
+
}
|
1772 |
+
|
1773 |
+
function TransferForm($option, $files){
|
1774 |
+
global $baDownloadPath, $mosConfig_absolute_path, $clonerPath, $task;
|
1775 |
+
|
1776 |
+
?>
|
1777 |
+
<form action="index2.php" method="GET" name="adminForm">
|
1778 |
+
<script language="javascript" type="text/javascript">
|
1779 |
+
|
1780 |
+
|
1781 |
+
function submitbutton(pressbutton) {
|
1782 |
+
var form = document.adminForm;
|
1783 |
+
if (pressbutton == 'cancel') {
|
1784 |
+
submitform( pressbutton );
|
1785 |
+
return;
|
1786 |
+
}
|
1787 |
+
|
1788 |
+
submitform( pressbutton );
|
1789 |
+
|
1790 |
+
}
|
1791 |
+
|
1792 |
+
function gotocontact( id ) {
|
1793 |
var form = document.adminForm;
|
1794 |
form.contact_id.value = id;
|
1795 |
submitform( 'contact' );
|
1877 |
<form action="index2.php" method="post" name="adminForm">
|
1878 |
<?php
|
1879 |
$tabs = new mosTabs(1);
|
1880 |
+
#$tabs->startPane("BGeneratePane");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1881 |
if($_CONFIG['enable_db_backup']){
|
1882 |
$tabs->startTab(LM_TAB_G_DATABASE,"users-databse-options-tab");
|
1883 |
?>
|
1884 |
|
1885 |
+
|
1886 |
<table class="adminform">
|
1887 |
+
<tr>
|
1888 |
<th colspan=2>
|
1889 |
+
<b><?php echo LM_DATABASE_ARCHIVE; ?></b>
|
1890 |
</th>
|
1891 |
+
</tr>
|
1892 |
<tr>
|
1893 |
+
<td><input type="checkbox" id="dbbackup" name="dbbackup" checked value="1" /> <?php echo LM_CONFIRM_DATABASE; ?></td>
|
1894 |
+
</tr>
|
1895 |
+
<tr>
|
1896 |
+
<td><input type="checkbox" id="dbbackup_drop" name="dbbackup_drop" value="1" /> <?php echo "Add DROP SYNTAX"; ?></td>
|
|
|
|
|
1897 |
</tr>
|
1898 |
<tr>
|
1899 |
<td><?php echo "Mysql Compatibility"; ?>
|
1908 |
<?php echo LM_DATABASE_EXCLUDE_TABLES?>
|
1909 |
</th></tr>
|
1910 |
<tr><td>
|
1911 |
+
<?php echo LM_DATABASE_CURRENT?> <b><?php echo $mosConfig_db;?></b><br />
|
1912 |
<select name='excltables[]' MULTIPLE SIZE=15>
|
1913 |
<?php
|
1914 |
|
1937 |
|
1938 |
while($row = mysql_fetch_array($query)){
|
1939 |
|
1940 |
+
echo "<option value='".$row[0]."'>$row[0]</option>";
|
|
|
1941 |
|
1942 |
}
|
1943 |
|
1951 |
?>
|
1952 |
|
1953 |
</table>
|
|
|
1954 |
<?php
|
1955 |
$tabs->endTab();
|
1956 |
}
|
1964 |
</tr>
|
1965 |
<tr>
|
1966 |
<td>
|
1967 |
+
<input type=text name='bname' value='' size=40><br/>
|
1968 |
<?php echo LM_BACKUP_NAME_SUB?>
|
1969 |
</td>
|
1970 |
</tr>
|
1998 |
?>
|
1999 |
|
2000 |
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001 |
<?php
|
2002 |
$tabs->endTab();
|
2003 |
$tabs->endPane();
|
2078 |
|
2079 |
function showHelp( $option ) {
|
2080 |
?>
|
2081 |
+
|
2082 |
+
<table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
|
2083 |
+
<tr><th>
|
2084 |
+
<?php echo LM_CREDIT_TOP?>
|
2085 |
+
</th></tr>
|
2086 |
+
<tr>
|
2087 |
+
<td>
|
2088 |
+
<?php echo LM_CLONER_ABOUT?>
|
2089 |
+
</td>
|
2090 |
+
</tr>
|
2091 |
+
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
2092 |
<form action="index2.php" name="adminForm" method="post">
|
2093 |
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2094 |
<input type="hidden" name="task" value=""/>
|
2103 |
|
2104 |
?>
|
2105 |
|
2106 |
+
|
2107 |
+
<table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
|
2108 |
+
<tr><th>
|
2109 |
+
<?php echo LM_RESTORE_TOP?>
|
2110 |
+
</th></tr>
|
2111 |
+
<tr>
|
2112 |
+
<td>
|
2113 |
+
<?php echo LM_CLONER_RESTORE?>
|
2114 |
+
</td>
|
2115 |
+
</tr>
|
2116 |
+
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2117 |
<form action="index2.php" name="adminForm" method="post">
|
2118 |
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2119 |
<input type="hidden" name="task" value=""/>
|
2126 |
// ----------------------------------------------------------
|
2127 |
|
2128 |
?>
|
2129 |
+
|
2130 |
+
<table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
|
2131 |
+
<tr><th>
|
2132 |
+
<?php echo LM_CREDIT_TOP?>
|
2133 |
+
</th></tr>
|
2134 |
+
<tr>
|
2135 |
+
<td>
|
2136 |
+
|
2137 |
+
<?echo LM_CLONER_CREDITS?>
|
2138 |
+
</td>
|
2139 |
+
</tr>
|
2140 |
+
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2141 |
<form action="index2.php" name="adminForm" method="post">
|
2142 |
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2143 |
<input type="hidden" name="task" value=""/>
|
admin.cloner.php
CHANGED
@@ -1,226 +1,202 @@
|
|
1 |
<?php
|
2 |
-
/*
|
3 |
-
* admin.cloner.php
|
4 |
-
*
|
5 |
-
* Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
|
24 |
-
session_start();
|
25 |
-
header('Content-Type: text/html; charset=utf-8');
|
26 |
-
@set_time_limit("3600");
|
27 |
-
@error_reporting(E_ALL ^ E_NOTICE);
|
28 |
-
|
29 |
-
define("_VALID_MOS", 1);
|
30 |
-
|
31 |
-
//load configuration
|
32 |
-
$config_file = "cloner.config.php";
|
33 |
-
require_once($config_file);
|
34 |
-
require_once("restore/TAR.php");
|
35 |
-
require_once("cloner.functions.php");
|
36 |
-
require_once("admin.cloner.html.php");
|
37 |
-
require_once("common.php");
|
38 |
-
|
39 |
-
$option = "xcloner";
|
40 |
-
|
41 |
-
//Doing some basic authentification
|
42 |
-
if ((!isset($_SESSION['clone'])) && ($task != 'dologin')) {
|
43 |
-
$task = 'login';
|
44 |
-
|
45 |
-
$html = new HTML_cloner();
|
46 |
-
$html->header();
|
47 |
-
|
48 |
-
$html->Login();
|
49 |
-
|
50 |
-
$html->footer();
|
51 |
-
|
52 |
-
exit;
|
53 |
-
} elseif ($task == 'dologin') {
|
54 |
-
if (($_REQUEST['username'] == $_CONFIG['jcuser']) && (md5($_REQUEST['password']) == $_CONFIG['jcpass'])) {
|
55 |
-
if (function_exists('session_register')) {
|
56 |
-
@session_register('clone');
|
57 |
-
}
|
58 |
-
$_SESSION['clone'] = 1;
|
59 |
-
|
60 |
-
mosRedirect('index2.php?option=' . $option, "Welcome to XCloner backend");
|
61 |
-
} else {
|
62 |
-
|
63 |
-
|
64 |
-
mosRedirect('index2.php?option=' . $option, "Incorrect username and/or password");
|
65 |
-
}
|
66 |
-
}
|
67 |
-
|
68 |
-
//###########GLOBALS in effect
|
69 |
-
$GLOBALS['lang_dir'] = $lang_dir;
|
70 |
-
//###########
|
71 |
-
$lang_array = get_avalaible_langs();
|
72 |
-
|
73 |
-
|
74 |
-
// retrieve row selection from forms
|
75 |
-
$cid = $_REQUEST['cid'];
|
76 |
-
if (!is_array($cid)) {
|
77 |
-
$cid = array(0);
|
78 |
-
}
|
79 |
|
80 |
-
if(!$_REQUEST['nohtml'])
|
81 |
-
if (($task != 'download') and (($_REQUEST['task']!="refresh") or (!$_CONFIG['refresh_mode']))){
|
82 |
-
//HTML_cloner::header();
|
83 |
-
$html = new HTML_cloner();
|
84 |
-
$html->header();
|
85 |
-
}
|
86 |
-
|
87 |
-
//########## SETTING THE GLOBALS VARIABLES #########################
|
88 |
-
|
89 |
-
$GLOBALS['joomla_compatible'] = $joomla_compatible;
|
90 |
-
|
91 |
-
$GLOBALS['_CONFIG'] = $_CONFIG;
|
92 |
-
|
93 |
-
$GLOBALS['clonerPath'] = $clonerPath;
|
94 |
-
|
95 |
-
$GLOBALS['baDownloadPath'] = $baDownloadPath;
|
96 |
-
|
97 |
-
$GLOBALS['config_file'] = $config_file;
|
98 |
-
|
99 |
-
$GLOBALS['lang_array'] = $lang_array;
|
100 |
-
|
101 |
-
openXLog();
|
102 |
-
|
103 |
-
// process the workflow selection
|
104 |
-
switch ($task) {
|
105 |
-
case 'rename_save':
|
106 |
-
case 'rename':
|
107 |
-
clone_rename($option);
|
108 |
-
break;
|
109 |
-
case 'action':
|
110 |
-
action($option);
|
111 |
-
break;
|
112 |
-
|
113 |
-
|
114 |
-
case 'cancel_lang':
|
115 |
-
mosRedirect('index2.php?option=' . $option . "&task=lang");
|
116 |
-
break;
|
117 |
-
case 'add_lang':
|
118 |
-
case 'add_lang_new':
|
119 |
-
translator_add($option, $task);
|
120 |
-
break;
|
121 |
-
case 'save_lang_apply':
|
122 |
-
case 'save_lang':
|
123 |
-
case 'edit_lang':
|
124 |
-
translator_edit($option, $task);
|
125 |
-
break;
|
126 |
-
|
127 |
-
|
128 |
-
case 'del_lang':
|
129 |
-
case 'lang':
|
130 |
-
translator($option);
|
131 |
-
break;
|
132 |
-
|
133 |
-
case 'recurse_database';
|
134 |
-
goRecurseDatabases();
|
135 |
-
break;
|
136 |
-
|
137 |
-
case 'recurse_files':
|
138 |
-
goRecurseFiles();
|
139 |
-
break;
|
140 |
-
|
141 |
-
case 'cleanup':
|
142 |
-
include_once("classes/main.class.php");
|
143 |
-
$main = new Main();
|
144 |
-
$main->init($_CONFIG);
|
145 |
-
$main->cleanUp();
|
146 |
-
break;
|
147 |
-
|
148 |
-
case 'refresh':
|
149 |
-
generateBackuprefresh($cid, $option, $_REQUEST['backup'], $_CONFIG['refresh_mode']);
|
150 |
-
break;
|
151 |
-
|
152 |
-
case 'generate':
|
153 |
-
if($_CONFIG['refresh_mode']){
|
154 |
-
$_REQUEST['mode'] = "start";
|
155 |
-
if($_CONFIG['enable_db_backup'])
|
156 |
-
goRecurseDatabases();
|
157 |
-
//initBackup($_REQUEST['bname']);
|
158 |
-
//break;
|
159 |
-
}
|
160 |
-
generateBackup($cid, $option);
|
161 |
-
break;
|
162 |
-
|
163 |
-
case 'confirm':
|
164 |
-
deleteXLog();
|
165 |
-
confirmBackup($option);
|
166 |
-
break;
|
167 |
-
case 'download':
|
168 |
-
downloadBackup($_REQUEST[file]);
|
169 |
-
break;
|
170 |
-
case 'cron':
|
171 |
-
$html->Cron();
|
172 |
-
break;
|
173 |
-
case 'about':
|
174 |
-
case 'credits':
|
175 |
-
showHelp($option);
|
176 |
-
break;
|
177 |
-
case 'restore':
|
178 |
-
$html->Restore($option);
|
179 |
-
break;
|
180 |
-
|
181 |
-
case 'cron_delete':
|
182 |
-
if (unlink($_CONFIG['multiple_config_dir'] . "/" . $_REQUEST['fconfig']))
|
183 |
-
$msg = " was deleted";
|
184 |
-
else
|
185 |
-
$msg = " was not deleted, please delete it manually!";
|
186 |
-
|
187 |
-
mosRedirect('index2.php?option=' . $option . "&task=config", $_REQUEST['fconfig'] . $msg);
|
188 |
-
break;
|
189 |
-
|
190 |
-
case 'delete':
|
191 |
-
case 'remove':
|
192 |
-
deleteBackups($cid, $option);
|
193 |
-
break;
|
194 |
-
case 'continue':
|
195 |
-
case 'move':
|
196 |
-
case 'clone':
|
197 |
-
moveBackup($option);
|
198 |
-
break;
|
199 |
-
|
200 |
-
case 'cancel':
|
201 |
-
mosRedirect('index2.php?option=' . $option);
|
202 |
-
break;
|
203 |
-
case 'config':
|
204 |
-
config($option);
|
205 |
-
break;
|
206 |
-
case 'rename_cancel':
|
207 |
-
mosRedirect('index2.php?option=' . $option . "&task=view");
|
208 |
-
break;
|
209 |
-
case 'show':
|
210 |
-
case 'view':
|
211 |
-
showBackups($option);
|
212 |
-
break;
|
213 |
-
case 'logout':
|
214 |
-
doLogout();
|
215 |
-
break;
|
216 |
-
default:
|
217 |
-
fdefault();
|
218 |
-
break;
|
219 |
-
}
|
220 |
-
|
221 |
-
closeXLog();
|
222 |
-
if(!$_REQUEST['nohtml'])
|
223 |
-
$html->footer();
|
224 |
|
225 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
?>
|
1 |
<?php
|
2 |
+
/*
|
3 |
+
* admin.cloner.php
|
4 |
+
*
|
5 |
+
* Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
|
6 |
+
*
|
7 |
+
* This program is free software; you can redistribute it and/or modify
|
8 |
+
* it under the terms of the GNU General Public License as published by
|
9 |
+
* the Free Software Foundation; either version 2 of the License, or
|
10 |
+
* (at your option) any later version.
|
11 |
+
*
|
12 |
+
* This program is distributed in the hope that it will be useful,
|
13 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
* GNU General Public License for more details.
|
16 |
+
*
|
17 |
+
* You should have received a copy of the GNU General Public License
|
18 |
+
* along with this program; if not, write to the Free Software
|
19 |
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
+
* MA 02110-1301, USA.
|
21 |
+
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
+
session_start();
|
25 |
+
@set_time_limit("3600");
|
26 |
+
@error_reporting(E_ALL ^ E_NOTICE);
|
27 |
+
|
28 |
+
define("_VALID_MOS", 1);
|
29 |
+
|
30 |
+
//load configuration
|
31 |
+
$config_file = "cloner.config.php";
|
32 |
+
require_once($config_file);
|
33 |
+
require_once("restore/TAR.php");
|
34 |
+
require_once("cloner.functions.php");
|
35 |
+
require_once("admin.cloner.html.php");
|
36 |
+
require_once("common.php");
|
37 |
+
|
38 |
+
|
39 |
+
//Doing some basic authentification
|
40 |
+
if ((!isset($_SESSION['clone'])) && ($task != 'dologin')) {
|
41 |
+
$task = 'login';
|
42 |
+
|
43 |
+
HTML_cloner::header();
|
44 |
+
|
45 |
+
HTML_cloner::Login();
|
46 |
+
|
47 |
+
HTML_cloner::footer();
|
48 |
+
|
49 |
+
exit;
|
50 |
+
} elseif ($task == 'dologin') {
|
51 |
+
if (($_REQUEST['username'] == $_CONFIG['jcuser']) && (md5($_REQUEST['password']) == $_CONFIG['jcpass'])) {
|
52 |
+
if (function_exists('session_register')) {
|
53 |
+
@session_register('clone');
|
54 |
+
}
|
55 |
+
$_SESSION['clone'] = 1;
|
56 |
+
|
57 |
+
mosRedirect('index2.php?option=' . $option, "Welcome to XCloner backend");
|
58 |
+
} else {
|
59 |
+
|
60 |
+
|
61 |
+
mosRedirect('index2.php?option=' . $option, "Incorrect username and/or password");
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
|
66 |
+
|
67 |
+
//###########GLOBALS in effect
|
68 |
+
$GLOBALS['lang_dir'] = $lang_dir;
|
69 |
+
//###########
|
70 |
+
$lang_array = get_avalaible_langs();
|
71 |
+
|
72 |
+
|
73 |
+
// retrieve row selection from forms
|
74 |
+
$cid = $_REQUEST['cid'];
|
75 |
+
if (!is_array($cid)) {
|
76 |
+
$cid = array(0);
|
77 |
+
}
|
78 |
+
|
79 |
+
if(!$_REQUEST['nohtml'])
|
80 |
+
if (($task != 'download') and (($_REQUEST['task']!="refresh") or (!$_CONFIG['refresh_mode'])))
|
81 |
+
HTML_cloner::header();
|
82 |
+
|
83 |
+
|
84 |
+
//########## SETTING THE GLOBALS VARIABLES #########################
|
85 |
+
|
86 |
+
$GLOBALS['joomla_compatible'] = $joomla_compatible;
|
87 |
+
|
88 |
+
$GLOBALS['_CONFIG'] = $_CONFIG;
|
89 |
+
|
90 |
+
$GLOBALS['clonerPath'] = $clonerPath;
|
91 |
+
|
92 |
+
$GLOBALS['baDownloadPath'] = $baDownloadPath;
|
93 |
+
|
94 |
+
$GLOBALS['config_file'] = $config_file;
|
95 |
+
|
96 |
+
$GLOBALS['lang_array'] = $lang_array;
|
97 |
+
|
98 |
+
openXLog();
|
99 |
+
|
100 |
+
// process the workflow selection
|
101 |
+
switch ($task) {
|
102 |
+
case 'rename_save':
|
103 |
+
case 'rename':
|
104 |
+
clone_rename($option);
|
105 |
+
break;
|
106 |
+
case 'action':
|
107 |
+
action($option);
|
108 |
+
break;
|
109 |
+
|
110 |
+
|
111 |
+
case 'cancel_lang':
|
112 |
+
mosRedirect('index2.php?option=' . $option . "&task=lang");
|
113 |
+
break;
|
114 |
+
case 'add_lang':
|
115 |
+
case 'add_lang_new':
|
116 |
+
translator_add($option, $task);
|
117 |
+
break;
|
118 |
+
case 'save_lang_apply':
|
119 |
+
case 'save_lang':
|
120 |
+
case 'edit_lang':
|
121 |
+
translator_edit($option, $task);
|
122 |
+
break;
|
123 |
+
|
124 |
+
|
125 |
+
case 'del_lang':
|
126 |
+
case 'lang':
|
127 |
+
translator($option);
|
128 |
+
break;
|
129 |
+
|
130 |
+
case 'recurse_files':
|
131 |
+
goRecurseFiles();
|
132 |
+
break;
|
133 |
+
|
134 |
+
case 'refresh':
|
135 |
+
generateBackuprefresh($cid, $option, $_REQUEST['backup'], $_CONFIG['refresh_mode']);
|
136 |
+
break;
|
137 |
+
|
138 |
+
case 'generate':
|
139 |
+
generateBackup($cid, $option);
|
140 |
+
break;
|
141 |
+
|
142 |
+
case 'confirm':
|
143 |
+
deleteXLog();
|
144 |
+
confirmBackup($option);
|
145 |
+
break;
|
146 |
+
case 'download':
|
147 |
+
downloadBackup($_REQUEST[file]);
|
148 |
+
break;
|
149 |
+
case 'cron':
|
150 |
+
HTML_cloner::Cron();
|
151 |
+
break;
|
152 |
+
case 'about':
|
153 |
+
case 'credits':
|
154 |
+
showHelp($option);
|
155 |
+
break;
|
156 |
+
case 'restore':
|
157 |
+
HTML_cloner::Restore($option);
|
158 |
+
break;
|
159 |
+
|
160 |
+
case 'cron_delete':
|
161 |
+
if (unlink($_CONFIG['multiple_config_dir'] . "/" . $_REQUEST['fconfig']))
|
162 |
+
$msg = " was deleted";
|
163 |
+
else
|
164 |
+
$msg = " was not deleted, please delete it manually!";
|
165 |
+
|
166 |
+
mosRedirect('index2.php?option=' . $option . "&task=config", $_REQUEST['fconfig'] . $msg);
|
167 |
+
break;
|
168 |
+
|
169 |
+
case 'remove':
|
170 |
+
deleteBackups($cid, $option);
|
171 |
+
break;
|
172 |
+
case 'continue':
|
173 |
+
case 'move':
|
174 |
+
case 'clone':
|
175 |
+
moveBackup($option);
|
176 |
+
break;
|
177 |
+
|
178 |
+
case 'cancel':
|
179 |
+
mosRedirect('index2.php?option=' . $option);
|
180 |
+
break;
|
181 |
+
case 'config':
|
182 |
+
config($option);
|
183 |
+
break;
|
184 |
+
case 'rename_cancel':
|
185 |
+
mosRedirect('index2.php?option=' . $option . "&task=view");
|
186 |
+
break;
|
187 |
+
case 'show':
|
188 |
+
case 'view':
|
189 |
+
showBackups($option);
|
190 |
+
break;
|
191 |
+
case 'logout':
|
192 |
+
doLogout();
|
193 |
+
break;
|
194 |
+
default:
|
195 |
+
fdefault();
|
196 |
+
break;
|
197 |
+
}
|
198 |
+
|
199 |
+
closeXLog();
|
200 |
+
|
201 |
+
HTML_cloner::footer();
|
202 |
?>
|
admin.xcloner-backupandrestore.php
DELETED
@@ -1,5 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
print "<iframe src='components/com_xcloner-backupandrestore/index.php' width='100%' height='900' frameborder=0 marginWidth=0 frameSpacing=0 marginHeight=110 ></iframe>";
|
4 |
-
|
5 |
-
?>
|
|
|
|
|
|
|
|
|
|
classes/error.class.php → administrator/backups/.excl
RENAMED
File without changes
|
browser/files_inpage.php
CHANGED
@@ -1,25 +1,18 @@
|
|
1 |
<?php
|
2 |
@ini_set("error_reporting", "2");
|
3 |
|
4 |
-
define("_VALID_MOS", 1);
|
5 |
-
|
6 |
$thisApp=$_SERVER['PHP_SELF'] . "?browse=true";
|
7 |
|
8 |
-
$fp = @fopen($_CONFIG['exfile'], "w");
|
9 |
-
if($fp){
|
10 |
-
@fwrite($fp, $_CONFIG['cron_exclude']);
|
11 |
-
@fclose($fp);
|
12 |
-
}
|
13 |
-
|
14 |
if(isset($_GET['browse'])){
|
15 |
$dir = isset($_GET['dir']) ? $_GET['dir'] : '/files';
|
16 |
if(strpos($dir, "../")===true){
|
17 |
exit;
|
18 |
-
|
|
|
19 |
}else{
|
20 |
|
21 |
echo "Please wait... we are loading the folder structure";
|
22 |
|
23 |
}
|
24 |
|
25 |
-
?>
|
1 |
<?php
|
2 |
@ini_set("error_reporting", "2");
|
3 |
|
|
|
|
|
4 |
$thisApp=$_SERVER['PHP_SELF'] . "?browse=true";
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
if(isset($_GET['browse'])){
|
7 |
$dir = isset($_GET['dir']) ? $_GET['dir'] : '/files';
|
8 |
if(strpos($dir, "../")===true){
|
9 |
exit;
|
10 |
+
}
|
11 |
+
|
12 |
}else{
|
13 |
|
14 |
echo "Please wait... we are loading the folder structure";
|
15 |
|
16 |
}
|
17 |
|
18 |
+
?>
|
browser/files_xml.php
CHANGED
@@ -10,17 +10,9 @@
|
|
10 |
* Date: November 2010
|
11 |
**/
|
12 |
|
13 |
-
define("_VALID_MOS", 1);
|
14 |
-
|
15 |
-
session_start();
|
16 |
-
if(!isset($_SESSION['clone'])){
|
17 |
-
echo "Not Authorized";
|
18 |
-
exit;
|
19 |
-
}
|
20 |
-
|
21 |
header("Cache-Control: no-cache");
|
22 |
header("Pragma: nocache");
|
23 |
-
header("Content-Type: text/xml
|
24 |
|
25 |
error_reporting(2);
|
26 |
|
@@ -30,7 +22,7 @@ if($_COOKIE["auth_clone"] != 1){
|
|
30 |
exit;
|
31 |
}
|
32 |
|
33 |
-
|
34 |
include("../cloner.config.php");
|
35 |
include("../common.php");
|
36 |
|
@@ -53,15 +45,15 @@ $path = $_REQUEST['path'];
|
|
53 |
$loc = $_REQUEST['dir'];
|
54 |
|
55 |
if(!is_dir($_CONFIG['backup_path'])){
|
56 |
-
|
57 |
echo "<directory location=\"Error: Directory $_CONFIG[backup_path] does not exist!\"></directory>";
|
58 |
exit;
|
59 |
-
|
60 |
}elseif(!is_readable($_CONFIG['backup_path'])){
|
61 |
-
|
62 |
echo "<directory location=\"Error: Directory $_CONFIG[backup_path] is not readable!\"></directory>";
|
63 |
exit;
|
64 |
-
|
65 |
}
|
66 |
|
67 |
|
@@ -78,8 +70,8 @@ elseif($_REQUEST['act'] == "uncheckall"){
|
|
78 |
|
79 |
if($loc == "")
|
80 |
$loc = "/";
|
81 |
-
|
82 |
-
|
83 |
$data = "";
|
84 |
|
85 |
if($fp = @fopen($exfile,"r")){
|
@@ -92,6 +84,7 @@ fclose($fp);
|
|
92 |
$_COOKIES = explode("\r\n", $data);
|
93 |
|
94 |
|
|
|
95 |
$exc = 0;
|
96 |
|
97 |
if($fp = @fopen($exfile,"w")){
|
@@ -134,10 +127,10 @@ fclose($fp);
|
|
134 |
|
135 |
}
|
136 |
else{
|
137 |
-
|
138 |
echo "<directory location=\"Error: Unable to write to file $exfile\"></directory>";
|
139 |
exit;
|
140 |
-
|
141 |
}
|
142 |
|
143 |
$_COOKIES = explode("\r\n", $data);
|
@@ -194,7 +187,7 @@ sort($exclude);
|
|
194 |
$check = 'checked';
|
195 |
else
|
196 |
$check = '';
|
197 |
-
|
198 |
echo "<file check='$check' link=\"#\">".htmlspecialchars($file)."</file>";
|
199 |
|
200 |
}
|
@@ -209,7 +202,7 @@ sort($exclude);
|
|
209 |
|
210 |
function check($loc, $exfile, $act ){
|
211 |
global $_CONFIG;
|
212 |
-
|
213 |
$fulldir = $loc;
|
214 |
$flist = array();
|
215 |
$_COOKIES = array();
|
@@ -242,7 +235,7 @@ function check($loc, $exfile, $act ){
|
|
242 |
if($act == 1){
|
243 |
|
244 |
$flist = @array_merge($_COOKIES, $flist);
|
245 |
-
|
246 |
}
|
247 |
else{
|
248 |
|
10 |
* Date: November 2010
|
11 |
**/
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
header("Cache-Control: no-cache");
|
14 |
header("Pragma: nocache");
|
15 |
+
header("Content-Type: text/xml");
|
16 |
|
17 |
error_reporting(2);
|
18 |
|
22 |
exit;
|
23 |
}
|
24 |
|
25 |
+
|
26 |
include("../cloner.config.php");
|
27 |
include("../common.php");
|
28 |
|
45 |
$loc = $_REQUEST['dir'];
|
46 |
|
47 |
if(!is_dir($_CONFIG['backup_path'])){
|
48 |
+
|
49 |
echo "<directory location=\"Error: Directory $_CONFIG[backup_path] does not exist!\"></directory>";
|
50 |
exit;
|
51 |
+
|
52 |
}elseif(!is_readable($_CONFIG['backup_path'])){
|
53 |
+
|
54 |
echo "<directory location=\"Error: Directory $_CONFIG[backup_path] is not readable!\"></directory>";
|
55 |
exit;
|
56 |
+
|
57 |
}
|
58 |
|
59 |
|
70 |
|
71 |
if($loc == "")
|
72 |
$loc = "/";
|
73 |
+
|
74 |
+
|
75 |
$data = "";
|
76 |
|
77 |
if($fp = @fopen($exfile,"r")){
|
84 |
$_COOKIES = explode("\r\n", $data);
|
85 |
|
86 |
|
87 |
+
|
88 |
$exc = 0;
|
89 |
|
90 |
if($fp = @fopen($exfile,"w")){
|
127 |
|
128 |
}
|
129 |
else{
|
130 |
+
|
131 |
echo "<directory location=\"Error: Unable to write to file $exfile\"></directory>";
|
132 |
exit;
|
133 |
+
|
134 |
}
|
135 |
|
136 |
$_COOKIES = explode("\r\n", $data);
|
187 |
$check = 'checked';
|
188 |
else
|
189 |
$check = '';
|
190 |
+
|
191 |
echo "<file check='$check' link=\"#\">".htmlspecialchars($file)."</file>";
|
192 |
|
193 |
}
|
202 |
|
203 |
function check($loc, $exfile, $act ){
|
204 |
global $_CONFIG;
|
205 |
+
|
206 |
$fulldir = $loc;
|
207 |
$flist = array();
|
208 |
$_COOKIES = array();
|
235 |
if($act == 1){
|
236 |
|
237 |
$flist = @array_merge($_COOKIES, $flist);
|
238 |
+
|
239 |
}
|
240 |
else{
|
241 |
|
browser/xmlhttp.js
CHANGED
@@ -35,7 +35,7 @@ function processXMLRequest() {
|
|
35 |
|
36 |
function do_browser(){
|
37 |
targetDiv=document.getElementById("browser");
|
38 |
-
|
39 |
if(loadXMLDoc("browser/files_xml.php")){
|
40 |
targetDiv.className="searching";
|
41 |
targetDiv.innerHTML="";
|
@@ -102,7 +102,7 @@ function checkc(value){
|
|
102 |
function useXML(xmlInfo){
|
103 |
targetDiv.className="";
|
104 |
message = "";
|
105 |
-
|
106 |
var infoTags=xmlInfo.getElementsByTagName("directory");
|
107 |
var loc=infoTags[0].getAttribute("location");
|
108 |
if(loc == "")
|
@@ -124,11 +124,11 @@ function useXML(xmlInfo){
|
|
124 |
|
125 |
var newloc="browser/files_xml.php?dir=" + loc ;
|
126 |
path = loc+"/"+node.firstChild.nodeValue;
|
127 |
-
|
128 |
if(node.nodeName=="file"){
|
129 |
|
130 |
stringHTML=stringHTML+"<li class=\"file\"><img src='browser/file.gif' border='0'><input type=checkbox "+node.getAttribute('check')+" onclick=\"loadXMLDoc('" + newloc +"&path="+path+"')\" name=cid[] value='"+path+"'><a href=\"" +node.getAttribute('link')+ "\">"+node.firstChild.nodeValue+"</a></li>";
|
131 |
-
|
132 |
}
|
133 |
if(node.nodeName=="message"){
|
134 |
|
@@ -150,5 +150,5 @@ function useXML(xmlInfo){
|
|
150 |
}
|
151 |
|
152 |
//stringHTML = stringHTML+ "</form>";
|
153 |
-
targetDiv.innerHTML= "<table align='right' width='
|
154 |
}
|
35 |
|
36 |
function do_browser(){
|
37 |
targetDiv=document.getElementById("browser");
|
38 |
+
|
39 |
if(loadXMLDoc("browser/files_xml.php")){
|
40 |
targetDiv.className="searching";
|
41 |
targetDiv.innerHTML="";
|
102 |
function useXML(xmlInfo){
|
103 |
targetDiv.className="";
|
104 |
message = "";
|
105 |
+
|
106 |
var infoTags=xmlInfo.getElementsByTagName("directory");
|
107 |
var loc=infoTags[0].getAttribute("location");
|
108 |
if(loc == "")
|
124 |
|
125 |
var newloc="browser/files_xml.php?dir=" + loc ;
|
126 |
path = loc+"/"+node.firstChild.nodeValue;
|
127 |
+
|
128 |
if(node.nodeName=="file"){
|
129 |
|
130 |
stringHTML=stringHTML+"<li class=\"file\"><img src='browser/file.gif' border='0'><input type=checkbox "+node.getAttribute('check')+" onclick=\"loadXMLDoc('" + newloc +"&path="+path+"')\" name=cid[] value='"+path+"'><a href=\"" +node.getAttribute('link')+ "\">"+node.firstChild.nodeValue+"</a></li>";
|
131 |
+
|
132 |
}
|
133 |
if(node.nodeName=="message"){
|
134 |
|
150 |
}
|
151 |
|
152 |
//stringHTML = stringHTML+ "</form>";
|
153 |
+
targetDiv.innerHTML= "<table align='right' width='200'><tr><td align='right'><b>" + "Excluded items list:" + "</b><br />"+ message+"</td></tr></table>" + stringHTML ;
|
154 |
}
|
classes/S3.php
CHANGED
@@ -28,9 +28,6 @@
|
|
28 |
* Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
|
29 |
*/
|
30 |
|
31 |
-
/** ensure this file is being included by a parent file */
|
32 |
-
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
|
33 |
-
|
34 |
/**
|
35 |
* Amazon S3 PHP class
|
36 |
*
|
@@ -797,7 +794,7 @@ class S3 {
|
|
797 |
}
|
798 |
array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
|
799 |
$policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
|
800 |
-
|
801 |
// Create parameters
|
802 |
$params = new stdClass;
|
803 |
$params->AWSAccessKeyId = self::$__accessKey;
|
28 |
* Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
|
29 |
*/
|
30 |
|
|
|
|
|
|
|
31 |
/**
|
32 |
* Amazon S3 PHP class
|
33 |
*
|
794 |
}
|
795 |
array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
|
796 |
$policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
|
797 |
+
|
798 |
// Create parameters
|
799 |
$params = new stdClass;
|
800 |
$params->AWSAccessKeyId = self::$__accessKey;
|
classes/fileRecursion.php
CHANGED
@@ -27,7 +27,6 @@ class fileRecursion{
|
|
27 |
|
28 |
private static $fp;
|
29 |
private static $fpd;
|
30 |
-
private static $fpe;
|
31 |
private static $d_arr;
|
32 |
private static $f_arr;
|
33 |
private static $BACKUP_EXTENSIONS = array("tar", "zip", "tgz", "tar.gz");
|
@@ -40,22 +39,17 @@ class fileRecursion{
|
|
40 |
public static $TEMP_EXCL = "tmp/.excl";
|
41 |
public static $TEMP_DIR = "/opt/lampp/htdocs/joomla/administrator/backups"; //exclude other backups
|
42 |
public static $START_DIR = "/"; # Backups Start Dir
|
43 |
-
public static $EXCLUDE_FILES_SIZE = -1; //disabled
|
44 |
-
public static $TEMP_OVERSIZED_FILE = "tmp/.oversized_files";
|
45 |
|
46 |
|
47 |
|
48 |
-
public static function setData($
|
49 |
|
50 |
-
self::$TEMP_PERM
|
51 |
-
self::$TEMP_EXCL
|
52 |
-
self::$TEMP_D_ARR
|
53 |
-
self::$TEMP_DIR
|
54 |
-
self::$START_DIR
|
55 |
-
self::$EXCLUDE_FILES_SIZE = $data['EXCLUDE_FILES_SIZE'];
|
56 |
-
self::$TEMP_OVERSIZED_FILE = $data['TEMP_OVERSIZED_FILE'];
|
57 |
}
|
58 |
-
|
59 |
/*
|
60 |
* Init the recursion system
|
61 |
* name: init
|
@@ -80,7 +74,6 @@ class fileRecursion{
|
|
80 |
|
81 |
self::$fp = fopen(self::$TEMP_PERM, "a");
|
82 |
self::$fpd = fopen(self::$TEMP_D_ARR, "w");
|
83 |
-
self::$fpe = fopen(self::$TEMP_OVERSIZED_FILE, "a");
|
84 |
|
85 |
self::initEXCL();
|
86 |
|
@@ -91,20 +84,6 @@ class fileRecursion{
|
|
91 |
|
92 |
}
|
93 |
|
94 |
-
/*
|
95 |
-
* We close the stuff left opened
|
96 |
-
* name: close
|
97 |
-
* @param
|
98 |
-
* @return
|
99 |
-
*/
|
100 |
-
public static function close(){
|
101 |
-
|
102 |
-
@fclose(self::$fp );
|
103 |
-
@fclose(self::$fpd );
|
104 |
-
@fclose(self::$fpe );
|
105 |
-
|
106 |
-
}
|
107 |
-
|
108 |
/*
|
109 |
* Count the number of files saved in TEMP_PERM
|
110 |
* name: countPermFiles
|
@@ -348,23 +327,6 @@ class fileRecursion{
|
|
348 |
|
349 |
}
|
350 |
|
351 |
-
public static function getOverLimitFiles(){
|
352 |
-
@fclose(self::$fpe);
|
353 |
-
$files = explode("\n", file_get_contents(self::$TEMP_OVERSIZED_FILE));
|
354 |
-
|
355 |
-
return array_diff($files, array(""));
|
356 |
-
}
|
357 |
-
|
358 |
-
public static function writeExcludedFile($file, $fsize = 0){
|
359 |
-
|
360 |
-
self::debug("Excluded $file from list as it is bigger than ". self::$EXCLUDE_FILES_SIZE." MB!!!");
|
361 |
-
|
362 |
-
if(self::$fpe){
|
363 |
-
fwrite(self::$fpe, $file."\t(".$fsize." bytes)\n");
|
364 |
-
}
|
365 |
-
|
366 |
-
}
|
367 |
-
|
368 |
/*
|
369 |
* Writing file details(path, permissions, size) to file
|
370 |
*
|
@@ -376,23 +338,12 @@ class fileRecursion{
|
|
376 |
public static function writePermFile($file, $append = "", $force = 0){
|
377 |
|
378 |
$file = realpath($file);
|
379 |
-
|
380 |
if((self::isNotExcluded($file)) or ($force)){
|
381 |
-
// we check if file is not excluded
|
382 |
$fperm = substr(sprintf('%o', @fileperms($file)), -4);
|
383 |
$fsize = self::getFileSize($file);
|
384 |
-
|
385 |
-
|
386 |
-
if(intval(self::$EXCLUDE_FILES_SIZE) > -1){
|
387 |
-
if(($fsize > $sizeLimit) and is_file($file)){
|
388 |
-
//we check if file is larger than $EXCLUDE_FILES_SIZE
|
389 |
-
self::writeExcludedFile($file, $fsize);
|
390 |
-
return;
|
391 |
-
}
|
392 |
-
}
|
393 |
-
|
394 |
$file = str_replace(self::$START_DIR, "", str_replace("\\","/", $file));
|
395 |
-
|
396 |
fwrite(self::$fp, $file."|".$fperm."|".$fsize."|".$append."\n");
|
397 |
self::debug($file ." added to list");
|
398 |
}
|
27 |
|
28 |
private static $fp;
|
29 |
private static $fpd;
|
|
|
30 |
private static $d_arr;
|
31 |
private static $f_arr;
|
32 |
private static $BACKUP_EXTENSIONS = array("tar", "zip", "tgz", "tar.gz");
|
39 |
public static $TEMP_EXCL = "tmp/.excl";
|
40 |
public static $TEMP_DIR = "/opt/lampp/htdocs/joomla/administrator/backups"; //exclude other backups
|
41 |
public static $START_DIR = "/"; # Backups Start Dir
|
|
|
|
|
42 |
|
43 |
|
44 |
|
45 |
+
public static function setData($TEMP_PERM,$TEMP_EXCL,$TEMP_D_ARR,$TEMP_DIR, $START_DIR) {
|
46 |
|
47 |
+
self::$TEMP_PERM = $TEMP_PERM;
|
48 |
+
self::$TEMP_EXCL = $TEMP_EXCL;
|
49 |
+
self::$TEMP_D_ARR = $TEMP_D_ARR;
|
50 |
+
self::$TEMP_DIR = $TEMP_DIR;
|
51 |
+
self::$START_DIR = $START_DIR;
|
|
|
|
|
52 |
}
|
|
|
53 |
/*
|
54 |
* Init the recursion system
|
55 |
* name: init
|
74 |
|
75 |
self::$fp = fopen(self::$TEMP_PERM, "a");
|
76 |
self::$fpd = fopen(self::$TEMP_D_ARR, "w");
|
|
|
77 |
|
78 |
self::initEXCL();
|
79 |
|
84 |
|
85 |
}
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
/*
|
88 |
* Count the number of files saved in TEMP_PERM
|
89 |
* name: countPermFiles
|
327 |
|
328 |
}
|
329 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
/*
|
331 |
* Writing file details(path, permissions, size) to file
|
332 |
*
|
338 |
public static function writePermFile($file, $append = "", $force = 0){
|
339 |
|
340 |
$file = realpath($file);
|
|
|
341 |
if((self::isNotExcluded($file)) or ($force)){
|
|
|
342 |
$fperm = substr(sprintf('%o', @fileperms($file)), -4);
|
343 |
$fsize = self::getFileSize($file);
|
344 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
345 |
$file = str_replace(self::$START_DIR, "", str_replace("\\","/", $file));
|
346 |
+
|
347 |
fwrite(self::$fp, $file."|".$fperm."|".$fsize."|".$append."\n");
|
348 |
self::debug($file ." added to list");
|
349 |
}
|
classes/index.html
CHANGED
File without changes
|
classes/main.class.php
DELETED
@@ -1,116 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* main.class.php
|
4 |
-
*
|
5 |
-
* Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
class Main{
|
24 |
-
|
25 |
-
public static $_CONFIG;
|
26 |
-
|
27 |
-
|
28 |
-
/*
|
29 |
-
*
|
30 |
-
* name: init
|
31 |
-
* @param
|
32 |
-
* @return
|
33 |
-
*/
|
34 |
-
public static function init($_CONFIG){
|
35 |
-
self::$_CONFIG = $_CONFIG;
|
36 |
-
}
|
37 |
-
|
38 |
-
/*
|
39 |
-
*
|
40 |
-
* name: unknown
|
41 |
-
* @param
|
42 |
-
* @return
|
43 |
-
*/
|
44 |
-
public static function initBackup($backupName){
|
45 |
-
|
46 |
-
self::generateBackupName($backupName);
|
47 |
-
|
48 |
-
}
|
49 |
-
|
50 |
-
/*
|
51 |
-
* Will cleanup the temporary directory
|
52 |
-
*
|
53 |
-
* name: cleanUp
|
54 |
-
* @param
|
55 |
-
* @return
|
56 |
-
*/
|
57 |
-
public static function cleanUp(){
|
58 |
-
|
59 |
-
$dir = self::$_CONFIG['temp_dir'] ;
|
60 |
-
|
61 |
-
if (@is_dir($dir)) {
|
62 |
-
if ($dh = @opendir($dir)) {
|
63 |
-
while (($file = @readdir($dh)) !== false) {
|
64 |
-
if(($file!=".") and ($file!="..")){
|
65 |
-
if(($file[0] == ".") and ($file[0] != ".htaccess"))
|
66 |
-
//cleanup temp files
|
67 |
-
@unlink($dir."/".$file);
|
68 |
-
elseif(strstr( $file, "-sql.sql") != "")
|
69 |
-
//cleanup sql files
|
70 |
-
@unlink($dir."/".$file);
|
71 |
-
|
72 |
-
}
|
73 |
-
}
|
74 |
-
closedir($dh);
|
75 |
-
}
|
76 |
-
}
|
77 |
-
|
78 |
-
}
|
79 |
-
|
80 |
-
public static function generateBackupName($backupName, $backupDatabase = 0, $dbbackup_drop = 0){
|
81 |
-
|
82 |
-
$domainname = $_SERVER['HTTP_HOST'];
|
83 |
-
|
84 |
-
if ((self::$_CONFIG['mem']) && ($_CONFIG['backup_refresh'])) {
|
85 |
-
$f_ext = '.tar';
|
86 |
-
$_CONFIG['tarcompress'] = '';
|
87 |
-
} elseif (self::$_CONFIG['backup_compress']) {
|
88 |
-
$f_ext = '.tgz';
|
89 |
-
$_CONFIG['tarcompress'] = 'z';
|
90 |
-
} else {
|
91 |
-
$f_ext = '.tar';
|
92 |
-
$_CONFIG['tarcompress'] = '';
|
93 |
-
}
|
94 |
-
|
95 |
-
|
96 |
-
if ($backupName == "") {
|
97 |
-
if ($backupDatabase == 1) {
|
98 |
-
if ($_REQUEST['dbbackup_drop']) {
|
99 |
-
$filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-sql-drop' . $f_ext;
|
100 |
-
} else {
|
101 |
-
$filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-sql-nodrop' . $f_ext;
|
102 |
-
}
|
103 |
-
} else
|
104 |
-
$filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-nosql' . $f_ext;
|
105 |
-
} else {
|
106 |
-
$filename = $_REQUEST['bname'] . $f_ext;
|
107 |
-
}
|
108 |
-
|
109 |
-
return $filename;
|
110 |
-
|
111 |
-
}
|
112 |
-
|
113 |
-
}
|
114 |
-
|
115 |
-
|
116 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/mysqlBackup.class.php
DELETED
@@ -1,488 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* mysqlBackup.class.php
|
4 |
-
*
|
5 |
-
* Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
|
24 |
-
class DB{
|
25 |
-
|
26 |
-
public static $dbHostname = "localhost";
|
27 |
-
public static $dbUsername = "root";
|
28 |
-
public static $dbPassword = "";
|
29 |
-
public static $dbDatabase = "";
|
30 |
-
public static $excludedTables = array();
|
31 |
-
|
32 |
-
public static $debug = 0;
|
33 |
-
public static $recordsPerSession = 10000;
|
34 |
-
public static $dbCompatibility = "";
|
35 |
-
public static $dbDropSyntax = 0;
|
36 |
-
public static $countRecords = 0;
|
37 |
-
|
38 |
-
private static $link;
|
39 |
-
private static $db_selected;
|
40 |
-
|
41 |
-
public static $TEMP_DBPROCESS_FILE = "tmp/.database";
|
42 |
-
public static $TEMP_DUMP_FILE = "tmp/database-sql.sql";
|
43 |
-
|
44 |
-
/*
|
45 |
-
*Return any error
|
46 |
-
*
|
47 |
-
* name: error
|
48 |
-
* @param string $message
|
49 |
-
* @return
|
50 |
-
*/
|
51 |
-
public function error($message, $force = ""){
|
52 |
-
|
53 |
-
$return = "";
|
54 |
-
$date = date("M j, Y @ H:i:s");
|
55 |
-
|
56 |
-
if((self::$debug) && ($force)){
|
57 |
-
//we have debug message as force is 1
|
58 |
-
printf("Debug(%s) - %s \n", $date, $message);
|
59 |
-
}
|
60 |
-
|
61 |
-
if(!$force){
|
62 |
-
//we have an error message
|
63 |
-
printf("Error(%s) - %s \n", $date, $message);
|
64 |
-
}
|
65 |
-
|
66 |
-
return;
|
67 |
-
|
68 |
-
}
|
69 |
-
|
70 |
-
/*
|
71 |
-
* Initialize the database connection
|
72 |
-
*
|
73 |
-
* name: init
|
74 |
-
* @param array $data {'dbHostname', 'dbUsername', 'dbPassword', 'dbDatabase'}
|
75 |
-
* @return
|
76 |
-
*/
|
77 |
-
public function init($data, $start = 0){
|
78 |
-
|
79 |
-
self::$dbHostname = $data['dbHostname'];
|
80 |
-
self::$dbUsername = $data['dbUsername'];
|
81 |
-
self::$dbPassword = $data['dbPassword'];
|
82 |
-
self::$dbDatabase = $data['dbDatabase'];
|
83 |
-
self::$excludedTables = $data['excludedTables'];
|
84 |
-
self::$TEMP_DBPROCESS_FILE = $data['TEMP_DBPROCESS_FILE'];
|
85 |
-
self::$TEMP_DUMP_FILE = $data['TEMP_DUMP_FILE'];
|
86 |
-
self::$recordsPerSession = $data['recordsPerSession'];
|
87 |
-
self::$dbCompatibility = $data['dbCompatibility'];
|
88 |
-
self::$dbDropSyntax = $data['dbDropSyntax'];
|
89 |
-
|
90 |
-
self::connect();
|
91 |
-
self::headers();
|
92 |
-
|
93 |
-
if($start){
|
94 |
-
@unlink(self::$TEMP_DBPROCESS_FILE);
|
95 |
-
}
|
96 |
-
|
97 |
-
}
|
98 |
-
|
99 |
-
/*
|
100 |
-
* Connect to the database
|
101 |
-
*
|
102 |
-
* name: connect
|
103 |
-
* @param
|
104 |
-
* @return
|
105 |
-
*/
|
106 |
-
public function connect(){
|
107 |
-
|
108 |
-
self::$link = mysql_connect(self::$dbHostname, self::$dbUsername, self::$dbPassword);
|
109 |
-
if (!self::$link) {
|
110 |
-
self::error('Could not connect: ' . mysql_error());
|
111 |
-
}
|
112 |
-
|
113 |
-
if(self::$dbDatabase != ""){
|
114 |
-
self::$db_selected = mysql_select_db(self::$dbDatabase, self::$link);
|
115 |
-
if (!self::$db_selected) {
|
116 |
-
self::error ('Can\'t use foo : ' . mysql_error());
|
117 |
-
}
|
118 |
-
}
|
119 |
-
|
120 |
-
}
|
121 |
-
|
122 |
-
/*
|
123 |
-
* Disconnect from the database
|
124 |
-
*
|
125 |
-
* name: disconnect
|
126 |
-
* @param
|
127 |
-
* @return
|
128 |
-
*/
|
129 |
-
public function disconnect(){
|
130 |
-
|
131 |
-
mysql_close(self::$link);
|
132 |
-
|
133 |
-
}
|
134 |
-
|
135 |
-
/*
|
136 |
-
* Send some special headers after the connection is initialized
|
137 |
-
*
|
138 |
-
* name: headers
|
139 |
-
* @param
|
140 |
-
* @return
|
141 |
-
*/
|
142 |
-
private function headers(){
|
143 |
-
|
144 |
-
self::query("SET SQL_QUOTE_SHOW_CREATE=1;");
|
145 |
-
self::query("SET sql_mode = 0;");
|
146 |
-
mysql_set_charset('utf8', self::$link);
|
147 |
-
if (self::$dbCompatibility)
|
148 |
-
self::query("SET sql_mode=" . self::$dbCompatibility . ";");
|
149 |
-
|
150 |
-
}
|
151 |
-
|
152 |
-
/*
|
153 |
-
* Run a mysql qeury
|
154 |
-
*
|
155 |
-
* name: query
|
156 |
-
* @param string $query Query to run
|
157 |
-
* @return $result or false
|
158 |
-
*/
|
159 |
-
public function query($query){
|
160 |
-
|
161 |
-
$result = mysql_query($query.";", self::$link);
|
162 |
-
self::error($query, 1);
|
163 |
-
|
164 |
-
if (!$result) {
|
165 |
-
self::error('Invalid query: ' . mysql_error());
|
166 |
-
return false;
|
167 |
-
}
|
168 |
-
else{
|
169 |
-
return $result;
|
170 |
-
}
|
171 |
-
|
172 |
-
}
|
173 |
-
|
174 |
-
|
175 |
-
/*
|
176 |
-
* Returns an array of tables from a database and mark $2excluded ones
|
177 |
-
*
|
178 |
-
* name: lisTables
|
179 |
-
* @param array $excluded array of tables to mark as excluded
|
180 |
-
* @return array $tablesList
|
181 |
-
*/
|
182 |
-
public function listTables($excluded){
|
183 |
-
|
184 |
-
$tablesList = array("");
|
185 |
-
$inc = 0;
|
186 |
-
|
187 |
-
$result = self::query("SHOW TABLES in `".self::$dbDatabase."`");
|
188 |
-
|
189 |
-
while ($row = mysql_fetch_array($result)){
|
190 |
-
$tablesList[$inc]['table'] = $row[0];
|
191 |
-
|
192 |
-
if(is_array($excluded))
|
193 |
-
if( in_array($row[0], $excluded) )
|
194 |
-
$tablesList[$inc]['excluded'] = 1;
|
195 |
-
$inc++;
|
196 |
-
}
|
197 |
-
|
198 |
-
return $tablesList;
|
199 |
-
|
200 |
-
}
|
201 |
-
|
202 |
-
public function writeTempFile(){
|
203 |
-
|
204 |
-
$tables = self::listTables(self::$excludedTables);
|
205 |
-
|
206 |
-
$fp = fopen(self::$TEMP_DBPROCESS_FILE, "a");
|
207 |
-
|
208 |
-
if($fp){
|
209 |
-
|
210 |
-
fwrite($fp, sprintf("###newdump###\t%s\t%s\n", self::$dbDatabase, self::$TEMP_DUMP_FILE));
|
211 |
-
|
212 |
-
// write this to the class and write to $TEMP_DBPROCESS_FILE file as database.table records
|
213 |
-
foreach($tables as $key=>$table) if($table!= ""){
|
214 |
-
|
215 |
-
$tables[$key]['records'] = 0;
|
216 |
-
|
217 |
-
if(!$tables[$key]['excluded'])
|
218 |
-
$tables[$key]['records'] = self::countRecords($tables[$key]['table']);
|
219 |
-
|
220 |
-
$tmp = sprintf("`%s`.`%s`\t%s\t%s\n", self::$dbDatabase, $tables[$key]['table'], $tables[$key]['records'], $tables[$key]['excluded']);
|
221 |
-
fwrite($fp, $tmp);
|
222 |
-
}
|
223 |
-
|
224 |
-
fwrite($fp, "###enddump###\n");
|
225 |
-
fclose($fp);
|
226 |
-
}
|
227 |
-
else{
|
228 |
-
self::error("Unable to open for writing file ".self::$TEMP_DBPROCESS_FILE);
|
229 |
-
}
|
230 |
-
|
231 |
-
}
|
232 |
-
|
233 |
-
/*
|
234 |
-
* Returns the number of records from a table
|
235 |
-
*
|
236 |
-
* name: countRecords
|
237 |
-
* @param string $table - the source table
|
238 |
-
* @return int $count
|
239 |
-
*/
|
240 |
-
public function countRecords($table){
|
241 |
-
|
242 |
-
$table = "`".self::$dbDatabase."`.`$table`";
|
243 |
-
|
244 |
-
$result = self::query("SELECT count(*) FROM $table;");
|
245 |
-
|
246 |
-
$count = mysql_fetch_row($result);
|
247 |
-
|
248 |
-
return intval($count[0]) ;// not max limit on 32 bit systems 2147483647; on 64 bit 9223372036854775807
|
249 |
-
|
250 |
-
}
|
251 |
-
|
252 |
-
/*
|
253 |
-
* Processing the mysql backup incrementally
|
254 |
-
*
|
255 |
-
* name: processIncremental
|
256 |
-
* @param
|
257 |
-
* int $startAtLine - at which line from the perm.txt file to start reading
|
258 |
-
* int startAtRecord - at which record to start from the table found at $startAtLine
|
259 |
-
* string $dumpfie - where to save the data
|
260 |
-
* string $dbCompatibility - MYSQL40, MYSQ32, none=default
|
261 |
-
* int $dbDropSyntax - check if the DROP TABLE syntax should be added
|
262 |
-
* @return array $return
|
263 |
-
*/
|
264 |
-
public function processIncremental($startAtLine= 0, $startAtRecord = 0, $dumpfile = "", $dbCompatibility= "", $dbDropSyntax= ""){
|
265 |
-
|
266 |
-
$count = 0;
|
267 |
-
$return = array();
|
268 |
-
|
269 |
-
self::error("Starting new process at line $startAtLine from record $startAtRecord", 1);
|
270 |
-
|
271 |
-
$fp = fopen(self::$TEMP_DBPROCESS_FILE, "r");
|
272 |
-
if($fp){
|
273 |
-
|
274 |
-
while (($buffer = fgets($fp, 4096)) !== false){
|
275 |
-
|
276 |
-
if($count == $startAtLine){
|
277 |
-
|
278 |
-
$buffer = str_replace("\n", "", $buffer);
|
279 |
-
$tableInfo =explode("\t", $buffer);
|
280 |
-
//print_r($tableInfo);
|
281 |
-
if($tableInfo[0] == "###newdump###"){
|
282 |
-
// we create a new mysql dump file
|
283 |
-
if($dumpfile != ""){
|
284 |
-
// we finished a previous one and write the footers
|
285 |
-
$return['dumpsize'] = self::dataFooters($dumpfile);
|
286 |
-
}
|
287 |
-
|
288 |
-
$dump = fopen($tableInfo[2], "w");
|
289 |
-
fwrite($dump, self::dataHeaders($tableInfo[1]));
|
290 |
-
$startAtLine++;
|
291 |
-
fclose($dump);
|
292 |
-
$dumpfile = $tableInfo[2];
|
293 |
-
|
294 |
-
$return['newDump'] = 1;
|
295 |
-
//break;
|
296 |
-
}
|
297 |
-
else{
|
298 |
-
//we export the table
|
299 |
-
if($tableInfo[0] == "###enddump###")
|
300 |
-
$return['endDump'] = 1;
|
301 |
-
|
302 |
-
$fd = fopen($dumpfile, "a");
|
303 |
-
|
304 |
-
if($fd){
|
305 |
-
|
306 |
-
$next = $startAtRecord + self::$recordsPerSession;
|
307 |
-
// $tableInfo[1] number of records in the table
|
308 |
-
$table = explode("`.`", $tableInfo[0]);
|
309 |
-
$tableName = str_replace("`", "", $table[1]);
|
310 |
-
$databaseName = str_replace("`", "", $table[0]);
|
311 |
-
|
312 |
-
//return something to the browser
|
313 |
-
$return['tableName'] = $tableName;
|
314 |
-
$return['databaseName'] = $databaseName;
|
315 |
-
$return['totalRecords'] = $tableInfo[1];
|
316 |
-
|
317 |
-
//if(intval($return['totalRecords']) != 0)
|
318 |
-
if(trim($tableName) !="")
|
319 |
-
self::exportTable($databaseName, $tableName, $startAtRecord, self::$recordsPerSession, $fd);
|
320 |
-
|
321 |
-
fclose($fd);
|
322 |
-
|
323 |
-
if($next > $tableInfo[1]) //we finished loading the records for next sessions, will go to the new record
|
324 |
-
{
|
325 |
-
$startAtLine ++;
|
326 |
-
$startAtRecord = 0;
|
327 |
-
}else{
|
328 |
-
$startAtRecord = $startAtRecord + self::$recordsPerSession;
|
329 |
-
}
|
330 |
-
|
331 |
-
//$return['dbCompatibility'] = self::$dbCompatibility;
|
332 |
-
//$return['dbDropSyntax'] = self::$dbDropSyntax;
|
333 |
-
$return['startAtLine'] = $startAtLine;
|
334 |
-
$return['startAtRecord'] = $startAtRecord;
|
335 |
-
$return['dumpfile'] = $dumpfile;
|
336 |
-
|
337 |
-
return $return;
|
338 |
-
break;
|
339 |
-
|
340 |
-
}else{
|
341 |
-
self::error("Unable to open for writing file $dumpfile");
|
342 |
-
}
|
343 |
-
}
|
344 |
-
|
345 |
-
}
|
346 |
-
|
347 |
-
$count++;
|
348 |
-
|
349 |
-
|
350 |
-
}
|
351 |
-
|
352 |
-
//while is finished, lets go home...
|
353 |
-
if($dumpfile != ""){
|
354 |
-
// we finished a previous one and write the footers
|
355 |
-
$return['dumpsize'] = self::dataFooters($dumpfile);
|
356 |
-
}
|
357 |
-
$return['finished'] = 1;
|
358 |
-
$return['startAtLine'] = $startAtLine;
|
359 |
-
|
360 |
-
return $return;
|
361 |
-
|
362 |
-
}else{
|
363 |
-
self::error("Unable to open for reading file ".self::$TEMP_DBPROCESS_FILE);
|
364 |
-
}
|
365 |
-
|
366 |
-
|
367 |
-
}
|
368 |
-
|
369 |
-
|
370 |
-
/*
|
371 |
-
* Exporting the table records
|
372 |
-
*
|
373 |
-
* name: exportTable
|
374 |
-
* @param
|
375 |
-
* string $databaseName - database name of the table
|
376 |
-
* string tableName - table name
|
377 |
-
* int $start - where to start from
|
378 |
-
* int $limit - how many records
|
379 |
-
* handler $fd - file handler where to write the records
|
380 |
-
* @return
|
381 |
-
*/
|
382 |
-
public function exportTable($databaseName, $tableName, $start, $limit, $fd){
|
383 |
-
|
384 |
-
if($start == 0)
|
385 |
-
self::dumpStructure($databaseName, $tableName, $fd);
|
386 |
-
|
387 |
-
$start = intval($start);
|
388 |
-
$limit = intval($limit);
|
389 |
-
//exporting the table content now
|
390 |
-
|
391 |
-
$result = self::query("SELECT * from `$databaseName`.`$tableName` Limit $start, $limit ;");
|
392 |
-
if($result){
|
393 |
-
while($row = mysql_fetch_array($result, MYSQL_ASSOC)){
|
394 |
-
|
395 |
-
fwrite($fd, "INSERT INTO `$tableName` VALUES (");
|
396 |
-
$arr = $row;
|
397 |
-
$buffer = "";
|
398 |
-
self::$countRecords++;
|
399 |
-
|
400 |
-
foreach ($arr as $key => $value) {
|
401 |
-
$value = mysql_real_escape_string($value);
|
402 |
-
$buffer .= "'".$value."', ";
|
403 |
-
}
|
404 |
-
$buffer = rtrim($buffer, ', ') . ");\n";
|
405 |
-
fwrite($fd, $buffer);
|
406 |
-
unset($buffer);
|
407 |
-
|
408 |
-
}
|
409 |
-
}
|
410 |
-
|
411 |
-
}
|
412 |
-
|
413 |
-
public function dumpStructure($databaseName, $tableName ,$fd){
|
414 |
-
|
415 |
-
fwrite($fd, "\n#\n# Table structure for table `$tableName`\n#\n\n");
|
416 |
-
|
417 |
-
if (self::$dbDropSyntax)
|
418 |
-
fwrite($fd, "\nDROP table IF EXISTS `$tableName`;\n");
|
419 |
-
|
420 |
-
$result = self::query("SHOW CREATE table `$databaseName`.`$tableName`;");
|
421 |
-
if($result){
|
422 |
-
$row = mysql_fetch_row($result);
|
423 |
-
fwrite($fd, $row[1].";\n");
|
424 |
-
}
|
425 |
-
|
426 |
-
fwrite($fd, "\n#\n# End Structure for table `$tableName`\n#\n\n");
|
427 |
-
fwrite($fd, "#\n# Dumping data for table `$tableName`\n#\n\n");
|
428 |
-
return;
|
429 |
-
|
430 |
-
}
|
431 |
-
|
432 |
-
public function dataFooters($dumpfile){
|
433 |
-
|
434 |
-
// we finished the dump file, not return the size of it
|
435 |
-
$ftemp = fopen($dumpfile, "a");
|
436 |
-
if($ftemp){
|
437 |
-
fwrite($ftemp, "\n#\n# Finished at: ".date("M j, Y \a\\t H:i")."\n#");
|
438 |
-
fclose($ftemp);
|
439 |
-
}else{
|
440 |
-
self::error("Unable to open file $ftemp for writing");
|
441 |
-
}
|
442 |
-
|
443 |
-
return sprintf("%u", filesize($dumpfile));
|
444 |
-
|
445 |
-
}
|
446 |
-
|
447 |
-
public function resetcountRecords(){
|
448 |
-
self::$countRecords = 0;
|
449 |
-
|
450 |
-
return self::$countRecords;
|
451 |
-
}
|
452 |
-
|
453 |
-
public function getcountRecords(){
|
454 |
-
return self::$countRecords;
|
455 |
-
}
|
456 |
-
|
457 |
-
|
458 |
-
public function dataHeaders($database){
|
459 |
-
|
460 |
-
$return = "";
|
461 |
-
|
462 |
-
$return .= "#\n";
|
463 |
-
$return .= "# Powered by XCloner Site Backup\n";
|
464 |
-
$return .= "# http://www.xcloner.com\n";
|
465 |
-
$return .= "#\n";
|
466 |
-
$return .= "# Host: " . $_SERVER['HTTP_HOST'] . "\n";
|
467 |
-
$return .= "# Generation Time: " . date("M j, Y \a\\t H:i") . "\n";
|
468 |
-
$return .= "# PHP Version: " . phpversion() . "\n";
|
469 |
-
$return .= "# Mysql Compatibility: ". self::$dbCompatibility . "\n";
|
470 |
-
|
471 |
-
$result = self::query("SHOW VARIABLES LIKE \"%version%\";");
|
472 |
-
if($result){
|
473 |
-
while($row = mysql_fetch_array($result)){
|
474 |
-
|
475 |
-
$return .= "# MYSQL ".$row[0].": ".$row[1]."\n";
|
476 |
-
|
477 |
-
}
|
478 |
-
}
|
479 |
-
|
480 |
-
$return .= "#\n# Database : `" . $database . "`\n# --------------------------------------------------------\n\n";
|
481 |
-
return $return;
|
482 |
-
|
483 |
-
}
|
484 |
-
|
485 |
-
|
486 |
-
}
|
487 |
-
|
488 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/AES.php
DELETED
@@ -1,594 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of AES.
|
6 |
-
*
|
7 |
-
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
12 |
-
* {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
|
13 |
-
* it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}
|
14 |
-
* is called, again, at which point, it'll be recalculated.
|
15 |
-
*
|
16 |
-
* Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
|
17 |
-
* make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
|
18 |
-
* however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
|
19 |
-
*
|
20 |
-
* Here's a short example of how to use this library:
|
21 |
-
* <code>
|
22 |
-
* <?php
|
23 |
-
* include('Crypt/AES.php');
|
24 |
-
*
|
25 |
-
* $aes = new Crypt_AES();
|
26 |
-
*
|
27 |
-
* $aes->setKey('abcdefghijklmnop');
|
28 |
-
*
|
29 |
-
* $size = 10 * 1024;
|
30 |
-
* $plaintext = '';
|
31 |
-
* for ($i = 0; $i < $size; $i++) {
|
32 |
-
* $plaintext.= 'a';
|
33 |
-
* }
|
34 |
-
*
|
35 |
-
* echo $aes->decrypt($aes->encrypt($plaintext));
|
36 |
-
* ?>
|
37 |
-
* </code>
|
38 |
-
*
|
39 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
40 |
-
* of this software and associated documentation files (the "Software"), to deal
|
41 |
-
* in the Software without restriction, including without limitation the rights
|
42 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
43 |
-
* copies of the Software, and to permit persons to whom the Software is
|
44 |
-
* furnished to do so, subject to the following conditions:
|
45 |
-
*
|
46 |
-
* The above copyright notice and this permission notice shall be included in
|
47 |
-
* all copies or substantial portions of the Software.
|
48 |
-
*
|
49 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
50 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
51 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
52 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
53 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
54 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
55 |
-
* THE SOFTWARE.
|
56 |
-
*
|
57 |
-
* @category Crypt
|
58 |
-
* @package Crypt_AES
|
59 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
60 |
-
* @copyright MMVIII Jim Wigginton
|
61 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
62 |
-
* @version $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $
|
63 |
-
* @link http://phpseclib.sourceforge.net
|
64 |
-
*/
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Include Crypt_Rijndael
|
68 |
-
*/
|
69 |
-
require_once 'Rijndael.php';
|
70 |
-
|
71 |
-
/**#@+
|
72 |
-
* @access public
|
73 |
-
* @see Crypt_AES::encrypt()
|
74 |
-
* @see Crypt_AES::decrypt()
|
75 |
-
*/
|
76 |
-
/**
|
77 |
-
* Encrypt / decrypt using the Counter mode.
|
78 |
-
*
|
79 |
-
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
80 |
-
*
|
81 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
82 |
-
*/
|
83 |
-
define('CRYPT_AES_MODE_CTR', -1);
|
84 |
-
/**
|
85 |
-
* Encrypt / decrypt using the Electronic Code Book mode.
|
86 |
-
*
|
87 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
88 |
-
*/
|
89 |
-
define('CRYPT_AES_MODE_ECB', 1);
|
90 |
-
/**
|
91 |
-
* Encrypt / decrypt using the Code Book Chaining mode.
|
92 |
-
*
|
93 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
94 |
-
*/
|
95 |
-
define('CRYPT_AES_MODE_CBC', 2);
|
96 |
-
/**
|
97 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
98 |
-
*
|
99 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
100 |
-
*/
|
101 |
-
define('CRYPT_AES_MODE_CFB', 3);
|
102 |
-
/**
|
103 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
104 |
-
*
|
105 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
106 |
-
*/
|
107 |
-
define('CRYPT_AES_MODE_OFB', 4);
|
108 |
-
/**#@-*/
|
109 |
-
|
110 |
-
/**#@+
|
111 |
-
* @access private
|
112 |
-
* @see Crypt_AES::Crypt_AES()
|
113 |
-
*/
|
114 |
-
/**
|
115 |
-
* Toggles the internal implementation
|
116 |
-
*/
|
117 |
-
define('CRYPT_AES_MODE_INTERNAL', 1);
|
118 |
-
/**
|
119 |
-
* Toggles the mcrypt implementation
|
120 |
-
*/
|
121 |
-
define('CRYPT_AES_MODE_MCRYPT', 2);
|
122 |
-
/**#@-*/
|
123 |
-
|
124 |
-
/**
|
125 |
-
* Pure-PHP implementation of AES.
|
126 |
-
*
|
127 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
128 |
-
* @version 0.1.0
|
129 |
-
* @access public
|
130 |
-
* @package Crypt_AES
|
131 |
-
*/
|
132 |
-
class Crypt_AES extends Crypt_Rijndael {
|
133 |
-
/**
|
134 |
-
* mcrypt resource for encryption
|
135 |
-
*
|
136 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
137 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
138 |
-
*
|
139 |
-
* @see Crypt_AES::encrypt()
|
140 |
-
* @var String
|
141 |
-
* @access private
|
142 |
-
*/
|
143 |
-
var $enmcrypt;
|
144 |
-
|
145 |
-
/**
|
146 |
-
* mcrypt resource for decryption
|
147 |
-
*
|
148 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
149 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
150 |
-
*
|
151 |
-
* @see Crypt_AES::decrypt()
|
152 |
-
* @var String
|
153 |
-
* @access private
|
154 |
-
*/
|
155 |
-
var $demcrypt;
|
156 |
-
|
157 |
-
/**
|
158 |
-
* mcrypt resource for CFB mode
|
159 |
-
*
|
160 |
-
* @see Crypt_AES::encrypt()
|
161 |
-
* @see Crypt_AES::decrypt()
|
162 |
-
* @var String
|
163 |
-
* @access private
|
164 |
-
*/
|
165 |
-
var $ecb;
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Default Constructor.
|
169 |
-
*
|
170 |
-
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
|
171 |
-
* CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC. If not explictly set, CRYPT_AES_MODE_CBC will be used.
|
172 |
-
*
|
173 |
-
* @param optional Integer $mode
|
174 |
-
* @return Crypt_AES
|
175 |
-
* @access public
|
176 |
-
*/
|
177 |
-
function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
|
178 |
-
{
|
179 |
-
if ( !defined('CRYPT_AES_MODE') ) {
|
180 |
-
switch (true) {
|
181 |
-
case extension_loaded('mcrypt'):
|
182 |
-
// i'd check to see if aes was supported, by doing in_array('des', mcrypt_list_algorithms('')),
|
183 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
184 |
-
// a lot of point...
|
185 |
-
define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
|
186 |
-
break;
|
187 |
-
default:
|
188 |
-
define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
|
189 |
-
}
|
190 |
-
}
|
191 |
-
|
192 |
-
switch ( CRYPT_AES_MODE ) {
|
193 |
-
case CRYPT_AES_MODE_MCRYPT:
|
194 |
-
switch ($mode) {
|
195 |
-
case CRYPT_AES_MODE_ECB:
|
196 |
-
$this->paddable = true;
|
197 |
-
$this->mode = MCRYPT_MODE_ECB;
|
198 |
-
break;
|
199 |
-
case CRYPT_AES_MODE_CTR:
|
200 |
-
// ctr doesn't have a constant associated with it even though it appears to be fairly widely
|
201 |
-
// supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to
|
202 |
-
// include a compatibility layer. the layer has been implemented but, for now, is commented out.
|
203 |
-
$this->mode = 'ctr';
|
204 |
-
//$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
|
205 |
-
break;
|
206 |
-
case CRYPT_AES_MODE_CFB:
|
207 |
-
$this->mode = 'ncfb';
|
208 |
-
break;
|
209 |
-
case CRYPT_AES_MODE_OFB:
|
210 |
-
$this->mode = MCRYPT_MODE_NOFB;
|
211 |
-
break;
|
212 |
-
case CRYPT_AES_MODE_CBC:
|
213 |
-
default:
|
214 |
-
$this->paddable = true;
|
215 |
-
$this->mode = MCRYPT_MODE_CBC;
|
216 |
-
}
|
217 |
-
|
218 |
-
$this->debuffer = $this->enbuffer = '';
|
219 |
-
|
220 |
-
break;
|
221 |
-
default:
|
222 |
-
switch ($mode) {
|
223 |
-
case CRYPT_AES_MODE_ECB:
|
224 |
-
$this->paddable = true;
|
225 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_ECB;
|
226 |
-
break;
|
227 |
-
case CRYPT_AES_MODE_CTR:
|
228 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_CTR;
|
229 |
-
break;
|
230 |
-
case CRYPT_AES_MODE_CFB:
|
231 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_CFB;
|
232 |
-
break;
|
233 |
-
case CRYPT_AES_MODE_OFB:
|
234 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_OFB;
|
235 |
-
break;
|
236 |
-
case CRYPT_AES_MODE_CBC:
|
237 |
-
default:
|
238 |
-
$this->paddable = true;
|
239 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
240 |
-
}
|
241 |
-
}
|
242 |
-
|
243 |
-
if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
|
244 |
-
parent::Crypt_Rijndael($this->mode);
|
245 |
-
}
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Dummy function
|
250 |
-
*
|
251 |
-
* Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
|
252 |
-
*
|
253 |
-
* @access public
|
254 |
-
* @param Integer $length
|
255 |
-
*/
|
256 |
-
function setBlockLength($length)
|
257 |
-
{
|
258 |
-
return;
|
259 |
-
}
|
260 |
-
|
261 |
-
/**
|
262 |
-
* Encrypts a message.
|
263 |
-
*
|
264 |
-
* $plaintext will be padded with up to 16 additional bytes. Other AES implementations may or may not pad in the
|
265 |
-
* same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
|
266 |
-
* URL:
|
267 |
-
*
|
268 |
-
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
|
269 |
-
*
|
270 |
-
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
|
271 |
-
* strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
|
272 |
-
* length.
|
273 |
-
*
|
274 |
-
* @see Crypt_AES::decrypt()
|
275 |
-
* @access public
|
276 |
-
* @param String $plaintext
|
277 |
-
*/
|
278 |
-
function encrypt($plaintext)
|
279 |
-
{
|
280 |
-
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
|
281 |
-
$changed = $this->changed;
|
282 |
-
$this->_mcryptSetup();
|
283 |
-
/*
|
284 |
-
if ($this->mode == CRYPT_AES_MODE_CTR) {
|
285 |
-
$iv = $this->encryptIV;
|
286 |
-
$xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));
|
287 |
-
$ciphertext = $plaintext ^ $xor;
|
288 |
-
if ($this->continuousBuffer) {
|
289 |
-
$this->encryptIV = $iv;
|
290 |
-
}
|
291 |
-
return $ciphertext;
|
292 |
-
}
|
293 |
-
*/
|
294 |
-
// re: http://phpseclib.sourceforge.net/cfb-demo.phps
|
295 |
-
// using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
|
296 |
-
// rewritten CFB implementation the above outputs the same thing twice.
|
297 |
-
if ($this->mode == 'ncfb') {
|
298 |
-
if ($changed) {
|
299 |
-
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
|
300 |
-
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
301 |
-
}
|
302 |
-
|
303 |
-
if (strlen($this->enbuffer)) {
|
304 |
-
$ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
|
305 |
-
$this->enbuffer.= $ciphertext;
|
306 |
-
if (strlen($this->enbuffer) == 16) {
|
307 |
-
$this->encryptIV = $this->enbuffer;
|
308 |
-
$this->enbuffer = '';
|
309 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
310 |
-
}
|
311 |
-
$plaintext = substr($plaintext, strlen($ciphertext));
|
312 |
-
} else {
|
313 |
-
$ciphertext = '';
|
314 |
-
}
|
315 |
-
|
316 |
-
$last_pos = strlen($plaintext) & 0xFFFFFFF0;
|
317 |
-
$ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
|
318 |
-
|
319 |
-
if (strlen($plaintext) & 0xF) {
|
320 |
-
if (strlen($ciphertext)) {
|
321 |
-
$this->encryptIV = substr($ciphertext, -16);
|
322 |
-
}
|
323 |
-
$this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
|
324 |
-
$this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
|
325 |
-
$ciphertext.= $this->enbuffer;
|
326 |
-
}
|
327 |
-
|
328 |
-
return $ciphertext;
|
329 |
-
}
|
330 |
-
|
331 |
-
if ($this->paddable) {
|
332 |
-
$plaintext = $this->_pad($plaintext);
|
333 |
-
}
|
334 |
-
|
335 |
-
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
336 |
-
|
337 |
-
if (!$this->continuousBuffer) {
|
338 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
|
339 |
-
}
|
340 |
-
|
341 |
-
return $ciphertext;
|
342 |
-
}
|
343 |
-
|
344 |
-
return parent::encrypt($plaintext);
|
345 |
-
}
|
346 |
-
|
347 |
-
/**
|
348 |
-
* Decrypts a message.
|
349 |
-
*
|
350 |
-
* If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
|
351 |
-
*
|
352 |
-
* @see Crypt_AES::encrypt()
|
353 |
-
* @access public
|
354 |
-
* @param String $ciphertext
|
355 |
-
*/
|
356 |
-
function decrypt($ciphertext)
|
357 |
-
{
|
358 |
-
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
|
359 |
-
$changed = $this->changed;
|
360 |
-
$this->_mcryptSetup();
|
361 |
-
/*
|
362 |
-
if ($this->mode == CRYPT_AES_MODE_CTR) {
|
363 |
-
$iv = $this->decryptIV;
|
364 |
-
$xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));
|
365 |
-
$plaintext = $ciphertext ^ $xor;
|
366 |
-
if ($this->continuousBuffer) {
|
367 |
-
$this->decryptIV = $iv;
|
368 |
-
}
|
369 |
-
return $plaintext;
|
370 |
-
}
|
371 |
-
*/
|
372 |
-
if ($this->mode == 'ncfb') {
|
373 |
-
if ($changed) {
|
374 |
-
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
|
375 |
-
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
376 |
-
}
|
377 |
-
|
378 |
-
if (strlen($this->debuffer)) {
|
379 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
|
380 |
-
|
381 |
-
$this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
|
382 |
-
if (strlen($this->debuffer) == 16) {
|
383 |
-
$this->decryptIV = $this->debuffer;
|
384 |
-
$this->debuffer = '';
|
385 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
386 |
-
}
|
387 |
-
$ciphertext = substr($ciphertext, strlen($plaintext));
|
388 |
-
} else {
|
389 |
-
$plaintext = '';
|
390 |
-
}
|
391 |
-
|
392 |
-
$last_pos = strlen($ciphertext) & 0xFFFFFFF0;
|
393 |
-
$plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
|
394 |
-
|
395 |
-
if (strlen($ciphertext) & 0xF) {
|
396 |
-
if (strlen($plaintext)) {
|
397 |
-
$this->decryptIV = substr($ciphertext, $last_pos - 16, 16);
|
398 |
-
}
|
399 |
-
$this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
|
400 |
-
$this->debuffer = substr($ciphertext, $last_pos);
|
401 |
-
$plaintext.= $this->debuffer ^ $this->decryptIV;
|
402 |
-
}
|
403 |
-
|
404 |
-
return $plaintext;
|
405 |
-
}
|
406 |
-
|
407 |
-
if ($this->paddable) {
|
408 |
-
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
409 |
-
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
410 |
-
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
|
411 |
-
}
|
412 |
-
|
413 |
-
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
414 |
-
|
415 |
-
if (!$this->continuousBuffer) {
|
416 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
|
417 |
-
}
|
418 |
-
|
419 |
-
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
420 |
-
}
|
421 |
-
|
422 |
-
return parent::decrypt($ciphertext);
|
423 |
-
}
|
424 |
-
|
425 |
-
/**
|
426 |
-
* Setup mcrypt
|
427 |
-
*
|
428 |
-
* Validates all the variables.
|
429 |
-
*
|
430 |
-
* @access private
|
431 |
-
*/
|
432 |
-
function _mcryptSetup()
|
433 |
-
{
|
434 |
-
if (!$this->changed) {
|
435 |
-
return;
|
436 |
-
}
|
437 |
-
|
438 |
-
if (!$this->explicit_key_length) {
|
439 |
-
// this just copied from Crypt_Rijndael::_setup()
|
440 |
-
$length = strlen($this->key) >> 2;
|
441 |
-
if ($length > 8) {
|
442 |
-
$length = 8;
|
443 |
-
} else if ($length < 4) {
|
444 |
-
$length = 4;
|
445 |
-
}
|
446 |
-
$this->Nk = $length;
|
447 |
-
$this->key_size = $length << 2;
|
448 |
-
}
|
449 |
-
|
450 |
-
switch ($this->Nk) {
|
451 |
-
case 4: // 128
|
452 |
-
$this->key_size = 16;
|
453 |
-
break;
|
454 |
-
case 5: // 160
|
455 |
-
case 6: // 192
|
456 |
-
$this->key_size = 24;
|
457 |
-
break;
|
458 |
-
case 7: // 224
|
459 |
-
case 8: // 256
|
460 |
-
$this->key_size = 32;
|
461 |
-
}
|
462 |
-
|
463 |
-
$this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
|
464 |
-
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
|
465 |
-
|
466 |
-
if (!isset($this->enmcrypt)) {
|
467 |
-
$mode = $this->mode;
|
468 |
-
//$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
|
469 |
-
|
470 |
-
$this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
|
471 |
-
$this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
|
472 |
-
} // else should mcrypt_generic_deinit be called?
|
473 |
-
|
474 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
|
475 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
|
476 |
-
|
477 |
-
$this->changed = false;
|
478 |
-
}
|
479 |
-
|
480 |
-
/**
|
481 |
-
* Encrypts a block
|
482 |
-
*
|
483 |
-
* Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
|
484 |
-
*
|
485 |
-
* @see Crypt_Rijndael::_encryptBlock()
|
486 |
-
* @access private
|
487 |
-
* @param String $in
|
488 |
-
* @return String
|
489 |
-
*/
|
490 |
-
function _encryptBlock($in)
|
491 |
-
{
|
492 |
-
$state = unpack('N*word', $in);
|
493 |
-
|
494 |
-
$Nr = $this->Nr;
|
495 |
-
$w = $this->w;
|
496 |
-
$t0 = $this->t0;
|
497 |
-
$t1 = $this->t1;
|
498 |
-
$t2 = $this->t2;
|
499 |
-
$t3 = $this->t3;
|
500 |
-
|
501 |
-
// addRoundKey and reindex $state
|
502 |
-
$state = array(
|
503 |
-
$state['word1'] ^ $w[0][0],
|
504 |
-
$state['word2'] ^ $w[0][1],
|
505 |
-
$state['word3'] ^ $w[0][2],
|
506 |
-
$state['word4'] ^ $w[0][3]
|
507 |
-
);
|
508 |
-
|
509 |
-
// shiftRows + subWord + mixColumns + addRoundKey
|
510 |
-
// we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
|
511 |
-
// only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
|
512 |
-
for ($round = 1; $round < $this->Nr; $round++) {
|
513 |
-
$state = array(
|
514 |
-
$t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
|
515 |
-
$t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
|
516 |
-
$t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2],
|
517 |
-
$t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3]
|
518 |
-
);
|
519 |
-
|
520 |
-
}
|
521 |
-
|
522 |
-
// subWord
|
523 |
-
$state = array(
|
524 |
-
$this->_subWord($state[0]),
|
525 |
-
$this->_subWord($state[1]),
|
526 |
-
$this->_subWord($state[2]),
|
527 |
-
$this->_subWord($state[3])
|
528 |
-
);
|
529 |
-
|
530 |
-
// shiftRows + addRoundKey
|
531 |
-
$state = array(
|
532 |
-
($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0],
|
533 |
-
($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1],
|
534 |
-
($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2],
|
535 |
-
($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3]
|
536 |
-
);
|
537 |
-
|
538 |
-
return pack('N*', $state[0], $state[1], $state[2], $state[3]);
|
539 |
-
}
|
540 |
-
|
541 |
-
/**
|
542 |
-
* Decrypts a block
|
543 |
-
*
|
544 |
-
* Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
|
545 |
-
*
|
546 |
-
* @see Crypt_Rijndael::_decryptBlock()
|
547 |
-
* @access private
|
548 |
-
* @param String $in
|
549 |
-
* @return String
|
550 |
-
*/
|
551 |
-
function _decryptBlock($in)
|
552 |
-
{
|
553 |
-
$state = unpack('N*word', $in);
|
554 |
-
|
555 |
-
$Nr = $this->Nr;
|
556 |
-
$dw = $this->dw;
|
557 |
-
$dt0 = $this->dt0;
|
558 |
-
$dt1 = $this->dt1;
|
559 |
-
$dt2 = $this->dt2;
|
560 |
-
$dt3 = $this->dt3;
|
561 |
-
|
562 |
-
// addRoundKey and reindex $state
|
563 |
-
$state = array(
|
564 |
-
$state['word1'] ^ $dw[$this->Nr][0],
|
565 |
-
$state['word2'] ^ $dw[$this->Nr][1],
|
566 |
-
$state['word3'] ^ $dw[$this->Nr][2],
|
567 |
-
$state['word4'] ^ $dw[$this->Nr][3]
|
568 |
-
);
|
569 |
-
|
570 |
-
|
571 |
-
// invShiftRows + invSubBytes + invMixColumns + addRoundKey
|
572 |
-
for ($round = $this->Nr - 1; $round > 0; $round--) {
|
573 |
-
$state = array(
|
574 |
-
$dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
|
575 |
-
$dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
|
576 |
-
$dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2],
|
577 |
-
$dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3]
|
578 |
-
);
|
579 |
-
}
|
580 |
-
|
581 |
-
// invShiftRows + invSubWord + addRoundKey
|
582 |
-
$state = array(
|
583 |
-
$this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0],
|
584 |
-
$this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1],
|
585 |
-
$this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2],
|
586 |
-
$this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3]
|
587 |
-
);
|
588 |
-
|
589 |
-
return pack('N*', $state[0], $state[1], $state[2], $state[3]);
|
590 |
-
}
|
591 |
-
}
|
592 |
-
|
593 |
-
// vim: ts=4:sw=4:et:
|
594 |
-
// vim6: fdl=1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/DES.php
DELETED
@@ -1,1245 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of DES.
|
6 |
-
*
|
7 |
-
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* Useful resources are as follows:
|
12 |
-
*
|
13 |
-
* - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
|
14 |
-
* - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
|
15 |
-
* - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
|
16 |
-
*
|
17 |
-
* Here's a short example of how to use this library:
|
18 |
-
* <code>
|
19 |
-
* <?php
|
20 |
-
* include('Crypt/DES.php');
|
21 |
-
*
|
22 |
-
* $des = new Crypt_DES();
|
23 |
-
*
|
24 |
-
* $des->setKey('abcdefgh');
|
25 |
-
*
|
26 |
-
* $size = 10 * 1024;
|
27 |
-
* $plaintext = '';
|
28 |
-
* for ($i = 0; $i < $size; $i++) {
|
29 |
-
* $plaintext.= 'a';
|
30 |
-
* }
|
31 |
-
*
|
32 |
-
* echo $des->decrypt($des->encrypt($plaintext));
|
33 |
-
* ?>
|
34 |
-
* </code>
|
35 |
-
*
|
36 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
37 |
-
* of this software and associated documentation files (the "Software"), to deal
|
38 |
-
* in the Software without restriction, including without limitation the rights
|
39 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
40 |
-
* copies of the Software, and to permit persons to whom the Software is
|
41 |
-
* furnished to do so, subject to the following conditions:
|
42 |
-
*
|
43 |
-
* The above copyright notice and this permission notice shall be included in
|
44 |
-
* all copies or substantial portions of the Software.
|
45 |
-
*
|
46 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
47 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
48 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
49 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
50 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
51 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
52 |
-
* THE SOFTWARE.
|
53 |
-
*
|
54 |
-
* @category Crypt
|
55 |
-
* @package Crypt_DES
|
56 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
57 |
-
* @copyright MMVII Jim Wigginton
|
58 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
59 |
-
* @version $Id: DES.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
|
60 |
-
* @link http://phpseclib.sourceforge.net
|
61 |
-
*/
|
62 |
-
|
63 |
-
/**#@+
|
64 |
-
* @access private
|
65 |
-
* @see Crypt_DES::_prepareKey()
|
66 |
-
* @see Crypt_DES::_processBlock()
|
67 |
-
*/
|
68 |
-
/**
|
69 |
-
* Contains array_reverse($keys[CRYPT_DES_DECRYPT])
|
70 |
-
*/
|
71 |
-
define('CRYPT_DES_ENCRYPT', 0);
|
72 |
-
/**
|
73 |
-
* Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
|
74 |
-
*/
|
75 |
-
define('CRYPT_DES_DECRYPT', 1);
|
76 |
-
/**#@-*/
|
77 |
-
|
78 |
-
/**#@+
|
79 |
-
* @access public
|
80 |
-
* @see Crypt_DES::encrypt()
|
81 |
-
* @see Crypt_DES::decrypt()
|
82 |
-
*/
|
83 |
-
/**
|
84 |
-
* Encrypt / decrypt using the Counter mode.
|
85 |
-
*
|
86 |
-
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
87 |
-
*
|
88 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
89 |
-
*/
|
90 |
-
define('CRYPT_DES_MODE_CTR', -1);
|
91 |
-
/**
|
92 |
-
* Encrypt / decrypt using the Electronic Code Book mode.
|
93 |
-
*
|
94 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
95 |
-
*/
|
96 |
-
define('CRYPT_DES_MODE_ECB', 1);
|
97 |
-
/**
|
98 |
-
* Encrypt / decrypt using the Code Book Chaining mode.
|
99 |
-
*
|
100 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
101 |
-
*/
|
102 |
-
define('CRYPT_DES_MODE_CBC', 2);
|
103 |
-
/**
|
104 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
105 |
-
*
|
106 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
107 |
-
*/
|
108 |
-
define('CRYPT_DES_MODE_CFB', 3);
|
109 |
-
/**
|
110 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
111 |
-
*
|
112 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
113 |
-
*/
|
114 |
-
define('CRYPT_DES_MODE_OFB', 4);
|
115 |
-
/**#@-*/
|
116 |
-
|
117 |
-
/**#@+
|
118 |
-
* @access private
|
119 |
-
* @see Crypt_DES::Crypt_DES()
|
120 |
-
*/
|
121 |
-
/**
|
122 |
-
* Toggles the internal implementation
|
123 |
-
*/
|
124 |
-
define('CRYPT_DES_MODE_INTERNAL', 1);
|
125 |
-
/**
|
126 |
-
* Toggles the mcrypt implementation
|
127 |
-
*/
|
128 |
-
define('CRYPT_DES_MODE_MCRYPT', 2);
|
129 |
-
/**#@-*/
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Pure-PHP implementation of DES.
|
133 |
-
*
|
134 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
135 |
-
* @version 0.1.0
|
136 |
-
* @access public
|
137 |
-
* @package Crypt_DES
|
138 |
-
*/
|
139 |
-
class Crypt_DES {
|
140 |
-
/**
|
141 |
-
* The Key Schedule
|
142 |
-
*
|
143 |
-
* @see Crypt_DES::setKey()
|
144 |
-
* @var Array
|
145 |
-
* @access private
|
146 |
-
*/
|
147 |
-
var $keys = "\0\0\0\0\0\0\0\0";
|
148 |
-
|
149 |
-
/**
|
150 |
-
* The Encryption Mode
|
151 |
-
*
|
152 |
-
* @see Crypt_DES::Crypt_DES()
|
153 |
-
* @var Integer
|
154 |
-
* @access private
|
155 |
-
*/
|
156 |
-
var $mode;
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Continuous Buffer status
|
160 |
-
*
|
161 |
-
* @see Crypt_DES::enableContinuousBuffer()
|
162 |
-
* @var Boolean
|
163 |
-
* @access private
|
164 |
-
*/
|
165 |
-
var $continuousBuffer = false;
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Padding status
|
169 |
-
*
|
170 |
-
* @see Crypt_DES::enablePadding()
|
171 |
-
* @var Boolean
|
172 |
-
* @access private
|
173 |
-
*/
|
174 |
-
var $padding = true;
|
175 |
-
|
176 |
-
/**
|
177 |
-
* The Initialization Vector
|
178 |
-
*
|
179 |
-
* @see Crypt_DES::setIV()
|
180 |
-
* @var String
|
181 |
-
* @access private
|
182 |
-
*/
|
183 |
-
var $iv = "\0\0\0\0\0\0\0\0";
|
184 |
-
|
185 |
-
/**
|
186 |
-
* A "sliding" Initialization Vector
|
187 |
-
*
|
188 |
-
* @see Crypt_DES::enableContinuousBuffer()
|
189 |
-
* @var String
|
190 |
-
* @access private
|
191 |
-
*/
|
192 |
-
var $encryptIV = "\0\0\0\0\0\0\0\0";
|
193 |
-
|
194 |
-
/**
|
195 |
-
* A "sliding" Initialization Vector
|
196 |
-
*
|
197 |
-
* @see Crypt_DES::enableContinuousBuffer()
|
198 |
-
* @var String
|
199 |
-
* @access private
|
200 |
-
*/
|
201 |
-
var $decryptIV = "\0\0\0\0\0\0\0\0";
|
202 |
-
|
203 |
-
/**
|
204 |
-
* mcrypt resource for encryption
|
205 |
-
*
|
206 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
207 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
208 |
-
*
|
209 |
-
* @see Crypt_DES::encrypt()
|
210 |
-
* @var String
|
211 |
-
* @access private
|
212 |
-
*/
|
213 |
-
var $enmcrypt;
|
214 |
-
|
215 |
-
/**
|
216 |
-
* mcrypt resource for decryption
|
217 |
-
*
|
218 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
219 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
220 |
-
*
|
221 |
-
* @see Crypt_DES::decrypt()
|
222 |
-
* @var String
|
223 |
-
* @access private
|
224 |
-
*/
|
225 |
-
var $demcrypt;
|
226 |
-
|
227 |
-
/**
|
228 |
-
* Does the enmcrypt resource need to be (re)initialized?
|
229 |
-
*
|
230 |
-
* @see Crypt_DES::setKey()
|
231 |
-
* @see Crypt_DES::setIV()
|
232 |
-
* @var Boolean
|
233 |
-
* @access private
|
234 |
-
*/
|
235 |
-
var $enchanged = true;
|
236 |
-
|
237 |
-
/**
|
238 |
-
* Does the demcrypt resource need to be (re)initialized?
|
239 |
-
*
|
240 |
-
* @see Crypt_DES::setKey()
|
241 |
-
* @see Crypt_DES::setIV()
|
242 |
-
* @var Boolean
|
243 |
-
* @access private
|
244 |
-
*/
|
245 |
-
var $dechanged = true;
|
246 |
-
|
247 |
-
/**
|
248 |
-
* Is the mode one that is paddable?
|
249 |
-
*
|
250 |
-
* @see Crypt_DES::Crypt_DES()
|
251 |
-
* @var Boolean
|
252 |
-
* @access private
|
253 |
-
*/
|
254 |
-
var $paddable = false;
|
255 |
-
|
256 |
-
/**
|
257 |
-
* Encryption buffer for CTR, OFB and CFB modes
|
258 |
-
*
|
259 |
-
* @see Crypt_DES::encrypt()
|
260 |
-
* @var String
|
261 |
-
* @access private
|
262 |
-
*/
|
263 |
-
var $enbuffer = '';
|
264 |
-
|
265 |
-
/**
|
266 |
-
* Decryption buffer for CTR, OFB and CFB modes
|
267 |
-
*
|
268 |
-
* @see Crypt_DES::decrypt()
|
269 |
-
* @var String
|
270 |
-
* @access private
|
271 |
-
*/
|
272 |
-
var $debuffer = '';
|
273 |
-
|
274 |
-
/**
|
275 |
-
* mcrypt resource for CFB mode
|
276 |
-
*
|
277 |
-
* @see Crypt_DES::encrypt()
|
278 |
-
* @see Crypt_DES::decrypt()
|
279 |
-
* @var String
|
280 |
-
* @access private
|
281 |
-
*/
|
282 |
-
var $ecb;
|
283 |
-
|
284 |
-
/**
|
285 |
-
* Default Constructor.
|
286 |
-
*
|
287 |
-
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
|
288 |
-
* CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
|
289 |
-
*
|
290 |
-
* @param optional Integer $mode
|
291 |
-
* @return Crypt_DES
|
292 |
-
* @access public
|
293 |
-
*/
|
294 |
-
function Crypt_DES($mode = CRYPT_MODE_DES_CBC)
|
295 |
-
{
|
296 |
-
if ( !defined('CRYPT_DES_MODE') ) {
|
297 |
-
switch (true) {
|
298 |
-
case extension_loaded('mcrypt'):
|
299 |
-
// i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
|
300 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
301 |
-
// a lot of point...
|
302 |
-
define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
|
303 |
-
break;
|
304 |
-
default:
|
305 |
-
define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
|
306 |
-
}
|
307 |
-
}
|
308 |
-
|
309 |
-
switch ( CRYPT_DES_MODE ) {
|
310 |
-
case CRYPT_DES_MODE_MCRYPT:
|
311 |
-
switch ($mode) {
|
312 |
-
case CRYPT_DES_MODE_ECB:
|
313 |
-
$this->paddable = true;
|
314 |
-
$this->mode = MCRYPT_MODE_ECB;
|
315 |
-
break;
|
316 |
-
case CRYPT_DES_MODE_CTR:
|
317 |
-
$this->mode = 'ctr';
|
318 |
-
//$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
|
319 |
-
break;
|
320 |
-
case CRYPT_DES_MODE_CFB:
|
321 |
-
$this->mode = 'ncfb';
|
322 |
-
break;
|
323 |
-
case CRYPT_DES_MODE_OFB:
|
324 |
-
$this->mode = MCRYPT_MODE_NOFB;
|
325 |
-
break;
|
326 |
-
case CRYPT_DES_MODE_CBC:
|
327 |
-
default:
|
328 |
-
$this->paddable = true;
|
329 |
-
$this->mode = MCRYPT_MODE_CBC;
|
330 |
-
}
|
331 |
-
|
332 |
-
break;
|
333 |
-
default:
|
334 |
-
switch ($mode) {
|
335 |
-
case CRYPT_DES_MODE_ECB:
|
336 |
-
case CRYPT_DES_MODE_CBC:
|
337 |
-
$this->paddable = true;
|
338 |
-
$this->mode = $mode;
|
339 |
-
break;
|
340 |
-
case CRYPT_DES_MODE_CTR:
|
341 |
-
case CRYPT_DES_MODE_CFB:
|
342 |
-
case CRYPT_DES_MODE_OFB:
|
343 |
-
$this->mode = $mode;
|
344 |
-
break;
|
345 |
-
default:
|
346 |
-
$this->paddable = true;
|
347 |
-
$this->mode = CRYPT_DES_MODE_CBC;
|
348 |
-
}
|
349 |
-
}
|
350 |
-
}
|
351 |
-
|
352 |
-
/**
|
353 |
-
* Sets the key.
|
354 |
-
*
|
355 |
-
* Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
|
356 |
-
* only use the first eight, if $key has more then eight characters in it, and pad $key with the
|
357 |
-
* null byte if it is less then eight characters long.
|
358 |
-
*
|
359 |
-
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
360 |
-
*
|
361 |
-
* If the key is not explicitly set, it'll be assumed to be all zero's.
|
362 |
-
*
|
363 |
-
* @access public
|
364 |
-
* @param String $key
|
365 |
-
*/
|
366 |
-
function setKey($key)
|
367 |
-
{
|
368 |
-
$this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? str_pad(substr($key, 0, 8), 8, chr(0)) : $this->_prepareKey($key);
|
369 |
-
$this->changed = true;
|
370 |
-
}
|
371 |
-
|
372 |
-
/**
|
373 |
-
* Sets the initialization vector. (optional)
|
374 |
-
*
|
375 |
-
* SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
|
376 |
-
* to be all zero's.
|
377 |
-
*
|
378 |
-
* @access public
|
379 |
-
* @param String $iv
|
380 |
-
*/
|
381 |
-
function setIV($iv)
|
382 |
-
{
|
383 |
-
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
|
384 |
-
$this->changed = true;
|
385 |
-
}
|
386 |
-
|
387 |
-
/**
|
388 |
-
* Generate CTR XOR encryption key
|
389 |
-
*
|
390 |
-
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
391 |
-
* plaintext / ciphertext in CTR mode.
|
392 |
-
*
|
393 |
-
* @see Crypt_DES::decrypt()
|
394 |
-
* @see Crypt_DES::encrypt()
|
395 |
-
* @access public
|
396 |
-
* @param Integer $length
|
397 |
-
* @param String $iv
|
398 |
-
*/
|
399 |
-
function _generate_xor($length, &$iv)
|
400 |
-
{
|
401 |
-
$xor = '';
|
402 |
-
$num_blocks = ($length + 7) >> 3;
|
403 |
-
for ($i = 0; $i < $num_blocks; $i++) {
|
404 |
-
$xor.= $iv;
|
405 |
-
for ($j = 4; $j <= 8; $j+=4) {
|
406 |
-
$temp = substr($iv, -$j, 4);
|
407 |
-
switch ($temp) {
|
408 |
-
case "\xFF\xFF\xFF\xFF":
|
409 |
-
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
410 |
-
break;
|
411 |
-
case "\x7F\xFF\xFF\xFF":
|
412 |
-
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
413 |
-
break 2;
|
414 |
-
default:
|
415 |
-
extract(unpack('Ncount', $temp));
|
416 |
-
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
417 |
-
break 2;
|
418 |
-
}
|
419 |
-
}
|
420 |
-
}
|
421 |
-
|
422 |
-
return $xor;
|
423 |
-
}
|
424 |
-
|
425 |
-
/**
|
426 |
-
* Encrypts a message.
|
427 |
-
*
|
428 |
-
* $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
|
429 |
-
* same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
|
430 |
-
* URL:
|
431 |
-
*
|
432 |
-
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
|
433 |
-
*
|
434 |
-
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
|
435 |
-
* strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
|
436 |
-
* length.
|
437 |
-
*
|
438 |
-
* @see Crypt_DES::decrypt()
|
439 |
-
* @access public
|
440 |
-
* @param String $plaintext
|
441 |
-
*/
|
442 |
-
function encrypt($plaintext)
|
443 |
-
{
|
444 |
-
if ($this->paddable) {
|
445 |
-
$plaintext = $this->_pad($plaintext);
|
446 |
-
}
|
447 |
-
|
448 |
-
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
449 |
-
if ($this->enchanged) {
|
450 |
-
if (!isset($this->enmcrypt)) {
|
451 |
-
$this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
|
452 |
-
}
|
453 |
-
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
454 |
-
if ($this->mode != 'ncfb') {
|
455 |
-
$this->enchanged = false;
|
456 |
-
}
|
457 |
-
}
|
458 |
-
|
459 |
-
if ($this->mode != 'ncfb') {
|
460 |
-
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
461 |
-
} else {
|
462 |
-
if ($this->enchanged) {
|
463 |
-
$this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
|
464 |
-
mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
|
465 |
-
$this->enchanged = false;
|
466 |
-
}
|
467 |
-
|
468 |
-
if (strlen($this->enbuffer)) {
|
469 |
-
$ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
|
470 |
-
$this->enbuffer.= $ciphertext;
|
471 |
-
if (strlen($this->enbuffer) == 8) {
|
472 |
-
$this->encryptIV = $this->enbuffer;
|
473 |
-
$this->enbuffer = '';
|
474 |
-
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
475 |
-
}
|
476 |
-
$plaintext = substr($plaintext, strlen($ciphertext));
|
477 |
-
} else {
|
478 |
-
$ciphertext = '';
|
479 |
-
}
|
480 |
-
|
481 |
-
$last_pos = strlen($plaintext) & 0xFFFFFFF8;
|
482 |
-
$ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
|
483 |
-
|
484 |
-
if (strlen($plaintext) & 0x7) {
|
485 |
-
if (strlen($ciphertext)) {
|
486 |
-
$this->encryptIV = substr($ciphertext, -8);
|
487 |
-
}
|
488 |
-
$this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
|
489 |
-
$this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
|
490 |
-
$ciphertext.= $this->enbuffer;
|
491 |
-
}
|
492 |
-
}
|
493 |
-
|
494 |
-
if (!$this->continuousBuffer) {
|
495 |
-
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
496 |
-
}
|
497 |
-
|
498 |
-
return $ciphertext;
|
499 |
-
}
|
500 |
-
|
501 |
-
if (!is_array($this->keys)) {
|
502 |
-
$this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
|
503 |
-
}
|
504 |
-
|
505 |
-
$buffer = &$this->enbuffer;
|
506 |
-
$continuousBuffer = $this->continuousBuffer;
|
507 |
-
$ciphertext = '';
|
508 |
-
switch ($this->mode) {
|
509 |
-
case CRYPT_DES_MODE_ECB:
|
510 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
511 |
-
$ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
|
512 |
-
}
|
513 |
-
break;
|
514 |
-
case CRYPT_DES_MODE_CBC:
|
515 |
-
$xor = $this->encryptIV;
|
516 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
517 |
-
$block = substr($plaintext, $i, 8);
|
518 |
-
$block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
|
519 |
-
$xor = $block;
|
520 |
-
$ciphertext.= $block;
|
521 |
-
}
|
522 |
-
if ($this->continuousBuffer) {
|
523 |
-
$this->encryptIV = $xor;
|
524 |
-
}
|
525 |
-
break;
|
526 |
-
case CRYPT_DES_MODE_CTR:
|
527 |
-
$xor = $this->encryptIV;
|
528 |
-
if (strlen($buffer)) {
|
529 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
530 |
-
$block = substr($plaintext, $i, 8);
|
531 |
-
$buffer.= $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
532 |
-
$key = $this->_string_shift($buffer, 8);
|
533 |
-
$ciphertext.= $block ^ $key;
|
534 |
-
}
|
535 |
-
} else {
|
536 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
537 |
-
$block = substr($plaintext, $i, 8);
|
538 |
-
$key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
539 |
-
$ciphertext.= $block ^ $key;
|
540 |
-
}
|
541 |
-
}
|
542 |
-
if ($this->continuousBuffer) {
|
543 |
-
$this->encryptIV = $xor;
|
544 |
-
if ($start = strlen($plaintext) & 7) {
|
545 |
-
$buffer = substr($key, $start) . $buffer;
|
546 |
-
}
|
547 |
-
}
|
548 |
-
break;
|
549 |
-
case CRYPT_DES_MODE_CFB:
|
550 |
-
if (!empty($buffer['xor'])) {
|
551 |
-
$ciphertext = $plaintext ^ $buffer['xor'];
|
552 |
-
$iv = $buffer['encrypted'] . $ciphertext;
|
553 |
-
$start = strlen($ciphertext);
|
554 |
-
$buffer['encrypted'].= $ciphertext;
|
555 |
-
$buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
|
556 |
-
} else {
|
557 |
-
$ciphertext = '';
|
558 |
-
$iv = $this->encryptIV;
|
559 |
-
$start = 0;
|
560 |
-
}
|
561 |
-
|
562 |
-
for ($i = $start; $i < strlen($plaintext); $i+=8) {
|
563 |
-
$block = substr($plaintext, $i, 8);
|
564 |
-
$xor = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
565 |
-
$iv = $block ^ $xor;
|
566 |
-
if ($continuousBuffer && strlen($iv) != 8) {
|
567 |
-
$buffer = array(
|
568 |
-
'encrypted' => $iv,
|
569 |
-
'xor' => substr($xor, strlen($iv))
|
570 |
-
);
|
571 |
-
}
|
572 |
-
$ciphertext.= $iv;
|
573 |
-
}
|
574 |
-
|
575 |
-
if ($this->continuousBuffer) {
|
576 |
-
$this->encryptIV = $iv;
|
577 |
-
}
|
578 |
-
break;
|
579 |
-
case CRYPT_DES_MODE_OFB:
|
580 |
-
$xor = $this->encryptIV;
|
581 |
-
if (strlen($buffer)) {
|
582 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
583 |
-
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
584 |
-
$buffer.= $xor;
|
585 |
-
$key = $this->_string_shift($buffer, 8);
|
586 |
-
$ciphertext.= substr($plaintext, $i, 8) ^ $key;
|
587 |
-
}
|
588 |
-
} else {
|
589 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
590 |
-
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
591 |
-
$ciphertext.= substr($plaintext, $i, 8) ^ $xor;
|
592 |
-
}
|
593 |
-
$key = $xor;
|
594 |
-
}
|
595 |
-
if ($this->continuousBuffer) {
|
596 |
-
$this->encryptIV = $xor;
|
597 |
-
if ($start = strlen($plaintext) & 7) {
|
598 |
-
$buffer = substr($key, $start) . $buffer;
|
599 |
-
}
|
600 |
-
}
|
601 |
-
}
|
602 |
-
|
603 |
-
return $ciphertext;
|
604 |
-
}
|
605 |
-
|
606 |
-
/**
|
607 |
-
* Decrypts a message.
|
608 |
-
*
|
609 |
-
* If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
|
610 |
-
*
|
611 |
-
* @see Crypt_DES::encrypt()
|
612 |
-
* @access public
|
613 |
-
* @param String $ciphertext
|
614 |
-
*/
|
615 |
-
function decrypt($ciphertext)
|
616 |
-
{
|
617 |
-
if ($this->paddable) {
|
618 |
-
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
619 |
-
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
620 |
-
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
|
621 |
-
}
|
622 |
-
|
623 |
-
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
624 |
-
if ($this->dechanged) {
|
625 |
-
if (!isset($this->demcrypt)) {
|
626 |
-
$this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
|
627 |
-
}
|
628 |
-
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
629 |
-
if ($this->mode != 'ncfb') {
|
630 |
-
$this->dechanged = false;
|
631 |
-
}
|
632 |
-
}
|
633 |
-
|
634 |
-
if ($this->mode != 'ncfb') {
|
635 |
-
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
636 |
-
} else {
|
637 |
-
if ($this->dechanged) {
|
638 |
-
$this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
|
639 |
-
mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
|
640 |
-
$this->dechanged = false;
|
641 |
-
}
|
642 |
-
|
643 |
-
if (strlen($this->debuffer)) {
|
644 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
|
645 |
-
|
646 |
-
$this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
|
647 |
-
if (strlen($this->debuffer) == 8) {
|
648 |
-
$this->decryptIV = $this->debuffer;
|
649 |
-
$this->debuffer = '';
|
650 |
-
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
651 |
-
}
|
652 |
-
$ciphertext = substr($ciphertext, strlen($plaintext));
|
653 |
-
} else {
|
654 |
-
$plaintext = '';
|
655 |
-
}
|
656 |
-
|
657 |
-
$last_pos = strlen($ciphertext) & 0xFFFFFFF8;
|
658 |
-
$plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
|
659 |
-
|
660 |
-
if (strlen($ciphertext) & 0x7) {
|
661 |
-
if (strlen($plaintext)) {
|
662 |
-
$this->decryptIV = substr($ciphertext, $last_pos - 8, 8);
|
663 |
-
}
|
664 |
-
$this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
|
665 |
-
$this->debuffer = substr($ciphertext, $last_pos);
|
666 |
-
$plaintext.= $this->debuffer ^ $this->decryptIV;
|
667 |
-
}
|
668 |
-
|
669 |
-
return $plaintext;
|
670 |
-
}
|
671 |
-
|
672 |
-
if (!$this->continuousBuffer) {
|
673 |
-
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
674 |
-
}
|
675 |
-
|
676 |
-
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
677 |
-
}
|
678 |
-
|
679 |
-
if (!is_array($this->keys)) {
|
680 |
-
$this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
|
681 |
-
}
|
682 |
-
|
683 |
-
$buffer = &$this->debuffer;
|
684 |
-
$continuousBuffer = $this->continuousBuffer;
|
685 |
-
$plaintext = '';
|
686 |
-
switch ($this->mode) {
|
687 |
-
case CRYPT_DES_MODE_ECB:
|
688 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
689 |
-
$plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
|
690 |
-
}
|
691 |
-
break;
|
692 |
-
case CRYPT_DES_MODE_CBC:
|
693 |
-
$xor = $this->decryptIV;
|
694 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
695 |
-
$block = substr($ciphertext, $i, 8);
|
696 |
-
$plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
|
697 |
-
$xor = $block;
|
698 |
-
}
|
699 |
-
if ($this->continuousBuffer) {
|
700 |
-
$this->decryptIV = $xor;
|
701 |
-
}
|
702 |
-
break;
|
703 |
-
case CRYPT_DES_MODE_CTR:
|
704 |
-
$xor = $this->decryptIV;
|
705 |
-
if (strlen($buffer)) {
|
706 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
707 |
-
$block = substr($ciphertext, $i, 8);
|
708 |
-
$buffer.= $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
709 |
-
$key = $this->_string_shift($buffer, 8);
|
710 |
-
$plaintext.= $block ^ $key;
|
711 |
-
}
|
712 |
-
} else {
|
713 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
714 |
-
$block = substr($ciphertext, $i, 8);
|
715 |
-
$key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
716 |
-
$plaintext.= $block ^ $key;
|
717 |
-
}
|
718 |
-
}
|
719 |
-
if ($this->continuousBuffer) {
|
720 |
-
$this->decryptIV = $xor;
|
721 |
-
if ($start = strlen($ciphertext) % 8) {
|
722 |
-
$buffer = substr($key, $start) . $buffer;
|
723 |
-
}
|
724 |
-
}
|
725 |
-
break;
|
726 |
-
case CRYPT_DES_MODE_CFB:
|
727 |
-
if (!empty($buffer['ciphertext'])) {
|
728 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
|
729 |
-
$buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
|
730 |
-
if (strlen($buffer['ciphertext']) == 8) {
|
731 |
-
$xor = $this->_processBlock($buffer['ciphertext'], CRYPT_DES_ENCRYPT);
|
732 |
-
$buffer['ciphertext'] = '';
|
733 |
-
}
|
734 |
-
$start = strlen($plaintext);
|
735 |
-
$block = $this->decryptIV;
|
736 |
-
} else {
|
737 |
-
$plaintext = '';
|
738 |
-
$xor = $this->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
|
739 |
-
$start = 0;
|
740 |
-
}
|
741 |
-
|
742 |
-
for ($i = $start; $i < strlen($ciphertext); $i+=8) {
|
743 |
-
$block = substr($ciphertext, $i, 8);
|
744 |
-
$plaintext.= $block ^ $xor;
|
745 |
-
if ($continuousBuffer && strlen($block) != 8) {
|
746 |
-
$buffer['ciphertext'].= $block;
|
747 |
-
$block = $xor;
|
748 |
-
} else if (strlen($block) == 8) {
|
749 |
-
$xor = $this->_processBlock($block, CRYPT_DES_ENCRYPT);
|
750 |
-
}
|
751 |
-
}
|
752 |
-
if ($this->continuousBuffer) {
|
753 |
-
$this->decryptIV = $block;
|
754 |
-
}
|
755 |
-
break;
|
756 |
-
case CRYPT_DES_MODE_OFB:
|
757 |
-
$xor = $this->decryptIV;
|
758 |
-
if (strlen($buffer)) {
|
759 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
760 |
-
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
761 |
-
$buffer.= $xor;
|
762 |
-
$key = $this->_string_shift($buffer, 8);
|
763 |
-
$plaintext.= substr($ciphertext, $i, 8) ^ $key;
|
764 |
-
}
|
765 |
-
} else {
|
766 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
767 |
-
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
768 |
-
$plaintext.= substr($ciphertext, $i, 8) ^ $xor;
|
769 |
-
}
|
770 |
-
$key = $xor;
|
771 |
-
}
|
772 |
-
if ($this->continuousBuffer) {
|
773 |
-
$this->decryptIV = $xor;
|
774 |
-
if ($start = strlen($ciphertext) % 8) {
|
775 |
-
$buffer = substr($key, $start) . $buffer;
|
776 |
-
}
|
777 |
-
}
|
778 |
-
}
|
779 |
-
|
780 |
-
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
781 |
-
}
|
782 |
-
|
783 |
-
/**
|
784 |
-
* Treat consecutive "packets" as if they are a continuous buffer.
|
785 |
-
*
|
786 |
-
* Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
|
787 |
-
* will yield different outputs:
|
788 |
-
*
|
789 |
-
* <code>
|
790 |
-
* echo $des->encrypt(substr($plaintext, 0, 8));
|
791 |
-
* echo $des->encrypt(substr($plaintext, 8, 8));
|
792 |
-
* </code>
|
793 |
-
* <code>
|
794 |
-
* echo $des->encrypt($plaintext);
|
795 |
-
* </code>
|
796 |
-
*
|
797 |
-
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
|
798 |
-
* another, as demonstrated with the following:
|
799 |
-
*
|
800 |
-
* <code>
|
801 |
-
* $des->encrypt(substr($plaintext, 0, 8));
|
802 |
-
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
803 |
-
* </code>
|
804 |
-
* <code>
|
805 |
-
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
806 |
-
* </code>
|
807 |
-
*
|
808 |
-
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
|
809 |
-
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
810 |
-
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
811 |
-
*
|
812 |
-
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
|
813 |
-
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
814 |
-
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
815 |
-
* however, they are also less intuitive and more likely to cause you problems.
|
816 |
-
*
|
817 |
-
* @see Crypt_DES::disableContinuousBuffer()
|
818 |
-
* @access public
|
819 |
-
*/
|
820 |
-
function enableContinuousBuffer()
|
821 |
-
{
|
822 |
-
$this->continuousBuffer = true;
|
823 |
-
}
|
824 |
-
|
825 |
-
/**
|
826 |
-
* Treat consecutive packets as if they are a discontinuous buffer.
|
827 |
-
*
|
828 |
-
* The default behavior.
|
829 |
-
*
|
830 |
-
* @see Crypt_DES::enableContinuousBuffer()
|
831 |
-
* @access public
|
832 |
-
*/
|
833 |
-
function disableContinuousBuffer()
|
834 |
-
{
|
835 |
-
$this->continuousBuffer = false;
|
836 |
-
$this->encryptIV = $this->iv;
|
837 |
-
$this->decryptIV = $this->iv;
|
838 |
-
}
|
839 |
-
|
840 |
-
/**
|
841 |
-
* Pad "packets".
|
842 |
-
*
|
843 |
-
* DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
|
844 |
-
* a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
|
845 |
-
*
|
846 |
-
* Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
|
847 |
-
* where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
|
848 |
-
* away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
|
849 |
-
* transmitted separately)
|
850 |
-
*
|
851 |
-
* @see Crypt_DES::disablePadding()
|
852 |
-
* @access public
|
853 |
-
*/
|
854 |
-
function enablePadding()
|
855 |
-
{
|
856 |
-
$this->padding = true;
|
857 |
-
}
|
858 |
-
|
859 |
-
/**
|
860 |
-
* Do not pad packets.
|
861 |
-
*
|
862 |
-
* @see Crypt_DES::enablePadding()
|
863 |
-
* @access public
|
864 |
-
*/
|
865 |
-
function disablePadding()
|
866 |
-
{
|
867 |
-
$this->padding = false;
|
868 |
-
}
|
869 |
-
|
870 |
-
/**
|
871 |
-
* Pads a string
|
872 |
-
*
|
873 |
-
* Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
|
874 |
-
* 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
|
875 |
-
*
|
876 |
-
* If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
|
877 |
-
* and padding will, hence forth, be enabled.
|
878 |
-
*
|
879 |
-
* @see Crypt_DES::_unpad()
|
880 |
-
* @access private
|
881 |
-
*/
|
882 |
-
function _pad($text)
|
883 |
-
{
|
884 |
-
$length = strlen($text);
|
885 |
-
|
886 |
-
if (!$this->padding) {
|
887 |
-
if (($length & 7) == 0) {
|
888 |
-
return $text;
|
889 |
-
} else {
|
890 |
-
user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
|
891 |
-
$this->padding = true;
|
892 |
-
}
|
893 |
-
}
|
894 |
-
|
895 |
-
$pad = 8 - ($length & 7);
|
896 |
-
return str_pad($text, $length + $pad, chr($pad));
|
897 |
-
}
|
898 |
-
|
899 |
-
/**
|
900 |
-
* Unpads a string
|
901 |
-
*
|
902 |
-
* If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
|
903 |
-
* and false will be returned.
|
904 |
-
*
|
905 |
-
* @see Crypt_DES::_pad()
|
906 |
-
* @access private
|
907 |
-
*/
|
908 |
-
function _unpad($text)
|
909 |
-
{
|
910 |
-
if (!$this->padding) {
|
911 |
-
return $text;
|
912 |
-
}
|
913 |
-
|
914 |
-
$length = ord($text[strlen($text) - 1]);
|
915 |
-
|
916 |
-
if (!$length || $length > 8) {
|
917 |
-
return false;
|
918 |
-
}
|
919 |
-
|
920 |
-
return substr($text, 0, -$length);
|
921 |
-
}
|
922 |
-
|
923 |
-
/**
|
924 |
-
* Encrypts or decrypts a 64-bit block
|
925 |
-
*
|
926 |
-
* $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
|
927 |
-
* {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
|
928 |
-
* idea of what this function does.
|
929 |
-
*
|
930 |
-
* @access private
|
931 |
-
* @param String $block
|
932 |
-
* @param Integer $mode
|
933 |
-
* @return String
|
934 |
-
*/
|
935 |
-
function _processBlock($block, $mode)
|
936 |
-
{
|
937 |
-
// s-boxes. in the official DES docs, they're described as being matrices that
|
938 |
-
// one accesses by using the first and last bits to determine the row and the
|
939 |
-
// middle four bits to determine the column. in this implementation, they've
|
940 |
-
// been converted to vectors
|
941 |
-
static $sbox = array(
|
942 |
-
array(
|
943 |
-
14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
|
944 |
-
3, 10 ,10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
|
945 |
-
4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
|
946 |
-
15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
|
947 |
-
),
|
948 |
-
array(
|
949 |
-
15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
|
950 |
-
9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
|
951 |
-
0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
|
952 |
-
5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
|
953 |
-
),
|
954 |
-
array(
|
955 |
-
10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
|
956 |
-
1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
|
957 |
-
13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
|
958 |
-
11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
|
959 |
-
),
|
960 |
-
array(
|
961 |
-
7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
|
962 |
-
1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
|
963 |
-
10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
|
964 |
-
15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
|
965 |
-
),
|
966 |
-
array(
|
967 |
-
2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
|
968 |
-
8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
|
969 |
-
4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
|
970 |
-
15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
|
971 |
-
),
|
972 |
-
array(
|
973 |
-
12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
|
974 |
-
0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
|
975 |
-
9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
|
976 |
-
7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
|
977 |
-
),
|
978 |
-
array(
|
979 |
-
4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
|
980 |
-
3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
|
981 |
-
1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
|
982 |
-
10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
|
983 |
-
),
|
984 |
-
array(
|
985 |
-
13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
|
986 |
-
10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
|
987 |
-
7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
|
988 |
-
0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
|
989 |
-
)
|
990 |
-
);
|
991 |
-
|
992 |
-
$keys = $this->keys;
|
993 |
-
|
994 |
-
$temp = unpack('Na/Nb', $block);
|
995 |
-
$block = array($temp['a'], $temp['b']);
|
996 |
-
|
997 |
-
// because php does arithmetic right shifts, if the most significant bits are set, right
|
998 |
-
// shifting those into the correct position will add 1's - not 0's. this will intefere
|
999 |
-
// with the | operation unless a second & is done. so we isolate these bits and left shift
|
1000 |
-
// them into place. we then & each block with 0x7FFFFFFF to prevennt 1's from being added
|
1001 |
-
// for any other shifts.
|
1002 |
-
$msb = array(
|
1003 |
-
($block[0] >> 31) & 1,
|
1004 |
-
($block[1] >> 31) & 1
|
1005 |
-
);
|
1006 |
-
$block[0] &= 0x7FFFFFFF;
|
1007 |
-
$block[1] &= 0x7FFFFFFF;
|
1008 |
-
|
1009 |
-
// we isolate the appropriate bit in the appropriate integer and shift as appropriate. in
|
1010 |
-
// some cases, there are going to be multiple bits in the same integer that need to be shifted
|
1011 |
-
// in the same way. we combine those into one shift operation.
|
1012 |
-
$block = array(
|
1013 |
-
(($block[1] & 0x00000040) << 25) | (($block[1] & 0x00004000) << 16) |
|
1014 |
-
(($block[1] & 0x00400001) << 7) | (($block[1] & 0x40000100) >> 2) |
|
1015 |
-
(($block[0] & 0x00000040) << 21) | (($block[0] & 0x00004000) << 12) |
|
1016 |
-
(($block[0] & 0x00400001) << 3) | (($block[0] & 0x40000100) >> 6) |
|
1017 |
-
(($block[1] & 0x00000010) << 19) | (($block[1] & 0x00001000) << 10) |
|
1018 |
-
(($block[1] & 0x00100000) << 1) | (($block[1] & 0x10000000) >> 8) |
|
1019 |
-
(($block[0] & 0x00000010) << 15) | (($block[0] & 0x00001000) << 6) |
|
1020 |
-
(($block[0] & 0x00100000) >> 3) | (($block[0] & 0x10000000) >> 12) |
|
1021 |
-
(($block[1] & 0x00000004) << 13) | (($block[1] & 0x00000400) << 4) |
|
1022 |
-
(($block[1] & 0x00040000) >> 5) | (($block[1] & 0x04000000) >> 14) |
|
1023 |
-
(($block[0] & 0x00000004) << 9) | ( $block[0] & 0x00000400 ) |
|
1024 |
-
(($block[0] & 0x00040000) >> 9) | (($block[0] & 0x04000000) >> 18) |
|
1025 |
-
(($block[1] & 0x00010000) >> 11) | (($block[1] & 0x01000000) >> 20) |
|
1026 |
-
(($block[0] & 0x00010000) >> 15) | (($block[0] & 0x01000000) >> 24)
|
1027 |
-
,
|
1028 |
-
(($block[1] & 0x00000080) << 24) | (($block[1] & 0x00008000) << 15) |
|
1029 |
-
(($block[1] & 0x00800002) << 6) | (($block[0] & 0x00000080) << 20) |
|
1030 |
-
(($block[0] & 0x00008000) << 11) | (($block[0] & 0x00800002) << 2) |
|
1031 |
-
(($block[1] & 0x00000020) << 18) | (($block[1] & 0x00002000) << 9) |
|
1032 |
-
( $block[1] & 0x00200000 ) | (($block[1] & 0x20000000) >> 9) |
|
1033 |
-
(($block[0] & 0x00000020) << 14) | (($block[0] & 0x00002000) << 5) |
|
1034 |
-
(($block[0] & 0x00200000) >> 4) | (($block[0] & 0x20000000) >> 13) |
|
1035 |
-
(($block[1] & 0x00000008) << 12) | (($block[1] & 0x00000800) << 3) |
|
1036 |
-
(($block[1] & 0x00080000) >> 6) | (($block[1] & 0x08000000) >> 15) |
|
1037 |
-
(($block[0] & 0x00000008) << 8) | (($block[0] & 0x00000800) >> 1) |
|
1038 |
-
(($block[0] & 0x00080000) >> 10) | (($block[0] & 0x08000000) >> 19) |
|
1039 |
-
(($block[1] & 0x00000200) >> 3) | (($block[0] & 0x00000200) >> 7) |
|
1040 |
-
(($block[1] & 0x00020000) >> 12) | (($block[1] & 0x02000000) >> 21) |
|
1041 |
-
(($block[0] & 0x00020000) >> 16) | (($block[0] & 0x02000000) >> 25) |
|
1042 |
-
($msb[1] << 28) | ($msb[0] << 24)
|
1043 |
-
);
|
1044 |
-
|
1045 |
-
for ($i = 0; $i < 16; $i++) {
|
1046 |
-
// start of "the Feistel (F) function" - see the following URL:
|
1047 |
-
// http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
|
1048 |
-
$temp = (($sbox[0][((($block[1] >> 27) & 0x1F) | (($block[1] & 1) << 5)) ^ $keys[$mode][$i][0]]) << 28)
|
1049 |
-
| (($sbox[1][(($block[1] & 0x1F800000) >> 23) ^ $keys[$mode][$i][1]]) << 24)
|
1050 |
-
| (($sbox[2][(($block[1] & 0x01F80000) >> 19) ^ $keys[$mode][$i][2]]) << 20)
|
1051 |
-
| (($sbox[3][(($block[1] & 0x001F8000) >> 15) ^ $keys[$mode][$i][3]]) << 16)
|
1052 |
-
| (($sbox[4][(($block[1] & 0x0001F800) >> 11) ^ $keys[$mode][$i][4]]) << 12)
|
1053 |
-
| (($sbox[5][(($block[1] & 0x00001F80) >> 7) ^ $keys[$mode][$i][5]]) << 8)
|
1054 |
-
| (($sbox[6][(($block[1] & 0x000001F8) >> 3) ^ $keys[$mode][$i][6]]) << 4)
|
1055 |
-
| ( $sbox[7][((($block[1] & 0x1F) << 1) | (($block[1] >> 31) & 1)) ^ $keys[$mode][$i][7]]);
|
1056 |
-
|
1057 |
-
$msb = ($temp >> 31) & 1;
|
1058 |
-
$temp &= 0x7FFFFFFF;
|
1059 |
-
$newBlock = (($temp & 0x00010000) << 15) | (($temp & 0x02020120) << 5)
|
1060 |
-
| (($temp & 0x00001800) << 17) | (($temp & 0x01000000) >> 10)
|
1061 |
-
| (($temp & 0x00000008) << 24) | (($temp & 0x00100000) << 6)
|
1062 |
-
| (($temp & 0x00000010) << 21) | (($temp & 0x00008000) << 9)
|
1063 |
-
| (($temp & 0x00000200) << 12) | (($temp & 0x10000000) >> 27)
|
1064 |
-
| (($temp & 0x00000040) << 14) | (($temp & 0x08000000) >> 8)
|
1065 |
-
| (($temp & 0x00004000) << 4) | (($temp & 0x00000002) << 16)
|
1066 |
-
| (($temp & 0x00442000) >> 6) | (($temp & 0x40800000) >> 15)
|
1067 |
-
| (($temp & 0x00000001) << 11) | (($temp & 0x20000000) >> 20)
|
1068 |
-
| (($temp & 0x00080000) >> 13) | (($temp & 0x00000004) << 3)
|
1069 |
-
| (($temp & 0x04000000) >> 22) | (($temp & 0x00000480) >> 7)
|
1070 |
-
| (($temp & 0x00200000) >> 19) | ($msb << 23);
|
1071 |
-
// end of "the Feistel (F) function" - $newBlock is F's output
|
1072 |
-
|
1073 |
-
$temp = $block[1];
|
1074 |
-
$block[1] = $block[0] ^ $newBlock;
|
1075 |
-
$block[0] = $temp;
|
1076 |
-
}
|
1077 |
-
|
1078 |
-
$msb = array(
|
1079 |
-
($block[0] >> 31) & 1,
|
1080 |
-
($block[1] >> 31) & 1
|
1081 |
-
);
|
1082 |
-
$block[0] &= 0x7FFFFFFF;
|
1083 |
-
$block[1] &= 0x7FFFFFFF;
|
1084 |
-
|
1085 |
-
$block = array(
|
1086 |
-
(($block[0] & 0x01000004) << 7) | (($block[1] & 0x01000004) << 6) |
|
1087 |
-
(($block[0] & 0x00010000) << 13) | (($block[1] & 0x00010000) << 12) |
|
1088 |
-
(($block[0] & 0x00000100) << 19) | (($block[1] & 0x00000100) << 18) |
|
1089 |
-
(($block[0] & 0x00000001) << 25) | (($block[1] & 0x00000001) << 24) |
|
1090 |
-
(($block[0] & 0x02000008) >> 2) | (($block[1] & 0x02000008) >> 3) |
|
1091 |
-
(($block[0] & 0x00020000) << 4) | (($block[1] & 0x00020000) << 3) |
|
1092 |
-
(($block[0] & 0x00000200) << 10) | (($block[1] & 0x00000200) << 9) |
|
1093 |
-
(($block[0] & 0x00000002) << 16) | (($block[1] & 0x00000002) << 15) |
|
1094 |
-
(($block[0] & 0x04000000) >> 11) | (($block[1] & 0x04000000) >> 12) |
|
1095 |
-
(($block[0] & 0x00040000) >> 5) | (($block[1] & 0x00040000) >> 6) |
|
1096 |
-
(($block[0] & 0x00000400) << 1) | ( $block[1] & 0x00000400 ) |
|
1097 |
-
(($block[0] & 0x08000000) >> 20) | (($block[1] & 0x08000000) >> 21) |
|
1098 |
-
(($block[0] & 0x00080000) >> 14) | (($block[1] & 0x00080000) >> 15) |
|
1099 |
-
(($block[0] & 0x00000800) >> 8) | (($block[1] & 0x00000800) >> 9)
|
1100 |
-
,
|
1101 |
-
(($block[0] & 0x10000040) << 3) | (($block[1] & 0x10000040) << 2) |
|
1102 |
-
(($block[0] & 0x00100000) << 9) | (($block[1] & 0x00100000) << 8) |
|
1103 |
-
(($block[0] & 0x00001000) << 15) | (($block[1] & 0x00001000) << 14) |
|
1104 |
-
(($block[0] & 0x00000010) << 21) | (($block[1] & 0x00000010) << 20) |
|
1105 |
-
(($block[0] & 0x20000080) >> 6) | (($block[1] & 0x20000080) >> 7) |
|
1106 |
-
( $block[0] & 0x00200000 ) | (($block[1] & 0x00200000) >> 1) |
|
1107 |
-
(($block[0] & 0x00002000) << 6) | (($block[1] & 0x00002000) << 5) |
|
1108 |
-
(($block[0] & 0x00000020) << 12) | (($block[1] & 0x00000020) << 11) |
|
1109 |
-
(($block[0] & 0x40000000) >> 15) | (($block[1] & 0x40000000) >> 16) |
|
1110 |
-
(($block[0] & 0x00400000) >> 9) | (($block[1] & 0x00400000) >> 10) |
|
1111 |
-
(($block[0] & 0x00004000) >> 3) | (($block[1] & 0x00004000) >> 4) |
|
1112 |
-
(($block[0] & 0x00800000) >> 18) | (($block[1] & 0x00800000) >> 19) |
|
1113 |
-
(($block[0] & 0x00008000) >> 12) | (($block[1] & 0x00008000) >> 13) |
|
1114 |
-
($msb[0] << 7) | ($msb[1] << 6)
|
1115 |
-
);
|
1116 |
-
|
1117 |
-
return pack('NN', $block[0], $block[1]);
|
1118 |
-
}
|
1119 |
-
|
1120 |
-
/**
|
1121 |
-
* Creates the key schedule.
|
1122 |
-
*
|
1123 |
-
* @access private
|
1124 |
-
* @param String $key
|
1125 |
-
* @return Array
|
1126 |
-
*/
|
1127 |
-
function _prepareKey($key)
|
1128 |
-
{
|
1129 |
-
static $shifts = array( // number of key bits shifted per round
|
1130 |
-
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
1131 |
-
);
|
1132 |
-
|
1133 |
-
// pad the key and remove extra characters as appropriate.
|
1134 |
-
$key = str_pad(substr($key, 0, 8), 8, chr(0));
|
1135 |
-
|
1136 |
-
$temp = unpack('Na/Nb', $key);
|
1137 |
-
$key = array($temp['a'], $temp['b']);
|
1138 |
-
$msb = array(
|
1139 |
-
($key[0] >> 31) & 1,
|
1140 |
-
($key[1] >> 31) & 1
|
1141 |
-
);
|
1142 |
-
$key[0] &= 0x7FFFFFFF;
|
1143 |
-
$key[1] &= 0x7FFFFFFF;
|
1144 |
-
|
1145 |
-
$key = array(
|
1146 |
-
(($key[1] & 0x00000002) << 26) | (($key[1] & 0x00000204) << 17) |
|
1147 |
-
(($key[1] & 0x00020408) << 8) | (($key[1] & 0x02040800) >> 1) |
|
1148 |
-
(($key[0] & 0x00000002) << 22) | (($key[0] & 0x00000204) << 13) |
|
1149 |
-
(($key[0] & 0x00020408) << 4) | (($key[0] & 0x02040800) >> 5) |
|
1150 |
-
(($key[1] & 0x04080000) >> 10) | (($key[0] & 0x04080000) >> 14) |
|
1151 |
-
(($key[1] & 0x08000000) >> 19) | (($key[0] & 0x08000000) >> 23) |
|
1152 |
-
(($key[0] & 0x00000010) >> 1) | (($key[0] & 0x00001000) >> 10) |
|
1153 |
-
(($key[0] & 0x00100000) >> 19) | (($key[0] & 0x10000000) >> 28)
|
1154 |
-
,
|
1155 |
-
(($key[1] & 0x00000080) << 20) | (($key[1] & 0x00008000) << 11) |
|
1156 |
-
(($key[1] & 0x00800000) << 2) | (($key[0] & 0x00000080) << 16) |
|
1157 |
-
(($key[0] & 0x00008000) << 7) | (($key[0] & 0x00800000) >> 2) |
|
1158 |
-
(($key[1] & 0x00000040) << 13) | (($key[1] & 0x00004000) << 4) |
|
1159 |
-
(($key[1] & 0x00400000) >> 5) | (($key[1] & 0x40000000) >> 14) |
|
1160 |
-
(($key[0] & 0x00000040) << 9) | ( $key[0] & 0x00004000 ) |
|
1161 |
-
(($key[0] & 0x00400000) >> 9) | (($key[0] & 0x40000000) >> 18) |
|
1162 |
-
(($key[1] & 0x00000020) << 6) | (($key[1] & 0x00002000) >> 3) |
|
1163 |
-
(($key[1] & 0x00200000) >> 12) | (($key[1] & 0x20000000) >> 21) |
|
1164 |
-
(($key[0] & 0x00000020) << 2) | (($key[0] & 0x00002000) >> 7) |
|
1165 |
-
(($key[0] & 0x00200000) >> 16) | (($key[0] & 0x20000000) >> 25) |
|
1166 |
-
(($key[1] & 0x00000010) >> 1) | (($key[1] & 0x00001000) >> 10) |
|
1167 |
-
(($key[1] & 0x00100000) >> 19) | (($key[1] & 0x10000000) >> 28) |
|
1168 |
-
($msb[1] << 24) | ($msb[0] << 20)
|
1169 |
-
);
|
1170 |
-
|
1171 |
-
$keys = array();
|
1172 |
-
for ($i = 0; $i < 16; $i++) {
|
1173 |
-
$key[0] <<= $shifts[$i];
|
1174 |
-
$temp = ($key[0] & 0xF0000000) >> 28;
|
1175 |
-
$key[0] = ($key[0] | $temp) & 0x0FFFFFFF;
|
1176 |
-
|
1177 |
-
$key[1] <<= $shifts[$i];
|
1178 |
-
$temp = ($key[1] & 0xF0000000) >> 28;
|
1179 |
-
$key[1] = ($key[1] | $temp) & 0x0FFFFFFF;
|
1180 |
-
|
1181 |
-
$temp = array(
|
1182 |
-
(($key[1] & 0x00004000) >> 9) | (($key[1] & 0x00000800) >> 7) |
|
1183 |
-
(($key[1] & 0x00020000) >> 14) | (($key[1] & 0x00000010) >> 2) |
|
1184 |
-
(($key[1] & 0x08000000) >> 26) | (($key[1] & 0x00800000) >> 23)
|
1185 |
-
,
|
1186 |
-
(($key[1] & 0x02400000) >> 20) | (($key[1] & 0x00000001) << 4) |
|
1187 |
-
(($key[1] & 0x00002000) >> 10) | (($key[1] & 0x00040000) >> 18) |
|
1188 |
-
(($key[1] & 0x00000080) >> 6)
|
1189 |
-
,
|
1190 |
-
( $key[1] & 0x00000020 ) | (($key[1] & 0x00000200) >> 5) |
|
1191 |
-
(($key[1] & 0x00010000) >> 13) | (($key[1] & 0x01000000) >> 22) |
|
1192 |
-
(($key[1] & 0x00000004) >> 1) | (($key[1] & 0x00100000) >> 20)
|
1193 |
-
,
|
1194 |
-
(($key[1] & 0x00001000) >> 7) | (($key[1] & 0x00200000) >> 17) |
|
1195 |
-
(($key[1] & 0x00000002) << 2) | (($key[1] & 0x00000100) >> 6) |
|
1196 |
-
(($key[1] & 0x00008000) >> 14) | (($key[1] & 0x04000000) >> 26)
|
1197 |
-
,
|
1198 |
-
(($key[0] & 0x00008000) >> 10) | ( $key[0] & 0x00000010 ) |
|
1199 |
-
(($key[0] & 0x02000000) >> 22) | (($key[0] & 0x00080000) >> 17) |
|
1200 |
-
(($key[0] & 0x00000200) >> 8) | (($key[0] & 0x00000002) >> 1)
|
1201 |
-
,
|
1202 |
-
(($key[0] & 0x04000000) >> 21) | (($key[0] & 0x00010000) >> 12) |
|
1203 |
-
(($key[0] & 0x00000020) >> 2) | (($key[0] & 0x00000800) >> 9) |
|
1204 |
-
(($key[0] & 0x00800000) >> 22) | (($key[0] & 0x00000100) >> 8)
|
1205 |
-
,
|
1206 |
-
(($key[0] & 0x00001000) >> 7) | (($key[0] & 0x00000088) >> 3) |
|
1207 |
-
(($key[0] & 0x00020000) >> 14) | (($key[0] & 0x00000001) << 2) |
|
1208 |
-
(($key[0] & 0x00400000) >> 21)
|
1209 |
-
,
|
1210 |
-
(($key[0] & 0x00000400) >> 5) | (($key[0] & 0x00004000) >> 10) |
|
1211 |
-
(($key[0] & 0x00000040) >> 3) | (($key[0] & 0x00100000) >> 18) |
|
1212 |
-
(($key[0] & 0x08000000) >> 26) | (($key[0] & 0x01000000) >> 24)
|
1213 |
-
);
|
1214 |
-
|
1215 |
-
$keys[] = $temp;
|
1216 |
-
}
|
1217 |
-
|
1218 |
-
$temp = array(
|
1219 |
-
CRYPT_DES_ENCRYPT => $keys,
|
1220 |
-
CRYPT_DES_DECRYPT => array_reverse($keys)
|
1221 |
-
);
|
1222 |
-
|
1223 |
-
return $temp;
|
1224 |
-
}
|
1225 |
-
|
1226 |
-
/**
|
1227 |
-
* String Shift
|
1228 |
-
*
|
1229 |
-
* Inspired by array_shift
|
1230 |
-
*
|
1231 |
-
* @param String $string
|
1232 |
-
* @param optional Integer $index
|
1233 |
-
* @return String
|
1234 |
-
* @access private
|
1235 |
-
*/
|
1236 |
-
function _string_shift(&$string, $index = 1)
|
1237 |
-
{
|
1238 |
-
$substr = substr($string, 0, $index);
|
1239 |
-
$string = substr($string, $index);
|
1240 |
-
return $substr;
|
1241 |
-
}
|
1242 |
-
}
|
1243 |
-
|
1244 |
-
// vim: ts=4:sw=4:et:
|
1245 |
-
// vim6: fdl=1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/Hash.php
DELETED
@@ -1,824 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
6 |
-
*
|
7 |
-
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
|
8 |
-
*
|
9 |
-
* md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
|
10 |
-
*
|
11 |
-
* If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
|
12 |
-
* the hash. If no valid algorithm is provided, sha1 will be used.
|
13 |
-
*
|
14 |
-
* PHP versions 4 and 5
|
15 |
-
*
|
16 |
-
* {@internal The variable names are the same as those in
|
17 |
-
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
|
18 |
-
*
|
19 |
-
* Here's a short example of how to use this library:
|
20 |
-
* <code>
|
21 |
-
* <?php
|
22 |
-
* include('Crypt/Hash.php');
|
23 |
-
*
|
24 |
-
* $hash = new Crypt_Hash('sha1');
|
25 |
-
*
|
26 |
-
* $hash->setKey('abcdefg');
|
27 |
-
*
|
28 |
-
* echo base64_encode($hash->hash('abcdefg'));
|
29 |
-
* ?>
|
30 |
-
* </code>
|
31 |
-
*
|
32 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
33 |
-
* of this software and associated documentation files (the "Software"), to deal
|
34 |
-
* in the Software without restriction, including without limitation the rights
|
35 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
36 |
-
* copies of the Software, and to permit persons to whom the Software is
|
37 |
-
* furnished to do so, subject to the following conditions:
|
38 |
-
*
|
39 |
-
* The above copyright notice and this permission notice shall be included in
|
40 |
-
* all copies or substantial portions of the Software.
|
41 |
-
*
|
42 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
43 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
44 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
45 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
46 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
47 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
48 |
-
* THE SOFTWARE.
|
49 |
-
*
|
50 |
-
* @category Crypt
|
51 |
-
* @package Crypt_Hash
|
52 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
53 |
-
* @copyright MMVII Jim Wigginton
|
54 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
55 |
-
* @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
|
56 |
-
* @link http://phpseclib.sourceforge.net
|
57 |
-
*/
|
58 |
-
|
59 |
-
/**#@+
|
60 |
-
* @access private
|
61 |
-
* @see Crypt_Hash::Crypt_Hash()
|
62 |
-
*/
|
63 |
-
/**
|
64 |
-
* Toggles the internal implementation
|
65 |
-
*/
|
66 |
-
define('CRYPT_HASH_MODE_INTERNAL', 1);
|
67 |
-
/**
|
68 |
-
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
|
69 |
-
*/
|
70 |
-
define('CRYPT_HASH_MODE_MHASH', 2);
|
71 |
-
/**
|
72 |
-
* Toggles the hash() implementation, which works on PHP 5.1.2+.
|
73 |
-
*/
|
74 |
-
define('CRYPT_HASH_MODE_HASH', 3);
|
75 |
-
/**#@-*/
|
76 |
-
|
77 |
-
/**
|
78 |
-
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
79 |
-
*
|
80 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
81 |
-
* @version 0.1.0
|
82 |
-
* @access public
|
83 |
-
* @package Crypt_Hash
|
84 |
-
*/
|
85 |
-
class Crypt_Hash {
|
86 |
-
/**
|
87 |
-
* Byte-length of compression blocks / key (Internal HMAC)
|
88 |
-
*
|
89 |
-
* @see Crypt_Hash::setAlgorithm()
|
90 |
-
* @var Integer
|
91 |
-
* @access private
|
92 |
-
*/
|
93 |
-
var $b;
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Byte-length of hash output (Internal HMAC)
|
97 |
-
*
|
98 |
-
* @see Crypt_Hash::setHash()
|
99 |
-
* @var Integer
|
100 |
-
* @access private
|
101 |
-
*/
|
102 |
-
var $l = false;
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Hash Algorithm
|
106 |
-
*
|
107 |
-
* @see Crypt_Hash::setHash()
|
108 |
-
* @var String
|
109 |
-
* @access private
|
110 |
-
*/
|
111 |
-
var $hash;
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Key
|
115 |
-
*
|
116 |
-
* @see Crypt_Hash::setKey()
|
117 |
-
* @var String
|
118 |
-
* @access private
|
119 |
-
*/
|
120 |
-
var $key = '';
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Outer XOR (Internal HMAC)
|
124 |
-
*
|
125 |
-
* @see Crypt_Hash::setKey()
|
126 |
-
* @var String
|
127 |
-
* @access private
|
128 |
-
*/
|
129 |
-
var $opad;
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Inner XOR (Internal HMAC)
|
133 |
-
*
|
134 |
-
* @see Crypt_Hash::setKey()
|
135 |
-
* @var String
|
136 |
-
* @access private
|
137 |
-
*/
|
138 |
-
var $ipad;
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Default Constructor.
|
142 |
-
*
|
143 |
-
* @param optional String $hash
|
144 |
-
* @return Crypt_Hash
|
145 |
-
* @access public
|
146 |
-
*/
|
147 |
-
function Crypt_Hash($hash = 'sha1')
|
148 |
-
{
|
149 |
-
if ( !defined('CRYPT_HASH_MODE') ) {
|
150 |
-
switch (true) {
|
151 |
-
case extension_loaded('hash'):
|
152 |
-
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
|
153 |
-
break;
|
154 |
-
case extension_loaded('mhash'):
|
155 |
-
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
|
156 |
-
break;
|
157 |
-
default:
|
158 |
-
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
|
159 |
-
}
|
160 |
-
}
|
161 |
-
|
162 |
-
$this->setHash($hash);
|
163 |
-
}
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Sets the key for HMACs
|
167 |
-
*
|
168 |
-
* Keys can be of any length.
|
169 |
-
*
|
170 |
-
* @access public
|
171 |
-
* @param String $key
|
172 |
-
*/
|
173 |
-
function setKey($key)
|
174 |
-
{
|
175 |
-
$this->key = $key;
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* Sets the hash function.
|
180 |
-
*
|
181 |
-
* @access public
|
182 |
-
* @param String $hash
|
183 |
-
*/
|
184 |
-
function setHash($hash)
|
185 |
-
{
|
186 |
-
switch ($hash) {
|
187 |
-
case 'md5-96':
|
188 |
-
case 'sha1-96':
|
189 |
-
$this->l = 12; // 96 / 8 = 12
|
190 |
-
break;
|
191 |
-
case 'md2':
|
192 |
-
case 'md5':
|
193 |
-
$this->l = 16;
|
194 |
-
break;
|
195 |
-
case 'sha1':
|
196 |
-
$this->l = 20;
|
197 |
-
break;
|
198 |
-
case 'sha256':
|
199 |
-
$this->l = 32;
|
200 |
-
break;
|
201 |
-
case 'sha384':
|
202 |
-
$this->l = 48;
|
203 |
-
break;
|
204 |
-
case 'sha512':
|
205 |
-
$this->l = 64;
|
206 |
-
}
|
207 |
-
|
208 |
-
switch ($hash) {
|
209 |
-
case 'md2':
|
210 |
-
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
|
211 |
-
CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
|
212 |
-
break;
|
213 |
-
case 'sha384':
|
214 |
-
case 'sha512':
|
215 |
-
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
216 |
-
break;
|
217 |
-
default:
|
218 |
-
$mode = CRYPT_HASH_MODE;
|
219 |
-
}
|
220 |
-
|
221 |
-
switch ( $mode ) {
|
222 |
-
case CRYPT_HASH_MODE_MHASH:
|
223 |
-
switch ($hash) {
|
224 |
-
case 'md5':
|
225 |
-
case 'md5-96':
|
226 |
-
$this->hash = MHASH_MD5;
|
227 |
-
break;
|
228 |
-
case 'sha256':
|
229 |
-
$this->hash = MHASH_SHA256;
|
230 |
-
break;
|
231 |
-
case 'sha1':
|
232 |
-
case 'sha1-96':
|
233 |
-
default:
|
234 |
-
$this->hash = MHASH_SHA1;
|
235 |
-
}
|
236 |
-
return;
|
237 |
-
case CRYPT_HASH_MODE_HASH:
|
238 |
-
switch ($hash) {
|
239 |
-
case 'md5':
|
240 |
-
case 'md5-96':
|
241 |
-
$this->hash = 'md5';
|
242 |
-
return;
|
243 |
-
case 'md2':
|
244 |
-
case 'sha256':
|
245 |
-
case 'sha384':
|
246 |
-
case 'sha512':
|
247 |
-
$this->hash = $hash;
|
248 |
-
return;
|
249 |
-
case 'sha1':
|
250 |
-
case 'sha1-96':
|
251 |
-
default:
|
252 |
-
$this->hash = 'sha1';
|
253 |
-
}
|
254 |
-
return;
|
255 |
-
}
|
256 |
-
|
257 |
-
switch ($hash) {
|
258 |
-
case 'md2':
|
259 |
-
$this->b = 16;
|
260 |
-
$this->hash = array($this, '_md2');
|
261 |
-
break;
|
262 |
-
case 'md5':
|
263 |
-
case 'md5-96':
|
264 |
-
$this->b = 64;
|
265 |
-
$this->hash = array($this, '_md5');
|
266 |
-
break;
|
267 |
-
case 'sha256':
|
268 |
-
$this->b = 64;
|
269 |
-
$this->hash = array($this, '_sha256');
|
270 |
-
break;
|
271 |
-
case 'sha384':
|
272 |
-
case 'sha512':
|
273 |
-
$this->b = 128;
|
274 |
-
$this->hash = array($this, '_sha512');
|
275 |
-
break;
|
276 |
-
case 'sha1':
|
277 |
-
case 'sha1-96':
|
278 |
-
default:
|
279 |
-
$this->b = 64;
|
280 |
-
$this->hash = array($this, '_sha1');
|
281 |
-
}
|
282 |
-
|
283 |
-
$this->ipad = str_repeat(chr(0x36), $this->b);
|
284 |
-
$this->opad = str_repeat(chr(0x5C), $this->b);
|
285 |
-
}
|
286 |
-
|
287 |
-
/**
|
288 |
-
* Compute the HMAC.
|
289 |
-
*
|
290 |
-
* @access public
|
291 |
-
* @param String $text
|
292 |
-
* @return String
|
293 |
-
*/
|
294 |
-
function hash($text)
|
295 |
-
{
|
296 |
-
$mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
297 |
-
|
298 |
-
if (!empty($this->key)) {
|
299 |
-
switch ( $mode ) {
|
300 |
-
case CRYPT_HASH_MODE_MHASH:
|
301 |
-
$output = mhash($this->hash, $text, $this->key);
|
302 |
-
break;
|
303 |
-
case CRYPT_HASH_MODE_HASH:
|
304 |
-
$output = hash_hmac($this->hash, $text, $this->key, true);
|
305 |
-
break;
|
306 |
-
case CRYPT_HASH_MODE_INTERNAL:
|
307 |
-
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
308 |
-
resultant L byte string as the actual key to HMAC."
|
309 |
-
|
310 |
-
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
311 |
-
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
|
312 |
-
|
313 |
-
$key = str_pad($key, $this->b, chr(0)); // step 1
|
314 |
-
$temp = $this->ipad ^ $key; // step 2
|
315 |
-
$temp .= $text; // step 3
|
316 |
-
$temp = call_user_func($this->hash, $temp); // step 4
|
317 |
-
$output = $this->opad ^ $key; // step 5
|
318 |
-
$output.= $temp; // step 6
|
319 |
-
$output = call_user_func($this->hash, $output); // step 7
|
320 |
-
}
|
321 |
-
} else {
|
322 |
-
switch ( $mode ) {
|
323 |
-
case CRYPT_HASH_MODE_MHASH:
|
324 |
-
$output = mhash($this->hash, $text);
|
325 |
-
break;
|
326 |
-
case CRYPT_HASH_MODE_HASH:
|
327 |
-
$output = hash($this->hash, $text, true);
|
328 |
-
break;
|
329 |
-
case CRYPT_HASH_MODE_INTERNAL:
|
330 |
-
$output = call_user_func($this->hash, $text);
|
331 |
-
}
|
332 |
-
}
|
333 |
-
|
334 |
-
return substr($output, 0, $this->l);
|
335 |
-
}
|
336 |
-
|
337 |
-
/**
|
338 |
-
* Returns the hash length (in bytes)
|
339 |
-
*
|
340 |
-
* @access public
|
341 |
-
* @return Integer
|
342 |
-
*/
|
343 |
-
function getLength()
|
344 |
-
{
|
345 |
-
return $this->l;
|
346 |
-
}
|
347 |
-
|
348 |
-
/**
|
349 |
-
* Wrapper for MD5
|
350 |
-
*
|
351 |
-
* @access private
|
352 |
-
* @param String $text
|
353 |
-
*/
|
354 |
-
function _md5($m)
|
355 |
-
{
|
356 |
-
return pack('H*', md5($m));
|
357 |
-
}
|
358 |
-
|
359 |
-
/**
|
360 |
-
* Wrapper for SHA1
|
361 |
-
*
|
362 |
-
* @access private
|
363 |
-
* @param String $text
|
364 |
-
*/
|
365 |
-
function _sha1($m)
|
366 |
-
{
|
367 |
-
return pack('H*', sha1($m));
|
368 |
-
}
|
369 |
-
|
370 |
-
/**
|
371 |
-
* Pure-PHP implementation of MD2
|
372 |
-
*
|
373 |
-
* See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
|
374 |
-
*
|
375 |
-
* @access private
|
376 |
-
* @param String $text
|
377 |
-
*/
|
378 |
-
function _md2($m)
|
379 |
-
{
|
380 |
-
static $s = array(
|
381 |
-
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
382 |
-
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
383 |
-
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
384 |
-
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
385 |
-
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
386 |
-
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
387 |
-
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
388 |
-
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
389 |
-
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
390 |
-
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
391 |
-
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
392 |
-
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
393 |
-
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
394 |
-
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
395 |
-
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
396 |
-
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
397 |
-
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
398 |
-
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
399 |
-
);
|
400 |
-
|
401 |
-
// Step 1. Append Padding Bytes
|
402 |
-
$pad = 16 - (strlen($m) & 0xF);
|
403 |
-
$m.= str_repeat(chr($pad), $pad);
|
404 |
-
|
405 |
-
$length = strlen($m);
|
406 |
-
|
407 |
-
// Step 2. Append Checksum
|
408 |
-
$c = str_repeat(chr(0), 16);
|
409 |
-
$l = chr(0);
|
410 |
-
for ($i = 0; $i < $length; $i+= 16) {
|
411 |
-
for ($j = 0; $j < 16; $j++) {
|
412 |
-
// RFC1319 incorrectly states that C[j] should be set to S[c xor L]
|
413 |
-
//$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
|
414 |
-
// per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
|
415 |
-
$c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
|
416 |
-
$l = $c[$j];
|
417 |
-
}
|
418 |
-
}
|
419 |
-
$m.= $c;
|
420 |
-
|
421 |
-
$length+= 16;
|
422 |
-
|
423 |
-
// Step 3. Initialize MD Buffer
|
424 |
-
$x = str_repeat(chr(0), 48);
|
425 |
-
|
426 |
-
// Step 4. Process Message in 16-Byte Blocks
|
427 |
-
for ($i = 0; $i < $length; $i+= 16) {
|
428 |
-
for ($j = 0; $j < 16; $j++) {
|
429 |
-
$x[$j + 16] = $m[$i + $j];
|
430 |
-
$x[$j + 32] = $x[$j + 16] ^ $x[$j];
|
431 |
-
}
|
432 |
-
$t = chr(0);
|
433 |
-
for ($j = 0; $j < 18; $j++) {
|
434 |
-
for ($k = 0; $k < 48; $k++) {
|
435 |
-
$x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
|
436 |
-
//$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
|
437 |
-
}
|
438 |
-
$t = chr(ord($t) + $j);
|
439 |
-
}
|
440 |
-
}
|
441 |
-
|
442 |
-
// Step 5. Output
|
443 |
-
return substr($x, 0, 16);
|
444 |
-
}
|
445 |
-
|
446 |
-
/**
|
447 |
-
* Pure-PHP implementation of SHA256
|
448 |
-
*
|
449 |
-
* 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}.
|
450 |
-
*
|
451 |
-
* @access private
|
452 |
-
* @param String $text
|
453 |
-
*/
|
454 |
-
function _sha256($m)
|
455 |
-
{
|
456 |
-
if (extension_loaded('suhosin')) {
|
457 |
-
return pack('H*', sha256($m));
|
458 |
-
}
|
459 |
-
|
460 |
-
// Initialize variables
|
461 |
-
$hash = array(
|
462 |
-
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
463 |
-
);
|
464 |
-
// Initialize table of round constants
|
465 |
-
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
|
466 |
-
static $k = array(
|
467 |
-
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
468 |
-
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
469 |
-
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
470 |
-
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
471 |
-
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
472 |
-
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
473 |
-
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
474 |
-
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
475 |
-
);
|
476 |
-
|
477 |
-
// Pre-processing
|
478 |
-
$length = strlen($m);
|
479 |
-
// to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
|
480 |
-
$m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
|
481 |
-
$m[$length] = chr(0x80);
|
482 |
-
// we don't support hashing strings 512MB long
|
483 |
-
$m.= pack('N2', 0, $length << 3);
|
484 |
-
|
485 |
-
// Process the message in successive 512-bit chunks
|
486 |
-
$chunks = str_split($m, 64);
|
487 |
-
foreach ($chunks as $chunk) {
|
488 |
-
$w = array();
|
489 |
-
for ($i = 0; $i < 16; $i++) {
|
490 |
-
extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
|
491 |
-
$w[] = $temp;
|
492 |
-
}
|
493 |
-
|
494 |
-
// Extend the sixteen 32-bit words into sixty-four 32-bit words
|
495 |
-
for ($i = 16; $i < 64; $i++) {
|
496 |
-
$s0 = $this->_rightRotate($w[$i - 15], 7) ^
|
497 |
-
$this->_rightRotate($w[$i - 15], 18) ^
|
498 |
-
$this->_rightShift( $w[$i - 15], 3);
|
499 |
-
$s1 = $this->_rightRotate($w[$i - 2], 17) ^
|
500 |
-
$this->_rightRotate($w[$i - 2], 19) ^
|
501 |
-
$this->_rightShift( $w[$i - 2], 10);
|
502 |
-
$w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
|
503 |
-
|
504 |
-
}
|
505 |
-
|
506 |
-
// Initialize hash value for this chunk
|
507 |
-
list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
|
508 |
-
|
509 |
-
// Main loop
|
510 |
-
for ($i = 0; $i < 64; $i++) {
|
511 |
-
$s0 = $this->_rightRotate($a, 2) ^
|
512 |
-
$this->_rightRotate($a, 13) ^
|
513 |
-
$this->_rightRotate($a, 22);
|
514 |
-
$maj = ($a & $b) ^
|
515 |
-
($a & $c) ^
|
516 |
-
($b & $c);
|
517 |
-
$t2 = $this->_add($s0, $maj);
|
518 |
-
|
519 |
-
$s1 = $this->_rightRotate($e, 6) ^
|
520 |
-
$this->_rightRotate($e, 11) ^
|
521 |
-
$this->_rightRotate($e, 25);
|
522 |
-
$ch = ($e & $f) ^
|
523 |
-
($this->_not($e) & $g);
|
524 |
-
$t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
|
525 |
-
|
526 |
-
$h = $g;
|
527 |
-
$g = $f;
|
528 |
-
$f = $e;
|
529 |
-
$e = $this->_add($d, $t1);
|
530 |
-
$d = $c;
|
531 |
-
$c = $b;
|
532 |
-
$b = $a;
|
533 |
-
$a = $this->_add($t1, $t2);
|
534 |
-
}
|
535 |
-
|
536 |
-
// Add this chunk's hash to result so far
|
537 |
-
$hash = array(
|
538 |
-
$this->_add($hash[0], $a),
|
539 |
-
$this->_add($hash[1], $b),
|
540 |
-
$this->_add($hash[2], $c),
|
541 |
-
$this->_add($hash[3], $d),
|
542 |
-
$this->_add($hash[4], $e),
|
543 |
-
$this->_add($hash[5], $f),
|
544 |
-
$this->_add($hash[6], $g),
|
545 |
-
$this->_add($hash[7], $h)
|
546 |
-
);
|
547 |
-
}
|
548 |
-
|
549 |
-
// Produce the final hash value (big-endian)
|
550 |
-
return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
|
551 |
-
}
|
552 |
-
|
553 |
-
/**
|
554 |
-
* Pure-PHP implementation of SHA384 and SHA512
|
555 |
-
*
|
556 |
-
* @access private
|
557 |
-
* @param String $text
|
558 |
-
*/
|
559 |
-
function _sha512($m)
|
560 |
-
{
|
561 |
-
if (!class_exists('Math_BigInteger')) {
|
562 |
-
require_once('Math/BigInteger.php');
|
563 |
-
}
|
564 |
-
|
565 |
-
static $init384, $init512, $k;
|
566 |
-
|
567 |
-
if (!isset($k)) {
|
568 |
-
// Initialize variables
|
569 |
-
$init384 = array( // initial values for SHA384
|
570 |
-
'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
|
571 |
-
'67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
|
572 |
-
);
|
573 |
-
$init512 = array( // initial values for SHA512
|
574 |
-
'6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
|
575 |
-
'510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
|
576 |
-
);
|
577 |
-
|
578 |
-
for ($i = 0; $i < 8; $i++) {
|
579 |
-
$init384[$i] = new Math_BigInteger($init384[$i], 16);
|
580 |
-
$init384[$i]->setPrecision(64);
|
581 |
-
$init512[$i] = new Math_BigInteger($init512[$i], 16);
|
582 |
-
$init512[$i]->setPrecision(64);
|
583 |
-
}
|
584 |
-
|
585 |
-
// Initialize table of round constants
|
586 |
-
// (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
|
587 |
-
$k = array(
|
588 |
-
'428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
|
589 |
-
'3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
|
590 |
-
'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
|
591 |
-
'72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
|
592 |
-
'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
|
593 |
-
'2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
|
594 |
-
'983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
|
595 |
-
'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
|
596 |
-
'27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
|
597 |
-
'650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
|
598 |
-
'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
|
599 |
-
'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
|
600 |
-
'19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
|
601 |
-
'391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
|
602 |
-
'748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
|
603 |
-
'90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
|
604 |
-
'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
|
605 |
-
'06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
|
606 |
-
'28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
|
607 |
-
'4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
|
608 |
-
);
|
609 |
-
|
610 |
-
for ($i = 0; $i < 80; $i++) {
|
611 |
-
$k[$i] = new Math_BigInteger($k[$i], 16);
|
612 |
-
}
|
613 |
-
}
|
614 |
-
|
615 |
-
$hash = $this->l == 48 ? $init384 : $init512;
|
616 |
-
|
617 |
-
// Pre-processing
|
618 |
-
$length = strlen($m);
|
619 |
-
// to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
|
620 |
-
$m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
|
621 |
-
$m[$length] = chr(0x80);
|
622 |
-
// we don't support hashing strings 512MB long
|
623 |
-
$m.= pack('N4', 0, 0, 0, $length << 3);
|
624 |
-
|
625 |
-
// Process the message in successive 1024-bit chunks
|
626 |
-
$chunks = str_split($m, 128);
|
627 |
-
foreach ($chunks as $chunk) {
|
628 |
-
$w = array();
|
629 |
-
for ($i = 0; $i < 16; $i++) {
|
630 |
-
$temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
|
631 |
-
$temp->setPrecision(64);
|
632 |
-
$w[] = $temp;
|
633 |
-
}
|
634 |
-
|
635 |
-
// Extend the sixteen 32-bit words into eighty 32-bit words
|
636 |
-
for ($i = 16; $i < 80; $i++) {
|
637 |
-
$temp = array(
|
638 |
-
$w[$i - 15]->bitwise_rightRotate(1),
|
639 |
-
$w[$i - 15]->bitwise_rightRotate(8),
|
640 |
-
$w[$i - 15]->bitwise_rightShift(7)
|
641 |
-
);
|
642 |
-
$s0 = $temp[0]->bitwise_xor($temp[1]);
|
643 |
-
$s0 = $s0->bitwise_xor($temp[2]);
|
644 |
-
$temp = array(
|
645 |
-
$w[$i - 2]->bitwise_rightRotate(19),
|
646 |
-
$w[$i - 2]->bitwise_rightRotate(61),
|
647 |
-
$w[$i - 2]->bitwise_rightShift(6)
|
648 |
-
);
|
649 |
-
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
650 |
-
$s1 = $s1->bitwise_xor($temp[2]);
|
651 |
-
$w[$i] = $w[$i - 16]->copy();
|
652 |
-
$w[$i] = $w[$i]->add($s0);
|
653 |
-
$w[$i] = $w[$i]->add($w[$i - 7]);
|
654 |
-
$w[$i] = $w[$i]->add($s1);
|
655 |
-
}
|
656 |
-
|
657 |
-
// Initialize hash value for this chunk
|
658 |
-
$a = $hash[0]->copy();
|
659 |
-
$b = $hash[1]->copy();
|
660 |
-
$c = $hash[2]->copy();
|
661 |
-
$d = $hash[3]->copy();
|
662 |
-
$e = $hash[4]->copy();
|
663 |
-
$f = $hash[5]->copy();
|
664 |
-
$g = $hash[6]->copy();
|
665 |
-
$h = $hash[7]->copy();
|
666 |
-
|
667 |
-
// Main loop
|
668 |
-
for ($i = 0; $i < 80; $i++) {
|
669 |
-
$temp = array(
|
670 |
-
$a->bitwise_rightRotate(28),
|
671 |
-
$a->bitwise_rightRotate(34),
|
672 |
-
$a->bitwise_rightRotate(39)
|
673 |
-
);
|
674 |
-
$s0 = $temp[0]->bitwise_xor($temp[1]);
|
675 |
-
$s0 = $s0->bitwise_xor($temp[2]);
|
676 |
-
$temp = array(
|
677 |
-
$a->bitwise_and($b),
|
678 |
-
$a->bitwise_and($c),
|
679 |
-
$b->bitwise_and($c)
|
680 |
-
);
|
681 |
-
$maj = $temp[0]->bitwise_xor($temp[1]);
|
682 |
-
$maj = $maj->bitwise_xor($temp[2]);
|
683 |
-
$t2 = $s0->add($maj);
|
684 |
-
|
685 |
-
$temp = array(
|
686 |
-
$e->bitwise_rightRotate(14),
|
687 |
-
$e->bitwise_rightRotate(18),
|
688 |
-
$e->bitwise_rightRotate(41)
|
689 |
-
);
|
690 |
-
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
691 |
-
$s1 = $s1->bitwise_xor($temp[2]);
|
692 |
-
$temp = array(
|
693 |
-
$e->bitwise_and($f),
|
694 |
-
$g->bitwise_and($e->bitwise_not())
|
695 |
-
);
|
696 |
-
$ch = $temp[0]->bitwise_xor($temp[1]);
|
697 |
-
$t1 = $h->add($s1);
|
698 |
-
$t1 = $t1->add($ch);
|
699 |
-
$t1 = $t1->add($k[$i]);
|
700 |
-
$t1 = $t1->add($w[$i]);
|
701 |
-
|
702 |
-
$h = $g->copy();
|
703 |
-
$g = $f->copy();
|
704 |
-
$f = $e->copy();
|
705 |
-
$e = $d->add($t1);
|
706 |
-
$d = $c->copy();
|
707 |
-
$c = $b->copy();
|
708 |
-
$b = $a->copy();
|
709 |
-
$a = $t1->add($t2);
|
710 |
-
}
|
711 |
-
|
712 |
-
// Add this chunk's hash to result so far
|
713 |
-
$hash = array(
|
714 |
-
$hash[0]->add($a),
|
715 |
-
$hash[1]->add($b),
|
716 |
-
$hash[2]->add($c),
|
717 |
-
$hash[3]->add($d),
|
718 |
-
$hash[4]->add($e),
|
719 |
-
$hash[5]->add($f),
|
720 |
-
$hash[6]->add($g),
|
721 |
-
$hash[7]->add($h)
|
722 |
-
);
|
723 |
-
}
|
724 |
-
|
725 |
-
// Produce the final hash value (big-endian)
|
726 |
-
// (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
|
727 |
-
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
|
728 |
-
$hash[4]->toBytes() . $hash[5]->toBytes();
|
729 |
-
if ($this->l != 48) {
|
730 |
-
$temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
|
731 |
-
}
|
732 |
-
|
733 |
-
return $temp;
|
734 |
-
}
|
735 |
-
|
736 |
-
/**
|
737 |
-
* Right Rotate
|
738 |
-
*
|
739 |
-
* @access private
|
740 |
-
* @param Integer $int
|
741 |
-
* @param Integer $amt
|
742 |
-
* @see _sha256()
|
743 |
-
* @return Integer
|
744 |
-
*/
|
745 |
-
function _rightRotate($int, $amt)
|
746 |
-
{
|
747 |
-
$invamt = 32 - $amt;
|
748 |
-
$mask = (1 << $invamt) - 1;
|
749 |
-
return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
|
750 |
-
}
|
751 |
-
|
752 |
-
/**
|
753 |
-
* Right Shift
|
754 |
-
*
|
755 |
-
* @access private
|
756 |
-
* @param Integer $int
|
757 |
-
* @param Integer $amt
|
758 |
-
* @see _sha256()
|
759 |
-
* @return Integer
|
760 |
-
*/
|
761 |
-
function _rightShift($int, $amt)
|
762 |
-
{
|
763 |
-
$mask = (1 << (32 - $amt)) - 1;
|
764 |
-
return ($int >> $amt) & $mask;
|
765 |
-
}
|
766 |
-
|
767 |
-
/**
|
768 |
-
* Not
|
769 |
-
*
|
770 |
-
* @access private
|
771 |
-
* @param Integer $int
|
772 |
-
* @see _sha256()
|
773 |
-
* @return Integer
|
774 |
-
*/
|
775 |
-
function _not($int)
|
776 |
-
{
|
777 |
-
return ~$int & 0xFFFFFFFF;
|
778 |
-
}
|
779 |
-
|
780 |
-
/**
|
781 |
-
* Add
|
782 |
-
*
|
783 |
-
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
|
784 |
-
* possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
|
785 |
-
*
|
786 |
-
* @param String $string
|
787 |
-
* @param optional Integer $index
|
788 |
-
* @return String
|
789 |
-
* @see _sha256()
|
790 |
-
* @access private
|
791 |
-
*/
|
792 |
-
function _add()
|
793 |
-
{
|
794 |
-
static $mod;
|
795 |
-
if (!isset($mod)) {
|
796 |
-
$mod = pow(2, 32);
|
797 |
-
}
|
798 |
-
|
799 |
-
$result = 0;
|
800 |
-
$arguments = func_get_args();
|
801 |
-
foreach ($arguments as $argument) {
|
802 |
-
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
803 |
-
}
|
804 |
-
|
805 |
-
return fmod($result, $mod);
|
806 |
-
}
|
807 |
-
|
808 |
-
/**
|
809 |
-
* String Shift
|
810 |
-
*
|
811 |
-
* Inspired by array_shift
|
812 |
-
*
|
813 |
-
* @param String $string
|
814 |
-
* @param optional Integer $index
|
815 |
-
* @return String
|
816 |
-
* @access private
|
817 |
-
*/
|
818 |
-
function _string_shift(&$string, $index = 1)
|
819 |
-
{
|
820 |
-
$substr = substr($string, 0, $index);
|
821 |
-
$string = substr($string, $index);
|
822 |
-
return $substr;
|
823 |
-
}
|
824 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/RC4.php
DELETED
@@ -1,505 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of RC4.
|
6 |
-
*
|
7 |
-
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* Useful resources are as follows:
|
12 |
-
*
|
13 |
-
* - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
|
14 |
-
* - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
|
15 |
-
*
|
16 |
-
* RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
|
17 |
-
* ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.
|
18 |
-
*
|
19 |
-
* Here's a short example of how to use this library:
|
20 |
-
* <code>
|
21 |
-
* <?php
|
22 |
-
* include('Crypt/RC4.php');
|
23 |
-
*
|
24 |
-
* $rc4 = new Crypt_RC4();
|
25 |
-
*
|
26 |
-
* $rc4->setKey('abcdefgh');
|
27 |
-
*
|
28 |
-
* $size = 10 * 1024;
|
29 |
-
* $plaintext = '';
|
30 |
-
* for ($i = 0; $i < $size; $i++) {
|
31 |
-
* $plaintext.= 'a';
|
32 |
-
* }
|
33 |
-
*
|
34 |
-
* echo $rc4->decrypt($rc4->encrypt($plaintext));
|
35 |
-
* ?>
|
36 |
-
* </code>
|
37 |
-
*
|
38 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
39 |
-
* of this software and associated documentation files (the "Software"), to deal
|
40 |
-
* in the Software without restriction, including without limitation the rights
|
41 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
42 |
-
* copies of the Software, and to permit persons to whom the Software is
|
43 |
-
* furnished to do so, subject to the following conditions:
|
44 |
-
*
|
45 |
-
* The above copyright notice and this permission notice shall be included in
|
46 |
-
* all copies or substantial portions of the Software.
|
47 |
-
*
|
48 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
49 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
50 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
51 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
52 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
53 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
54 |
-
* THE SOFTWARE.
|
55 |
-
*
|
56 |
-
* @category Crypt
|
57 |
-
* @package Crypt_RC4
|
58 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
59 |
-
* @copyright MMVII Jim Wigginton
|
60 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
61 |
-
* @version $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $
|
62 |
-
* @link http://phpseclib.sourceforge.net
|
63 |
-
*/
|
64 |
-
|
65 |
-
/**#@+
|
66 |
-
* @access private
|
67 |
-
* @see Crypt_RC4::Crypt_RC4()
|
68 |
-
*/
|
69 |
-
/**
|
70 |
-
* Toggles the internal implementation
|
71 |
-
*/
|
72 |
-
define('CRYPT_RC4_MODE_INTERNAL', 1);
|
73 |
-
/**
|
74 |
-
* Toggles the mcrypt implementation
|
75 |
-
*/
|
76 |
-
define('CRYPT_RC4_MODE_MCRYPT', 2);
|
77 |
-
/**#@-*/
|
78 |
-
|
79 |
-
/**#@+
|
80 |
-
* @access private
|
81 |
-
* @see Crypt_RC4::_crypt()
|
82 |
-
*/
|
83 |
-
define('CRYPT_RC4_ENCRYPT', 0);
|
84 |
-
define('CRYPT_RC4_DECRYPT', 1);
|
85 |
-
/**#@-*/
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Pure-PHP implementation of RC4.
|
89 |
-
*
|
90 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
91 |
-
* @version 0.1.0
|
92 |
-
* @access public
|
93 |
-
* @package Crypt_RC4
|
94 |
-
*/
|
95 |
-
class Crypt_RC4 {
|
96 |
-
/**
|
97 |
-
* The Key
|
98 |
-
*
|
99 |
-
* @see Crypt_RC4::setKey()
|
100 |
-
* @var String
|
101 |
-
* @access private
|
102 |
-
*/
|
103 |
-
var $key = "\0";
|
104 |
-
|
105 |
-
/**
|
106 |
-
* The Key Stream for encryption
|
107 |
-
*
|
108 |
-
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
|
109 |
-
*
|
110 |
-
* @see Crypt_RC4::setKey()
|
111 |
-
* @var Array
|
112 |
-
* @access private
|
113 |
-
*/
|
114 |
-
var $encryptStream = false;
|
115 |
-
|
116 |
-
/**
|
117 |
-
* The Key Stream for decryption
|
118 |
-
*
|
119 |
-
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
|
120 |
-
*
|
121 |
-
* @see Crypt_RC4::setKey()
|
122 |
-
* @var Array
|
123 |
-
* @access private
|
124 |
-
*/
|
125 |
-
var $decryptStream = false;
|
126 |
-
|
127 |
-
/**
|
128 |
-
* The $i and $j indexes for encryption
|
129 |
-
*
|
130 |
-
* @see Crypt_RC4::_crypt()
|
131 |
-
* @var Integer
|
132 |
-
* @access private
|
133 |
-
*/
|
134 |
-
var $encryptIndex = 0;
|
135 |
-
|
136 |
-
/**
|
137 |
-
* The $i and $j indexes for decryption
|
138 |
-
*
|
139 |
-
* @see Crypt_RC4::_crypt()
|
140 |
-
* @var Integer
|
141 |
-
* @access private
|
142 |
-
*/
|
143 |
-
var $decryptIndex = 0;
|
144 |
-
|
145 |
-
/**
|
146 |
-
* MCrypt parameters
|
147 |
-
*
|
148 |
-
* @see Crypt_RC4::setMCrypt()
|
149 |
-
* @var Array
|
150 |
-
* @access private
|
151 |
-
*/
|
152 |
-
var $mcrypt = array('', '');
|
153 |
-
|
154 |
-
/**
|
155 |
-
* The Encryption Algorithm
|
156 |
-
*
|
157 |
-
* Only used if CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT. Only possible values are MCRYPT_RC4 or MCRYPT_ARCFOUR.
|
158 |
-
*
|
159 |
-
* @see Crypt_RC4::Crypt_RC4()
|
160 |
-
* @var Integer
|
161 |
-
* @access private
|
162 |
-
*/
|
163 |
-
var $mode;
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Continuous Buffer status
|
167 |
-
*
|
168 |
-
* @see Crypt_RC4::enableContinuousBuffer()
|
169 |
-
* @var Boolean
|
170 |
-
* @access private
|
171 |
-
*/
|
172 |
-
var $continuousBuffer = false;
|
173 |
-
|
174 |
-
/**
|
175 |
-
* Default Constructor.
|
176 |
-
*
|
177 |
-
* Determines whether or not the mcrypt extension should be used.
|
178 |
-
*
|
179 |
-
* @param optional Integer $mode
|
180 |
-
* @return Crypt_RC4
|
181 |
-
* @access public
|
182 |
-
*/
|
183 |
-
function Crypt_RC4()
|
184 |
-
{
|
185 |
-
if ( !defined('CRYPT_RC4_MODE') ) {
|
186 |
-
switch (true) {
|
187 |
-
case extension_loaded('mcrypt') && (defined('MCRYPT_ARCFOUR') || defined('MCRYPT_RC4')):
|
188 |
-
// i'd check to see if rc4 was supported, by doing in_array('arcfour', mcrypt_list_algorithms('')),
|
189 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
190 |
-
// a lot of point...
|
191 |
-
define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_MCRYPT);
|
192 |
-
break;
|
193 |
-
default:
|
194 |
-
define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_INTERNAL);
|
195 |
-
}
|
196 |
-
}
|
197 |
-
|
198 |
-
switch ( CRYPT_RC4_MODE ) {
|
199 |
-
case CRYPT_RC4_MODE_MCRYPT:
|
200 |
-
switch (true) {
|
201 |
-
case defined('MCRYPT_ARCFOUR'):
|
202 |
-
$this->mode = MCRYPT_ARCFOUR;
|
203 |
-
break;
|
204 |
-
case defined('MCRYPT_RC4');
|
205 |
-
$this->mode = MCRYPT_RC4;
|
206 |
-
}
|
207 |
-
}
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Sets the key.
|
212 |
-
*
|
213 |
-
* Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
|
214 |
-
* be used. If no key is explicitly set, it'll be assumed to be a single null byte.
|
215 |
-
*
|
216 |
-
* @access public
|
217 |
-
* @param String $key
|
218 |
-
*/
|
219 |
-
function setKey($key)
|
220 |
-
{
|
221 |
-
$this->key = $key;
|
222 |
-
|
223 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
224 |
-
return;
|
225 |
-
}
|
226 |
-
|
227 |
-
$keyLength = strlen($key);
|
228 |
-
$keyStream = array();
|
229 |
-
for ($i = 0; $i < 256; $i++) {
|
230 |
-
$keyStream[$i] = $i;
|
231 |
-
}
|
232 |
-
$j = 0;
|
233 |
-
for ($i = 0; $i < 256; $i++) {
|
234 |
-
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
|
235 |
-
$temp = $keyStream[$i];
|
236 |
-
$keyStream[$i] = $keyStream[$j];
|
237 |
-
$keyStream[$j] = $temp;
|
238 |
-
}
|
239 |
-
|
240 |
-
$this->encryptIndex = $this->decryptIndex = array(0, 0);
|
241 |
-
$this->encryptStream = $this->decryptStream = $keyStream;
|
242 |
-
}
|
243 |
-
|
244 |
-
/**
|
245 |
-
* Dummy function.
|
246 |
-
*
|
247 |
-
* Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
|
248 |
-
* If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
|
249 |
-
* calling setKey().
|
250 |
-
*
|
251 |
-
* [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
|
252 |
-
* the IV's are relatively easy to predict, an attack described by
|
253 |
-
* {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
|
254 |
-
* can be used to quickly guess at the rest of the key. The following links elaborate:
|
255 |
-
*
|
256 |
-
* {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
|
257 |
-
* {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
|
258 |
-
*
|
259 |
-
* @param String $iv
|
260 |
-
* @see Crypt_RC4::setKey()
|
261 |
-
* @access public
|
262 |
-
*/
|
263 |
-
function setIV($iv)
|
264 |
-
{
|
265 |
-
}
|
266 |
-
|
267 |
-
/**
|
268 |
-
* Sets MCrypt parameters. (optional)
|
269 |
-
*
|
270 |
-
* If MCrypt is being used, empty strings will be used, unless otherwise specified.
|
271 |
-
*
|
272 |
-
* @link http://php.net/function.mcrypt-module-open#function.mcrypt-module-open
|
273 |
-
* @access public
|
274 |
-
* @param optional Integer $algorithm_directory
|
275 |
-
* @param optional Integer $mode_directory
|
276 |
-
*/
|
277 |
-
function setMCrypt($algorithm_directory = '', $mode_directory = '')
|
278 |
-
{
|
279 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
280 |
-
$this->mcrypt = array($algorithm_directory, $mode_directory);
|
281 |
-
$this->_closeMCrypt();
|
282 |
-
}
|
283 |
-
}
|
284 |
-
|
285 |
-
/**
|
286 |
-
* Encrypts a message.
|
287 |
-
*
|
288 |
-
* @see Crypt_RC4::_crypt()
|
289 |
-
* @access public
|
290 |
-
* @param String $plaintext
|
291 |
-
*/
|
292 |
-
function encrypt($plaintext)
|
293 |
-
{
|
294 |
-
return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
|
295 |
-
}
|
296 |
-
|
297 |
-
/**
|
298 |
-
* Decrypts a message.
|
299 |
-
*
|
300 |
-
* $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
|
301 |
-
* Atleast if the continuous buffer is disabled.
|
302 |
-
*
|
303 |
-
* @see Crypt_RC4::_crypt()
|
304 |
-
* @access public
|
305 |
-
* @param String $ciphertext
|
306 |
-
*/
|
307 |
-
function decrypt($ciphertext)
|
308 |
-
{
|
309 |
-
return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
|
310 |
-
}
|
311 |
-
|
312 |
-
/**
|
313 |
-
* Encrypts or decrypts a message.
|
314 |
-
*
|
315 |
-
* @see Crypt_RC4::encrypt()
|
316 |
-
* @see Crypt_RC4::decrypt()
|
317 |
-
* @access private
|
318 |
-
* @param String $text
|
319 |
-
* @param Integer $mode
|
320 |
-
*/
|
321 |
-
function _crypt($text, $mode)
|
322 |
-
{
|
323 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
324 |
-
$keyStream = $mode == CRYPT_RC4_ENCRYPT ? 'encryptStream' : 'decryptStream';
|
325 |
-
|
326 |
-
if ($this->$keyStream === false) {
|
327 |
-
$this->$keyStream = mcrypt_module_open($this->mode, $this->mcrypt[0], MCRYPT_MODE_STREAM, $this->mcrypt[1]);
|
328 |
-
mcrypt_generic_init($this->$keyStream, $this->key, '');
|
329 |
-
} else if (!$this->continuousBuffer) {
|
330 |
-
mcrypt_generic_init($this->$keyStream, $this->key, '');
|
331 |
-
}
|
332 |
-
$newText = mcrypt_generic($this->$keyStream, $text);
|
333 |
-
if (!$this->continuousBuffer) {
|
334 |
-
mcrypt_generic_deinit($this->$keyStream);
|
335 |
-
}
|
336 |
-
|
337 |
-
return $newText;
|
338 |
-
}
|
339 |
-
|
340 |
-
if ($this->encryptStream === false) {
|
341 |
-
$this->setKey($this->key);
|
342 |
-
}
|
343 |
-
|
344 |
-
switch ($mode) {
|
345 |
-
case CRYPT_RC4_ENCRYPT:
|
346 |
-
$keyStream = $this->encryptStream;
|
347 |
-
list($i, $j) = $this->encryptIndex;
|
348 |
-
break;
|
349 |
-
case CRYPT_RC4_DECRYPT:
|
350 |
-
$keyStream = $this->decryptStream;
|
351 |
-
list($i, $j) = $this->decryptIndex;
|
352 |
-
}
|
353 |
-
|
354 |
-
$newText = '';
|
355 |
-
for ($k = 0; $k < strlen($text); $k++) {
|
356 |
-
$i = ($i + 1) & 255;
|
357 |
-
$j = ($j + $keyStream[$i]) & 255;
|
358 |
-
$temp = $keyStream[$i];
|
359 |
-
$keyStream[$i] = $keyStream[$j];
|
360 |
-
$keyStream[$j] = $temp;
|
361 |
-
$temp = $keyStream[($keyStream[$i] + $keyStream[$j]) & 255];
|
362 |
-
$newText.= chr(ord($text[$k]) ^ $temp);
|
363 |
-
}
|
364 |
-
|
365 |
-
if ($this->continuousBuffer) {
|
366 |
-
switch ($mode) {
|
367 |
-
case CRYPT_RC4_ENCRYPT:
|
368 |
-
$this->encryptStream = $keyStream;
|
369 |
-
$this->encryptIndex = array($i, $j);
|
370 |
-
break;
|
371 |
-
case CRYPT_RC4_DECRYPT:
|
372 |
-
$this->decryptStream = $keyStream;
|
373 |
-
$this->decryptIndex = array($i, $j);
|
374 |
-
}
|
375 |
-
}
|
376 |
-
|
377 |
-
return $newText;
|
378 |
-
}
|
379 |
-
|
380 |
-
/**
|
381 |
-
* Treat consecutive "packets" as if they are a continuous buffer.
|
382 |
-
*
|
383 |
-
* Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
|
384 |
-
* will yield different outputs:
|
385 |
-
*
|
386 |
-
* <code>
|
387 |
-
* echo $rc4->encrypt(substr($plaintext, 0, 8));
|
388 |
-
* echo $rc4->encrypt(substr($plaintext, 8, 8));
|
389 |
-
* </code>
|
390 |
-
* <code>
|
391 |
-
* echo $rc4->encrypt($plaintext);
|
392 |
-
* </code>
|
393 |
-
*
|
394 |
-
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
|
395 |
-
* another, as demonstrated with the following:
|
396 |
-
*
|
397 |
-
* <code>
|
398 |
-
* $rc4->encrypt(substr($plaintext, 0, 8));
|
399 |
-
* echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
400 |
-
* </code>
|
401 |
-
* <code>
|
402 |
-
* echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
403 |
-
* </code>
|
404 |
-
*
|
405 |
-
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
|
406 |
-
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
407 |
-
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
408 |
-
*
|
409 |
-
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
|
410 |
-
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
411 |
-
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
412 |
-
* however, they are also less intuitive and more likely to cause you problems.
|
413 |
-
*
|
414 |
-
* @see Crypt_RC4::disableContinuousBuffer()
|
415 |
-
* @access public
|
416 |
-
*/
|
417 |
-
function enableContinuousBuffer()
|
418 |
-
{
|
419 |
-
$this->continuousBuffer = true;
|
420 |
-
}
|
421 |
-
|
422 |
-
/**
|
423 |
-
* Treat consecutive packets as if they are a discontinuous buffer.
|
424 |
-
*
|
425 |
-
* The default behavior.
|
426 |
-
*
|
427 |
-
* @see Crypt_RC4::enableContinuousBuffer()
|
428 |
-
* @access public
|
429 |
-
*/
|
430 |
-
function disableContinuousBuffer()
|
431 |
-
{
|
432 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_INTERNAL ) {
|
433 |
-
$this->encryptIndex = $this->decryptIndex = array(0, 0);
|
434 |
-
$this->setKey($this->key);
|
435 |
-
}
|
436 |
-
|
437 |
-
$this->continuousBuffer = false;
|
438 |
-
}
|
439 |
-
|
440 |
-
/**
|
441 |
-
* Dummy function.
|
442 |
-
*
|
443 |
-
* Since RC4 is a stream cipher and not a block cipher, no padding is necessary. The only reason this function is
|
444 |
-
* included is so that you can switch between a block cipher and a stream cipher transparently.
|
445 |
-
*
|
446 |
-
* @see Crypt_RC4::disablePadding()
|
447 |
-
* @access public
|
448 |
-
*/
|
449 |
-
function enablePadding()
|
450 |
-
{
|
451 |
-
}
|
452 |
-
|
453 |
-
/**
|
454 |
-
* Dummy function.
|
455 |
-
*
|
456 |
-
* @see Crypt_RC4::enablePadding()
|
457 |
-
* @access public
|
458 |
-
*/
|
459 |
-
function disablePadding()
|
460 |
-
{
|
461 |
-
}
|
462 |
-
|
463 |
-
/**
|
464 |
-
* Class destructor.
|
465 |
-
*
|
466 |
-
* Will be called, automatically, if you're using PHP5. If you're using PHP4, call it yourself. Only really
|
467 |
-
* needs to be called if mcrypt is being used.
|
468 |
-
*
|
469 |
-
* @access public
|
470 |
-
*/
|
471 |
-
function __destruct()
|
472 |
-
{
|
473 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
474 |
-
$this->_closeMCrypt();
|
475 |
-
}
|
476 |
-
}
|
477 |
-
|
478 |
-
/**
|
479 |
-
* Properly close the MCrypt objects.
|
480 |
-
*
|
481 |
-
* @access prviate
|
482 |
-
*/
|
483 |
-
function _closeMCrypt()
|
484 |
-
{
|
485 |
-
if ( $this->encryptStream !== false ) {
|
486 |
-
if ( $this->continuousBuffer ) {
|
487 |
-
mcrypt_generic_deinit($this->encryptStream);
|
488 |
-
}
|
489 |
-
|
490 |
-
mcrypt_module_close($this->encryptStream);
|
491 |
-
|
492 |
-
$this->encryptStream = false;
|
493 |
-
}
|
494 |
-
|
495 |
-
if ( $this->decryptStream !== false ) {
|
496 |
-
if ( $this->continuousBuffer ) {
|
497 |
-
mcrypt_generic_deinit($this->decryptStream);
|
498 |
-
}
|
499 |
-
|
500 |
-
mcrypt_module_close($this->decryptStream);
|
501 |
-
|
502 |
-
$this->decryptStream = false;
|
503 |
-
}
|
504 |
-
}
|
505 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/RSA.php
DELETED
@@ -1,2356 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
|
6 |
-
*
|
7 |
-
* PHP versions 4 and 5
|
8 |
-
*
|
9 |
-
* Here's an example of how to encrypt and decrypt text with this library:
|
10 |
-
* <code>
|
11 |
-
* <?php
|
12 |
-
* include('Crypt/RSA.php');
|
13 |
-
*
|
14 |
-
* $rsa = new Crypt_RSA();
|
15 |
-
* extract($rsa->createKey());
|
16 |
-
*
|
17 |
-
* $plaintext = 'terrafrost';
|
18 |
-
*
|
19 |
-
* $rsa->loadKey($privatekey);
|
20 |
-
* $ciphertext = $rsa->encrypt($plaintext);
|
21 |
-
*
|
22 |
-
* $rsa->loadKey($publickey);
|
23 |
-
* echo $rsa->decrypt($ciphertext);
|
24 |
-
* ?>
|
25 |
-
* </code>
|
26 |
-
*
|
27 |
-
* Here's an example of how to create signatures and verify signatures with this library:
|
28 |
-
* <code>
|
29 |
-
* <?php
|
30 |
-
* include('Crypt/RSA.php');
|
31 |
-
*
|
32 |
-
* $rsa = new Crypt_RSA();
|
33 |
-
* extract($rsa->createKey());
|
34 |
-
*
|
35 |
-
* $plaintext = 'terrafrost';
|
36 |
-
*
|
37 |
-
* $rsa->loadKey($privatekey);
|
38 |
-
* $signature = $rsa->sign($plaintext);
|
39 |
-
*
|
40 |
-
* $rsa->loadKey($publickey);
|
41 |
-
* echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
|
42 |
-
* ?>
|
43 |
-
* </code>
|
44 |
-
*
|
45 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
46 |
-
* of this software and associated documentation files (the "Software"), to deal
|
47 |
-
* in the Software without restriction, including without limitation the rights
|
48 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
49 |
-
* copies of the Software, and to permit persons to whom the Software is
|
50 |
-
* furnished to do so, subject to the following conditions:
|
51 |
-
*
|
52 |
-
* The above copyright notice and this permission notice shall be included in
|
53 |
-
* all copies or substantial portions of the Software.
|
54 |
-
*
|
55 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
56 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
57 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
58 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
59 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
60 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
61 |
-
* THE SOFTWARE.
|
62 |
-
*
|
63 |
-
* @category Crypt
|
64 |
-
* @package Crypt_RSA
|
65 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
66 |
-
* @copyright MMIX Jim Wigginton
|
67 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
68 |
-
* @version $Id: RSA.php,v 1.19 2010/09/12 21:58:54 terrafrost Exp $
|
69 |
-
* @link http://phpseclib.sourceforge.net
|
70 |
-
*/
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Include Math_BigInteger
|
74 |
-
*/
|
75 |
-
require_once('Math/BigInteger.php');
|
76 |
-
|
77 |
-
/**
|
78 |
-
* Include Crypt_Random
|
79 |
-
*/
|
80 |
-
require_once('Crypt/Random.php');
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Include Crypt_Hash
|
84 |
-
*/
|
85 |
-
require_once('Crypt/Hash.php');
|
86 |
-
|
87 |
-
/**#@+
|
88 |
-
* @access public
|
89 |
-
* @see Crypt_RSA::encrypt()
|
90 |
-
* @see Crypt_RSA::decrypt()
|
91 |
-
*/
|
92 |
-
/**
|
93 |
-
* Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
|
94 |
-
* (OAEP) for encryption / decryption.
|
95 |
-
*
|
96 |
-
* Uses sha1 by default.
|
97 |
-
*
|
98 |
-
* @see Crypt_RSA::setHash()
|
99 |
-
* @see Crypt_RSA::setMGFHash()
|
100 |
-
*/
|
101 |
-
define('CRYPT_RSA_ENCRYPTION_OAEP', 1);
|
102 |
-
/**
|
103 |
-
* Use PKCS#1 padding.
|
104 |
-
*
|
105 |
-
* Although CRYPT_RSA_ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards
|
106 |
-
* compatability with protocols (like SSH-1) written before OAEP's introduction.
|
107 |
-
*/
|
108 |
-
define('CRYPT_RSA_ENCRYPTION_PKCS1', 2);
|
109 |
-
/**#@-*/
|
110 |
-
|
111 |
-
/**#@+
|
112 |
-
* @access public
|
113 |
-
* @see Crypt_RSA::sign()
|
114 |
-
* @see Crypt_RSA::verify()
|
115 |
-
* @see Crypt_RSA::setHash()
|
116 |
-
*/
|
117 |
-
/**
|
118 |
-
* Use the Probabilistic Signature Scheme for signing
|
119 |
-
*
|
120 |
-
* Uses sha1 by default.
|
121 |
-
*
|
122 |
-
* @see Crypt_RSA::setSaltLength()
|
123 |
-
* @see Crypt_RSA::setMGFHash()
|
124 |
-
*/
|
125 |
-
define('CRYPT_RSA_SIGNATURE_PSS', 1);
|
126 |
-
/**
|
127 |
-
* Use the PKCS#1 scheme by default.
|
128 |
-
*
|
129 |
-
* Although CRYPT_RSA_SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards
|
130 |
-
* compatability with protocols (like SSH-2) written before PSS's introduction.
|
131 |
-
*/
|
132 |
-
define('CRYPT_RSA_SIGNATURE_PKCS1', 2);
|
133 |
-
/**#@-*/
|
134 |
-
|
135 |
-
/**#@+
|
136 |
-
* @access private
|
137 |
-
* @see Crypt_RSA::createKey()
|
138 |
-
*/
|
139 |
-
/**
|
140 |
-
* ASN1 Integer
|
141 |
-
*/
|
142 |
-
define('CRYPT_RSA_ASN1_INTEGER', 2);
|
143 |
-
/**
|
144 |
-
* ASN1 Sequence (with the constucted bit set)
|
145 |
-
*/
|
146 |
-
define('CRYPT_RSA_ASN1_SEQUENCE', 48);
|
147 |
-
/**#@-*/
|
148 |
-
|
149 |
-
/**#@+
|
150 |
-
* @access private
|
151 |
-
* @see Crypt_RSA::Crypt_RSA()
|
152 |
-
*/
|
153 |
-
/**
|
154 |
-
* To use the pure-PHP implementation
|
155 |
-
*/
|
156 |
-
define('CRYPT_RSA_MODE_INTERNAL', 1);
|
157 |
-
/**
|
158 |
-
* To use the OpenSSL library
|
159 |
-
*
|
160 |
-
* (if enabled; otherwise, the internal implementation will be used)
|
161 |
-
*/
|
162 |
-
define('CRYPT_RSA_MODE_OPENSSL', 2);
|
163 |
-
/**#@-*/
|
164 |
-
|
165 |
-
/**#@+
|
166 |
-
* @access public
|
167 |
-
* @see Crypt_RSA::createKey()
|
168 |
-
* @see Crypt_RSA::setPrivateKeyFormat()
|
169 |
-
*/
|
170 |
-
/**
|
171 |
-
* PKCS#1 formatted private key
|
172 |
-
*
|
173 |
-
* Used by OpenSSH
|
174 |
-
*/
|
175 |
-
define('CRYPT_RSA_PRIVATE_FORMAT_PKCS1', 0);
|
176 |
-
/**
|
177 |
-
* PuTTY formatted private key
|
178 |
-
*/
|
179 |
-
define('CRYPT_RSA_PRIVATE_FORMAT_PUTTY', 1);
|
180 |
-
/**
|
181 |
-
* XML formatted private key
|
182 |
-
*/
|
183 |
-
define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2);
|
184 |
-
/**#@-*/
|
185 |
-
|
186 |
-
/**#@+
|
187 |
-
* @access public
|
188 |
-
* @see Crypt_RSA::createKey()
|
189 |
-
* @see Crypt_RSA::setPublicKeyFormat()
|
190 |
-
*/
|
191 |
-
/**
|
192 |
-
* Raw public key
|
193 |
-
*
|
194 |
-
* An array containing two Math_BigInteger objects.
|
195 |
-
*
|
196 |
-
* The exponent can be indexed with any of the following:
|
197 |
-
*
|
198 |
-
* 0, e, exponent, publicExponent
|
199 |
-
*
|
200 |
-
* The modulus can be indexed with any of the following:
|
201 |
-
*
|
202 |
-
* 1, n, modulo, modulus
|
203 |
-
*/
|
204 |
-
define('CRYPT_RSA_PUBLIC_FORMAT_RAW', 3);
|
205 |
-
/**
|
206 |
-
* PKCS#1 formatted public key
|
207 |
-
*/
|
208 |
-
define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 4);
|
209 |
-
/**
|
210 |
-
* XML formatted public key
|
211 |
-
*/
|
212 |
-
define('CRYPT_RSA_PUBLIC_FORMAT_XML', 5);
|
213 |
-
/**
|
214 |
-
* OpenSSH formatted public key
|
215 |
-
*
|
216 |
-
* Place in $HOME/.ssh/authorized_keys
|
217 |
-
*/
|
218 |
-
define('CRYPT_RSA_PUBLIC_FORMAT_OPENSSH', 6);
|
219 |
-
/**#@-*/
|
220 |
-
|
221 |
-
/**
|
222 |
-
* Pure-PHP PKCS#1 compliant implementation of RSA.
|
223 |
-
*
|
224 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
225 |
-
* @version 0.1.0
|
226 |
-
* @access public
|
227 |
-
* @package Crypt_RSA
|
228 |
-
*/
|
229 |
-
class Crypt_RSA {
|
230 |
-
/**
|
231 |
-
* Precomputed Zero
|
232 |
-
*
|
233 |
-
* @var Array
|
234 |
-
* @access private
|
235 |
-
*/
|
236 |
-
var $zero;
|
237 |
-
|
238 |
-
/**
|
239 |
-
* Precomputed One
|
240 |
-
*
|
241 |
-
* @var Array
|
242 |
-
* @access private
|
243 |
-
*/
|
244 |
-
var $one;
|
245 |
-
|
246 |
-
/**
|
247 |
-
* Private Key Format
|
248 |
-
*
|
249 |
-
* @var Integer
|
250 |
-
* @access private
|
251 |
-
*/
|
252 |
-
var $privateKeyFormat = CRYPT_RSA_PRIVATE_FORMAT_PKCS1;
|
253 |
-
|
254 |
-
/**
|
255 |
-
* Public Key Format
|
256 |
-
*
|
257 |
-
* @var Integer
|
258 |
-
* @access public
|
259 |
-
*/
|
260 |
-
var $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS1;
|
261 |
-
|
262 |
-
/**
|
263 |
-
* Modulus (ie. n)
|
264 |
-
*
|
265 |
-
* @var Math_BigInteger
|
266 |
-
* @access private
|
267 |
-
*/
|
268 |
-
var $modulus;
|
269 |
-
|
270 |
-
/**
|
271 |
-
* Modulus length
|
272 |
-
*
|
273 |
-
* @var Math_BigInteger
|
274 |
-
* @access private
|
275 |
-
*/
|
276 |
-
var $k;
|
277 |
-
|
278 |
-
/**
|
279 |
-
* Exponent (ie. e or d)
|
280 |
-
*
|
281 |
-
* @var Math_BigInteger
|
282 |
-
* @access private
|
283 |
-
*/
|
284 |
-
var $exponent;
|
285 |
-
|
286 |
-
/**
|
287 |
-
* Primes for Chinese Remainder Theorem (ie. p and q)
|
288 |
-
*
|
289 |
-
* @var Array
|
290 |
-
* @access private
|
291 |
-
*/
|
292 |
-
var $primes;
|
293 |
-
|
294 |
-
/**
|
295 |
-
* Exponents for Chinese Remainder Theorem (ie. dP and dQ)
|
296 |
-
*
|
297 |
-
* @var Array
|
298 |
-
* @access private
|
299 |
-
*/
|
300 |
-
var $exponents;
|
301 |
-
|
302 |
-
/**
|
303 |
-
* Coefficients for Chinese Remainder Theorem (ie. qInv)
|
304 |
-
*
|
305 |
-
* @var Array
|
306 |
-
* @access private
|
307 |
-
*/
|
308 |
-
var $coefficients;
|
309 |
-
|
310 |
-
/**
|
311 |
-
* Hash name
|
312 |
-
*
|
313 |
-
* @var String
|
314 |
-
* @access private
|
315 |
-
*/
|
316 |
-
var $hashName;
|
317 |
-
|
318 |
-
/**
|
319 |
-
* Hash function
|
320 |
-
*
|
321 |
-
* @var Crypt_Hash
|
322 |
-
* @access private
|
323 |
-
*/
|
324 |
-
var $hash;
|
325 |
-
|
326 |
-
/**
|
327 |
-
* Length of hash function output
|
328 |
-
*
|
329 |
-
* @var Integer
|
330 |
-
* @access private
|
331 |
-
*/
|
332 |
-
var $hLen;
|
333 |
-
|
334 |
-
/**
|
335 |
-
* Length of salt
|
336 |
-
*
|
337 |
-
* @var Integer
|
338 |
-
* @access private
|
339 |
-
*/
|
340 |
-
var $sLen;
|
341 |
-
|
342 |
-
/**
|
343 |
-
* Hash function for the Mask Generation Function
|
344 |
-
*
|
345 |
-
* @var Crypt_Hash
|
346 |
-
* @access private
|
347 |
-
*/
|
348 |
-
var $mgfHash;
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Length of MGF hash function output
|
352 |
-
*
|
353 |
-
* @var Integer
|
354 |
-
* @access private
|
355 |
-
*/
|
356 |
-
var $mgfHLen;
|
357 |
-
|
358 |
-
/**
|
359 |
-
* Encryption mode
|
360 |
-
*
|
361 |
-
* @var Integer
|
362 |
-
* @access private
|
363 |
-
*/
|
364 |
-
var $encryptionMode = CRYPT_RSA_ENCRYPTION_OAEP;
|
365 |
-
|
366 |
-
/**
|
367 |
-
* Signature mode
|
368 |
-
*
|
369 |
-
* @var Integer
|
370 |
-
* @access private
|
371 |
-
*/
|
372 |
-
var $signatureMode = CRYPT_RSA_SIGNATURE_PSS;
|
373 |
-
|
374 |
-
/**
|
375 |
-
* Public Exponent
|
376 |
-
*
|
377 |
-
* @var Mixed
|
378 |
-
* @access private
|
379 |
-
*/
|
380 |
-
var $publicExponent = false;
|
381 |
-
|
382 |
-
/**
|
383 |
-
* Password
|
384 |
-
*
|
385 |
-
* @var String
|
386 |
-
* @access private
|
387 |
-
*/
|
388 |
-
var $password = '';
|
389 |
-
|
390 |
-
/**
|
391 |
-
* Components
|
392 |
-
*
|
393 |
-
* For use with parsing XML formatted keys. PHP's XML Parser functions use utilized - instead of PHP's DOM functions -
|
394 |
-
* because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't.
|
395 |
-
*
|
396 |
-
* @see Crypt_RSA::_start_element_handler()
|
397 |
-
* @var Array
|
398 |
-
* @access private
|
399 |
-
*/
|
400 |
-
var $components = array();
|
401 |
-
|
402 |
-
/**
|
403 |
-
* Current String
|
404 |
-
*
|
405 |
-
* For use with parsing XML formatted keys.
|
406 |
-
*
|
407 |
-
* @see Crypt_RSA::_character_handler()
|
408 |
-
* @see Crypt_RSA::_stop_element_handler()
|
409 |
-
* @var Mixed
|
410 |
-
* @access private
|
411 |
-
*/
|
412 |
-
var $current;
|
413 |
-
|
414 |
-
/**
|
415 |
-
* The constructor
|
416 |
-
*
|
417 |
-
* If you want to make use of the openssl extension, you'll need to set the mode manually, yourself. The reason
|
418 |
-
* Crypt_RSA doesn't do it is because OpenSSL doesn't fail gracefully. openssl_pkey_new(), in particular, requires
|
419 |
-
* openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late.
|
420 |
-
*
|
421 |
-
* @return Crypt_RSA
|
422 |
-
* @access public
|
423 |
-
*/
|
424 |
-
function Crypt_RSA()
|
425 |
-
{
|
426 |
-
if ( !defined('CRYPT_RSA_MODE') ) {
|
427 |
-
switch (true) {
|
428 |
-
//case extension_loaded('openssl') && version_compare(PHP_VERSION, '4.2.0', '>='):
|
429 |
-
// define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_OPENSSL);
|
430 |
-
// break;
|
431 |
-
default:
|
432 |
-
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
433 |
-
}
|
434 |
-
}
|
435 |
-
|
436 |
-
$this->zero = new Math_BigInteger();
|
437 |
-
$this->one = new Math_BigInteger(1);
|
438 |
-
|
439 |
-
$this->hash = new Crypt_Hash('sha1');
|
440 |
-
$this->hLen = $this->hash->getLength();
|
441 |
-
$this->hashName = 'sha1';
|
442 |
-
$this->mgfHash = new Crypt_Hash('sha1');
|
443 |
-
$this->mgfHLen = $this->mgfHash->getLength();
|
444 |
-
}
|
445 |
-
|
446 |
-
/**
|
447 |
-
* Create public / private key pair
|
448 |
-
*
|
449 |
-
* Returns an array with the following three elements:
|
450 |
-
* - 'privatekey': The private key.
|
451 |
-
* - 'publickey': The public key.
|
452 |
-
* - 'partialkey': A partially computed key (if the execution time exceeded $timeout).
|
453 |
-
* Will need to be passed back to Crypt_RSA::createKey() as the third parameter for further processing.
|
454 |
-
*
|
455 |
-
* @access public
|
456 |
-
* @param optional Integer $bits
|
457 |
-
* @param optional Integer $timeout
|
458 |
-
* @param optional Math_BigInteger $p
|
459 |
-
*/
|
460 |
-
function createKey($bits = 1024, $timeout = false, $partial = array())
|
461 |
-
{
|
462 |
-
if ( CRYPT_RSA_MODE == CRYPT_RSA_MODE_OPENSSL ) {
|
463 |
-
$rsa = openssl_pkey_new(array('private_key_bits' => $bits));
|
464 |
-
openssl_pkey_export($rsa, $privatekey);
|
465 |
-
$publickey = openssl_pkey_get_details($rsa);
|
466 |
-
$publickey = $publickey['key'];
|
467 |
-
|
468 |
-
if ($this->privateKeyFormat != CRYPT_RSA_PRIVATE_FORMAT_PKCS1) {
|
469 |
-
$privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, CRYPT_RSA_PRIVATE_FORMAT_PKCS1)));
|
470 |
-
$publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, CRYPT_RSA_PUBLIC_FORMAT_PKCS1)));
|
471 |
-
}
|
472 |
-
|
473 |
-
return array(
|
474 |
-
'privatekey' => $privatekey,
|
475 |
-
'publickey' => $publickey,
|
476 |
-
'partialkey' => false
|
477 |
-
);
|
478 |
-
}
|
479 |
-
|
480 |
-
static $e;
|
481 |
-
if (!isset($e)) {
|
482 |
-
if (!defined('CRYPT_RSA_EXPONENT')) {
|
483 |
-
// http://en.wikipedia.org/wiki/65537_%28number%29
|
484 |
-
define('CRYPT_RSA_EXPONENT', '65537');
|
485 |
-
}
|
486 |
-
if (!defined('CRYPT_RSA_COMMENT')) {
|
487 |
-
define('CRYPT_RSA_COMMENT', 'phpseclib-generated-key');
|
488 |
-
}
|
489 |
-
// per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
|
490 |
-
// than 256 bits.
|
491 |
-
if (!defined('CRYPT_RSA_SMALLEST_PRIME')) {
|
492 |
-
define('CRYPT_RSA_SMALLEST_PRIME', 4096);
|
493 |
-
}
|
494 |
-
|
495 |
-
$e = new Math_BigInteger(CRYPT_RSA_EXPONENT);
|
496 |
-
}
|
497 |
-
|
498 |
-
extract($this->_generateMinMax($bits));
|
499 |
-
$absoluteMin = $min;
|
500 |
-
$temp = $bits >> 1;
|
501 |
-
if ($temp > CRYPT_RSA_SMALLEST_PRIME) {
|
502 |
-
$num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME);
|
503 |
-
$temp = CRYPT_RSA_SMALLEST_PRIME;
|
504 |
-
} else {
|
505 |
-
$num_primes = 2;
|
506 |
-
}
|
507 |
-
extract($this->_generateMinMax($temp + $bits % $temp));
|
508 |
-
$finalMax = $max;
|
509 |
-
extract($this->_generateMinMax($temp));
|
510 |
-
|
511 |
-
$generator = new Math_BigInteger();
|
512 |
-
$generator->setRandomGenerator('crypt_random');
|
513 |
-
|
514 |
-
$n = $this->one->copy();
|
515 |
-
if (!empty($partial)) {
|
516 |
-
extract(unserialize($partial));
|
517 |
-
} else {
|
518 |
-
$exponents = $coefficients = $primes = array();
|
519 |
-
$lcm = array(
|
520 |
-
'top' => $this->one->copy(),
|
521 |
-
'bottom' => false
|
522 |
-
);
|
523 |
-
}
|
524 |
-
|
525 |
-
$start = time();
|
526 |
-
$i0 = count($primes) + 1;
|
527 |
-
|
528 |
-
do {
|
529 |
-
for ($i = $i0; $i <= $num_primes; $i++) {
|
530 |
-
if ($timeout !== false) {
|
531 |
-
$timeout-= time() - $start;
|
532 |
-
$start = time();
|
533 |
-
if ($timeout <= 0) {
|
534 |
-
return array(
|
535 |
-
'privatekey' => '',
|
536 |
-
'publickey' => '',
|
537 |
-
'partialkey' => serialize(array(
|
538 |
-
'primes' => $primes,
|
539 |
-
'coefficients' => $coefficients,
|
540 |
-
'lcm' => $lcm,
|
541 |
-
'exponents' => $exponents
|
542 |
-
))
|
543 |
-
);
|
544 |
-
}
|
545 |
-
}
|
546 |
-
|
547 |
-
if ($i == $num_primes) {
|
548 |
-
list($min, $temp) = $absoluteMin->divide($n);
|
549 |
-
if (!$temp->equals($this->zero)) {
|
550 |
-
$min = $min->add($this->one); // ie. ceil()
|
551 |
-
}
|
552 |
-
$primes[$i] = $generator->randomPrime($min, $finalMax, $timeout);
|
553 |
-
} else {
|
554 |
-
$primes[$i] = $generator->randomPrime($min, $max, $timeout);
|
555 |
-
}
|
556 |
-
|
557 |
-
if ($primes[$i] === false) { // if we've reached the timeout
|
558 |
-
if (count($primes) > 1) {
|
559 |
-
$partialkey = '';
|
560 |
-
} else {
|
561 |
-
array_pop($primes);
|
562 |
-
$partialkey = serialize(array(
|
563 |
-
'primes' => $primes,
|
564 |
-
'coefficients' => $coefficients,
|
565 |
-
'lcm' => $lcm,
|
566 |
-
'exponents' => $exponents
|
567 |
-
));
|
568 |
-
}
|
569 |
-
|
570 |
-
return array(
|
571 |
-
'privatekey' => '',
|
572 |
-
'publickey' => '',
|
573 |
-
'partialkey' => $partialkey
|
574 |
-
);
|
575 |
-
}
|
576 |
-
|
577 |
-
// the first coefficient is calculated differently from the rest
|
578 |
-
// ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
|
579 |
-
if ($i > 2) {
|
580 |
-
$coefficients[$i] = $n->modInverse($primes[$i]);
|
581 |
-
}
|
582 |
-
|
583 |
-
$n = $n->multiply($primes[$i]);
|
584 |
-
|
585 |
-
$temp = $primes[$i]->subtract($this->one);
|
586 |
-
|
587 |
-
// textbook RSA implementations use Euler's totient function instead of the least common multiple.
|
588 |
-
// see http://en.wikipedia.org/wiki/Euler%27s_totient_function
|
589 |
-
$lcm['top'] = $lcm['top']->multiply($temp);
|
590 |
-
$lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
|
591 |
-
|
592 |
-
$exponents[$i] = $e->modInverse($temp);
|
593 |
-
}
|
594 |
-
|
595 |
-
list($lcm) = $lcm['top']->divide($lcm['bottom']);
|
596 |
-
$gcd = $lcm->gcd($e);
|
597 |
-
$i0 = 1;
|
598 |
-
} while (!$gcd->equals($this->one));
|
599 |
-
|
600 |
-
$d = $e->modInverse($lcm);
|
601 |
-
|
602 |
-
$coefficients[2] = $primes[2]->modInverse($primes[1]);
|
603 |
-
|
604 |
-
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
|
605 |
-
// RSAPrivateKey ::= SEQUENCE {
|
606 |
-
// version Version,
|
607 |
-
// modulus INTEGER, -- n
|
608 |
-
// publicExponent INTEGER, -- e
|
609 |
-
// privateExponent INTEGER, -- d
|
610 |
-
// prime1 INTEGER, -- p
|
611 |
-
// prime2 INTEGER, -- q
|
612 |
-
// exponent1 INTEGER, -- d mod (p-1)
|
613 |
-
// exponent2 INTEGER, -- d mod (q-1)
|
614 |
-
// coefficient INTEGER, -- (inverse of q) mod p
|
615 |
-
// otherPrimeInfos OtherPrimeInfos OPTIONAL
|
616 |
-
// }
|
617 |
-
|
618 |
-
return array(
|
619 |
-
'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients),
|
620 |
-
'publickey' => $this->_convertPublicKey($n, $e),
|
621 |
-
'partialkey' => false
|
622 |
-
);
|
623 |
-
}
|
624 |
-
|
625 |
-
/**
|
626 |
-
* Convert a private key to the appropriate format.
|
627 |
-
*
|
628 |
-
* @access private
|
629 |
-
* @see setPrivateKeyFormat()
|
630 |
-
* @param String $RSAPrivateKey
|
631 |
-
* @return String
|
632 |
-
*/
|
633 |
-
function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
|
634 |
-
{
|
635 |
-
$num_primes = count($primes);
|
636 |
-
$raw = array(
|
637 |
-
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
638 |
-
'modulus' => $n->toBytes(true),
|
639 |
-
'publicExponent' => $e->toBytes(true),
|
640 |
-
'privateExponent' => $d->toBytes(true),
|
641 |
-
'prime1' => $primes[1]->toBytes(true),
|
642 |
-
'prime2' => $primes[2]->toBytes(true),
|
643 |
-
'exponent1' => $exponents[1]->toBytes(true),
|
644 |
-
'exponent2' => $exponents[2]->toBytes(true),
|
645 |
-
'coefficient' => $coefficients[2]->toBytes(true)
|
646 |
-
);
|
647 |
-
|
648 |
-
// if the format in question does not support multi-prime rsa and multi-prime rsa was used,
|
649 |
-
// call _convertPublicKey() instead.
|
650 |
-
switch ($this->privateKeyFormat) {
|
651 |
-
default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
|
652 |
-
$components = array();
|
653 |
-
foreach ($raw as $name => $value) {
|
654 |
-
$components[$name] = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
|
655 |
-
}
|
656 |
-
|
657 |
-
$RSAPrivateKey = implode('', $components);
|
658 |
-
|
659 |
-
if ($num_primes > 2) {
|
660 |
-
$OtherPrimeInfos = '';
|
661 |
-
for ($i = 3; $i <= $num_primes; $i++) {
|
662 |
-
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
|
663 |
-
//
|
664 |
-
// OtherPrimeInfo ::= SEQUENCE {
|
665 |
-
// prime INTEGER, -- ri
|
666 |
-
// exponent INTEGER, -- di
|
667 |
-
// coefficient INTEGER -- ti
|
668 |
-
// }
|
669 |
-
$OtherPrimeInfo = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
|
670 |
-
$OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
|
671 |
-
$OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
|
672 |
-
$OtherPrimeInfos.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
|
673 |
-
}
|
674 |
-
$RSAPrivateKey.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
|
675 |
-
}
|
676 |
-
|
677 |
-
$RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
678 |
-
|
679 |
-
if (!empty($this->password)) {
|
680 |
-
$iv = $this->_random(8);
|
681 |
-
$symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
|
682 |
-
$symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
|
683 |
-
if (!class_exists('Crypt_TripleDES')) {
|
684 |
-
require_once('Crypt/TripleDES.php');
|
685 |
-
}
|
686 |
-
$des = new Crypt_TripleDES();
|
687 |
-
$des->setKey($symkey);
|
688 |
-
$des->setIV($iv);
|
689 |
-
$iv = strtoupper(bin2hex($iv));
|
690 |
-
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
|
691 |
-
"Proc-Type: 4,ENCRYPTED\r\n" .
|
692 |
-
"DEK-Info: DES-EDE3-CBC,$iv\r\n" .
|
693 |
-
"\r\n" .
|
694 |
-
chunk_split(base64_encode($des->encrypt($RSAPrivateKey))) .
|
695 |
-
'-----END RSA PRIVATE KEY-----';
|
696 |
-
} else {
|
697 |
-
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
|
698 |
-
chunk_split(base64_encode($RSAPrivateKey)) .
|
699 |
-
'-----END RSA PRIVATE KEY-----';
|
700 |
-
}
|
701 |
-
|
702 |
-
return $RSAPrivateKey;
|
703 |
-
}
|
704 |
-
}
|
705 |
-
|
706 |
-
/**
|
707 |
-
* Convert a public key to the appropriate format
|
708 |
-
*
|
709 |
-
* @access private
|
710 |
-
* @see setPublicKeyFormat()
|
711 |
-
* @param String $RSAPrivateKey
|
712 |
-
* @return String
|
713 |
-
*/
|
714 |
-
function _convertPublicKey($n, $e)
|
715 |
-
{
|
716 |
-
$modulus = $n->toBytes(true);
|
717 |
-
$publicExponent = $e->toBytes(true);
|
718 |
-
|
719 |
-
switch ($this->publicKeyFormat) {
|
720 |
-
case CRYPT_RSA_PUBLIC_FORMAT_RAW:
|
721 |
-
return array('e' => $e->copy(), 'n' => $n->copy());
|
722 |
-
case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
|
723 |
-
// from <http://tools.ietf.org/html/rfc4253#page-15>:
|
724 |
-
// string "ssh-rsa"
|
725 |
-
// mpint e
|
726 |
-
// mpint n
|
727 |
-
$RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
|
728 |
-
$RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . CRYPT_RSA_COMMENT;
|
729 |
-
|
730 |
-
return $RSAPublicKey;
|
731 |
-
default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1
|
732 |
-
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
|
733 |
-
// RSAPublicKey ::= SEQUENCE {
|
734 |
-
// modulus INTEGER, -- n
|
735 |
-
// publicExponent INTEGER -- e
|
736 |
-
// }
|
737 |
-
$components = array(
|
738 |
-
'modulus' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus),
|
739 |
-
'publicExponent' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
|
740 |
-
);
|
741 |
-
|
742 |
-
$RSAPublicKey = pack('Ca*a*a*',
|
743 |
-
CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
|
744 |
-
$components['modulus'], $components['publicExponent']
|
745 |
-
);
|
746 |
-
|
747 |
-
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
|
748 |
-
chunk_split(base64_encode($RSAPublicKey)) .
|
749 |
-
'-----END PUBLIC KEY-----';
|
750 |
-
|
751 |
-
return $RSAPublicKey;
|
752 |
-
}
|
753 |
-
}
|
754 |
-
|
755 |
-
/**
|
756 |
-
* Break a public or private key down into its constituant components
|
757 |
-
*
|
758 |
-
* @access private
|
759 |
-
* @see _convertPublicKey()
|
760 |
-
* @see _convertPrivateKey()
|
761 |
-
* @param String $key
|
762 |
-
* @param Integer $type
|
763 |
-
* @return Array
|
764 |
-
*/
|
765 |
-
function _parseKey($key, $type)
|
766 |
-
{
|
767 |
-
switch ($type) {
|
768 |
-
case CRYPT_RSA_PUBLIC_FORMAT_RAW:
|
769 |
-
if (!is_array($key)) {
|
770 |
-
return false;
|
771 |
-
}
|
772 |
-
$components = array();
|
773 |
-
switch (true) {
|
774 |
-
case isset($key['e']):
|
775 |
-
$components['publicExponent'] = $key['e']->copy();
|
776 |
-
break;
|
777 |
-
case isset($key['exponent']):
|
778 |
-
$components['publicExponent'] = $key['exponent']->copy();
|
779 |
-
break;
|
780 |
-
case isset($key['publicExponent']):
|
781 |
-
$components['publicExponent'] = $key['publicExponent']->copy();
|
782 |
-
break;
|
783 |
-
case isset($key[0]):
|
784 |
-
$components['publicExponent'] = $key[0]->copy();
|
785 |
-
}
|
786 |
-
switch (true) {
|
787 |
-
case isset($key['n']):
|
788 |
-
$components['modulus'] = $key['n']->copy();
|
789 |
-
break;
|
790 |
-
case isset($key['modulo']):
|
791 |
-
$components['modulus'] = $key['modulo']->copy();
|
792 |
-
break;
|
793 |
-
case isset($key['modulus']):
|
794 |
-
$components['modulus'] = $key['modulus']->copy();
|
795 |
-
break;
|
796 |
-
case isset($key[1]):
|
797 |
-
$components['modulus'] = $key[1]->copy();
|
798 |
-
}
|
799 |
-
return $components;
|
800 |
-
case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:
|
801 |
-
case CRYPT_RSA_PUBLIC_FORMAT_PKCS1:
|
802 |
-
/* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
|
803 |
-
"outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
|
804 |
-
protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
|
805 |
-
two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
|
806 |
-
|
807 |
-
http://tools.ietf.org/html/rfc1421#section-4.6.1.1
|
808 |
-
http://tools.ietf.org/html/rfc1421#section-4.6.1.3
|
809 |
-
|
810 |
-
DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
|
811 |
-
DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
|
812 |
-
function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
|
813 |
-
own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
|
814 |
-
implementation are part of the standard, as well.
|
815 |
-
|
816 |
-
* OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
|
817 |
-
if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
|
818 |
-
$iv = pack('H*', trim($matches[2]));
|
819 |
-
$symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key
|
820 |
-
$symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
|
821 |
-
$ciphertext = preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-#s', '', $key);
|
822 |
-
$ciphertext = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $ciphertext) ? base64_decode($ciphertext) : false;
|
823 |
-
if ($ciphertext === false) {
|
824 |
-
$ciphertext = $key;
|
825 |
-
}
|
826 |
-
switch ($matches[1]) {
|
827 |
-
case 'AES-128-CBC':
|
828 |
-
if (!class_exists('Crypt_AES')) {
|
829 |
-
require_once('Crypt/AES.php');
|
830 |
-
}
|
831 |
-
$symkey = substr($symkey, 0, 16);
|
832 |
-
$crypto = new Crypt_AES();
|
833 |
-
break;
|
834 |
-
case 'DES-EDE3-CFB':
|
835 |
-
if (!class_exists('Crypt_TripleDES')) {
|
836 |
-
require_once('Crypt/TripleDES.php');
|
837 |
-
}
|
838 |
-
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
|
839 |
-
break;
|
840 |
-
case 'DES-EDE3-CBC':
|
841 |
-
if (!class_exists('Crypt_TripleDES')) {
|
842 |
-
require_once('Crypt/TripleDES.php');
|
843 |
-
}
|
844 |
-
$crypto = new Crypt_TripleDES();
|
845 |
-
break;
|
846 |
-
case 'DES-CBC':
|
847 |
-
if (!class_exists('Crypt_DES')) {
|
848 |
-
require_once('Crypt/DES.php');
|
849 |
-
}
|
850 |
-
$crypto = new Crypt_DES();
|
851 |
-
break;
|
852 |
-
default:
|
853 |
-
return false;
|
854 |
-
}
|
855 |
-
$crypto->setKey($symkey);
|
856 |
-
$crypto->setIV($iv);
|
857 |
-
$decoded = $crypto->decrypt($ciphertext);
|
858 |
-
} else {
|
859 |
-
$decoded = preg_replace('#-.+-|[\r\n]#', '', $key);
|
860 |
-
$decoded = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $decoded) ? base64_decode($decoded) : false;
|
861 |
-
}
|
862 |
-
|
863 |
-
if ($decoded !== false) {
|
864 |
-
$key = $decoded;
|
865 |
-
}
|
866 |
-
|
867 |
-
$components = array();
|
868 |
-
|
869 |
-
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
|
870 |
-
return false;
|
871 |
-
}
|
872 |
-
if ($this->_decodeLength($key) != strlen($key)) {
|
873 |
-
return false;
|
874 |
-
}
|
875 |
-
|
876 |
-
$tag = ord($this->_string_shift($key));
|
877 |
-
if ($tag == CRYPT_RSA_ASN1_SEQUENCE) {
|
878 |
-
/* intended for keys for which OpenSSL's asn1parse returns the following:
|
879 |
-
|
880 |
-
0:d=0 hl=4 l= 290 cons: SEQUENCE
|
881 |
-
4:d=1 hl=2 l= 13 cons: SEQUENCE
|
882 |
-
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
|
883 |
-
17:d=2 hl=2 l= 0 prim: NULL
|
884 |
-
19:d=1 hl=4 l= 271 prim: BIT STRING */
|
885 |
-
$this->_string_shift($key, $this->_decodeLength($key));
|
886 |
-
$this->_string_shift($key); // skip over the BIT STRING tag
|
887 |
-
$this->_decodeLength($key); // skip over the BIT STRING length
|
888 |
-
// "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
|
889 |
-
// unused bits in teh final subsequent octet. The number shall be in the range zero to seven."
|
890 |
-
// -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
|
891 |
-
$this->_string_shift($key);
|
892 |
-
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
|
893 |
-
return false;
|
894 |
-
}
|
895 |
-
if ($this->_decodeLength($key) != strlen($key)) {
|
896 |
-
return false;
|
897 |
-
}
|
898 |
-
$tag = ord($this->_string_shift($key));
|
899 |
-
}
|
900 |
-
if ($tag != CRYPT_RSA_ASN1_INTEGER) {
|
901 |
-
return false;
|
902 |
-
}
|
903 |
-
|
904 |
-
$length = $this->_decodeLength($key);
|
905 |
-
$temp = $this->_string_shift($key, $length);
|
906 |
-
if (strlen($temp) != 1 || ord($temp) > 2) {
|
907 |
-
$components['modulus'] = new Math_BigInteger($temp, -256);
|
908 |
-
$this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER
|
909 |
-
$length = $this->_decodeLength($key);
|
910 |
-
$components[$type == CRYPT_RSA_PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
911 |
-
|
912 |
-
return $components;
|
913 |
-
}
|
914 |
-
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) {
|
915 |
-
return false;
|
916 |
-
}
|
917 |
-
$length = $this->_decodeLength($key);
|
918 |
-
$components['modulus'] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
919 |
-
$this->_string_shift($key);
|
920 |
-
$length = $this->_decodeLength($key);
|
921 |
-
$components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
922 |
-
$this->_string_shift($key);
|
923 |
-
$length = $this->_decodeLength($key);
|
924 |
-
$components['privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
925 |
-
$this->_string_shift($key);
|
926 |
-
$length = $this->_decodeLength($key);
|
927 |
-
$components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), -256));
|
928 |
-
$this->_string_shift($key);
|
929 |
-
$length = $this->_decodeLength($key);
|
930 |
-
$components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
931 |
-
$this->_string_shift($key);
|
932 |
-
$length = $this->_decodeLength($key);
|
933 |
-
$components['exponents'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), -256));
|
934 |
-
$this->_string_shift($key);
|
935 |
-
$length = $this->_decodeLength($key);
|
936 |
-
$components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
937 |
-
$this->_string_shift($key);
|
938 |
-
$length = $this->_decodeLength($key);
|
939 |
-
$components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($key, $length), -256));
|
940 |
-
|
941 |
-
if (!empty($key)) {
|
942 |
-
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
|
943 |
-
return false;
|
944 |
-
}
|
945 |
-
$this->_decodeLength($key);
|
946 |
-
while (!empty($key)) {
|
947 |
-
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
|
948 |
-
return false;
|
949 |
-
}
|
950 |
-
$this->_decodeLength($key);
|
951 |
-
$key = substr($key, 1);
|
952 |
-
$length = $this->_decodeLength($key);
|
953 |
-
$components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
954 |
-
$this->_string_shift($key);
|
955 |
-
$length = $this->_decodeLength($key);
|
956 |
-
$components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
957 |
-
$this->_string_shift($key);
|
958 |
-
$length = $this->_decodeLength($key);
|
959 |
-
$components['coefficients'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
960 |
-
}
|
961 |
-
}
|
962 |
-
|
963 |
-
return $components;
|
964 |
-
case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
|
965 |
-
$key = base64_decode(preg_replace('#^ssh-rsa | .+$#', '', $key));
|
966 |
-
if ($key === false) {
|
967 |
-
return false;
|
968 |
-
}
|
969 |
-
|
970 |
-
$cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa";
|
971 |
-
|
972 |
-
extract(unpack('Nlength', $this->_string_shift($key, 4)));
|
973 |
-
$publicExponent = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
974 |
-
extract(unpack('Nlength', $this->_string_shift($key, 4)));
|
975 |
-
$modulus = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
976 |
-
|
977 |
-
if ($cleanup && strlen($key)) {
|
978 |
-
extract(unpack('Nlength', $this->_string_shift($key, 4)));
|
979 |
-
return array(
|
980 |
-
'modulus' => new Math_BigInteger($this->_string_shift($key, $length), -256),
|
981 |
-
'publicExponent' => $modulus
|
982 |
-
);
|
983 |
-
} else {
|
984 |
-
return array(
|
985 |
-
'modulus' => $modulus,
|
986 |
-
'publicExponent' => $publicExponent
|
987 |
-
);
|
988 |
-
}
|
989 |
-
// http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
|
990 |
-
// http://en.wikipedia.org/wiki/XML_Signature
|
991 |
-
case CRYPT_RSA_PRIVATE_FORMAT_XML:
|
992 |
-
case CRYPT_RSA_PUBLIC_FORMAT_XML:
|
993 |
-
$this->components = array();
|
994 |
-
|
995 |
-
$xml = xml_parser_create('UTF-8');
|
996 |
-
xml_set_object($xml, $this);
|
997 |
-
xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler');
|
998 |
-
xml_set_character_data_handler($xml, '_data_handler');
|
999 |
-
if (!xml_parse($xml, $key)) {
|
1000 |
-
return false;
|
1001 |
-
}
|
1002 |
-
|
1003 |
-
return $this->components;
|
1004 |
-
// from PuTTY's SSHPUBK.C
|
1005 |
-
case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
|
1006 |
-
$components = array();
|
1007 |
-
$key = preg_split('#\r\n|\r|\n#', $key);
|
1008 |
-
$type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
|
1009 |
-
if ($type != 'ssh-rsa') {
|
1010 |
-
return false;
|
1011 |
-
}
|
1012 |
-
$encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
|
1013 |
-
|
1014 |
-
$publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
|
1015 |
-
$public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
|
1016 |
-
$public = substr($public, 11);
|
1017 |
-
extract(unpack('Nlength', $this->_string_shift($public, 4)));
|
1018 |
-
$components['publicExponent'] = new Math_BigInteger($this->_string_shift($public, $length), -256);
|
1019 |
-
extract(unpack('Nlength', $this->_string_shift($public, 4)));
|
1020 |
-
$components['modulus'] = new Math_BigInteger($this->_string_shift($public, $length), -256);
|
1021 |
-
|
1022 |
-
$privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4]));
|
1023 |
-
$private = base64_decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
|
1024 |
-
|
1025 |
-
switch ($encryption) {
|
1026 |
-
case 'aes256-cbc':
|
1027 |
-
if (!class_exists('Crypt_AES')) {
|
1028 |
-
require_once('Crypt/AES.php');
|
1029 |
-
}
|
1030 |
-
$symkey = '';
|
1031 |
-
$sequence = 0;
|
1032 |
-
while (strlen($symkey) < 32) {
|
1033 |
-
$temp = pack('Na*', $sequence++, $this->password);
|
1034 |
-
$symkey.= pack('H*', sha1($temp));
|
1035 |
-
}
|
1036 |
-
$symkey = substr($symkey, 0, 32);
|
1037 |
-
$crypto = new Crypt_AES();
|
1038 |
-
}
|
1039 |
-
|
1040 |
-
if ($encryption != 'none') {
|
1041 |
-
$crypto->setKey($symkey);
|
1042 |
-
$crypto->disablePadding();
|
1043 |
-
$private = $crypto->decrypt($private);
|
1044 |
-
if ($private === false) {
|
1045 |
-
return false;
|
1046 |
-
}
|
1047 |
-
}
|
1048 |
-
|
1049 |
-
extract(unpack('Nlength', $this->_string_shift($private, 4)));
|
1050 |
-
$components['privateExponent'] = new Math_BigInteger($this->_string_shift($private, $length), -256);
|
1051 |
-
extract(unpack('Nlength', $this->_string_shift($private, 4)));
|
1052 |
-
$components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($private, $length), -256));
|
1053 |
-
extract(unpack('Nlength', $this->_string_shift($private, 4)));
|
1054 |
-
$components['primes'][] = new Math_BigInteger($this->_string_shift($private, $length), -256);
|
1055 |
-
|
1056 |
-
$temp = $components['primes'][1]->subtract($this->one);
|
1057 |
-
$components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
|
1058 |
-
$temp = $components['primes'][2]->subtract($this->one);
|
1059 |
-
$components['exponents'][] = $components['publicExponent']->modInverse($temp);
|
1060 |
-
|
1061 |
-
extract(unpack('Nlength', $this->_string_shift($private, 4)));
|
1062 |
-
$components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($private, $length), -256));
|
1063 |
-
|
1064 |
-
return $components;
|
1065 |
-
}
|
1066 |
-
}
|
1067 |
-
|
1068 |
-
/**
|
1069 |
-
* Start Element Handler
|
1070 |
-
*
|
1071 |
-
* Called by xml_set_element_handler()
|
1072 |
-
*
|
1073 |
-
* @access private
|
1074 |
-
* @param Resource $parser
|
1075 |
-
* @param String $name
|
1076 |
-
* @param Array $attribs
|
1077 |
-
*/
|
1078 |
-
function _start_element_handler($parser, $name, $attribs)
|
1079 |
-
{
|
1080 |
-
//$name = strtoupper($name);
|
1081 |
-
switch ($name) {
|
1082 |
-
case 'MODULUS':
|
1083 |
-
$this->current = &$this->components['modulus'];
|
1084 |
-
break;
|
1085 |
-
case 'EXPONENT':
|
1086 |
-
$this->current = &$this->components['publicExponent'];
|
1087 |
-
break;
|
1088 |
-
case 'P':
|
1089 |
-
$this->current = &$this->components['primes'][1];
|
1090 |
-
break;
|
1091 |
-
case 'Q':
|
1092 |
-
$this->current = &$this->components['primes'][2];
|
1093 |
-
break;
|
1094 |
-
case 'DP':
|
1095 |
-
$this->current = &$this->components['exponents'][1];
|
1096 |
-
break;
|
1097 |
-
case 'DQ':
|
1098 |
-
$this->current = &$this->components['exponents'][2];
|
1099 |
-
break;
|
1100 |
-
case 'INVERSEQ':
|
1101 |
-
$this->current = &$this->components['coefficients'][2];
|
1102 |
-
break;
|
1103 |
-
case 'D':
|
1104 |
-
$this->current = &$this->components['privateExponent'];
|
1105 |
-
break;
|
1106 |
-
default:
|
1107 |
-
unset($this->current);
|
1108 |
-
}
|
1109 |
-
$this->current = '';
|
1110 |
-
}
|
1111 |
-
|
1112 |
-
/**
|
1113 |
-
* Stop Element Handler
|
1114 |
-
*
|
1115 |
-
* Called by xml_set_element_handler()
|
1116 |
-
*
|
1117 |
-
* @access private
|
1118 |
-
* @param Resource $parser
|
1119 |
-
* @param String $name
|
1120 |
-
*/
|
1121 |
-
function _stop_element_handler($parser, $name)
|
1122 |
-
{
|
1123 |
-
//$name = strtoupper($name);
|
1124 |
-
if ($name == 'RSAKEYVALUE') {
|
1125 |
-
return;
|
1126 |
-
}
|
1127 |
-
$this->current = new Math_BigInteger(base64_decode($this->current), 256);
|
1128 |
-
}
|
1129 |
-
|
1130 |
-
/**
|
1131 |
-
* Data Handler
|
1132 |
-
*
|
1133 |
-
* Called by xml_set_character_data_handler()
|
1134 |
-
*
|
1135 |
-
* @access private
|
1136 |
-
* @param Resource $parser
|
1137 |
-
* @param String $data
|
1138 |
-
*/
|
1139 |
-
function _data_handler($parser, $data)
|
1140 |
-
{
|
1141 |
-
if (!isset($this->current) || is_object($this->current)) {
|
1142 |
-
return;
|
1143 |
-
}
|
1144 |
-
$this->current.= trim($data);
|
1145 |
-
}
|
1146 |
-
|
1147 |
-
/**
|
1148 |
-
* Loads a public or private key
|
1149 |
-
*
|
1150 |
-
* Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)
|
1151 |
-
*
|
1152 |
-
* @access public
|
1153 |
-
* @param String $key
|
1154 |
-
* @param Integer $type optional
|
1155 |
-
*/
|
1156 |
-
function loadKey($key, $type = false)
|
1157 |
-
{
|
1158 |
-
if ($type === false) {
|
1159 |
-
$types = array(
|
1160 |
-
CRYPT_RSA_PUBLIC_FORMAT_RAW,
|
1161 |
-
CRYPT_RSA_PRIVATE_FORMAT_PKCS1,
|
1162 |
-
CRYPT_RSA_PRIVATE_FORMAT_XML,
|
1163 |
-
CRYPT_RSA_PRIVATE_FORMAT_PUTTY,
|
1164 |
-
CRYPT_RSA_PUBLIC_FORMAT_OPENSSH
|
1165 |
-
);
|
1166 |
-
foreach ($types as $type) {
|
1167 |
-
$components = $this->_parseKey($key, $type);
|
1168 |
-
if ($components !== false) {
|
1169 |
-
break;
|
1170 |
-
}
|
1171 |
-
}
|
1172 |
-
|
1173 |
-
} else {
|
1174 |
-
$components = $this->_parseKey($key, $type);
|
1175 |
-
}
|
1176 |
-
|
1177 |
-
if ($components === false) {
|
1178 |
-
return false;
|
1179 |
-
}
|
1180 |
-
|
1181 |
-
$this->modulus = $components['modulus'];
|
1182 |
-
$this->k = strlen($this->modulus->toBytes());
|
1183 |
-
$this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];
|
1184 |
-
if (isset($components['primes'])) {
|
1185 |
-
$this->primes = $components['primes'];
|
1186 |
-
$this->exponents = $components['exponents'];
|
1187 |
-
$this->coefficients = $components['coefficients'];
|
1188 |
-
$this->publicExponent = $components['publicExponent'];
|
1189 |
-
} else {
|
1190 |
-
$this->primes = array();
|
1191 |
-
$this->exponents = array();
|
1192 |
-
$this->coefficients = array();
|
1193 |
-
$this->publicExponent = false;
|
1194 |
-
}
|
1195 |
-
|
1196 |
-
return true;
|
1197 |
-
}
|
1198 |
-
|
1199 |
-
/**
|
1200 |
-
* Sets the password
|
1201 |
-
*
|
1202 |
-
* Private keys can be encrypted with a password. To unset the password, pass in the empty string or false.
|
1203 |
-
* Or rather, pass in $password such that empty($password) is true.
|
1204 |
-
*
|
1205 |
-
* @see createKey()
|
1206 |
-
* @see loadKey()
|
1207 |
-
* @access public
|
1208 |
-
* @param String $password
|
1209 |
-
*/
|
1210 |
-
function setPassword($password)
|
1211 |
-
{
|
1212 |
-
$this->password = $password;
|
1213 |
-
}
|
1214 |
-
|
1215 |
-
/**
|
1216 |
-
* Defines the public key
|
1217 |
-
*
|
1218 |
-
* Some private key formats define the public exponent and some don't. Those that don't define it are problematic when
|
1219 |
-
* used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a
|
1220 |
-
* message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys
|
1221 |
-
* and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public
|
1222 |
-
* exponent this won't work unless you manually add the public exponent.
|
1223 |
-
*
|
1224 |
-
* Do note that when a new key is loaded the index will be cleared.
|
1225 |
-
*
|
1226 |
-
* Returns true on success, false on failure
|
1227 |
-
*
|
1228 |
-
* @see getPublicKey()
|
1229 |
-
* @access public
|
1230 |
-
* @param String $key
|
1231 |
-
* @param Integer $type optional
|
1232 |
-
* @return Boolean
|
1233 |
-
*/
|
1234 |
-
function setPublicKey($key, $type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)
|
1235 |
-
{
|
1236 |
-
$components = $this->_parseKey($key, $type);
|
1237 |
-
|
1238 |
-
if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) {
|
1239 |
-
user_error('Trying to load a public key? Use loadKey() instead. It\'s called loadKey() and not loadPrivateKey() for a reason.', E_USER_NOTICE);
|
1240 |
-
return false;
|
1241 |
-
}
|
1242 |
-
|
1243 |
-
$this->publicExponent = $components['publicExponent'];
|
1244 |
-
|
1245 |
-
return true;
|
1246 |
-
}
|
1247 |
-
|
1248 |
-
/**
|
1249 |
-
* Returns the public key
|
1250 |
-
*
|
1251 |
-
* The public key is only returned under two circumstances - if the private key had the public key embedded within it
|
1252 |
-
* or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this
|
1253 |
-
* function won't return it since this library, for the most part, doesn't distinguish between public and private keys.
|
1254 |
-
*
|
1255 |
-
* @see getPublicKey()
|
1256 |
-
* @access public
|
1257 |
-
* @param String $key
|
1258 |
-
* @param Integer $type optional
|
1259 |
-
*/
|
1260 |
-
function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)
|
1261 |
-
{
|
1262 |
-
if (empty($this->modulus) || empty($this->publicExponent)) {
|
1263 |
-
return false;
|
1264 |
-
}
|
1265 |
-
|
1266 |
-
$oldFormat = $this->publicKeyFormat;
|
1267 |
-
$this->publicKeyFormat = $type;
|
1268 |
-
$temp = $this->_convertPublicKey($this->modulus, $this->publicExponent);
|
1269 |
-
$this->publicKeyFormat = $oldFormat;
|
1270 |
-
return $temp;
|
1271 |
-
}
|
1272 |
-
|
1273 |
-
/**
|
1274 |
-
* Generates the smallest and largest numbers requiring $bits bits
|
1275 |
-
*
|
1276 |
-
* @access private
|
1277 |
-
* @param Integer $bits
|
1278 |
-
* @return Array
|
1279 |
-
*/
|
1280 |
-
function _generateMinMax($bits)
|
1281 |
-
{
|
1282 |
-
$bytes = $bits >> 3;
|
1283 |
-
$min = str_repeat(chr(0), $bytes);
|
1284 |
-
$max = str_repeat(chr(0xFF), $bytes);
|
1285 |
-
$msb = $bits & 7;
|
1286 |
-
if ($msb) {
|
1287 |
-
$min = chr(1 << ($msb - 1)) . $min;
|
1288 |
-
$max = chr((1 << $msb) - 1) . $max;
|
1289 |
-
} else {
|
1290 |
-
$min[0] = chr(0x80);
|
1291 |
-
}
|
1292 |
-
|
1293 |
-
return array(
|
1294 |
-
'min' => new Math_BigInteger($min, 256),
|
1295 |
-
'max' => new Math_BigInteger($max, 256)
|
1296 |
-
);
|
1297 |
-
}
|
1298 |
-
|
1299 |
-
/**
|
1300 |
-
* DER-decode the length
|
1301 |
-
*
|
1302 |
-
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
1303 |
-
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 � 8.1.3} for more information.
|
1304 |
-
*
|
1305 |
-
* @access private
|
1306 |
-
* @param String $string
|
1307 |
-
* @return Integer
|
1308 |
-
*/
|
1309 |
-
function _decodeLength(&$string)
|
1310 |
-
{
|
1311 |
-
$length = ord($this->_string_shift($string));
|
1312 |
-
if ( $length & 0x80 ) { // definite length, long form
|
1313 |
-
$length&= 0x7F;
|
1314 |
-
$temp = $this->_string_shift($string, $length);
|
1315 |
-
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
|
1316 |
-
}
|
1317 |
-
return $length;
|
1318 |
-
}
|
1319 |
-
|
1320 |
-
/**
|
1321 |
-
* DER-encode the length
|
1322 |
-
*
|
1323 |
-
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
1324 |
-
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 � 8.1.3} for more information.
|
1325 |
-
*
|
1326 |
-
* @access private
|
1327 |
-
* @param Integer $length
|
1328 |
-
* @return String
|
1329 |
-
*/
|
1330 |
-
function _encodeLength($length)
|
1331 |
-
{
|
1332 |
-
if ($length <= 0x7F) {
|
1333 |
-
return chr($length);
|
1334 |
-
}
|
1335 |
-
|
1336 |
-
$temp = ltrim(pack('N', $length), chr(0));
|
1337 |
-
return pack('Ca*', 0x80 | strlen($temp), $temp);
|
1338 |
-
}
|
1339 |
-
|
1340 |
-
/**
|
1341 |
-
* String Shift
|
1342 |
-
*
|
1343 |
-
* Inspired by array_shift
|
1344 |
-
*
|
1345 |
-
* @param String $string
|
1346 |
-
* @param optional Integer $index
|
1347 |
-
* @return String
|
1348 |
-
* @access private
|
1349 |
-
*/
|
1350 |
-
function _string_shift(&$string, $index = 1)
|
1351 |
-
{
|
1352 |
-
$substr = substr($string, 0, $index);
|
1353 |
-
$string = substr($string, $index);
|
1354 |
-
return $substr;
|
1355 |
-
}
|
1356 |
-
|
1357 |
-
/**
|
1358 |
-
* Determines the private key format
|
1359 |
-
*
|
1360 |
-
* @see createKey()
|
1361 |
-
* @access public
|
1362 |
-
* @param Integer $format
|
1363 |
-
*/
|
1364 |
-
function setPrivateKeyFormat($format)
|
1365 |
-
{
|
1366 |
-
$this->privateKeyFormat = $format;
|
1367 |
-
}
|
1368 |
-
|
1369 |
-
/**
|
1370 |
-
* Determines the public key format
|
1371 |
-
*
|
1372 |
-
* @see createKey()
|
1373 |
-
* @access public
|
1374 |
-
* @param Integer $format
|
1375 |
-
*/
|
1376 |
-
function setPublicKeyFormat($format)
|
1377 |
-
{
|
1378 |
-
$this->publicKeyFormat = $format;
|
1379 |
-
}
|
1380 |
-
|
1381 |
-
/**
|
1382 |
-
* Determines which hashing function should be used
|
1383 |
-
*
|
1384 |
-
* Used with signature production / verification and (if the encryption mode is CRYPT_RSA_ENCRYPTION_OAEP) encryption and
|
1385 |
-
* decryption. If $hash isn't supported, sha1 is used.
|
1386 |
-
*
|
1387 |
-
* @access public
|
1388 |
-
* @param String $hash
|
1389 |
-
*/
|
1390 |
-
function setHash($hash)
|
1391 |
-
{
|
1392 |
-
// Crypt_Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
|
1393 |
-
switch ($hash) {
|
1394 |
-
case 'md2':
|
1395 |
-
case 'md5':
|
1396 |
-
case 'sha1':
|
1397 |
-
case 'sha256':
|
1398 |
-
case 'sha384':
|
1399 |
-
case 'sha512':
|
1400 |
-
$this->hash = new Crypt_Hash($hash);
|
1401 |
-
$this->hashName = $hash;
|
1402 |
-
break;
|
1403 |
-
default:
|
1404 |
-
$this->hash = new Crypt_Hash('sha1');
|
1405 |
-
$this->hashName = 'sha1';
|
1406 |
-
}
|
1407 |
-
$this->hLen = $this->hash->getLength();
|
1408 |
-
}
|
1409 |
-
|
1410 |
-
/**
|
1411 |
-
* Determines which hashing function should be used for the mask generation function
|
1412 |
-
*
|
1413 |
-
* The mask generation function is used by CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_SIGNATURE_PSS and although it's
|
1414 |
-
* best if Hash and MGFHash are set to the same thing this is not a requirement.
|
1415 |
-
*
|
1416 |
-
* @access public
|
1417 |
-
* @param String $hash
|
1418 |
-
*/
|
1419 |
-
function setMGFHash($hash)
|
1420 |
-
{
|
1421 |
-
// Crypt_Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
|
1422 |
-
switch ($hash) {
|
1423 |
-
case 'md2':
|
1424 |
-
case 'md5':
|
1425 |
-
case 'sha1':
|
1426 |
-
case 'sha256':
|
1427 |
-
case 'sha384':
|
1428 |
-
case 'sha512':
|
1429 |
-
$this->mgfHash = new Crypt_Hash($hash);
|
1430 |
-
break;
|
1431 |
-
default:
|
1432 |
-
$this->mgfHash = new Crypt_Hash('sha1');
|
1433 |
-
}
|
1434 |
-
$this->mgfHLen = $this->mgfHash->getLength();
|
1435 |
-
}
|
1436 |
-
|
1437 |
-
/**
|
1438 |
-
* Determines the salt length
|
1439 |
-
*
|
1440 |
-
* To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
|
1441 |
-
*
|
1442 |
-
* Typical salt lengths in octets are hLen (the length of the output
|
1443 |
-
* of the hash function Hash) and 0.
|
1444 |
-
*
|
1445 |
-
* @access public
|
1446 |
-
* @param Integer $format
|
1447 |
-
*/
|
1448 |
-
function setSaltLength($sLen)
|
1449 |
-
{
|
1450 |
-
$this->sLen = $sLen;
|
1451 |
-
}
|
1452 |
-
|
1453 |
-
/**
|
1454 |
-
* Generates a random string x bytes long
|
1455 |
-
*
|
1456 |
-
* @access public
|
1457 |
-
* @param Integer $bytes
|
1458 |
-
* @param optional Integer $nonzero
|
1459 |
-
* @return String
|
1460 |
-
*/
|
1461 |
-
function _random($bytes, $nonzero = false)
|
1462 |
-
{
|
1463 |
-
$temp = '';
|
1464 |
-
if ($nonzero) {
|
1465 |
-
for ($i = 0; $i < $bytes; $i++) {
|
1466 |
-
$temp.= chr(crypt_random(1, 255));
|
1467 |
-
}
|
1468 |
-
} else {
|
1469 |
-
$ints = ($bytes + 1) >> 2;
|
1470 |
-
for ($i = 0; $i < $ints; $i++) {
|
1471 |
-
$temp.= pack('N', crypt_random());
|
1472 |
-
}
|
1473 |
-
$temp = substr($temp, 0, $bytes);
|
1474 |
-
}
|
1475 |
-
return $temp;
|
1476 |
-
}
|
1477 |
-
|
1478 |
-
/**
|
1479 |
-
* Integer-to-Octet-String primitive
|
1480 |
-
*
|
1481 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
|
1482 |
-
*
|
1483 |
-
* @access private
|
1484 |
-
* @param Math_BigInteger $x
|
1485 |
-
* @param Integer $xLen
|
1486 |
-
* @return String
|
1487 |
-
*/
|
1488 |
-
function _i2osp($x, $xLen)
|
1489 |
-
{
|
1490 |
-
$x = $x->toBytes();
|
1491 |
-
if (strlen($x) > $xLen) {
|
1492 |
-
user_error('Integer too large', E_USER_NOTICE);
|
1493 |
-
return false;
|
1494 |
-
}
|
1495 |
-
return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
|
1496 |
-
}
|
1497 |
-
|
1498 |
-
/**
|
1499 |
-
* Octet-String-to-Integer primitive
|
1500 |
-
*
|
1501 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
|
1502 |
-
*
|
1503 |
-
* @access private
|
1504 |
-
* @param String $x
|
1505 |
-
* @return Math_BigInteger
|
1506 |
-
*/
|
1507 |
-
function _os2ip($x)
|
1508 |
-
{
|
1509 |
-
return new Math_BigInteger($x, 256);
|
1510 |
-
}
|
1511 |
-
|
1512 |
-
/**
|
1513 |
-
* Exponentiate with or without Chinese Remainder Theorem
|
1514 |
-
*
|
1515 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.
|
1516 |
-
*
|
1517 |
-
* @access private
|
1518 |
-
* @param Math_BigInteger $x
|
1519 |
-
* @return Math_BigInteger
|
1520 |
-
*/
|
1521 |
-
function _exponentiate($x)
|
1522 |
-
{
|
1523 |
-
if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {
|
1524 |
-
return $x->modPow($this->exponent, $this->modulus);
|
1525 |
-
}
|
1526 |
-
|
1527 |
-
$num_primes = count($this->primes);
|
1528 |
-
|
1529 |
-
if (defined('CRYPT_RSA_DISABLE_BLINDING')) {
|
1530 |
-
$m_i = array(
|
1531 |
-
1 => $x->modPow($this->exponents[1], $this->primes[1]),
|
1532 |
-
2 => $x->modPow($this->exponents[2], $this->primes[2])
|
1533 |
-
);
|
1534 |
-
$h = $m_i[1]->subtract($m_i[2]);
|
1535 |
-
$h = $h->multiply($this->coefficients[2]);
|
1536 |
-
list(, $h) = $h->divide($this->primes[1]);
|
1537 |
-
$m = $m_i[2]->add($h->multiply($this->primes[2]));
|
1538 |
-
|
1539 |
-
$r = $this->primes[1];
|
1540 |
-
for ($i = 3; $i <= $num_primes; $i++) {
|
1541 |
-
$m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);
|
1542 |
-
|
1543 |
-
$r = $r->multiply($this->primes[$i - 1]);
|
1544 |
-
|
1545 |
-
$h = $m_i->subtract($m);
|
1546 |
-
$h = $h->multiply($this->coefficients[$i]);
|
1547 |
-
list(, $h) = $h->divide($this->primes[$i]);
|
1548 |
-
|
1549 |
-
$m = $m->add($r->multiply($h));
|
1550 |
-
}
|
1551 |
-
} else {
|
1552 |
-
$smallest = $this->primes[1];
|
1553 |
-
for ($i = 2; $i <= $num_primes; $i++) {
|
1554 |
-
if ($smallest->compare($this->primes[$i]) > 0) {
|
1555 |
-
$smallest = $this->primes[$i];
|
1556 |
-
}
|
1557 |
-
}
|
1558 |
-
|
1559 |
-
$one = new Math_BigInteger(1);
|
1560 |
-
$one->setRandomGenerator('crypt_random');
|
1561 |
-
|
1562 |
-
$r = $one->random($one, $smallest->subtract($one));
|
1563 |
-
|
1564 |
-
$m_i = array(
|
1565 |
-
1 => $this->_blind($x, $r, 1),
|
1566 |
-
2 => $this->_blind($x, $r, 2)
|
1567 |
-
);
|
1568 |
-
$h = $m_i[1]->subtract($m_i[2]);
|
1569 |
-
$h = $h->multiply($this->coefficients[2]);
|
1570 |
-
list(, $h) = $h->divide($this->primes[1]);
|
1571 |
-
$m = $m_i[2]->add($h->multiply($this->primes[2]));
|
1572 |
-
|
1573 |
-
$r = $this->primes[1];
|
1574 |
-
for ($i = 3; $i <= $num_primes; $i++) {
|
1575 |
-
$m_i = $this->_blind($x, $r, $i);
|
1576 |
-
|
1577 |
-
$r = $r->multiply($this->primes[$i - 1]);
|
1578 |
-
|
1579 |
-
$h = $m_i->subtract($m);
|
1580 |
-
$h = $h->multiply($this->coefficients[$i]);
|
1581 |
-
list(, $h) = $h->divide($this->primes[$i]);
|
1582 |
-
|
1583 |
-
$m = $m->add($r->multiply($h));
|
1584 |
-
}
|
1585 |
-
}
|
1586 |
-
|
1587 |
-
return $m;
|
1588 |
-
}
|
1589 |
-
|
1590 |
-
/**
|
1591 |
-
* Performs RSA Blinding
|
1592 |
-
*
|
1593 |
-
* Protects against timing attacks by employing RSA Blinding.
|
1594 |
-
* Returns $x->modPow($this->exponents[$i], $this->primes[$i])
|
1595 |
-
*
|
1596 |
-
* @access private
|
1597 |
-
* @param Math_BigInteger $x
|
1598 |
-
* @param Math_BigInteger $r
|
1599 |
-
* @param Integer $i
|
1600 |
-
* @return Math_BigInteger
|
1601 |
-
*/
|
1602 |
-
function _blind($x, $r, $i)
|
1603 |
-
{
|
1604 |
-
$x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i]));
|
1605 |
-
$x = $x->modPow($this->exponents[$i], $this->primes[$i]);
|
1606 |
-
|
1607 |
-
$r = $r->modInverse($this->primes[$i]);
|
1608 |
-
$x = $x->multiply($r);
|
1609 |
-
list(, $x) = $x->divide($this->primes[$i]);
|
1610 |
-
|
1611 |
-
return $x;
|
1612 |
-
}
|
1613 |
-
|
1614 |
-
/**
|
1615 |
-
* RSAEP
|
1616 |
-
*
|
1617 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}.
|
1618 |
-
*
|
1619 |
-
* @access private
|
1620 |
-
* @param Math_BigInteger $m
|
1621 |
-
* @return Math_BigInteger
|
1622 |
-
*/
|
1623 |
-
function _rsaep($m)
|
1624 |
-
{
|
1625 |
-
if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
|
1626 |
-
user_error('Message representative out of range', E_USER_NOTICE);
|
1627 |
-
return false;
|
1628 |
-
}
|
1629 |
-
return $this->_exponentiate($m);
|
1630 |
-
}
|
1631 |
-
|
1632 |
-
/**
|
1633 |
-
* RSADP
|
1634 |
-
*
|
1635 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}.
|
1636 |
-
*
|
1637 |
-
* @access private
|
1638 |
-
* @param Math_BigInteger $c
|
1639 |
-
* @return Math_BigInteger
|
1640 |
-
*/
|
1641 |
-
function _rsadp($c)
|
1642 |
-
{
|
1643 |
-
if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
|
1644 |
-
user_error('Ciphertext representative out of range', E_USER_NOTICE);
|
1645 |
-
return false;
|
1646 |
-
}
|
1647 |
-
return $this->_exponentiate($c);
|
1648 |
-
}
|
1649 |
-
|
1650 |
-
/**
|
1651 |
-
* RSASP1
|
1652 |
-
*
|
1653 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}.
|
1654 |
-
*
|
1655 |
-
* @access private
|
1656 |
-
* @param Math_BigInteger $m
|
1657 |
-
* @return Math_BigInteger
|
1658 |
-
*/
|
1659 |
-
function _rsasp1($m)
|
1660 |
-
{
|
1661 |
-
if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
|
1662 |
-
user_error('Message representative out of range', E_USER_NOTICE);
|
1663 |
-
return false;
|
1664 |
-
}
|
1665 |
-
return $this->_exponentiate($m);
|
1666 |
-
}
|
1667 |
-
|
1668 |
-
/**
|
1669 |
-
* RSAVP1
|
1670 |
-
*
|
1671 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}.
|
1672 |
-
*
|
1673 |
-
* @access private
|
1674 |
-
* @param Math_BigInteger $s
|
1675 |
-
* @return Math_BigInteger
|
1676 |
-
*/
|
1677 |
-
function _rsavp1($s)
|
1678 |
-
{
|
1679 |
-
if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
|
1680 |
-
user_error('Signature representative out of range', E_USER_NOTICE);
|
1681 |
-
return false;
|
1682 |
-
}
|
1683 |
-
return $this->_exponentiate($s);
|
1684 |
-
}
|
1685 |
-
|
1686 |
-
/**
|
1687 |
-
* MGF1
|
1688 |
-
*
|
1689 |
-
* See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
|
1690 |
-
*
|
1691 |
-
* @access private
|
1692 |
-
* @param String $mgfSeed
|
1693 |
-
* @param Integer $mgfLen
|
1694 |
-
* @return String
|
1695 |
-
*/
|
1696 |
-
function _mgf1($mgfSeed, $maskLen)
|
1697 |
-
{
|
1698 |
-
// if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
|
1699 |
-
|
1700 |
-
$t = '';
|
1701 |
-
$count = ceil($maskLen / $this->mgfHLen);
|
1702 |
-
for ($i = 0; $i < $count; $i++) {
|
1703 |
-
$c = pack('N', $i);
|
1704 |
-
$t.= $this->mgfHash->hash($mgfSeed . $c);
|
1705 |
-
}
|
1706 |
-
|
1707 |
-
return substr($t, 0, $maskLen);
|
1708 |
-
}
|
1709 |
-
|
1710 |
-
/**
|
1711 |
-
* RSAES-OAEP-ENCRYPT
|
1712 |
-
*
|
1713 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and
|
1714 |
-
* {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.
|
1715 |
-
*
|
1716 |
-
* @access private
|
1717 |
-
* @param String $m
|
1718 |
-
* @param String $l
|
1719 |
-
* @return String
|
1720 |
-
*/
|
1721 |
-
function _rsaes_oaep_encrypt($m, $l = '')
|
1722 |
-
{
|
1723 |
-
$mLen = strlen($m);
|
1724 |
-
|
1725 |
-
// Length checking
|
1726 |
-
|
1727 |
-
// if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
|
1728 |
-
// be output.
|
1729 |
-
|
1730 |
-
if ($mLen > $this->k - 2 * $this->hLen - 2) {
|
1731 |
-
user_error('Message too long', E_USER_NOTICE);
|
1732 |
-
return false;
|
1733 |
-
}
|
1734 |
-
|
1735 |
-
// EME-OAEP encoding
|
1736 |
-
|
1737 |
-
$lHash = $this->hash->hash($l);
|
1738 |
-
$ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2);
|
1739 |
-
$db = $lHash . $ps . chr(1) . $m;
|
1740 |
-
$seed = $this->_random($this->hLen);
|
1741 |
-
$dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
|
1742 |
-
$maskedDB = $db ^ $dbMask;
|
1743 |
-
$seedMask = $this->_mgf1($maskedDB, $this->hLen);
|
1744 |
-
$maskedSeed = $seed ^ $seedMask;
|
1745 |
-
$em = chr(0) . $maskedSeed . $maskedDB;
|
1746 |
-
|
1747 |
-
// RSA encryption
|
1748 |
-
|
1749 |
-
$m = $this->_os2ip($em);
|
1750 |
-
$c = $this->_rsaep($m);
|
1751 |
-
$c = $this->_i2osp($c, $this->k);
|
1752 |
-
|
1753 |
-
// Output the ciphertext C
|
1754 |
-
|
1755 |
-
return $c;
|
1756 |
-
}
|
1757 |
-
|
1758 |
-
/**
|
1759 |
-
* RSAES-OAEP-DECRYPT
|
1760 |
-
*
|
1761 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error
|
1762 |
-
* messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2:
|
1763 |
-
*
|
1764 |
-
* Note. Care must be taken to ensure that an opponent cannot
|
1765 |
-
* distinguish the different error conditions in Step 3.g, whether by
|
1766 |
-
* error message or timing, or, more generally, learn partial
|
1767 |
-
* information about the encoded message EM. Otherwise an opponent may
|
1768 |
-
* be able to obtain useful information about the decryption of the
|
1769 |
-
* ciphertext C, leading to a chosen-ciphertext attack such as the one
|
1770 |
-
* observed by Manger [36].
|
1771 |
-
*
|
1772 |
-
* As for $l... to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
|
1773 |
-
*
|
1774 |
-
* Both the encryption and the decryption operations of RSAES-OAEP take
|
1775 |
-
* the value of a label L as input. In this version of PKCS #1, L is
|
1776 |
-
* the empty string; other uses of the label are outside the scope of
|
1777 |
-
* this document.
|
1778 |
-
*
|
1779 |
-
* @access private
|
1780 |
-
* @param String $c
|
1781 |
-
* @param String $l
|
1782 |
-
* @return String
|
1783 |
-
*/
|
1784 |
-
function _rsaes_oaep_decrypt($c, $l = '')
|
1785 |
-
{
|
1786 |
-
// Length checking
|
1787 |
-
|
1788 |
-
// if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
|
1789 |
-
// be output.
|
1790 |
-
|
1791 |
-
if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
|
1792 |
-
user_error('Decryption error', E_USER_NOTICE);
|
1793 |
-
return false;
|
1794 |
-
}
|
1795 |
-
|
1796 |
-
// RSA decryption
|
1797 |
-
|
1798 |
-
$c = $this->_os2ip($c);
|
1799 |
-
$m = $this->_rsadp($c);
|
1800 |
-
if ($m === false) {
|
1801 |
-
user_error('Decryption error', E_USER_NOTICE);
|
1802 |
-
return false;
|
1803 |
-
}
|
1804 |
-
$em = $this->_i2osp($m, $this->k);
|
1805 |
-
|
1806 |
-
// EME-OAEP decoding
|
1807 |
-
|
1808 |
-
$lHash = $this->hash->hash($l);
|
1809 |
-
$y = ord($em[0]);
|
1810 |
-
$maskedSeed = substr($em, 1, $this->hLen);
|
1811 |
-
$maskedDB = substr($em, $this->hLen + 1);
|
1812 |
-
$seedMask = $this->_mgf1($maskedDB, $this->hLen);
|
1813 |
-
$seed = $maskedSeed ^ $seedMask;
|
1814 |
-
$dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
|
1815 |
-
$db = $maskedDB ^ $dbMask;
|
1816 |
-
$lHash2 = substr($db, 0, $this->hLen);
|
1817 |
-
$m = substr($db, $this->hLen);
|
1818 |
-
if ($lHash != $lHash2) {
|
1819 |
-
user_error('Decryption error', E_USER_NOTICE);
|
1820 |
-
return false;
|
1821 |
-
}
|
1822 |
-
$m = ltrim($m, chr(0));
|
1823 |
-
if (ord($m[0]) != 1) {
|
1824 |
-
user_error('Decryption error', E_USER_NOTICE);
|
1825 |
-
return false;
|
1826 |
-
}
|
1827 |
-
|
1828 |
-
// Output the message M
|
1829 |
-
|
1830 |
-
return substr($m, 1);
|
1831 |
-
}
|
1832 |
-
|
1833 |
-
/**
|
1834 |
-
* RSAES-PKCS1-V1_5-ENCRYPT
|
1835 |
-
*
|
1836 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}.
|
1837 |
-
*
|
1838 |
-
* @access private
|
1839 |
-
* @param String $m
|
1840 |
-
* @return String
|
1841 |
-
*/
|
1842 |
-
function _rsaes_pkcs1_v1_5_encrypt($m)
|
1843 |
-
{
|
1844 |
-
$mLen = strlen($m);
|
1845 |
-
|
1846 |
-
// Length checking
|
1847 |
-
|
1848 |
-
if ($mLen > $this->k - 11) {
|
1849 |
-
user_error('Message too long', E_USER_NOTICE);
|
1850 |
-
return false;
|
1851 |
-
}
|
1852 |
-
|
1853 |
-
// EME-PKCS1-v1_5 encoding
|
1854 |
-
|
1855 |
-
$ps = $this->_random($this->k - $mLen - 3, true);
|
1856 |
-
$em = chr(0) . chr(2) . $ps . chr(0) . $m;
|
1857 |
-
|
1858 |
-
// RSA encryption
|
1859 |
-
$m = $this->_os2ip($em);
|
1860 |
-
$c = $this->_rsaep($m);
|
1861 |
-
$c = $this->_i2osp($c, $this->k);
|
1862 |
-
|
1863 |
-
// Output the ciphertext C
|
1864 |
-
|
1865 |
-
return $c;
|
1866 |
-
}
|
1867 |
-
|
1868 |
-
/**
|
1869 |
-
* RSAES-PKCS1-V1_5-DECRYPT
|
1870 |
-
*
|
1871 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}.
|
1872 |
-
*
|
1873 |
-
* For compatability purposes, this function departs slightly from the description given in RFC3447.
|
1874 |
-
* The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the
|
1875 |
-
* private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the
|
1876 |
-
* public key should have the second byte set to 2. In RFC3447 (PKCS#1 v2.1), the second byte is supposed
|
1877 |
-
* to be 2 regardless of which key is used. for compatability purposes, we'll just check to make sure the
|
1878 |
-
* second byte is 2 or less. If it is, we'll accept the decrypted string as valid.
|
1879 |
-
*
|
1880 |
-
* As a consequence of this, a private key encrypted ciphertext produced with Crypt_RSA may not decrypt
|
1881 |
-
* with a strictly PKCS#1 v1.5 compliant RSA implementation. Public key encrypted ciphertext's should but
|
1882 |
-
* not private key encrypted ciphertext's.
|
1883 |
-
*
|
1884 |
-
* @access private
|
1885 |
-
* @param String $c
|
1886 |
-
* @return String
|
1887 |
-
*/
|
1888 |
-
function _rsaes_pkcs1_v1_5_decrypt($c)
|
1889 |
-
{
|
1890 |
-
// Length checking
|
1891 |
-
|
1892 |
-
if (strlen($c) != $this->k) { // or if k < 11
|
1893 |
-
user_error('Decryption error', E_USER_NOTICE);
|
1894 |
-
return false;
|
1895 |
-
}
|
1896 |
-
|
1897 |
-
// RSA decryption
|
1898 |
-
|
1899 |
-
$c = $this->_os2ip($c);
|
1900 |
-
$m = $this->_rsadp($c);
|
1901 |
-
|
1902 |
-
if ($m === false) {
|
1903 |
-
user_error('Decryption error', E_USER_NOTICE);
|
1904 |
-
return false;
|
1905 |
-
}
|
1906 |
-
$em = $this->_i2osp($m, $this->k);
|
1907 |
-
|
1908 |
-
// EME-PKCS1-v1_5 decoding
|
1909 |
-
|
1910 |
-
if (ord($em[0]) != 0 || ord($em[1]) > 2) {
|
1911 |
-
user_error('Decryption error', E_USER_NOTICE);
|
1912 |
-
return false;
|
1913 |
-
}
|
1914 |
-
|
1915 |
-
$ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
|
1916 |
-
$m = substr($em, strlen($ps) + 3);
|
1917 |
-
|
1918 |
-
if (strlen($ps) < 8) {
|
1919 |
-
user_error('Decryption error', E_USER_NOTICE);
|
1920 |
-
return false;
|
1921 |
-
}
|
1922 |
-
|
1923 |
-
// Output M
|
1924 |
-
|
1925 |
-
return $m;
|
1926 |
-
}
|
1927 |
-
|
1928 |
-
/**
|
1929 |
-
* EMSA-PSS-ENCODE
|
1930 |
-
*
|
1931 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.
|
1932 |
-
*
|
1933 |
-
* @access private
|
1934 |
-
* @param String $m
|
1935 |
-
* @param Integer $emBits
|
1936 |
-
*/
|
1937 |
-
function _emsa_pss_encode($m, $emBits)
|
1938 |
-
{
|
1939 |
-
// if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
|
1940 |
-
// be output.
|
1941 |
-
|
1942 |
-
$emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8)
|
1943 |
-
$sLen = $this->sLen == false ? $this->hLen : $this->sLen;
|
1944 |
-
|
1945 |
-
$mHash = $this->hash->hash($m);
|
1946 |
-
if ($emLen < $this->hLen + $sLen + 2) {
|
1947 |
-
user_error('Encoding error', E_USER_NOTICE);
|
1948 |
-
return false;
|
1949 |
-
}
|
1950 |
-
|
1951 |
-
$salt = $this->_random($sLen);
|
1952 |
-
$m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
|
1953 |
-
$h = $this->hash->hash($m2);
|
1954 |
-
$ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2);
|
1955 |
-
$db = $ps . chr(1) . $salt;
|
1956 |
-
$dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
|
1957 |
-
$maskedDB = $db ^ $dbMask;
|
1958 |
-
$maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0];
|
1959 |
-
$em = $maskedDB . $h . chr(0xBC);
|
1960 |
-
|
1961 |
-
return $em;
|
1962 |
-
}
|
1963 |
-
|
1964 |
-
/**
|
1965 |
-
* EMSA-PSS-VERIFY
|
1966 |
-
*
|
1967 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}.
|
1968 |
-
*
|
1969 |
-
* @access private
|
1970 |
-
* @param String $m
|
1971 |
-
* @param String $em
|
1972 |
-
* @param Integer $emBits
|
1973 |
-
* @return String
|
1974 |
-
*/
|
1975 |
-
function _emsa_pss_verify($m, $em, $emBits)
|
1976 |
-
{
|
1977 |
-
// if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
|
1978 |
-
// be output.
|
1979 |
-
|
1980 |
-
$emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8);
|
1981 |
-
$sLen = $this->sLen == false ? $this->hLen : $this->sLen;
|
1982 |
-
|
1983 |
-
$mHash = $this->hash->hash($m);
|
1984 |
-
if ($emLen < $this->hLen + $sLen + 2) {
|
1985 |
-
return false;
|
1986 |
-
}
|
1987 |
-
|
1988 |
-
if ($em[strlen($em) - 1] != chr(0xBC)) {
|
1989 |
-
return false;
|
1990 |
-
}
|
1991 |
-
|
1992 |
-
$maskedDB = substr($em, 0, -$this->hLen - 1);
|
1993 |
-
$h = substr($em, -$this->hLen - 1, $this->hLen);
|
1994 |
-
$temp = chr(0xFF << ($emBits & 7));
|
1995 |
-
if ((~$maskedDB[0] & $temp) != $temp) {
|
1996 |
-
return false;
|
1997 |
-
}
|
1998 |
-
$dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
|
1999 |
-
$db = $maskedDB ^ $dbMask;
|
2000 |
-
$db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];
|
2001 |
-
$temp = $emLen - $this->hLen - $sLen - 2;
|
2002 |
-
if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) {
|
2003 |
-
return false;
|
2004 |
-
}
|
2005 |
-
$salt = substr($db, $temp + 1); // should be $sLen long
|
2006 |
-
$m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
|
2007 |
-
$h2 = $this->hash->hash($m2);
|
2008 |
-
return $h == $h2;
|
2009 |
-
}
|
2010 |
-
|
2011 |
-
/**
|
2012 |
-
* RSASSA-PSS-SIGN
|
2013 |
-
*
|
2014 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}.
|
2015 |
-
*
|
2016 |
-
* @access private
|
2017 |
-
* @param String $m
|
2018 |
-
* @return String
|
2019 |
-
*/
|
2020 |
-
function _rsassa_pss_sign($m)
|
2021 |
-
{
|
2022 |
-
// EMSA-PSS encoding
|
2023 |
-
|
2024 |
-
$em = $this->_emsa_pss_encode($m, 8 * $this->k - 1);
|
2025 |
-
|
2026 |
-
// RSA signature
|
2027 |
-
|
2028 |
-
$m = $this->_os2ip($em);
|
2029 |
-
$s = $this->_rsasp1($m);
|
2030 |
-
$s = $this->_i2osp($s, $this->k);
|
2031 |
-
|
2032 |
-
// Output the signature S
|
2033 |
-
|
2034 |
-
return $s;
|
2035 |
-
}
|
2036 |
-
|
2037 |
-
/**
|
2038 |
-
* RSASSA-PSS-VERIFY
|
2039 |
-
*
|
2040 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}.
|
2041 |
-
*
|
2042 |
-
* @access private
|
2043 |
-
* @param String $m
|
2044 |
-
* @param String $s
|
2045 |
-
* @return String
|
2046 |
-
*/
|
2047 |
-
function _rsassa_pss_verify($m, $s)
|
2048 |
-
{
|
2049 |
-
// Length checking
|
2050 |
-
|
2051 |
-
if (strlen($s) != $this->k) {
|
2052 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2053 |
-
return false;
|
2054 |
-
}
|
2055 |
-
|
2056 |
-
// RSA verification
|
2057 |
-
|
2058 |
-
$modBits = 8 * $this->k;
|
2059 |
-
|
2060 |
-
$s2 = $this->_os2ip($s);
|
2061 |
-
$m2 = $this->_rsavp1($s2);
|
2062 |
-
if ($m2 === false) {
|
2063 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2064 |
-
return false;
|
2065 |
-
}
|
2066 |
-
$em = $this->_i2osp($m2, $modBits >> 3);
|
2067 |
-
if ($em === false) {
|
2068 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2069 |
-
return false;
|
2070 |
-
}
|
2071 |
-
|
2072 |
-
// EMSA-PSS verification
|
2073 |
-
|
2074 |
-
return $this->_emsa_pss_verify($m, $em, $modBits - 1);
|
2075 |
-
}
|
2076 |
-
|
2077 |
-
/**
|
2078 |
-
* EMSA-PKCS1-V1_5-ENCODE
|
2079 |
-
*
|
2080 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
|
2081 |
-
*
|
2082 |
-
* @access private
|
2083 |
-
* @param String $m
|
2084 |
-
* @param Integer $emLen
|
2085 |
-
* @return String
|
2086 |
-
*/
|
2087 |
-
function _emsa_pkcs1_v1_5_encode($m, $emLen)
|
2088 |
-
{
|
2089 |
-
$h = $this->hash->hash($m);
|
2090 |
-
if ($h === false) {
|
2091 |
-
return false;
|
2092 |
-
}
|
2093 |
-
|
2094 |
-
// see http://tools.ietf.org/html/rfc3447#page-43
|
2095 |
-
switch ($this->hashName) {
|
2096 |
-
case 'md2':
|
2097 |
-
$t = pack('H*', '3020300c06082a864886f70d020205000410');
|
2098 |
-
break;
|
2099 |
-
case 'md5':
|
2100 |
-
$t = pack('H*', '3020300c06082a864886f70d020505000410');
|
2101 |
-
break;
|
2102 |
-
case 'sha1':
|
2103 |
-
$t = pack('H*', '3021300906052b0e03021a05000414');
|
2104 |
-
break;
|
2105 |
-
case 'sha256':
|
2106 |
-
$t = pack('H*', '3031300d060960864801650304020105000420');
|
2107 |
-
break;
|
2108 |
-
case 'sha384':
|
2109 |
-
$t = pack('H*', '3041300d060960864801650304020205000430');
|
2110 |
-
break;
|
2111 |
-
case 'sha512':
|
2112 |
-
$t = pack('H*', '3051300d060960864801650304020305000440');
|
2113 |
-
}
|
2114 |
-
$t.= $h;
|
2115 |
-
$tLen = strlen($t);
|
2116 |
-
|
2117 |
-
if ($emLen < $tLen + 11) {
|
2118 |
-
user_error('Intended encoded message length too short', E_USER_NOTICE);
|
2119 |
-
return false;
|
2120 |
-
}
|
2121 |
-
|
2122 |
-
$ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
|
2123 |
-
|
2124 |
-
$em = "\0\1$ps\0$t";
|
2125 |
-
|
2126 |
-
return $em;
|
2127 |
-
}
|
2128 |
-
|
2129 |
-
/**
|
2130 |
-
* RSASSA-PKCS1-V1_5-SIGN
|
2131 |
-
*
|
2132 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.
|
2133 |
-
*
|
2134 |
-
* @access private
|
2135 |
-
* @param String $m
|
2136 |
-
* @return String
|
2137 |
-
*/
|
2138 |
-
function _rsassa_pkcs1_v1_5_sign($m)
|
2139 |
-
{
|
2140 |
-
// EMSA-PKCS1-v1_5 encoding
|
2141 |
-
|
2142 |
-
$em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
|
2143 |
-
if ($em === false) {
|
2144 |
-
user_error('RSA modulus too short', E_USER_NOTICE);
|
2145 |
-
return false;
|
2146 |
-
}
|
2147 |
-
|
2148 |
-
// RSA signature
|
2149 |
-
|
2150 |
-
$m = $this->_os2ip($em);
|
2151 |
-
$s = $this->_rsasp1($m);
|
2152 |
-
$s = $this->_i2osp($s, $this->k);
|
2153 |
-
|
2154 |
-
// Output the signature S
|
2155 |
-
|
2156 |
-
return $s;
|
2157 |
-
}
|
2158 |
-
|
2159 |
-
/**
|
2160 |
-
* RSASSA-PKCS1-V1_5-VERIFY
|
2161 |
-
*
|
2162 |
-
* See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}.
|
2163 |
-
*
|
2164 |
-
* @access private
|
2165 |
-
* @param String $m
|
2166 |
-
* @return String
|
2167 |
-
*/
|
2168 |
-
function _rsassa_pkcs1_v1_5_verify($m, $s)
|
2169 |
-
{
|
2170 |
-
// Length checking
|
2171 |
-
|
2172 |
-
if (strlen($s) != $this->k) {
|
2173 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2174 |
-
return false;
|
2175 |
-
}
|
2176 |
-
|
2177 |
-
// RSA verification
|
2178 |
-
|
2179 |
-
$s = $this->_os2ip($s);
|
2180 |
-
$m2 = $this->_rsavp1($s);
|
2181 |
-
if ($m2 === false) {
|
2182 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2183 |
-
return false;
|
2184 |
-
}
|
2185 |
-
$em = $this->_i2osp($m2, $this->k);
|
2186 |
-
if ($em === false) {
|
2187 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2188 |
-
return false;
|
2189 |
-
}
|
2190 |
-
|
2191 |
-
// EMSA-PKCS1-v1_5 encoding
|
2192 |
-
|
2193 |
-
$em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
|
2194 |
-
if ($em2 === false) {
|
2195 |
-
user_error('RSA modulus too short', E_USER_NOTICE);
|
2196 |
-
return false;
|
2197 |
-
}
|
2198 |
-
|
2199 |
-
// Compare
|
2200 |
-
|
2201 |
-
return $em === $em2;
|
2202 |
-
}
|
2203 |
-
|
2204 |
-
/**
|
2205 |
-
* Set Encryption Mode
|
2206 |
-
*
|
2207 |
-
* Valid values include CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1.
|
2208 |
-
*
|
2209 |
-
* @access public
|
2210 |
-
* @param Integer $mode
|
2211 |
-
*/
|
2212 |
-
function setEncryptionMode($mode)
|
2213 |
-
{
|
2214 |
-
$this->encryptionMode = $mode;
|
2215 |
-
}
|
2216 |
-
|
2217 |
-
/**
|
2218 |
-
* Set Signature Mode
|
2219 |
-
*
|
2220 |
-
* Valid values include CRYPT_RSA_SIGNATURE_PSS and CRYPT_RSA_SIGNATURE_PKCS1
|
2221 |
-
*
|
2222 |
-
* @access public
|
2223 |
-
* @param Integer $mode
|
2224 |
-
*/
|
2225 |
-
function setSignatureMode($mode)
|
2226 |
-
{
|
2227 |
-
$this->signatureMode = $mode;
|
2228 |
-
}
|
2229 |
-
|
2230 |
-
/**
|
2231 |
-
* Encryption
|
2232 |
-
*
|
2233 |
-
* Both CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1 both place limits on how long $plaintext can be.
|
2234 |
-
* If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will
|
2235 |
-
* be concatenated together.
|
2236 |
-
*
|
2237 |
-
* @see decrypt()
|
2238 |
-
* @access public
|
2239 |
-
* @param String $plaintext
|
2240 |
-
* @return String
|
2241 |
-
*/
|
2242 |
-
function encrypt($plaintext)
|
2243 |
-
{
|
2244 |
-
switch ($this->encryptionMode) {
|
2245 |
-
case CRYPT_RSA_ENCRYPTION_PKCS1:
|
2246 |
-
$length = $this->k - 11;
|
2247 |
-
if ($length <= 0) {
|
2248 |
-
return false;
|
2249 |
-
}
|
2250 |
-
|
2251 |
-
$plaintext = str_split($plaintext, $length);
|
2252 |
-
$ciphertext = '';
|
2253 |
-
foreach ($plaintext as $m) {
|
2254 |
-
$ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m);
|
2255 |
-
}
|
2256 |
-
return $ciphertext;
|
2257 |
-
//case CRYPT_RSA_ENCRYPTION_OAEP:
|
2258 |
-
default:
|
2259 |
-
$length = $this->k - 2 * $this->hLen - 2;
|
2260 |
-
if ($length <= 0) {
|
2261 |
-
return false;
|
2262 |
-
}
|
2263 |
-
|
2264 |
-
$plaintext = str_split($plaintext, $length);
|
2265 |
-
$ciphertext = '';
|
2266 |
-
foreach ($plaintext as $m) {
|
2267 |
-
$ciphertext.= $this->_rsaes_oaep_encrypt($m);
|
2268 |
-
}
|
2269 |
-
return $ciphertext;
|
2270 |
-
}
|
2271 |
-
}
|
2272 |
-
|
2273 |
-
/**
|
2274 |
-
* Decryption
|
2275 |
-
*
|
2276 |
-
* @see encrypt()
|
2277 |
-
* @access public
|
2278 |
-
* @param String $plaintext
|
2279 |
-
* @return String
|
2280 |
-
*/
|
2281 |
-
function decrypt($ciphertext)
|
2282 |
-
{
|
2283 |
-
if ($this->k <= 0) {
|
2284 |
-
return false;
|
2285 |
-
}
|
2286 |
-
|
2287 |
-
$ciphertext = str_split($ciphertext, $this->k);
|
2288 |
-
$plaintext = '';
|
2289 |
-
|
2290 |
-
switch ($this->encryptionMode) {
|
2291 |
-
case CRYPT_RSA_ENCRYPTION_PKCS1:
|
2292 |
-
$decrypt = '_rsaes_pkcs1_v1_5_decrypt';
|
2293 |
-
break;
|
2294 |
-
//case CRYPT_RSA_ENCRYPTION_OAEP:
|
2295 |
-
default:
|
2296 |
-
$decrypt = '_rsaes_oaep_decrypt';
|
2297 |
-
}
|
2298 |
-
|
2299 |
-
foreach ($ciphertext as $c) {
|
2300 |
-
$temp = $this->$decrypt($c);
|
2301 |
-
if ($temp === false) {
|
2302 |
-
return false;
|
2303 |
-
}
|
2304 |
-
$plaintext.= $temp;
|
2305 |
-
}
|
2306 |
-
|
2307 |
-
return $plaintext;
|
2308 |
-
}
|
2309 |
-
|
2310 |
-
/**
|
2311 |
-
* Create a signature
|
2312 |
-
*
|
2313 |
-
* @see verify()
|
2314 |
-
* @access public
|
2315 |
-
* @param String $message
|
2316 |
-
* @return String
|
2317 |
-
*/
|
2318 |
-
function sign($message)
|
2319 |
-
{
|
2320 |
-
if (empty($this->modulus) || empty($this->exponent)) {
|
2321 |
-
return false;
|
2322 |
-
}
|
2323 |
-
|
2324 |
-
switch ($this->signatureMode) {
|
2325 |
-
case CRYPT_RSA_SIGNATURE_PKCS1:
|
2326 |
-
return $this->_rsassa_pkcs1_v1_5_sign($message);
|
2327 |
-
//case CRYPT_RSA_SIGNATURE_PSS:
|
2328 |
-
default:
|
2329 |
-
return $this->_rsassa_pss_sign($message);
|
2330 |
-
}
|
2331 |
-
}
|
2332 |
-
|
2333 |
-
/**
|
2334 |
-
* Verifies a signature
|
2335 |
-
*
|
2336 |
-
* @see sign()
|
2337 |
-
* @access public
|
2338 |
-
* @param String $message
|
2339 |
-
* @param String $signature
|
2340 |
-
* @return Boolean
|
2341 |
-
*/
|
2342 |
-
function verify($message, $signature)
|
2343 |
-
{
|
2344 |
-
if (empty($this->modulus) || empty($this->exponent)) {
|
2345 |
-
return false;
|
2346 |
-
}
|
2347 |
-
|
2348 |
-
switch ($this->signatureMode) {
|
2349 |
-
case CRYPT_RSA_SIGNATURE_PKCS1:
|
2350 |
-
return $this->_rsassa_pkcs1_v1_5_verify($message, $signature);
|
2351 |
-
//case CRYPT_RSA_SIGNATURE_PSS:
|
2352 |
-
default:
|
2353 |
-
return $this->_rsassa_pss_verify($message, $signature);
|
2354 |
-
}
|
2355 |
-
}
|
2356 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/Random.php
DELETED
@@ -1,133 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Random Number Generator
|
6 |
-
*
|
7 |
-
* PHP versions 4 and 5
|
8 |
-
*
|
9 |
-
* Here's a short example of how to use this library:
|
10 |
-
* <code>
|
11 |
-
* <?php
|
12 |
-
* include('Crypt/Random.php');
|
13 |
-
*
|
14 |
-
* echo crypt_random();
|
15 |
-
* ?>
|
16 |
-
* </code>
|
17 |
-
*
|
18 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
19 |
-
* of this software and associated documentation files (the "Software"), to deal
|
20 |
-
* in the Software without restriction, including without limitation the rights
|
21 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
22 |
-
* copies of the Software, and to permit persons to whom the Software is
|
23 |
-
* furnished to do so, subject to the following conditions:
|
24 |
-
*
|
25 |
-
* The above copyright notice and this permission notice shall be included in
|
26 |
-
* all copies or substantial portions of the Software.
|
27 |
-
*
|
28 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
29 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
30 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
31 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
32 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
33 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
34 |
-
* THE SOFTWARE.
|
35 |
-
*
|
36 |
-
* @category Crypt
|
37 |
-
* @package Crypt_Random
|
38 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
39 |
-
* @copyright MMVII Jim Wigginton
|
40 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
41 |
-
* @version $Id: Random.php,v 1.9 2010/04/24 06:40:48 terrafrost Exp $
|
42 |
-
* @link http://phpseclib.sourceforge.net
|
43 |
-
*/
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Generate a random value.
|
47 |
-
*
|
48 |
-
* On 32-bit machines, the largest distance that can exist between $min and $max is 2**31.
|
49 |
-
* If $min and $max are farther apart than that then the last ($max - range) numbers.
|
50 |
-
*
|
51 |
-
* Depending on how this is being used, it may be worth while to write a replacement. For example,
|
52 |
-
* a PHP-based web app that stores its data in an SQL database can collect more entropy than this function
|
53 |
-
* can.
|
54 |
-
*
|
55 |
-
* @param optional Integer $min
|
56 |
-
* @param optional Integer $max
|
57 |
-
* @return Integer
|
58 |
-
* @access public
|
59 |
-
*/
|
60 |
-
function crypt_random($min = 0, $max = 0x7FFFFFFF)
|
61 |
-
{
|
62 |
-
if ($min == $max) {
|
63 |
-
return $min;
|
64 |
-
}
|
65 |
-
|
66 |
-
// see http://en.wikipedia.org/wiki//dev/random
|
67 |
-
static $urandom = true;
|
68 |
-
if ($urandom === true) {
|
69 |
-
// Warning's will be output unles the error suppression operator is used. Errors such as
|
70 |
-
// "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
|
71 |
-
$urandom = @fopen('/dev/urandom', 'rb');
|
72 |
-
}
|
73 |
-
if (!is_bool($urandom)) {
|
74 |
-
extract(unpack('Nrandom', fread($urandom, 4)));
|
75 |
-
|
76 |
-
// say $min = 0 and $max = 3. if we didn't do abs() then we could have stuff like this:
|
77 |
-
// -4 % 3 + 0 = -1, even though -1 < $min
|
78 |
-
return abs($random) % ($max - $min) + $min;
|
79 |
-
}
|
80 |
-
|
81 |
-
/* Prior to PHP 4.2.0, mt_srand() had to be called before mt_rand() could be called.
|
82 |
-
Prior to PHP 5.2.6, mt_rand()'s automatic seeding was subpar, as elaborated here:
|
83 |
-
|
84 |
-
http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbers/
|
85 |
-
|
86 |
-
The seeding routine is pretty much ripped from PHP's own internal GENERATE_SEED() macro:
|
87 |
-
|
88 |
-
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3_2/ext/standard/php_rand.h?view=markup */
|
89 |
-
if (version_compare(PHP_VERSION, '5.2.5', '<=')) {
|
90 |
-
static $seeded;
|
91 |
-
if (!isset($seeded)) {
|
92 |
-
$seeded = true;
|
93 |
-
mt_srand(fmod(time() * getmypid(), 0x7FFFFFFF) ^ fmod(1000000 * lcg_value(), 0x7FFFFFFF));
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
static $crypto;
|
98 |
-
|
99 |
-
// The CSPRNG's Yarrow and Fortuna periodically reseed. This function can be reseeded by hitting F5
|
100 |
-
// in the browser and reloading the page.
|
101 |
-
|
102 |
-
if (!isset($crypto)) {
|
103 |
-
$key = $iv = '';
|
104 |
-
for ($i = 0; $i < 8; $i++) {
|
105 |
-
$key.= pack('n', mt_rand(0, 0xFFFF));
|
106 |
-
$iv .= pack('n', mt_rand(0, 0xFFFF));
|
107 |
-
}
|
108 |
-
switch (true) {
|
109 |
-
case class_exists('Crypt_AES'):
|
110 |
-
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
111 |
-
break;
|
112 |
-
case class_exists('Crypt_TripleDES'):
|
113 |
-
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
114 |
-
break;
|
115 |
-
case class_exists('Crypt_DES'):
|
116 |
-
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
|
117 |
-
break;
|
118 |
-
case class_exists('Crypt_RC4'):
|
119 |
-
$crypto = new Crypt_RC4();
|
120 |
-
break;
|
121 |
-
default:
|
122 |
-
extract(unpack('Nrandom', pack('H*', sha1(mt_rand(0, 0x7FFFFFFF)))));
|
123 |
-
return abs($random) % ($max - $min) + $min;
|
124 |
-
}
|
125 |
-
$crypto->setKey($key);
|
126 |
-
$crypto->setIV($iv);
|
127 |
-
$crypto->enableContinuousBuffer();
|
128 |
-
}
|
129 |
-
|
130 |
-
extract(unpack('Nrandom', $crypto->encrypt("\0\0\0\0")));
|
131 |
-
return abs($random) % ($max - $min) + $min;
|
132 |
-
}
|
133 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/Rijndael.php
DELETED
@@ -1,1424 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of Rijndael.
|
6 |
-
*
|
7 |
-
* Does not use mcrypt, even when available, for reasons that are explained below.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
|
12 |
-
* {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
13 |
-
* {@link Crypt_Rijndael::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
|
14 |
-
* 136-bits it'll be null-padded to 160-bits and 160 bits will be the key length until
|
15 |
-
* {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
|
16 |
-
*
|
17 |
-
* Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
|
18 |
-
* does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
|
19 |
-
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
|
20 |
-
* algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
|
21 |
-
* are first defined as valid key / block lengths in
|
22 |
-
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
|
23 |
-
* Extensions: Other block and Cipher Key lengths.
|
24 |
-
*
|
25 |
-
* {@internal The variable names are the same as those in
|
26 |
-
* {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
|
27 |
-
*
|
28 |
-
* Here's a short example of how to use this library:
|
29 |
-
* <code>
|
30 |
-
* <?php
|
31 |
-
* include('Crypt/Rijndael.php');
|
32 |
-
*
|
33 |
-
* $rijndael = new Crypt_Rijndael();
|
34 |
-
*
|
35 |
-
* $rijndael->setKey('abcdefghijklmnop');
|
36 |
-
*
|
37 |
-
* $size = 10 * 1024;
|
38 |
-
* $plaintext = '';
|
39 |
-
* for ($i = 0; $i < $size; $i++) {
|
40 |
-
* $plaintext.= 'a';
|
41 |
-
* }
|
42 |
-
*
|
43 |
-
* echo $rijndael->decrypt($rijndael->encrypt($plaintext));
|
44 |
-
* ?>
|
45 |
-
* </code>
|
46 |
-
*
|
47 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
48 |
-
* of this software and associated documentation files (the "Software"), to deal
|
49 |
-
* in the Software without restriction, including without limitation the rights
|
50 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
51 |
-
* copies of the Software, and to permit persons to whom the Software is
|
52 |
-
* furnished to do so, subject to the following conditions:
|
53 |
-
*
|
54 |
-
* The above copyright notice and this permission notice shall be included in
|
55 |
-
* all copies or substantial portions of the Software.
|
56 |
-
*
|
57 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
58 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
59 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
60 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
61 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
62 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
63 |
-
* THE SOFTWARE.
|
64 |
-
*
|
65 |
-
* @category Crypt
|
66 |
-
* @package Crypt_Rijndael
|
67 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
68 |
-
* @copyright MMVIII Jim Wigginton
|
69 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
70 |
-
* @version $Id: Rijndael.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
|
71 |
-
* @link http://phpseclib.sourceforge.net
|
72 |
-
*/
|
73 |
-
|
74 |
-
/**#@+
|
75 |
-
* @access public
|
76 |
-
* @see Crypt_Rijndael::encrypt()
|
77 |
-
* @see Crypt_Rijndael::decrypt()
|
78 |
-
*/
|
79 |
-
/**
|
80 |
-
* Encrypt / decrypt using the Counter mode.
|
81 |
-
*
|
82 |
-
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
83 |
-
*
|
84 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
85 |
-
*/
|
86 |
-
define('CRYPT_RIJNDAEL_MODE_CTR', -1);
|
87 |
-
/**
|
88 |
-
* Encrypt / decrypt using the Electronic Code Book mode.
|
89 |
-
*
|
90 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
91 |
-
*/
|
92 |
-
define('CRYPT_RIJNDAEL_MODE_ECB', 1);
|
93 |
-
/**
|
94 |
-
* Encrypt / decrypt using the Code Book Chaining mode.
|
95 |
-
*
|
96 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
97 |
-
*/
|
98 |
-
define('CRYPT_RIJNDAEL_MODE_CBC', 2);
|
99 |
-
/**
|
100 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
101 |
-
*
|
102 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
103 |
-
*/
|
104 |
-
define('CRYPT_RIJNDAEL_MODE_CFB', 3);
|
105 |
-
/**
|
106 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
107 |
-
*
|
108 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
109 |
-
*/
|
110 |
-
define('CRYPT_RIJNDAEL_MODE_OFB', 4);
|
111 |
-
/**#@-*/
|
112 |
-
|
113 |
-
/**#@+
|
114 |
-
* @access private
|
115 |
-
* @see Crypt_Rijndael::Crypt_Rijndael()
|
116 |
-
*/
|
117 |
-
/**
|
118 |
-
* Toggles the internal implementation
|
119 |
-
*/
|
120 |
-
define('CRYPT_RIJNDAEL_MODE_INTERNAL', 1);
|
121 |
-
/**
|
122 |
-
* Toggles the mcrypt implementation
|
123 |
-
*/
|
124 |
-
define('CRYPT_RIJNDAEL_MODE_MCRYPT', 2);
|
125 |
-
/**#@-*/
|
126 |
-
|
127 |
-
/**
|
128 |
-
* Pure-PHP implementation of Rijndael.
|
129 |
-
*
|
130 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
131 |
-
* @version 0.1.0
|
132 |
-
* @access public
|
133 |
-
* @package Crypt_Rijndael
|
134 |
-
*/
|
135 |
-
class Crypt_Rijndael {
|
136 |
-
/**
|
137 |
-
* The Encryption Mode
|
138 |
-
*
|
139 |
-
* @see Crypt_Rijndael::Crypt_Rijndael()
|
140 |
-
* @var Integer
|
141 |
-
* @access private
|
142 |
-
*/
|
143 |
-
var $mode;
|
144 |
-
|
145 |
-
/**
|
146 |
-
* The Key
|
147 |
-
*
|
148 |
-
* @see Crypt_Rijndael::setKey()
|
149 |
-
* @var String
|
150 |
-
* @access private
|
151 |
-
*/
|
152 |
-
var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
153 |
-
|
154 |
-
/**
|
155 |
-
* The Initialization Vector
|
156 |
-
*
|
157 |
-
* @see Crypt_Rijndael::setIV()
|
158 |
-
* @var String
|
159 |
-
* @access private
|
160 |
-
*/
|
161 |
-
var $iv = '';
|
162 |
-
|
163 |
-
/**
|
164 |
-
* A "sliding" Initialization Vector
|
165 |
-
*
|
166 |
-
* @see Crypt_Rijndael::enableContinuousBuffer()
|
167 |
-
* @var String
|
168 |
-
* @access private
|
169 |
-
*/
|
170 |
-
var $encryptIV = '';
|
171 |
-
|
172 |
-
/**
|
173 |
-
* A "sliding" Initialization Vector
|
174 |
-
*
|
175 |
-
* @see Crypt_Rijndael::enableContinuousBuffer()
|
176 |
-
* @var String
|
177 |
-
* @access private
|
178 |
-
*/
|
179 |
-
var $decryptIV = '';
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Continuous Buffer status
|
183 |
-
*
|
184 |
-
* @see Crypt_Rijndael::enableContinuousBuffer()
|
185 |
-
* @var Boolean
|
186 |
-
* @access private
|
187 |
-
*/
|
188 |
-
var $continuousBuffer = false;
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Padding status
|
192 |
-
*
|
193 |
-
* @see Crypt_Rijndael::enablePadding()
|
194 |
-
* @var Boolean
|
195 |
-
* @access private
|
196 |
-
*/
|
197 |
-
var $padding = true;
|
198 |
-
|
199 |
-
/**
|
200 |
-
* Does the key schedule need to be (re)calculated?
|
201 |
-
*
|
202 |
-
* @see setKey()
|
203 |
-
* @see setBlockLength()
|
204 |
-
* @see setKeyLength()
|
205 |
-
* @var Boolean
|
206 |
-
* @access private
|
207 |
-
*/
|
208 |
-
var $changed = true;
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Has the key length explicitly been set or should it be derived from the key, itself?
|
212 |
-
*
|
213 |
-
* @see setKeyLength()
|
214 |
-
* @var Boolean
|
215 |
-
* @access private
|
216 |
-
*/
|
217 |
-
var $explicit_key_length = false;
|
218 |
-
|
219 |
-
/**
|
220 |
-
* The Key Schedule
|
221 |
-
*
|
222 |
-
* @see _setup()
|
223 |
-
* @var Array
|
224 |
-
* @access private
|
225 |
-
*/
|
226 |
-
var $w;
|
227 |
-
|
228 |
-
/**
|
229 |
-
* The Inverse Key Schedule
|
230 |
-
*
|
231 |
-
* @see _setup()
|
232 |
-
* @var Array
|
233 |
-
* @access private
|
234 |
-
*/
|
235 |
-
var $dw;
|
236 |
-
|
237 |
-
/**
|
238 |
-
* The Block Length
|
239 |
-
*
|
240 |
-
* @see setBlockLength()
|
241 |
-
* @var Integer
|
242 |
-
* @access private
|
243 |
-
* @internal The max value is 32, the min value is 16. All valid values are multiples of 4. Exists in conjunction with
|
244 |
-
* $Nb because we need this value and not $Nb to pad strings appropriately.
|
245 |
-
*/
|
246 |
-
var $block_size = 16;
|
247 |
-
|
248 |
-
/**
|
249 |
-
* The Block Length divided by 32
|
250 |
-
*
|
251 |
-
* @see setBlockLength()
|
252 |
-
* @var Integer
|
253 |
-
* @access private
|
254 |
-
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
|
255 |
-
* because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
|
256 |
-
* derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
257 |
-
* of that, we'll just precompute it once.
|
258 |
-
*
|
259 |
-
*/
|
260 |
-
var $Nb = 4;
|
261 |
-
|
262 |
-
/**
|
263 |
-
* The Key Length
|
264 |
-
*
|
265 |
-
* @see setKeyLength()
|
266 |
-
* @var Integer
|
267 |
-
* @access private
|
268 |
-
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $key_size
|
269 |
-
* because the encryption / decryption / key schedule creation requires this number and not $key_size. We could
|
270 |
-
* derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
271 |
-
* of that, we'll just precompute it once.
|
272 |
-
*/
|
273 |
-
var $key_size = 16;
|
274 |
-
|
275 |
-
/**
|
276 |
-
* The Key Length divided by 32
|
277 |
-
*
|
278 |
-
* @see setKeyLength()
|
279 |
-
* @var Integer
|
280 |
-
* @access private
|
281 |
-
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
|
282 |
-
*/
|
283 |
-
var $Nk = 4;
|
284 |
-
|
285 |
-
/**
|
286 |
-
* The Number of Rounds
|
287 |
-
*
|
288 |
-
* @var Integer
|
289 |
-
* @access private
|
290 |
-
* @internal The max value is 14, the min value is 10.
|
291 |
-
*/
|
292 |
-
var $Nr;
|
293 |
-
|
294 |
-
/**
|
295 |
-
* Shift offsets
|
296 |
-
*
|
297 |
-
* @var Array
|
298 |
-
* @access private
|
299 |
-
*/
|
300 |
-
var $c;
|
301 |
-
|
302 |
-
/**
|
303 |
-
* Precomputed mixColumns table
|
304 |
-
*
|
305 |
-
* @see Crypt_Rijndael()
|
306 |
-
* @var Array
|
307 |
-
* @access private
|
308 |
-
*/
|
309 |
-
var $t0;
|
310 |
-
|
311 |
-
/**
|
312 |
-
* Precomputed mixColumns table
|
313 |
-
*
|
314 |
-
* @see Crypt_Rijndael()
|
315 |
-
* @var Array
|
316 |
-
* @access private
|
317 |
-
*/
|
318 |
-
var $t1;
|
319 |
-
|
320 |
-
/**
|
321 |
-
* Precomputed mixColumns table
|
322 |
-
*
|
323 |
-
* @see Crypt_Rijndael()
|
324 |
-
* @var Array
|
325 |
-
* @access private
|
326 |
-
*/
|
327 |
-
var $t2;
|
328 |
-
|
329 |
-
/**
|
330 |
-
* Precomputed mixColumns table
|
331 |
-
*
|
332 |
-
* @see Crypt_Rijndael()
|
333 |
-
* @var Array
|
334 |
-
* @access private
|
335 |
-
*/
|
336 |
-
var $t3;
|
337 |
-
|
338 |
-
/**
|
339 |
-
* Precomputed invMixColumns table
|
340 |
-
*
|
341 |
-
* @see Crypt_Rijndael()
|
342 |
-
* @var Array
|
343 |
-
* @access private
|
344 |
-
*/
|
345 |
-
var $dt0;
|
346 |
-
|
347 |
-
/**
|
348 |
-
* Precomputed invMixColumns table
|
349 |
-
*
|
350 |
-
* @see Crypt_Rijndael()
|
351 |
-
* @var Array
|
352 |
-
* @access private
|
353 |
-
*/
|
354 |
-
var $dt1;
|
355 |
-
|
356 |
-
/**
|
357 |
-
* Precomputed invMixColumns table
|
358 |
-
*
|
359 |
-
* @see Crypt_Rijndael()
|
360 |
-
* @var Array
|
361 |
-
* @access private
|
362 |
-
*/
|
363 |
-
var $dt2;
|
364 |
-
|
365 |
-
/**
|
366 |
-
* Precomputed invMixColumns table
|
367 |
-
*
|
368 |
-
* @see Crypt_Rijndael()
|
369 |
-
* @var Array
|
370 |
-
* @access private
|
371 |
-
*/
|
372 |
-
var $dt3;
|
373 |
-
|
374 |
-
/**
|
375 |
-
* Is the mode one that is paddable?
|
376 |
-
*
|
377 |
-
* @see Crypt_Rijndael::Crypt_Rijndael()
|
378 |
-
* @var Boolean
|
379 |
-
* @access private
|
380 |
-
*/
|
381 |
-
var $paddable = false;
|
382 |
-
|
383 |
-
/**
|
384 |
-
* Encryption buffer for CTR, OFB and CFB modes
|
385 |
-
*
|
386 |
-
* @see Crypt_Rijndael::encrypt()
|
387 |
-
* @var String
|
388 |
-
* @access private
|
389 |
-
*/
|
390 |
-
var $enbuffer = array('encrypted' => '', 'xor' => '');
|
391 |
-
|
392 |
-
/**
|
393 |
-
* Decryption buffer for CTR, OFB and CFB modes
|
394 |
-
*
|
395 |
-
* @see Crypt_Rijndael::decrypt()
|
396 |
-
* @var String
|
397 |
-
* @access private
|
398 |
-
*/
|
399 |
-
var $debuffer = array('ciphertext' => '');
|
400 |
-
|
401 |
-
/**
|
402 |
-
* Default Constructor.
|
403 |
-
*
|
404 |
-
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
|
405 |
-
* CRYPT_RIJNDAEL_MODE_ECB or CRYPT_RIJNDAEL_MODE_CBC. If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used.
|
406 |
-
*
|
407 |
-
* @param optional Integer $mode
|
408 |
-
* @return Crypt_Rijndael
|
409 |
-
* @access public
|
410 |
-
*/
|
411 |
-
function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)
|
412 |
-
{
|
413 |
-
switch ($mode) {
|
414 |
-
case CRYPT_RIJNDAEL_MODE_ECB:
|
415 |
-
case CRYPT_RIJNDAEL_MODE_CBC:
|
416 |
-
$this->paddable = true;
|
417 |
-
$this->mode = $mode;
|
418 |
-
break;
|
419 |
-
case CRYPT_RIJNDAEL_MODE_CTR:
|
420 |
-
case CRYPT_RIJNDAEL_MODE_CFB:
|
421 |
-
case CRYPT_RIJNDAEL_MODE_OFB:
|
422 |
-
$this->mode = $mode;
|
423 |
-
break;
|
424 |
-
default:
|
425 |
-
$this->paddable = true;
|
426 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
427 |
-
}
|
428 |
-
|
429 |
-
$t3 = &$this->t3;
|
430 |
-
$t2 = &$this->t2;
|
431 |
-
$t1 = &$this->t1;
|
432 |
-
$t0 = &$this->t0;
|
433 |
-
|
434 |
-
$dt3 = &$this->dt3;
|
435 |
-
$dt2 = &$this->dt2;
|
436 |
-
$dt1 = &$this->dt1;
|
437 |
-
$dt0 = &$this->dt0;
|
438 |
-
|
439 |
-
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
|
440 |
-
// precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
|
441 |
-
// those are the names we'll use.
|
442 |
-
$t3 = array(
|
443 |
-
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
|
444 |
-
0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
|
445 |
-
0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
|
446 |
-
0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
|
447 |
-
0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
|
448 |
-
0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
|
449 |
-
0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
|
450 |
-
0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
|
451 |
-
0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
|
452 |
-
0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
|
453 |
-
0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
|
454 |
-
0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
|
455 |
-
0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
|
456 |
-
0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
|
457 |
-
0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
|
458 |
-
0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
|
459 |
-
0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
|
460 |
-
0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
|
461 |
-
0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
|
462 |
-
0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
|
463 |
-
0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
|
464 |
-
0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
|
465 |
-
0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
|
466 |
-
0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
|
467 |
-
0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
|
468 |
-
0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
|
469 |
-
0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
|
470 |
-
0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
|
471 |
-
0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
|
472 |
-
0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
|
473 |
-
0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
|
474 |
-
0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
|
475 |
-
);
|
476 |
-
|
477 |
-
$dt3 = array(
|
478 |
-
0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
|
479 |
-
0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
|
480 |
-
0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
|
481 |
-
0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
|
482 |
-
0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
|
483 |
-
0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
|
484 |
-
0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
|
485 |
-
0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
|
486 |
-
0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
|
487 |
-
0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
|
488 |
-
0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
|
489 |
-
0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
|
490 |
-
0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
|
491 |
-
0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
|
492 |
-
0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
|
493 |
-
0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
|
494 |
-
0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
|
495 |
-
0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
|
496 |
-
0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
|
497 |
-
0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
|
498 |
-
0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
|
499 |
-
0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
|
500 |
-
0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
|
501 |
-
0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
|
502 |
-
0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
|
503 |
-
0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
|
504 |
-
0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
|
505 |
-
0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
|
506 |
-
0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
|
507 |
-
0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
|
508 |
-
0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
|
509 |
-
0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
|
510 |
-
);
|
511 |
-
|
512 |
-
for ($i = 0; $i < 256; $i++) {
|
513 |
-
$t2[$i << 8] = (($t3[$i] << 8) & 0xFFFFFF00) | (($t3[$i] >> 24) & 0x000000FF);
|
514 |
-
$t1[$i << 16] = (($t3[$i] << 16) & 0xFFFF0000) | (($t3[$i] >> 16) & 0x0000FFFF);
|
515 |
-
$t0[$i << 24] = (($t3[$i] << 24) & 0xFF000000) | (($t3[$i] >> 8) & 0x00FFFFFF);
|
516 |
-
|
517 |
-
$dt2[$i << 8] = (($this->dt3[$i] << 8) & 0xFFFFFF00) | (($dt3[$i] >> 24) & 0x000000FF);
|
518 |
-
$dt1[$i << 16] = (($this->dt3[$i] << 16) & 0xFFFF0000) | (($dt3[$i] >> 16) & 0x0000FFFF);
|
519 |
-
$dt0[$i << 24] = (($this->dt3[$i] << 24) & 0xFF000000) | (($dt3[$i] >> 8) & 0x00FFFFFF);
|
520 |
-
}
|
521 |
-
}
|
522 |
-
|
523 |
-
/**
|
524 |
-
* Sets the key.
|
525 |
-
*
|
526 |
-
* Keys can be of any length. Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and
|
527 |
-
* whose length is a multiple of 32. If the key is less than 256-bits and the key length isn't set, we round the length
|
528 |
-
* up to the closest valid key length, padding $key with null bytes. If the key is more than 256-bits, we trim the
|
529 |
-
* excess bits.
|
530 |
-
*
|
531 |
-
* If the key is not explicitly set, it'll be assumed to be all null bytes.
|
532 |
-
*
|
533 |
-
* @access public
|
534 |
-
* @param String $key
|
535 |
-
*/
|
536 |
-
function setKey($key)
|
537 |
-
{
|
538 |
-
$this->key = $key;
|
539 |
-
$this->changed = true;
|
540 |
-
}
|
541 |
-
|
542 |
-
/**
|
543 |
-
* Sets the initialization vector. (optional)
|
544 |
-
*
|
545 |
-
* SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used. If not explictly set, it'll be assumed
|
546 |
-
* to be all zero's.
|
547 |
-
*
|
548 |
-
* @access public
|
549 |
-
* @param String $iv
|
550 |
-
*/
|
551 |
-
function setIV($iv)
|
552 |
-
{
|
553 |
-
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, $this->block_size), $this->block_size, chr(0));;
|
554 |
-
}
|
555 |
-
|
556 |
-
/**
|
557 |
-
* Sets the key length
|
558 |
-
*
|
559 |
-
* Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
560 |
-
* 128. If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.
|
561 |
-
*
|
562 |
-
* @access public
|
563 |
-
* @param Integer $length
|
564 |
-
*/
|
565 |
-
function setKeyLength($length)
|
566 |
-
{
|
567 |
-
$length >>= 5;
|
568 |
-
if ($length > 8) {
|
569 |
-
$length = 8;
|
570 |
-
} else if ($length < 4) {
|
571 |
-
$length = 4;
|
572 |
-
}
|
573 |
-
$this->Nk = $length;
|
574 |
-
$this->key_size = $length << 2;
|
575 |
-
|
576 |
-
$this->explicit_key_length = true;
|
577 |
-
$this->changed = true;
|
578 |
-
}
|
579 |
-
|
580 |
-
/**
|
581 |
-
* Sets the block length
|
582 |
-
*
|
583 |
-
* Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
584 |
-
* 128. If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.
|
585 |
-
*
|
586 |
-
* @access public
|
587 |
-
* @param Integer $length
|
588 |
-
*/
|
589 |
-
function setBlockLength($length)
|
590 |
-
{
|
591 |
-
$length >>= 5;
|
592 |
-
if ($length > 8) {
|
593 |
-
$length = 8;
|
594 |
-
} else if ($length < 4) {
|
595 |
-
$length = 4;
|
596 |
-
}
|
597 |
-
$this->Nb = $length;
|
598 |
-
$this->block_size = $length << 2;
|
599 |
-
$this->changed = true;
|
600 |
-
}
|
601 |
-
|
602 |
-
/**
|
603 |
-
* Generate CTR XOR encryption key
|
604 |
-
*
|
605 |
-
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
606 |
-
* plaintext / ciphertext in CTR mode.
|
607 |
-
*
|
608 |
-
* @see Crypt_Rijndael::decrypt()
|
609 |
-
* @see Crypt_Rijndael::encrypt()
|
610 |
-
* @access public
|
611 |
-
* @param Integer $length
|
612 |
-
* @param String $iv
|
613 |
-
*/
|
614 |
-
function _generate_xor($length, &$iv)
|
615 |
-
{
|
616 |
-
$xor = '';
|
617 |
-
$block_size = $this->block_size;
|
618 |
-
$num_blocks = floor(($length + ($block_size - 1)) / $block_size);
|
619 |
-
for ($i = 0; $i < $num_blocks; $i++) {
|
620 |
-
$xor.= $iv;
|
621 |
-
for ($j = 4; $j <= $block_size; $j+=4) {
|
622 |
-
$temp = substr($iv, -$j, 4);
|
623 |
-
switch ($temp) {
|
624 |
-
case "\xFF\xFF\xFF\xFF":
|
625 |
-
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
626 |
-
break;
|
627 |
-
case "\x7F\xFF\xFF\xFF":
|
628 |
-
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
629 |
-
break 2;
|
630 |
-
default:
|
631 |
-
extract(unpack('Ncount', $temp));
|
632 |
-
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
633 |
-
break 2;
|
634 |
-
}
|
635 |
-
}
|
636 |
-
}
|
637 |
-
|
638 |
-
return $xor;
|
639 |
-
}
|
640 |
-
|
641 |
-
/**
|
642 |
-
* Encrypts a message.
|
643 |
-
*
|
644 |
-
* $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other Rjindael
|
645 |
-
* implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's
|
646 |
-
* necessary are discussed in the following
|
647 |
-
* URL:
|
648 |
-
*
|
649 |
-
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
|
650 |
-
*
|
651 |
-
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
|
652 |
-
* strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
|
653 |
-
* length.
|
654 |
-
*
|
655 |
-
* @see Crypt_Rijndael::decrypt()
|
656 |
-
* @access public
|
657 |
-
* @param String $plaintext
|
658 |
-
*/
|
659 |
-
function encrypt($plaintext)
|
660 |
-
{
|
661 |
-
$this->_setup();
|
662 |
-
if ($this->paddable) {
|
663 |
-
$plaintext = $this->_pad($plaintext);
|
664 |
-
}
|
665 |
-
|
666 |
-
$block_size = $this->block_size;
|
667 |
-
$buffer = &$this->enbuffer;
|
668 |
-
$continuousBuffer = $this->continuousBuffer;
|
669 |
-
$ciphertext = '';
|
670 |
-
switch ($this->mode) {
|
671 |
-
case CRYPT_RIJNDAEL_MODE_ECB:
|
672 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
673 |
-
$ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
|
674 |
-
}
|
675 |
-
break;
|
676 |
-
case CRYPT_RIJNDAEL_MODE_CBC:
|
677 |
-
$xor = $this->encryptIV;
|
678 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
679 |
-
$block = substr($plaintext, $i, $block_size);
|
680 |
-
$block = $this->_encryptBlock($block ^ $xor);
|
681 |
-
$xor = $block;
|
682 |
-
$ciphertext.= $block;
|
683 |
-
}
|
684 |
-
if ($this->continuousBuffer) {
|
685 |
-
$this->encryptIV = $xor;
|
686 |
-
}
|
687 |
-
break;
|
688 |
-
case CRYPT_RIJNDAEL_MODE_CTR:
|
689 |
-
$xor = $this->encryptIV;
|
690 |
-
if (!empty($buffer)) {
|
691 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
692 |
-
$block = substr($plaintext, $i, $block_size);
|
693 |
-
$buffer.= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
694 |
-
$key = $this->_string_shift($buffer, $block_size);
|
695 |
-
$ciphertext.= $block ^ $key;
|
696 |
-
}
|
697 |
-
} else {
|
698 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
699 |
-
$block = substr($plaintext, $i, $block_size);
|
700 |
-
$key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
701 |
-
$ciphertext.= $block ^ $key;
|
702 |
-
}
|
703 |
-
}
|
704 |
-
if ($this->continuousBuffer) {
|
705 |
-
$this->encryptIV = $xor;
|
706 |
-
if ($start = strlen($plaintext) % $block_size) {
|
707 |
-
$buffer = substr($key, $start) . $buffer;
|
708 |
-
}
|
709 |
-
}
|
710 |
-
break;
|
711 |
-
case CRYPT_RIJNDAEL_MODE_CFB:
|
712 |
-
if (!empty($buffer['xor'])) {
|
713 |
-
$ciphertext = $plaintext ^ $buffer['xor'];
|
714 |
-
$iv = $buffer['encrypted'] . $ciphertext;
|
715 |
-
$start = strlen($ciphertext);
|
716 |
-
$buffer['encrypted'].= $ciphertext;
|
717 |
-
$buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
|
718 |
-
} else {
|
719 |
-
$ciphertext = '';
|
720 |
-
$iv = $this->encryptIV;
|
721 |
-
$start = 0;
|
722 |
-
}
|
723 |
-
|
724 |
-
for ($i = $start; $i < strlen($plaintext); $i+=$block_size) {
|
725 |
-
$block = substr($plaintext, $i, $block_size);
|
726 |
-
$xor = $this->_encryptBlock($iv);
|
727 |
-
$iv = $block ^ $xor;
|
728 |
-
if ($continuousBuffer && strlen($iv) != $block_size) {
|
729 |
-
$buffer = array(
|
730 |
-
'encrypted' => $iv,
|
731 |
-
'xor' => substr($xor, strlen($iv))
|
732 |
-
);
|
733 |
-
}
|
734 |
-
$ciphertext.= $iv;
|
735 |
-
}
|
736 |
-
|
737 |
-
if ($this->continuousBuffer) {
|
738 |
-
$this->encryptIV = $iv;
|
739 |
-
}
|
740 |
-
break;
|
741 |
-
case CRYPT_RIJNDAEL_MODE_OFB:
|
742 |
-
$xor = $this->encryptIV;
|
743 |
-
if (strlen($buffer)) {
|
744 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
745 |
-
$xor = $this->_encryptBlock($xor);
|
746 |
-
$buffer.= $xor;
|
747 |
-
$key = $this->_string_shift($buffer, $block_size);
|
748 |
-
$ciphertext.= substr($plaintext, $i, $block_size) ^ $key;
|
749 |
-
}
|
750 |
-
} else {
|
751 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
752 |
-
$xor = $this->_encryptBlock($xor);
|
753 |
-
$ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
|
754 |
-
}
|
755 |
-
$key = $xor;
|
756 |
-
}
|
757 |
-
if ($this->continuousBuffer) {
|
758 |
-
$this->encryptIV = $xor;
|
759 |
-
if ($start = strlen($plaintext) % $block_size) {
|
760 |
-
$buffer = substr($key, $start) . $buffer;
|
761 |
-
}
|
762 |
-
}
|
763 |
-
}
|
764 |
-
|
765 |
-
return $ciphertext;
|
766 |
-
}
|
767 |
-
|
768 |
-
/**
|
769 |
-
* Decrypts a message.
|
770 |
-
*
|
771 |
-
* If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
|
772 |
-
* it is.
|
773 |
-
*
|
774 |
-
* @see Crypt_Rijndael::encrypt()
|
775 |
-
* @access public
|
776 |
-
* @param String $ciphertext
|
777 |
-
*/
|
778 |
-
function decrypt($ciphertext)
|
779 |
-
{
|
780 |
-
$this->_setup();
|
781 |
-
|
782 |
-
if ($this->paddable) {
|
783 |
-
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
784 |
-
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
785 |
-
$ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
|
786 |
-
}
|
787 |
-
|
788 |
-
$block_size = $this->block_size;
|
789 |
-
$buffer = &$this->debuffer;
|
790 |
-
$continuousBuffer = $this->continuousBuffer;
|
791 |
-
$plaintext = '';
|
792 |
-
switch ($this->mode) {
|
793 |
-
case CRYPT_RIJNDAEL_MODE_ECB:
|
794 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
795 |
-
$plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
|
796 |
-
}
|
797 |
-
break;
|
798 |
-
case CRYPT_RIJNDAEL_MODE_CBC:
|
799 |
-
$xor = $this->decryptIV;
|
800 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
801 |
-
$block = substr($ciphertext, $i, $block_size);
|
802 |
-
$plaintext.= $this->_decryptBlock($block) ^ $xor;
|
803 |
-
$xor = $block;
|
804 |
-
}
|
805 |
-
if ($this->continuousBuffer) {
|
806 |
-
$this->decryptIV = $xor;
|
807 |
-
}
|
808 |
-
break;
|
809 |
-
case CRYPT_RIJNDAEL_MODE_CTR:
|
810 |
-
$xor = $this->decryptIV;
|
811 |
-
if (strlen($buffer)) {
|
812 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
813 |
-
$block = substr($ciphertext, $i, $block_size);
|
814 |
-
$buffer.= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
815 |
-
$key = $this->_string_shift($buffer, $block_size);
|
816 |
-
$plaintext.= $block ^ $key;
|
817 |
-
}
|
818 |
-
} else {
|
819 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
820 |
-
$block = substr($ciphertext, $i, $block_size);
|
821 |
-
$key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
822 |
-
$plaintext.= $block ^ $key;
|
823 |
-
}
|
824 |
-
}
|
825 |
-
if ($this->continuousBuffer) {
|
826 |
-
$this->decryptIV = $xor;
|
827 |
-
if ($start = strlen($ciphertext) % $block_size) {
|
828 |
-
$buffer = substr($key, $start) . $buffer;
|
829 |
-
}
|
830 |
-
}
|
831 |
-
break;
|
832 |
-
case CRYPT_RIJNDAEL_MODE_CFB:
|
833 |
-
if (!empty($buffer['ciphertext'])) {
|
834 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
|
835 |
-
$buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
|
836 |
-
if (strlen($buffer['ciphertext']) == $block_size) {
|
837 |
-
$xor = $this->_encryptBlock($buffer['ciphertext']);
|
838 |
-
$buffer['ciphertext'] = '';
|
839 |
-
}
|
840 |
-
$start = strlen($plaintext);
|
841 |
-
$block = $this->decryptIV;
|
842 |
-
} else {
|
843 |
-
$plaintext = '';
|
844 |
-
$xor = $this->_encryptBlock($this->decryptIV);
|
845 |
-
$start = 0;
|
846 |
-
}
|
847 |
-
|
848 |
-
for ($i = $start; $i < strlen($ciphertext); $i+=$block_size) {
|
849 |
-
$block = substr($ciphertext, $i, $block_size);
|
850 |
-
$plaintext.= $block ^ $xor;
|
851 |
-
if ($continuousBuffer && strlen($block) != $block_size) {
|
852 |
-
$buffer['ciphertext'].= $block;
|
853 |
-
$block = $xor;
|
854 |
-
} else if (strlen($block) == $block_size) {
|
855 |
-
$xor = $this->_encryptBlock($block);
|
856 |
-
}
|
857 |
-
}
|
858 |
-
if ($this->continuousBuffer) {
|
859 |
-
$this->decryptIV = $block;
|
860 |
-
}
|
861 |
-
break;
|
862 |
-
case CRYPT_RIJNDAEL_MODE_OFB:
|
863 |
-
$xor = $this->decryptIV;
|
864 |
-
if (strlen($buffer)) {
|
865 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
866 |
-
$xor = $this->_encryptBlock($xor);
|
867 |
-
$buffer.= $xor;
|
868 |
-
$key = $this->_string_shift($buffer, $block_size);
|
869 |
-
$plaintext.= substr($ciphertext, $i, $block_size) ^ $key;
|
870 |
-
}
|
871 |
-
} else {
|
872 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
873 |
-
$xor = $this->_encryptBlock($xor);
|
874 |
-
$plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
|
875 |
-
}
|
876 |
-
$key = $xor;
|
877 |
-
}
|
878 |
-
if ($this->continuousBuffer) {
|
879 |
-
$this->decryptIV = $xor;
|
880 |
-
if ($start = strlen($ciphertext) % $block_size) {
|
881 |
-
$buffer = substr($key, $start) . $buffer;
|
882 |
-
}
|
883 |
-
}
|
884 |
-
}
|
885 |
-
|
886 |
-
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
887 |
-
}
|
888 |
-
|
889 |
-
/**
|
890 |
-
* Encrypts a block
|
891 |
-
*
|
892 |
-
* @access private
|
893 |
-
* @param String $in
|
894 |
-
* @return String
|
895 |
-
*/
|
896 |
-
function _encryptBlock($in)
|
897 |
-
{
|
898 |
-
$state = array();
|
899 |
-
$words = unpack('N*word', $in);
|
900 |
-
|
901 |
-
$w = $this->w;
|
902 |
-
$t0 = $this->t0;
|
903 |
-
$t1 = $this->t1;
|
904 |
-
$t2 = $this->t2;
|
905 |
-
$t3 = $this->t3;
|
906 |
-
$Nb = $this->Nb;
|
907 |
-
$Nr = $this->Nr;
|
908 |
-
$c = $this->c;
|
909 |
-
|
910 |
-
// addRoundKey
|
911 |
-
$i = 0;
|
912 |
-
foreach ($words as $word) {
|
913 |
-
$state[] = $word ^ $w[0][$i++];
|
914 |
-
}
|
915 |
-
|
916 |
-
// fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
|
917 |
-
// subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
|
918 |
-
// Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
|
919 |
-
// Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
|
920 |
-
// Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1],
|
921 |
-
// equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
|
922 |
-
|
923 |
-
// [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
|
924 |
-
$temp = array();
|
925 |
-
for ($round = 1; $round < $Nr; $round++) {
|
926 |
-
$i = 0; // $c[0] == 0
|
927 |
-
$j = $c[1];
|
928 |
-
$k = $c[2];
|
929 |
-
$l = $c[3];
|
930 |
-
|
931 |
-
while ($i < $this->Nb) {
|
932 |
-
$temp[$i] = $t0[$state[$i] & 0xFF000000] ^
|
933 |
-
$t1[$state[$j] & 0x00FF0000] ^
|
934 |
-
$t2[$state[$k] & 0x0000FF00] ^
|
935 |
-
$t3[$state[$l] & 0x000000FF] ^
|
936 |
-
$w[$round][$i];
|
937 |
-
$i++;
|
938 |
-
$j = ($j + 1) % $Nb;
|
939 |
-
$k = ($k + 1) % $Nb;
|
940 |
-
$l = ($l + 1) % $Nb;
|
941 |
-
}
|
942 |
-
|
943 |
-
for ($i = 0; $i < $Nb; $i++) {
|
944 |
-
$state[$i] = $temp[$i];
|
945 |
-
}
|
946 |
-
}
|
947 |
-
|
948 |
-
// subWord
|
949 |
-
for ($i = 0; $i < $Nb; $i++) {
|
950 |
-
$state[$i] = $this->_subWord($state[$i]);
|
951 |
-
}
|
952 |
-
|
953 |
-
// shiftRows + addRoundKey
|
954 |
-
$i = 0; // $c[0] == 0
|
955 |
-
$j = $c[1];
|
956 |
-
$k = $c[2];
|
957 |
-
$l = $c[3];
|
958 |
-
while ($i < $this->Nb) {
|
959 |
-
$temp[$i] = ($state[$i] & 0xFF000000) ^
|
960 |
-
($state[$j] & 0x00FF0000) ^
|
961 |
-
($state[$k] & 0x0000FF00) ^
|
962 |
-
($state[$l] & 0x000000FF) ^
|
963 |
-
$w[$Nr][$i];
|
964 |
-
$i++;
|
965 |
-
$j = ($j + 1) % $Nb;
|
966 |
-
$k = ($k + 1) % $Nb;
|
967 |
-
$l = ($l + 1) % $Nb;
|
968 |
-
}
|
969 |
-
$state = $temp;
|
970 |
-
|
971 |
-
array_unshift($state, 'N*');
|
972 |
-
|
973 |
-
return call_user_func_array('pack', $state);
|
974 |
-
}
|
975 |
-
|
976 |
-
/**
|
977 |
-
* Decrypts a block
|
978 |
-
*
|
979 |
-
* @access private
|
980 |
-
* @param String $in
|
981 |
-
* @return String
|
982 |
-
*/
|
983 |
-
function _decryptBlock($in)
|
984 |
-
{
|
985 |
-
$state = array();
|
986 |
-
$words = unpack('N*word', $in);
|
987 |
-
|
988 |
-
$num_states = count($state);
|
989 |
-
$dw = $this->dw;
|
990 |
-
$dt0 = $this->dt0;
|
991 |
-
$dt1 = $this->dt1;
|
992 |
-
$dt2 = $this->dt2;
|
993 |
-
$dt3 = $this->dt3;
|
994 |
-
$Nb = $this->Nb;
|
995 |
-
$Nr = $this->Nr;
|
996 |
-
$c = $this->c;
|
997 |
-
|
998 |
-
// addRoundKey
|
999 |
-
$i = 0;
|
1000 |
-
foreach ($words as $word) {
|
1001 |
-
$state[] = $word ^ $dw[$Nr][$i++];
|
1002 |
-
}
|
1003 |
-
|
1004 |
-
$temp = array();
|
1005 |
-
for ($round = $Nr - 1; $round > 0; $round--) {
|
1006 |
-
$i = 0; // $c[0] == 0
|
1007 |
-
$j = $Nb - $c[1];
|
1008 |
-
$k = $Nb - $c[2];
|
1009 |
-
$l = $Nb - $c[3];
|
1010 |
-
|
1011 |
-
while ($i < $Nb) {
|
1012 |
-
$temp[$i] = $dt0[$state[$i] & 0xFF000000] ^
|
1013 |
-
$dt1[$state[$j] & 0x00FF0000] ^
|
1014 |
-
$dt2[$state[$k] & 0x0000FF00] ^
|
1015 |
-
$dt3[$state[$l] & 0x000000FF] ^
|
1016 |
-
$dw[$round][$i];
|
1017 |
-
$i++;
|
1018 |
-
$j = ($j + 1) % $Nb;
|
1019 |
-
$k = ($k + 1) % $Nb;
|
1020 |
-
$l = ($l + 1) % $Nb;
|
1021 |
-
}
|
1022 |
-
|
1023 |
-
for ($i = 0; $i < $Nb; $i++) {
|
1024 |
-
$state[$i] = $temp[$i];
|
1025 |
-
}
|
1026 |
-
}
|
1027 |
-
|
1028 |
-
// invShiftRows + invSubWord + addRoundKey
|
1029 |
-
$i = 0; // $c[0] == 0
|
1030 |
-
$j = $Nb - $c[1];
|
1031 |
-
$k = $Nb - $c[2];
|
1032 |
-
$l = $Nb - $c[3];
|
1033 |
-
|
1034 |
-
while ($i < $Nb) {
|
1035 |
-
$temp[$i] = $dw[0][$i] ^
|
1036 |
-
$this->_invSubWord(($state[$i] & 0xFF000000) |
|
1037 |
-
($state[$j] & 0x00FF0000) |
|
1038 |
-
($state[$k] & 0x0000FF00) |
|
1039 |
-
($state[$l] & 0x000000FF));
|
1040 |
-
$i++;
|
1041 |
-
$j = ($j + 1) % $Nb;
|
1042 |
-
$k = ($k + 1) % $Nb;
|
1043 |
-
$l = ($l + 1) % $Nb;
|
1044 |
-
}
|
1045 |
-
|
1046 |
-
$state = $temp;
|
1047 |
-
|
1048 |
-
array_unshift($state, 'N*');
|
1049 |
-
|
1050 |
-
return call_user_func_array('pack', $state);
|
1051 |
-
}
|
1052 |
-
|
1053 |
-
/**
|
1054 |
-
* Setup Rijndael
|
1055 |
-
*
|
1056 |
-
* Validates all the variables and calculates $Nr - the number of rounds that need to be performed - and $w - the key
|
1057 |
-
* key schedule.
|
1058 |
-
*
|
1059 |
-
* @access private
|
1060 |
-
*/
|
1061 |
-
function _setup()
|
1062 |
-
{
|
1063 |
-
// Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
|
1064 |
-
// See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
|
1065 |
-
static $rcon = array(0,
|
1066 |
-
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
1067 |
-
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
|
1068 |
-
0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
|
1069 |
-
0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
|
1070 |
-
0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
|
1071 |
-
0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
|
1072 |
-
);
|
1073 |
-
|
1074 |
-
if (!$this->changed) {
|
1075 |
-
return;
|
1076 |
-
}
|
1077 |
-
|
1078 |
-
if (!$this->explicit_key_length) {
|
1079 |
-
// we do >> 2, here, and not >> 5, as we do above, since strlen($this->key) tells us the number of bytes - not bits
|
1080 |
-
$length = strlen($this->key) >> 2;
|
1081 |
-
if ($length > 8) {
|
1082 |
-
$length = 8;
|
1083 |
-
} else if ($length < 4) {
|
1084 |
-
$length = 4;
|
1085 |
-
}
|
1086 |
-
$this->Nk = $length;
|
1087 |
-
$this->key_size = $length << 2;
|
1088 |
-
}
|
1089 |
-
|
1090 |
-
$this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
|
1091 |
-
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, chr(0));
|
1092 |
-
|
1093 |
-
// see Rijndael-ammended.pdf#page=44
|
1094 |
-
$this->Nr = max($this->Nk, $this->Nb) + 6;
|
1095 |
-
|
1096 |
-
// shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
|
1097 |
-
// "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
|
1098 |
-
// shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
|
1099 |
-
// "Table 2: Shift offsets for different block lengths"
|
1100 |
-
switch ($this->Nb) {
|
1101 |
-
case 4:
|
1102 |
-
case 5:
|
1103 |
-
case 6:
|
1104 |
-
$this->c = array(0, 1, 2, 3);
|
1105 |
-
break;
|
1106 |
-
case 7:
|
1107 |
-
$this->c = array(0, 1, 2, 4);
|
1108 |
-
break;
|
1109 |
-
case 8:
|
1110 |
-
$this->c = array(0, 1, 3, 4);
|
1111 |
-
}
|
1112 |
-
|
1113 |
-
$key = $this->key;
|
1114 |
-
|
1115 |
-
$w = array_values(unpack('N*words', $key));
|
1116 |
-
|
1117 |
-
$length = $this->Nb * ($this->Nr + 1);
|
1118 |
-
for ($i = $this->Nk; $i < $length; $i++) {
|
1119 |
-
$temp = $w[$i - 1];
|
1120 |
-
if ($i % $this->Nk == 0) {
|
1121 |
-
// according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
|
1122 |
-
// on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
|
1123 |
-
// 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
|
1124 |
-
// with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
|
1125 |
-
$temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
|
1126 |
-
$temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
|
1127 |
-
} else if ($this->Nk > 6 && $i % $this->Nk == 4) {
|
1128 |
-
$temp = $this->_subWord($temp);
|
1129 |
-
}
|
1130 |
-
$w[$i] = $w[$i - $this->Nk] ^ $temp;
|
1131 |
-
}
|
1132 |
-
|
1133 |
-
// convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
|
1134 |
-
// and generate the inverse key schedule. more specifically,
|
1135 |
-
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
|
1136 |
-
// "The key expansion for the Inverse Cipher is defined as follows:
|
1137 |
-
// 1. Apply the Key Expansion.
|
1138 |
-
// 2. Apply InvMixColumn to all Round Keys except the first and the last one."
|
1139 |
-
// also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
|
1140 |
-
$temp = array();
|
1141 |
-
for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
|
1142 |
-
if ($col == $this->Nb) {
|
1143 |
-
if ($row == 0) {
|
1144 |
-
$this->dw[0] = $this->w[0];
|
1145 |
-
} else {
|
1146 |
-
// subWord + invMixColumn + invSubWord = invMixColumn
|
1147 |
-
$j = 0;
|
1148 |
-
while ($j < $this->Nb) {
|
1149 |
-
$dw = $this->_subWord($this->w[$row][$j]);
|
1150 |
-
$temp[$j] = $this->dt0[$dw & 0xFF000000] ^
|
1151 |
-
$this->dt1[$dw & 0x00FF0000] ^
|
1152 |
-
$this->dt2[$dw & 0x0000FF00] ^
|
1153 |
-
$this->dt3[$dw & 0x000000FF];
|
1154 |
-
$j++;
|
1155 |
-
}
|
1156 |
-
$this->dw[$row] = $temp;
|
1157 |
-
}
|
1158 |
-
|
1159 |
-
$col = 0;
|
1160 |
-
$row++;
|
1161 |
-
}
|
1162 |
-
$this->w[$row][$col] = $w[$i];
|
1163 |
-
}
|
1164 |
-
|
1165 |
-
$this->dw[$row] = $this->w[$row];
|
1166 |
-
|
1167 |
-
$this->changed = false;
|
1168 |
-
}
|
1169 |
-
|
1170 |
-
/**
|
1171 |
-
* Performs S-Box substitutions
|
1172 |
-
*
|
1173 |
-
* @access private
|
1174 |
-
*/
|
1175 |
-
function _subWord($word)
|
1176 |
-
{
|
1177 |
-
static $sbox0, $sbox1, $sbox2, $sbox3;
|
1178 |
-
|
1179 |
-
if (empty($sbox0)) {
|
1180 |
-
$sbox0 = array(
|
1181 |
-
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
1182 |
-
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
1183 |
-
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
1184 |
-
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
1185 |
-
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
1186 |
-
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
1187 |
-
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
1188 |
-
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
1189 |
-
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
1190 |
-
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
1191 |
-
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
1192 |
-
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
1193 |
-
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
1194 |
-
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
1195 |
-
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
1196 |
-
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
1197 |
-
);
|
1198 |
-
|
1199 |
-
$sbox1 = array();
|
1200 |
-
$sbox2 = array();
|
1201 |
-
$sbox3 = array();
|
1202 |
-
|
1203 |
-
for ($i = 0; $i < 256; $i++) {
|
1204 |
-
$sbox1[$i << 8] = $sbox0[$i] << 8;
|
1205 |
-
$sbox2[$i << 16] = $sbox0[$i] << 16;
|
1206 |
-
$sbox3[$i << 24] = $sbox0[$i] << 24;
|
1207 |
-
}
|
1208 |
-
}
|
1209 |
-
|
1210 |
-
return $sbox0[$word & 0x000000FF] |
|
1211 |
-
$sbox1[$word & 0x0000FF00] |
|
1212 |
-
$sbox2[$word & 0x00FF0000] |
|
1213 |
-
$sbox3[$word & 0xFF000000];
|
1214 |
-
}
|
1215 |
-
|
1216 |
-
/**
|
1217 |
-
* Performs inverse S-Box substitutions
|
1218 |
-
*
|
1219 |
-
* @access private
|
1220 |
-
*/
|
1221 |
-
function _invSubWord($word)
|
1222 |
-
{
|
1223 |
-
static $sbox0, $sbox1, $sbox2, $sbox3;
|
1224 |
-
|
1225 |
-
if (empty($sbox0)) {
|
1226 |
-
$sbox0 = array(
|
1227 |
-
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
|
1228 |
-
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
|
1229 |
-
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
|
1230 |
-
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
|
1231 |
-
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
|
1232 |
-
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
|
1233 |
-
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
|
1234 |
-
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
|
1235 |
-
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
|
1236 |
-
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
|
1237 |
-
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
|
1238 |
-
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
|
1239 |
-
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
|
1240 |
-
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
|
1241 |
-
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
|
1242 |
-
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
|
1243 |
-
);
|
1244 |
-
|
1245 |
-
$sbox1 = array();
|
1246 |
-
$sbox2 = array();
|
1247 |
-
$sbox3 = array();
|
1248 |
-
|
1249 |
-
for ($i = 0; $i < 256; $i++) {
|
1250 |
-
$sbox1[$i << 8] = $sbox0[$i] << 8;
|
1251 |
-
$sbox2[$i << 16] = $sbox0[$i] << 16;
|
1252 |
-
$sbox3[$i << 24] = $sbox0[$i] << 24;
|
1253 |
-
}
|
1254 |
-
}
|
1255 |
-
|
1256 |
-
return $sbox0[$word & 0x000000FF] |
|
1257 |
-
$sbox1[$word & 0x0000FF00] |
|
1258 |
-
$sbox2[$word & 0x00FF0000] |
|
1259 |
-
$sbox3[$word & 0xFF000000];
|
1260 |
-
}
|
1261 |
-
|
1262 |
-
/**
|
1263 |
-
* Pad "packets".
|
1264 |
-
*
|
1265 |
-
* Rijndael works by encrypting between sixteen and thirty-two bytes at a time, provided that number is also a multiple
|
1266 |
-
* of four. If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
|
1267 |
-
* pad the input so that it is of the proper length.
|
1268 |
-
*
|
1269 |
-
* Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH,
|
1270 |
-
* where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
|
1271 |
-
* away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
|
1272 |
-
* transmitted separately)
|
1273 |
-
*
|
1274 |
-
* @see Crypt_Rijndael::disablePadding()
|
1275 |
-
* @access public
|
1276 |
-
*/
|
1277 |
-
function enablePadding()
|
1278 |
-
{
|
1279 |
-
$this->padding = true;
|
1280 |
-
}
|
1281 |
-
|
1282 |
-
/**
|
1283 |
-
* Do not pad packets.
|
1284 |
-
*
|
1285 |
-
* @see Crypt_Rijndael::enablePadding()
|
1286 |
-
* @access public
|
1287 |
-
*/
|
1288 |
-
function disablePadding()
|
1289 |
-
{
|
1290 |
-
$this->padding = false;
|
1291 |
-
}
|
1292 |
-
|
1293 |
-
/**
|
1294 |
-
* Pads a string
|
1295 |
-
*
|
1296 |
-
* Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
|
1297 |
-
* $block_size - (strlen($text) % $block_size) bytes are added, each of which is equal to
|
1298 |
-
* chr($block_size - (strlen($text) % $block_size)
|
1299 |
-
*
|
1300 |
-
* If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
|
1301 |
-
* and padding will, hence forth, be enabled.
|
1302 |
-
*
|
1303 |
-
* @see Crypt_Rijndael::_unpad()
|
1304 |
-
* @access private
|
1305 |
-
*/
|
1306 |
-
function _pad($text)
|
1307 |
-
{
|
1308 |
-
$length = strlen($text);
|
1309 |
-
|
1310 |
-
if (!$this->padding) {
|
1311 |
-
if ($length % $this->block_size == 0) {
|
1312 |
-
return $text;
|
1313 |
-
} else {
|
1314 |
-
user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})", E_USER_NOTICE);
|
1315 |
-
$this->padding = true;
|
1316 |
-
}
|
1317 |
-
}
|
1318 |
-
|
1319 |
-
$pad = $this->block_size - ($length % $this->block_size);
|
1320 |
-
|
1321 |
-
return str_pad($text, $length + $pad, chr($pad));
|
1322 |
-
}
|
1323 |
-
|
1324 |
-
/**
|
1325 |
-
* Unpads a string.
|
1326 |
-
*
|
1327 |
-
* If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
|
1328 |
-
* and false will be returned.
|
1329 |
-
*
|
1330 |
-
* @see Crypt_Rijndael::_pad()
|
1331 |
-
* @access private
|
1332 |
-
*/
|
1333 |
-
function _unpad($text)
|
1334 |
-
{
|
1335 |
-
if (!$this->padding) {
|
1336 |
-
return $text;
|
1337 |
-
}
|
1338 |
-
|
1339 |
-
$length = ord($text[strlen($text) - 1]);
|
1340 |
-
|
1341 |
-
if (!$length || $length > $this->block_size) {
|
1342 |
-
return false;
|
1343 |
-
}
|
1344 |
-
|
1345 |
-
return substr($text, 0, -$length);
|
1346 |
-
}
|
1347 |
-
|
1348 |
-
/**
|
1349 |
-
* Treat consecutive "packets" as if they are a continuous buffer.
|
1350 |
-
*
|
1351 |
-
* Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets
|
1352 |
-
* will yield different outputs:
|
1353 |
-
*
|
1354 |
-
* <code>
|
1355 |
-
* echo $rijndael->encrypt(substr($plaintext, 0, 16));
|
1356 |
-
* echo $rijndael->encrypt(substr($plaintext, 16, 16));
|
1357 |
-
* </code>
|
1358 |
-
* <code>
|
1359 |
-
* echo $rijndael->encrypt($plaintext);
|
1360 |
-
* </code>
|
1361 |
-
*
|
1362 |
-
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
|
1363 |
-
* another, as demonstrated with the following:
|
1364 |
-
*
|
1365 |
-
* <code>
|
1366 |
-
* $rijndael->encrypt(substr($plaintext, 0, 16));
|
1367 |
-
* echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16)));
|
1368 |
-
* </code>
|
1369 |
-
* <code>
|
1370 |
-
* echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16)));
|
1371 |
-
* </code>
|
1372 |
-
*
|
1373 |
-
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
|
1374 |
-
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
1375 |
-
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
1376 |
-
*
|
1377 |
-
* Put another way, when the continuous buffer is enabled, the state of the Crypt_Rijndael() object changes after each
|
1378 |
-
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
1379 |
-
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
1380 |
-
* however, they are also less intuitive and more likely to cause you problems.
|
1381 |
-
*
|
1382 |
-
* @see Crypt_Rijndael::disableContinuousBuffer()
|
1383 |
-
* @access public
|
1384 |
-
*/
|
1385 |
-
function enableContinuousBuffer()
|
1386 |
-
{
|
1387 |
-
$this->continuousBuffer = true;
|
1388 |
-
}
|
1389 |
-
|
1390 |
-
/**
|
1391 |
-
* Treat consecutive packets as if they are a discontinuous buffer.
|
1392 |
-
*
|
1393 |
-
* The default behavior.
|
1394 |
-
*
|
1395 |
-
* @see Crypt_Rijndael::enableContinuousBuffer()
|
1396 |
-
* @access public
|
1397 |
-
*/
|
1398 |
-
function disableContinuousBuffer()
|
1399 |
-
{
|
1400 |
-
$this->continuousBuffer = false;
|
1401 |
-
$this->encryptIV = $this->iv;
|
1402 |
-
$this->decryptIV = $this->iv;
|
1403 |
-
}
|
1404 |
-
|
1405 |
-
/**
|
1406 |
-
* String Shift
|
1407 |
-
*
|
1408 |
-
* Inspired by array_shift
|
1409 |
-
*
|
1410 |
-
* @param String $string
|
1411 |
-
* @param optional Integer $index
|
1412 |
-
* @return String
|
1413 |
-
* @access private
|
1414 |
-
*/
|
1415 |
-
function _string_shift(&$string, $index = 1)
|
1416 |
-
{
|
1417 |
-
$substr = substr($string, 0, $index);
|
1418 |
-
$string = substr($string, $index);
|
1419 |
-
return $substr;
|
1420 |
-
}
|
1421 |
-
}
|
1422 |
-
|
1423 |
-
// vim: ts=4:sw=4:et:
|
1424 |
-
// vim6: fdl=1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/TripleDES.php
DELETED
@@ -1,1009 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of Triple DES.
|
6 |
-
*
|
7 |
-
* Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* Here's a short example of how to use this library:
|
12 |
-
* <code>
|
13 |
-
* <?php
|
14 |
-
* include('Crypt/TripleDES.php');
|
15 |
-
*
|
16 |
-
* $des = new Crypt_TripleDES();
|
17 |
-
*
|
18 |
-
* $des->setKey('abcdefghijklmnopqrstuvwx');
|
19 |
-
*
|
20 |
-
* $size = 10 * 1024;
|
21 |
-
* $plaintext = '';
|
22 |
-
* for ($i = 0; $i < $size; $i++) {
|
23 |
-
* $plaintext.= 'a';
|
24 |
-
* }
|
25 |
-
*
|
26 |
-
* echo $des->decrypt($des->encrypt($plaintext));
|
27 |
-
* ?>
|
28 |
-
* </code>
|
29 |
-
*
|
30 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
31 |
-
* of this software and associated documentation files (the "Software"), to deal
|
32 |
-
* in the Software without restriction, including without limitation the rights
|
33 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
34 |
-
* copies of the Software, and to permit persons to whom the Software is
|
35 |
-
* furnished to do so, subject to the following conditions:
|
36 |
-
*
|
37 |
-
* The above copyright notice and this permission notice shall be included in
|
38 |
-
* all copies or substantial portions of the Software.
|
39 |
-
*
|
40 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
41 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
42 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
43 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
44 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
45 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
46 |
-
* THE SOFTWARE.
|
47 |
-
*
|
48 |
-
* @category Crypt
|
49 |
-
* @package Crypt_TripleDES
|
50 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
51 |
-
* @copyright MMVII Jim Wigginton
|
52 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
53 |
-
* @version $Id: TripleDES.php,v 1.13 2010/02/26 03:40:25 terrafrost Exp $
|
54 |
-
* @link http://phpseclib.sourceforge.net
|
55 |
-
*/
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Include Crypt_DES
|
59 |
-
*/
|
60 |
-
require_once('DES.php');
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Encrypt / decrypt using inner chaining
|
64 |
-
*
|
65 |
-
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
|
66 |
-
*/
|
67 |
-
define('CRYPT_DES_MODE_3CBC', -2);
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Encrypt / decrypt using outer chaining
|
71 |
-
*
|
72 |
-
* Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
|
73 |
-
*/
|
74 |
-
define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Pure-PHP implementation of Triple DES.
|
78 |
-
*
|
79 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
80 |
-
* @version 0.1.0
|
81 |
-
* @access public
|
82 |
-
* @package Crypt_TerraDES
|
83 |
-
*/
|
84 |
-
class Crypt_TripleDES {
|
85 |
-
/**
|
86 |
-
* The Three Keys
|
87 |
-
*
|
88 |
-
* @see Crypt_TripleDES::setKey()
|
89 |
-
* @var String
|
90 |
-
* @access private
|
91 |
-
*/
|
92 |
-
var $key = "\0\0\0\0\0\0\0\0";
|
93 |
-
|
94 |
-
/**
|
95 |
-
* The Encryption Mode
|
96 |
-
*
|
97 |
-
* @see Crypt_TripleDES::Crypt_TripleDES()
|
98 |
-
* @var Integer
|
99 |
-
* @access private
|
100 |
-
*/
|
101 |
-
var $mode = CRYPT_DES_MODE_CBC;
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Continuous Buffer status
|
105 |
-
*
|
106 |
-
* @see Crypt_TripleDES::enableContinuousBuffer()
|
107 |
-
* @var Boolean
|
108 |
-
* @access private
|
109 |
-
*/
|
110 |
-
var $continuousBuffer = false;
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Padding status
|
114 |
-
*
|
115 |
-
* @see Crypt_TripleDES::enablePadding()
|
116 |
-
* @var Boolean
|
117 |
-
* @access private
|
118 |
-
*/
|
119 |
-
var $padding = true;
|
120 |
-
|
121 |
-
/**
|
122 |
-
* The Initialization Vector
|
123 |
-
*
|
124 |
-
* @see Crypt_TripleDES::setIV()
|
125 |
-
* @var String
|
126 |
-
* @access private
|
127 |
-
*/
|
128 |
-
var $iv = "\0\0\0\0\0\0\0\0";
|
129 |
-
|
130 |
-
/**
|
131 |
-
* A "sliding" Initialization Vector
|
132 |
-
*
|
133 |
-
* @see Crypt_TripleDES::enableContinuousBuffer()
|
134 |
-
* @var String
|
135 |
-
* @access private
|
136 |
-
*/
|
137 |
-
var $encryptIV = "\0\0\0\0\0\0\0\0";
|
138 |
-
|
139 |
-
/**
|
140 |
-
* A "sliding" Initialization Vector
|
141 |
-
*
|
142 |
-
* @see Crypt_TripleDES::enableContinuousBuffer()
|
143 |
-
* @var String
|
144 |
-
* @access private
|
145 |
-
*/
|
146 |
-
var $decryptIV = "\0\0\0\0\0\0\0\0";
|
147 |
-
|
148 |
-
/**
|
149 |
-
* The Crypt_DES objects
|
150 |
-
*
|
151 |
-
* @var Array
|
152 |
-
* @access private
|
153 |
-
*/
|
154 |
-
var $des;
|
155 |
-
|
156 |
-
/**
|
157 |
-
* mcrypt resource for encryption
|
158 |
-
*
|
159 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
160 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
161 |
-
*
|
162 |
-
* @see Crypt_TripleDES::encrypt()
|
163 |
-
* @var String
|
164 |
-
* @access private
|
165 |
-
*/
|
166 |
-
var $enmcrypt;
|
167 |
-
|
168 |
-
/**
|
169 |
-
* mcrypt resource for decryption
|
170 |
-
*
|
171 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
172 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
173 |
-
*
|
174 |
-
* @see Crypt_TripleDES::decrypt()
|
175 |
-
* @var String
|
176 |
-
* @access private
|
177 |
-
*/
|
178 |
-
var $demcrypt;
|
179 |
-
|
180 |
-
/**
|
181 |
-
* Does the enmcrypt resource need to be (re)initialized?
|
182 |
-
*
|
183 |
-
* @see Crypt_TripleDES::setKey()
|
184 |
-
* @see Crypt_TripleDES::setIV()
|
185 |
-
* @var Boolean
|
186 |
-
* @access private
|
187 |
-
*/
|
188 |
-
var $enchanged = true;
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Does the demcrypt resource need to be (re)initialized?
|
192 |
-
*
|
193 |
-
* @see Crypt_TripleDES::setKey()
|
194 |
-
* @see Crypt_TripleDES::setIV()
|
195 |
-
* @var Boolean
|
196 |
-
* @access private
|
197 |
-
*/
|
198 |
-
var $dechanged = true;
|
199 |
-
|
200 |
-
/**
|
201 |
-
* Is the mode one that is paddable?
|
202 |
-
*
|
203 |
-
* @see Crypt_TripleDES::Crypt_TripleDES()
|
204 |
-
* @var Boolean
|
205 |
-
* @access private
|
206 |
-
*/
|
207 |
-
var $paddable = false;
|
208 |
-
|
209 |
-
/**
|
210 |
-
* Encryption buffer for CTR, OFB and CFB modes
|
211 |
-
*
|
212 |
-
* @see Crypt_TripleDES::encrypt()
|
213 |
-
* @var String
|
214 |
-
* @access private
|
215 |
-
*/
|
216 |
-
var $enbuffer = '';
|
217 |
-
|
218 |
-
/**
|
219 |
-
* Decryption buffer for CTR, OFB and CFB modes
|
220 |
-
*
|
221 |
-
* @see Crypt_TripleDES::decrypt()
|
222 |
-
* @var String
|
223 |
-
* @access private
|
224 |
-
*/
|
225 |
-
var $debuffer = '';
|
226 |
-
|
227 |
-
/**
|
228 |
-
* mcrypt resource for CFB mode
|
229 |
-
*
|
230 |
-
* @see Crypt_TripleDES::encrypt()
|
231 |
-
* @see Crypt_TripleDES::decrypt()
|
232 |
-
* @var String
|
233 |
-
* @access private
|
234 |
-
*/
|
235 |
-
var $ecb;
|
236 |
-
|
237 |
-
/**
|
238 |
-
* Default Constructor.
|
239 |
-
*
|
240 |
-
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
|
241 |
-
* CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
|
242 |
-
*
|
243 |
-
* @param optional Integer $mode
|
244 |
-
* @return Crypt_TripleDES
|
245 |
-
* @access public
|
246 |
-
*/
|
247 |
-
function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC)
|
248 |
-
{
|
249 |
-
if ( !defined('CRYPT_DES_MODE') ) {
|
250 |
-
switch (true) {
|
251 |
-
case extension_loaded('mcrypt'):
|
252 |
-
// i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
|
253 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
254 |
-
// a lot of point...
|
255 |
-
define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
|
256 |
-
break;
|
257 |
-
default:
|
258 |
-
define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
|
259 |
-
}
|
260 |
-
}
|
261 |
-
|
262 |
-
if ( $mode == CRYPT_DES_MODE_3CBC ) {
|
263 |
-
$this->mode = CRYPT_DES_MODE_3CBC;
|
264 |
-
$this->des = array(
|
265 |
-
new Crypt_DES(CRYPT_DES_MODE_CBC),
|
266 |
-
new Crypt_DES(CRYPT_DES_MODE_CBC),
|
267 |
-
new Crypt_DES(CRYPT_DES_MODE_CBC)
|
268 |
-
);
|
269 |
-
|
270 |
-
// we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
|
271 |
-
$this->des[0]->disablePadding();
|
272 |
-
$this->des[1]->disablePadding();
|
273 |
-
$this->des[2]->disablePadding();
|
274 |
-
|
275 |
-
return;
|
276 |
-
}
|
277 |
-
|
278 |
-
switch ( CRYPT_DES_MODE ) {
|
279 |
-
case CRYPT_DES_MODE_MCRYPT:
|
280 |
-
switch ($mode) {
|
281 |
-
case CRYPT_DES_MODE_ECB:
|
282 |
-
$this->paddable = true;
|
283 |
-
$this->mode = MCRYPT_MODE_ECB;
|
284 |
-
break;
|
285 |
-
case CRYPT_DES_MODE_CTR:
|
286 |
-
$this->mode = 'ctr';
|
287 |
-
break;
|
288 |
-
case CRYPT_DES_MODE_CFB:
|
289 |
-
$this->mode = 'ncfb';
|
290 |
-
break;
|
291 |
-
case CRYPT_DES_MODE_OFB:
|
292 |
-
$this->mode = MCRYPT_MODE_NOFB;
|
293 |
-
break;
|
294 |
-
case CRYPT_DES_MODE_CBC:
|
295 |
-
default:
|
296 |
-
$this->paddable = true;
|
297 |
-
$this->mode = MCRYPT_MODE_CBC;
|
298 |
-
}
|
299 |
-
|
300 |
-
break;
|
301 |
-
default:
|
302 |
-
$this->des = array(
|
303 |
-
new Crypt_DES(CRYPT_DES_MODE_ECB),
|
304 |
-
new Crypt_DES(CRYPT_DES_MODE_ECB),
|
305 |
-
new Crypt_DES(CRYPT_DES_MODE_ECB)
|
306 |
-
);
|
307 |
-
|
308 |
-
// we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
|
309 |
-
$this->des[0]->disablePadding();
|
310 |
-
$this->des[1]->disablePadding();
|
311 |
-
$this->des[2]->disablePadding();
|
312 |
-
|
313 |
-
switch ($mode) {
|
314 |
-
case CRYPT_DES_MODE_ECB:
|
315 |
-
case CRYPT_DES_MODE_CBC:
|
316 |
-
$this->paddable = true;
|
317 |
-
$this->mode = $mode;
|
318 |
-
break;
|
319 |
-
case CRYPT_DES_MODE_CTR:
|
320 |
-
case CRYPT_DES_MODE_CFB:
|
321 |
-
case CRYPT_DES_MODE_OFB:
|
322 |
-
$this->mode = $mode;
|
323 |
-
break;
|
324 |
-
default:
|
325 |
-
$this->paddable = true;
|
326 |
-
$this->mode = CRYPT_DES_MODE_CBC;
|
327 |
-
}
|
328 |
-
}
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* Sets the key.
|
333 |
-
*
|
334 |
-
* Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
|
335 |
-
* 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
|
336 |
-
*
|
337 |
-
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
338 |
-
*
|
339 |
-
* If the key is not explicitly set, it'll be assumed to be all zero's.
|
340 |
-
*
|
341 |
-
* @access public
|
342 |
-
* @param String $key
|
343 |
-
*/
|
344 |
-
function setKey($key)
|
345 |
-
{
|
346 |
-
$length = strlen($key);
|
347 |
-
if ($length > 8) {
|
348 |
-
$key = str_pad($key, 24, chr(0));
|
349 |
-
// if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
|
350 |
-
// http://php.net/function.mcrypt-encrypt#47973
|
351 |
-
//$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
|
352 |
-
} else {
|
353 |
-
$key = str_pad($key, 8, chr(0));
|
354 |
-
}
|
355 |
-
$this->key = $key;
|
356 |
-
switch (true) {
|
357 |
-
case CRYPT_DES_MODE == CRYPT_DES_MODE_INTERNAL:
|
358 |
-
case $this->mode == CRYPT_DES_MODE_3CBC:
|
359 |
-
$this->des[0]->setKey(substr($key, 0, 8));
|
360 |
-
$this->des[1]->setKey(substr($key, 8, 8));
|
361 |
-
$this->des[2]->setKey(substr($key, 16, 8));
|
362 |
-
}
|
363 |
-
$this->enchanged = $this->dechanged = true;
|
364 |
-
}
|
365 |
-
|
366 |
-
/**
|
367 |
-
* Sets the initialization vector. (optional)
|
368 |
-
*
|
369 |
-
* SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
|
370 |
-
* to be all zero's.
|
371 |
-
*
|
372 |
-
* @access public
|
373 |
-
* @param String $iv
|
374 |
-
*/
|
375 |
-
function setIV($iv)
|
376 |
-
{
|
377 |
-
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
|
378 |
-
if ($this->mode == CRYPT_DES_MODE_3CBC) {
|
379 |
-
$this->des[0]->setIV($iv);
|
380 |
-
$this->des[1]->setIV($iv);
|
381 |
-
$this->des[2]->setIV($iv);
|
382 |
-
}
|
383 |
-
$this->enchanged = $this->dechanged = true;
|
384 |
-
}
|
385 |
-
|
386 |
-
/**
|
387 |
-
* Generate CTR XOR encryption key
|
388 |
-
*
|
389 |
-
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
390 |
-
* plaintext / ciphertext in CTR mode.
|
391 |
-
*
|
392 |
-
* @see Crypt_TripleDES::decrypt()
|
393 |
-
* @see Crypt_TripleDES::encrypt()
|
394 |
-
* @access private
|
395 |
-
* @param Integer $length
|
396 |
-
* @param String $iv
|
397 |
-
*/
|
398 |
-
function _generate_xor($length, &$iv)
|
399 |
-
{
|
400 |
-
$xor = '';
|
401 |
-
$num_blocks = ($length + 7) >> 3;
|
402 |
-
for ($i = 0; $i < $num_blocks; $i++) {
|
403 |
-
$xor.= $iv;
|
404 |
-
for ($j = 4; $j <= 8; $j+=4) {
|
405 |
-
$temp = substr($iv, -$j, 4);
|
406 |
-
switch ($temp) {
|
407 |
-
case "\xFF\xFF\xFF\xFF":
|
408 |
-
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
409 |
-
break;
|
410 |
-
case "\x7F\xFF\xFF\xFF":
|
411 |
-
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
412 |
-
break 2;
|
413 |
-
default:
|
414 |
-
extract(unpack('Ncount', $temp));
|
415 |
-
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
416 |
-
break 2;
|
417 |
-
}
|
418 |
-
}
|
419 |
-
}
|
420 |
-
|
421 |
-
return $xor;
|
422 |
-
}
|
423 |
-
|
424 |
-
/**
|
425 |
-
* Encrypts a message.
|
426 |
-
*
|
427 |
-
* @access public
|
428 |
-
* @param String $plaintext
|
429 |
-
*/
|
430 |
-
function encrypt($plaintext)
|
431 |
-
{
|
432 |
-
if ($this->paddable) {
|
433 |
-
$plaintext = $this->_pad($plaintext);
|
434 |
-
}
|
435 |
-
|
436 |
-
// if the key is smaller then 8, do what we'd normally do
|
437 |
-
if ($this->mode == CRYPT_DES_MODE_3CBC && strlen($this->key) > 8) {
|
438 |
-
$ciphertext = $this->des[2]->encrypt($this->des[1]->decrypt($this->des[0]->encrypt($plaintext)));
|
439 |
-
|
440 |
-
return $ciphertext;
|
441 |
-
}
|
442 |
-
|
443 |
-
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
444 |
-
if ($this->enchanged) {
|
445 |
-
if (!isset($this->enmcrypt)) {
|
446 |
-
$this->enmcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
|
447 |
-
}
|
448 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
449 |
-
if ($this->mode != 'ncfb') {
|
450 |
-
$this->enchanged = false;
|
451 |
-
}
|
452 |
-
}
|
453 |
-
|
454 |
-
if ($this->mode != 'ncfb') {
|
455 |
-
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
456 |
-
} else {
|
457 |
-
if ($this->enchanged) {
|
458 |
-
$this->ecb = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
|
459 |
-
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0");
|
460 |
-
$this->enchanged = false;
|
461 |
-
}
|
462 |
-
|
463 |
-
if (strlen($this->enbuffer)) {
|
464 |
-
$ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
|
465 |
-
$this->enbuffer.= $ciphertext;
|
466 |
-
if (strlen($this->enbuffer) == 8) {
|
467 |
-
$this->encryptIV = $this->enbuffer;
|
468 |
-
$this->enbuffer = '';
|
469 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
470 |
-
}
|
471 |
-
$plaintext = substr($plaintext, strlen($ciphertext));
|
472 |
-
} else {
|
473 |
-
$ciphertext = '';
|
474 |
-
}
|
475 |
-
|
476 |
-
$last_pos = strlen($plaintext) & 0xFFFFFFF8;
|
477 |
-
$ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
|
478 |
-
|
479 |
-
if (strlen($plaintext) & 0x7) {
|
480 |
-
if (strlen($ciphertext)) {
|
481 |
-
$this->encryptIV = substr($ciphertext, -8);
|
482 |
-
}
|
483 |
-
$this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
|
484 |
-
$this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
|
485 |
-
$ciphertext.= $this->enbuffer;
|
486 |
-
}
|
487 |
-
}
|
488 |
-
|
489 |
-
if (!$this->continuousBuffer) {
|
490 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
491 |
-
}
|
492 |
-
|
493 |
-
return $ciphertext;
|
494 |
-
}
|
495 |
-
|
496 |
-
if (strlen($this->key) <= 8) {
|
497 |
-
$this->des[0]->mode = $this->mode;
|
498 |
-
|
499 |
-
return $this->des[0]->encrypt($plaintext);
|
500 |
-
}
|
501 |
-
|
502 |
-
$des = $this->des;
|
503 |
-
|
504 |
-
$buffer = &$this->enbuffer;
|
505 |
-
$continuousBuffer = $this->continuousBuffer;
|
506 |
-
$ciphertext = '';
|
507 |
-
switch ($this->mode) {
|
508 |
-
case CRYPT_DES_MODE_ECB:
|
509 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
510 |
-
$block = substr($plaintext, $i, 8);
|
511 |
-
// all of these _processBlock calls could, in theory, be put in a function - say Crypt_TripleDES::_ede_encrypt() or something.
|
512 |
-
// only problem with that: it would slow encryption and decryption down. $this->des would have to be called every time that
|
513 |
-
// function is called, instead of once for the whole string of text that's being encrypted, which would, in turn, make
|
514 |
-
// encryption and decryption take more time, per this:
|
515 |
-
//
|
516 |
-
// http://blog.libssh2.org/index.php?/archives/21-Compiled-Variables.html
|
517 |
-
$block = $des[0]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
518 |
-
$block = $des[1]->_processBlock($block, CRYPT_DES_DECRYPT);
|
519 |
-
$block = $des[2]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
520 |
-
$ciphertext.= $block;
|
521 |
-
}
|
522 |
-
break;
|
523 |
-
case CRYPT_DES_MODE_CBC:
|
524 |
-
$xor = $this->encryptIV;
|
525 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
526 |
-
$block = substr($plaintext, $i, 8) ^ $xor;
|
527 |
-
$block = $des[0]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
528 |
-
$block = $des[1]->_processBlock($block, CRYPT_DES_DECRYPT);
|
529 |
-
$block = $des[2]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
530 |
-
$xor = $block;
|
531 |
-
$ciphertext.= $block;
|
532 |
-
}
|
533 |
-
if ($this->continuousBuffer) {
|
534 |
-
$this->encryptIV = $xor;
|
535 |
-
}
|
536 |
-
break;
|
537 |
-
case CRYPT_DES_MODE_CTR:
|
538 |
-
$xor = $this->encryptIV;
|
539 |
-
if (strlen($buffer)) {
|
540 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
541 |
-
$block = substr($plaintext, $i, 8);
|
542 |
-
$key = $this->_generate_xor(8, $xor);
|
543 |
-
$key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
544 |
-
$key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
|
545 |
-
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
546 |
-
$buffer.= $key;
|
547 |
-
$key = $this->_string_shift($buffer, 8);
|
548 |
-
$ciphertext.= $block ^ $key;
|
549 |
-
}
|
550 |
-
} else {
|
551 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
552 |
-
$block = substr($plaintext, $i, 8);
|
553 |
-
$key = $this->_generate_xor(8, $xor);
|
554 |
-
$key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
555 |
-
$key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
|
556 |
-
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
557 |
-
$ciphertext.= $block ^ $key;
|
558 |
-
}
|
559 |
-
}
|
560 |
-
if ($this->continuousBuffer) {
|
561 |
-
$this->encryptIV = $xor;
|
562 |
-
if ($start = strlen($plaintext) & 7) {
|
563 |
-
$buffer = substr($key, $start) . $buffer;
|
564 |
-
}
|
565 |
-
}
|
566 |
-
break;
|
567 |
-
case CRYPT_DES_MODE_CFB:
|
568 |
-
if (!empty($buffer['xor'])) {
|
569 |
-
$ciphertext = $plaintext ^ $buffer['xor'];
|
570 |
-
$iv = $buffer['encrypted'] . $ciphertext;
|
571 |
-
$start = strlen($ciphertext);
|
572 |
-
$buffer['encrypted'].= $ciphertext;
|
573 |
-
$buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
|
574 |
-
} else {
|
575 |
-
$ciphertext = '';
|
576 |
-
$iv = $this->encryptIV;
|
577 |
-
$start = 0;
|
578 |
-
}
|
579 |
-
|
580 |
-
for ($i = $start; $i < strlen($plaintext); $i+=8) {
|
581 |
-
$block = substr($plaintext, $i, 8);
|
582 |
-
$iv = $des[0]->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
583 |
-
$iv = $des[1]->_processBlock($iv, CRYPT_DES_DECRYPT);
|
584 |
-
$xor= $des[2]->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
585 |
-
|
586 |
-
$iv = $block ^ $xor;
|
587 |
-
if ($continuousBuffer && strlen($iv) != 8) {
|
588 |
-
$buffer = array(
|
589 |
-
'encrypted' => $iv,
|
590 |
-
'xor' => substr($xor, strlen($iv))
|
591 |
-
);
|
592 |
-
}
|
593 |
-
$ciphertext.= $iv;
|
594 |
-
}
|
595 |
-
|
596 |
-
if ($this->continuousBuffer) {
|
597 |
-
$this->encryptIV = $iv;
|
598 |
-
}
|
599 |
-
break;
|
600 |
-
case CRYPT_DES_MODE_OFB:
|
601 |
-
$xor = $this->encryptIV;
|
602 |
-
if (strlen($buffer)) {
|
603 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
604 |
-
$xor = $des[0]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
605 |
-
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
606 |
-
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
607 |
-
$buffer.= $xor;
|
608 |
-
$key = $this->_string_shift($buffer, 8);
|
609 |
-
$ciphertext.= substr($plaintext, $i, 8) ^ $key;
|
610 |
-
}
|
611 |
-
} else {
|
612 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
613 |
-
$xor = $des[0]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
614 |
-
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
615 |
-
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
616 |
-
$ciphertext.= substr($plaintext, $i, 8) ^ $xor;
|
617 |
-
}
|
618 |
-
$key = $xor;
|
619 |
-
}
|
620 |
-
if ($this->continuousBuffer) {
|
621 |
-
$this->encryptIV = $xor;
|
622 |
-
if ($start = strlen($plaintext) & 7) {
|
623 |
-
$buffer = substr($key, $start) . $buffer;
|
624 |
-
}
|
625 |
-
}
|
626 |
-
}
|
627 |
-
|
628 |
-
return $ciphertext;
|
629 |
-
}
|
630 |
-
|
631 |
-
/**
|
632 |
-
* Decrypts a message.
|
633 |
-
*
|
634 |
-
* @access public
|
635 |
-
* @param String $ciphertext
|
636 |
-
*/
|
637 |
-
function decrypt($ciphertext)
|
638 |
-
{
|
639 |
-
if ($this->mode == CRYPT_DES_MODE_3CBC && strlen($this->key) > 8) {
|
640 |
-
$plaintext = $this->des[0]->decrypt($this->des[1]->encrypt($this->des[2]->decrypt($ciphertext)));
|
641 |
-
|
642 |
-
return $this->_unpad($plaintext);
|
643 |
-
}
|
644 |
-
|
645 |
-
if ($this->paddable) {
|
646 |
-
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
647 |
-
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
648 |
-
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
|
649 |
-
}
|
650 |
-
|
651 |
-
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
652 |
-
if ($this->dechanged) {
|
653 |
-
if (!isset($this->demcrypt)) {
|
654 |
-
$this->demcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
|
655 |
-
}
|
656 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
657 |
-
if ($this->mode != 'ncfb') {
|
658 |
-
$this->dechanged = false;
|
659 |
-
}
|
660 |
-
}
|
661 |
-
|
662 |
-
if ($this->mode != 'ncfb') {
|
663 |
-
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
664 |
-
} else {
|
665 |
-
if ($this->dechanged) {
|
666 |
-
$this->ecb = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
|
667 |
-
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0");
|
668 |
-
$this->dechanged = false;
|
669 |
-
}
|
670 |
-
|
671 |
-
if (strlen($this->debuffer)) {
|
672 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
|
673 |
-
|
674 |
-
$this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
|
675 |
-
if (strlen($this->debuffer) == 8) {
|
676 |
-
$this->decryptIV = $this->debuffer;
|
677 |
-
$this->debuffer = '';
|
678 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
679 |
-
}
|
680 |
-
$ciphertext = substr($ciphertext, strlen($plaintext));
|
681 |
-
} else {
|
682 |
-
$plaintext = '';
|
683 |
-
}
|
684 |
-
|
685 |
-
$last_pos = strlen($ciphertext) & 0xFFFFFFF8;
|
686 |
-
$plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
|
687 |
-
|
688 |
-
if (strlen($ciphertext) & 0x7) {
|
689 |
-
if (strlen($plaintext)) {
|
690 |
-
$this->decryptIV = substr($ciphertext, $last_pos - 8, 8);
|
691 |
-
}
|
692 |
-
$this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
|
693 |
-
$this->debuffer = substr($ciphertext, $last_pos);
|
694 |
-
$plaintext.= $this->debuffer ^ $this->decryptIV;
|
695 |
-
}
|
696 |
-
|
697 |
-
return $plaintext;
|
698 |
-
}
|
699 |
-
|
700 |
-
if (!$this->continuousBuffer) {
|
701 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
702 |
-
}
|
703 |
-
|
704 |
-
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
705 |
-
}
|
706 |
-
|
707 |
-
if (strlen($this->key) <= 8) {
|
708 |
-
$this->des[0]->mode = $this->mode;
|
709 |
-
$plaintext = $this->des[0]->decrypt($ciphertext);
|
710 |
-
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
711 |
-
}
|
712 |
-
|
713 |
-
$des = $this->des;
|
714 |
-
|
715 |
-
$buffer = &$this->enbuffer;
|
716 |
-
$continuousBuffer = $this->continuousBuffer;
|
717 |
-
$plaintext = '';
|
718 |
-
switch ($this->mode) {
|
719 |
-
case CRYPT_DES_MODE_ECB:
|
720 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
721 |
-
$block = substr($ciphertext, $i, 8);
|
722 |
-
$block = $des[2]->_processBlock($block, CRYPT_DES_DECRYPT);
|
723 |
-
$block = $des[1]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
724 |
-
$block = $des[0]->_processBlock($block, CRYPT_DES_DECRYPT);
|
725 |
-
$plaintext.= $block;
|
726 |
-
}
|
727 |
-
break;
|
728 |
-
case CRYPT_DES_MODE_CBC:
|
729 |
-
$xor = $this->decryptIV;
|
730 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
731 |
-
$orig = $block = substr($ciphertext, $i, 8);
|
732 |
-
$block = $des[2]->_processBlock($block, CRYPT_DES_DECRYPT);
|
733 |
-
$block = $des[1]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
734 |
-
$block = $des[0]->_processBlock($block, CRYPT_DES_DECRYPT);
|
735 |
-
$plaintext.= $block ^ $xor;
|
736 |
-
$xor = $orig;
|
737 |
-
}
|
738 |
-
if ($this->continuousBuffer) {
|
739 |
-
$this->decryptIV = $xor;
|
740 |
-
}
|
741 |
-
break;
|
742 |
-
case CRYPT_DES_MODE_CTR:
|
743 |
-
$xor = $this->decryptIV;
|
744 |
-
if (strlen($buffer)) {
|
745 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
746 |
-
$block = substr($ciphertext, $i, 8);
|
747 |
-
$key = $this->_generate_xor(8, $xor);
|
748 |
-
$key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
749 |
-
$key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
|
750 |
-
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
751 |
-
$buffer.= $key;
|
752 |
-
$key = $this->_string_shift($buffer, 8);
|
753 |
-
$plaintext.= $block ^ $key;
|
754 |
-
}
|
755 |
-
} else {
|
756 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
757 |
-
$block = substr($ciphertext, $i, 8);
|
758 |
-
$key = $this->_generate_xor(8, $xor);
|
759 |
-
$key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
760 |
-
$key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
|
761 |
-
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
762 |
-
$plaintext.= $block ^ $key;
|
763 |
-
}
|
764 |
-
}
|
765 |
-
if ($this->continuousBuffer) {
|
766 |
-
$this->decryptIV = $xor;
|
767 |
-
if ($start = strlen($plaintext) & 7) {
|
768 |
-
$buffer = substr($key, $start) . $buffer;
|
769 |
-
}
|
770 |
-
}
|
771 |
-
break;
|
772 |
-
case CRYPT_DES_MODE_CFB:
|
773 |
-
if (!empty($buffer['ciphertext'])) {
|
774 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
|
775 |
-
$buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
|
776 |
-
if (strlen($buffer['ciphertext']) == 8) {
|
777 |
-
$xor = $des[0]->_processBlock($buffer['ciphertext'], CRYPT_DES_ENCRYPT);
|
778 |
-
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
779 |
-
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
780 |
-
$buffer['ciphertext'] = '';
|
781 |
-
}
|
782 |
-
$start = strlen($plaintext);
|
783 |
-
$block = $this->decryptIV;
|
784 |
-
} else {
|
785 |
-
$plaintext = '';
|
786 |
-
$xor = $des[0]->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
|
787 |
-
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
788 |
-
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
789 |
-
$start = 0;
|
790 |
-
}
|
791 |
-
|
792 |
-
for ($i = $start; $i < strlen($ciphertext); $i+=8) {
|
793 |
-
$block = substr($ciphertext, $i, 8);
|
794 |
-
$plaintext.= $block ^ $xor;
|
795 |
-
if ($continuousBuffer && strlen($block) != 8) {
|
796 |
-
$buffer['ciphertext'].= $block;
|
797 |
-
$block = $xor;
|
798 |
-
} else if (strlen($block) == 8) {
|
799 |
-
$xor = $des[0]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
800 |
-
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
801 |
-
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
802 |
-
}
|
803 |
-
}
|
804 |
-
if ($this->continuousBuffer) {
|
805 |
-
$this->decryptIV = $block;
|
806 |
-
}
|
807 |
-
break;
|
808 |
-
case CRYPT_DES_MODE_OFB:
|
809 |
-
$xor = $this->decryptIV;
|
810 |
-
if (strlen($buffer)) {
|
811 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
812 |
-
$xor = $des[0]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
813 |
-
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
814 |
-
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
815 |
-
$buffer.= $xor;
|
816 |
-
$key = $this->_string_shift($buffer, 8);
|
817 |
-
$plaintext.= substr($ciphertext, $i, 8) ^ $key;
|
818 |
-
}
|
819 |
-
} else {
|
820 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
821 |
-
$xor = $des[0]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
822 |
-
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
823 |
-
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
824 |
-
$plaintext.= substr($ciphertext, $i, 8) ^ $xor;
|
825 |
-
}
|
826 |
-
$key = $xor;
|
827 |
-
}
|
828 |
-
if ($this->continuousBuffer) {
|
829 |
-
$this->decryptIV = $xor;
|
830 |
-
if ($start = strlen($ciphertext) & 7) {
|
831 |
-
$buffer = substr($key, $start) . $buffer;
|
832 |
-
}
|
833 |
-
}
|
834 |
-
}
|
835 |
-
|
836 |
-
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
837 |
-
}
|
838 |
-
|
839 |
-
/**
|
840 |
-
* Treat consecutive "packets" as if they are a continuous buffer.
|
841 |
-
*
|
842 |
-
* Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
|
843 |
-
* will yield different outputs:
|
844 |
-
*
|
845 |
-
* <code>
|
846 |
-
* echo $des->encrypt(substr($plaintext, 0, 8));
|
847 |
-
* echo $des->encrypt(substr($plaintext, 8, 8));
|
848 |
-
* </code>
|
849 |
-
* <code>
|
850 |
-
* echo $des->encrypt($plaintext);
|
851 |
-
* </code>
|
852 |
-
*
|
853 |
-
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
|
854 |
-
* another, as demonstrated with the following:
|
855 |
-
*
|
856 |
-
* <code>
|
857 |
-
* $des->encrypt(substr($plaintext, 0, 8));
|
858 |
-
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
859 |
-
* </code>
|
860 |
-
* <code>
|
861 |
-
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
862 |
-
* </code>
|
863 |
-
*
|
864 |
-
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
|
865 |
-
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
866 |
-
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
867 |
-
*
|
868 |
-
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
|
869 |
-
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
870 |
-
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
871 |
-
* however, they are also less intuitive and more likely to cause you problems.
|
872 |
-
*
|
873 |
-
* @see Crypt_TripleDES::disableContinuousBuffer()
|
874 |
-
* @access public
|
875 |
-
*/
|
876 |
-
function enableContinuousBuffer()
|
877 |
-
{
|
878 |
-
$this->continuousBuffer = true;
|
879 |
-
if ($this->mode == CRYPT_DES_MODE_3CBC) {
|
880 |
-
$this->des[0]->enableContinuousBuffer();
|
881 |
-
$this->des[1]->enableContinuousBuffer();
|
882 |
-
$this->des[2]->enableContinuousBuffer();
|
883 |
-
}
|
884 |
-
}
|
885 |
-
|
886 |
-
/**
|
887 |
-
* Treat consecutive packets as if they are a discontinuous buffer.
|
888 |
-
*
|
889 |
-
* The default behavior.
|
890 |
-
*
|
891 |
-
* @see Crypt_TripleDES::enableContinuousBuffer()
|
892 |
-
* @access public
|
893 |
-
*/
|
894 |
-
function disableContinuousBuffer()
|
895 |
-
{
|
896 |
-
$this->continuousBuffer = false;
|
897 |
-
$this->encryptIV = $this->iv;
|
898 |
-
$this->decryptIV = $this->iv;
|
899 |
-
|
900 |
-
if ($this->mode == CRYPT_DES_MODE_3CBC) {
|
901 |
-
$this->des[0]->disableContinuousBuffer();
|
902 |
-
$this->des[1]->disableContinuousBuffer();
|
903 |
-
$this->des[2]->disableContinuousBuffer();
|
904 |
-
}
|
905 |
-
}
|
906 |
-
|
907 |
-
/**
|
908 |
-
* Pad "packets".
|
909 |
-
*
|
910 |
-
* DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
|
911 |
-
* a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
|
912 |
-
*
|
913 |
-
* Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
|
914 |
-
* where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
|
915 |
-
* away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
|
916 |
-
* transmitted separately)
|
917 |
-
*
|
918 |
-
* @see Crypt_TripleDES::disablePadding()
|
919 |
-
* @access public
|
920 |
-
*/
|
921 |
-
function enablePadding()
|
922 |
-
{
|
923 |
-
$this->padding = true;
|
924 |
-
}
|
925 |
-
|
926 |
-
/**
|
927 |
-
* Do not pad packets.
|
928 |
-
*
|
929 |
-
* @see Crypt_TripleDES::enablePadding()
|
930 |
-
* @access public
|
931 |
-
*/
|
932 |
-
function disablePadding()
|
933 |
-
{
|
934 |
-
$this->padding = false;
|
935 |
-
}
|
936 |
-
|
937 |
-
/**
|
938 |
-
* Pads a string
|
939 |
-
*
|
940 |
-
* Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
|
941 |
-
* 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
|
942 |
-
*
|
943 |
-
* If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
|
944 |
-
* and padding will, hence forth, be enabled.
|
945 |
-
*
|
946 |
-
* @see Crypt_TripleDES::_unpad()
|
947 |
-
* @access private
|
948 |
-
*/
|
949 |
-
function _pad($text)
|
950 |
-
{
|
951 |
-
$length = strlen($text);
|
952 |
-
|
953 |
-
if (!$this->padding) {
|
954 |
-
if (($length & 7) == 0) {
|
955 |
-
return $text;
|
956 |
-
} else {
|
957 |
-
user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
|
958 |
-
$this->padding = true;
|
959 |
-
}
|
960 |
-
}
|
961 |
-
|
962 |
-
$pad = 8 - ($length & 7);
|
963 |
-
return str_pad($text, $length + $pad, chr($pad));
|
964 |
-
}
|
965 |
-
|
966 |
-
/**
|
967 |
-
* Unpads a string
|
968 |
-
*
|
969 |
-
* If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
|
970 |
-
* and false will be returned.
|
971 |
-
*
|
972 |
-
* @see Crypt_TripleDES::_pad()
|
973 |
-
* @access private
|
974 |
-
*/
|
975 |
-
function _unpad($text)
|
976 |
-
{
|
977 |
-
if (!$this->padding) {
|
978 |
-
return $text;
|
979 |
-
}
|
980 |
-
|
981 |
-
$length = ord($text[strlen($text) - 1]);
|
982 |
-
|
983 |
-
if (!$length || $length > 8) {
|
984 |
-
return false;
|
985 |
-
}
|
986 |
-
|
987 |
-
return substr($text, 0, -$length);
|
988 |
-
}
|
989 |
-
|
990 |
-
/**
|
991 |
-
* String Shift
|
992 |
-
*
|
993 |
-
* Inspired by array_shift
|
994 |
-
*
|
995 |
-
* @param String $string
|
996 |
-
* @param optional Integer $index
|
997 |
-
* @return String
|
998 |
-
* @access private
|
999 |
-
*/
|
1000 |
-
function _string_shift(&$string, $index = 1)
|
1001 |
-
{
|
1002 |
-
$substr = substr($string, 0, $index);
|
1003 |
-
$string = substr($string, $index);
|
1004 |
-
return $substr;
|
1005 |
-
}
|
1006 |
-
}
|
1007 |
-
|
1008 |
-
// vim: ts=4:sw=4:et:
|
1009 |
-
// vim6: fdl=1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Math/BigInteger.php
DELETED
@@ -1,3551 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP arbitrary precision integer arithmetic library.
|
6 |
-
*
|
7 |
-
* Supports base-2, base-10, base-16, and base-256 numbers. Uses the GMP or BCMath extensions, if available,
|
8 |
-
* and an internal implementation, otherwise.
|
9 |
-
*
|
10 |
-
* PHP versions 4 and 5
|
11 |
-
*
|
12 |
-
* {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the
|
13 |
-
* {@link MATH_BIGINTEGER_MODE_INTERNAL MATH_BIGINTEGER_MODE_INTERNAL} mode)
|
14 |
-
*
|
15 |
-
* Math_BigInteger uses base-2**26 to perform operations such as multiplication and division and
|
16 |
-
* base-2**52 (ie. two base 2**26 digits) to perform addition and subtraction. Because the largest possible
|
17 |
-
* value when multiplying two base-2**26 numbers together is a base-2**52 number, double precision floating
|
18 |
-
* point numbers - numbers that should be supported on most hardware and whose significand is 53 bits - are
|
19 |
-
* used. As a consequence, bitwise operators such as >> and << cannot be used, nor can the modulo operator %,
|
20 |
-
* which only supports integers. Although this fact will slow this library down, the fact that such a high
|
21 |
-
* base is being used should more than compensate.
|
22 |
-
*
|
23 |
-
* When PHP version 6 is officially released, we'll be able to use 64-bit integers. This should, once again,
|
24 |
-
* allow bitwise operators, and will increase the maximum possible base to 2**31 (or 2**62 for addition /
|
25 |
-
* subtraction).
|
26 |
-
*
|
27 |
-
* Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format. ie.
|
28 |
-
* (new Math_BigInteger(pow(2, 26)))->value = array(0, 1)
|
29 |
-
*
|
30 |
-
* Useful resources are as follows:
|
31 |
-
*
|
32 |
-
* - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)}
|
33 |
-
* - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)}
|
34 |
-
* - Java's BigInteger classes. See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip
|
35 |
-
*
|
36 |
-
* Here's an example of how to use this library:
|
37 |
-
* <code>
|
38 |
-
* <?php
|
39 |
-
* include('Math/BigInteger.php');
|
40 |
-
*
|
41 |
-
* $a = new Math_BigInteger(2);
|
42 |
-
* $b = new Math_BigInteger(3);
|
43 |
-
*
|
44 |
-
* $c = $a->add($b);
|
45 |
-
*
|
46 |
-
* echo $c->toString(); // outputs 5
|
47 |
-
* ?>
|
48 |
-
* </code>
|
49 |
-
*
|
50 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
51 |
-
* of this software and associated documentation files (the "Software"), to deal
|
52 |
-
* in the Software without restriction, including without limitation the rights
|
53 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
54 |
-
* copies of the Software, and to permit persons to whom the Software is
|
55 |
-
* furnished to do so, subject to the following conditions:
|
56 |
-
*
|
57 |
-
* The above copyright notice and this permission notice shall be included in
|
58 |
-
* all copies or substantial portions of the Software.
|
59 |
-
*
|
60 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
61 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
62 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
63 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
64 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
65 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
66 |
-
* THE SOFTWARE.
|
67 |
-
*
|
68 |
-
* @category Math
|
69 |
-
* @package Math_BigInteger
|
70 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
71 |
-
* @copyright MMVI Jim Wigginton
|
72 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
73 |
-
* @version $Id: BigInteger.php,v 1.33 2010/03/22 22:32:03 terrafrost Exp $
|
74 |
-
* @link http://pear.php.net/package/Math_BigInteger
|
75 |
-
*/
|
76 |
-
|
77 |
-
/**#@+
|
78 |
-
* Reduction constants
|
79 |
-
*
|
80 |
-
* @access private
|
81 |
-
* @see Math_BigInteger::_reduce()
|
82 |
-
*/
|
83 |
-
/**
|
84 |
-
* @see Math_BigInteger::_montgomery()
|
85 |
-
* @see Math_BigInteger::_prepMontgomery()
|
86 |
-
*/
|
87 |
-
define('MATH_BIGINTEGER_MONTGOMERY', 0);
|
88 |
-
/**
|
89 |
-
* @see Math_BigInteger::_barrett()
|
90 |
-
*/
|
91 |
-
define('MATH_BIGINTEGER_BARRETT', 1);
|
92 |
-
/**
|
93 |
-
* @see Math_BigInteger::_mod2()
|
94 |
-
*/
|
95 |
-
define('MATH_BIGINTEGER_POWEROF2', 2);
|
96 |
-
/**
|
97 |
-
* @see Math_BigInteger::_remainder()
|
98 |
-
*/
|
99 |
-
define('MATH_BIGINTEGER_CLASSIC', 3);
|
100 |
-
/**
|
101 |
-
* @see Math_BigInteger::__clone()
|
102 |
-
*/
|
103 |
-
define('MATH_BIGINTEGER_NONE', 4);
|
104 |
-
/**#@-*/
|
105 |
-
|
106 |
-
/**#@+
|
107 |
-
* Array constants
|
108 |
-
*
|
109 |
-
* Rather than create a thousands and thousands of new Math_BigInteger objects in repeated function calls to add() and
|
110 |
-
* multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them.
|
111 |
-
*
|
112 |
-
* @access private
|
113 |
-
*/
|
114 |
-
/**
|
115 |
-
* $result[MATH_BIGINTEGER_VALUE] contains the value.
|
116 |
-
*/
|
117 |
-
define('MATH_BIGINTEGER_VALUE', 0);
|
118 |
-
/**
|
119 |
-
* $result[MATH_BIGINTEGER_SIGN] contains the sign.
|
120 |
-
*/
|
121 |
-
define('MATH_BIGINTEGER_SIGN', 1);
|
122 |
-
/**#@-*/
|
123 |
-
|
124 |
-
/**#@+
|
125 |
-
* @access private
|
126 |
-
* @see Math_BigInteger::_montgomery()
|
127 |
-
* @see Math_BigInteger::_barrett()
|
128 |
-
*/
|
129 |
-
/**
|
130 |
-
* Cache constants
|
131 |
-
*
|
132 |
-
* $cache[MATH_BIGINTEGER_VARIABLE] tells us whether or not the cached data is still valid.
|
133 |
-
*/
|
134 |
-
define('MATH_BIGINTEGER_VARIABLE', 0);
|
135 |
-
/**
|
136 |
-
* $cache[MATH_BIGINTEGER_DATA] contains the cached data.
|
137 |
-
*/
|
138 |
-
define('MATH_BIGINTEGER_DATA', 1);
|
139 |
-
/**#@-*/
|
140 |
-
|
141 |
-
/**#@+
|
142 |
-
* Mode constants.
|
143 |
-
*
|
144 |
-
* @access private
|
145 |
-
* @see Math_BigInteger::Math_BigInteger()
|
146 |
-
*/
|
147 |
-
/**
|
148 |
-
* To use the pure-PHP implementation
|
149 |
-
*/
|
150 |
-
define('MATH_BIGINTEGER_MODE_INTERNAL', 1);
|
151 |
-
/**
|
152 |
-
* To use the BCMath library
|
153 |
-
*
|
154 |
-
* (if enabled; otherwise, the internal implementation will be used)
|
155 |
-
*/
|
156 |
-
define('MATH_BIGINTEGER_MODE_BCMATH', 2);
|
157 |
-
/**
|
158 |
-
* To use the GMP library
|
159 |
-
*
|
160 |
-
* (if present; otherwise, either the BCMath or the internal implementation will be used)
|
161 |
-
*/
|
162 |
-
define('MATH_BIGINTEGER_MODE_GMP', 3);
|
163 |
-
/**#@-*/
|
164 |
-
|
165 |
-
/**
|
166 |
-
* The largest digit that may be used in addition / subtraction
|
167 |
-
*
|
168 |
-
* (we do pow(2, 52) instead of using 4503599627370496, directly, because some PHP installations
|
169 |
-
* will truncate 4503599627370496)
|
170 |
-
*
|
171 |
-
* @access private
|
172 |
-
*/
|
173 |
-
define('MATH_BIGINTEGER_MAX_DIGIT52', pow(2, 52));
|
174 |
-
|
175 |
-
/**
|
176 |
-
* Karatsuba Cutoff
|
177 |
-
*
|
178 |
-
* At what point do we switch between Karatsuba multiplication and schoolbook long multiplication?
|
179 |
-
*
|
180 |
-
* @access private
|
181 |
-
*/
|
182 |
-
define('MATH_BIGINTEGER_KARATSUBA_CUTOFF', 25);
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256
|
186 |
-
* numbers.
|
187 |
-
*
|
188 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
189 |
-
* @version 1.0.0RC4
|
190 |
-
* @access public
|
191 |
-
* @package Math_BigInteger
|
192 |
-
*/
|
193 |
-
class Math_BigInteger {
|
194 |
-
/**
|
195 |
-
* Holds the BigInteger's value.
|
196 |
-
*
|
197 |
-
* @var Array
|
198 |
-
* @access private
|
199 |
-
*/
|
200 |
-
var $value;
|
201 |
-
|
202 |
-
/**
|
203 |
-
* Holds the BigInteger's magnitude.
|
204 |
-
*
|
205 |
-
* @var Boolean
|
206 |
-
* @access private
|
207 |
-
*/
|
208 |
-
var $is_negative = false;
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Random number generator function
|
212 |
-
*
|
213 |
-
* @see setRandomGenerator()
|
214 |
-
* @access private
|
215 |
-
*/
|
216 |
-
var $generator = 'mt_rand';
|
217 |
-
|
218 |
-
/**
|
219 |
-
* Precision
|
220 |
-
*
|
221 |
-
* @see setPrecision()
|
222 |
-
* @access private
|
223 |
-
*/
|
224 |
-
var $precision = -1;
|
225 |
-
|
226 |
-
/**
|
227 |
-
* Precision Bitmask
|
228 |
-
*
|
229 |
-
* @see setPrecision()
|
230 |
-
* @access private
|
231 |
-
*/
|
232 |
-
var $bitmask = false;
|
233 |
-
|
234 |
-
/**
|
235 |
-
* Mode independant value used for serialization.
|
236 |
-
*
|
237 |
-
* If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for
|
238 |
-
* a variable that'll be serializable regardless of whether or not extensions are being used. Unlike $this->value,
|
239 |
-
* however, $this->hex is only calculated when $this->__sleep() is called.
|
240 |
-
*
|
241 |
-
* @see __sleep()
|
242 |
-
* @see __wakeup()
|
243 |
-
* @var String
|
244 |
-
* @access private
|
245 |
-
*/
|
246 |
-
var $hex;
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Converts base-2, base-10, base-16, and binary strings (eg. base-256) to BigIntegers.
|
250 |
-
*
|
251 |
-
* If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
|
252 |
-
* two's compliment. The sole exception to this is -10, which is treated the same as 10 is.
|
253 |
-
*
|
254 |
-
* Here's an example:
|
255 |
-
* <code>
|
256 |
-
* <?php
|
257 |
-
* include('Math/BigInteger.php');
|
258 |
-
*
|
259 |
-
* $a = new Math_BigInteger('0x32', 16); // 50 in base-16
|
260 |
-
*
|
261 |
-
* echo $a->toString(); // outputs 50
|
262 |
-
* ?>
|
263 |
-
* </code>
|
264 |
-
*
|
265 |
-
* @param optional $x base-10 number or base-$base number if $base set.
|
266 |
-
* @param optional integer $base
|
267 |
-
* @return Math_BigInteger
|
268 |
-
* @access public
|
269 |
-
*/
|
270 |
-
function Math_BigInteger($x = 0, $base = 10)
|
271 |
-
{
|
272 |
-
if ( !defined('MATH_BIGINTEGER_MODE') ) {
|
273 |
-
switch (true) {
|
274 |
-
case extension_loaded('gmp'):
|
275 |
-
define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_GMP);
|
276 |
-
break;
|
277 |
-
case extension_loaded('bcmath'):
|
278 |
-
define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_BCMATH);
|
279 |
-
break;
|
280 |
-
default:
|
281 |
-
define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_INTERNAL);
|
282 |
-
}
|
283 |
-
}
|
284 |
-
|
285 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
286 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
287 |
-
if (is_resource($x) && get_resource_type($x) == 'GMP integer') {
|
288 |
-
$this->value = $x;
|
289 |
-
return;
|
290 |
-
}
|
291 |
-
$this->value = gmp_init(0);
|
292 |
-
break;
|
293 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
294 |
-
$this->value = '0';
|
295 |
-
break;
|
296 |
-
default:
|
297 |
-
$this->value = array();
|
298 |
-
}
|
299 |
-
|
300 |
-
if (empty($x)) {
|
301 |
-
return;
|
302 |
-
}
|
303 |
-
|
304 |
-
switch ($base) {
|
305 |
-
case -256:
|
306 |
-
if (ord($x[0]) & 0x80) {
|
307 |
-
$x = ~$x;
|
308 |
-
$this->is_negative = true;
|
309 |
-
}
|
310 |
-
case 256:
|
311 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
312 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
313 |
-
$sign = $this->is_negative ? '-' : '';
|
314 |
-
$this->value = gmp_init($sign . '0x' . bin2hex($x));
|
315 |
-
break;
|
316 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
317 |
-
// round $len to the nearest 4 (thanks, DavidMJ!)
|
318 |
-
$len = (strlen($x) + 3) & 0xFFFFFFFC;
|
319 |
-
|
320 |
-
$x = str_pad($x, $len, chr(0), STR_PAD_LEFT);
|
321 |
-
|
322 |
-
for ($i = 0; $i < $len; $i+= 4) {
|
323 |
-
$this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32
|
324 |
-
$this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0);
|
325 |
-
}
|
326 |
-
|
327 |
-
if ($this->is_negative) {
|
328 |
-
$this->value = '-' . $this->value;
|
329 |
-
}
|
330 |
-
|
331 |
-
break;
|
332 |
-
// converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb)
|
333 |
-
default:
|
334 |
-
while (strlen($x)) {
|
335 |
-
$this->value[] = $this->_bytes2int($this->_base256_rshift($x, 26));
|
336 |
-
}
|
337 |
-
}
|
338 |
-
|
339 |
-
if ($this->is_negative) {
|
340 |
-
if (MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL) {
|
341 |
-
$this->is_negative = false;
|
342 |
-
}
|
343 |
-
$temp = $this->add(new Math_BigInteger('-1'));
|
344 |
-
$this->value = $temp->value;
|
345 |
-
}
|
346 |
-
break;
|
347 |
-
case 16:
|
348 |
-
case -16:
|
349 |
-
if ($base > 0 && $x[0] == '-') {
|
350 |
-
$this->is_negative = true;
|
351 |
-
$x = substr($x, 1);
|
352 |
-
}
|
353 |
-
|
354 |
-
$x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x);
|
355 |
-
|
356 |
-
$is_negative = false;
|
357 |
-
if ($base < 0 && hexdec($x[0]) >= 8) {
|
358 |
-
$this->is_negative = $is_negative = true;
|
359 |
-
$x = bin2hex(~pack('H*', $x));
|
360 |
-
}
|
361 |
-
|
362 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
363 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
364 |
-
$temp = $this->is_negative ? '-0x' . $x : '0x' . $x;
|
365 |
-
$this->value = gmp_init($temp);
|
366 |
-
$this->is_negative = false;
|
367 |
-
break;
|
368 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
369 |
-
$x = ( strlen($x) & 1 ) ? '0' . $x : $x;
|
370 |
-
$temp = new Math_BigInteger(pack('H*', $x), 256);
|
371 |
-
$this->value = $this->is_negative ? '-' . $temp->value : $temp->value;
|
372 |
-
$this->is_negative = false;
|
373 |
-
break;
|
374 |
-
default:
|
375 |
-
$x = ( strlen($x) & 1 ) ? '0' . $x : $x;
|
376 |
-
$temp = new Math_BigInteger(pack('H*', $x), 256);
|
377 |
-
$this->value = $temp->value;
|
378 |
-
}
|
379 |
-
|
380 |
-
if ($is_negative) {
|
381 |
-
$temp = $this->add(new Math_BigInteger('-1'));
|
382 |
-
$this->value = $temp->value;
|
383 |
-
}
|
384 |
-
break;
|
385 |
-
case 10:
|
386 |
-
case -10:
|
387 |
-
$x = preg_replace('#^(-?[0-9]*).*#', '$1', $x);
|
388 |
-
|
389 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
390 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
391 |
-
$this->value = gmp_init($x);
|
392 |
-
break;
|
393 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
394 |
-
// explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different
|
395 |
-
// results then doing it on '-1' does (modInverse does $x[0])
|
396 |
-
$this->value = (string) $x;
|
397 |
-
break;
|
398 |
-
default:
|
399 |
-
$temp = new Math_BigInteger();
|
400 |
-
|
401 |
-
// array(10000000) is 10**7 in base-2**26. 10**7 is the closest to 2**26 we can get without passing it.
|
402 |
-
$multiplier = new Math_BigInteger();
|
403 |
-
$multiplier->value = array(10000000);
|
404 |
-
|
405 |
-
if ($x[0] == '-') {
|
406 |
-
$this->is_negative = true;
|
407 |
-
$x = substr($x, 1);
|
408 |
-
}
|
409 |
-
|
410 |
-
$x = str_pad($x, strlen($x) + (6 * strlen($x)) % 7, 0, STR_PAD_LEFT);
|
411 |
-
|
412 |
-
while (strlen($x)) {
|
413 |
-
$temp = $temp->multiply($multiplier);
|
414 |
-
$temp = $temp->add(new Math_BigInteger($this->_int2bytes(substr($x, 0, 7)), 256));
|
415 |
-
$x = substr($x, 7);
|
416 |
-
}
|
417 |
-
|
418 |
-
$this->value = $temp->value;
|
419 |
-
}
|
420 |
-
break;
|
421 |
-
case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
|
422 |
-
case -2:
|
423 |
-
if ($base > 0 && $x[0] == '-') {
|
424 |
-
$this->is_negative = true;
|
425 |
-
$x = substr($x, 1);
|
426 |
-
}
|
427 |
-
|
428 |
-
$x = preg_replace('#^([01]*).*#', '$1', $x);
|
429 |
-
$x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT);
|
430 |
-
|
431 |
-
$str = '0x';
|
432 |
-
while (strlen($x)) {
|
433 |
-
$part = substr($x, 0, 4);
|
434 |
-
$str.= dechex(bindec($part));
|
435 |
-
$x = substr($x, 4);
|
436 |
-
}
|
437 |
-
|
438 |
-
if ($this->is_negative) {
|
439 |
-
$str = '-' . $str;
|
440 |
-
}
|
441 |
-
|
442 |
-
$temp = new Math_BigInteger($str, 8 * $base); // ie. either -16 or +16
|
443 |
-
$this->value = $temp->value;
|
444 |
-
$this->is_negative = $temp->is_negative;
|
445 |
-
|
446 |
-
break;
|
447 |
-
default:
|
448 |
-
// base not supported, so we'll let $this == 0
|
449 |
-
}
|
450 |
-
}
|
451 |
-
|
452 |
-
/**
|
453 |
-
* Converts a BigInteger to a byte string (eg. base-256).
|
454 |
-
*
|
455 |
-
* Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
|
456 |
-
* saved as two's compliment.
|
457 |
-
*
|
458 |
-
* Here's an example:
|
459 |
-
* <code>
|
460 |
-
* <?php
|
461 |
-
* include('Math/BigInteger.php');
|
462 |
-
*
|
463 |
-
* $a = new Math_BigInteger('65');
|
464 |
-
*
|
465 |
-
* echo $a->toBytes(); // outputs chr(65)
|
466 |
-
* ?>
|
467 |
-
* </code>
|
468 |
-
*
|
469 |
-
* @param Boolean $twos_compliment
|
470 |
-
* @return String
|
471 |
-
* @access public
|
472 |
-
* @internal Converts a base-2**26 number to base-2**8
|
473 |
-
*/
|
474 |
-
function toBytes($twos_compliment = false)
|
475 |
-
{
|
476 |
-
if ($twos_compliment) {
|
477 |
-
$comparison = $this->compare(new Math_BigInteger());
|
478 |
-
if ($comparison == 0) {
|
479 |
-
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
|
480 |
-
}
|
481 |
-
|
482 |
-
$temp = $comparison < 0 ? $this->add(new Math_BigInteger(1)) : $this->copy();
|
483 |
-
$bytes = $temp->toBytes();
|
484 |
-
|
485 |
-
if (empty($bytes)) { // eg. if the number we're trying to convert is -1
|
486 |
-
$bytes = chr(0);
|
487 |
-
}
|
488 |
-
|
489 |
-
if (ord($bytes[0]) & 0x80) {
|
490 |
-
$bytes = chr(0) . $bytes;
|
491 |
-
}
|
492 |
-
|
493 |
-
return $comparison < 0 ? ~$bytes : $bytes;
|
494 |
-
}
|
495 |
-
|
496 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
497 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
498 |
-
if (gmp_cmp($this->value, gmp_init(0)) == 0) {
|
499 |
-
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
|
500 |
-
}
|
501 |
-
|
502 |
-
$temp = gmp_strval(gmp_abs($this->value), 16);
|
503 |
-
$temp = ( strlen($temp) & 1 ) ? '0' . $temp : $temp;
|
504 |
-
$temp = pack('H*', $temp);
|
505 |
-
|
506 |
-
return $this->precision > 0 ?
|
507 |
-
substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
|
508 |
-
ltrim($temp, chr(0));
|
509 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
510 |
-
if ($this->value === '0') {
|
511 |
-
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
|
512 |
-
}
|
513 |
-
|
514 |
-
$value = '';
|
515 |
-
$current = $this->value;
|
516 |
-
|
517 |
-
if ($current[0] == '-') {
|
518 |
-
$current = substr($current, 1);
|
519 |
-
}
|
520 |
-
|
521 |
-
while (bccomp($current, '0', 0) > 0) {
|
522 |
-
$temp = bcmod($current, '16777216');
|
523 |
-
$value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value;
|
524 |
-
$current = bcdiv($current, '16777216', 0);
|
525 |
-
}
|
526 |
-
|
527 |
-
return $this->precision > 0 ?
|
528 |
-
substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
|
529 |
-
ltrim($value, chr(0));
|
530 |
-
}
|
531 |
-
|
532 |
-
if (!count($this->value)) {
|
533 |
-
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
|
534 |
-
}
|
535 |
-
$result = $this->_int2bytes($this->value[count($this->value) - 1]);
|
536 |
-
|
537 |
-
$temp = $this->copy();
|
538 |
-
|
539 |
-
for ($i = count($temp->value) - 2; $i >= 0; --$i) {
|
540 |
-
$temp->_base256_lshift($result, 26);
|
541 |
-
$result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT);
|
542 |
-
}
|
543 |
-
|
544 |
-
return $this->precision > 0 ?
|
545 |
-
str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) :
|
546 |
-
$result;
|
547 |
-
}
|
548 |
-
|
549 |
-
/**
|
550 |
-
* Converts a BigInteger to a hex string (eg. base-16)).
|
551 |
-
*
|
552 |
-
* Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
|
553 |
-
* saved as two's compliment.
|
554 |
-
*
|
555 |
-
* Here's an example:
|
556 |
-
* <code>
|
557 |
-
* <?php
|
558 |
-
* include('Math/BigInteger.php');
|
559 |
-
*
|
560 |
-
* $a = new Math_BigInteger('65');
|
561 |
-
*
|
562 |
-
* echo $a->toHex(); // outputs '41'
|
563 |
-
* ?>
|
564 |
-
* </code>
|
565 |
-
*
|
566 |
-
* @param Boolean $twos_compliment
|
567 |
-
* @return String
|
568 |
-
* @access public
|
569 |
-
* @internal Converts a base-2**26 number to base-2**8
|
570 |
-
*/
|
571 |
-
function toHex($twos_compliment = false)
|
572 |
-
{
|
573 |
-
return bin2hex($this->toBytes($twos_compliment));
|
574 |
-
}
|
575 |
-
|
576 |
-
/**
|
577 |
-
* Converts a BigInteger to a bit string (eg. base-2).
|
578 |
-
*
|
579 |
-
* Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
|
580 |
-
* saved as two's compliment.
|
581 |
-
*
|
582 |
-
* Here's an example:
|
583 |
-
* <code>
|
584 |
-
* <?php
|
585 |
-
* include('Math/BigInteger.php');
|
586 |
-
*
|
587 |
-
* $a = new Math_BigInteger('65');
|
588 |
-
*
|
589 |
-
* echo $a->toBits(); // outputs '1000001'
|
590 |
-
* ?>
|
591 |
-
* </code>
|
592 |
-
*
|
593 |
-
* @param Boolean $twos_compliment
|
594 |
-
* @return String
|
595 |
-
* @access public
|
596 |
-
* @internal Converts a base-2**26 number to base-2**2
|
597 |
-
*/
|
598 |
-
function toBits($twos_compliment = false)
|
599 |
-
{
|
600 |
-
$hex = $this->toHex($twos_compliment);
|
601 |
-
$bits = '';
|
602 |
-
for ($i = 0, $end = strlen($hex) & 0xFFFFFFF8; $i < $end; $i+=8) {
|
603 |
-
$bits.= str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT);
|
604 |
-
}
|
605 |
-
if ($end != strlen($hex)) { // hexdec('') == 0
|
606 |
-
$bits.= str_pad(decbin(hexdec(substr($hex, $end))), strlen($hex) & 7, '0', STR_PAD_LEFT);
|
607 |
-
}
|
608 |
-
return $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0');
|
609 |
-
}
|
610 |
-
|
611 |
-
/**
|
612 |
-
* Converts a BigInteger to a base-10 number.
|
613 |
-
*
|
614 |
-
* Here's an example:
|
615 |
-
* <code>
|
616 |
-
* <?php
|
617 |
-
* include('Math/BigInteger.php');
|
618 |
-
*
|
619 |
-
* $a = new Math_BigInteger('50');
|
620 |
-
*
|
621 |
-
* echo $a->toString(); // outputs 50
|
622 |
-
* ?>
|
623 |
-
* </code>
|
624 |
-
*
|
625 |
-
* @return String
|
626 |
-
* @access public
|
627 |
-
* @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10)
|
628 |
-
*/
|
629 |
-
function toString()
|
630 |
-
{
|
631 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
632 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
633 |
-
return gmp_strval($this->value);
|
634 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
635 |
-
if ($this->value === '0') {
|
636 |
-
return '0';
|
637 |
-
}
|
638 |
-
|
639 |
-
return ltrim($this->value, '0');
|
640 |
-
}
|
641 |
-
|
642 |
-
if (!count($this->value)) {
|
643 |
-
return '0';
|
644 |
-
}
|
645 |
-
|
646 |
-
$temp = $this->copy();
|
647 |
-
$temp->is_negative = false;
|
648 |
-
|
649 |
-
$divisor = new Math_BigInteger();
|
650 |
-
$divisor->value = array(10000000); // eg. 10**7
|
651 |
-
$result = '';
|
652 |
-
while (count($temp->value)) {
|
653 |
-
list($temp, $mod) = $temp->divide($divisor);
|
654 |
-
$result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', 7, '0', STR_PAD_LEFT) . $result;
|
655 |
-
}
|
656 |
-
$result = ltrim($result, '0');
|
657 |
-
if (empty($result)) {
|
658 |
-
$result = '0';
|
659 |
-
}
|
660 |
-
|
661 |
-
if ($this->is_negative) {
|
662 |
-
$result = '-' . $result;
|
663 |
-
}
|
664 |
-
|
665 |
-
return $result;
|
666 |
-
}
|
667 |
-
|
668 |
-
/**
|
669 |
-
* Copy an object
|
670 |
-
*
|
671 |
-
* PHP5 passes objects by reference while PHP4 passes by value. As such, we need a function to guarantee
|
672 |
-
* that all objects are passed by value, when appropriate. More information can be found here:
|
673 |
-
*
|
674 |
-
* {@link http://php.net/language.oop5.basic#51624}
|
675 |
-
*
|
676 |
-
* @access public
|
677 |
-
* @see __clone()
|
678 |
-
* @return Math_BigInteger
|
679 |
-
*/
|
680 |
-
function copy()
|
681 |
-
{
|
682 |
-
$temp = new Math_BigInteger();
|
683 |
-
$temp->value = $this->value;
|
684 |
-
$temp->is_negative = $this->is_negative;
|
685 |
-
$temp->generator = $this->generator;
|
686 |
-
$temp->precision = $this->precision;
|
687 |
-
$temp->bitmask = $this->bitmask;
|
688 |
-
return $temp;
|
689 |
-
}
|
690 |
-
|
691 |
-
/**
|
692 |
-
* __toString() magic method
|
693 |
-
*
|
694 |
-
* Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call
|
695 |
-
* toString().
|
696 |
-
*
|
697 |
-
* @access public
|
698 |
-
* @internal Implemented per a suggestion by Techie-Michael - thanks!
|
699 |
-
*/
|
700 |
-
function __toString()
|
701 |
-
{
|
702 |
-
return $this->toString();
|
703 |
-
}
|
704 |
-
|
705 |
-
/**
|
706 |
-
* __clone() magic method
|
707 |
-
*
|
708 |
-
* Although you can call Math_BigInteger::__toString() directly in PHP5, you cannot call Math_BigInteger::__clone()
|
709 |
-
* directly in PHP5. You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5
|
710 |
-
* only syntax of $y = clone $x. As such, if you're trying to write an application that works on both PHP4 and PHP5,
|
711 |
-
* call Math_BigInteger::copy(), instead.
|
712 |
-
*
|
713 |
-
* @access public
|
714 |
-
* @see copy()
|
715 |
-
* @return Math_BigInteger
|
716 |
-
*/
|
717 |
-
function __clone()
|
718 |
-
{
|
719 |
-
return $this->copy();
|
720 |
-
}
|
721 |
-
|
722 |
-
/**
|
723 |
-
* __sleep() magic method
|
724 |
-
*
|
725 |
-
* Will be called, automatically, when serialize() is called on a Math_BigInteger object.
|
726 |
-
*
|
727 |
-
* @see __wakeup()
|
728 |
-
* @access public
|
729 |
-
*/
|
730 |
-
function __sleep()
|
731 |
-
{
|
732 |
-
$this->hex = $this->toHex(true);
|
733 |
-
$vars = array('hex');
|
734 |
-
if ($this->generator != 'mt_rand') {
|
735 |
-
$vars[] = 'generator';
|
736 |
-
}
|
737 |
-
if ($this->precision > 0) {
|
738 |
-
$vars[] = 'precision';
|
739 |
-
}
|
740 |
-
return $vars;
|
741 |
-
|
742 |
-
}
|
743 |
-
|
744 |
-
/**
|
745 |
-
* __wakeup() magic method
|
746 |
-
*
|
747 |
-
* Will be called, automatically, when unserialize() is called on a Math_BigInteger object.
|
748 |
-
*
|
749 |
-
* @see __sleep()
|
750 |
-
* @access public
|
751 |
-
*/
|
752 |
-
function __wakeup()
|
753 |
-
{
|
754 |
-
$temp = new Math_BigInteger($this->hex, -16);
|
755 |
-
$this->value = $temp->value;
|
756 |
-
$this->is_negative = $temp->is_negative;
|
757 |
-
$this->setRandomGenerator($this->generator);
|
758 |
-
if ($this->precision > 0) {
|
759 |
-
// recalculate $this->bitmask
|
760 |
-
$this->setPrecision($this->precision);
|
761 |
-
}
|
762 |
-
}
|
763 |
-
|
764 |
-
/**
|
765 |
-
* Adds two BigIntegers.
|
766 |
-
*
|
767 |
-
* Here's an example:
|
768 |
-
* <code>
|
769 |
-
* <?php
|
770 |
-
* include('Math/BigInteger.php');
|
771 |
-
*
|
772 |
-
* $a = new Math_BigInteger('10');
|
773 |
-
* $b = new Math_BigInteger('20');
|
774 |
-
*
|
775 |
-
* $c = $a->add($b);
|
776 |
-
*
|
777 |
-
* echo $c->toString(); // outputs 30
|
778 |
-
* ?>
|
779 |
-
* </code>
|
780 |
-
*
|
781 |
-
* @param Math_BigInteger $y
|
782 |
-
* @return Math_BigInteger
|
783 |
-
* @access public
|
784 |
-
* @internal Performs base-2**52 addition
|
785 |
-
*/
|
786 |
-
function add($y)
|
787 |
-
{
|
788 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
789 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
790 |
-
$temp = new Math_BigInteger();
|
791 |
-
$temp->value = gmp_add($this->value, $y->value);
|
792 |
-
|
793 |
-
return $this->_normalize($temp);
|
794 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
795 |
-
$temp = new Math_BigInteger();
|
796 |
-
$temp->value = bcadd($this->value, $y->value, 0);
|
797 |
-
|
798 |
-
return $this->_normalize($temp);
|
799 |
-
}
|
800 |
-
|
801 |
-
$temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative);
|
802 |
-
|
803 |
-
$result = new Math_BigInteger();
|
804 |
-
$result->value = $temp[MATH_BIGINTEGER_VALUE];
|
805 |
-
$result->is_negative = $temp[MATH_BIGINTEGER_SIGN];
|
806 |
-
|
807 |
-
return $this->_normalize($result);
|
808 |
-
}
|
809 |
-
|
810 |
-
/**
|
811 |
-
* Performs addition.
|
812 |
-
*
|
813 |
-
* @param Array $x_value
|
814 |
-
* @param Boolean $x_negative
|
815 |
-
* @param Array $y_value
|
816 |
-
* @param Boolean $y_negative
|
817 |
-
* @return Array
|
818 |
-
* @access private
|
819 |
-
*/
|
820 |
-
function _add($x_value, $x_negative, $y_value, $y_negative)
|
821 |
-
{
|
822 |
-
$x_size = count($x_value);
|
823 |
-
$y_size = count($y_value);
|
824 |
-
|
825 |
-
if ($x_size == 0) {
|
826 |
-
return array(
|
827 |
-
MATH_BIGINTEGER_VALUE => $y_value,
|
828 |
-
MATH_BIGINTEGER_SIGN => $y_negative
|
829 |
-
);
|
830 |
-
} else if ($y_size == 0) {
|
831 |
-
return array(
|
832 |
-
MATH_BIGINTEGER_VALUE => $x_value,
|
833 |
-
MATH_BIGINTEGER_SIGN => $x_negative
|
834 |
-
);
|
835 |
-
}
|
836 |
-
|
837 |
-
// subtract, if appropriate
|
838 |
-
if ( $x_negative != $y_negative ) {
|
839 |
-
if ( $x_value == $y_value ) {
|
840 |
-
return array(
|
841 |
-
MATH_BIGINTEGER_VALUE => array(),
|
842 |
-
MATH_BIGINTEGER_SIGN => false
|
843 |
-
);
|
844 |
-
}
|
845 |
-
|
846 |
-
$temp = $this->_subtract($x_value, false, $y_value, false);
|
847 |
-
$temp[MATH_BIGINTEGER_SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ?
|
848 |
-
$x_negative : $y_negative;
|
849 |
-
|
850 |
-
return $temp;
|
851 |
-
}
|
852 |
-
|
853 |
-
if ($x_size < $y_size) {
|
854 |
-
$size = $x_size;
|
855 |
-
$value = $y_value;
|
856 |
-
} else {
|
857 |
-
$size = $y_size;
|
858 |
-
$value = $x_value;
|
859 |
-
}
|
860 |
-
|
861 |
-
$value[] = 0; // just in case the carry adds an extra digit
|
862 |
-
|
863 |
-
$carry = 0;
|
864 |
-
for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
|
865 |
-
$sum = $x_value[$j] * 0x4000000 + $x_value[$i] + $y_value[$j] * 0x4000000 + $y_value[$i] + $carry;
|
866 |
-
$carry = $sum >= MATH_BIGINTEGER_MAX_DIGIT52; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
|
867 |
-
$sum = $carry ? $sum - MATH_BIGINTEGER_MAX_DIGIT52 : $sum;
|
868 |
-
|
869 |
-
$temp = (int) ($sum / 0x4000000);
|
870 |
-
|
871 |
-
$value[$i] = (int) ($sum - 0x4000000 * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)
|
872 |
-
$value[$j] = $temp;
|
873 |
-
}
|
874 |
-
|
875 |
-
if ($j == $size) { // ie. if $y_size is odd
|
876 |
-
$sum = $x_value[$i] + $y_value[$i] + $carry;
|
877 |
-
$carry = $sum >= 0x4000000;
|
878 |
-
$value[$i] = $carry ? $sum - 0x4000000 : $sum;
|
879 |
-
++$i; // ie. let $i = $j since we've just done $value[$i]
|
880 |
-
}
|
881 |
-
|
882 |
-
if ($carry) {
|
883 |
-
for (; $value[$i] == 0x3FFFFFF; ++$i) {
|
884 |
-
$value[$i] = 0;
|
885 |
-
}
|
886 |
-
++$value[$i];
|
887 |
-
}
|
888 |
-
|
889 |
-
return array(
|
890 |
-
MATH_BIGINTEGER_VALUE => $this->_trim($value),
|
891 |
-
MATH_BIGINTEGER_SIGN => $x_negative
|
892 |
-
);
|
893 |
-
}
|
894 |
-
|
895 |
-
/**
|
896 |
-
* Subtracts two BigIntegers.
|
897 |
-
*
|
898 |
-
* Here's an example:
|
899 |
-
* <code>
|
900 |
-
* <?php
|
901 |
-
* include('Math/BigInteger.php');
|
902 |
-
*
|
903 |
-
* $a = new Math_BigInteger('10');
|
904 |
-
* $b = new Math_BigInteger('20');
|
905 |
-
*
|
906 |
-
* $c = $a->subtract($b);
|
907 |
-
*
|
908 |
-
* echo $c->toString(); // outputs -10
|
909 |
-
* ?>
|
910 |
-
* </code>
|
911 |
-
*
|
912 |
-
* @param Math_BigInteger $y
|
913 |
-
* @return Math_BigInteger
|
914 |
-
* @access public
|
915 |
-
* @internal Performs base-2**52 subtraction
|
916 |
-
*/
|
917 |
-
function subtract($y)
|
918 |
-
{
|
919 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
920 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
921 |
-
$temp = new Math_BigInteger();
|
922 |
-
$temp->value = gmp_sub($this->value, $y->value);
|
923 |
-
|
924 |
-
return $this->_normalize($temp);
|
925 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
926 |
-
$temp = new Math_BigInteger();
|
927 |
-
$temp->value = bcsub($this->value, $y->value, 0);
|
928 |
-
|
929 |
-
return $this->_normalize($temp);
|
930 |
-
}
|
931 |
-
|
932 |
-
$temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative);
|
933 |
-
|
934 |
-
$result = new Math_BigInteger();
|
935 |
-
$result->value = $temp[MATH_BIGINTEGER_VALUE];
|
936 |
-
$result->is_negative = $temp[MATH_BIGINTEGER_SIGN];
|
937 |
-
|
938 |
-
return $this->_normalize($result);
|
939 |
-
}
|
940 |
-
|
941 |
-
/**
|
942 |
-
* Performs subtraction.
|
943 |
-
*
|
944 |
-
* @param Array $x_value
|
945 |
-
* @param Boolean $x_negative
|
946 |
-
* @param Array $y_value
|
947 |
-
* @param Boolean $y_negative
|
948 |
-
* @return Array
|
949 |
-
* @access private
|
950 |
-
*/
|
951 |
-
function _subtract($x_value, $x_negative, $y_value, $y_negative)
|
952 |
-
{
|
953 |
-
$x_size = count($x_value);
|
954 |
-
$y_size = count($y_value);
|
955 |
-
|
956 |
-
if ($x_size == 0) {
|
957 |
-
return array(
|
958 |
-
MATH_BIGINTEGER_VALUE => $y_value,
|
959 |
-
MATH_BIGINTEGER_SIGN => !$y_negative
|
960 |
-
);
|
961 |
-
} else if ($y_size == 0) {
|
962 |
-
return array(
|
963 |
-
MATH_BIGINTEGER_VALUE => $x_value,
|
964 |
-
MATH_BIGINTEGER_SIGN => $x_negative
|
965 |
-
);
|
966 |
-
}
|
967 |
-
|
968 |
-
// add, if appropriate (ie. -$x - +$y or +$x - -$y)
|
969 |
-
if ( $x_negative != $y_negative ) {
|
970 |
-
$temp = $this->_add($x_value, false, $y_value, false);
|
971 |
-
$temp[MATH_BIGINTEGER_SIGN] = $x_negative;
|
972 |
-
|
973 |
-
return $temp;
|
974 |
-
}
|
975 |
-
|
976 |
-
$diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);
|
977 |
-
|
978 |
-
if ( !$diff ) {
|
979 |
-
return array(
|
980 |
-
MATH_BIGINTEGER_VALUE => array(),
|
981 |
-
MATH_BIGINTEGER_SIGN => false
|
982 |
-
);
|
983 |
-
}
|
984 |
-
|
985 |
-
// switch $x and $y around, if appropriate.
|
986 |
-
if ( (!$x_negative && $diff < 0) || ($x_negative && $diff > 0) ) {
|
987 |
-
$temp = $x_value;
|
988 |
-
$x_value = $y_value;
|
989 |
-
$y_value = $temp;
|
990 |
-
|
991 |
-
$x_negative = !$x_negative;
|
992 |
-
|
993 |
-
$x_size = count($x_value);
|
994 |
-
$y_size = count($y_value);
|
995 |
-
}
|
996 |
-
|
997 |
-
// at this point, $x_value should be at least as big as - if not bigger than - $y_value
|
998 |
-
|
999 |
-
$carry = 0;
|
1000 |
-
for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) {
|
1001 |
-
$sum = $x_value[$j] * 0x4000000 + $x_value[$i] - $y_value[$j] * 0x4000000 - $y_value[$i] - $carry;
|
1002 |
-
$carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
|
1003 |
-
$sum = $carry ? $sum + MATH_BIGINTEGER_MAX_DIGIT52 : $sum;
|
1004 |
-
|
1005 |
-
$temp = (int) ($sum / 0x4000000);
|
1006 |
-
|
1007 |
-
$x_value[$i] = (int) ($sum - 0x4000000 * $temp);
|
1008 |
-
$x_value[$j] = $temp;
|
1009 |
-
}
|
1010 |
-
|
1011 |
-
if ($j == $y_size) { // ie. if $y_size is odd
|
1012 |
-
$sum = $x_value[$i] - $y_value[$i] - $carry;
|
1013 |
-
$carry = $sum < 0;
|
1014 |
-
$x_value[$i] = $carry ? $sum + 0x4000000 : $sum;
|
1015 |
-
++$i;
|
1016 |
-
}
|
1017 |
-
|
1018 |
-
if ($carry) {
|
1019 |
-
for (; !$x_value[$i]; ++$i) {
|
1020 |
-
$x_value[$i] = 0x3FFFFFF;
|
1021 |
-
}
|
1022 |
-
--$x_value[$i];
|
1023 |
-
}
|
1024 |
-
|
1025 |
-
return array(
|
1026 |
-
MATH_BIGINTEGER_VALUE => $this->_trim($x_value),
|
1027 |
-
MATH_BIGINTEGER_SIGN => $x_negative
|
1028 |
-
);
|
1029 |
-
}
|
1030 |
-
|
1031 |
-
/**
|
1032 |
-
* Multiplies two BigIntegers
|
1033 |
-
*
|
1034 |
-
* Here's an example:
|
1035 |
-
* <code>
|
1036 |
-
* <?php
|
1037 |
-
* include('Math/BigInteger.php');
|
1038 |
-
*
|
1039 |
-
* $a = new Math_BigInteger('10');
|
1040 |
-
* $b = new Math_BigInteger('20');
|
1041 |
-
*
|
1042 |
-
* $c = $a->multiply($b);
|
1043 |
-
*
|
1044 |
-
* echo $c->toString(); // outputs 200
|
1045 |
-
* ?>
|
1046 |
-
* </code>
|
1047 |
-
*
|
1048 |
-
* @param Math_BigInteger $x
|
1049 |
-
* @return Math_BigInteger
|
1050 |
-
* @access public
|
1051 |
-
*/
|
1052 |
-
function multiply($x)
|
1053 |
-
{
|
1054 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
1055 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
1056 |
-
$temp = new Math_BigInteger();
|
1057 |
-
$temp->value = gmp_mul($this->value, $x->value);
|
1058 |
-
|
1059 |
-
return $this->_normalize($temp);
|
1060 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
1061 |
-
$temp = new Math_BigInteger();
|
1062 |
-
$temp->value = bcmul($this->value, $x->value, 0);
|
1063 |
-
|
1064 |
-
return $this->_normalize($temp);
|
1065 |
-
}
|
1066 |
-
|
1067 |
-
$temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative);
|
1068 |
-
|
1069 |
-
$product = new Math_BigInteger();
|
1070 |
-
$product->value = $temp[MATH_BIGINTEGER_VALUE];
|
1071 |
-
$product->is_negative = $temp[MATH_BIGINTEGER_SIGN];
|
1072 |
-
|
1073 |
-
return $this->_normalize($product);
|
1074 |
-
}
|
1075 |
-
|
1076 |
-
/**
|
1077 |
-
* Performs multiplication.
|
1078 |
-
*
|
1079 |
-
* @param Array $x_value
|
1080 |
-
* @param Boolean $x_negative
|
1081 |
-
* @param Array $y_value
|
1082 |
-
* @param Boolean $y_negative
|
1083 |
-
* @return Array
|
1084 |
-
* @access private
|
1085 |
-
*/
|
1086 |
-
function _multiply($x_value, $x_negative, $y_value, $y_negative)
|
1087 |
-
{
|
1088 |
-
//if ( $x_value == $y_value ) {
|
1089 |
-
// return array(
|
1090 |
-
// MATH_BIGINTEGER_VALUE => $this->_square($x_value),
|
1091 |
-
// MATH_BIGINTEGER_SIGN => $x_sign != $y_value
|
1092 |
-
// );
|
1093 |
-
//}
|
1094 |
-
|
1095 |
-
$x_length = count($x_value);
|
1096 |
-
$y_length = count($y_value);
|
1097 |
-
|
1098 |
-
if ( !$x_length || !$y_length ) { // a 0 is being multiplied
|
1099 |
-
return array(
|
1100 |
-
MATH_BIGINTEGER_VALUE => array(),
|
1101 |
-
MATH_BIGINTEGER_SIGN => false
|
1102 |
-
);
|
1103 |
-
}
|
1104 |
-
|
1105 |
-
return array(
|
1106 |
-
MATH_BIGINTEGER_VALUE => min($x_length, $y_length) < 2 * MATH_BIGINTEGER_KARATSUBA_CUTOFF ?
|
1107 |
-
$this->_trim($this->_regularMultiply($x_value, $y_value)) :
|
1108 |
-
$this->_trim($this->_karatsuba($x_value, $y_value)),
|
1109 |
-
MATH_BIGINTEGER_SIGN => $x_negative != $y_negative
|
1110 |
-
);
|
1111 |
-
}
|
1112 |
-
|
1113 |
-
/**
|
1114 |
-
* Performs long multiplication on two BigIntegers
|
1115 |
-
*
|
1116 |
-
* Modeled after 'multiply' in MutableBigInteger.java.
|
1117 |
-
*
|
1118 |
-
* @param Array $x_value
|
1119 |
-
* @param Array $y_value
|
1120 |
-
* @return Array
|
1121 |
-
* @access private
|
1122 |
-
*/
|
1123 |
-
function _regularMultiply($x_value, $y_value)
|
1124 |
-
{
|
1125 |
-
$x_length = count($x_value);
|
1126 |
-
$y_length = count($y_value);
|
1127 |
-
|
1128 |
-
if ( !$x_length || !$y_length ) { // a 0 is being multiplied
|
1129 |
-
return array();
|
1130 |
-
}
|
1131 |
-
|
1132 |
-
if ( $x_length < $y_length ) {
|
1133 |
-
$temp = $x_value;
|
1134 |
-
$x_value = $y_value;
|
1135 |
-
$y_value = $temp;
|
1136 |
-
|
1137 |
-
$x_length = count($x_value);
|
1138 |
-
$y_length = count($y_value);
|
1139 |
-
}
|
1140 |
-
|
1141 |
-
$product_value = $this->_array_repeat(0, $x_length + $y_length);
|
1142 |
-
|
1143 |
-
// the following for loop could be removed if the for loop following it
|
1144 |
-
// (the one with nested for loops) initially set $i to 0, but
|
1145 |
-
// doing so would also make the result in one set of unnecessary adds,
|
1146 |
-
// since on the outermost loops first pass, $product->value[$k] is going
|
1147 |
-
// to always be 0
|
1148 |
-
|
1149 |
-
$carry = 0;
|
1150 |
-
|
1151 |
-
for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0
|
1152 |
-
$temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
|
1153 |
-
$carry = (int) ($temp / 0x4000000);
|
1154 |
-
$product_value[$j] = (int) ($temp - 0x4000000 * $carry);
|
1155 |
-
}
|
1156 |
-
|
1157 |
-
$product_value[$j] = $carry;
|
1158 |
-
|
1159 |
-
// the above for loop is what the previous comment was talking about. the
|
1160 |
-
// following for loop is the "one with nested for loops"
|
1161 |
-
for ($i = 1; $i < $y_length; ++$i) {
|
1162 |
-
$carry = 0;
|
1163 |
-
|
1164 |
-
for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {
|
1165 |
-
$temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
|
1166 |
-
$carry = (int) ($temp / 0x4000000);
|
1167 |
-
$product_value[$k] = (int) ($temp - 0x4000000 * $carry);
|
1168 |
-
}
|
1169 |
-
|
1170 |
-
$product_value[$k] = $carry;
|
1171 |
-
}
|
1172 |
-
|
1173 |
-
return $product_value;
|
1174 |
-
}
|
1175 |
-
|
1176 |
-
/**
|
1177 |
-
* Performs Karatsuba multiplication on two BigIntegers
|
1178 |
-
*
|
1179 |
-
* See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
|
1180 |
-
* {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}.
|
1181 |
-
*
|
1182 |
-
* @param Array $x_value
|
1183 |
-
* @param Array $y_value
|
1184 |
-
* @return Array
|
1185 |
-
* @access private
|
1186 |
-
*/
|
1187 |
-
function _karatsuba($x_value, $y_value)
|
1188 |
-
{
|
1189 |
-
$m = min(count($x_value) >> 1, count($y_value) >> 1);
|
1190 |
-
|
1191 |
-
if ($m < MATH_BIGINTEGER_KARATSUBA_CUTOFF) {
|
1192 |
-
return $this->_regularMultiply($x_value, $y_value);
|
1193 |
-
}
|
1194 |
-
|
1195 |
-
$x1 = array_slice($x_value, $m);
|
1196 |
-
$x0 = array_slice($x_value, 0, $m);
|
1197 |
-
$y1 = array_slice($y_value, $m);
|
1198 |
-
$y0 = array_slice($y_value, 0, $m);
|
1199 |
-
|
1200 |
-
$z2 = $this->_karatsuba($x1, $y1);
|
1201 |
-
$z0 = $this->_karatsuba($x0, $y0);
|
1202 |
-
|
1203 |
-
$z1 = $this->_add($x1, false, $x0, false);
|
1204 |
-
$temp = $this->_add($y1, false, $y0, false);
|
1205 |
-
$z1 = $this->_karatsuba($z1[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_VALUE]);
|
1206 |
-
$temp = $this->_add($z2, false, $z0, false);
|
1207 |
-
$z1 = $this->_subtract($z1, false, $temp[MATH_BIGINTEGER_VALUE], false);
|
1208 |
-
|
1209 |
-
$z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
|
1210 |
-
$z1[MATH_BIGINTEGER_VALUE] = array_merge(array_fill(0, $m, 0), $z1[MATH_BIGINTEGER_VALUE]);
|
1211 |
-
|
1212 |
-
$xy = $this->_add($z2, false, $z1[MATH_BIGINTEGER_VALUE], $z1[MATH_BIGINTEGER_SIGN]);
|
1213 |
-
$xy = $this->_add($xy[MATH_BIGINTEGER_VALUE], $xy[MATH_BIGINTEGER_SIGN], $z0, false);
|
1214 |
-
|
1215 |
-
return $xy[MATH_BIGINTEGER_VALUE];
|
1216 |
-
}
|
1217 |
-
|
1218 |
-
/**
|
1219 |
-
* Performs squaring
|
1220 |
-
*
|
1221 |
-
* @param Array $x
|
1222 |
-
* @return Array
|
1223 |
-
* @access private
|
1224 |
-
*/
|
1225 |
-
function _square($x = false)
|
1226 |
-
{
|
1227 |
-
return count($x) < 2 * MATH_BIGINTEGER_KARATSUBA_CUTOFF ?
|
1228 |
-
$this->_trim($this->_baseSquare($x)) :
|
1229 |
-
$this->_trim($this->_karatsubaSquare($x));
|
1230 |
-
}
|
1231 |
-
|
1232 |
-
/**
|
1233 |
-
* Performs traditional squaring on two BigIntegers
|
1234 |
-
*
|
1235 |
-
* Squaring can be done faster than multiplying a number by itself can be. See
|
1236 |
-
* {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} /
|
1237 |
-
* {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information.
|
1238 |
-
*
|
1239 |
-
* @param Array $value
|
1240 |
-
* @return Array
|
1241 |
-
* @access private
|
1242 |
-
*/
|
1243 |
-
function _baseSquare($value)
|
1244 |
-
{
|
1245 |
-
if ( empty($value) ) {
|
1246 |
-
return array();
|
1247 |
-
}
|
1248 |
-
$square_value = $this->_array_repeat(0, 2 * count($value));
|
1249 |
-
|
1250 |
-
for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) {
|
1251 |
-
$i2 = $i << 1;
|
1252 |
-
|
1253 |
-
$temp = $square_value[$i2] + $value[$i] * $value[$i];
|
1254 |
-
$carry = (int) ($temp / 0x4000000);
|
1255 |
-
$square_value[$i2] = (int) ($temp - 0x4000000 * $carry);
|
1256 |
-
|
1257 |
-
// note how we start from $i+1 instead of 0 as we do in multiplication.
|
1258 |
-
for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {
|
1259 |
-
$temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;
|
1260 |
-
$carry = (int) ($temp / 0x4000000);
|
1261 |
-
$square_value[$k] = (int) ($temp - 0x4000000 * $carry);
|
1262 |
-
}
|
1263 |
-
|
1264 |
-
// the following line can yield values larger 2**15. at this point, PHP should switch
|
1265 |
-
// over to floats.
|
1266 |
-
$square_value[$i + $max_index + 1] = $carry;
|
1267 |
-
}
|
1268 |
-
|
1269 |
-
return $square_value;
|
1270 |
-
}
|
1271 |
-
|
1272 |
-
/**
|
1273 |
-
* Performs Karatsuba "squaring" on two BigIntegers
|
1274 |
-
*
|
1275 |
-
* See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
|
1276 |
-
* {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}.
|
1277 |
-
*
|
1278 |
-
* @param Array $value
|
1279 |
-
* @return Array
|
1280 |
-
* @access private
|
1281 |
-
*/
|
1282 |
-
function _karatsubaSquare($value)
|
1283 |
-
{
|
1284 |
-
$m = count($value) >> 1;
|
1285 |
-
|
1286 |
-
if ($m < MATH_BIGINTEGER_KARATSUBA_CUTOFF) {
|
1287 |
-
return $this->_baseSquare($value);
|
1288 |
-
}
|
1289 |
-
|
1290 |
-
$x1 = array_slice($value, $m);
|
1291 |
-
$x0 = array_slice($value, 0, $m);
|
1292 |
-
|
1293 |
-
$z2 = $this->_karatsubaSquare($x1);
|
1294 |
-
$z0 = $this->_karatsubaSquare($x0);
|
1295 |
-
|
1296 |
-
$z1 = $this->_add($x1, false, $x0, false);
|
1297 |
-
$z1 = $this->_karatsubaSquare($z1[MATH_BIGINTEGER_VALUE]);
|
1298 |
-
$temp = $this->_add($z2, false, $z0, false);
|
1299 |
-
$z1 = $this->_subtract($z1, false, $temp[MATH_BIGINTEGER_VALUE], false);
|
1300 |
-
|
1301 |
-
$z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
|
1302 |
-
$z1[MATH_BIGINTEGER_VALUE] = array_merge(array_fill(0, $m, 0), $z1[MATH_BIGINTEGER_VALUE]);
|
1303 |
-
|
1304 |
-
$xx = $this->_add($z2, false, $z1[MATH_BIGINTEGER_VALUE], $z1[MATH_BIGINTEGER_SIGN]);
|
1305 |
-
$xx = $this->_add($xx[MATH_BIGINTEGER_VALUE], $xx[MATH_BIGINTEGER_SIGN], $z0, false);
|
1306 |
-
|
1307 |
-
return $xx[MATH_BIGINTEGER_VALUE];
|
1308 |
-
}
|
1309 |
-
|
1310 |
-
/**
|
1311 |
-
* Divides two BigIntegers.
|
1312 |
-
*
|
1313 |
-
* Returns an array whose first element contains the quotient and whose second element contains the
|
1314 |
-
* "common residue". If the remainder would be positive, the "common residue" and the remainder are the
|
1315 |
-
* same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder
|
1316 |
-
* and the divisor (basically, the "common residue" is the first positive modulo).
|
1317 |
-
*
|
1318 |
-
* Here's an example:
|
1319 |
-
* <code>
|
1320 |
-
* <?php
|
1321 |
-
* include('Math/BigInteger.php');
|
1322 |
-
*
|
1323 |
-
* $a = new Math_BigInteger('10');
|
1324 |
-
* $b = new Math_BigInteger('20');
|
1325 |
-
*
|
1326 |
-
* list($quotient, $remainder) = $a->divide($b);
|
1327 |
-
*
|
1328 |
-
* echo $quotient->toString(); // outputs 0
|
1329 |
-
* echo "\r\n";
|
1330 |
-
* echo $remainder->toString(); // outputs 10
|
1331 |
-
* ?>
|
1332 |
-
* </code>
|
1333 |
-
*
|
1334 |
-
* @param Math_BigInteger $y
|
1335 |
-
* @return Array
|
1336 |
-
* @access public
|
1337 |
-
* @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.
|
1338 |
-
*/
|
1339 |
-
function divide($y)
|
1340 |
-
{
|
1341 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
1342 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
1343 |
-
$quotient = new Math_BigInteger();
|
1344 |
-
$remainder = new Math_BigInteger();
|
1345 |
-
|
1346 |
-
list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
|
1347 |
-
|
1348 |
-
if (gmp_sign($remainder->value) < 0) {
|
1349 |
-
$remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
|
1350 |
-
}
|
1351 |
-
|
1352 |
-
return array($this->_normalize($quotient), $this->_normalize($remainder));
|
1353 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
1354 |
-
$quotient = new Math_BigInteger();
|
1355 |
-
$remainder = new Math_BigInteger();
|
1356 |
-
|
1357 |
-
$quotient->value = bcdiv($this->value, $y->value, 0);
|
1358 |
-
$remainder->value = bcmod($this->value, $y->value);
|
1359 |
-
|
1360 |
-
if ($remainder->value[0] == '-') {
|
1361 |
-
$remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);
|
1362 |
-
}
|
1363 |
-
|
1364 |
-
return array($this->_normalize($quotient), $this->_normalize($remainder));
|
1365 |
-
}
|
1366 |
-
|
1367 |
-
if (count($y->value) == 1) {
|
1368 |
-
list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);
|
1369 |
-
$quotient = new Math_BigInteger();
|
1370 |
-
$remainder = new Math_BigInteger();
|
1371 |
-
$quotient->value = $q;
|
1372 |
-
$remainder->value = array($r);
|
1373 |
-
$quotient->is_negative = $this->is_negative != $y->is_negative;
|
1374 |
-
return array($this->_normalize($quotient), $this->_normalize($remainder));
|
1375 |
-
}
|
1376 |
-
|
1377 |
-
static $zero;
|
1378 |
-
if ( !isset($zero) ) {
|
1379 |
-
$zero = new Math_BigInteger();
|
1380 |
-
}
|
1381 |
-
|
1382 |
-
$x = $this->copy();
|
1383 |
-
$y = $y->copy();
|
1384 |
-
|
1385 |
-
$x_sign = $x->is_negative;
|
1386 |
-
$y_sign = $y->is_negative;
|
1387 |
-
|
1388 |
-
$x->is_negative = $y->is_negative = false;
|
1389 |
-
|
1390 |
-
$diff = $x->compare($y);
|
1391 |
-
|
1392 |
-
if ( !$diff ) {
|
1393 |
-
$temp = new Math_BigInteger();
|
1394 |
-
$temp->value = array(1);
|
1395 |
-
$temp->is_negative = $x_sign != $y_sign;
|
1396 |
-
return array($this->_normalize($temp), $this->_normalize(new Math_BigInteger()));
|
1397 |
-
}
|
1398 |
-
|
1399 |
-
if ( $diff < 0 ) {
|
1400 |
-
// if $x is negative, "add" $y.
|
1401 |
-
if ( $x_sign ) {
|
1402 |
-
$x = $y->subtract($x);
|
1403 |
-
}
|
1404 |
-
return array($this->_normalize(new Math_BigInteger()), $this->_normalize($x));
|
1405 |
-
}
|
1406 |
-
|
1407 |
-
// normalize $x and $y as described in HAC 14.23 / 14.24
|
1408 |
-
$msb = $y->value[count($y->value) - 1];
|
1409 |
-
for ($shift = 0; !($msb & 0x2000000); ++$shift) {
|
1410 |
-
$msb <<= 1;
|
1411 |
-
}
|
1412 |
-
$x->_lshift($shift);
|
1413 |
-
$y->_lshift($shift);
|
1414 |
-
$y_value = &$y->value;
|
1415 |
-
|
1416 |
-
$x_max = count($x->value) - 1;
|
1417 |
-
$y_max = count($y->value) - 1;
|
1418 |
-
|
1419 |
-
$quotient = new Math_BigInteger();
|
1420 |
-
$quotient_value = &$quotient->value;
|
1421 |
-
$quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);
|
1422 |
-
|
1423 |
-
static $temp, $lhs, $rhs;
|
1424 |
-
if (!isset($temp)) {
|
1425 |
-
$temp = new Math_BigInteger();
|
1426 |
-
$lhs = new Math_BigInteger();
|
1427 |
-
$rhs = new Math_BigInteger();
|
1428 |
-
}
|
1429 |
-
$temp_value = &$temp->value;
|
1430 |
-
$rhs_value = &$rhs->value;
|
1431 |
-
|
1432 |
-
// $temp = $y << ($x_max - $y_max-1) in base 2**26
|
1433 |
-
$temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
|
1434 |
-
|
1435 |
-
while ( $x->compare($temp) >= 0 ) {
|
1436 |
-
// calculate the "common residue"
|
1437 |
-
++$quotient_value[$x_max - $y_max];
|
1438 |
-
$x = $x->subtract($temp);
|
1439 |
-
$x_max = count($x->value) - 1;
|
1440 |
-
}
|
1441 |
-
|
1442 |
-
for ($i = $x_max; $i >= $y_max + 1; --$i) {
|
1443 |
-
$x_value = &$x->value;
|
1444 |
-
$x_window = array(
|
1445 |
-
isset($x_value[$i]) ? $x_value[$i] : 0,
|
1446 |
-
isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0,
|
1447 |
-
isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0
|
1448 |
-
);
|
1449 |
-
$y_window = array(
|
1450 |
-
$y_value[$y_max],
|
1451 |
-
( $y_max > 0 ) ? $y_value[$y_max - 1] : 0
|
1452 |
-
);
|
1453 |
-
|
1454 |
-
$q_index = $i - $y_max - 1;
|
1455 |
-
if ($x_window[0] == $y_window[0]) {
|
1456 |
-
$quotient_value[$q_index] = 0x3FFFFFF;
|
1457 |
-
} else {
|
1458 |
-
$quotient_value[$q_index] = (int) (
|
1459 |
-
($x_window[0] * 0x4000000 + $x_window[1])
|
1460 |
-
/
|
1461 |
-
$y_window[0]
|
1462 |
-
);
|
1463 |
-
}
|
1464 |
-
|
1465 |
-
$temp_value = array($y_window[1], $y_window[0]);
|
1466 |
-
|
1467 |
-
$lhs->value = array($quotient_value[$q_index]);
|
1468 |
-
$lhs = $lhs->multiply($temp);
|
1469 |
-
|
1470 |
-
$rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
|
1471 |
-
|
1472 |
-
while ( $lhs->compare($rhs) > 0 ) {
|
1473 |
-
--$quotient_value[$q_index];
|
1474 |
-
|
1475 |
-
$lhs->value = array($quotient_value[$q_index]);
|
1476 |
-
$lhs = $lhs->multiply($temp);
|
1477 |
-
}
|
1478 |
-
|
1479 |
-
$adjust = $this->_array_repeat(0, $q_index);
|
1480 |
-
$temp_value = array($quotient_value[$q_index]);
|
1481 |
-
$temp = $temp->multiply($y);
|
1482 |
-
$temp_value = &$temp->value;
|
1483 |
-
$temp_value = array_merge($adjust, $temp_value);
|
1484 |
-
|
1485 |
-
$x = $x->subtract($temp);
|
1486 |
-
|
1487 |
-
if ($x->compare($zero) < 0) {
|
1488 |
-
$temp_value = array_merge($adjust, $y_value);
|
1489 |
-
$x = $x->add($temp);
|
1490 |
-
|
1491 |
-
--$quotient_value[$q_index];
|
1492 |
-
}
|
1493 |
-
|
1494 |
-
$x_max = count($x_value) - 1;
|
1495 |
-
}
|
1496 |
-
|
1497 |
-
// unnormalize the remainder
|
1498 |
-
$x->_rshift($shift);
|
1499 |
-
|
1500 |
-
$quotient->is_negative = $x_sign != $y_sign;
|
1501 |
-
|
1502 |
-
// calculate the "common residue", if appropriate
|
1503 |
-
if ( $x_sign ) {
|
1504 |
-
$y->_rshift($shift);
|
1505 |
-
$x = $y->subtract($x);
|
1506 |
-
}
|
1507 |
-
|
1508 |
-
return array($this->_normalize($quotient), $this->_normalize($x));
|
1509 |
-
}
|
1510 |
-
|
1511 |
-
/**
|
1512 |
-
* Divides a BigInteger by a regular integer
|
1513 |
-
*
|
1514 |
-
* abc / x = a00 / x + b0 / x + c / x
|
1515 |
-
*
|
1516 |
-
* @param Array $dividend
|
1517 |
-
* @param Array $divisor
|
1518 |
-
* @return Array
|
1519 |
-
* @access private
|
1520 |
-
*/
|
1521 |
-
function _divide_digit($dividend, $divisor)
|
1522 |
-
{
|
1523 |
-
$carry = 0;
|
1524 |
-
$result = array();
|
1525 |
-
|
1526 |
-
for ($i = count($dividend) - 1; $i >= 0; --$i) {
|
1527 |
-
$temp = 0x4000000 * $carry + $dividend[$i];
|
1528 |
-
$result[$i] = (int) ($temp / $divisor);
|
1529 |
-
$carry = (int) ($temp - $divisor * $result[$i]);
|
1530 |
-
}
|
1531 |
-
|
1532 |
-
return array($result, $carry);
|
1533 |
-
}
|
1534 |
-
|
1535 |
-
/**
|
1536 |
-
* Performs modular exponentiation.
|
1537 |
-
*
|
1538 |
-
* Here's an example:
|
1539 |
-
* <code>
|
1540 |
-
* <?php
|
1541 |
-
* include('Math/BigInteger.php');
|
1542 |
-
*
|
1543 |
-
* $a = new Math_BigInteger('10');
|
1544 |
-
* $b = new Math_BigInteger('20');
|
1545 |
-
* $c = new Math_BigInteger('30');
|
1546 |
-
*
|
1547 |
-
* $c = $a->modPow($b, $c);
|
1548 |
-
*
|
1549 |
-
* echo $c->toString(); // outputs 10
|
1550 |
-
* ?>
|
1551 |
-
* </code>
|
1552 |
-
*
|
1553 |
-
* @param Math_BigInteger $e
|
1554 |
-
* @param Math_BigInteger $n
|
1555 |
-
* @return Math_BigInteger
|
1556 |
-
* @access public
|
1557 |
-
* @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
|
1558 |
-
* and although the approach involving repeated squaring does vastly better, it, too, is impractical
|
1559 |
-
* for our purposes. The reason being that division - by far the most complicated and time-consuming
|
1560 |
-
* of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
|
1561 |
-
*
|
1562 |
-
* Modular reductions resolve this issue. Although an individual modular reduction takes more time
|
1563 |
-
* then an individual division, when performed in succession (with the same modulo), they're a lot faster.
|
1564 |
-
*
|
1565 |
-
* The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction,
|
1566 |
-
* although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the
|
1567 |
-
* base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
|
1568 |
-
* the product of two odd numbers is odd), but what about when RSA isn't used?
|
1569 |
-
*
|
1570 |
-
* In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a
|
1571 |
-
* Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the
|
1572 |
-
* modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however,
|
1573 |
-
* uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
|
1574 |
-
* the other, a power of two - and recombine them, later. This is the method that this modPow function uses.
|
1575 |
-
* {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
|
1576 |
-
*/
|
1577 |
-
function modPow($e, $n)
|
1578 |
-
{
|
1579 |
-
$n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();
|
1580 |
-
|
1581 |
-
if ($e->compare(new Math_BigInteger()) < 0) {
|
1582 |
-
$e = $e->abs();
|
1583 |
-
|
1584 |
-
$temp = $this->modInverse($n);
|
1585 |
-
if ($temp === false) {
|
1586 |
-
return false;
|
1587 |
-
}
|
1588 |
-
|
1589 |
-
return $this->_normalize($temp->modPow($e, $n));
|
1590 |
-
}
|
1591 |
-
|
1592 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
1593 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
1594 |
-
$temp = new Math_BigInteger();
|
1595 |
-
$temp->value = gmp_powm($this->value, $e->value, $n->value);
|
1596 |
-
|
1597 |
-
return $this->_normalize($temp);
|
1598 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
1599 |
-
$temp = new Math_BigInteger();
|
1600 |
-
$temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
|
1601 |
-
|
1602 |
-
return $this->_normalize($temp);
|
1603 |
-
}
|
1604 |
-
|
1605 |
-
if ( empty($e->value) ) {
|
1606 |
-
$temp = new Math_BigInteger();
|
1607 |
-
$temp->value = array(1);
|
1608 |
-
return $this->_normalize($temp);
|
1609 |
-
}
|
1610 |
-
|
1611 |
-
if ( $e->value == array(1) ) {
|
1612 |
-
list(, $temp) = $this->divide($n);
|
1613 |
-
return $this->_normalize($temp);
|
1614 |
-
}
|
1615 |
-
|
1616 |
-
if ( $e->value == array(2) ) {
|
1617 |
-
$temp = new Math_BigInteger();
|
1618 |
-
$temp->value = $this->_square($this->value);
|
1619 |
-
list(, $temp) = $temp->divide($n);
|
1620 |
-
return $this->_normalize($temp);
|
1621 |
-
}
|
1622 |
-
|
1623 |
-
return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_BARRETT));
|
1624 |
-
|
1625 |
-
// is the modulo odd?
|
1626 |
-
if ( $n->value[0] & 1 ) {
|
1627 |
-
return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_MONTGOMERY));
|
1628 |
-
}
|
1629 |
-
// if it's not, it's even
|
1630 |
-
|
1631 |
-
// find the lowest set bit (eg. the max pow of 2 that divides $n)
|
1632 |
-
for ($i = 0; $i < count($n->value); ++$i) {
|
1633 |
-
if ( $n->value[$i] ) {
|
1634 |
-
$temp = decbin($n->value[$i]);
|
1635 |
-
$j = strlen($temp) - strrpos($temp, '1') - 1;
|
1636 |
-
$j+= 26 * $i;
|
1637 |
-
break;
|
1638 |
-
}
|
1639 |
-
}
|
1640 |
-
// at this point, 2^$j * $n/(2^$j) == $n
|
1641 |
-
|
1642 |
-
$mod1 = $n->copy();
|
1643 |
-
$mod1->_rshift($j);
|
1644 |
-
$mod2 = new Math_BigInteger();
|
1645 |
-
$mod2->value = array(1);
|
1646 |
-
$mod2->_lshift($j);
|
1647 |
-
|
1648 |
-
$part1 = ( $mod1->value != array(1) ) ? $this->_slidingWindow($e, $mod1, MATH_BIGINTEGER_MONTGOMERY) : new Math_BigInteger();
|
1649 |
-
$part2 = $this->_slidingWindow($e, $mod2, MATH_BIGINTEGER_POWEROF2);
|
1650 |
-
|
1651 |
-
$y1 = $mod2->modInverse($mod1);
|
1652 |
-
$y2 = $mod1->modInverse($mod2);
|
1653 |
-
|
1654 |
-
$result = $part1->multiply($mod2);
|
1655 |
-
$result = $result->multiply($y1);
|
1656 |
-
|
1657 |
-
$temp = $part2->multiply($mod1);
|
1658 |
-
$temp = $temp->multiply($y2);
|
1659 |
-
|
1660 |
-
$result = $result->add($temp);
|
1661 |
-
list(, $result) = $result->divide($n);
|
1662 |
-
|
1663 |
-
return $this->_normalize($result);
|
1664 |
-
}
|
1665 |
-
|
1666 |
-
/**
|
1667 |
-
* Performs modular exponentiation.
|
1668 |
-
*
|
1669 |
-
* Alias for Math_BigInteger::modPow()
|
1670 |
-
*
|
1671 |
-
* @param Math_BigInteger $e
|
1672 |
-
* @param Math_BigInteger $n
|
1673 |
-
* @return Math_BigInteger
|
1674 |
-
* @access public
|
1675 |
-
*/
|
1676 |
-
function powMod($e, $n)
|
1677 |
-
{
|
1678 |
-
return $this->modPow($e, $n);
|
1679 |
-
}
|
1680 |
-
|
1681 |
-
/**
|
1682 |
-
* Sliding Window k-ary Modular Exponentiation
|
1683 |
-
*
|
1684 |
-
* Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} /
|
1685 |
-
* {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims,
|
1686 |
-
* however, this function performs a modular reduction after every multiplication and squaring operation.
|
1687 |
-
* As such, this function has the same preconditions that the reductions being used do.
|
1688 |
-
*
|
1689 |
-
* @param Math_BigInteger $e
|
1690 |
-
* @param Math_BigInteger $n
|
1691 |
-
* @param Integer $mode
|
1692 |
-
* @return Math_BigInteger
|
1693 |
-
* @access private
|
1694 |
-
*/
|
1695 |
-
function _slidingWindow($e, $n, $mode)
|
1696 |
-
{
|
1697 |
-
static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function
|
1698 |
-
//static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1
|
1699 |
-
|
1700 |
-
$e_value = $e->value;
|
1701 |
-
$e_length = count($e_value) - 1;
|
1702 |
-
$e_bits = decbin($e_value[$e_length]);
|
1703 |
-
for ($i = $e_length - 1; $i >= 0; --$i) {
|
1704 |
-
$e_bits.= str_pad(decbin($e_value[$i]), 26, '0', STR_PAD_LEFT);
|
1705 |
-
}
|
1706 |
-
|
1707 |
-
$e_length = strlen($e_bits);
|
1708 |
-
|
1709 |
-
// calculate the appropriate window size.
|
1710 |
-
// $window_size == 3 if $window_ranges is between 25 and 81, for example.
|
1711 |
-
for ($i = 0, $window_size = 1; $e_length > $window_ranges[$i] && $i < count($window_ranges); ++$window_size, ++$i);
|
1712 |
-
|
1713 |
-
$n_value = $n->value;
|
1714 |
-
|
1715 |
-
// precompute $this^0 through $this^$window_size
|
1716 |
-
$powers = array();
|
1717 |
-
$powers[1] = $this->_prepareReduce($this->value, $n_value, $mode);
|
1718 |
-
$powers[2] = $this->_squareReduce($powers[1], $n_value, $mode);
|
1719 |
-
|
1720 |
-
// we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end
|
1721 |
-
// in a 1. ie. it's supposed to be odd.
|
1722 |
-
$temp = 1 << ($window_size - 1);
|
1723 |
-
for ($i = 1; $i < $temp; ++$i) {
|
1724 |
-
$i2 = $i << 1;
|
1725 |
-
$powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode);
|
1726 |
-
}
|
1727 |
-
|
1728 |
-
$result = array(1);
|
1729 |
-
$result = $this->_prepareReduce($result, $n_value, $mode);
|
1730 |
-
|
1731 |
-
for ($i = 0; $i < $e_length; ) {
|
1732 |
-
if ( !$e_bits[$i] ) {
|
1733 |
-
$result = $this->_squareReduce($result, $n_value, $mode);
|
1734 |
-
++$i;
|
1735 |
-
} else {
|
1736 |
-
for ($j = $window_size - 1; $j > 0; --$j) {
|
1737 |
-
if ( !empty($e_bits[$i + $j]) ) {
|
1738 |
-
break;
|
1739 |
-
}
|
1740 |
-
}
|
1741 |
-
|
1742 |
-
for ($k = 0; $k <= $j; ++$k) {// eg. the length of substr($e_bits, $i, $j+1)
|
1743 |
-
$result = $this->_squareReduce($result, $n_value, $mode);
|
1744 |
-
}
|
1745 |
-
|
1746 |
-
$result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode);
|
1747 |
-
|
1748 |
-
$i+=$j + 1;
|
1749 |
-
}
|
1750 |
-
}
|
1751 |
-
|
1752 |
-
$temp = new Math_BigInteger();
|
1753 |
-
$temp->value = $this->_reduce($result, $n_value, $mode);
|
1754 |
-
|
1755 |
-
return $temp;
|
1756 |
-
}
|
1757 |
-
|
1758 |
-
/**
|
1759 |
-
* Modular reduction
|
1760 |
-
*
|
1761 |
-
* For most $modes this will return the remainder.
|
1762 |
-
*
|
1763 |
-
* @see _slidingWindow()
|
1764 |
-
* @access private
|
1765 |
-
* @param Array $x
|
1766 |
-
* @param Array $n
|
1767 |
-
* @param Integer $mode
|
1768 |
-
* @return Array
|
1769 |
-
*/
|
1770 |
-
function _reduce($x, $n, $mode)
|
1771 |
-
{
|
1772 |
-
switch ($mode) {
|
1773 |
-
case MATH_BIGINTEGER_MONTGOMERY:
|
1774 |
-
return $this->_montgomery($x, $n);
|
1775 |
-
case MATH_BIGINTEGER_BARRETT:
|
1776 |
-
return $this->_barrett($x, $n);
|
1777 |
-
case MATH_BIGINTEGER_POWEROF2:
|
1778 |
-
$lhs = new Math_BigInteger();
|
1779 |
-
$lhs->value = $x;
|
1780 |
-
$rhs = new Math_BigInteger();
|
1781 |
-
$rhs->value = $n;
|
1782 |
-
return $x->_mod2($n);
|
1783 |
-
case MATH_BIGINTEGER_CLASSIC:
|
1784 |
-
$lhs = new Math_BigInteger();
|
1785 |
-
$lhs->value = $x;
|
1786 |
-
$rhs = new Math_BigInteger();
|
1787 |
-
$rhs->value = $n;
|
1788 |
-
list(, $temp) = $lhs->divide($rhs);
|
1789 |
-
return $temp->value;
|
1790 |
-
case MATH_BIGINTEGER_NONE:
|
1791 |
-
return $x;
|
1792 |
-
default:
|
1793 |
-
// an invalid $mode was provided
|
1794 |
-
}
|
1795 |
-
}
|
1796 |
-
|
1797 |
-
/**
|
1798 |
-
* Modular reduction preperation
|
1799 |
-
*
|
1800 |
-
* @see _slidingWindow()
|
1801 |
-
* @access private
|
1802 |
-
* @param Array $x
|
1803 |
-
* @param Array $n
|
1804 |
-
* @param Integer $mode
|
1805 |
-
* @return Array
|
1806 |
-
*/
|
1807 |
-
function _prepareReduce($x, $n, $mode)
|
1808 |
-
{
|
1809 |
-
if ($mode == MATH_BIGINTEGER_MONTGOMERY) {
|
1810 |
-
return $this->_prepMontgomery($x, $n);
|
1811 |
-
}
|
1812 |
-
return $this->_reduce($x, $n, $mode);
|
1813 |
-
}
|
1814 |
-
|
1815 |
-
/**
|
1816 |
-
* Modular multiply
|
1817 |
-
*
|
1818 |
-
* @see _slidingWindow()
|
1819 |
-
* @access private
|
1820 |
-
* @param Array $x
|
1821 |
-
* @param Array $y
|
1822 |
-
* @param Array $n
|
1823 |
-
* @param Integer $mode
|
1824 |
-
* @return Array
|
1825 |
-
*/
|
1826 |
-
function _multiplyReduce($x, $y, $n, $mode)
|
1827 |
-
{
|
1828 |
-
if ($mode == MATH_BIGINTEGER_MONTGOMERY) {
|
1829 |
-
return $this->_montgomeryMultiply($x, $y, $n);
|
1830 |
-
}
|
1831 |
-
$temp = $this->_multiply($x, false, $y, false);
|
1832 |
-
return $this->_reduce($temp[MATH_BIGINTEGER_VALUE], $n, $mode);
|
1833 |
-
}
|
1834 |
-
|
1835 |
-
/**
|
1836 |
-
* Modular square
|
1837 |
-
*
|
1838 |
-
* @see _slidingWindow()
|
1839 |
-
* @access private
|
1840 |
-
* @param Array $x
|
1841 |
-
* @param Array $n
|
1842 |
-
* @param Integer $mode
|
1843 |
-
* @return Array
|
1844 |
-
*/
|
1845 |
-
function _squareReduce($x, $n, $mode)
|
1846 |
-
{
|
1847 |
-
if ($mode == MATH_BIGINTEGER_MONTGOMERY) {
|
1848 |
-
return $this->_montgomeryMultiply($x, $x, $n);
|
1849 |
-
}
|
1850 |
-
return $this->_reduce($this->_square($x), $n, $mode);
|
1851 |
-
}
|
1852 |
-
|
1853 |
-
/**
|
1854 |
-
* Modulos for Powers of Two
|
1855 |
-
*
|
1856 |
-
* Calculates $x%$n, where $n = 2**$e, for some $e. Since this is basically the same as doing $x & ($n-1),
|
1857 |
-
* we'll just use this function as a wrapper for doing that.
|
1858 |
-
*
|
1859 |
-
* @see _slidingWindow()
|
1860 |
-
* @access private
|
1861 |
-
* @param Math_BigInteger
|
1862 |
-
* @return Math_BigInteger
|
1863 |
-
*/
|
1864 |
-
function _mod2($n)
|
1865 |
-
{
|
1866 |
-
$temp = new Math_BigInteger();
|
1867 |
-
$temp->value = array(1);
|
1868 |
-
return $this->bitwise_and($n->subtract($temp));
|
1869 |
-
}
|
1870 |
-
|
1871 |
-
/**
|
1872 |
-
* Barrett Modular Reduction
|
1873 |
-
*
|
1874 |
-
* See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} /
|
1875 |
-
* {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly,
|
1876 |
-
* so as not to require negative numbers (initially, this script didn't support negative numbers).
|
1877 |
-
*
|
1878 |
-
* Employs "folding", as described at
|
1879 |
-
* {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from
|
1880 |
-
* it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x."
|
1881 |
-
*
|
1882 |
-
* Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that
|
1883 |
-
* usable on account of (1) its not using reasonable radix points as discussed in
|
1884 |
-
* {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable
|
1885 |
-
* radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that
|
1886 |
-
* (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line
|
1887 |
-
* comments for details.
|
1888 |
-
*
|
1889 |
-
* @see _slidingWindow()
|
1890 |
-
* @access private
|
1891 |
-
* @param Array $n
|
1892 |
-
* @param Array $m
|
1893 |
-
* @return Array
|
1894 |
-
*/
|
1895 |
-
function _barrett($n, $m)
|
1896 |
-
{
|
1897 |
-
static $cache = array(
|
1898 |
-
MATH_BIGINTEGER_VARIABLE => array(),
|
1899 |
-
MATH_BIGINTEGER_DATA => array()
|
1900 |
-
);
|
1901 |
-
|
1902 |
-
$m_length = count($m);
|
1903 |
-
|
1904 |
-
// if ($this->_compare($n, $this->_square($m)) >= 0) {
|
1905 |
-
if (count($n) > 2 * $m_length) {
|
1906 |
-
$lhs = new Math_BigInteger();
|
1907 |
-
$rhs = new Math_BigInteger();
|
1908 |
-
$lhs->value = $n;
|
1909 |
-
$rhs->value = $m;
|
1910 |
-
list(, $temp) = $lhs->divide($rhs);
|
1911 |
-
return $temp->value;
|
1912 |
-
}
|
1913 |
-
|
1914 |
-
// if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced
|
1915 |
-
if ($m_length < 5) {
|
1916 |
-
return $this->_regularBarrett($n, $m);
|
1917 |
-
}
|
1918 |
-
|
1919 |
-
// n = 2 * m.length
|
1920 |
-
|
1921 |
-
if ( ($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
|
1922 |
-
$key = count($cache[MATH_BIGINTEGER_VARIABLE]);
|
1923 |
-
$cache[MATH_BIGINTEGER_VARIABLE][] = $m;
|
1924 |
-
|
1925 |
-
$lhs = new Math_BigInteger();
|
1926 |
-
$lhs_value = &$lhs->value;
|
1927 |
-
$lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1));
|
1928 |
-
$lhs_value[] = 1;
|
1929 |
-
$rhs = new Math_BigInteger();
|
1930 |
-
$rhs->value = $m;
|
1931 |
-
|
1932 |
-
list($u, $m1) = $lhs->divide($rhs);
|
1933 |
-
$u = $u->value;
|
1934 |
-
$m1 = $m1->value;
|
1935 |
-
|
1936 |
-
$cache[MATH_BIGINTEGER_DATA][] = array(
|
1937 |
-
'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1)
|
1938 |
-
'm1'=> $m1 // m.length
|
1939 |
-
);
|
1940 |
-
} else {
|
1941 |
-
extract($cache[MATH_BIGINTEGER_DATA][$key]);
|
1942 |
-
}
|
1943 |
-
|
1944 |
-
$cutoff = $m_length + ($m_length >> 1);
|
1945 |
-
$lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1)
|
1946 |
-
$msd = array_slice($n, $cutoff); // m.length >> 1
|
1947 |
-
$lsd = $this->_trim($lsd);
|
1948 |
-
$temp = $this->_multiply($msd, false, $m1, false);
|
1949 |
-
$n = $this->_add($lsd, false, $temp[MATH_BIGINTEGER_VALUE], false); // m.length + (m.length >> 1) + 1
|
1950 |
-
|
1951 |
-
if ($m_length & 1) {
|
1952 |
-
return $this->_regularBarrett($n[MATH_BIGINTEGER_VALUE], $m);
|
1953 |
-
}
|
1954 |
-
|
1955 |
-
// (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2
|
1956 |
-
$temp = array_slice($n[MATH_BIGINTEGER_VALUE], $m_length - 1);
|
1957 |
-
// if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2
|
1958 |
-
// if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1
|
1959 |
-
$temp = $this->_multiply($temp, false, $u, false);
|
1960 |
-
// if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1
|
1961 |
-
// if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1)
|
1962 |
-
$temp = array_slice($temp[MATH_BIGINTEGER_VALUE], ($m_length >> 1) + 1);
|
1963 |
-
// if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1
|
1964 |
-
// if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1)
|
1965 |
-
$temp = $this->_multiply($temp, false, $m, false);
|
1966 |
-
|
1967 |
-
// at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit
|
1968 |
-
// number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop
|
1969 |
-
// following this comment would loop a lot (hence our calling _regularBarrett() in that situation).
|
1970 |
-
|
1971 |
-
$result = $this->_subtract($n[MATH_BIGINTEGER_VALUE], false, $temp[MATH_BIGINTEGER_VALUE], false);
|
1972 |
-
|
1973 |
-
while ($this->_compare($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $m, false) >= 0) {
|
1974 |
-
$result = $this->_subtract($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $m, false);
|
1975 |
-
}
|
1976 |
-
|
1977 |
-
return $result[MATH_BIGINTEGER_VALUE];
|
1978 |
-
}
|
1979 |
-
|
1980 |
-
/**
|
1981 |
-
* (Regular) Barrett Modular Reduction
|
1982 |
-
*
|
1983 |
-
* For numbers with more than four digits Math_BigInteger::_barrett() is faster. The difference between that and this
|
1984 |
-
* is that this function does not fold the denominator into a smaller form.
|
1985 |
-
*
|
1986 |
-
* @see _slidingWindow()
|
1987 |
-
* @access private
|
1988 |
-
* @param Array $x
|
1989 |
-
* @param Array $n
|
1990 |
-
* @return Array
|
1991 |
-
*/
|
1992 |
-
function _regularBarrett($x, $n)
|
1993 |
-
{
|
1994 |
-
static $cache = array(
|
1995 |
-
MATH_BIGINTEGER_VARIABLE => array(),
|
1996 |
-
MATH_BIGINTEGER_DATA => array()
|
1997 |
-
);
|
1998 |
-
|
1999 |
-
$n_length = count($n);
|
2000 |
-
|
2001 |
-
if (count($x) > 2 * $n_length) {
|
2002 |
-
$lhs = new Math_BigInteger();
|
2003 |
-
$rhs = new Math_BigInteger();
|
2004 |
-
$lhs->value = $x;
|
2005 |
-
$rhs->value = $n;
|
2006 |
-
list(, $temp) = $lhs->divide($rhs);
|
2007 |
-
return $temp->value;
|
2008 |
-
}
|
2009 |
-
|
2010 |
-
if ( ($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
|
2011 |
-
$key = count($cache[MATH_BIGINTEGER_VARIABLE]);
|
2012 |
-
$cache[MATH_BIGINTEGER_VARIABLE][] = $n;
|
2013 |
-
$lhs = new Math_BigInteger();
|
2014 |
-
$lhs_value = &$lhs->value;
|
2015 |
-
$lhs_value = $this->_array_repeat(0, 2 * $n_length);
|
2016 |
-
$lhs_value[] = 1;
|
2017 |
-
$rhs = new Math_BigInteger();
|
2018 |
-
$rhs->value = $n;
|
2019 |
-
list($temp, ) = $lhs->divide($rhs); // m.length
|
2020 |
-
$cache[MATH_BIGINTEGER_DATA][] = $temp->value;
|
2021 |
-
}
|
2022 |
-
|
2023 |
-
// 2 * m.length - (m.length - 1) = m.length + 1
|
2024 |
-
$temp = array_slice($x, $n_length - 1);
|
2025 |
-
// (m.length + 1) + m.length = 2 * m.length + 1
|
2026 |
-
$temp = $this->_multiply($temp, false, $cache[MATH_BIGINTEGER_DATA][$key], false);
|
2027 |
-
// (2 * m.length + 1) - (m.length - 1) = m.length + 2
|
2028 |
-
$temp = array_slice($temp[MATH_BIGINTEGER_VALUE], $n_length + 1);
|
2029 |
-
|
2030 |
-
// m.length + 1
|
2031 |
-
$result = array_slice($x, 0, $n_length + 1);
|
2032 |
-
// m.length + 1
|
2033 |
-
$temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1);
|
2034 |
-
// $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1)
|
2035 |
-
|
2036 |
-
if ($this->_compare($result, false, $temp[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_SIGN]) < 0) {
|
2037 |
-
$corrector_value = $this->_array_repeat(0, $n_length + 1);
|
2038 |
-
$corrector_value[] = 1;
|
2039 |
-
$result = $this->_add($result, false, $corrector, false);
|
2040 |
-
$result = $result[MATH_BIGINTEGER_VALUE];
|
2041 |
-
}
|
2042 |
-
|
2043 |
-
// at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits
|
2044 |
-
$result = $this->_subtract($result, false, $temp[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_SIGN]);
|
2045 |
-
while ($this->_compare($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $n, false) > 0) {
|
2046 |
-
$result = $this->_subtract($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $n, false);
|
2047 |
-
}
|
2048 |
-
|
2049 |
-
return $result[MATH_BIGINTEGER_VALUE];
|
2050 |
-
}
|
2051 |
-
|
2052 |
-
/**
|
2053 |
-
* Performs long multiplication up to $stop digits
|
2054 |
-
*
|
2055 |
-
* If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved.
|
2056 |
-
*
|
2057 |
-
* @see _regularBarrett()
|
2058 |
-
* @param Array $x_value
|
2059 |
-
* @param Boolean $x_negative
|
2060 |
-
* @param Array $y_value
|
2061 |
-
* @param Boolean $y_negative
|
2062 |
-
* @return Array
|
2063 |
-
* @access private
|
2064 |
-
*/
|
2065 |
-
function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop)
|
2066 |
-
{
|
2067 |
-
$x_length = count($x_value);
|
2068 |
-
$y_length = count($y_value);
|
2069 |
-
|
2070 |
-
if ( !$x_length || !$y_length ) { // a 0 is being multiplied
|
2071 |
-
return array(
|
2072 |
-
MATH_BIGINTEGER_VALUE => array(),
|
2073 |
-
MATH_BIGINTEGER_SIGN => false
|
2074 |
-
);
|
2075 |
-
}
|
2076 |
-
|
2077 |
-
if ( $x_length < $y_length ) {
|
2078 |
-
$temp = $x_value;
|
2079 |
-
$x_value = $y_value;
|
2080 |
-
$y_value = $temp;
|
2081 |
-
|
2082 |
-
$x_length = count($x_value);
|
2083 |
-
$y_length = count($y_value);
|
2084 |
-
}
|
2085 |
-
|
2086 |
-
$product_value = $this->_array_repeat(0, $x_length + $y_length);
|
2087 |
-
|
2088 |
-
// the following for loop could be removed if the for loop following it
|
2089 |
-
// (the one with nested for loops) initially set $i to 0, but
|
2090 |
-
// doing so would also make the result in one set of unnecessary adds,
|
2091 |
-
// since on the outermost loops first pass, $product->value[$k] is going
|
2092 |
-
// to always be 0
|
2093 |
-
|
2094 |
-
$carry = 0;
|
2095 |
-
|
2096 |
-
for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i
|
2097 |
-
$temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
|
2098 |
-
$carry = (int) ($temp / 0x4000000);
|
2099 |
-
$product_value[$j] = (int) ($temp - 0x4000000 * $carry);
|
2100 |
-
}
|
2101 |
-
|
2102 |
-
if ($j < $stop) {
|
2103 |
-
$product_value[$j] = $carry;
|
2104 |
-
}
|
2105 |
-
|
2106 |
-
// the above for loop is what the previous comment was talking about. the
|
2107 |
-
// following for loop is the "one with nested for loops"
|
2108 |
-
|
2109 |
-
for ($i = 1; $i < $y_length; ++$i) {
|
2110 |
-
$carry = 0;
|
2111 |
-
|
2112 |
-
for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {
|
2113 |
-
$temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
|
2114 |
-
$carry = (int) ($temp / 0x4000000);
|
2115 |
-
$product_value[$k] = (int) ($temp - 0x4000000 * $carry);
|
2116 |
-
}
|
2117 |
-
|
2118 |
-
if ($k < $stop) {
|
2119 |
-
$product_value[$k] = $carry;
|
2120 |
-
}
|
2121 |
-
}
|
2122 |
-
|
2123 |
-
return array(
|
2124 |
-
MATH_BIGINTEGER_VALUE => $this->_trim($product_value),
|
2125 |
-
MATH_BIGINTEGER_SIGN => $x_negative != $y_negative
|
2126 |
-
);
|
2127 |
-
}
|
2128 |
-
|
2129 |
-
/**
|
2130 |
-
* Montgomery Modular Reduction
|
2131 |
-
*
|
2132 |
-
* ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n.
|
2133 |
-
* {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be
|
2134 |
-
* improved upon (basically, by using the comba method). gcd($n, 2) must be equal to one for this function
|
2135 |
-
* to work correctly.
|
2136 |
-
*
|
2137 |
-
* @see _prepMontgomery()
|
2138 |
-
* @see _slidingWindow()
|
2139 |
-
* @access private
|
2140 |
-
* @param Array $x
|
2141 |
-
* @param Array $n
|
2142 |
-
* @return Array
|
2143 |
-
*/
|
2144 |
-
function _montgomery($x, $n)
|
2145 |
-
{
|
2146 |
-
static $cache = array(
|
2147 |
-
MATH_BIGINTEGER_VARIABLE => array(),
|
2148 |
-
MATH_BIGINTEGER_DATA => array()
|
2149 |
-
);
|
2150 |
-
|
2151 |
-
if ( ($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
|
2152 |
-
$key = count($cache[MATH_BIGINTEGER_VARIABLE]);
|
2153 |
-
$cache[MATH_BIGINTEGER_VARIABLE][] = $x;
|
2154 |
-
$cache[MATH_BIGINTEGER_DATA][] = $this->_modInverse67108864($n);
|
2155 |
-
}
|
2156 |
-
|
2157 |
-
$k = count($n);
|
2158 |
-
|
2159 |
-
$result = array(MATH_BIGINTEGER_VALUE => $x);
|
2160 |
-
|
2161 |
-
for ($i = 0; $i < $k; ++$i) {
|
2162 |
-
$temp = $result[MATH_BIGINTEGER_VALUE][$i] * $cache[MATH_BIGINTEGER_DATA][$key];
|
2163 |
-
$temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));
|
2164 |
-
$temp = $this->_regularMultiply(array($temp), $n);
|
2165 |
-
$temp = array_merge($this->_array_repeat(0, $i), $temp);
|
2166 |
-
$result = $this->_add($result[MATH_BIGINTEGER_VALUE], false, $temp, false);
|
2167 |
-
}
|
2168 |
-
|
2169 |
-
$result[MATH_BIGINTEGER_VALUE] = array_slice($result[MATH_BIGINTEGER_VALUE], $k);
|
2170 |
-
|
2171 |
-
if ($this->_compare($result, false, $n, false) >= 0) {
|
2172 |
-
$result = $this->_subtract($result[MATH_BIGINTEGER_VALUE], false, $n, false);
|
2173 |
-
}
|
2174 |
-
|
2175 |
-
return $result[MATH_BIGINTEGER_VALUE];
|
2176 |
-
}
|
2177 |
-
|
2178 |
-
/**
|
2179 |
-
* Montgomery Multiply
|
2180 |
-
*
|
2181 |
-
* Interleaves the montgomery reduction and long multiplication algorithms together as described in
|
2182 |
-
* {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36}
|
2183 |
-
*
|
2184 |
-
* @see _prepMontgomery()
|
2185 |
-
* @see _montgomery()
|
2186 |
-
* @access private
|
2187 |
-
* @param Array $x
|
2188 |
-
* @param Array $y
|
2189 |
-
* @param Array $m
|
2190 |
-
* @return Array
|
2191 |
-
*/
|
2192 |
-
function _montgomeryMultiply($x, $y, $m)
|
2193 |
-
{
|
2194 |
-
$temp = $this->_multiply($x, false, $y, false);
|
2195 |
-
return $this->_montgomery($temp[MATH_BIGINTEGER_VALUE], $m);
|
2196 |
-
|
2197 |
-
static $cache = array(
|
2198 |
-
MATH_BIGINTEGER_VARIABLE => array(),
|
2199 |
-
MATH_BIGINTEGER_DATA => array()
|
2200 |
-
);
|
2201 |
-
|
2202 |
-
if ( ($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
|
2203 |
-
$key = count($cache[MATH_BIGINTEGER_VARIABLE]);
|
2204 |
-
$cache[MATH_BIGINTEGER_VARIABLE][] = $m;
|
2205 |
-
$cache[MATH_BIGINTEGER_DATA][] = $this->_modInverse67108864($m);
|
2206 |
-
}
|
2207 |
-
|
2208 |
-
$n = max(count($x), count($y), count($m));
|
2209 |
-
$x = array_pad($x, $n, 0);
|
2210 |
-
$y = array_pad($y, $n, 0);
|
2211 |
-
$m = array_pad($m, $n, 0);
|
2212 |
-
$a = array(MATH_BIGINTEGER_VALUE => $this->_array_repeat(0, $n + 1));
|
2213 |
-
for ($i = 0; $i < $n; ++$i) {
|
2214 |
-
$temp = $a[MATH_BIGINTEGER_VALUE][0] + $x[$i] * $y[0];
|
2215 |
-
$temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));
|
2216 |
-
$temp = $temp * $cache[MATH_BIGINTEGER_DATA][$key];
|
2217 |
-
$temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));
|
2218 |
-
$temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false);
|
2219 |
-
$a = $this->_add($a[MATH_BIGINTEGER_VALUE], false, $temp[MATH_BIGINTEGER_VALUE], false);
|
2220 |
-
$a[MATH_BIGINTEGER_VALUE] = array_slice($a[MATH_BIGINTEGER_VALUE], 1);
|
2221 |
-
}
|
2222 |
-
if ($this->_compare($a[MATH_BIGINTEGER_VALUE], false, $m, false) >= 0) {
|
2223 |
-
$a = $this->_subtract($a[MATH_BIGINTEGER_VALUE], false, $m, false);
|
2224 |
-
}
|
2225 |
-
return $a[MATH_BIGINTEGER_VALUE];
|
2226 |
-
}
|
2227 |
-
|
2228 |
-
/**
|
2229 |
-
* Prepare a number for use in Montgomery Modular Reductions
|
2230 |
-
*
|
2231 |
-
* @see _montgomery()
|
2232 |
-
* @see _slidingWindow()
|
2233 |
-
* @access private
|
2234 |
-
* @param Array $x
|
2235 |
-
* @param Array $n
|
2236 |
-
* @return Array
|
2237 |
-
*/
|
2238 |
-
function _prepMontgomery($x, $n)
|
2239 |
-
{
|
2240 |
-
$lhs = new Math_BigInteger();
|
2241 |
-
$lhs->value = array_merge($this->_array_repeat(0, count($n)), $x);
|
2242 |
-
$rhs = new Math_BigInteger();
|
2243 |
-
$rhs->value = $n;
|
2244 |
-
|
2245 |
-
list(, $temp) = $lhs->divide($rhs);
|
2246 |
-
return $temp->value;
|
2247 |
-
}
|
2248 |
-
|
2249 |
-
/**
|
2250 |
-
* Modular Inverse of a number mod 2**26 (eg. 67108864)
|
2251 |
-
*
|
2252 |
-
* Based off of the bnpInvDigit function implemented and justified in the following URL:
|
2253 |
-
*
|
2254 |
-
* {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js}
|
2255 |
-
*
|
2256 |
-
* The following URL provides more info:
|
2257 |
-
*
|
2258 |
-
* {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85}
|
2259 |
-
*
|
2260 |
-
* As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For
|
2261 |
-
* instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields
|
2262 |
-
* int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't
|
2263 |
-
* auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that
|
2264 |
-
* the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the
|
2265 |
-
* maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to
|
2266 |
-
* 40 bits, which only 64-bit floating points will support.
|
2267 |
-
*
|
2268 |
-
* Thanks to Pedro Gimeno Fortea for input!
|
2269 |
-
*
|
2270 |
-
* @see _montgomery()
|
2271 |
-
* @access private
|
2272 |
-
* @param Array $x
|
2273 |
-
* @return Integer
|
2274 |
-
*/
|
2275 |
-
function _modInverse67108864($x) // 2**26 == 67108864
|
2276 |
-
{
|
2277 |
-
$x = -$x[0];
|
2278 |
-
$result = $x & 0x3; // x**-1 mod 2**2
|
2279 |
-
$result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4
|
2280 |
-
$result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8
|
2281 |
-
$result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16
|
2282 |
-
$result = fmod($result * (2 - fmod($x * $result, 0x4000000)), 0x4000000); // x**-1 mod 2**26
|
2283 |
-
return $result & 0x3FFFFFF;
|
2284 |
-
}
|
2285 |
-
|
2286 |
-
/**
|
2287 |
-
* Calculates modular inverses.
|
2288 |
-
*
|
2289 |
-
* Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses.
|
2290 |
-
*
|
2291 |
-
* Here's an example:
|
2292 |
-
* <code>
|
2293 |
-
* <?php
|
2294 |
-
* include('Math/BigInteger.php');
|
2295 |
-
*
|
2296 |
-
* $a = new Math_BigInteger(30);
|
2297 |
-
* $b = new Math_BigInteger(17);
|
2298 |
-
*
|
2299 |
-
* $c = $a->modInverse($b);
|
2300 |
-
* echo $c->toString(); // outputs 4
|
2301 |
-
*
|
2302 |
-
* echo "\r\n";
|
2303 |
-
*
|
2304 |
-
* $d = $a->multiply($c);
|
2305 |
-
* list(, $d) = $d->divide($b);
|
2306 |
-
* echo $d; // outputs 1 (as per the definition of modular inverse)
|
2307 |
-
* ?>
|
2308 |
-
* </code>
|
2309 |
-
*
|
2310 |
-
* @param Math_BigInteger $n
|
2311 |
-
* @return mixed false, if no modular inverse exists, Math_BigInteger, otherwise.
|
2312 |
-
* @access public
|
2313 |
-
* @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.
|
2314 |
-
*/
|
2315 |
-
function modInverse($n)
|
2316 |
-
{
|
2317 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2318 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2319 |
-
$temp = new Math_BigInteger();
|
2320 |
-
$temp->value = gmp_invert($this->value, $n->value);
|
2321 |
-
|
2322 |
-
return ( $temp->value === false ) ? false : $this->_normalize($temp);
|
2323 |
-
}
|
2324 |
-
|
2325 |
-
static $zero, $one;
|
2326 |
-
if (!isset($zero)) {
|
2327 |
-
$zero = new Math_BigInteger();
|
2328 |
-
$one = new Math_BigInteger(1);
|
2329 |
-
}
|
2330 |
-
|
2331 |
-
// $x mod $n == $x mod -$n.
|
2332 |
-
$n = $n->abs();
|
2333 |
-
|
2334 |
-
if ($this->compare($zero) < 0) {
|
2335 |
-
$temp = $this->abs();
|
2336 |
-
$temp = $temp->modInverse($n);
|
2337 |
-
return $negated === false ? false : $this->_normalize($n->subtract($temp));
|
2338 |
-
}
|
2339 |
-
|
2340 |
-
extract($this->extendedGCD($n));
|
2341 |
-
|
2342 |
-
if (!$gcd->equals($one)) {
|
2343 |
-
return false;
|
2344 |
-
}
|
2345 |
-
|
2346 |
-
$x = $x->compare($zero) < 0 ? $x->add($n) : $x;
|
2347 |
-
|
2348 |
-
return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x);
|
2349 |
-
}
|
2350 |
-
|
2351 |
-
/**
|
2352 |
-
* Calculates the greatest common divisor and B�zout's identity.
|
2353 |
-
*
|
2354 |
-
* Say you have 693 and 609. The GCD is 21. B�zout's identity states that there exist integers x and y such that
|
2355 |
-
* 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which
|
2356 |
-
* combination is returned is dependant upon which mode is in use. See
|
2357 |
-
* {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity B�zout's identity - Wikipedia} for more information.
|
2358 |
-
*
|
2359 |
-
* Here's an example:
|
2360 |
-
* <code>
|
2361 |
-
* <?php
|
2362 |
-
* include('Math/BigInteger.php');
|
2363 |
-
*
|
2364 |
-
* $a = new Math_BigInteger(693);
|
2365 |
-
* $b = new Math_BigInteger(609);
|
2366 |
-
*
|
2367 |
-
* extract($a->extendedGCD($b));
|
2368 |
-
*
|
2369 |
-
* echo $gcd->toString() . "\r\n"; // outputs 21
|
2370 |
-
* echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21
|
2371 |
-
* ?>
|
2372 |
-
* </code>
|
2373 |
-
*
|
2374 |
-
* @param Math_BigInteger $n
|
2375 |
-
* @return Math_BigInteger
|
2376 |
-
* @access public
|
2377 |
-
* @internal Calculates the GCD using the binary xGCD algorithim described in
|
2378 |
-
* {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}. As the text above 14.61 notes,
|
2379 |
-
* the more traditional algorithim requires "relatively costly multiple-precision divisions".
|
2380 |
-
*/
|
2381 |
-
function extendedGCD($n)
|
2382 |
-
{
|
2383 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2384 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2385 |
-
extract(gmp_gcdext($this->value, $n->value));
|
2386 |
-
|
2387 |
-
return array(
|
2388 |
-
'gcd' => $this->_normalize(new Math_BigInteger($g)),
|
2389 |
-
'x' => $this->_normalize(new Math_BigInteger($s)),
|
2390 |
-
'y' => $this->_normalize(new Math_BigInteger($t))
|
2391 |
-
);
|
2392 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
2393 |
-
// it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works
|
2394 |
-
// best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is,
|
2395 |
-
// the basic extended euclidean algorithim is what we're using.
|
2396 |
-
|
2397 |
-
$u = $this->value;
|
2398 |
-
$v = $n->value;
|
2399 |
-
|
2400 |
-
$a = '1';
|
2401 |
-
$b = '0';
|
2402 |
-
$c = '0';
|
2403 |
-
$d = '1';
|
2404 |
-
|
2405 |
-
while (bccomp($v, '0', 0) != 0) {
|
2406 |
-
$q = bcdiv($u, $v, 0);
|
2407 |
-
|
2408 |
-
$temp = $u;
|
2409 |
-
$u = $v;
|
2410 |
-
$v = bcsub($temp, bcmul($v, $q, 0), 0);
|
2411 |
-
|
2412 |
-
$temp = $a;
|
2413 |
-
$a = $c;
|
2414 |
-
$c = bcsub($temp, bcmul($a, $q, 0), 0);
|
2415 |
-
|
2416 |
-
$temp = $b;
|
2417 |
-
$b = $d;
|
2418 |
-
$d = bcsub($temp, bcmul($b, $q, 0), 0);
|
2419 |
-
}
|
2420 |
-
|
2421 |
-
return array(
|
2422 |
-
'gcd' => $this->_normalize(new Math_BigInteger($u)),
|
2423 |
-
'x' => $this->_normalize(new Math_BigInteger($a)),
|
2424 |
-
'y' => $this->_normalize(new Math_BigInteger($b))
|
2425 |
-
);
|
2426 |
-
}
|
2427 |
-
|
2428 |
-
$y = $n->copy();
|
2429 |
-
$x = $this->copy();
|
2430 |
-
$g = new Math_BigInteger();
|
2431 |
-
$g->value = array(1);
|
2432 |
-
|
2433 |
-
while ( !(($x->value[0] & 1)|| ($y->value[0] & 1)) ) {
|
2434 |
-
$x->_rshift(1);
|
2435 |
-
$y->_rshift(1);
|
2436 |
-
$g->_lshift(1);
|
2437 |
-
}
|
2438 |
-
|
2439 |
-
$u = $x->copy();
|
2440 |
-
$v = $y->copy();
|
2441 |
-
|
2442 |
-
$a = new Math_BigInteger();
|
2443 |
-
$b = new Math_BigInteger();
|
2444 |
-
$c = new Math_BigInteger();
|
2445 |
-
$d = new Math_BigInteger();
|
2446 |
-
|
2447 |
-
$a->value = $d->value = $g->value = array(1);
|
2448 |
-
$b->value = $c->value = array();
|
2449 |
-
|
2450 |
-
while ( !empty($u->value) ) {
|
2451 |
-
while ( !($u->value[0] & 1) ) {
|
2452 |
-
$u->_rshift(1);
|
2453 |
-
if ( (!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1)) ) {
|
2454 |
-
$a = $a->add($y);
|
2455 |
-
$b = $b->subtract($x);
|
2456 |
-
}
|
2457 |
-
$a->_rshift(1);
|
2458 |
-
$b->_rshift(1);
|
2459 |
-
}
|
2460 |
-
|
2461 |
-
while ( !($v->value[0] & 1) ) {
|
2462 |
-
$v->_rshift(1);
|
2463 |
-
if ( (!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1)) ) {
|
2464 |
-
$c = $c->add($y);
|
2465 |
-
$d = $d->subtract($x);
|
2466 |
-
}
|
2467 |
-
$c->_rshift(1);
|
2468 |
-
$d->_rshift(1);
|
2469 |
-
}
|
2470 |
-
|
2471 |
-
if ($u->compare($v) >= 0) {
|
2472 |
-
$u = $u->subtract($v);
|
2473 |
-
$a = $a->subtract($c);
|
2474 |
-
$b = $b->subtract($d);
|
2475 |
-
} else {
|
2476 |
-
$v = $v->subtract($u);
|
2477 |
-
$c = $c->subtract($a);
|
2478 |
-
$d = $d->subtract($b);
|
2479 |
-
}
|
2480 |
-
}
|
2481 |
-
|
2482 |
-
return array(
|
2483 |
-
'gcd' => $this->_normalize($g->multiply($v)),
|
2484 |
-
'x' => $this->_normalize($c),
|
2485 |
-
'y' => $this->_normalize($d)
|
2486 |
-
);
|
2487 |
-
}
|
2488 |
-
|
2489 |
-
/**
|
2490 |
-
* Calculates the greatest common divisor
|
2491 |
-
*
|
2492 |
-
* Say you have 693 and 609. The GCD is 21.
|
2493 |
-
*
|
2494 |
-
* Here's an example:
|
2495 |
-
* <code>
|
2496 |
-
* <?php
|
2497 |
-
* include('Math/BigInteger.php');
|
2498 |
-
*
|
2499 |
-
* $a = new Math_BigInteger(693);
|
2500 |
-
* $b = new Math_BigInteger(609);
|
2501 |
-
*
|
2502 |
-
* $gcd = a->extendedGCD($b);
|
2503 |
-
*
|
2504 |
-
* echo $gcd->toString() . "\r\n"; // outputs 21
|
2505 |
-
* ?>
|
2506 |
-
* </code>
|
2507 |
-
*
|
2508 |
-
* @param Math_BigInteger $n
|
2509 |
-
* @return Math_BigInteger
|
2510 |
-
* @access public
|
2511 |
-
*/
|
2512 |
-
function gcd($n)
|
2513 |
-
{
|
2514 |
-
extract($this->extendedGCD($n));
|
2515 |
-
return $gcd;
|
2516 |
-
}
|
2517 |
-
|
2518 |
-
/**
|
2519 |
-
* Absolute value.
|
2520 |
-
*
|
2521 |
-
* @return Math_BigInteger
|
2522 |
-
* @access public
|
2523 |
-
*/
|
2524 |
-
function abs()
|
2525 |
-
{
|
2526 |
-
$temp = new Math_BigInteger();
|
2527 |
-
|
2528 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2529 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2530 |
-
$temp->value = gmp_abs($this->value);
|
2531 |
-
break;
|
2532 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
2533 |
-
$temp->value = (bccomp($this->value, '0', 0) < 0) ? substr($this->value, 1) : $this->value;
|
2534 |
-
break;
|
2535 |
-
default:
|
2536 |
-
$temp->value = $this->value;
|
2537 |
-
}
|
2538 |
-
|
2539 |
-
return $temp;
|
2540 |
-
}
|
2541 |
-
|
2542 |
-
/**
|
2543 |
-
* Compares two numbers.
|
2544 |
-
*
|
2545 |
-
* Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is
|
2546 |
-
* demonstrated thusly:
|
2547 |
-
*
|
2548 |
-
* $x > $y: $x->compare($y) > 0
|
2549 |
-
* $x < $y: $x->compare($y) < 0
|
2550 |
-
* $x == $y: $x->compare($y) == 0
|
2551 |
-
*
|
2552 |
-
* Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y).
|
2553 |
-
*
|
2554 |
-
* @param Math_BigInteger $x
|
2555 |
-
* @return Integer < 0 if $this is less than $x; > 0 if $this is greater than $x, and 0 if they are equal.
|
2556 |
-
* @access public
|
2557 |
-
* @see equals()
|
2558 |
-
* @internal Could return $this->subtract($x), but that's not as fast as what we do do.
|
2559 |
-
*/
|
2560 |
-
function compare($y)
|
2561 |
-
{
|
2562 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2563 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2564 |
-
return gmp_cmp($this->value, $y->value);
|
2565 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
2566 |
-
return bccomp($this->value, $y->value, 0);
|
2567 |
-
}
|
2568 |
-
|
2569 |
-
return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative);
|
2570 |
-
}
|
2571 |
-
|
2572 |
-
/**
|
2573 |
-
* Compares two numbers.
|
2574 |
-
*
|
2575 |
-
* @param Array $x_value
|
2576 |
-
* @param Boolean $x_negative
|
2577 |
-
* @param Array $y_value
|
2578 |
-
* @param Boolean $y_negative
|
2579 |
-
* @return Integer
|
2580 |
-
* @see compare()
|
2581 |
-
* @access private
|
2582 |
-
*/
|
2583 |
-
function _compare($x_value, $x_negative, $y_value, $y_negative)
|
2584 |
-
{
|
2585 |
-
if ( $x_negative != $y_negative ) {
|
2586 |
-
return ( !$x_negative && $y_negative ) ? 1 : -1;
|
2587 |
-
}
|
2588 |
-
|
2589 |
-
$result = $x_negative ? -1 : 1;
|
2590 |
-
|
2591 |
-
if ( count($x_value) != count($y_value) ) {
|
2592 |
-
return ( count($x_value) > count($y_value) ) ? $result : -$result;
|
2593 |
-
}
|
2594 |
-
$size = max(count($x_value), count($y_value));
|
2595 |
-
|
2596 |
-
$x_value = array_pad($x_value, $size, 0);
|
2597 |
-
$y_value = array_pad($y_value, $size, 0);
|
2598 |
-
|
2599 |
-
for ($i = count($x_value) - 1; $i >= 0; --$i) {
|
2600 |
-
if ($x_value[$i] != $y_value[$i]) {
|
2601 |
-
return ( $x_value[$i] > $y_value[$i] ) ? $result : -$result;
|
2602 |
-
}
|
2603 |
-
}
|
2604 |
-
|
2605 |
-
return 0;
|
2606 |
-
}
|
2607 |
-
|
2608 |
-
/**
|
2609 |
-
* Tests the equality of two numbers.
|
2610 |
-
*
|
2611 |
-
* If you need to see if one number is greater than or less than another number, use Math_BigInteger::compare()
|
2612 |
-
*
|
2613 |
-
* @param Math_BigInteger $x
|
2614 |
-
* @return Boolean
|
2615 |
-
* @access public
|
2616 |
-
* @see compare()
|
2617 |
-
*/
|
2618 |
-
function equals($x)
|
2619 |
-
{
|
2620 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2621 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2622 |
-
return gmp_cmp($this->value, $x->value) == 0;
|
2623 |
-
default:
|
2624 |
-
return $this->value === $x->value && $this->is_negative == $x->is_negative;
|
2625 |
-
}
|
2626 |
-
}
|
2627 |
-
|
2628 |
-
/**
|
2629 |
-
* Set Precision
|
2630 |
-
*
|
2631 |
-
* Some bitwise operations give different results depending on the precision being used. Examples include left
|
2632 |
-
* shift, not, and rotates.
|
2633 |
-
*
|
2634 |
-
* @param Math_BigInteger $x
|
2635 |
-
* @access public
|
2636 |
-
* @return Math_BigInteger
|
2637 |
-
*/
|
2638 |
-
function setPrecision($bits)
|
2639 |
-
{
|
2640 |
-
$this->precision = $bits;
|
2641 |
-
if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_BCMATH ) {
|
2642 |
-
$this->bitmask = new Math_BigInteger(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256);
|
2643 |
-
} else {
|
2644 |
-
$this->bitmask = new Math_BigInteger(bcpow('2', $bits, 0));
|
2645 |
-
}
|
2646 |
-
|
2647 |
-
$temp = $this->_normalize($this);
|
2648 |
-
$this->value = $temp->value;
|
2649 |
-
}
|
2650 |
-
|
2651 |
-
/**
|
2652 |
-
* Logical And
|
2653 |
-
*
|
2654 |
-
* @param Math_BigInteger $x
|
2655 |
-
* @access public
|
2656 |
-
* @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
|
2657 |
-
* @return Math_BigInteger
|
2658 |
-
*/
|
2659 |
-
function bitwise_and($x)
|
2660 |
-
{
|
2661 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2662 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2663 |
-
$temp = new Math_BigInteger();
|
2664 |
-
$temp->value = gmp_and($this->value, $x->value);
|
2665 |
-
|
2666 |
-
return $this->_normalize($temp);
|
2667 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
2668 |
-
$left = $this->toBytes();
|
2669 |
-
$right = $x->toBytes();
|
2670 |
-
|
2671 |
-
$length = max(strlen($left), strlen($right));
|
2672 |
-
|
2673 |
-
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
|
2674 |
-
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
|
2675 |
-
|
2676 |
-
return $this->_normalize(new Math_BigInteger($left & $right, 256));
|
2677 |
-
}
|
2678 |
-
|
2679 |
-
$result = $this->copy();
|
2680 |
-
|
2681 |
-
$length = min(count($x->value), count($this->value));
|
2682 |
-
|
2683 |
-
$result->value = array_slice($result->value, 0, $length);
|
2684 |
-
|
2685 |
-
for ($i = 0; $i < $length; ++$i) {
|
2686 |
-
$result->value[$i] = $result->value[$i] & $x->value[$i];
|
2687 |
-
}
|
2688 |
-
|
2689 |
-
return $this->_normalize($result);
|
2690 |
-
}
|
2691 |
-
|
2692 |
-
/**
|
2693 |
-
* Logical Or
|
2694 |
-
*
|
2695 |
-
* @param Math_BigInteger $x
|
2696 |
-
* @access public
|
2697 |
-
* @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
|
2698 |
-
* @return Math_BigInteger
|
2699 |
-
*/
|
2700 |
-
function bitwise_or($x)
|
2701 |
-
{
|
2702 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2703 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2704 |
-
$temp = new Math_BigInteger();
|
2705 |
-
$temp->value = gmp_or($this->value, $x->value);
|
2706 |
-
|
2707 |
-
return $this->_normalize($temp);
|
2708 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
2709 |
-
$left = $this->toBytes();
|
2710 |
-
$right = $x->toBytes();
|
2711 |
-
|
2712 |
-
$length = max(strlen($left), strlen($right));
|
2713 |
-
|
2714 |
-
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
|
2715 |
-
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
|
2716 |
-
|
2717 |
-
return $this->_normalize(new Math_BigInteger($left | $right, 256));
|
2718 |
-
}
|
2719 |
-
|
2720 |
-
$length = max(count($this->value), count($x->value));
|
2721 |
-
$result = $this->copy();
|
2722 |
-
$result->value = array_pad($result->value, 0, $length);
|
2723 |
-
$x->value = array_pad($x->value, 0, $length);
|
2724 |
-
|
2725 |
-
for ($i = 0; $i < $length; ++$i) {
|
2726 |
-
$result->value[$i] = $this->value[$i] | $x->value[$i];
|
2727 |
-
}
|
2728 |
-
|
2729 |
-
return $this->_normalize($result);
|
2730 |
-
}
|
2731 |
-
|
2732 |
-
/**
|
2733 |
-
* Logical Exclusive-Or
|
2734 |
-
*
|
2735 |
-
* @param Math_BigInteger $x
|
2736 |
-
* @access public
|
2737 |
-
* @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
|
2738 |
-
* @return Math_BigInteger
|
2739 |
-
*/
|
2740 |
-
function bitwise_xor($x)
|
2741 |
-
{
|
2742 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2743 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2744 |
-
$temp = new Math_BigInteger();
|
2745 |
-
$temp->value = gmp_xor($this->value, $x->value);
|
2746 |
-
|
2747 |
-
return $this->_normalize($temp);
|
2748 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
2749 |
-
$left = $this->toBytes();
|
2750 |
-
$right = $x->toBytes();
|
2751 |
-
|
2752 |
-
$length = max(strlen($left), strlen($right));
|
2753 |
-
|
2754 |
-
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
|
2755 |
-
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
|
2756 |
-
|
2757 |
-
return $this->_normalize(new Math_BigInteger($left ^ $right, 256));
|
2758 |
-
}
|
2759 |
-
|
2760 |
-
$length = max(count($this->value), count($x->value));
|
2761 |
-
$result = $this->copy();
|
2762 |
-
$result->value = array_pad($result->value, 0, $length);
|
2763 |
-
$x->value = array_pad($x->value, 0, $length);
|
2764 |
-
|
2765 |
-
for ($i = 0; $i < $length; ++$i) {
|
2766 |
-
$result->value[$i] = $this->value[$i] ^ $x->value[$i];
|
2767 |
-
}
|
2768 |
-
|
2769 |
-
return $this->_normalize($result);
|
2770 |
-
}
|
2771 |
-
|
2772 |
-
/**
|
2773 |
-
* Logical Not
|
2774 |
-
*
|
2775 |
-
* @access public
|
2776 |
-
* @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
|
2777 |
-
* @return Math_BigInteger
|
2778 |
-
*/
|
2779 |
-
function bitwise_not()
|
2780 |
-
{
|
2781 |
-
// calculuate "not" without regard to $this->precision
|
2782 |
-
// (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
|
2783 |
-
$temp = $this->toBytes();
|
2784 |
-
$pre_msb = decbin(ord($temp[0]));
|
2785 |
-
$temp = ~$temp;
|
2786 |
-
$msb = decbin(ord($temp[0]));
|
2787 |
-
if (strlen($msb) == 8) {
|
2788 |
-
$msb = substr($msb, strpos($msb, '0'));
|
2789 |
-
}
|
2790 |
-
$temp[0] = chr(bindec($msb));
|
2791 |
-
|
2792 |
-
// see if we need to add extra leading 1's
|
2793 |
-
$current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8;
|
2794 |
-
$new_bits = $this->precision - $current_bits;
|
2795 |
-
if ($new_bits <= 0) {
|
2796 |
-
return $this->_normalize(new Math_BigInteger($temp, 256));
|
2797 |
-
}
|
2798 |
-
|
2799 |
-
// generate as many leading 1's as we need to.
|
2800 |
-
$leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3);
|
2801 |
-
$this->_base256_lshift($leading_ones, $current_bits);
|
2802 |
-
|
2803 |
-
$temp = str_pad($temp, ceil($this->bits / 8), chr(0), STR_PAD_LEFT);
|
2804 |
-
|
2805 |
-
return $this->_normalize(new Math_BigInteger($leading_ones | $temp, 256));
|
2806 |
-
}
|
2807 |
-
|
2808 |
-
/**
|
2809 |
-
* Logical Right Shift
|
2810 |
-
*
|
2811 |
-
* Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift.
|
2812 |
-
*
|
2813 |
-
* @param Integer $shift
|
2814 |
-
* @return Math_BigInteger
|
2815 |
-
* @access public
|
2816 |
-
* @internal The only version that yields any speed increases is the internal version.
|
2817 |
-
*/
|
2818 |
-
function bitwise_rightShift($shift)
|
2819 |
-
{
|
2820 |
-
$temp = new Math_BigInteger();
|
2821 |
-
|
2822 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2823 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2824 |
-
static $two;
|
2825 |
-
|
2826 |
-
if (!isset($two)) {
|
2827 |
-
$two = gmp_init('2');
|
2828 |
-
}
|
2829 |
-
|
2830 |
-
$temp->value = gmp_div_q($this->value, gmp_pow($two, $shift));
|
2831 |
-
|
2832 |
-
break;
|
2833 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
2834 |
-
$temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0);
|
2835 |
-
|
2836 |
-
break;
|
2837 |
-
default: // could just replace _lshift with this, but then all _lshift() calls would need to be rewritten
|
2838 |
-
// and I don't want to do that...
|
2839 |
-
$temp->value = $this->value;
|
2840 |
-
$temp->_rshift($shift);
|
2841 |
-
}
|
2842 |
-
|
2843 |
-
return $this->_normalize($temp);
|
2844 |
-
}
|
2845 |
-
|
2846 |
-
/**
|
2847 |
-
* Logical Left Shift
|
2848 |
-
*
|
2849 |
-
* Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.
|
2850 |
-
*
|
2851 |
-
* @param Integer $shift
|
2852 |
-
* @return Math_BigInteger
|
2853 |
-
* @access public
|
2854 |
-
* @internal The only version that yields any speed increases is the internal version.
|
2855 |
-
*/
|
2856 |
-
function bitwise_leftShift($shift)
|
2857 |
-
{
|
2858 |
-
$temp = new Math_BigInteger();
|
2859 |
-
|
2860 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
2861 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
2862 |
-
static $two;
|
2863 |
-
|
2864 |
-
if (!isset($two)) {
|
2865 |
-
$two = gmp_init('2');
|
2866 |
-
}
|
2867 |
-
|
2868 |
-
$temp->value = gmp_mul($this->value, gmp_pow($two, $shift));
|
2869 |
-
|
2870 |
-
break;
|
2871 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
2872 |
-
$temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0);
|
2873 |
-
|
2874 |
-
break;
|
2875 |
-
default: // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten
|
2876 |
-
// and I don't want to do that...
|
2877 |
-
$temp->value = $this->value;
|
2878 |
-
$temp->_lshift($shift);
|
2879 |
-
}
|
2880 |
-
|
2881 |
-
return $this->_normalize($temp);
|
2882 |
-
}
|
2883 |
-
|
2884 |
-
/**
|
2885 |
-
* Logical Left Rotate
|
2886 |
-
*
|
2887 |
-
* Instead of the top x bits being dropped they're appended to the shifted bit string.
|
2888 |
-
*
|
2889 |
-
* @param Integer $shift
|
2890 |
-
* @return Math_BigInteger
|
2891 |
-
* @access public
|
2892 |
-
*/
|
2893 |
-
function bitwise_leftRotate($shift)
|
2894 |
-
{
|
2895 |
-
$bits = $this->toBytes();
|
2896 |
-
|
2897 |
-
if ($this->precision > 0) {
|
2898 |
-
$precision = $this->precision;
|
2899 |
-
if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH ) {
|
2900 |
-
$mask = $this->bitmask->subtract(new Math_BigInteger(1));
|
2901 |
-
$mask = $mask->toBytes();
|
2902 |
-
} else {
|
2903 |
-
$mask = $this->bitmask->toBytes();
|
2904 |
-
}
|
2905 |
-
} else {
|
2906 |
-
$temp = ord($bits[0]);
|
2907 |
-
for ($i = 0; $temp >> $i; ++$i);
|
2908 |
-
$precision = 8 * strlen($bits) - 8 + $i;
|
2909 |
-
$mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3);
|
2910 |
-
}
|
2911 |
-
|
2912 |
-
if ($shift < 0) {
|
2913 |
-
$shift+= $precision;
|
2914 |
-
}
|
2915 |
-
$shift%= $precision;
|
2916 |
-
|
2917 |
-
if (!$shift) {
|
2918 |
-
return $this->copy();
|
2919 |
-
}
|
2920 |
-
|
2921 |
-
$left = $this->bitwise_leftShift($shift);
|
2922 |
-
$left = $left->bitwise_and(new Math_BigInteger($mask, 256));
|
2923 |
-
$right = $this->bitwise_rightShift($precision - $shift);
|
2924 |
-
$result = MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_BCMATH ? $left->bitwise_or($right) : $left->add($right);
|
2925 |
-
return $this->_normalize($result);
|
2926 |
-
}
|
2927 |
-
|
2928 |
-
/**
|
2929 |
-
* Logical Right Rotate
|
2930 |
-
*
|
2931 |
-
* Instead of the bottom x bits being dropped they're prepended to the shifted bit string.
|
2932 |
-
*
|
2933 |
-
* @param Integer $shift
|
2934 |
-
* @return Math_BigInteger
|
2935 |
-
* @access public
|
2936 |
-
*/
|
2937 |
-
function bitwise_rightRotate($shift)
|
2938 |
-
{
|
2939 |
-
return $this->bitwise_leftRotate(-$shift);
|
2940 |
-
}
|
2941 |
-
|
2942 |
-
/**
|
2943 |
-
* Set random number generator function
|
2944 |
-
*
|
2945 |
-
* $generator should be the name of a random generating function whose first parameter is the minimum
|
2946 |
-
* value and whose second parameter is the maximum value. If this function needs to be seeded, it should
|
2947 |
-
* be seeded prior to calling Math_BigInteger::random() or Math_BigInteger::randomPrime()
|
2948 |
-
*
|
2949 |
-
* If the random generating function is not explicitly set, it'll be assumed to be mt_rand().
|
2950 |
-
*
|
2951 |
-
* @see random()
|
2952 |
-
* @see randomPrime()
|
2953 |
-
* @param optional String $generator
|
2954 |
-
* @access public
|
2955 |
-
*/
|
2956 |
-
function setRandomGenerator($generator)
|
2957 |
-
{
|
2958 |
-
$this->generator = $generator;
|
2959 |
-
}
|
2960 |
-
|
2961 |
-
/**
|
2962 |
-
* Generate a random number
|
2963 |
-
*
|
2964 |
-
* @param optional Integer $min
|
2965 |
-
* @param optional Integer $max
|
2966 |
-
* @return Math_BigInteger
|
2967 |
-
* @access public
|
2968 |
-
*/
|
2969 |
-
function random($min = false, $max = false)
|
2970 |
-
{
|
2971 |
-
if ($min === false) {
|
2972 |
-
$min = new Math_BigInteger(0);
|
2973 |
-
}
|
2974 |
-
|
2975 |
-
if ($max === false) {
|
2976 |
-
$max = new Math_BigInteger(0x7FFFFFFF);
|
2977 |
-
}
|
2978 |
-
|
2979 |
-
$compare = $max->compare($min);
|
2980 |
-
|
2981 |
-
if (!$compare) {
|
2982 |
-
return $this->_normalize($min);
|
2983 |
-
} else if ($compare < 0) {
|
2984 |
-
// if $min is bigger then $max, swap $min and $max
|
2985 |
-
$temp = $max;
|
2986 |
-
$max = $min;
|
2987 |
-
$min = $temp;
|
2988 |
-
}
|
2989 |
-
|
2990 |
-
$generator = $this->generator;
|
2991 |
-
|
2992 |
-
$max = $max->subtract($min);
|
2993 |
-
$max = ltrim($max->toBytes(), chr(0));
|
2994 |
-
$size = strlen($max) - 1;
|
2995 |
-
$random = '';
|
2996 |
-
|
2997 |
-
$bytes = $size & 1;
|
2998 |
-
for ($i = 0; $i < $bytes; ++$i) {
|
2999 |
-
$random.= chr($generator(0, 255));
|
3000 |
-
}
|
3001 |
-
|
3002 |
-
$blocks = $size >> 1;
|
3003 |
-
for ($i = 0; $i < $blocks; ++$i) {
|
3004 |
-
// mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
|
3005 |
-
$random.= pack('n', $generator(0, 0xFFFF));
|
3006 |
-
}
|
3007 |
-
|
3008 |
-
$temp = new Math_BigInteger($random, 256);
|
3009 |
-
if ($temp->compare(new Math_BigInteger(substr($max, 1), 256)) > 0) {
|
3010 |
-
$random = chr($generator(0, ord($max[0]) - 1)) . $random;
|
3011 |
-
} else {
|
3012 |
-
$random = chr($generator(0, ord($max[0]) )) . $random;
|
3013 |
-
}
|
3014 |
-
|
3015 |
-
$random = new Math_BigInteger($random, 256);
|
3016 |
-
|
3017 |
-
return $this->_normalize($random->add($min));
|
3018 |
-
}
|
3019 |
-
|
3020 |
-
/**
|
3021 |
-
* Generate a random prime number.
|
3022 |
-
*
|
3023 |
-
* If there's not a prime within the given range, false will be returned. If more than $timeout seconds have elapsed,
|
3024 |
-
* give up and return false.
|
3025 |
-
*
|
3026 |
-
* @param optional Integer $min
|
3027 |
-
* @param optional Integer $max
|
3028 |
-
* @param optional Integer $timeout
|
3029 |
-
* @return Math_BigInteger
|
3030 |
-
* @access public
|
3031 |
-
* @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.
|
3032 |
-
*/
|
3033 |
-
function randomPrime($min = false, $max = false, $timeout = false)
|
3034 |
-
{
|
3035 |
-
$compare = $max->compare($min);
|
3036 |
-
|
3037 |
-
if (!$compare) {
|
3038 |
-
return $min;
|
3039 |
-
} else if ($compare < 0) {
|
3040 |
-
// if $min is bigger then $max, swap $min and $max
|
3041 |
-
$temp = $max;
|
3042 |
-
$max = $min;
|
3043 |
-
$min = $temp;
|
3044 |
-
}
|
3045 |
-
|
3046 |
-
// gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
|
3047 |
-
if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP && function_exists('gmp_nextprime') ) {
|
3048 |
-
// we don't rely on Math_BigInteger::random()'s min / max when gmp_nextprime() is being used since this function
|
3049 |
-
// does its own checks on $max / $min when gmp_nextprime() is used. When gmp_nextprime() is not used, however,
|
3050 |
-
// the same $max / $min checks are not performed.
|
3051 |
-
if ($min === false) {
|
3052 |
-
$min = new Math_BigInteger(0);
|
3053 |
-
}
|
3054 |
-
|
3055 |
-
if ($max === false) {
|
3056 |
-
$max = new Math_BigInteger(0x7FFFFFFF);
|
3057 |
-
}
|
3058 |
-
|
3059 |
-
$x = $this->random($min, $max);
|
3060 |
-
|
3061 |
-
$x->value = gmp_nextprime($x->value);
|
3062 |
-
|
3063 |
-
if ($x->compare($max) <= 0) {
|
3064 |
-
return $x;
|
3065 |
-
}
|
3066 |
-
|
3067 |
-
$x->value = gmp_nextprime($min->value);
|
3068 |
-
|
3069 |
-
if ($x->compare($max) <= 0) {
|
3070 |
-
return $x;
|
3071 |
-
}
|
3072 |
-
|
3073 |
-
return false;
|
3074 |
-
}
|
3075 |
-
|
3076 |
-
static $one, $two;
|
3077 |
-
if (!isset($one)) {
|
3078 |
-
$one = new Math_BigInteger(1);
|
3079 |
-
$two = new Math_BigInteger(2);
|
3080 |
-
}
|
3081 |
-
|
3082 |
-
$start = time();
|
3083 |
-
|
3084 |
-
$x = $this->random($min, $max);
|
3085 |
-
if ($x->equals($two)) {
|
3086 |
-
return $x;
|
3087 |
-
}
|
3088 |
-
|
3089 |
-
$x->_make_odd();
|
3090 |
-
if ($x->compare($max) > 0) {
|
3091 |
-
// if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range
|
3092 |
-
if ($min->equals($max)) {
|
3093 |
-
return false;
|
3094 |
-
}
|
3095 |
-
$x = $min->copy();
|
3096 |
-
$x->_make_odd();
|
3097 |
-
}
|
3098 |
-
|
3099 |
-
$initial_x = $x->copy();
|
3100 |
-
|
3101 |
-
while (true) {
|
3102 |
-
if ($timeout !== false && time() - $start > $timeout) {
|
3103 |
-
return false;
|
3104 |
-
}
|
3105 |
-
|
3106 |
-
if ($x->isPrime()) {
|
3107 |
-
return $x;
|
3108 |
-
}
|
3109 |
-
|
3110 |
-
$x = $x->add($two);
|
3111 |
-
|
3112 |
-
if ($x->compare($max) > 0) {
|
3113 |
-
$x = $min->copy();
|
3114 |
-
if ($x->equals($two)) {
|
3115 |
-
return $x;
|
3116 |
-
}
|
3117 |
-
$x->_make_odd();
|
3118 |
-
}
|
3119 |
-
|
3120 |
-
if ($x->equals($initial_x)) {
|
3121 |
-
return false;
|
3122 |
-
}
|
3123 |
-
}
|
3124 |
-
}
|
3125 |
-
|
3126 |
-
/**
|
3127 |
-
* Make the current number odd
|
3128 |
-
*
|
3129 |
-
* If the current number is odd it'll be unchanged. If it's even, one will be added to it.
|
3130 |
-
*
|
3131 |
-
* @see randomPrime()
|
3132 |
-
* @access private
|
3133 |
-
*/
|
3134 |
-
function _make_odd()
|
3135 |
-
{
|
3136 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
3137 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
3138 |
-
gmp_setbit($this->value, 0);
|
3139 |
-
break;
|
3140 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
3141 |
-
if ($this->value[strlen($this->value) - 1] % 2 == 0) {
|
3142 |
-
$this->value = bcadd($this->value, '1');
|
3143 |
-
}
|
3144 |
-
break;
|
3145 |
-
default:
|
3146 |
-
$this->value[0] |= 1;
|
3147 |
-
}
|
3148 |
-
}
|
3149 |
-
|
3150 |
-
/**
|
3151 |
-
* Checks a numer to see if it's prime
|
3152 |
-
*
|
3153 |
-
* Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the
|
3154 |
-
* $t parameter is distributability. Math_BigInteger::randomPrime() can be distributed accross multiple pageloads
|
3155 |
-
* on a website instead of just one.
|
3156 |
-
*
|
3157 |
-
* @param optional Integer $t
|
3158 |
-
* @return Boolean
|
3159 |
-
* @access public
|
3160 |
-
* @internal Uses the
|
3161 |
-
* {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. See
|
3162 |
-
* {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24}.
|
3163 |
-
*/
|
3164 |
-
function isPrime($t = false)
|
3165 |
-
{
|
3166 |
-
$length = strlen($this->toBytes());
|
3167 |
-
|
3168 |
-
if (!$t) {
|
3169 |
-
// see HAC 4.49 "Note (controlling the error probability)"
|
3170 |
-
if ($length >= 163) { $t = 2; } // floor(1300 / 8)
|
3171 |
-
else if ($length >= 106) { $t = 3; } // floor( 850 / 8)
|
3172 |
-
else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8)
|
3173 |
-
else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8)
|
3174 |
-
else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8)
|
3175 |
-
else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8)
|
3176 |
-
else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8)
|
3177 |
-
else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8)
|
3178 |
-
else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8)
|
3179 |
-
else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8)
|
3180 |
-
else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8)
|
3181 |
-
else { $t = 27; }
|
3182 |
-
}
|
3183 |
-
|
3184 |
-
// ie. gmp_testbit($this, 0)
|
3185 |
-
// ie. isEven() or !isOdd()
|
3186 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
3187 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
3188 |
-
return gmp_prob_prime($this->value, $t) != 0;
|
3189 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
3190 |
-
if ($this->value === '2') {
|
3191 |
-
return true;
|
3192 |
-
}
|
3193 |
-
if ($this->value[strlen($this->value) - 1] % 2 == 0) {
|
3194 |
-
return false;
|
3195 |
-
}
|
3196 |
-
break;
|
3197 |
-
default:
|
3198 |
-
if ($this->value == array(2)) {
|
3199 |
-
return true;
|
3200 |
-
}
|
3201 |
-
if (~$this->value[0] & 1) {
|
3202 |
-
return false;
|
3203 |
-
}
|
3204 |
-
}
|
3205 |
-
|
3206 |
-
static $primes, $zero, $one, $two;
|
3207 |
-
|
3208 |
-
if (!isset($primes)) {
|
3209 |
-
$primes = array(
|
3210 |
-
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
|
3211 |
-
61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
|
3212 |
-
139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
|
3213 |
-
229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,
|
3214 |
-
317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419,
|
3215 |
-
421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509,
|
3216 |
-
521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617,
|
3217 |
-
619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727,
|
3218 |
-
733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
|
3219 |
-
839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947,
|
3220 |
-
953, 967, 971, 977, 983, 991, 997
|
3221 |
-
);
|
3222 |
-
|
3223 |
-
if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL ) {
|
3224 |
-
for ($i = 0; $i < count($primes); ++$i) {
|
3225 |
-
$primes[$i] = new Math_BigInteger($primes[$i]);
|
3226 |
-
}
|
3227 |
-
}
|
3228 |
-
|
3229 |
-
$zero = new Math_BigInteger();
|
3230 |
-
$one = new Math_BigInteger(1);
|
3231 |
-
$two = new Math_BigInteger(2);
|
3232 |
-
}
|
3233 |
-
|
3234 |
-
if ($this->equals($one)) {
|
3235 |
-
return false;
|
3236 |
-
}
|
3237 |
-
|
3238 |
-
// see HAC 4.4.1 "Random search for probable primes"
|
3239 |
-
if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL ) {
|
3240 |
-
foreach ($primes as $prime) {
|
3241 |
-
list(, $r) = $this->divide($prime);
|
3242 |
-
if ($r->equals($zero)) {
|
3243 |
-
return $this->equals($prime);
|
3244 |
-
}
|
3245 |
-
}
|
3246 |
-
} else {
|
3247 |
-
$value = $this->value;
|
3248 |
-
foreach ($primes as $prime) {
|
3249 |
-
list(, $r) = $this->_divide_digit($value, $prime);
|
3250 |
-
if (!$r) {
|
3251 |
-
return count($value) == 1 && $value[0] == $prime;
|
3252 |
-
}
|
3253 |
-
}
|
3254 |
-
}
|
3255 |
-
|
3256 |
-
$n = $this->copy();
|
3257 |
-
$n_1 = $n->subtract($one);
|
3258 |
-
$n_2 = $n->subtract($two);
|
3259 |
-
|
3260 |
-
$r = $n_1->copy();
|
3261 |
-
$r_value = $r->value;
|
3262 |
-
// ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));
|
3263 |
-
if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH ) {
|
3264 |
-
$s = 0;
|
3265 |
-
// if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier
|
3266 |
-
while ($r->value[strlen($r->value) - 1] % 2 == 0) {
|
3267 |
-
$r->value = bcdiv($r->value, '2', 0);
|
3268 |
-
++$s;
|
3269 |
-
}
|
3270 |
-
} else {
|
3271 |
-
for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) {
|
3272 |
-
$temp = ~$r_value[$i] & 0xFFFFFF;
|
3273 |
-
for ($j = 1; ($temp >> $j) & 1; ++$j);
|
3274 |
-
if ($j != 25) {
|
3275 |
-
break;
|
3276 |
-
}
|
3277 |
-
}
|
3278 |
-
$s = 26 * $i + $j - 1;
|
3279 |
-
$r->_rshift($s);
|
3280 |
-
}
|
3281 |
-
|
3282 |
-
for ($i = 0; $i < $t; ++$i) {
|
3283 |
-
$a = $this->random($two, $n_2);
|
3284 |
-
$y = $a->modPow($r, $n);
|
3285 |
-
|
3286 |
-
if (!$y->equals($one) && !$y->equals($n_1)) {
|
3287 |
-
for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) {
|
3288 |
-
$y = $y->modPow($two, $n);
|
3289 |
-
if ($y->equals($one)) {
|
3290 |
-
return false;
|
3291 |
-
}
|
3292 |
-
}
|
3293 |
-
|
3294 |
-
if (!$y->equals($n_1)) {
|
3295 |
-
return false;
|
3296 |
-
}
|
3297 |
-
}
|
3298 |
-
}
|
3299 |
-
return true;
|
3300 |
-
}
|
3301 |
-
|
3302 |
-
/**
|
3303 |
-
* Logical Left Shift
|
3304 |
-
*
|
3305 |
-
* Shifts BigInteger's by $shift bits.
|
3306 |
-
*
|
3307 |
-
* @param Integer $shift
|
3308 |
-
* @access private
|
3309 |
-
*/
|
3310 |
-
function _lshift($shift)
|
3311 |
-
{
|
3312 |
-
if ( $shift == 0 ) {
|
3313 |
-
return;
|
3314 |
-
}
|
3315 |
-
|
3316 |
-
$num_digits = (int) ($shift / 26);
|
3317 |
-
$shift %= 26;
|
3318 |
-
$shift = 1 << $shift;
|
3319 |
-
|
3320 |
-
$carry = 0;
|
3321 |
-
|
3322 |
-
for ($i = 0; $i < count($this->value); ++$i) {
|
3323 |
-
$temp = $this->value[$i] * $shift + $carry;
|
3324 |
-
$carry = (int) ($temp / 0x4000000);
|
3325 |
-
$this->value[$i] = (int) ($temp - $carry * 0x4000000);
|
3326 |
-
}
|
3327 |
-
|
3328 |
-
if ( $carry ) {
|
3329 |
-
$this->value[] = $carry;
|
3330 |
-
}
|
3331 |
-
|
3332 |
-
while ($num_digits--) {
|
3333 |
-
array_unshift($this->value, 0);
|
3334 |
-
}
|
3335 |
-
}
|
3336 |
-
|
3337 |
-
/**
|
3338 |
-
* Logical Right Shift
|
3339 |
-
*
|
3340 |
-
* Shifts BigInteger's by $shift bits.
|
3341 |
-
*
|
3342 |
-
* @param Integer $shift
|
3343 |
-
* @access private
|
3344 |
-
*/
|
3345 |
-
function _rshift($shift)
|
3346 |
-
{
|
3347 |
-
if ($shift == 0) {
|
3348 |
-
return;
|
3349 |
-
}
|
3350 |
-
|
3351 |
-
$num_digits = (int) ($shift / 26);
|
3352 |
-
$shift %= 26;
|
3353 |
-
$carry_shift = 26 - $shift;
|
3354 |
-
$carry_mask = (1 << $shift) - 1;
|
3355 |
-
|
3356 |
-
if ( $num_digits ) {
|
3357 |
-
$this->value = array_slice($this->value, $num_digits);
|
3358 |
-
}
|
3359 |
-
|
3360 |
-
$carry = 0;
|
3361 |
-
|
3362 |
-
for ($i = count($this->value) - 1; $i >= 0; --$i) {
|
3363 |
-
$temp = $this->value[$i] >> $shift | $carry;
|
3364 |
-
$carry = ($this->value[$i] & $carry_mask) << $carry_shift;
|
3365 |
-
$this->value[$i] = $temp;
|
3366 |
-
}
|
3367 |
-
|
3368 |
-
$this->value = $this->_trim($this->value);
|
3369 |
-
}
|
3370 |
-
|
3371 |
-
/**
|
3372 |
-
* Normalize
|
3373 |
-
*
|
3374 |
-
* Removes leading zeros and truncates (if necessary) to maintain the appropriate precision
|
3375 |
-
*
|
3376 |
-
* @param Math_BigInteger
|
3377 |
-
* @return Math_BigInteger
|
3378 |
-
* @see _trim()
|
3379 |
-
* @access private
|
3380 |
-
*/
|
3381 |
-
function _normalize($result)
|
3382 |
-
{
|
3383 |
-
$result->precision = $this->precision;
|
3384 |
-
$result->bitmask = $this->bitmask;
|
3385 |
-
|
3386 |
-
switch ( MATH_BIGINTEGER_MODE ) {
|
3387 |
-
case MATH_BIGINTEGER_MODE_GMP:
|
3388 |
-
if (!empty($result->bitmask->value)) {
|
3389 |
-
$result->value = gmp_and($result->value, $result->bitmask->value);
|
3390 |
-
}
|
3391 |
-
|
3392 |
-
return $result;
|
3393 |
-
case MATH_BIGINTEGER_MODE_BCMATH:
|
3394 |
-
if (!empty($result->bitmask->value)) {
|
3395 |
-
$result->value = bcmod($result->value, $result->bitmask->value);
|
3396 |
-
}
|
3397 |
-
|
3398 |
-
return $result;
|
3399 |
-
}
|
3400 |
-
|
3401 |
-
$value = &$result->value;
|
3402 |
-
|
3403 |
-
if ( !count($value) ) {
|
3404 |
-
return $result;
|
3405 |
-
}
|
3406 |
-
|
3407 |
-
$value = $this->_trim($value);
|
3408 |
-
|
3409 |
-
if (!empty($result->bitmask->value)) {
|
3410 |
-
$length = min(count($value), count($this->bitmask->value));
|
3411 |
-
$value = array_slice($value, 0, $length);
|
3412 |
-
|
3413 |
-
for ($i = 0; $i < $length; ++$i) {
|
3414 |
-
$value[$i] = $value[$i] & $this->bitmask->value[$i];
|
3415 |
-
}
|
3416 |
-
}
|
3417 |
-
|
3418 |
-
return $result;
|
3419 |
-
}
|
3420 |
-
|
3421 |
-
/**
|
3422 |
-
* Trim
|
3423 |
-
*
|
3424 |
-
* Removes leading zeros
|
3425 |
-
*
|
3426 |
-
* @return Math_BigInteger
|
3427 |
-
* @access private
|
3428 |
-
*/
|
3429 |
-
function _trim($value)
|
3430 |
-
{
|
3431 |
-
for ($i = count($value) - 1; $i >= 0; --$i) {
|
3432 |
-
if ( $value[$i] ) {
|
3433 |
-
break;
|
3434 |
-
}
|
3435 |
-
unset($value[$i]);
|
3436 |
-
}
|
3437 |
-
|
3438 |
-
return $value;
|
3439 |
-
}
|
3440 |
-
|
3441 |
-
/**
|
3442 |
-
* Array Repeat
|
3443 |
-
*
|
3444 |
-
* @param $input Array
|
3445 |
-
* @param $multiplier mixed
|
3446 |
-
* @return Array
|
3447 |
-
* @access private
|
3448 |
-
*/
|
3449 |
-
function _array_repeat($input, $multiplier)
|
3450 |
-
{
|
3451 |
-
return ($multiplier) ? array_fill(0, $multiplier, $input) : array();
|
3452 |
-
}
|
3453 |
-
|
3454 |
-
/**
|
3455 |
-
* Logical Left Shift
|
3456 |
-
*
|
3457 |
-
* Shifts binary strings $shift bits, essentially multiplying by 2**$shift.
|
3458 |
-
*
|
3459 |
-
* @param $x String
|
3460 |
-
* @param $shift Integer
|
3461 |
-
* @return String
|
3462 |
-
* @access private
|
3463 |
-
*/
|
3464 |
-
function _base256_lshift(&$x, $shift)
|
3465 |
-
{
|
3466 |
-
if ($shift == 0) {
|
3467 |
-
return;
|
3468 |
-
}
|
3469 |
-
|
3470 |
-
$num_bytes = $shift >> 3; // eg. floor($shift/8)
|
3471 |
-
$shift &= 7; // eg. $shift % 8
|
3472 |
-
|
3473 |
-
$carry = 0;
|
3474 |
-
for ($i = strlen($x) - 1; $i >= 0; --$i) {
|
3475 |
-
$temp = ord($x[$i]) << $shift | $carry;
|
3476 |
-
$x[$i] = chr($temp);
|
3477 |
-
$carry = $temp >> 8;
|
3478 |
-
}
|
3479 |
-
$carry = ($carry != 0) ? chr($carry) : '';
|
3480 |
-
$x = $carry . $x . str_repeat(chr(0), $num_bytes);
|
3481 |
-
}
|
3482 |
-
|
3483 |
-
/**
|
3484 |
-
* Logical Right Shift
|
3485 |
-
*
|
3486 |
-
* Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder.
|
3487 |
-
*
|
3488 |
-
* @param $x String
|
3489 |
-
* @param $shift Integer
|
3490 |
-
* @return String
|
3491 |
-
* @access private
|
3492 |
-
*/
|
3493 |
-
function _base256_rshift(&$x, $shift)
|
3494 |
-
{
|
3495 |
-
if ($shift == 0) {
|
3496 |
-
$x = ltrim($x, chr(0));
|
3497 |
-
return '';
|
3498 |
-
}
|
3499 |
-
|
3500 |
-
$num_bytes = $shift >> 3; // eg. floor($shift/8)
|
3501 |
-
$shift &= 7; // eg. $shift % 8
|
3502 |
-
|
3503 |
-
$remainder = '';
|
3504 |
-
if ($num_bytes) {
|
3505 |
-
$start = $num_bytes > strlen($x) ? -strlen($x) : -$num_bytes;
|
3506 |
-
$remainder = substr($x, $start);
|
3507 |
-
$x = substr($x, 0, -$num_bytes);
|
3508 |
-
}
|
3509 |
-
|
3510 |
-
$carry = 0;
|
3511 |
-
$carry_shift = 8 - $shift;
|
3512 |
-
for ($i = 0; $i < strlen($x); ++$i) {
|
3513 |
-
$temp = (ord($x[$i]) >> $shift) | $carry;
|
3514 |
-
$carry = (ord($x[$i]) << $carry_shift) & 0xFF;
|
3515 |
-
$x[$i] = chr($temp);
|
3516 |
-
}
|
3517 |
-
$x = ltrim($x, chr(0));
|
3518 |
-
|
3519 |
-
$remainder = chr($carry >> $carry_shift) . $remainder;
|
3520 |
-
|
3521 |
-
return ltrim($remainder, chr(0));
|
3522 |
-
}
|
3523 |
-
|
3524 |
-
// one quirk about how the following functions are implemented is that PHP defines N to be an unsigned long
|
3525 |
-
// at 32-bits, while java's longs are 64-bits.
|
3526 |
-
|
3527 |
-
/**
|
3528 |
-
* Converts 32-bit integers to bytes.
|
3529 |
-
*
|
3530 |
-
* @param Integer $x
|
3531 |
-
* @return String
|
3532 |
-
* @access private
|
3533 |
-
*/
|
3534 |
-
function _int2bytes($x)
|
3535 |
-
{
|
3536 |
-
return ltrim(pack('N', $x), chr(0));
|
3537 |
-
}
|
3538 |
-
|
3539 |
-
/**
|
3540 |
-
* Converts bytes to 32-bit integers
|
3541 |
-
*
|
3542 |
-
* @param String $x
|
3543 |
-
* @return Integer
|
3544 |
-
* @access private
|
3545 |
-
*/
|
3546 |
-
function _bytes2int($x)
|
3547 |
-
{
|
3548 |
-
$temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT));
|
3549 |
-
return $temp['int'];
|
3550 |
-
}
|
3551 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Net/SFTP.php
DELETED
@@ -1,1609 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of SFTP.
|
6 |
-
*
|
7 |
-
* PHP versions 4 and 5
|
8 |
-
*
|
9 |
-
* Currently only supports SFTPv3, which, according to wikipedia.org, "is the most widely used version,
|
10 |
-
* implemented by the popular OpenSSH SFTP server". If you want SFTPv4/5/6 support, provide me with access
|
11 |
-
* to an SFTPv4/5/6 server.
|
12 |
-
*
|
13 |
-
* The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
|
14 |
-
*
|
15 |
-
* Here's a short example of how to use this library:
|
16 |
-
* <code>
|
17 |
-
* <?php
|
18 |
-
* include('Net/SFTP.php');
|
19 |
-
*
|
20 |
-
* $sftp = new Net_SFTP('www.domain.tld');
|
21 |
-
* if (!$sftp->login('username', 'password')) {
|
22 |
-
* exit('Login Failed');
|
23 |
-
* }
|
24 |
-
*
|
25 |
-
* echo $sftp->pwd() . "\r\n";
|
26 |
-
* $sftp->put('filename.ext', 'hello, world!');
|
27 |
-
* print_r($sftp->nlist());
|
28 |
-
* ?>
|
29 |
-
* </code>
|
30 |
-
*
|
31 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
32 |
-
* of this software and associated documentation files (the "Software"), to deal
|
33 |
-
* in the Software without restriction, including without limitation the rights
|
34 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
35 |
-
* copies of the Software, and to permit persons to whom the Software is
|
36 |
-
* furnished to do so, subject to the following conditions:
|
37 |
-
*
|
38 |
-
* The above copyright notice and this permission notice shall be included in
|
39 |
-
* all copies or substantial portions of the Software.
|
40 |
-
*
|
41 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
42 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
43 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
44 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
45 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
46 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
47 |
-
* THE SOFTWARE.
|
48 |
-
*
|
49 |
-
* @category Net
|
50 |
-
* @package Net_SFTP
|
51 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
52 |
-
* @copyright MMIX Jim Wigginton
|
53 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
54 |
-
* @link http://phpseclib.sourceforge.net
|
55 |
-
*/
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Include Net_SSH2
|
59 |
-
*/
|
60 |
-
require_once('Net/SSH2.php');
|
61 |
-
|
62 |
-
/**#@+
|
63 |
-
* @access public
|
64 |
-
* @see Net_SFTP::getLog()
|
65 |
-
*/
|
66 |
-
/**
|
67 |
-
* Returns the message numbers
|
68 |
-
*/
|
69 |
-
define('NET_SFTP_LOG_SIMPLE', NET_SSH2_LOG_SIMPLE);
|
70 |
-
/**
|
71 |
-
* Returns the message content
|
72 |
-
*/
|
73 |
-
define('NET_SFTP_LOG_COMPLEX', NET_SSH2_LOG_COMPLEX);
|
74 |
-
/**#@-*/
|
75 |
-
|
76 |
-
/**
|
77 |
-
* SFTP channel constant
|
78 |
-
*
|
79 |
-
* Net_SSH2::exec() uses 0 and Net_SSH2::read() / Net_SSH2::write() use 1.
|
80 |
-
*
|
81 |
-
* @see Net_SSH2::_send_channel_packet()
|
82 |
-
* @see Net_SSH2::_get_channel_packet()
|
83 |
-
* @access private
|
84 |
-
*/
|
85 |
-
define('NET_SFTP_CHANNEL', 2);
|
86 |
-
|
87 |
-
/**#@+
|
88 |
-
* @access public
|
89 |
-
* @see Net_SFTP::put()
|
90 |
-
*/
|
91 |
-
/**
|
92 |
-
* Reads data from a local file.
|
93 |
-
*/
|
94 |
-
define('NET_SFTP_LOCAL_FILE', 1);
|
95 |
-
/**
|
96 |
-
* Reads data from a string.
|
97 |
-
*/
|
98 |
-
define('NET_SFTP_STRING', 2);
|
99 |
-
/**#@-*/
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Pure-PHP implementations of SFTP.
|
103 |
-
*
|
104 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
105 |
-
* @version 0.1.0
|
106 |
-
* @access public
|
107 |
-
* @package Net_SFTP
|
108 |
-
*/
|
109 |
-
class Net_SFTP extends Net_SSH2 {
|
110 |
-
/**
|
111 |
-
* Packet Types
|
112 |
-
*
|
113 |
-
* @see Net_SFTP::Net_SFTP()
|
114 |
-
* @var Array
|
115 |
-
* @access private
|
116 |
-
*/
|
117 |
-
var $packet_types = array();
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Status Codes
|
121 |
-
*
|
122 |
-
* @see Net_SFTP::Net_SFTP()
|
123 |
-
* @var Array
|
124 |
-
* @access private
|
125 |
-
*/
|
126 |
-
var $status_codes = array();
|
127 |
-
|
128 |
-
/**
|
129 |
-
* The Request ID
|
130 |
-
*
|
131 |
-
* The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
|
132 |
-
* concurrent actions, so it's somewhat academic, here.
|
133 |
-
*
|
134 |
-
* @var Integer
|
135 |
-
* @see Net_SFTP::_send_sftp_packet()
|
136 |
-
* @access private
|
137 |
-
*/
|
138 |
-
var $request_id = false;
|
139 |
-
|
140 |
-
/**
|
141 |
-
* The Packet Type
|
142 |
-
*
|
143 |
-
* The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
|
144 |
-
* concurrent actions, so it's somewhat academic, here.
|
145 |
-
*
|
146 |
-
* @var Integer
|
147 |
-
* @see Net_SFTP::_get_sftp_packet()
|
148 |
-
* @access private
|
149 |
-
*/
|
150 |
-
var $packet_type = -1;
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Packet Buffer
|
154 |
-
*
|
155 |
-
* @var String
|
156 |
-
* @see Net_SFTP::_get_sftp_packet()
|
157 |
-
* @access private
|
158 |
-
*/
|
159 |
-
var $packet_buffer = '';
|
160 |
-
|
161 |
-
/**
|
162 |
-
* Extensions supported by the server
|
163 |
-
*
|
164 |
-
* @var Array
|
165 |
-
* @see Net_SFTP::_initChannel()
|
166 |
-
* @access private
|
167 |
-
*/
|
168 |
-
var $extensions = array();
|
169 |
-
|
170 |
-
/**
|
171 |
-
* Server SFTP version
|
172 |
-
*
|
173 |
-
* @var Integer
|
174 |
-
* @see Net_SFTP::_initChannel()
|
175 |
-
* @access private
|
176 |
-
*/
|
177 |
-
var $version;
|
178 |
-
|
179 |
-
/**
|
180 |
-
* Current working directory
|
181 |
-
*
|
182 |
-
* @var String
|
183 |
-
* @see Net_SFTP::_realpath()
|
184 |
-
* @see Net_SFTP::chdir()
|
185 |
-
* @access private
|
186 |
-
*/
|
187 |
-
var $pwd = false;
|
188 |
-
|
189 |
-
/**
|
190 |
-
* Packet Type Log
|
191 |
-
*
|
192 |
-
* @see Net_SFTP::getLog()
|
193 |
-
* @var Array
|
194 |
-
* @access private
|
195 |
-
*/
|
196 |
-
var $packet_type_log = array();
|
197 |
-
|
198 |
-
/**
|
199 |
-
* Packet Log
|
200 |
-
*
|
201 |
-
* @see Net_SFTP::getLog()
|
202 |
-
* @var Array
|
203 |
-
* @access private
|
204 |
-
*/
|
205 |
-
var $packet_log = array();
|
206 |
-
|
207 |
-
/**
|
208 |
-
* Error information
|
209 |
-
*
|
210 |
-
* @see Net_SFTP::getSFTPErrors()
|
211 |
-
* @see Net_SFTP::getLastSFTPError()
|
212 |
-
* @var String
|
213 |
-
* @access private
|
214 |
-
*/
|
215 |
-
var $sftp_errors = array();
|
216 |
-
|
217 |
-
/**
|
218 |
-
* File Type
|
219 |
-
*
|
220 |
-
* @see Net_SFTP::_parseLongname()
|
221 |
-
* @var Integer
|
222 |
-
* @access private
|
223 |
-
*/
|
224 |
-
var $fileType = 0;
|
225 |
-
|
226 |
-
/**
|
227 |
-
* Default Constructor.
|
228 |
-
*
|
229 |
-
* Connects to an SFTP server
|
230 |
-
*
|
231 |
-
* @param String $host
|
232 |
-
* @param optional Integer $port
|
233 |
-
* @param optional Integer $timeout
|
234 |
-
* @return Net_SFTP
|
235 |
-
* @access public
|
236 |
-
*/
|
237 |
-
function Net_SFTP($host, $port = 22, $timeout = 10)
|
238 |
-
{
|
239 |
-
parent::Net_SSH2($host, $port, $timeout);
|
240 |
-
$this->packet_types = array(
|
241 |
-
1 => 'NET_SFTP_INIT',
|
242 |
-
2 => 'NET_SFTP_VERSION',
|
243 |
-
/* the format of SSH_FXP_OPEN changed between SFTPv4 and SFTPv5+:
|
244 |
-
SFTPv5+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.1
|
245 |
-
pre-SFTPv5 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 */
|
246 |
-
3 => 'NET_SFTP_OPEN',
|
247 |
-
4 => 'NET_SFTP_CLOSE',
|
248 |
-
5 => 'NET_SFTP_READ',
|
249 |
-
6 => 'NET_SFTP_WRITE',
|
250 |
-
7 => 'NET_SFTP_LSTAT',
|
251 |
-
9 => 'NET_SFTP_SETSTAT',
|
252 |
-
11 => 'NET_SFTP_OPENDIR',
|
253 |
-
12 => 'NET_SFTP_READDIR',
|
254 |
-
13 => 'NET_SFTP_REMOVE',
|
255 |
-
14 => 'NET_SFTP_MKDIR',
|
256 |
-
15 => 'NET_SFTP_RMDIR',
|
257 |
-
16 => 'NET_SFTP_REALPATH',
|
258 |
-
17 => 'NET_SFTP_STAT',
|
259 |
-
/* the format of SSH_FXP_RENAME changed between SFTPv4 and SFTPv5+:
|
260 |
-
SFTPv5+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
|
261 |
-
pre-SFTPv5 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.5 */
|
262 |
-
18 => 'NET_SFTP_RENAME',
|
263 |
-
|
264 |
-
101=> 'NET_SFTP_STATUS',
|
265 |
-
102=> 'NET_SFTP_HANDLE',
|
266 |
-
/* the format of SSH_FXP_NAME changed between SFTPv3 and SFTPv4+:
|
267 |
-
SFTPv4+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.4
|
268 |
-
pre-SFTPv4 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-7 */
|
269 |
-
103=> 'NET_SFTP_DATA',
|
270 |
-
104=> 'NET_SFTP_NAME',
|
271 |
-
105=> 'NET_SFTP_ATTRS',
|
272 |
-
|
273 |
-
200=> 'NET_SFTP_EXTENDED'
|
274 |
-
);
|
275 |
-
$this->status_codes = array(
|
276 |
-
0 => 'NET_SFTP_STATUS_OK',
|
277 |
-
1 => 'NET_SFTP_STATUS_EOF',
|
278 |
-
2 => 'NET_SFTP_STATUS_NO_SUCH_FILE',
|
279 |
-
3 => 'NET_SFTP_STATUS_PERMISSION_DENIED',
|
280 |
-
4 => 'NET_SFTP_STATUS_FAILURE',
|
281 |
-
5 => 'NET_SFTP_STATUS_BAD_MESSAGE',
|
282 |
-
6 => 'NET_SFTP_STATUS_NO_CONNECTION',
|
283 |
-
7 => 'NET_SFTP_STATUS_CONNECTION_LOST',
|
284 |
-
8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED'
|
285 |
-
);
|
286 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
|
287 |
-
// the order, in this case, matters quite a lot - see Net_SFTP::_parseAttributes() to understand why
|
288 |
-
$this->attributes = array(
|
289 |
-
0x00000001 => 'NET_SFTP_ATTR_SIZE',
|
290 |
-
0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+
|
291 |
-
0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS',
|
292 |
-
0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME',
|
293 |
-
// 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers
|
294 |
-
// yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
|
295 |
-
// two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
|
296 |
-
// that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
|
297 |
-
-1 << 31 => 'NET_SFTP_ATTR_EXTENDED'
|
298 |
-
);
|
299 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
|
300 |
-
// the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
|
301 |
-
// the array for that $this->open5_flags and similarily alter the constant names.
|
302 |
-
$this->open_flags = array(
|
303 |
-
0x00000001 => 'NET_SFTP_OPEN_READ',
|
304 |
-
0x00000002 => 'NET_SFTP_OPEN_WRITE',
|
305 |
-
0x00000008 => 'NET_SFTP_OPEN_CREATE',
|
306 |
-
0x00000010 => 'NET_SFTP_OPEN_TRUNCATE'
|
307 |
-
);
|
308 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
|
309 |
-
// see Net_SFTP::_parseLongname() for an explanation
|
310 |
-
$this->file_types = array(
|
311 |
-
1 => 'NET_SFTP_TYPE_REGULAR',
|
312 |
-
2 => 'NET_SFTP_TYPE_DIRECTORY',
|
313 |
-
3 => 'NET_SFTP_TYPE_SYMLINK',
|
314 |
-
4 => 'NET_SFTP_TYPE_SPECIAL'
|
315 |
-
);
|
316 |
-
$this->_define_array(
|
317 |
-
$this->packet_types,
|
318 |
-
$this->status_codes,
|
319 |
-
$this->attributes,
|
320 |
-
$this->open_flags,
|
321 |
-
$this->file_types
|
322 |
-
);
|
323 |
-
}
|
324 |
-
|
325 |
-
/**
|
326 |
-
* Login
|
327 |
-
*
|
328 |
-
* @param String $username
|
329 |
-
* @param optional String $password
|
330 |
-
* @return Boolean
|
331 |
-
* @access public
|
332 |
-
*/
|
333 |
-
function login($username, $password = '')
|
334 |
-
{
|
335 |
-
if (!parent::login($username, $password)) {
|
336 |
-
return false;
|
337 |
-
}
|
338 |
-
|
339 |
-
$this->window_size_client_to_server[NET_SFTP_CHANNEL] = $this->window_size;
|
340 |
-
|
341 |
-
$packet = pack('CNa*N3',
|
342 |
-
NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SFTP_CHANNEL, $this->window_size, 0x4000);
|
343 |
-
|
344 |
-
if (!$this->_send_binary_packet($packet)) {
|
345 |
-
return false;
|
346 |
-
}
|
347 |
-
|
348 |
-
$this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
|
349 |
-
|
350 |
-
$response = $this->_get_channel_packet(NET_SFTP_CHANNEL);
|
351 |
-
if ($response === false) {
|
352 |
-
return false;
|
353 |
-
}
|
354 |
-
|
355 |
-
$packet = pack('CNNa*CNa*',
|
356 |
-
NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SFTP_CHANNEL], strlen('subsystem'), 'subsystem', 1, strlen('sftp'), 'sftp');
|
357 |
-
if (!$this->_send_binary_packet($packet)) {
|
358 |
-
return false;
|
359 |
-
}
|
360 |
-
|
361 |
-
$this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
362 |
-
|
363 |
-
$response = $this->_get_channel_packet(NET_SFTP_CHANNEL);
|
364 |
-
if ($response === false) {
|
365 |
-
return false;
|
366 |
-
}
|
367 |
-
|
368 |
-
$this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA;
|
369 |
-
|
370 |
-
if (!$this->_send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) {
|
371 |
-
return false;
|
372 |
-
}
|
373 |
-
|
374 |
-
$response = $this->_get_sftp_packet();
|
375 |
-
if ($this->packet_type != NET_SFTP_VERSION) {
|
376 |
-
user_error('Expected SSH_FXP_VERSION', E_USER_NOTICE);
|
377 |
-
return false;
|
378 |
-
}
|
379 |
-
|
380 |
-
extract(unpack('Nversion', $this->_string_shift($response, 4)));
|
381 |
-
$this->version = $version;
|
382 |
-
while (!empty($response)) {
|
383 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
384 |
-
$key = $this->_string_shift($response, $length);
|
385 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
386 |
-
$value = $this->_string_shift($response, $length);
|
387 |
-
$this->extensions[$key] = $value;
|
388 |
-
}
|
389 |
-
|
390 |
-
/*
|
391 |
-
SFTPv4+ defines a 'newline' extension. SFTPv3 seems to have unofficial support for it via 'newline@vandyke.com',
|
392 |
-
however, I'm not sure what 'newline@vandyke.com' is supposed to do (the fact that it's unofficial means that it's
|
393 |
-
not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for
|
394 |
-
one another due to the fact that 'newline' comes with a SSH_FXF_TEXT bitmask whereas it seems unlikely that
|
395 |
-
'newline@vandyke.com' would.
|
396 |
-
*/
|
397 |
-
/*
|
398 |
-
if (isset($this->extensions['newline@vandyke.com'])) {
|
399 |
-
$this->extensions['newline'] = $this->extensions['newline@vandyke.com'];
|
400 |
-
unset($this->extensions['newline@vandyke.com']);
|
401 |
-
}
|
402 |
-
*/
|
403 |
-
|
404 |
-
$this->request_id = 1;
|
405 |
-
|
406 |
-
/*
|
407 |
-
A Note on SFTPv4/5/6 support:
|
408 |
-
<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.1> states the following:
|
409 |
-
|
410 |
-
"If the client wishes to interoperate with servers that support noncontiguous version
|
411 |
-
numbers it SHOULD send '3'"
|
412 |
-
|
413 |
-
Given that the server only sends its version number after the client has already done so, the above
|
414 |
-
seems to be suggesting that v3 should be the default version. This makes sense given that v3 is the
|
415 |
-
most popular.
|
416 |
-
|
417 |
-
<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.5> states the following;
|
418 |
-
|
419 |
-
"If the server did not send the "versions" extension, or the version-from-list was not included, the
|
420 |
-
server MAY send a status response describing the failure, but MUST then close the channel without
|
421 |
-
processing any further requests."
|
422 |
-
|
423 |
-
So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and
|
424 |
-
a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements
|
425 |
-
v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed
|
426 |
-
in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what Net_SFTP would do is close the
|
427 |
-
channel and reopen it with a new and updated SSH_FXP_INIT packet.
|
428 |
-
*/
|
429 |
-
if ($this->version != 3) {
|
430 |
-
return false;
|
431 |
-
}
|
432 |
-
|
433 |
-
$this->pwd = $this->_realpath('.');
|
434 |
-
|
435 |
-
return true;
|
436 |
-
}
|
437 |
-
|
438 |
-
/**
|
439 |
-
* Returns the current directory name
|
440 |
-
*
|
441 |
-
* @return Mixed
|
442 |
-
* @access public
|
443 |
-
*/
|
444 |
-
function pwd()
|
445 |
-
{
|
446 |
-
return $this->pwd;
|
447 |
-
}
|
448 |
-
|
449 |
-
/**
|
450 |
-
* Canonicalize the Server-Side Path Name
|
451 |
-
*
|
452 |
-
* SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns
|
453 |
-
* the absolute (canonicalized) path. If $mode is set to NET_SFTP_CONFIRM_DIR (as opposed to NET_SFTP_CONFIRM_NONE,
|
454 |
-
* which is what it is set to by default), false is returned if $dir is not a valid directory.
|
455 |
-
*
|
456 |
-
* @see Net_SFTP::chdir()
|
457 |
-
* @param String $dir
|
458 |
-
* @param optional Integer $mode
|
459 |
-
* @return Mixed
|
460 |
-
* @access private
|
461 |
-
*/
|
462 |
-
function _realpath($dir)
|
463 |
-
{
|
464 |
-
/*
|
465 |
-
"This protocol represents file names as strings. File names are
|
466 |
-
assumed to use the slash ('/') character as a directory separator.
|
467 |
-
|
468 |
-
File names starting with a slash are "absolute", and are relative to
|
469 |
-
the root of the file system. Names starting with any other character
|
470 |
-
are relative to the user's default directory (home directory). Note
|
471 |
-
that identifying the user is assumed to take place outside of this
|
472 |
-
protocol."
|
473 |
-
|
474 |
-
-- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-6
|
475 |
-
*/
|
476 |
-
$file = '';
|
477 |
-
if ($this->pwd !== false) {
|
478 |
-
// if the SFTP server returned the canonicalized path even for non-existant files this wouldn't be necessary
|
479 |
-
// on OpenSSH it isn't necessary but on other SFTP servers it is. that and since the specs say nothing on
|
480 |
-
// the subject, we'll go ahead and work around it with the following.
|
481 |
-
if ($dir[strlen($dir) - 1] != '/') {
|
482 |
-
$file = basename($dir);
|
483 |
-
$dir = dirname($dir);
|
484 |
-
}
|
485 |
-
|
486 |
-
if ($dir == '.' || $dir == $this->pwd) {
|
487 |
-
return $this->pwd . $file;
|
488 |
-
}
|
489 |
-
|
490 |
-
if ($dir[0] != '/') {
|
491 |
-
$dir = $this->pwd . '/' . $dir;
|
492 |
-
}
|
493 |
-
// on the surface it seems like maybe resolving a path beginning with / is unnecessary, but such paths
|
494 |
-
// can contain .'s and ..'s just like any other. we could parse those out as appropriate or we can let
|
495 |
-
// the server do it. we'll do the latter.
|
496 |
-
}
|
497 |
-
|
498 |
-
/*
|
499 |
-
that SSH_FXP_REALPATH returns SSH_FXP_NAME does not necessarily mean that anything actually exists at the
|
500 |
-
specified path. generally speaking, no attributes are returned with this particular SSH_FXP_NAME packet
|
501 |
-
regardless of whether or not a file actually exists. and in SFTPv3, the longname field and the filename
|
502 |
-
field match for this particular SSH_FXP_NAME packet. for other SSH_FXP_NAME packets, this will likely
|
503 |
-
not be the case, but for this one, it is.
|
504 |
-
*/
|
505 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
|
506 |
-
if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($dir), $dir))) {
|
507 |
-
return false;
|
508 |
-
}
|
509 |
-
|
510 |
-
$response = $this->_get_sftp_packet();
|
511 |
-
switch ($this->packet_type) {
|
512 |
-
case NET_SFTP_NAME:
|
513 |
-
// although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following
|
514 |
-
// should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks
|
515 |
-
// at is the first part and that part is defined the same in SFTP versions 3 through 6.
|
516 |
-
$this->_string_shift($response, 4); // skip over the count - it should be 1, anyway
|
517 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
518 |
-
$realpath = $this->_string_shift($response, $length);
|
519 |
-
// the following is SFTPv3 only code. see Net_SFTP::_parseLongname() for more information.
|
520 |
-
// per the above comment, this is a shot in the dark that, on most servers, won't help us in determining
|
521 |
-
// the file type for Net_SFTP::stat() and Net_SFTP::lstat() but it's worth a shot.
|
522 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
523 |
-
$this->fileType = $this->_parseLongname($this->_string_shift($response, $length));
|
524 |
-
break;
|
525 |
-
case NET_SFTP_STATUS:
|
526 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
527 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
528 |
-
return false;
|
529 |
-
default:
|
530 |
-
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE);
|
531 |
-
return false;
|
532 |
-
}
|
533 |
-
|
534 |
-
// if $this->pwd isn't set than the only thing $realpath could be is for '.', which is pretty much guaranteed to
|
535 |
-
// be a bonafide directory
|
536 |
-
return $realpath . '/' . $file;
|
537 |
-
}
|
538 |
-
|
539 |
-
/**
|
540 |
-
* Changes the current directory
|
541 |
-
*
|
542 |
-
* @param String $dir
|
543 |
-
* @return Boolean
|
544 |
-
* @access public
|
545 |
-
*/
|
546 |
-
function chdir($dir)
|
547 |
-
{
|
548 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
549 |
-
return false;
|
550 |
-
}
|
551 |
-
|
552 |
-
if ($dir[strlen($dir) - 1] != '/') {
|
553 |
-
$dir.= '/';
|
554 |
-
}
|
555 |
-
$dir = $this->_realpath($dir);
|
556 |
-
|
557 |
-
// confirm that $dir is, in fact, a valid directory
|
558 |
-
if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) {
|
559 |
-
return false;
|
560 |
-
}
|
561 |
-
|
562 |
-
// see Net_SFTP::nlist() for a more thorough explanation of the following
|
563 |
-
$response = $this->_get_sftp_packet();
|
564 |
-
switch ($this->packet_type) {
|
565 |
-
case NET_SFTP_HANDLE:
|
566 |
-
$handle = substr($response, 4);
|
567 |
-
break;
|
568 |
-
case NET_SFTP_STATUS:
|
569 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
570 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
571 |
-
return false;
|
572 |
-
default:
|
573 |
-
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
574 |
-
return false;
|
575 |
-
}
|
576 |
-
|
577 |
-
if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {
|
578 |
-
return false;
|
579 |
-
}
|
580 |
-
|
581 |
-
$response = $this->_get_sftp_packet();
|
582 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
583 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
584 |
-
return false;
|
585 |
-
}
|
586 |
-
|
587 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
588 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
589 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
590 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
591 |
-
return false;
|
592 |
-
}
|
593 |
-
|
594 |
-
$this->pwd = $dir;
|
595 |
-
return true;
|
596 |
-
}
|
597 |
-
|
598 |
-
/**
|
599 |
-
* Returns a list of files in the given directory
|
600 |
-
*
|
601 |
-
* @param optional String $dir
|
602 |
-
* @return Mixed
|
603 |
-
* @access public
|
604 |
-
*/
|
605 |
-
function nlist($dir = '.')
|
606 |
-
{
|
607 |
-
return $this->_list($dir, false);
|
608 |
-
}
|
609 |
-
|
610 |
-
/**
|
611 |
-
* Returns a detailed list of files in the given directory
|
612 |
-
*
|
613 |
-
* @param optional String $dir
|
614 |
-
* @return Mixed
|
615 |
-
* @access public
|
616 |
-
*/
|
617 |
-
function rawlist($dir = '.')
|
618 |
-
{
|
619 |
-
return $this->_list($dir, true);
|
620 |
-
}
|
621 |
-
|
622 |
-
/**
|
623 |
-
* Reads a list, be it detailed or not, of files in the given directory
|
624 |
-
*
|
625 |
-
* @param optional String $dir
|
626 |
-
* @return Mixed
|
627 |
-
* @access private
|
628 |
-
*/
|
629 |
-
function _list($dir, $raw = true)
|
630 |
-
{
|
631 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
632 |
-
return false;
|
633 |
-
}
|
634 |
-
|
635 |
-
$dir = $this->_realpath($dir);
|
636 |
-
if ($dir === false) {
|
637 |
-
return false;
|
638 |
-
}
|
639 |
-
|
640 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2
|
641 |
-
if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) {
|
642 |
-
return false;
|
643 |
-
}
|
644 |
-
|
645 |
-
$response = $this->_get_sftp_packet();
|
646 |
-
switch ($this->packet_type) {
|
647 |
-
case NET_SFTP_HANDLE:
|
648 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2
|
649 |
-
// since 'handle' is the last field in the SSH_FXP_HANDLE packet, we'll just remove the first four bytes that
|
650 |
-
// represent the length of the string and leave it at that
|
651 |
-
$handle = substr($response, 4);
|
652 |
-
break;
|
653 |
-
case NET_SFTP_STATUS:
|
654 |
-
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
655 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
656 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
657 |
-
return false;
|
658 |
-
default:
|
659 |
-
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
660 |
-
return false;
|
661 |
-
}
|
662 |
-
|
663 |
-
$contents = array();
|
664 |
-
while (true) {
|
665 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2
|
666 |
-
// why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many
|
667 |
-
// SSH_MSG_CHANNEL_DATA messages is not known to me.
|
668 |
-
if (!$this->_send_sftp_packet(NET_SFTP_READDIR, pack('Na*', strlen($handle), $handle))) {
|
669 |
-
return false;
|
670 |
-
}
|
671 |
-
|
672 |
-
$response = $this->_get_sftp_packet();
|
673 |
-
switch ($this->packet_type) {
|
674 |
-
case NET_SFTP_NAME:
|
675 |
-
extract(unpack('Ncount', $this->_string_shift($response, 4)));
|
676 |
-
for ($i = 0; $i < $count; $i++) {
|
677 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
678 |
-
$shortname = $this->_string_shift($response, $length);
|
679 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
680 |
-
$longname = $this->_string_shift($response, $length);
|
681 |
-
$attributes = $this->_parseAttributes($response); // we also don't care about the attributes
|
682 |
-
if (!$raw) {
|
683 |
-
$contents[] = $shortname;
|
684 |
-
} else {
|
685 |
-
$contents[$shortname] = $attributes;
|
686 |
-
$fileType = $this->_parseLongname($longname);
|
687 |
-
if ($fileType) {
|
688 |
-
$contents[$shortname]['type'] = $fileType;
|
689 |
-
}
|
690 |
-
}
|
691 |
-
// SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the
|
692 |
-
// final SSH_FXP_STATUS packet should tell us that, already.
|
693 |
-
}
|
694 |
-
break;
|
695 |
-
case NET_SFTP_STATUS:
|
696 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
697 |
-
if ($status != NET_SFTP_STATUS_EOF) {
|
698 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
699 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
700 |
-
return false;
|
701 |
-
}
|
702 |
-
break 2;
|
703 |
-
default:
|
704 |
-
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE);
|
705 |
-
return false;
|
706 |
-
}
|
707 |
-
}
|
708 |
-
|
709 |
-
if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {
|
710 |
-
return false;
|
711 |
-
}
|
712 |
-
|
713 |
-
// "The client MUST release all resources associated with the handle regardless of the status."
|
714 |
-
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
|
715 |
-
$response = $this->_get_sftp_packet();
|
716 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
717 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
718 |
-
return false;
|
719 |
-
}
|
720 |
-
|
721 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
722 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
723 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
724 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
725 |
-
return false;
|
726 |
-
}
|
727 |
-
|
728 |
-
return $contents;
|
729 |
-
}
|
730 |
-
|
731 |
-
/**
|
732 |
-
* Returns the file size, in bytes, or false, on failure
|
733 |
-
*
|
734 |
-
* Files larger than 4GB will show up as being exactly 4GB.
|
735 |
-
*
|
736 |
-
* @param String $filename
|
737 |
-
* @return Mixed
|
738 |
-
* @access public
|
739 |
-
*/
|
740 |
-
function size($filename)
|
741 |
-
{
|
742 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
743 |
-
return false;
|
744 |
-
}
|
745 |
-
|
746 |
-
$filename = $this->_realpath($filename);
|
747 |
-
if ($filename === false) {
|
748 |
-
return false;
|
749 |
-
}
|
750 |
-
|
751 |
-
return $this->_size($filename);
|
752 |
-
}
|
753 |
-
|
754 |
-
/**
|
755 |
-
* Returns general information about a file.
|
756 |
-
*
|
757 |
-
* Returns an array on success and false otherwise.
|
758 |
-
*
|
759 |
-
* @param String $filename
|
760 |
-
* @return Mixed
|
761 |
-
* @access public
|
762 |
-
*/
|
763 |
-
function stat($filename)
|
764 |
-
{
|
765 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
766 |
-
return false;
|
767 |
-
}
|
768 |
-
|
769 |
-
$filename = $this->_realpath($filename);
|
770 |
-
if ($filename === false) {
|
771 |
-
return false;
|
772 |
-
}
|
773 |
-
|
774 |
-
return $this->_stat($filename, NET_SFTP_STAT);
|
775 |
-
}
|
776 |
-
|
777 |
-
/**
|
778 |
-
* Returns general information about a file or symbolic link.
|
779 |
-
*
|
780 |
-
* Returns an array on success and false otherwise.
|
781 |
-
*
|
782 |
-
* @param String $filename
|
783 |
-
* @return Mixed
|
784 |
-
* @access public
|
785 |
-
*/
|
786 |
-
function lstat($filename)
|
787 |
-
{
|
788 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
789 |
-
return false;
|
790 |
-
}
|
791 |
-
|
792 |
-
$filename = $this->_realpath($filename);
|
793 |
-
if ($filename === false) {
|
794 |
-
return false;
|
795 |
-
}
|
796 |
-
|
797 |
-
return $this->_stat($filename, NET_SFTP_LSTAT);
|
798 |
-
}
|
799 |
-
|
800 |
-
/**
|
801 |
-
* Returns general information about a file or symbolic link
|
802 |
-
*
|
803 |
-
* Determines information without calling Net_SFTP::_realpath().
|
804 |
-
* The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
|
805 |
-
*
|
806 |
-
* @param String $filename
|
807 |
-
* @param Integer $type
|
808 |
-
* @return Mixed
|
809 |
-
* @access private
|
810 |
-
*/
|
811 |
-
function _stat($filename, $type)
|
812 |
-
{
|
813 |
-
// SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
|
814 |
-
$packet = pack('Na*', strlen($filename), $filename);
|
815 |
-
if (!$this->_send_sftp_packet($type, $packet)) {
|
816 |
-
return false;
|
817 |
-
}
|
818 |
-
|
819 |
-
$response = $this->_get_sftp_packet();
|
820 |
-
switch ($this->packet_type) {
|
821 |
-
case NET_SFTP_ATTRS:
|
822 |
-
$attributes = $this->_parseAttributes($response);
|
823 |
-
if ($this->fileType) {
|
824 |
-
$attributes['type'] = $this->fileType;
|
825 |
-
}
|
826 |
-
return $attributes;
|
827 |
-
case NET_SFTP_STATUS:
|
828 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
829 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
830 |
-
return false;
|
831 |
-
}
|
832 |
-
|
833 |
-
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);
|
834 |
-
return false;
|
835 |
-
}
|
836 |
-
|
837 |
-
/**
|
838 |
-
* Returns the file size, in bytes, or false, on failure
|
839 |
-
*
|
840 |
-
* Determines the size without calling Net_SFTP::_realpath()
|
841 |
-
*
|
842 |
-
* @param String $filename
|
843 |
-
* @return Mixed
|
844 |
-
* @access private
|
845 |
-
*/
|
846 |
-
function _size($filename)
|
847 |
-
{
|
848 |
-
$result = $this->_stat($filename, NET_SFTP_LSTAT);
|
849 |
-
return $result === false ? false : $result['size'];
|
850 |
-
}
|
851 |
-
|
852 |
-
/**
|
853 |
-
* Set permissions on a file.
|
854 |
-
*
|
855 |
-
* Returns the new file permissions on success or FALSE on error.
|
856 |
-
*
|
857 |
-
* @param Integer $mode
|
858 |
-
* @param String $filename
|
859 |
-
* @return Mixed
|
860 |
-
* @access public
|
861 |
-
*/
|
862 |
-
function chmod($mode, $filename)
|
863 |
-
{
|
864 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
865 |
-
return false;
|
866 |
-
}
|
867 |
-
|
868 |
-
$filename = $this->_realpath($filename);
|
869 |
-
if ($filename === false) {
|
870 |
-
return false;
|
871 |
-
}
|
872 |
-
|
873 |
-
// SFTPv4+ has an additional byte field - type - that would need to be sent, as well. setting it to
|
874 |
-
// SSH_FILEXFER_TYPE_UNKNOWN might work. if not, we'd have to do an SSH_FXP_STAT before doing an SSH_FXP_SETSTAT.
|
875 |
-
$attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
|
876 |
-
if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($filename), $filename, $attr))) {
|
877 |
-
return false;
|
878 |
-
}
|
879 |
-
|
880 |
-
/*
|
881 |
-
"Because some systems must use separate system calls to set various attributes, it is possible that a failure
|
882 |
-
response will be returned, but yet some of the attributes may be have been successfully modified. If possible,
|
883 |
-
servers SHOULD avoid this situation; however, clients MUST be aware that this is possible."
|
884 |
-
|
885 |
-
-- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6
|
886 |
-
*/
|
887 |
-
$response = $this->_get_sftp_packet();
|
888 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
889 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
890 |
-
return false;
|
891 |
-
}
|
892 |
-
|
893 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
894 |
-
if ($status != NET_SFTP_STATUS_EOF) {
|
895 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
896 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
897 |
-
}
|
898 |
-
|
899 |
-
// rather than return what the permissions *should* be, we'll return what they actually are. this will also
|
900 |
-
// tell us if the file actually exists.
|
901 |
-
// incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
|
902 |
-
$packet = pack('Na*', strlen($filename), $filename);
|
903 |
-
if (!$this->_send_sftp_packet(NET_SFTP_STAT, $packet)) {
|
904 |
-
return false;
|
905 |
-
}
|
906 |
-
|
907 |
-
$response = $this->_get_sftp_packet();
|
908 |
-
switch ($this->packet_type) {
|
909 |
-
case NET_SFTP_ATTRS:
|
910 |
-
$attrs = $this->_parseAttributes($response);
|
911 |
-
return $attrs['permissions'];
|
912 |
-
case NET_SFTP_STATUS:
|
913 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
914 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
915 |
-
return false;
|
916 |
-
}
|
917 |
-
|
918 |
-
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);
|
919 |
-
return false;
|
920 |
-
}
|
921 |
-
|
922 |
-
/**
|
923 |
-
* Creates a directory.
|
924 |
-
*
|
925 |
-
* @param String $dir
|
926 |
-
* @return Boolean
|
927 |
-
* @access public
|
928 |
-
*/
|
929 |
-
function mkdir($dir)
|
930 |
-
{
|
931 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
932 |
-
return false;
|
933 |
-
}
|
934 |
-
|
935 |
-
$dir = $this->_realpath(rtrim($dir, '/'));
|
936 |
-
if ($dir === false) {
|
937 |
-
return false;
|
938 |
-
}
|
939 |
-
|
940 |
-
// by not providing any permissions, hopefully the server will use the logged in users umask - their
|
941 |
-
// default permissions.
|
942 |
-
if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*N', strlen($dir), $dir, 0))) {
|
943 |
-
return false;
|
944 |
-
}
|
945 |
-
|
946 |
-
$response = $this->_get_sftp_packet();
|
947 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
948 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
949 |
-
return false;
|
950 |
-
}
|
951 |
-
|
952 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
953 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
954 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
955 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
956 |
-
return false;
|
957 |
-
}
|
958 |
-
|
959 |
-
return true;
|
960 |
-
}
|
961 |
-
|
962 |
-
/**
|
963 |
-
* Removes a directory.
|
964 |
-
*
|
965 |
-
* @param String $dir
|
966 |
-
* @return Boolean
|
967 |
-
* @access public
|
968 |
-
*/
|
969 |
-
function rmdir($dir)
|
970 |
-
{
|
971 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
972 |
-
return false;
|
973 |
-
}
|
974 |
-
|
975 |
-
$dir = $this->_realpath($dir);
|
976 |
-
if ($dir === false) {
|
977 |
-
return false;
|
978 |
-
}
|
979 |
-
|
980 |
-
if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($dir), $dir))) {
|
981 |
-
return false;
|
982 |
-
}
|
983 |
-
|
984 |
-
$response = $this->_get_sftp_packet();
|
985 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
986 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
987 |
-
return false;
|
988 |
-
}
|
989 |
-
|
990 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
991 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
992 |
-
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?
|
993 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
994 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
995 |
-
return false;
|
996 |
-
}
|
997 |
-
|
998 |
-
return true;
|
999 |
-
}
|
1000 |
-
|
1001 |
-
/**
|
1002 |
-
* Uploads a file to the SFTP server.
|
1003 |
-
*
|
1004 |
-
* By default, Net_SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
|
1005 |
-
* So, for example, if you set $data to 'filename.ext' and then do Net_SFTP::get(), you will get a file, twelve bytes
|
1006 |
-
* long, containing 'filename.ext' as its contents.
|
1007 |
-
*
|
1008 |
-
* Setting $mode to NET_SFTP_LOCAL_FILE will change the above behavior. With NET_SFTP_LOCAL_FILE, $remote_file will
|
1009 |
-
* contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
|
1010 |
-
* large $remote_file will be, as well.
|
1011 |
-
*
|
1012 |
-
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
|
1013 |
-
* care of that, yourself.
|
1014 |
-
*
|
1015 |
-
* @param String $remote_file
|
1016 |
-
* @param String $data
|
1017 |
-
* @param optional Integer $mode
|
1018 |
-
* @return Boolean
|
1019 |
-
* @access public
|
1020 |
-
* @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - Net_SFTP::setMode().
|
1021 |
-
*/
|
1022 |
-
function put($remote_file, $data, $mode = NET_SFTP_STRING)
|
1023 |
-
{
|
1024 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
1025 |
-
return false;
|
1026 |
-
}
|
1027 |
-
|
1028 |
-
$remote_file = $this->_realpath($remote_file);
|
1029 |
-
if ($remote_file === false) {
|
1030 |
-
return false;
|
1031 |
-
}
|
1032 |
-
|
1033 |
-
$packet = pack('Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_TRUNCATE, 0);
|
1034 |
-
if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
|
1035 |
-
return false;
|
1036 |
-
}
|
1037 |
-
|
1038 |
-
$response = $this->_get_sftp_packet();
|
1039 |
-
switch ($this->packet_type) {
|
1040 |
-
case NET_SFTP_HANDLE:
|
1041 |
-
$handle = substr($response, 4);
|
1042 |
-
break;
|
1043 |
-
case NET_SFTP_STATUS:
|
1044 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
1045 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1046 |
-
return false;
|
1047 |
-
default:
|
1048 |
-
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
1049 |
-
return false;
|
1050 |
-
}
|
1051 |
-
|
1052 |
-
$initialize = true;
|
1053 |
-
|
1054 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
1055 |
-
if ($mode == NET_SFTP_LOCAL_FILE) {
|
1056 |
-
if (!is_file($data)) {
|
1057 |
-
user_error("$data is not a valid file", E_USER_NOTICE);
|
1058 |
-
return false;
|
1059 |
-
}
|
1060 |
-
$fp = @fopen($data, 'rb');
|
1061 |
-
if (!$fp) {
|
1062 |
-
return false;
|
1063 |
-
}
|
1064 |
-
$sent = 0;
|
1065 |
-
$size = filesize($data);
|
1066 |
-
} else {
|
1067 |
-
$sent = 0;
|
1068 |
-
$size = strlen($data);
|
1069 |
-
}
|
1070 |
-
|
1071 |
-
$size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;
|
1072 |
-
|
1073 |
-
$sftp_packet_size = 4096; // PuTTY uses 4096
|
1074 |
-
$i = 0;
|
1075 |
-
while ($sent < $size) {
|
1076 |
-
$temp = $mode == NET_SFTP_LOCAL_FILE ? fread($fp, $sftp_packet_size) : $this->_string_shift($data, $sftp_packet_size);
|
1077 |
-
$packet = pack('Na*N3a*', strlen($handle), $handle, 0, $sent, strlen($temp), $temp);
|
1078 |
-
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
|
1079 |
-
fclose($fp);
|
1080 |
-
return false;
|
1081 |
-
}
|
1082 |
-
$sent+= strlen($temp);
|
1083 |
-
|
1084 |
-
$i++;
|
1085 |
-
|
1086 |
-
if ($i == 50) {
|
1087 |
-
if (!$this->_read_put_responses($i)) {
|
1088 |
-
$i = 0;
|
1089 |
-
break;
|
1090 |
-
}
|
1091 |
-
$i = 0;
|
1092 |
-
}
|
1093 |
-
}
|
1094 |
-
|
1095 |
-
$this->_read_put_responses($i);
|
1096 |
-
|
1097 |
-
if ($mode == NET_SFTP_LOCAL_FILE) {
|
1098 |
-
fclose($fp);
|
1099 |
-
}
|
1100 |
-
|
1101 |
-
if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {
|
1102 |
-
return false;
|
1103 |
-
}
|
1104 |
-
|
1105 |
-
$response = $this->_get_sftp_packet();
|
1106 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
1107 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
1108 |
-
return false;
|
1109 |
-
}
|
1110 |
-
|
1111 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
1112 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
1113 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1114 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1115 |
-
return false;
|
1116 |
-
}
|
1117 |
-
|
1118 |
-
return true;
|
1119 |
-
}
|
1120 |
-
|
1121 |
-
/**
|
1122 |
-
* Reads multiple successive SSH_FXP_WRITE responses
|
1123 |
-
*
|
1124 |
-
* Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i
|
1125 |
-
* SSH_FXP_WRITEs, in succession, and then reading $i responses.
|
1126 |
-
*
|
1127 |
-
* @param Integer $i
|
1128 |
-
* @return Boolean
|
1129 |
-
* @access private
|
1130 |
-
*/
|
1131 |
-
function _read_put_responses($i)
|
1132 |
-
{
|
1133 |
-
while ($i--) {
|
1134 |
-
$response = $this->_get_sftp_packet();
|
1135 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
1136 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
1137 |
-
return false;
|
1138 |
-
}
|
1139 |
-
|
1140 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
1141 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
1142 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1143 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1144 |
-
break;
|
1145 |
-
}
|
1146 |
-
}
|
1147 |
-
|
1148 |
-
return $i < 0;
|
1149 |
-
}
|
1150 |
-
|
1151 |
-
/**
|
1152 |
-
* Downloads a file from the SFTP server.
|
1153 |
-
*
|
1154 |
-
* Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
|
1155 |
-
* the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the
|
1156 |
-
* operation
|
1157 |
-
*
|
1158 |
-
* @param String $remote_file
|
1159 |
-
* @param optional String $local_file
|
1160 |
-
* @return Mixed
|
1161 |
-
* @access public
|
1162 |
-
*/
|
1163 |
-
function get($remote_file, $local_file = false)
|
1164 |
-
{
|
1165 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
1166 |
-
return false;
|
1167 |
-
}
|
1168 |
-
|
1169 |
-
$remote_file = $this->_realpath($remote_file);
|
1170 |
-
if ($remote_file === false) {
|
1171 |
-
return false;
|
1172 |
-
}
|
1173 |
-
|
1174 |
-
$size = $this->_size($remote_file);
|
1175 |
-
if ($size === false) {
|
1176 |
-
return false;
|
1177 |
-
}
|
1178 |
-
|
1179 |
-
$packet = pack('Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_READ, 0);
|
1180 |
-
if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
|
1181 |
-
return false;
|
1182 |
-
}
|
1183 |
-
|
1184 |
-
$response = $this->_get_sftp_packet();
|
1185 |
-
switch ($this->packet_type) {
|
1186 |
-
case NET_SFTP_HANDLE:
|
1187 |
-
$handle = substr($response, 4);
|
1188 |
-
break;
|
1189 |
-
case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
1190 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
1191 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1192 |
-
return false;
|
1193 |
-
default:
|
1194 |
-
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
1195 |
-
return false;
|
1196 |
-
}
|
1197 |
-
|
1198 |
-
if ($local_file !== false) {
|
1199 |
-
$fp = fopen($local_file, 'wb');
|
1200 |
-
if (!$fp) {
|
1201 |
-
return false;
|
1202 |
-
}
|
1203 |
-
} else {
|
1204 |
-
$content = '';
|
1205 |
-
}
|
1206 |
-
|
1207 |
-
$read = 0;
|
1208 |
-
while ($read < $size) {
|
1209 |
-
$packet = pack('Na*N3', strlen($handle), $handle, 0, $read, 1 << 20);
|
1210 |
-
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
|
1211 |
-
return false;
|
1212 |
-
}
|
1213 |
-
|
1214 |
-
$response = $this->_get_sftp_packet();
|
1215 |
-
switch ($this->packet_type) {
|
1216 |
-
case NET_SFTP_DATA:
|
1217 |
-
$temp = substr($response, 4);
|
1218 |
-
$read+= strlen($temp);
|
1219 |
-
if ($local_file === false) {
|
1220 |
-
$content.= $temp;
|
1221 |
-
} else {
|
1222 |
-
fputs($fp, $temp);
|
1223 |
-
}
|
1224 |
-
break;
|
1225 |
-
case NET_SFTP_STATUS:
|
1226 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
1227 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1228 |
-
break 2;
|
1229 |
-
default:
|
1230 |
-
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS', E_USER_NOTICE);
|
1231 |
-
return false;
|
1232 |
-
}
|
1233 |
-
}
|
1234 |
-
|
1235 |
-
if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {
|
1236 |
-
return false;
|
1237 |
-
}
|
1238 |
-
|
1239 |
-
$response = $this->_get_sftp_packet();
|
1240 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
1241 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
1242 |
-
return false;
|
1243 |
-
}
|
1244 |
-
|
1245 |
-
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
1246 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1247 |
-
|
1248 |
-
// check the status from the NET_SFTP_STATUS case in the above switch after the file has been closed
|
1249 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
1250 |
-
return false;
|
1251 |
-
}
|
1252 |
-
|
1253 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
1254 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
1255 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1256 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1257 |
-
return false;
|
1258 |
-
}
|
1259 |
-
|
1260 |
-
if (isset($content)) {
|
1261 |
-
return $content;
|
1262 |
-
}
|
1263 |
-
|
1264 |
-
fclose($fp);
|
1265 |
-
return true;
|
1266 |
-
}
|
1267 |
-
|
1268 |
-
/**
|
1269 |
-
* Deletes a file on the SFTP server.
|
1270 |
-
*
|
1271 |
-
* @param String $path
|
1272 |
-
* @return Boolean
|
1273 |
-
* @access public
|
1274 |
-
*/
|
1275 |
-
function delete($path)
|
1276 |
-
{
|
1277 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
1278 |
-
return false;
|
1279 |
-
}
|
1280 |
-
|
1281 |
-
$path = $this->_realpath($path);
|
1282 |
-
if ($path === false) {
|
1283 |
-
return false;
|
1284 |
-
}
|
1285 |
-
|
1286 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
|
1287 |
-
if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path))) {
|
1288 |
-
return false;
|
1289 |
-
}
|
1290 |
-
|
1291 |
-
$response = $this->_get_sftp_packet();
|
1292 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
1293 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
1294 |
-
return false;
|
1295 |
-
}
|
1296 |
-
|
1297 |
-
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
1298 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
1299 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
1300 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1301 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1302 |
-
return false;
|
1303 |
-
}
|
1304 |
-
|
1305 |
-
return true;
|
1306 |
-
}
|
1307 |
-
|
1308 |
-
/**
|
1309 |
-
* Renames a file or a directory on the SFTP server
|
1310 |
-
*
|
1311 |
-
* @param String $oldname
|
1312 |
-
* @param String $newname
|
1313 |
-
* @return Boolean
|
1314 |
-
* @access public
|
1315 |
-
*/
|
1316 |
-
function rename($oldname, $newname)
|
1317 |
-
{
|
1318 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
1319 |
-
return false;
|
1320 |
-
}
|
1321 |
-
|
1322 |
-
$oldname = $this->_realpath($oldname);
|
1323 |
-
$newname = $this->_realpath($newname);
|
1324 |
-
if ($oldname === false || $newname === false) {
|
1325 |
-
return false;
|
1326 |
-
}
|
1327 |
-
|
1328 |
-
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
|
1329 |
-
$packet = pack('Na*Na*', strlen($oldname), $oldname, strlen($newname), $newname);
|
1330 |
-
if (!$this->_send_sftp_packet(NET_SFTP_RENAME, $packet)) {
|
1331 |
-
return false;
|
1332 |
-
}
|
1333 |
-
|
1334 |
-
$response = $this->_get_sftp_packet();
|
1335 |
-
if ($this->packet_type != NET_SFTP_STATUS) {
|
1336 |
-
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
1337 |
-
return false;
|
1338 |
-
}
|
1339 |
-
|
1340 |
-
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
1341 |
-
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
1342 |
-
if ($status != NET_SFTP_STATUS_OK) {
|
1343 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1344 |
-
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
1345 |
-
return false;
|
1346 |
-
}
|
1347 |
-
|
1348 |
-
return true;
|
1349 |
-
}
|
1350 |
-
|
1351 |
-
/**
|
1352 |
-
* Parse Attributes
|
1353 |
-
*
|
1354 |
-
* See '7. File Attributes' of draft-ietf-secsh-filexfer-13 for more info.
|
1355 |
-
*
|
1356 |
-
* @param String $response
|
1357 |
-
* @return Array
|
1358 |
-
* @access private
|
1359 |
-
*/
|
1360 |
-
function _parseAttributes(&$response)
|
1361 |
-
{
|
1362 |
-
$attr = array();
|
1363 |
-
extract(unpack('Nflags', $this->_string_shift($response, 4)));
|
1364 |
-
// SFTPv4+ have a type field (a byte) that follows the above flag field
|
1365 |
-
foreach ($this->attributes as $key => $value) {
|
1366 |
-
switch ($flags & $key) {
|
1367 |
-
case NET_SFTP_ATTR_SIZE: // 0x00000001
|
1368 |
-
// size is represented by a 64-bit integer, so we perhaps ought to be doing the following:
|
1369 |
-
// $attr['size'] = new Math_BigInteger($this->_string_shift($response, 8), 256);
|
1370 |
-
// of course, you shouldn't be using Net_SFTP to transfer files that are in excess of 4GB
|
1371 |
-
// (0xFFFFFFFF bytes), anyway. as such, we'll just represent all file sizes that are bigger than
|
1372 |
-
// 4GB as being 4GB.
|
1373 |
-
extract(unpack('Nupper/Nsize', $this->_string_shift($response, 8)));
|
1374 |
-
if ($upper) {
|
1375 |
-
$attr['size'] = 0xFFFFFFFF;
|
1376 |
-
} else {
|
1377 |
-
$attr['size'] = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;
|
1378 |
-
}
|
1379 |
-
break;
|
1380 |
-
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
|
1381 |
-
$attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));
|
1382 |
-
break;
|
1383 |
-
case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004
|
1384 |
-
$attr+= unpack('Npermissions', $this->_string_shift($response, 4));
|
1385 |
-
break;
|
1386 |
-
case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008
|
1387 |
-
$attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8));
|
1388 |
-
break;
|
1389 |
-
case NET_SFTP_ATTR_EXTENDED: // 0x80000000
|
1390 |
-
extract(unpack('Ncount', $this->_string_shift($response, 4)));
|
1391 |
-
for ($i = 0; $i < $count; $i++) {
|
1392 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1393 |
-
$key = $this->_string_shift($response, $length);
|
1394 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1395 |
-
$attr[$key] = $this->_string_shift($response, $length);
|
1396 |
-
}
|
1397 |
-
}
|
1398 |
-
}
|
1399 |
-
return $attr;
|
1400 |
-
}
|
1401 |
-
|
1402 |
-
/**
|
1403 |
-
* Parse Longname
|
1404 |
-
*
|
1405 |
-
* SFTPv3 doesn't provide any easy way of identifying a file type. You could try to open
|
1406 |
-
* a file as a directory and see if an error is returned or you could try to parse the
|
1407 |
-
* SFTPv3-specific longname field of the SSH_FXP_NAME packet. That's what this function does.
|
1408 |
-
* The result is returned using the
|
1409 |
-
* {@link http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 SFTPv4 type constants}.
|
1410 |
-
*
|
1411 |
-
* If the longname is in an unrecognized format bool(false) is returned.
|
1412 |
-
*
|
1413 |
-
* @param String $longname
|
1414 |
-
* @return Mixed
|
1415 |
-
* @access private
|
1416 |
-
*/
|
1417 |
-
function _parseLongname($longname)
|
1418 |
-
{
|
1419 |
-
// http://en.wikipedia.org/wiki/Unix_file_types
|
1420 |
-
if (preg_match('#^[^/]([r-][w-][x-]){3}#', $longname)) {
|
1421 |
-
switch ($longname[0]) {
|
1422 |
-
case '-':
|
1423 |
-
return NET_SFTP_TYPE_REGULAR;
|
1424 |
-
case 'd':
|
1425 |
-
return NET_SFTP_TYPE_DIRECTORY;
|
1426 |
-
case 'l':
|
1427 |
-
return NET_SFTP_TYPE_SYMLINK;
|
1428 |
-
default:
|
1429 |
-
return NET_SFTP_TYPE_SPECIAL;
|
1430 |
-
}
|
1431 |
-
}
|
1432 |
-
|
1433 |
-
return false;
|
1434 |
-
}
|
1435 |
-
|
1436 |
-
/**
|
1437 |
-
* Sends SFTP Packets
|
1438 |
-
*
|
1439 |
-
* See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
|
1440 |
-
*
|
1441 |
-
* @param Integer $type
|
1442 |
-
* @param String $data
|
1443 |
-
* @see Net_SFTP::_get_sftp_packet()
|
1444 |
-
* @see Net_SSH2::_send_channel_packet()
|
1445 |
-
* @return Boolean
|
1446 |
-
* @access private
|
1447 |
-
*/
|
1448 |
-
function _send_sftp_packet($type, $data)
|
1449 |
-
{
|
1450 |
-
$packet = $this->request_id !== false ?
|
1451 |
-
pack('NCNa*', strlen($data) + 5, $type, $this->request_id, $data) :
|
1452 |
-
pack('NCa*', strlen($data) + 1, $type, $data);
|
1453 |
-
|
1454 |
-
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
1455 |
-
$result = $this->_send_channel_packet(NET_SFTP_CHANNEL, $packet);
|
1456 |
-
$stop = strtok(microtime(), ' ') + strtok('');
|
1457 |
-
|
1458 |
-
if (defined('NET_SFTP_LOGGING')) {
|
1459 |
-
$this->packet_type_log[] = '-> ' . $this->packet_types[$type] .
|
1460 |
-
' (' . round($stop - $start, 4) . 's)';
|
1461 |
-
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
|
1462 |
-
$this->packet_log[] = $data;
|
1463 |
-
}
|
1464 |
-
}
|
1465 |
-
|
1466 |
-
return $result;
|
1467 |
-
}
|
1468 |
-
|
1469 |
-
/**
|
1470 |
-
* Receives SFTP Packets
|
1471 |
-
*
|
1472 |
-
* See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
|
1473 |
-
*
|
1474 |
-
* Incidentally, the number of SSH_MSG_CHANNEL_DATA messages has no bearing on the number of SFTP packets present.
|
1475 |
-
* There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA
|
1476 |
-
* messages containing one SFTP packet.
|
1477 |
-
*
|
1478 |
-
* @see Net_SFTP::_send_sftp_packet()
|
1479 |
-
* @return String
|
1480 |
-
* @access private
|
1481 |
-
*/
|
1482 |
-
function _get_sftp_packet()
|
1483 |
-
{
|
1484 |
-
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
1485 |
-
|
1486 |
-
// SFTP packet length
|
1487 |
-
while (strlen($this->packet_buffer) < 4) {
|
1488 |
-
$temp = $this->_get_channel_packet(NET_SFTP_CHANNEL);
|
1489 |
-
if (is_bool($temp)) {
|
1490 |
-
$this->packet_type = false;
|
1491 |
-
$this->packet_buffer = '';
|
1492 |
-
return false;
|
1493 |
-
}
|
1494 |
-
$this->packet_buffer.= $temp;
|
1495 |
-
}
|
1496 |
-
extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4)));
|
1497 |
-
$tempLength = $length;
|
1498 |
-
$tempLength-= strlen($this->packet_buffer);
|
1499 |
-
|
1500 |
-
// SFTP packet type and data payload
|
1501 |
-
while ($tempLength > 0) {
|
1502 |
-
$temp = $this->_get_channel_packet(NET_SFTP_CHANNEL);
|
1503 |
-
if (is_bool($temp)) {
|
1504 |
-
$this->packet_type = false;
|
1505 |
-
$this->packet_buffer = '';
|
1506 |
-
return false;
|
1507 |
-
}
|
1508 |
-
$this->packet_buffer.= $temp;
|
1509 |
-
$tempLength-= strlen($temp);
|
1510 |
-
}
|
1511 |
-
|
1512 |
-
$stop = strtok(microtime(), ' ') + strtok('');
|
1513 |
-
|
1514 |
-
$this->packet_type = ord($this->_string_shift($this->packet_buffer));
|
1515 |
-
|
1516 |
-
if ($this->request_id !== false) {
|
1517 |
-
$this->_string_shift($this->packet_buffer, 4); // remove the request id
|
1518 |
-
$length-= 5; // account for the request id and the packet type
|
1519 |
-
} else {
|
1520 |
-
$length-= 1; // account for the packet type
|
1521 |
-
}
|
1522 |
-
|
1523 |
-
$packet = $this->_string_shift($this->packet_buffer, $length);
|
1524 |
-
|
1525 |
-
if (defined('NET_SFTP_LOGGING')) {
|
1526 |
-
$this->packet_type_log[] = '<- ' . $this->packet_types[$this->packet_type] .
|
1527 |
-
' (' . round($stop - $start, 4) . 's)';
|
1528 |
-
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
|
1529 |
-
$this->packet_log[] = $packet;
|
1530 |
-
}
|
1531 |
-
}
|
1532 |
-
|
1533 |
-
return $packet;
|
1534 |
-
}
|
1535 |
-
|
1536 |
-
/**
|
1537 |
-
* Returns a log of the packets that have been sent and received.
|
1538 |
-
*
|
1539 |
-
* Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')
|
1540 |
-
*
|
1541 |
-
* @access public
|
1542 |
-
* @return String or Array
|
1543 |
-
*/
|
1544 |
-
function getSFTPLog()
|
1545 |
-
{
|
1546 |
-
if (!defined('NET_SFTP_LOGGING')) {
|
1547 |
-
return false;
|
1548 |
-
}
|
1549 |
-
|
1550 |
-
switch (NET_SFTP_LOGGING) {
|
1551 |
-
case NET_SFTP_LOG_COMPLEX:
|
1552 |
-
return $this->_format_log($this->packet_log, $this->packet_type_log);
|
1553 |
-
break;
|
1554 |
-
//case NET_SFTP_LOG_SIMPLE:
|
1555 |
-
default:
|
1556 |
-
return $this->packet_type_log;
|
1557 |
-
}
|
1558 |
-
}
|
1559 |
-
|
1560 |
-
/**
|
1561 |
-
* Returns all errors
|
1562 |
-
*
|
1563 |
-
* @return String
|
1564 |
-
* @access public
|
1565 |
-
*/
|
1566 |
-
function getSFTPErrors()
|
1567 |
-
{
|
1568 |
-
return $this->sftp_errors;
|
1569 |
-
}
|
1570 |
-
|
1571 |
-
/**
|
1572 |
-
* Returns the last error
|
1573 |
-
*
|
1574 |
-
* @return String
|
1575 |
-
* @access public
|
1576 |
-
*/
|
1577 |
-
function getLastSFTPError()
|
1578 |
-
{
|
1579 |
-
return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : '';
|
1580 |
-
}
|
1581 |
-
|
1582 |
-
/**
|
1583 |
-
* Get supported SFTP versions
|
1584 |
-
*
|
1585 |
-
* @return Array
|
1586 |
-
* @access public
|
1587 |
-
*/
|
1588 |
-
function getSupportedVersions()
|
1589 |
-
{
|
1590 |
-
$temp = array('version' => $this->version);
|
1591 |
-
if (isset($this->extensions['versions'])) {
|
1592 |
-
$temp['extensions'] = $this->extensions['versions'];
|
1593 |
-
}
|
1594 |
-
return $temp;
|
1595 |
-
}
|
1596 |
-
|
1597 |
-
/**
|
1598 |
-
* Disconnect
|
1599 |
-
*
|
1600 |
-
* @param Integer $reason
|
1601 |
-
* @return Boolean
|
1602 |
-
* @access private
|
1603 |
-
*/
|
1604 |
-
function _disconnect($reason)
|
1605 |
-
{
|
1606 |
-
$this->pwd = false;
|
1607 |
-
parent::_disconnect($reason);
|
1608 |
-
}
|
1609 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Net/SSH1.php
DELETED
@@ -1,1408 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of SSHv1.
|
6 |
-
*
|
7 |
-
* PHP versions 4 and 5
|
8 |
-
*
|
9 |
-
* Here's a short example of how to use this library:
|
10 |
-
* <code>
|
11 |
-
* <?php
|
12 |
-
* include('Net/SSH1.php');
|
13 |
-
*
|
14 |
-
* $ssh = new Net_SSH1('www.domain.tld');
|
15 |
-
* if (!$ssh->login('username', 'password')) {
|
16 |
-
* exit('Login Failed');
|
17 |
-
* }
|
18 |
-
*
|
19 |
-
* echo $ssh->exec('ls -la');
|
20 |
-
* ?>
|
21 |
-
* </code>
|
22 |
-
*
|
23 |
-
* Here's another short example:
|
24 |
-
* <code>
|
25 |
-
* <?php
|
26 |
-
* include('Net/SSH1.php');
|
27 |
-
*
|
28 |
-
* $ssh = new Net_SSH1('www.domain.tld');
|
29 |
-
* if (!$ssh->login('username', 'password')) {
|
30 |
-
* exit('Login Failed');
|
31 |
-
* }
|
32 |
-
*
|
33 |
-
* echo $ssh->read('username@username:~$');
|
34 |
-
* $ssh->write("ls -la\n");
|
35 |
-
* echo $ssh->read('username@username:~$');
|
36 |
-
* ?>
|
37 |
-
* </code>
|
38 |
-
*
|
39 |
-
* More information on the SSHv1 specification can be found by reading
|
40 |
-
* {@link http://www.snailbook.com/docs/protocol-1.5.txt protocol-1.5.txt}.
|
41 |
-
*
|
42 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
43 |
-
* of this software and associated documentation files (the "Software"), to deal
|
44 |
-
* in the Software without restriction, including without limitation the rights
|
45 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
46 |
-
* copies of the Software, and to permit persons to whom the Software is
|
47 |
-
* furnished to do so, subject to the following conditions:
|
48 |
-
*
|
49 |
-
* The above copyright notice and this permission notice shall be included in
|
50 |
-
* all copies or substantial portions of the Software.
|
51 |
-
*
|
52 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
53 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
54 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
55 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
56 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
57 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
58 |
-
* THE SOFTWARE.
|
59 |
-
*
|
60 |
-
* @category Net
|
61 |
-
* @package Net_SSH1
|
62 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
63 |
-
* @copyright MMVII Jim Wigginton
|
64 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
65 |
-
* @version $Id: SSH1.php,v 1.15 2010/03/22 22:01:38 terrafrost Exp $
|
66 |
-
* @link http://phpseclib.sourceforge.net
|
67 |
-
*/
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Include Math_BigInteger
|
71 |
-
*
|
72 |
-
* Used to do RSA encryption.
|
73 |
-
*/
|
74 |
-
require_once('Math/BigInteger.php');
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Include Crypt_Null
|
78 |
-
*/
|
79 |
-
//require_once('Crypt/Null.php');
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Include Crypt_DES
|
83 |
-
*/
|
84 |
-
require_once('Crypt/DES.php');
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Include Crypt_TripleDES
|
88 |
-
*/
|
89 |
-
require_once('Crypt/TripleDES.php');
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Include Crypt_RC4
|
93 |
-
*/
|
94 |
-
require_once('Crypt/RC4.php');
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Include Crypt_Random
|
98 |
-
*/
|
99 |
-
require_once('Crypt/Random.php');
|
100 |
-
|
101 |
-
/**#@+
|
102 |
-
* Encryption Methods
|
103 |
-
*
|
104 |
-
* @see Net_SSH1::getSupportedCiphers()
|
105 |
-
* @access public
|
106 |
-
*/
|
107 |
-
/**
|
108 |
-
* No encryption
|
109 |
-
*
|
110 |
-
* Not supported.
|
111 |
-
*/
|
112 |
-
define('NET_SSH1_CIPHER_NONE', 0);
|
113 |
-
/**
|
114 |
-
* IDEA in CFB mode
|
115 |
-
*
|
116 |
-
* Not supported.
|
117 |
-
*/
|
118 |
-
define('NET_SSH1_CIPHER_IDEA', 1);
|
119 |
-
/**
|
120 |
-
* DES in CBC mode
|
121 |
-
*/
|
122 |
-
define('NET_SSH1_CIPHER_DES', 2);
|
123 |
-
/**
|
124 |
-
* Triple-DES in CBC mode
|
125 |
-
*
|
126 |
-
* All implementations are required to support this
|
127 |
-
*/
|
128 |
-
define('NET_SSH1_CIPHER_3DES', 3);
|
129 |
-
/**
|
130 |
-
* TRI's Simple Stream encryption CBC
|
131 |
-
*
|
132 |
-
* Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, does define it (see cipher.h),
|
133 |
-
* although it doesn't use it (see cipher.c)
|
134 |
-
*/
|
135 |
-
define('NET_SSH1_CIPHER_BROKEN_TSS', 4);
|
136 |
-
/**
|
137 |
-
* RC4
|
138 |
-
*
|
139 |
-
* Not supported.
|
140 |
-
*
|
141 |
-
* @internal According to the SSH1 specs:
|
142 |
-
*
|
143 |
-
* "The first 16 bytes of the session key are used as the key for
|
144 |
-
* the server to client direction. The remaining 16 bytes are used
|
145 |
-
* as the key for the client to server direction. This gives
|
146 |
-
* independent 128-bit keys for each direction."
|
147 |
-
*
|
148 |
-
* This library currently only supports encryption when the same key is being used for both directions. This is
|
149 |
-
* because there's only one $crypto object. Two could be added ($encrypt and $decrypt, perhaps).
|
150 |
-
*/
|
151 |
-
define('NET_SSH1_CIPHER_RC4', 5);
|
152 |
-
/**
|
153 |
-
* Blowfish
|
154 |
-
*
|
155 |
-
* Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, defines it (see cipher.h) and
|
156 |
-
* uses it (see cipher.c)
|
157 |
-
*/
|
158 |
-
define('NET_SSH1_CIPHER_BLOWFISH', 6);
|
159 |
-
/**#@-*/
|
160 |
-
|
161 |
-
/**#@+
|
162 |
-
* Authentication Methods
|
163 |
-
*
|
164 |
-
* @see Net_SSH1::getSupportedAuthentications()
|
165 |
-
* @access public
|
166 |
-
*/
|
167 |
-
/**
|
168 |
-
* .rhosts or /etc/hosts.equiv
|
169 |
-
*/
|
170 |
-
define('NET_SSH1_AUTH_RHOSTS', 1);
|
171 |
-
/**
|
172 |
-
* pure RSA authentication
|
173 |
-
*/
|
174 |
-
define('NET_SSH1_AUTH_RSA', 2);
|
175 |
-
/**
|
176 |
-
* password authentication
|
177 |
-
*
|
178 |
-
* This is the only method that is supported by this library.
|
179 |
-
*/
|
180 |
-
define('NET_SSH1_AUTH_PASSWORD', 3);
|
181 |
-
/**
|
182 |
-
* .rhosts with RSA host authentication
|
183 |
-
*/
|
184 |
-
define('NET_SSH1_AUTH_RHOSTS_RSA', 4);
|
185 |
-
/**#@-*/
|
186 |
-
|
187 |
-
/**#@+
|
188 |
-
* Terminal Modes
|
189 |
-
*
|
190 |
-
* @link http://3sp.com/content/developer/maverick-net/docs/Maverick.SSH.PseudoTerminalModesMembers.html
|
191 |
-
* @access private
|
192 |
-
*/
|
193 |
-
define('NET_SSH1_TTY_OP_END', 0);
|
194 |
-
/**#@-*/
|
195 |
-
|
196 |
-
/**
|
197 |
-
* The Response Type
|
198 |
-
*
|
199 |
-
* @see Net_SSH1::_get_binary_packet()
|
200 |
-
* @access private
|
201 |
-
*/
|
202 |
-
define('NET_SSH1_RESPONSE_TYPE', 1);
|
203 |
-
|
204 |
-
/**
|
205 |
-
* The Response Data
|
206 |
-
*
|
207 |
-
* @see Net_SSH1::_get_binary_packet()
|
208 |
-
* @access private
|
209 |
-
*/
|
210 |
-
define('NET_SSH1_RESPONSE_DATA', 2);
|
211 |
-
|
212 |
-
/**#@+
|
213 |
-
* Execution Bitmap Masks
|
214 |
-
*
|
215 |
-
* @see Net_SSH1::bitmap
|
216 |
-
* @access private
|
217 |
-
*/
|
218 |
-
define('NET_SSH1_MASK_CONSTRUCTOR', 0x00000001);
|
219 |
-
define('NET_SSH1_MASK_LOGIN', 0x00000002);
|
220 |
-
define('NET_SSH1_MASK_SHELL', 0x00000004);
|
221 |
-
/**#@-*/
|
222 |
-
|
223 |
-
/**#@+
|
224 |
-
* @access public
|
225 |
-
* @see Net_SSH1::getLog()
|
226 |
-
*/
|
227 |
-
/**
|
228 |
-
* Returns the message numbers
|
229 |
-
*/
|
230 |
-
define('NET_SSH1_LOG_SIMPLE', 1);
|
231 |
-
/**
|
232 |
-
* Returns the message content
|
233 |
-
*/
|
234 |
-
define('NET_SSH1_LOG_COMPLEX', 2);
|
235 |
-
/**#@-*/
|
236 |
-
|
237 |
-
/**#@+
|
238 |
-
* @access public
|
239 |
-
* @see Net_SSH1::read()
|
240 |
-
*/
|
241 |
-
/**
|
242 |
-
* Returns when a string matching $expect exactly is found
|
243 |
-
*/
|
244 |
-
define('NET_SSH1_READ_SIMPLE', 1);
|
245 |
-
/**
|
246 |
-
* Returns when a string matching the regular expression $expect is found
|
247 |
-
*/
|
248 |
-
define('NET_SSH1_READ_REGEX', 2);
|
249 |
-
/**#@-*/
|
250 |
-
|
251 |
-
/**
|
252 |
-
* Pure-PHP implementation of SSHv1.
|
253 |
-
*
|
254 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
255 |
-
* @version 0.1.0
|
256 |
-
* @access public
|
257 |
-
* @package Net_SSH1
|
258 |
-
*/
|
259 |
-
class Net_SSH1 {
|
260 |
-
/**
|
261 |
-
* The SSH identifier
|
262 |
-
*
|
263 |
-
* @var String
|
264 |
-
* @access private
|
265 |
-
*/
|
266 |
-
var $identifier = 'SSH-1.5-phpseclib';
|
267 |
-
|
268 |
-
/**
|
269 |
-
* The Socket Object
|
270 |
-
*
|
271 |
-
* @var Object
|
272 |
-
* @access private
|
273 |
-
*/
|
274 |
-
var $fsock;
|
275 |
-
|
276 |
-
/**
|
277 |
-
* The cryptography object
|
278 |
-
*
|
279 |
-
* @var Object
|
280 |
-
* @access private
|
281 |
-
*/
|
282 |
-
var $crypto = false;
|
283 |
-
|
284 |
-
/**
|
285 |
-
* Execution Bitmap
|
286 |
-
*
|
287 |
-
* The bits that are set represent functions that have been called already. This is used to determine
|
288 |
-
* if a requisite function has been successfully executed. If not, an error should be thrown.
|
289 |
-
*
|
290 |
-
* @var Integer
|
291 |
-
* @access private
|
292 |
-
*/
|
293 |
-
var $bitmap = 0;
|
294 |
-
|
295 |
-
/**
|
296 |
-
* The Server Key Public Exponent
|
297 |
-
*
|
298 |
-
* Logged for debug purposes
|
299 |
-
*
|
300 |
-
* @see Net_SSH1::getServerKeyPublicExponent()
|
301 |
-
* @var String
|
302 |
-
* @access private
|
303 |
-
*/
|
304 |
-
var $server_key_public_exponent;
|
305 |
-
|
306 |
-
/**
|
307 |
-
* The Server Key Public Modulus
|
308 |
-
*
|
309 |
-
* Logged for debug purposes
|
310 |
-
*
|
311 |
-
* @see Net_SSH1::getServerKeyPublicModulus()
|
312 |
-
* @var String
|
313 |
-
* @access private
|
314 |
-
*/
|
315 |
-
var $server_key_public_modulus;
|
316 |
-
|
317 |
-
/**
|
318 |
-
* The Host Key Public Exponent
|
319 |
-
*
|
320 |
-
* Logged for debug purposes
|
321 |
-
*
|
322 |
-
* @see Net_SSH1::getHostKeyPublicExponent()
|
323 |
-
* @var String
|
324 |
-
* @access private
|
325 |
-
*/
|
326 |
-
var $host_key_public_exponent;
|
327 |
-
|
328 |
-
/**
|
329 |
-
* The Host Key Public Modulus
|
330 |
-
*
|
331 |
-
* Logged for debug purposes
|
332 |
-
*
|
333 |
-
* @see Net_SSH1::getHostKeyPublicModulus()
|
334 |
-
* @var String
|
335 |
-
* @access private
|
336 |
-
*/
|
337 |
-
var $host_key_public_modulus;
|
338 |
-
|
339 |
-
/**
|
340 |
-
* Supported Ciphers
|
341 |
-
*
|
342 |
-
* Logged for debug purposes
|
343 |
-
*
|
344 |
-
* @see Net_SSH1::getSupportedCiphers()
|
345 |
-
* @var Array
|
346 |
-
* @access private
|
347 |
-
*/
|
348 |
-
var $supported_ciphers = array(
|
349 |
-
NET_SSH1_CIPHER_NONE => 'No encryption',
|
350 |
-
NET_SSH1_CIPHER_IDEA => 'IDEA in CFB mode',
|
351 |
-
NET_SSH1_CIPHER_DES => 'DES in CBC mode',
|
352 |
-
NET_SSH1_CIPHER_3DES => 'Triple-DES in CBC mode',
|
353 |
-
NET_SSH1_CIPHER_BROKEN_TSS => 'TRI\'s Simple Stream encryption CBC',
|
354 |
-
NET_SSH1_CIPHER_RC4 => 'RC4',
|
355 |
-
NET_SSH1_CIPHER_BLOWFISH => 'Blowfish'
|
356 |
-
);
|
357 |
-
|
358 |
-
/**
|
359 |
-
* Supported Authentications
|
360 |
-
*
|
361 |
-
* Logged for debug purposes
|
362 |
-
*
|
363 |
-
* @see Net_SSH1::getSupportedAuthentications()
|
364 |
-
* @var Array
|
365 |
-
* @access private
|
366 |
-
*/
|
367 |
-
var $supported_authentications = array(
|
368 |
-
NET_SSH1_AUTH_RHOSTS => '.rhosts or /etc/hosts.equiv',
|
369 |
-
NET_SSH1_AUTH_RSA => 'pure RSA authentication',
|
370 |
-
NET_SSH1_AUTH_PASSWORD => 'password authentication',
|
371 |
-
NET_SSH1_AUTH_RHOSTS_RSA => '.rhosts with RSA host authentication'
|
372 |
-
);
|
373 |
-
|
374 |
-
/**
|
375 |
-
* Server Identification
|
376 |
-
*
|
377 |
-
* @see Net_SSH1::getServerIdentification()
|
378 |
-
* @var String
|
379 |
-
* @access private
|
380 |
-
*/
|
381 |
-
var $server_identification = '';
|
382 |
-
|
383 |
-
/**
|
384 |
-
* Protocol Flags
|
385 |
-
*
|
386 |
-
* @see Net_SSH1::Net_SSH1()
|
387 |
-
* @var Array
|
388 |
-
* @access private
|
389 |
-
*/
|
390 |
-
var $protocol_flags = array();
|
391 |
-
|
392 |
-
/**
|
393 |
-
* Protocol Flag Log
|
394 |
-
*
|
395 |
-
* @see Net_SSH1::getLog()
|
396 |
-
* @var Array
|
397 |
-
* @access private
|
398 |
-
*/
|
399 |
-
var $protocol_flag_log = array();
|
400 |
-
|
401 |
-
/**
|
402 |
-
* Message Log
|
403 |
-
*
|
404 |
-
* @see Net_SSH1::getLog()
|
405 |
-
* @var Array
|
406 |
-
* @access private
|
407 |
-
*/
|
408 |
-
var $message_log = array();
|
409 |
-
|
410 |
-
/**
|
411 |
-
* Interactive Buffer
|
412 |
-
*
|
413 |
-
* @see Net_SSH1::read()
|
414 |
-
* @var Array
|
415 |
-
* @access private
|
416 |
-
*/
|
417 |
-
var $interactive_buffer = '';
|
418 |
-
|
419 |
-
/**
|
420 |
-
* Default Constructor.
|
421 |
-
*
|
422 |
-
* Connects to an SSHv1 server
|
423 |
-
*
|
424 |
-
* @param String $host
|
425 |
-
* @param optional Integer $port
|
426 |
-
* @param optional Integer $timeout
|
427 |
-
* @param optional Integer $cipher
|
428 |
-
* @return Net_SSH1
|
429 |
-
* @access public
|
430 |
-
*/
|
431 |
-
function Net_SSH1($host, $port = 22, $timeout = 10, $cipher = NET_SSH1_CIPHER_3DES)
|
432 |
-
{
|
433 |
-
$this->protocol_flags = array(
|
434 |
-
1 => 'NET_SSH1_MSG_DISCONNECT',
|
435 |
-
2 => 'NET_SSH1_SMSG_PUBLIC_KEY',
|
436 |
-
3 => 'NET_SSH1_CMSG_SESSION_KEY',
|
437 |
-
4 => 'NET_SSH1_CMSG_USER',
|
438 |
-
9 => 'NET_SSH1_CMSG_AUTH_PASSWORD',
|
439 |
-
10 => 'NET_SSH1_CMSG_REQUEST_PTY',
|
440 |
-
12 => 'NET_SSH1_CMSG_EXEC_SHELL',
|
441 |
-
13 => 'NET_SSH1_CMSG_EXEC_CMD',
|
442 |
-
14 => 'NET_SSH1_SMSG_SUCCESS',
|
443 |
-
15 => 'NET_SSH1_SMSG_FAILURE',
|
444 |
-
16 => 'NET_SSH1_CMSG_STDIN_DATA',
|
445 |
-
17 => 'NET_SSH1_SMSG_STDOUT_DATA',
|
446 |
-
18 => 'NET_SSH1_SMSG_STDERR_DATA',
|
447 |
-
19 => 'NET_SSH1_CMSG_EOF',
|
448 |
-
20 => 'NET_SSH1_SMSG_EXITSTATUS',
|
449 |
-
33 => 'NET_SSH1_CMSG_EXIT_CONFIRMATION'
|
450 |
-
);
|
451 |
-
|
452 |
-
$this->_define_array($this->protocol_flags);
|
453 |
-
|
454 |
-
$this->fsock = @fsockopen($host, $port, $errno, $errstr, $timeout);
|
455 |
-
if (!$this->fsock) {
|
456 |
-
user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"), E_USER_NOTICE);
|
457 |
-
return;
|
458 |
-
}
|
459 |
-
|
460 |
-
$this->server_identification = $init_line = fgets($this->fsock, 255);
|
461 |
-
|
462 |
-
if (defined('NET_SSH1_LOGGING')) {
|
463 |
-
$this->protocol_flags_log[] = '<-';
|
464 |
-
$this->protocol_flags_log[] = '->';
|
465 |
-
|
466 |
-
if (NET_SSH1_LOGGING == NET_SSH1_LOG_COMPLEX) {
|
467 |
-
$this->message_log[] = $this->server_identification;
|
468 |
-
$this->message_log[] = $this->identifier . "\r\n";
|
469 |
-
}
|
470 |
-
}
|
471 |
-
|
472 |
-
if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) {
|
473 |
-
user_error('Can only connect to SSH servers', E_USER_NOTICE);
|
474 |
-
return;
|
475 |
-
}
|
476 |
-
if ($parts[1][0] != 1) {
|
477 |
-
user_error("Cannot connect to SSH $parts[1] servers", E_USER_NOTICE);
|
478 |
-
return;
|
479 |
-
}
|
480 |
-
|
481 |
-
fputs($this->fsock, $this->identifier."\r\n");
|
482 |
-
|
483 |
-
$response = $this->_get_binary_packet();
|
484 |
-
if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
|
485 |
-
user_error('Expected SSH_SMSG_PUBLIC_KEY', E_USER_NOTICE);
|
486 |
-
return;
|
487 |
-
}
|
488 |
-
|
489 |
-
$anti_spoofing_cookie = $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 8);
|
490 |
-
|
491 |
-
$this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4);
|
492 |
-
|
493 |
-
$temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2));
|
494 |
-
$server_key_public_exponent = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
495 |
-
$this->server_key_public_exponent = $server_key_public_exponent;
|
496 |
-
|
497 |
-
$temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2));
|
498 |
-
$server_key_public_modulus = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
499 |
-
$this->server_key_public_modulus = $server_key_public_modulus;
|
500 |
-
|
501 |
-
$this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4);
|
502 |
-
|
503 |
-
$temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2));
|
504 |
-
$host_key_public_exponent = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
505 |
-
$this->host_key_public_exponent = $host_key_public_exponent;
|
506 |
-
|
507 |
-
$temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2));
|
508 |
-
$host_key_public_modulus = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
509 |
-
$this->host_key_public_modulus = $host_key_public_modulus;
|
510 |
-
|
511 |
-
$this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4);
|
512 |
-
|
513 |
-
// get a list of the supported ciphers
|
514 |
-
extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4)));
|
515 |
-
foreach ($this->supported_ciphers as $mask=>$name) {
|
516 |
-
if (($supported_ciphers_mask & (1 << $mask)) == 0) {
|
517 |
-
unset($this->supported_ciphers[$mask]);
|
518 |
-
}
|
519 |
-
}
|
520 |
-
|
521 |
-
// get a list of the supported authentications
|
522 |
-
extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4)));
|
523 |
-
foreach ($this->supported_authentications as $mask=>$name) {
|
524 |
-
if (($supported_authentications_mask & (1 << $mask)) == 0) {
|
525 |
-
unset($this->supported_authentications[$mask]);
|
526 |
-
}
|
527 |
-
}
|
528 |
-
|
529 |
-
$session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie));
|
530 |
-
|
531 |
-
$session_key = '';
|
532 |
-
for ($i = 0; $i < 32; $i++) {
|
533 |
-
$session_key.= chr(crypt_random(0, 255));
|
534 |
-
}
|
535 |
-
$double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0));
|
536 |
-
|
537 |
-
if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) {
|
538 |
-
$double_encrypted_session_key = $this->_rsa_crypt(
|
539 |
-
$double_encrypted_session_key,
|
540 |
-
array(
|
541 |
-
$server_key_public_exponent,
|
542 |
-
$server_key_public_modulus
|
543 |
-
)
|
544 |
-
);
|
545 |
-
$double_encrypted_session_key = $this->_rsa_crypt(
|
546 |
-
$double_encrypted_session_key,
|
547 |
-
array(
|
548 |
-
$host_key_public_exponent,
|
549 |
-
$host_key_public_modulus
|
550 |
-
)
|
551 |
-
);
|
552 |
-
} else {
|
553 |
-
$double_encrypted_session_key = $this->_rsa_crypt(
|
554 |
-
$double_encrypted_session_key,
|
555 |
-
array(
|
556 |
-
$host_key_public_exponent,
|
557 |
-
$host_key_public_modulus
|
558 |
-
)
|
559 |
-
);
|
560 |
-
$double_encrypted_session_key = $this->_rsa_crypt(
|
561 |
-
$double_encrypted_session_key,
|
562 |
-
array(
|
563 |
-
$server_key_public_exponent,
|
564 |
-
$server_key_public_modulus
|
565 |
-
)
|
566 |
-
);
|
567 |
-
}
|
568 |
-
|
569 |
-
$cipher = isset($this->supported_ciphers[$cipher]) ? $cipher : NET_SSH1_CIPHER_3DES;
|
570 |
-
$data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);
|
571 |
-
|
572 |
-
if (!$this->_send_binary_packet($data)) {
|
573 |
-
user_error('Error sending SSH_CMSG_SESSION_KEY', E_USER_NOTICE);
|
574 |
-
return;
|
575 |
-
}
|
576 |
-
|
577 |
-
switch ($cipher) {
|
578 |
-
//case NET_SSH1_CIPHER_NONE:
|
579 |
-
// $this->crypto = new Crypt_Null();
|
580 |
-
// break;
|
581 |
-
case NET_SSH1_CIPHER_DES:
|
582 |
-
$this->crypto = new Crypt_DES();
|
583 |
-
$this->crypto->disablePadding();
|
584 |
-
$this->crypto->enableContinuousBuffer();
|
585 |
-
$this->crypto->setKey(substr($session_key, 0, 8));
|
586 |
-
break;
|
587 |
-
case NET_SSH1_CIPHER_3DES:
|
588 |
-
$this->crypto = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC);
|
589 |
-
$this->crypto->disablePadding();
|
590 |
-
$this->crypto->enableContinuousBuffer();
|
591 |
-
$this->crypto->setKey(substr($session_key, 0, 24));
|
592 |
-
break;
|
593 |
-
//case NET_SSH1_CIPHER_RC4:
|
594 |
-
// $this->crypto = new Crypt_RC4();
|
595 |
-
// $this->crypto->enableContinuousBuffer();
|
596 |
-
// $this->crypto->setKey(substr($session_key, 0, 16));
|
597 |
-
// break;
|
598 |
-
}
|
599 |
-
|
600 |
-
$response = $this->_get_binary_packet();
|
601 |
-
|
602 |
-
if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
|
603 |
-
user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE);
|
604 |
-
return;
|
605 |
-
}
|
606 |
-
|
607 |
-
$this->bitmap = NET_SSH1_MASK_CONSTRUCTOR;
|
608 |
-
}
|
609 |
-
|
610 |
-
/**
|
611 |
-
* Login
|
612 |
-
*
|
613 |
-
* @param String $username
|
614 |
-
* @param optional String $password
|
615 |
-
* @return Boolean
|
616 |
-
* @access public
|
617 |
-
*/
|
618 |
-
function login($username, $password = '')
|
619 |
-
{
|
620 |
-
if (!($this->bitmap & NET_SSH1_MASK_CONSTRUCTOR)) {
|
621 |
-
return false;
|
622 |
-
}
|
623 |
-
|
624 |
-
$data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username);
|
625 |
-
|
626 |
-
if (!$this->_send_binary_packet($data)) {
|
627 |
-
user_error('Error sending SSH_CMSG_USER', E_USER_NOTICE);
|
628 |
-
return false;
|
629 |
-
}
|
630 |
-
|
631 |
-
$response = $this->_get_binary_packet();
|
632 |
-
|
633 |
-
if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
|
634 |
-
$this->bitmap |= NET_SSH1_MASK_LOGIN;
|
635 |
-
return true;
|
636 |
-
} else if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
|
637 |
-
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE', E_USER_NOTICE);
|
638 |
-
return false;
|
639 |
-
}
|
640 |
-
|
641 |
-
$data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password);
|
642 |
-
|
643 |
-
if (!$this->_send_binary_packet($data)) {
|
644 |
-
user_error('Error sending SSH_CMSG_AUTH_PASSWORD', E_USER_NOTICE);
|
645 |
-
return false;
|
646 |
-
}
|
647 |
-
|
648 |
-
// remove the username and password from the last logged packet
|
649 |
-
if (defined('NET_SSH1_LOGGING') && NET_SSH1_LOGGING == NET_SSH1_LOG_COMPLEX) {
|
650 |
-
$data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen('password'), 'password');
|
651 |
-
$this->message_log[count($this->message_log) - 1] = $data; // zzzzz
|
652 |
-
}
|
653 |
-
|
654 |
-
$response = $this->_get_binary_packet();
|
655 |
-
|
656 |
-
if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
|
657 |
-
$this->bitmap |= NET_SSH1_MASK_LOGIN;
|
658 |
-
return true;
|
659 |
-
} else if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
|
660 |
-
return false;
|
661 |
-
} else {
|
662 |
-
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE', E_USER_NOTICE);
|
663 |
-
return false;
|
664 |
-
}
|
665 |
-
}
|
666 |
-
|
667 |
-
/**
|
668 |
-
* Executes a command on a non-interactive shell, returns the output, and quits.
|
669 |
-
*
|
670 |
-
* An SSH1 server will close the connection after a command has been executed on a non-interactive shell. SSH2
|
671 |
-
* servers don't, however, this isn't an SSH2 client. The way this works, on the server, is by initiating a
|
672 |
-
* shell with the -s option, as discussed in the following links:
|
673 |
-
*
|
674 |
-
* {@link http://www.faqs.org/docs/bashman/bashref_65.html http://www.faqs.org/docs/bashman/bashref_65.html}
|
675 |
-
* {@link http://www.faqs.org/docs/bashman/bashref_62.html http://www.faqs.org/docs/bashman/bashref_62.html}
|
676 |
-
*
|
677 |
-
* To execute further commands, a new Net_SSH1 object will need to be created.
|
678 |
-
*
|
679 |
-
* Returns false on failure and the output, otherwise.
|
680 |
-
*
|
681 |
-
* @see Net_SSH1::interactiveRead()
|
682 |
-
* @see Net_SSH1::interactiveWrite()
|
683 |
-
* @param String $cmd
|
684 |
-
* @return mixed
|
685 |
-
* @access public
|
686 |
-
*/
|
687 |
-
function exec($cmd, $block = true)
|
688 |
-
{
|
689 |
-
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {
|
690 |
-
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
691 |
-
return false;
|
692 |
-
}
|
693 |
-
|
694 |
-
$data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd);
|
695 |
-
|
696 |
-
if (!$this->_send_binary_packet($data)) {
|
697 |
-
user_error('Error sending SSH_CMSG_EXEC_CMD', E_USER_NOTICE);
|
698 |
-
return false;
|
699 |
-
}
|
700 |
-
|
701 |
-
if (!$block) {
|
702 |
-
return true;
|
703 |
-
}
|
704 |
-
|
705 |
-
$output = '';
|
706 |
-
$response = $this->_get_binary_packet();
|
707 |
-
|
708 |
-
do {
|
709 |
-
$output.= substr($response[NET_SSH1_RESPONSE_DATA], 4);
|
710 |
-
$response = $this->_get_binary_packet();
|
711 |
-
} while ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_EXITSTATUS);
|
712 |
-
|
713 |
-
$data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);
|
714 |
-
|
715 |
-
// i don't think it's really all that important if this packet gets sent or not.
|
716 |
-
$this->_send_binary_packet($data);
|
717 |
-
|
718 |
-
fclose($this->fsock);
|
719 |
-
|
720 |
-
// reset the execution bitmap - a new Net_SSH1 object needs to be created.
|
721 |
-
$this->bitmap = 0;
|
722 |
-
|
723 |
-
return $output;
|
724 |
-
}
|
725 |
-
|
726 |
-
/**
|
727 |
-
* Creates an interactive shell
|
728 |
-
*
|
729 |
-
* @see Net_SSH1::interactiveRead()
|
730 |
-
* @see Net_SSH1::interactiveWrite()
|
731 |
-
* @return Boolean
|
732 |
-
* @access private
|
733 |
-
*/
|
734 |
-
function _initShell()
|
735 |
-
{
|
736 |
-
// connect using the sample parameters in protocol-1.5.txt.
|
737 |
-
// according to wikipedia.org's entry on text terminals, "the fundamental type of application running on a text
|
738 |
-
// terminal is a command line interpreter or shell". thus, opening a terminal session to run the shell.
|
739 |
-
$data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, NET_SSH1_TTY_OP_END);
|
740 |
-
|
741 |
-
if (!$this->_send_binary_packet($data)) {
|
742 |
-
user_error('Error sending SSH_CMSG_REQUEST_PTY', E_USER_NOTICE);
|
743 |
-
return false;
|
744 |
-
}
|
745 |
-
|
746 |
-
$response = $this->_get_binary_packet();
|
747 |
-
|
748 |
-
if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
|
749 |
-
user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE);
|
750 |
-
return false;
|
751 |
-
}
|
752 |
-
|
753 |
-
$data = pack('C', NET_SSH1_CMSG_EXEC_SHELL);
|
754 |
-
|
755 |
-
if (!$this->_send_binary_packet($data)) {
|
756 |
-
user_error('Error sending SSH_CMSG_EXEC_SHELL', E_USER_NOTICE);
|
757 |
-
return false;
|
758 |
-
}
|
759 |
-
|
760 |
-
$this->bitmap |= NET_SSH1_MASK_SHELL;
|
761 |
-
|
762 |
-
//stream_set_blocking($this->fsock, 0);
|
763 |
-
|
764 |
-
return true;
|
765 |
-
}
|
766 |
-
|
767 |
-
/**
|
768 |
-
* Inputs a command into an interactive shell.
|
769 |
-
*
|
770 |
-
* @see Net_SSH1::interactiveWrite()
|
771 |
-
* @param String $cmd
|
772 |
-
* @return Boolean
|
773 |
-
* @access public
|
774 |
-
*/
|
775 |
-
function write($cmd)
|
776 |
-
{
|
777 |
-
return $this->interactiveWrite($cmd);
|
778 |
-
}
|
779 |
-
|
780 |
-
/**
|
781 |
-
* Returns the output of an interactive shell when there's a match for $expect
|
782 |
-
*
|
783 |
-
* $expect can take the form of a string literal or, if $mode == NET_SSH1_READ_REGEX,
|
784 |
-
* a regular expression.
|
785 |
-
*
|
786 |
-
* @see Net_SSH1::write()
|
787 |
-
* @param String $expect
|
788 |
-
* @param Integer $mode
|
789 |
-
* @return Boolean
|
790 |
-
* @access public
|
791 |
-
*/
|
792 |
-
function read($expect, $mode = NET_SSH1_READ_SIMPLE)
|
793 |
-
{
|
794 |
-
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {
|
795 |
-
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
796 |
-
return false;
|
797 |
-
}
|
798 |
-
|
799 |
-
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) {
|
800 |
-
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
801 |
-
return false;
|
802 |
-
}
|
803 |
-
|
804 |
-
$match = $expect;
|
805 |
-
while (true) {
|
806 |
-
if ($mode == NET_SSH1_READ_REGEX) {
|
807 |
-
preg_match($expect, $this->interactiveBuffer, $matches);
|
808 |
-
$match = $matches[0];
|
809 |
-
}
|
810 |
-
$pos = strpos($this->interactiveBuffer, $match);
|
811 |
-
if ($pos !== false) {
|
812 |
-
return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match));
|
813 |
-
}
|
814 |
-
$response = $this->_get_binary_packet();
|
815 |
-
$this->interactiveBuffer.= substr($response[NET_SSH1_RESPONSE_DATA], 4);
|
816 |
-
}
|
817 |
-
}
|
818 |
-
|
819 |
-
/**
|
820 |
-
* Inputs a command into an interactive shell.
|
821 |
-
*
|
822 |
-
* @see Net_SSH1::interactiveRead()
|
823 |
-
* @param String $cmd
|
824 |
-
* @return Boolean
|
825 |
-
* @access public
|
826 |
-
*/
|
827 |
-
function interactiveWrite($cmd)
|
828 |
-
{
|
829 |
-
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {
|
830 |
-
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
831 |
-
return false;
|
832 |
-
}
|
833 |
-
|
834 |
-
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) {
|
835 |
-
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
836 |
-
return false;
|
837 |
-
}
|
838 |
-
|
839 |
-
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd);
|
840 |
-
|
841 |
-
if (!$this->_send_binary_packet($data)) {
|
842 |
-
user_error('Error sending SSH_CMSG_STDIN', E_USER_NOTICE);
|
843 |
-
return false;
|
844 |
-
}
|
845 |
-
|
846 |
-
return true;
|
847 |
-
}
|
848 |
-
|
849 |
-
/**
|
850 |
-
* Returns the output of an interactive shell when no more output is available.
|
851 |
-
*
|
852 |
-
* Requires PHP 4.3.0 or later due to the use of the stream_select() function. If you see stuff like
|
853 |
-
* "[00m", you're seeing ANSI escape codes. According to
|
854 |
-
* {@link http://support.microsoft.com/kb/101875 How to Enable ANSI.SYS in a Command Window}, "Windows NT
|
855 |
-
* does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user,
|
856 |
-
* there's not going to be much recourse.
|
857 |
-
*
|
858 |
-
* @see Net_SSH1::interactiveRead()
|
859 |
-
* @return String
|
860 |
-
* @access public
|
861 |
-
*/
|
862 |
-
function interactiveRead()
|
863 |
-
{
|
864 |
-
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {
|
865 |
-
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
866 |
-
return false;
|
867 |
-
}
|
868 |
-
|
869 |
-
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) {
|
870 |
-
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
871 |
-
return false;
|
872 |
-
}
|
873 |
-
|
874 |
-
$read = array($this->fsock);
|
875 |
-
$write = $except = null;
|
876 |
-
if (stream_select($read, $write, $except, 0)) {
|
877 |
-
$response = $this->_get_binary_packet();
|
878 |
-
return substr($response[NET_SSH1_RESPONSE_DATA], 4);
|
879 |
-
} else {
|
880 |
-
return '';
|
881 |
-
}
|
882 |
-
}
|
883 |
-
|
884 |
-
/**
|
885 |
-
* Disconnect
|
886 |
-
*
|
887 |
-
* @access public
|
888 |
-
*/
|
889 |
-
function disconnect()
|
890 |
-
{
|
891 |
-
$this->_disconnect();
|
892 |
-
}
|
893 |
-
|
894 |
-
/**
|
895 |
-
* Destructor.
|
896 |
-
*
|
897 |
-
* Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call
|
898 |
-
* disconnect().
|
899 |
-
*
|
900 |
-
* @access public
|
901 |
-
*/
|
902 |
-
function __destruct()
|
903 |
-
{
|
904 |
-
$this->_disconnect();
|
905 |
-
}
|
906 |
-
|
907 |
-
/**
|
908 |
-
* Disconnect
|
909 |
-
*
|
910 |
-
* @param String $msg
|
911 |
-
* @access private
|
912 |
-
*/
|
913 |
-
function _disconnect($msg = 'Client Quit')
|
914 |
-
{
|
915 |
-
if ($this->bitmap) {
|
916 |
-
$data = pack('C', NET_SSH1_CMSG_EOF);
|
917 |
-
$this->_send_binary_packet($data);
|
918 |
-
|
919 |
-
$response = $this->_get_binary_packet();
|
920 |
-
switch ($response[NET_SSH1_RESPONSE_TYPE]) {
|
921 |
-
case NET_SSH1_SMSG_EXITSTATUS:
|
922 |
-
$data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);
|
923 |
-
break;
|
924 |
-
default:
|
925 |
-
$data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg);
|
926 |
-
}
|
927 |
-
|
928 |
-
$this->_send_binary_packet($data);
|
929 |
-
fclose($this->fsock);
|
930 |
-
$this->bitmap = 0;
|
931 |
-
}
|
932 |
-
}
|
933 |
-
|
934 |
-
/**
|
935 |
-
* Gets Binary Packets
|
936 |
-
*
|
937 |
-
* See 'The Binary Packet Protocol' of protocol-1.5.txt for more info.
|
938 |
-
*
|
939 |
-
* Also, this function could be improved upon by adding detection for the following exploit:
|
940 |
-
* http://www.securiteam.com/securitynews/5LP042K3FY.html
|
941 |
-
*
|
942 |
-
* @see Net_SSH1::_send_binary_packet()
|
943 |
-
* @return Array
|
944 |
-
* @access private
|
945 |
-
*/
|
946 |
-
function _get_binary_packet()
|
947 |
-
{
|
948 |
-
if (feof($this->fsock)) {
|
949 |
-
//user_error('connection closed prematurely', E_USER_NOTICE);
|
950 |
-
return false;
|
951 |
-
}
|
952 |
-
|
953 |
-
$temp = unpack('Nlength', fread($this->fsock, 4));
|
954 |
-
|
955 |
-
$padding_length = 8 - ($temp['length'] & 7);
|
956 |
-
$length = $temp['length'] + $padding_length;
|
957 |
-
|
958 |
-
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
959 |
-
$raw = fread($this->fsock, $length);
|
960 |
-
$stop = strtok(microtime(), ' ') + strtok('');
|
961 |
-
|
962 |
-
if ($this->crypto !== false) {
|
963 |
-
$raw = $this->crypto->decrypt($raw);
|
964 |
-
}
|
965 |
-
|
966 |
-
$padding = substr($raw, 0, $padding_length);
|
967 |
-
$type = $raw[$padding_length];
|
968 |
-
$data = substr($raw, $padding_length + 1, -4);
|
969 |
-
|
970 |
-
$temp = unpack('Ncrc', substr($raw, -4));
|
971 |
-
|
972 |
-
//if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {
|
973 |
-
// user_error('Bad CRC in packet from server', E_USER_NOTICE);
|
974 |
-
// return false;
|
975 |
-
//}
|
976 |
-
|
977 |
-
$type = ord($type);
|
978 |
-
|
979 |
-
if (defined('NET_SSH1_LOGGING')) {
|
980 |
-
$temp = isset($this->protocol_flags[$type]) ? $this->protocol_flags[$type] : 'UNKNOWN';
|
981 |
-
$this->protocol_flags_log[] = '<- ' . $temp .
|
982 |
-
' (' . round($stop - $start, 4) . 's)';
|
983 |
-
if (NET_SSH1_LOGGING == NET_SSH1_LOG_COMPLEX) {
|
984 |
-
$this->message_log[] = $data;
|
985 |
-
}
|
986 |
-
}
|
987 |
-
|
988 |
-
return array(
|
989 |
-
NET_SSH1_RESPONSE_TYPE => $type,
|
990 |
-
NET_SSH1_RESPONSE_DATA => $data
|
991 |
-
);
|
992 |
-
}
|
993 |
-
|
994 |
-
/**
|
995 |
-
* Sends Binary Packets
|
996 |
-
*
|
997 |
-
* Returns true on success, false on failure.
|
998 |
-
*
|
999 |
-
* @see Net_SSH1::_get_binary_packet()
|
1000 |
-
* @param String $data
|
1001 |
-
* @return Boolean
|
1002 |
-
* @access private
|
1003 |
-
*/
|
1004 |
-
function _send_binary_packet($data) {
|
1005 |
-
if (feof($this->fsock)) {
|
1006 |
-
//user_error('connection closed prematurely', E_USER_NOTICE);
|
1007 |
-
return false;
|
1008 |
-
}
|
1009 |
-
|
1010 |
-
if (defined('NET_SSH1_LOGGING')) {
|
1011 |
-
$temp = isset($this->protocol_flags[ord($data[0])]) ? $this->protocol_flags[ord($data[0])] : 'UNKNOWN';
|
1012 |
-
$this->protocol_flags_log[] = '-> ' . $temp .
|
1013 |
-
' (' . round($stop - $start, 4) . 's)';
|
1014 |
-
if (NET_SSH1_LOGGING == NET_SSH1_LOG_COMPLEX) {
|
1015 |
-
$this->message_log[] = substr($data, 1);
|
1016 |
-
}
|
1017 |
-
}
|
1018 |
-
|
1019 |
-
$length = strlen($data) + 4;
|
1020 |
-
|
1021 |
-
$padding_length = 8 - ($length & 7);
|
1022 |
-
$padding = '';
|
1023 |
-
for ($i = 0; $i < $padding_length; $i++) {
|
1024 |
-
$padding.= chr(crypt_random(0, 255));
|
1025 |
-
}
|
1026 |
-
|
1027 |
-
$data = $padding . $data;
|
1028 |
-
$data.= pack('N', $this->_crc($data));
|
1029 |
-
|
1030 |
-
if ($this->crypto !== false) {
|
1031 |
-
$data = $this->crypto->encrypt($data);
|
1032 |
-
}
|
1033 |
-
|
1034 |
-
$packet = pack('Na*', $length, $data);
|
1035 |
-
|
1036 |
-
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
1037 |
-
$result = strlen($packet) == fputs($this->fsock, $packet);
|
1038 |
-
$stop = strtok(microtime(), ' ') + strtok('');
|
1039 |
-
|
1040 |
-
return $result;
|
1041 |
-
}
|
1042 |
-
|
1043 |
-
/**
|
1044 |
-
* Cyclic Redundancy Check (CRC)
|
1045 |
-
*
|
1046 |
-
* PHP's crc32 function is implemented slightly differently than the one that SSH v1 uses, so
|
1047 |
-
* we've reimplemented it. A more detailed discussion of the differences can be found after
|
1048 |
-
* $crc_lookup_table's initialization.
|
1049 |
-
*
|
1050 |
-
* @see Net_SSH1::_get_binary_packet()
|
1051 |
-
* @see Net_SSH1::_send_binary_packet()
|
1052 |
-
* @param String $data
|
1053 |
-
* @return Integer
|
1054 |
-
* @access private
|
1055 |
-
*/
|
1056 |
-
function _crc($data)
|
1057 |
-
{
|
1058 |
-
static $crc_lookup_table = array(
|
1059 |
-
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
1060 |
-
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
1061 |
-
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
1062 |
-
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
1063 |
-
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
|
1064 |
-
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
1065 |
-
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
1066 |
-
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
1067 |
-
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
|
1068 |
-
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
1069 |
-
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
|
1070 |
-
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
1071 |
-
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
|
1072 |
-
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
1073 |
-
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
1074 |
-
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
1075 |
-
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
|
1076 |
-
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
1077 |
-
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
|
1078 |
-
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
1079 |
-
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
1080 |
-
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
1081 |
-
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
|
1082 |
-
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
1083 |
-
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
|
1084 |
-
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
1085 |
-
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
|
1086 |
-
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
1087 |
-
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
|
1088 |
-
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
1089 |
-
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
|
1090 |
-
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
1091 |
-
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
|
1092 |
-
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
1093 |
-
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
1094 |
-
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
1095 |
-
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
|
1096 |
-
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
1097 |
-
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
|
1098 |
-
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
1099 |
-
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
|
1100 |
-
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
1101 |
-
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
|
1102 |
-
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
1103 |
-
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
1104 |
-
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
1105 |
-
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
|
1106 |
-
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
1107 |
-
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
1108 |
-
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
1109 |
-
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
|
1110 |
-
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
1111 |
-
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
|
1112 |
-
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
1113 |
-
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
|
1114 |
-
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
1115 |
-
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
|
1116 |
-
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
1117 |
-
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
|
1118 |
-
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
1119 |
-
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
|
1120 |
-
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
1121 |
-
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
1122 |
-
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
1123 |
-
);
|
1124 |
-
|
1125 |
-
// For this function to yield the same output as PHP's crc32 function, $crc would have to be
|
1126 |
-
// set to 0xFFFFFFFF, initially - not 0x00000000 as it currently is.
|
1127 |
-
$crc = 0x00000000;
|
1128 |
-
$length = strlen($data);
|
1129 |
-
|
1130 |
-
for ($i=0;$i<$length;$i++) {
|
1131 |
-
// We AND $crc >> 8 with 0x00FFFFFF because we want the eight newly added bits to all
|
1132 |
-
// be zero. PHP, unfortunately, doesn't always do this. 0x80000000 >> 8, as an example,
|
1133 |
-
// yields 0xFF800000 - not 0x00800000. The following link elaborates:
|
1134 |
-
// http://www.php.net/manual/en/language.operators.bitwise.php#57281
|
1135 |
-
$crc = (($crc >> 8) & 0x00FFFFFF) ^ $crc_lookup_table[($crc & 0xFF) ^ ord($data[$i])];
|
1136 |
-
}
|
1137 |
-
|
1138 |
-
// In addition to having to set $crc to 0xFFFFFFFF, initially, the return value must be XOR'd with
|
1139 |
-
// 0xFFFFFFFF for this function to return the same thing that PHP's crc32 function would.
|
1140 |
-
return $crc;
|
1141 |
-
}
|
1142 |
-
|
1143 |
-
/**
|
1144 |
-
* String Shift
|
1145 |
-
*
|
1146 |
-
* Inspired by array_shift
|
1147 |
-
*
|
1148 |
-
* @param String $string
|
1149 |
-
* @param optional Integer $index
|
1150 |
-
* @return String
|
1151 |
-
* @access private
|
1152 |
-
*/
|
1153 |
-
function _string_shift(&$string, $index = 1)
|
1154 |
-
{
|
1155 |
-
$substr = substr($string, 0, $index);
|
1156 |
-
$string = substr($string, $index);
|
1157 |
-
return $substr;
|
1158 |
-
}
|
1159 |
-
|
1160 |
-
/**
|
1161 |
-
* RSA Encrypt
|
1162 |
-
*
|
1163 |
-
* Returns mod(pow($m, $e), $n), where $n should be the product of two (large) primes $p and $q and where $e
|
1164 |
-
* should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1. Could just make anything that
|
1165 |
-
* calls this call modexp, instead, but I think this makes things clearer, maybe...
|
1166 |
-
*
|
1167 |
-
* @see Net_SSH1::Net_SSH1()
|
1168 |
-
* @param Math_BigInteger $m
|
1169 |
-
* @param Array $key
|
1170 |
-
* @return Math_BigInteger
|
1171 |
-
* @access private
|
1172 |
-
*/
|
1173 |
-
function _rsa_crypt($m, $key)
|
1174 |
-
{
|
1175 |
-
/*
|
1176 |
-
if (!class_exists('Crypt_RSA')) {
|
1177 |
-
require_once('Crypt/RSA.php');
|
1178 |
-
}
|
1179 |
-
|
1180 |
-
$rsa = new Crypt_RSA();
|
1181 |
-
$rsa->loadKey($key, CRYPT_RSA_PUBLIC_FORMAT_RAW);
|
1182 |
-
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
|
1183 |
-
return $rsa->encrypt($m);
|
1184 |
-
*/
|
1185 |
-
|
1186 |
-
// To quote from protocol-1.5.txt:
|
1187 |
-
// The most significant byte (which is only partial as the value must be
|
1188 |
-
// less than the public modulus, which is never a power of two) is zero.
|
1189 |
-
//
|
1190 |
-
// The next byte contains the value 2 (which stands for public-key
|
1191 |
-
// encrypted data in the PKCS standard [PKCS#1]). Then, there are non-
|
1192 |
-
// zero random bytes to fill any unused space, a zero byte, and the data
|
1193 |
-
// to be encrypted in the least significant bytes, the last byte of the
|
1194 |
-
// data in the least significant byte.
|
1195 |
-
|
1196 |
-
// Presumably the part of PKCS#1 they're refering to is "Section 7.2.1 Encryption Operation",
|
1197 |
-
// under "7.2 RSAES-PKCS1-v1.5" and "7 Encryption schemes" of the following URL:
|
1198 |
-
// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
|
1199 |
-
$temp = chr(0) . chr(2);
|
1200 |
-
$modulus = $key[1]->toBytes();
|
1201 |
-
$length = strlen($modulus) - strlen($m) - 3;
|
1202 |
-
for ($i = 0; $i < $length; $i++) {
|
1203 |
-
$temp.= chr(crypt_random(1, 255));
|
1204 |
-
}
|
1205 |
-
$temp.= chr(0) . $m;
|
1206 |
-
|
1207 |
-
$m = new Math_BigInteger($temp, 256);
|
1208 |
-
$m = $m->modPow($key[0], $key[1]);
|
1209 |
-
|
1210 |
-
return $m->toBytes();
|
1211 |
-
}
|
1212 |
-
|
1213 |
-
/**
|
1214 |
-
* Define Array
|
1215 |
-
*
|
1216 |
-
* Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of
|
1217 |
-
* named constants from it, using the value as the name of the constant and the index as the value of the constant.
|
1218 |
-
* If any of the constants that would be defined already exists, none of the constants will be defined.
|
1219 |
-
*
|
1220 |
-
* @param Array $array
|
1221 |
-
* @access private
|
1222 |
-
*/
|
1223 |
-
function _define_array()
|
1224 |
-
{
|
1225 |
-
$args = func_get_args();
|
1226 |
-
foreach ($args as $arg) {
|
1227 |
-
foreach ($arg as $key=>$value) {
|
1228 |
-
if (!defined($value)) {
|
1229 |
-
define($value, $key);
|
1230 |
-
} else {
|
1231 |
-
break 2;
|
1232 |
-
}
|
1233 |
-
}
|
1234 |
-
}
|
1235 |
-
}
|
1236 |
-
|
1237 |
-
/**
|
1238 |
-
* Returns a log of the packets that have been sent and received.
|
1239 |
-
*
|
1240 |
-
* Returns a string if NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX, an array if NET_SSH2_LOGGING == NET_SSH2_LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING')
|
1241 |
-
*
|
1242 |
-
* @access public
|
1243 |
-
* @return String or Array
|
1244 |
-
*/
|
1245 |
-
function getLog()
|
1246 |
-
{
|
1247 |
-
if (!defined('NET_SSH1_LOGGING')) {
|
1248 |
-
return false;
|
1249 |
-
}
|
1250 |
-
|
1251 |
-
switch (NET_SSH1_LOGGING) {
|
1252 |
-
case NET_SSH1_LOG_SIMPLE:
|
1253 |
-
return $this->message_number_log;
|
1254 |
-
break;
|
1255 |
-
case NET_SSH1_LOG_COMPLEX:
|
1256 |
-
return $this->_format_log($this->message_log, $this->protocol_flags_log);
|
1257 |
-
break;
|
1258 |
-
default:
|
1259 |
-
return false;
|
1260 |
-
}
|
1261 |
-
}
|
1262 |
-
|
1263 |
-
/**
|
1264 |
-
* Formats a log for printing
|
1265 |
-
*
|
1266 |
-
* @param Array $message_log
|
1267 |
-
* @param Array $message_number_log
|
1268 |
-
* @access private
|
1269 |
-
* @return String
|
1270 |
-
*/
|
1271 |
-
function _format_log($message_log, $message_number_log)
|
1272 |
-
{
|
1273 |
-
static $boundary = ':', $long_width = 65, $short_width = 16;
|
1274 |
-
|
1275 |
-
$output = '';
|
1276 |
-
for ($i = 0; $i < count($message_log); $i++) {
|
1277 |
-
$output.= $message_number_log[$i] . "\r\n";
|
1278 |
-
$current_log = $message_log[$i];
|
1279 |
-
$j = 0;
|
1280 |
-
do {
|
1281 |
-
if (!empty($current_log)) {
|
1282 |
-
$output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 ';
|
1283 |
-
}
|
1284 |
-
$fragment = $this->_string_shift($current_log, $short_width);
|
1285 |
-
$hex = substr(
|
1286 |
-
preg_replace(
|
1287 |
-
'#(.)#es',
|
1288 |
-
'"' . $boundary . '" . str_pad(dechex(ord(substr("\\1", -1))), 2, "0", STR_PAD_LEFT)',
|
1289 |
-
$fragment),
|
1290 |
-
strlen($boundary)
|
1291 |
-
);
|
1292 |
-
// replace non ASCII printable characters with dots
|
1293 |
-
// http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
|
1294 |
-
// also replace < with a . since < messes up the output on web browsers
|
1295 |
-
$raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment);
|
1296 |
-
$output.= str_pad($hex, $long_width - $short_width, ' ') . $raw . "\r\n";
|
1297 |
-
$j++;
|
1298 |
-
} while (!empty($current_log));
|
1299 |
-
$output.= "\r\n";
|
1300 |
-
}
|
1301 |
-
|
1302 |
-
return $output;
|
1303 |
-
}
|
1304 |
-
|
1305 |
-
/**
|
1306 |
-
* Return the server key public exponent
|
1307 |
-
*
|
1308 |
-
* Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
|
1309 |
-
* the raw bytes. This behavior is similar to PHP's md5() function.
|
1310 |
-
*
|
1311 |
-
* @param optional Boolean $raw_output
|
1312 |
-
* @return String
|
1313 |
-
* @access public
|
1314 |
-
*/
|
1315 |
-
function getServerKeyPublicExponent($raw_output = false)
|
1316 |
-
{
|
1317 |
-
return $raw_output ? $this->server_key_public_exponent->toBytes() : $this->server_key_public_exponent->toString();
|
1318 |
-
}
|
1319 |
-
|
1320 |
-
/**
|
1321 |
-
* Return the server key public modulus
|
1322 |
-
*
|
1323 |
-
* Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
|
1324 |
-
* the raw bytes. This behavior is similar to PHP's md5() function.
|
1325 |
-
*
|
1326 |
-
* @param optional Boolean $raw_output
|
1327 |
-
* @return String
|
1328 |
-
* @access public
|
1329 |
-
*/
|
1330 |
-
function getServerKeyPublicModulus($raw_output = false)
|
1331 |
-
{
|
1332 |
-
return $raw_output ? $this->server_key_public_modulus->toBytes() : $this->server_key_public_modulus->toString();
|
1333 |
-
}
|
1334 |
-
|
1335 |
-
/**
|
1336 |
-
* Return the host key public exponent
|
1337 |
-
*
|
1338 |
-
* Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
|
1339 |
-
* the raw bytes. This behavior is similar to PHP's md5() function.
|
1340 |
-
*
|
1341 |
-
* @param optional Boolean $raw_output
|
1342 |
-
* @return String
|
1343 |
-
* @access public
|
1344 |
-
*/
|
1345 |
-
function getHostKeyPublicExponent($raw_output = false)
|
1346 |
-
{
|
1347 |
-
return $raw_output ? $this->host_key_public_exponent->toBytes() : $this->host_key_public_exponent->toString();
|
1348 |
-
}
|
1349 |
-
|
1350 |
-
/**
|
1351 |
-
* Return the host key public modulus
|
1352 |
-
*
|
1353 |
-
* Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
|
1354 |
-
* the raw bytes. This behavior is similar to PHP's md5() function.
|
1355 |
-
*
|
1356 |
-
* @param optional Boolean $raw_output
|
1357 |
-
* @return String
|
1358 |
-
* @access public
|
1359 |
-
*/
|
1360 |
-
function getHostKeyPublicModulus($raw_output = false)
|
1361 |
-
{
|
1362 |
-
return $raw_output ? $this->host_key_public_modulus->toBytes() : $this->host_key_public_modulus->toString();
|
1363 |
-
}
|
1364 |
-
|
1365 |
-
/**
|
1366 |
-
* Return a list of ciphers supported by SSH1 server.
|
1367 |
-
*
|
1368 |
-
* Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output
|
1369 |
-
* is set to true, returns, instead, an array of constants. ie. instead of array('Triple-DES in CBC mode'), you'll
|
1370 |
-
* get array(NET_SSH1_CIPHER_3DES).
|
1371 |
-
*
|
1372 |
-
* @param optional Boolean $raw_output
|
1373 |
-
* @return Array
|
1374 |
-
* @access public
|
1375 |
-
*/
|
1376 |
-
function getSupportedCiphers($raw_output = false)
|
1377 |
-
{
|
1378 |
-
return $raw_output ? array_keys($this->supported_ciphers) : array_values($this->supported_ciphers);
|
1379 |
-
}
|
1380 |
-
|
1381 |
-
/**
|
1382 |
-
* Return a list of authentications supported by SSH1 server.
|
1383 |
-
*
|
1384 |
-
* Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output
|
1385 |
-
* is set to true, returns, instead, an array of constants. ie. instead of array('password authentication'), you'll
|
1386 |
-
* get array(NET_SSH1_AUTH_PASSWORD).
|
1387 |
-
*
|
1388 |
-
* @param optional Boolean $raw_output
|
1389 |
-
* @return Array
|
1390 |
-
* @access public
|
1391 |
-
*/
|
1392 |
-
function getSupportedAuthentications($raw_output = false)
|
1393 |
-
{
|
1394 |
-
return $raw_output ? array_keys($this->supported_authentications) : array_values($this->supported_authentications);
|
1395 |
-
}
|
1396 |
-
|
1397 |
-
/**
|
1398 |
-
* Return the server identification.
|
1399 |
-
*
|
1400 |
-
* @return String
|
1401 |
-
* @access public
|
1402 |
-
*/
|
1403 |
-
function getServerIdentification()
|
1404 |
-
{
|
1405 |
-
return rtrim($this->server_identification);
|
1406 |
-
}
|
1407 |
-
}
|
1408 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Net/SSH2.php
DELETED
@@ -1,2660 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of SSHv2.
|
6 |
-
*
|
7 |
-
* PHP versions 4 and 5
|
8 |
-
*
|
9 |
-
* Here are some examples of how to use this library:
|
10 |
-
* <code>
|
11 |
-
* <?php
|
12 |
-
* include('Net/SSH2.php');
|
13 |
-
*
|
14 |
-
* $ssh = new Net_SSH2('www.domain.tld');
|
15 |
-
* if (!$ssh->login('username', 'password')) {
|
16 |
-
* exit('Login Failed');
|
17 |
-
* }
|
18 |
-
*
|
19 |
-
* echo $ssh->exec('pwd');
|
20 |
-
* echo $ssh->exec('ls -la');
|
21 |
-
* ?>
|
22 |
-
* </code>
|
23 |
-
*
|
24 |
-
* <code>
|
25 |
-
* <?php
|
26 |
-
* include('Crypt/RSA.php');
|
27 |
-
* include('Net/SSH2.php');
|
28 |
-
*
|
29 |
-
* $key = new Crypt_RSA();
|
30 |
-
* //$key->setPassword('whatever');
|
31 |
-
* $key->loadKey(file_get_contents('privatekey'));
|
32 |
-
*
|
33 |
-
* $ssh = new Net_SSH2('www.domain.tld');
|
34 |
-
* if (!$ssh->login('username', $key)) {
|
35 |
-
* exit('Login Failed');
|
36 |
-
* }
|
37 |
-
*
|
38 |
-
* echo $ssh->read('username@username:~$');
|
39 |
-
* $ssh->write("ls -la\n");
|
40 |
-
* echo $ssh->read('username@username:~$');
|
41 |
-
* ?>
|
42 |
-
* </code>
|
43 |
-
*
|
44 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
45 |
-
* of this software and associated documentation files (the "Software"), to deal
|
46 |
-
* in the Software without restriction, including without limitation the rights
|
47 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
48 |
-
* copies of the Software, and to permit persons to whom the Software is
|
49 |
-
* furnished to do so, subject to the following conditions:
|
50 |
-
*
|
51 |
-
* The above copyright notice and this permission notice shall be included in
|
52 |
-
* all copies or substantial portions of the Software.
|
53 |
-
*
|
54 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
55 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
56 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
57 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
58 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
59 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
60 |
-
* THE SOFTWARE.
|
61 |
-
*
|
62 |
-
* @category Net
|
63 |
-
* @package Net_SSH2
|
64 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
65 |
-
* @copyright MMVII Jim Wigginton
|
66 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
67 |
-
* @version $Id: SSH2.php,v 1.53 2010-10-24 01:24:30 terrafrost Exp $
|
68 |
-
* @link http://phpseclib.sourceforge.net
|
69 |
-
*/
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Include Math_BigInteger
|
73 |
-
*
|
74 |
-
* Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.
|
75 |
-
*/
|
76 |
-
require_once('Math/BigInteger.php');
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Include Crypt_Random
|
80 |
-
*/
|
81 |
-
require_once('Crypt/Random.php');
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Include Crypt_Hash
|
85 |
-
*/
|
86 |
-
require_once('Crypt/Hash.php');
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Include Crypt_TripleDES
|
90 |
-
*/
|
91 |
-
require_once('Crypt/TripleDES.php');
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Include Crypt_RC4
|
95 |
-
*/
|
96 |
-
require_once('Crypt/RC4.php');
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Include Crypt_AES
|
100 |
-
*/
|
101 |
-
require_once('Crypt/AES.php');
|
102 |
-
|
103 |
-
/**#@+
|
104 |
-
* Execution Bitmap Masks
|
105 |
-
*
|
106 |
-
* @see Net_SSH2::bitmap
|
107 |
-
* @access private
|
108 |
-
*/
|
109 |
-
define('NET_SSH2_MASK_CONSTRUCTOR', 0x00000001);
|
110 |
-
define('NET_SSH2_MASK_LOGIN', 0x00000002);
|
111 |
-
define('NET_SSH2_MASK_SHELL', 0x00000004);
|
112 |
-
/**#@-*/
|
113 |
-
|
114 |
-
/**#@+
|
115 |
-
* Channel constants
|
116 |
-
*
|
117 |
-
* RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer
|
118 |
-
* to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with
|
119 |
-
* a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a
|
120 |
-
* recepient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel
|
121 |
-
* would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snipet:
|
122 |
-
* The 'recipient channel' is the channel number given in the original
|
123 |
-
* open request, and 'sender channel' is the channel number allocated by
|
124 |
-
* the other side.
|
125 |
-
*
|
126 |
-
* @see Net_SSH2::_send_channel_packet()
|
127 |
-
* @see Net_SSH2::_get_channel_packet()
|
128 |
-
* @access private
|
129 |
-
*/
|
130 |
-
define('NET_SSH2_CHANNEL_EXEC', 0); // PuTTy uses 0x100
|
131 |
-
define('NET_SSH2_CHANNEL_SHELL',1);
|
132 |
-
/**#@-*/
|
133 |
-
|
134 |
-
/**#@+
|
135 |
-
* @access public
|
136 |
-
* @see Net_SSH2::getLog()
|
137 |
-
*/
|
138 |
-
/**
|
139 |
-
* Returns the message numbers
|
140 |
-
*/
|
141 |
-
define('NET_SSH2_LOG_SIMPLE', 1);
|
142 |
-
/**
|
143 |
-
* Returns the message content
|
144 |
-
*/
|
145 |
-
define('NET_SSH2_LOG_COMPLEX', 2);
|
146 |
-
/**#@-*/
|
147 |
-
|
148 |
-
/**#@+
|
149 |
-
* @access public
|
150 |
-
* @see Net_SSH2::read()
|
151 |
-
*/
|
152 |
-
/**
|
153 |
-
* Returns when a string matching $expect exactly is found
|
154 |
-
*/
|
155 |
-
define('NET_SSH2_READ_SIMPLE', 1);
|
156 |
-
/**
|
157 |
-
* Returns when a string matching the regular expression $expect is found
|
158 |
-
*/
|
159 |
-
define('NET_SSH2_READ_REGEX', 2);
|
160 |
-
/**#@-*/
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Pure-PHP implementation of SSHv2.
|
164 |
-
*
|
165 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
166 |
-
* @version 0.1.0
|
167 |
-
* @access public
|
168 |
-
* @package Net_SSH2
|
169 |
-
*/
|
170 |
-
class Net_SSH2 {
|
171 |
-
/**
|
172 |
-
* The SSH identifier
|
173 |
-
*
|
174 |
-
* @var String
|
175 |
-
* @access private
|
176 |
-
*/
|
177 |
-
var $identifier = 'SSH-2.0-phpseclib_0.2';
|
178 |
-
|
179 |
-
/**
|
180 |
-
* The Socket Object
|
181 |
-
*
|
182 |
-
* @var Object
|
183 |
-
* @access private
|
184 |
-
*/
|
185 |
-
var $fsock;
|
186 |
-
|
187 |
-
/**
|
188 |
-
* Execution Bitmap
|
189 |
-
*
|
190 |
-
* The bits that are set reprsent functions that have been called already. This is used to determine
|
191 |
-
* if a requisite function has been successfully executed. If not, an error should be thrown.
|
192 |
-
*
|
193 |
-
* @var Integer
|
194 |
-
* @access private
|
195 |
-
*/
|
196 |
-
var $bitmap = 0;
|
197 |
-
|
198 |
-
/**
|
199 |
-
* Error information
|
200 |
-
*
|
201 |
-
* @see Net_SSH2::getErrors()
|
202 |
-
* @see Net_SSH2::getLastError()
|
203 |
-
* @var String
|
204 |
-
* @access private
|
205 |
-
*/
|
206 |
-
var $errors = array();
|
207 |
-
|
208 |
-
/**
|
209 |
-
* Server Identifier
|
210 |
-
*
|
211 |
-
* @see Net_SSH2::getServerIdentification()
|
212 |
-
* @var String
|
213 |
-
* @access private
|
214 |
-
*/
|
215 |
-
var $server_identifier = '';
|
216 |
-
|
217 |
-
/**
|
218 |
-
* Key Exchange Algorithms
|
219 |
-
*
|
220 |
-
* @see Net_SSH2::getKexAlgorithims()
|
221 |
-
* @var Array
|
222 |
-
* @access private
|
223 |
-
*/
|
224 |
-
var $kex_algorithms;
|
225 |
-
|
226 |
-
/**
|
227 |
-
* Server Host Key Algorithms
|
228 |
-
*
|
229 |
-
* @see Net_SSH2::getServerHostKeyAlgorithms()
|
230 |
-
* @var Array
|
231 |
-
* @access private
|
232 |
-
*/
|
233 |
-
var $server_host_key_algorithms;
|
234 |
-
|
235 |
-
/**
|
236 |
-
* Encryption Algorithms: Client to Server
|
237 |
-
*
|
238 |
-
* @see Net_SSH2::getEncryptionAlgorithmsClient2Server()
|
239 |
-
* @var Array
|
240 |
-
* @access private
|
241 |
-
*/
|
242 |
-
var $encryption_algorithms_client_to_server;
|
243 |
-
|
244 |
-
/**
|
245 |
-
* Encryption Algorithms: Server to Client
|
246 |
-
*
|
247 |
-
* @see Net_SSH2::getEncryptionAlgorithmsServer2Client()
|
248 |
-
* @var Array
|
249 |
-
* @access private
|
250 |
-
*/
|
251 |
-
var $encryption_algorithms_server_to_client;
|
252 |
-
|
253 |
-
/**
|
254 |
-
* MAC Algorithms: Client to Server
|
255 |
-
*
|
256 |
-
* @see Net_SSH2::getMACAlgorithmsClient2Server()
|
257 |
-
* @var Array
|
258 |
-
* @access private
|
259 |
-
*/
|
260 |
-
var $mac_algorithms_client_to_server;
|
261 |
-
|
262 |
-
/**
|
263 |
-
* MAC Algorithms: Server to Client
|
264 |
-
*
|
265 |
-
* @see Net_SSH2::getMACAlgorithmsServer2Client()
|
266 |
-
* @var Array
|
267 |
-
* @access private
|
268 |
-
*/
|
269 |
-
var $mac_algorithms_server_to_client;
|
270 |
-
|
271 |
-
/**
|
272 |
-
* Compression Algorithms: Client to Server
|
273 |
-
*
|
274 |
-
* @see Net_SSH2::getCompressionAlgorithmsClient2Server()
|
275 |
-
* @var Array
|
276 |
-
* @access private
|
277 |
-
*/
|
278 |
-
var $compression_algorithms_client_to_server;
|
279 |
-
|
280 |
-
/**
|
281 |
-
* Compression Algorithms: Server to Client
|
282 |
-
*
|
283 |
-
* @see Net_SSH2::getCompressionAlgorithmsServer2Client()
|
284 |
-
* @var Array
|
285 |
-
* @access private
|
286 |
-
*/
|
287 |
-
var $compression_algorithms_server_to_client;
|
288 |
-
|
289 |
-
/**
|
290 |
-
* Languages: Server to Client
|
291 |
-
*
|
292 |
-
* @see Net_SSH2::getLanguagesServer2Client()
|
293 |
-
* @var Array
|
294 |
-
* @access private
|
295 |
-
*/
|
296 |
-
var $languages_server_to_client;
|
297 |
-
|
298 |
-
/**
|
299 |
-
* Languages: Client to Server
|
300 |
-
*
|
301 |
-
* @see Net_SSH2::getLanguagesClient2Server()
|
302 |
-
* @var Array
|
303 |
-
* @access private
|
304 |
-
*/
|
305 |
-
var $languages_client_to_server;
|
306 |
-
|
307 |
-
/**
|
308 |
-
* Block Size for Server to Client Encryption
|
309 |
-
*
|
310 |
-
* "Note that the length of the concatenation of 'packet_length',
|
311 |
-
* 'padding_length', 'payload', and 'random padding' MUST be a multiple
|
312 |
-
* of the cipher block size or 8, whichever is larger. This constraint
|
313 |
-
* MUST be enforced, even when using stream ciphers."
|
314 |
-
*
|
315 |
-
* -- http://tools.ietf.org/html/rfc4253#section-6
|
316 |
-
*
|
317 |
-
* @see Net_SSH2::Net_SSH2()
|
318 |
-
* @see Net_SSH2::_send_binary_packet()
|
319 |
-
* @var Integer
|
320 |
-
* @access private
|
321 |
-
*/
|
322 |
-
var $encrypt_block_size = 8;
|
323 |
-
|
324 |
-
/**
|
325 |
-
* Block Size for Client to Server Encryption
|
326 |
-
*
|
327 |
-
* @see Net_SSH2::Net_SSH2()
|
328 |
-
* @see Net_SSH2::_get_binary_packet()
|
329 |
-
* @var Integer
|
330 |
-
* @access private
|
331 |
-
*/
|
332 |
-
var $decrypt_block_size = 8;
|
333 |
-
|
334 |
-
/**
|
335 |
-
* Server to Client Encryption Object
|
336 |
-
*
|
337 |
-
* @see Net_SSH2::_get_binary_packet()
|
338 |
-
* @var Object
|
339 |
-
* @access private
|
340 |
-
*/
|
341 |
-
var $decrypt = false;
|
342 |
-
|
343 |
-
/**
|
344 |
-
* Client to Server Encryption Object
|
345 |
-
*
|
346 |
-
* @see Net_SSH2::_send_binary_packet()
|
347 |
-
* @var Object
|
348 |
-
* @access private
|
349 |
-
*/
|
350 |
-
var $encrypt = false;
|
351 |
-
|
352 |
-
/**
|
353 |
-
* Client to Server HMAC Object
|
354 |
-
*
|
355 |
-
* @see Net_SSH2::_send_binary_packet()
|
356 |
-
* @var Object
|
357 |
-
* @access private
|
358 |
-
*/
|
359 |
-
var $hmac_create = false;
|
360 |
-
|
361 |
-
/**
|
362 |
-
* Server to Client HMAC Object
|
363 |
-
*
|
364 |
-
* @see Net_SSH2::_get_binary_packet()
|
365 |
-
* @var Object
|
366 |
-
* @access private
|
367 |
-
*/
|
368 |
-
var $hmac_check = false;
|
369 |
-
|
370 |
-
/**
|
371 |
-
* Size of server to client HMAC
|
372 |
-
*
|
373 |
-
* We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read.
|
374 |
-
* For the client to server side, the HMAC object will make the HMAC as long as it needs to be. All we need to do is
|
375 |
-
* append it.
|
376 |
-
*
|
377 |
-
* @see Net_SSH2::_get_binary_packet()
|
378 |
-
* @var Integer
|
379 |
-
* @access private
|
380 |
-
*/
|
381 |
-
var $hmac_size = false;
|
382 |
-
|
383 |
-
/**
|
384 |
-
* Server Public Host Key
|
385 |
-
*
|
386 |
-
* @see Net_SSH2::getServerPublicHostKey()
|
387 |
-
* @var String
|
388 |
-
* @access private
|
389 |
-
*/
|
390 |
-
var $server_public_host_key;
|
391 |
-
|
392 |
-
/**
|
393 |
-
* Session identifer
|
394 |
-
*
|
395 |
-
* "The exchange hash H from the first key exchange is additionally
|
396 |
-
* used as the session identifier, which is a unique identifier for
|
397 |
-
* this connection."
|
398 |
-
*
|
399 |
-
* -- http://tools.ietf.org/html/rfc4253#section-7.2
|
400 |
-
*
|
401 |
-
* @see Net_SSH2::_key_exchange()
|
402 |
-
* @var String
|
403 |
-
* @access private
|
404 |
-
*/
|
405 |
-
var $session_id = false;
|
406 |
-
|
407 |
-
/**
|
408 |
-
* Exchange hash
|
409 |
-
*
|
410 |
-
* The current exchange hash
|
411 |
-
*
|
412 |
-
* @see Net_SSH2::_key_exchange()
|
413 |
-
* @var String
|
414 |
-
* @access private
|
415 |
-
*/
|
416 |
-
var $exchange_hash = false;
|
417 |
-
|
418 |
-
/**
|
419 |
-
* Message Numbers
|
420 |
-
*
|
421 |
-
* @see Net_SSH2::Net_SSH2()
|
422 |
-
* @var Array
|
423 |
-
* @access private
|
424 |
-
*/
|
425 |
-
var $message_numbers = array();
|
426 |
-
|
427 |
-
/**
|
428 |
-
* Disconnection Message 'reason codes' defined in RFC4253
|
429 |
-
*
|
430 |
-
* @see Net_SSH2::Net_SSH2()
|
431 |
-
* @var Array
|
432 |
-
* @access private
|
433 |
-
*/
|
434 |
-
var $disconnect_reasons = array();
|
435 |
-
|
436 |
-
/**
|
437 |
-
* SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254
|
438 |
-
*
|
439 |
-
* @see Net_SSH2::Net_SSH2()
|
440 |
-
* @var Array
|
441 |
-
* @access private
|
442 |
-
*/
|
443 |
-
var $channel_open_failure_reasons = array();
|
444 |
-
|
445 |
-
/**
|
446 |
-
* Terminal Modes
|
447 |
-
*
|
448 |
-
* @link http://tools.ietf.org/html/rfc4254#section-8
|
449 |
-
* @see Net_SSH2::Net_SSH2()
|
450 |
-
* @var Array
|
451 |
-
* @access private
|
452 |
-
*/
|
453 |
-
var $terminal_modes = array();
|
454 |
-
|
455 |
-
/**
|
456 |
-
* SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes
|
457 |
-
*
|
458 |
-
* @link http://tools.ietf.org/html/rfc4254#section-5.2
|
459 |
-
* @see Net_SSH2::Net_SSH2()
|
460 |
-
* @var Array
|
461 |
-
* @access private
|
462 |
-
*/
|
463 |
-
var $channel_extended_data_type_codes = array();
|
464 |
-
|
465 |
-
/**
|
466 |
-
* Send Sequence Number
|
467 |
-
*
|
468 |
-
* See 'Section 6.4. Data Integrity' of rfc4253 for more info.
|
469 |
-
*
|
470 |
-
* @see Net_SSH2::_send_binary_packet()
|
471 |
-
* @var Integer
|
472 |
-
* @access private
|
473 |
-
*/
|
474 |
-
var $send_seq_no = 0;
|
475 |
-
|
476 |
-
/**
|
477 |
-
* Get Sequence Number
|
478 |
-
*
|
479 |
-
* See 'Section 6.4. Data Integrity' of rfc4253 for more info.
|
480 |
-
*
|
481 |
-
* @see Net_SSH2::_get_binary_packet()
|
482 |
-
* @var Integer
|
483 |
-
* @access private
|
484 |
-
*/
|
485 |
-
var $get_seq_no = 0;
|
486 |
-
|
487 |
-
/**
|
488 |
-
* Server Channels
|
489 |
-
*
|
490 |
-
* Maps client channels to server channels
|
491 |
-
*
|
492 |
-
* @see Net_SSH2::_get_channel_packet()
|
493 |
-
* @see Net_SSH2::exec()
|
494 |
-
* @var Array
|
495 |
-
* @access private
|
496 |
-
*/
|
497 |
-
var $server_channels = array();
|
498 |
-
|
499 |
-
/**
|
500 |
-
* Channel Buffers
|
501 |
-
*
|
502 |
-
* If a client requests a packet from one channel but receives two packets from another those packets should
|
503 |
-
* be placed in a buffer
|
504 |
-
*
|
505 |
-
* @see Net_SSH2::_get_channel_packet()
|
506 |
-
* @see Net_SSH2::exec()
|
507 |
-
* @var Array
|
508 |
-
* @access private
|
509 |
-
*/
|
510 |
-
var $channel_buffers = array();
|
511 |
-
|
512 |
-
/**
|
513 |
-
* Channel Status
|
514 |
-
*
|
515 |
-
* Contains the type of the last sent message
|
516 |
-
*
|
517 |
-
* @see Net_SSH2::_get_channel_packet()
|
518 |
-
* @var Array
|
519 |
-
* @access private
|
520 |
-
*/
|
521 |
-
var $channel_status = array();
|
522 |
-
|
523 |
-
/**
|
524 |
-
* Packet Size
|
525 |
-
*
|
526 |
-
* Maximum packet size indexed by channel
|
527 |
-
*
|
528 |
-
* @see Net_SSH2::_send_channel_packet()
|
529 |
-
* @var Array
|
530 |
-
* @access private
|
531 |
-
*/
|
532 |
-
var $packet_size_client_to_server = array();
|
533 |
-
|
534 |
-
/**
|
535 |
-
* Message Number Log
|
536 |
-
*
|
537 |
-
* @see Net_SSH2::getLog()
|
538 |
-
* @var Array
|
539 |
-
* @access private
|
540 |
-
*/
|
541 |
-
var $message_number_log = array();
|
542 |
-
|
543 |
-
/**
|
544 |
-
* Message Log
|
545 |
-
*
|
546 |
-
* @see Net_SSH2::getLog()
|
547 |
-
* @var Array
|
548 |
-
* @access private
|
549 |
-
*/
|
550 |
-
var $message_log = array();
|
551 |
-
|
552 |
-
/**
|
553 |
-
* The Window Size
|
554 |
-
*
|
555 |
-
* Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 4GB)
|
556 |
-
*
|
557 |
-
* @var Integer
|
558 |
-
* @see Net_SSH2::_send_channel_packet()
|
559 |
-
* @see Net_SSH2::exec()
|
560 |
-
* @access private
|
561 |
-
*/
|
562 |
-
var $window_size = 0x7FFFFFFF;
|
563 |
-
|
564 |
-
/**
|
565 |
-
* Window size
|
566 |
-
*
|
567 |
-
* Window size indexed by channel
|
568 |
-
*
|
569 |
-
* @see Net_SSH2::_send_channel_packet()
|
570 |
-
* @var Array
|
571 |
-
* @access private
|
572 |
-
*/
|
573 |
-
var $window_size_client_to_server = array();
|
574 |
-
|
575 |
-
/**
|
576 |
-
* Server signature
|
577 |
-
*
|
578 |
-
* Verified against $this->session_id
|
579 |
-
*
|
580 |
-
* @see Net_SSH2::getServerPublicHostKey()
|
581 |
-
* @var String
|
582 |
-
* @access private
|
583 |
-
*/
|
584 |
-
var $signature = '';
|
585 |
-
|
586 |
-
/**
|
587 |
-
* Server signature format
|
588 |
-
*
|
589 |
-
* ssh-rsa or ssh-dss.
|
590 |
-
*
|
591 |
-
* @see Net_SSH2::getServerPublicHostKey()
|
592 |
-
* @var String
|
593 |
-
* @access private
|
594 |
-
*/
|
595 |
-
var $signature_format = '';
|
596 |
-
|
597 |
-
/**
|
598 |
-
* Interactive Buffer
|
599 |
-
*
|
600 |
-
* @see Net_SSH2::read()
|
601 |
-
* @var Array
|
602 |
-
* @access private
|
603 |
-
*/
|
604 |
-
var $interactiveBuffer = '';
|
605 |
-
|
606 |
-
/**
|
607 |
-
* Default Constructor.
|
608 |
-
*
|
609 |
-
* Connects to an SSHv2 server
|
610 |
-
*
|
611 |
-
* @param String $host
|
612 |
-
* @param optional Integer $port
|
613 |
-
* @param optional Integer $timeout
|
614 |
-
* @return Net_SSH2
|
615 |
-
* @access public
|
616 |
-
*/
|
617 |
-
function Net_SSH2($host, $port = 22, $timeout = 10)
|
618 |
-
{
|
619 |
-
$this->message_numbers = array(
|
620 |
-
1 => 'NET_SSH2_MSG_DISCONNECT',
|
621 |
-
2 => 'NET_SSH2_MSG_IGNORE',
|
622 |
-
3 => 'NET_SSH2_MSG_UNIMPLEMENTED',
|
623 |
-
4 => 'NET_SSH2_MSG_DEBUG',
|
624 |
-
5 => 'NET_SSH2_MSG_SERVICE_REQUEST',
|
625 |
-
6 => 'NET_SSH2_MSG_SERVICE_ACCEPT',
|
626 |
-
20 => 'NET_SSH2_MSG_KEXINIT',
|
627 |
-
21 => 'NET_SSH2_MSG_NEWKEYS',
|
628 |
-
30 => 'NET_SSH2_MSG_KEXDH_INIT',
|
629 |
-
31 => 'NET_SSH2_MSG_KEXDH_REPLY',
|
630 |
-
50 => 'NET_SSH2_MSG_USERAUTH_REQUEST',
|
631 |
-
51 => 'NET_SSH2_MSG_USERAUTH_FAILURE',
|
632 |
-
52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS',
|
633 |
-
53 => 'NET_SSH2_MSG_USERAUTH_BANNER',
|
634 |
-
|
635 |
-
80 => 'NET_SSH2_MSG_GLOBAL_REQUEST',
|
636 |
-
81 => 'NET_SSH2_MSG_REQUEST_SUCCESS',
|
637 |
-
82 => 'NET_SSH2_MSG_REQUEST_FAILURE',
|
638 |
-
90 => 'NET_SSH2_MSG_CHANNEL_OPEN',
|
639 |
-
91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION',
|
640 |
-
92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE',
|
641 |
-
93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST',
|
642 |
-
94 => 'NET_SSH2_MSG_CHANNEL_DATA',
|
643 |
-
95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA',
|
644 |
-
96 => 'NET_SSH2_MSG_CHANNEL_EOF',
|
645 |
-
97 => 'NET_SSH2_MSG_CHANNEL_CLOSE',
|
646 |
-
98 => 'NET_SSH2_MSG_CHANNEL_REQUEST',
|
647 |
-
99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS',
|
648 |
-
100 => 'NET_SSH2_MSG_CHANNEL_FAILURE'
|
649 |
-
);
|
650 |
-
$this->disconnect_reasons = array(
|
651 |
-
1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT',
|
652 |
-
2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR',
|
653 |
-
3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED',
|
654 |
-
4 => 'NET_SSH2_DISCONNECT_RESERVED',
|
655 |
-
5 => 'NET_SSH2_DISCONNECT_MAC_ERROR',
|
656 |
-
6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR',
|
657 |
-
7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE',
|
658 |
-
8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED',
|
659 |
-
9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE',
|
660 |
-
10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST',
|
661 |
-
11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION',
|
662 |
-
12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS',
|
663 |
-
13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER',
|
664 |
-
14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE',
|
665 |
-
15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME'
|
666 |
-
);
|
667 |
-
$this->channel_open_failure_reasons = array(
|
668 |
-
1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED'
|
669 |
-
);
|
670 |
-
$this->terminal_modes = array(
|
671 |
-
0 => 'NET_SSH2_TTY_OP_END'
|
672 |
-
);
|
673 |
-
$this->channel_extended_data_type_codes = array(
|
674 |
-
1 => 'NET_SSH2_EXTENDED_DATA_STDERR'
|
675 |
-
);
|
676 |
-
|
677 |
-
$this->_define_array(
|
678 |
-
$this->message_numbers,
|
679 |
-
$this->disconnect_reasons,
|
680 |
-
$this->channel_open_failure_reasons,
|
681 |
-
$this->terminal_modes,
|
682 |
-
$this->channel_extended_data_type_codes,
|
683 |
-
array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'),
|
684 |
-
array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'),
|
685 |
-
array(60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
|
686 |
-
61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE')
|
687 |
-
);
|
688 |
-
|
689 |
-
$this->fsock = @fsockopen($host, $port, $errno, $errstr, $timeout);
|
690 |
-
if (!$this->fsock) {
|
691 |
-
user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"), E_USER_NOTICE);
|
692 |
-
return;
|
693 |
-
}
|
694 |
-
|
695 |
-
/* According to the SSH2 specs,
|
696 |
-
|
697 |
-
"The server MAY send other lines of data before sending the version
|
698 |
-
string. Each line SHOULD be terminated by a Carriage Return and Line
|
699 |
-
Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded
|
700 |
-
in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients
|
701 |
-
MUST be able to process such lines." */
|
702 |
-
$temp = '';
|
703 |
-
$extra = '';
|
704 |
-
while (!feof($this->fsock) && !preg_match('#^SSH-(\d\.\d+)#', $temp, $matches)) {
|
705 |
-
if (substr($temp, -2) == "\r\n") {
|
706 |
-
$extra.= $temp;
|
707 |
-
$temp = '';
|
708 |
-
}
|
709 |
-
$temp.= fgets($this->fsock, 255);
|
710 |
-
}
|
711 |
-
|
712 |
-
if (feof($this->fsock)) {
|
713 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
714 |
-
return false;
|
715 |
-
}
|
716 |
-
|
717 |
-
$ext = array();
|
718 |
-
if (extension_loaded('mcrypt')) {
|
719 |
-
$ext[] = 'mcrypt';
|
720 |
-
}
|
721 |
-
if (extension_loaded('gmp')) {
|
722 |
-
$ext[] = 'gmp';
|
723 |
-
} else if (extension_loaded('bcmath')) {
|
724 |
-
$ext[] = 'bcmath';
|
725 |
-
}
|
726 |
-
|
727 |
-
if (!empty($ext)) {
|
728 |
-
$this->identifier.= ' (' . implode(', ', $ext) . ')';
|
729 |
-
}
|
730 |
-
|
731 |
-
if (defined('NET_SSH2_LOGGING')) {
|
732 |
-
$this->message_number_log[] = '<-';
|
733 |
-
$this->message_number_log[] = '->';
|
734 |
-
|
735 |
-
if (NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {
|
736 |
-
$this->message_log[] = $temp;
|
737 |
-
$this->message_log[] = $this->identifier . "\r\n";
|
738 |
-
}
|
739 |
-
}
|
740 |
-
|
741 |
-
$this->server_identifier = trim($temp, "\r\n");
|
742 |
-
if (!empty($extra)) {
|
743 |
-
$this->errors[] = utf8_decode($extra);
|
744 |
-
}
|
745 |
-
|
746 |
-
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
|
747 |
-
user_error("Cannot connect to SSH $matches[1] servers", E_USER_NOTICE);
|
748 |
-
return;
|
749 |
-
}
|
750 |
-
|
751 |
-
fputs($this->fsock, $this->identifier . "\r\n");
|
752 |
-
|
753 |
-
$response = $this->_get_binary_packet();
|
754 |
-
if ($response === false) {
|
755 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
756 |
-
return;
|
757 |
-
}
|
758 |
-
|
759 |
-
if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
760 |
-
user_error('Expected SSH_MSG_KEXINIT', E_USER_NOTICE);
|
761 |
-
return;
|
762 |
-
}
|
763 |
-
|
764 |
-
if (!$this->_key_exchange($response)) {
|
765 |
-
return;
|
766 |
-
}
|
767 |
-
|
768 |
-
$this->bitmap = NET_SSH2_MASK_CONSTRUCTOR;
|
769 |
-
}
|
770 |
-
|
771 |
-
/**
|
772 |
-
* Key Exchange
|
773 |
-
*
|
774 |
-
* @param String $kexinit_payload_server
|
775 |
-
* @access private
|
776 |
-
*/
|
777 |
-
function _key_exchange($kexinit_payload_server)
|
778 |
-
{
|
779 |
-
static $kex_algorithms = array(
|
780 |
-
'diffie-hellman-group1-sha1', // REQUIRED
|
781 |
-
'diffie-hellman-group14-sha1' // REQUIRED
|
782 |
-
);
|
783 |
-
|
784 |
-
static $server_host_key_algorithms = array(
|
785 |
-
'ssh-rsa', // RECOMMENDED sign Raw RSA Key
|
786 |
-
'ssh-dss' // REQUIRED sign Raw DSS Key
|
787 |
-
);
|
788 |
-
|
789 |
-
static $encryption_algorithms = array(
|
790 |
-
// from <http://tools.ietf.org/html/rfc4345#section-4>:
|
791 |
-
'arcfour256',
|
792 |
-
'arcfour128',
|
793 |
-
|
794 |
-
'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
|
795 |
-
|
796 |
-
'aes128-cbc', // RECOMMENDED AES with a 128-bit key
|
797 |
-
'aes192-cbc', // OPTIONAL AES with a 192-bit key
|
798 |
-
'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
|
799 |
-
|
800 |
-
// from <http://tools.ietf.org/html/rfc4344#section-4>:
|
801 |
-
'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
|
802 |
-
'aes192-ctr', // RECOMMENDED AES with 192-bit key
|
803 |
-
'aes256-ctr', // RECOMMENDED AES with 256-bit key
|
804 |
-
'3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
|
805 |
-
|
806 |
-
'3des-cbc', // REQUIRED three-key 3DES in CBC mode
|
807 |
-
'none' // OPTIONAL no encryption; NOT RECOMMENDED
|
808 |
-
);
|
809 |
-
|
810 |
-
static $mac_algorithms = array(
|
811 |
-
'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20)
|
812 |
-
'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20)
|
813 |
-
'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16)
|
814 |
-
'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16)
|
815 |
-
'none' // OPTIONAL no MAC; NOT RECOMMENDED
|
816 |
-
);
|
817 |
-
|
818 |
-
static $compression_algorithms = array(
|
819 |
-
'none' // REQUIRED no compression
|
820 |
-
//'zlib' // OPTIONAL ZLIB (LZ77) compression
|
821 |
-
);
|
822 |
-
|
823 |
-
static $str_kex_algorithms, $str_server_host_key_algorithms,
|
824 |
-
$encryption_algorithms_server_to_client, $mac_algorithms_server_to_client, $compression_algorithms_server_to_client,
|
825 |
-
$encryption_algorithms_client_to_server, $mac_algorithms_client_to_server, $compression_algorithms_client_to_server;
|
826 |
-
|
827 |
-
if (empty($str_kex_algorithms)) {
|
828 |
-
$str_kex_algorithms = implode(',', $kex_algorithms);
|
829 |
-
$str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
|
830 |
-
$encryption_algorithms_server_to_client = $encryption_algorithms_client_to_server = implode(',', $encryption_algorithms);
|
831 |
-
$mac_algorithms_server_to_client = $mac_algorithms_client_to_server = implode(',', $mac_algorithms);
|
832 |
-
$compression_algorithms_server_to_client = $compression_algorithms_client_to_server = implode(',', $compression_algorithms);
|
833 |
-
}
|
834 |
-
|
835 |
-
$client_cookie = '';
|
836 |
-
for ($i = 0; $i < 16; $i++) {
|
837 |
-
$client_cookie.= chr(crypt_random(0, 255));
|
838 |
-
}
|
839 |
-
|
840 |
-
$response = $kexinit_payload_server;
|
841 |
-
$this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
|
842 |
-
$server_cookie = $this->_string_shift($response, 16);
|
843 |
-
|
844 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
845 |
-
$this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
|
846 |
-
|
847 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
848 |
-
$this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
|
849 |
-
|
850 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
851 |
-
$this->encryption_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
|
852 |
-
|
853 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
854 |
-
$this->encryption_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
|
855 |
-
|
856 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
857 |
-
$this->mac_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
|
858 |
-
|
859 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
860 |
-
$this->mac_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
|
861 |
-
|
862 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
863 |
-
$this->compression_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
|
864 |
-
|
865 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
866 |
-
$this->compression_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
|
867 |
-
|
868 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
869 |
-
$this->languages_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
|
870 |
-
|
871 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
872 |
-
$this->languages_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
|
873 |
-
|
874 |
-
extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
|
875 |
-
$first_kex_packet_follows = $first_kex_packet_follows != 0;
|
876 |
-
|
877 |
-
// the sending of SSH2_MSG_KEXINIT could go in one of two places. this is the second place.
|
878 |
-
$kexinit_payload_client = pack('Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
|
879 |
-
NET_SSH2_MSG_KEXINIT, $client_cookie, strlen($str_kex_algorithms), $str_kex_algorithms,
|
880 |
-
strlen($str_server_host_key_algorithms), $str_server_host_key_algorithms, strlen($encryption_algorithms_client_to_server),
|
881 |
-
$encryption_algorithms_client_to_server, strlen($encryption_algorithms_server_to_client), $encryption_algorithms_server_to_client,
|
882 |
-
strlen($mac_algorithms_client_to_server), $mac_algorithms_client_to_server, strlen($mac_algorithms_server_to_client),
|
883 |
-
$mac_algorithms_server_to_client, strlen($compression_algorithms_client_to_server), $compression_algorithms_client_to_server,
|
884 |
-
strlen($compression_algorithms_server_to_client), $compression_algorithms_server_to_client, 0, '', 0, '',
|
885 |
-
0, 0
|
886 |
-
);
|
887 |
-
|
888 |
-
if (!$this->_send_binary_packet($kexinit_payload_client)) {
|
889 |
-
return false;
|
890 |
-
}
|
891 |
-
// here ends the second place.
|
892 |
-
|
893 |
-
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
|
894 |
-
for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_server_to_client); $i++);
|
895 |
-
if ($i == count($encryption_algorithms)) {
|
896 |
-
user_error('No compatible server to client encryption algorithms found', E_USER_NOTICE);
|
897 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
898 |
-
}
|
899 |
-
|
900 |
-
// we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
|
901 |
-
// diffie-hellman key exchange as fast as possible
|
902 |
-
$decrypt = $encryption_algorithms[$i];
|
903 |
-
switch ($decrypt) {
|
904 |
-
case '3des-cbc':
|
905 |
-
case '3des-ctr':
|
906 |
-
$decryptKeyLength = 24; // eg. 192 / 8
|
907 |
-
break;
|
908 |
-
case 'aes256-cbc':
|
909 |
-
case 'aes256-ctr':
|
910 |
-
$decryptKeyLength = 32; // eg. 256 / 8
|
911 |
-
break;
|
912 |
-
case 'aes192-cbc':
|
913 |
-
case 'aes192-ctr':
|
914 |
-
$decryptKeyLength = 24; // eg. 192 / 8
|
915 |
-
break;
|
916 |
-
case 'aes128-cbc':
|
917 |
-
case 'aes128-ctr':
|
918 |
-
$decryptKeyLength = 16; // eg. 128 / 8
|
919 |
-
break;
|
920 |
-
case 'arcfour':
|
921 |
-
case 'arcfour128':
|
922 |
-
$decryptKeyLength = 16; // eg. 128 / 8
|
923 |
-
break;
|
924 |
-
case 'arcfour256':
|
925 |
-
$decryptKeyLength = 32; // eg. 128 / 8
|
926 |
-
break;
|
927 |
-
case 'none';
|
928 |
-
$decryptKeyLength = 0;
|
929 |
-
}
|
930 |
-
|
931 |
-
for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_client_to_server); $i++);
|
932 |
-
if ($i == count($encryption_algorithms)) {
|
933 |
-
user_error('No compatible client to server encryption algorithms found', E_USER_NOTICE);
|
934 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
935 |
-
}
|
936 |
-
|
937 |
-
$encrypt = $encryption_algorithms[$i];
|
938 |
-
switch ($encrypt) {
|
939 |
-
case '3des-cbc':
|
940 |
-
case '3des-ctr':
|
941 |
-
$encryptKeyLength = 24;
|
942 |
-
break;
|
943 |
-
case 'aes256-cbc':
|
944 |
-
case 'aes256-ctr':
|
945 |
-
$encryptKeyLength = 32;
|
946 |
-
break;
|
947 |
-
case 'aes192-cbc':
|
948 |
-
case 'aes192-ctr':
|
949 |
-
$encryptKeyLength = 24;
|
950 |
-
break;
|
951 |
-
case 'aes128-cbc':
|
952 |
-
case 'aes128-ctr':
|
953 |
-
$encryptKeyLength = 16;
|
954 |
-
break;
|
955 |
-
case 'arcfour':
|
956 |
-
case 'arcfour128':
|
957 |
-
$encryptKeyLength = 16;
|
958 |
-
break;
|
959 |
-
case 'arcfour256':
|
960 |
-
$encryptKeyLength = 32;
|
961 |
-
break;
|
962 |
-
case 'none';
|
963 |
-
$encryptKeyLength = 0;
|
964 |
-
}
|
965 |
-
|
966 |
-
$keyLength = $decryptKeyLength > $encryptKeyLength ? $decryptKeyLength : $encryptKeyLength;
|
967 |
-
|
968 |
-
// through diffie-hellman key exchange a symmetric key is obtained
|
969 |
-
for ($i = 0; $i < count($kex_algorithms) && !in_array($kex_algorithms[$i], $this->kex_algorithms); $i++);
|
970 |
-
if ($i == count($kex_algorithms)) {
|
971 |
-
user_error('No compatible key exchange algorithms found', E_USER_NOTICE);
|
972 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
973 |
-
}
|
974 |
-
|
975 |
-
switch ($kex_algorithms[$i]) {
|
976 |
-
// see http://tools.ietf.org/html/rfc2409#section-6.2 and
|
977 |
-
// http://tools.ietf.org/html/rfc2412, appendex E
|
978 |
-
case 'diffie-hellman-group1-sha1':
|
979 |
-
$p = pack('H256', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
|
980 |
-
'020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
|
981 |
-
'4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
|
982 |
-
'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF');
|
983 |
-
$keyLength = $keyLength < 160 ? $keyLength : 160;
|
984 |
-
$hash = 'sha1';
|
985 |
-
break;
|
986 |
-
// see http://tools.ietf.org/html/rfc3526#section-3
|
987 |
-
case 'diffie-hellman-group14-sha1':
|
988 |
-
$p = pack('H512', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
|
989 |
-
'020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
|
990 |
-
'4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
|
991 |
-
'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' .
|
992 |
-
'98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' .
|
993 |
-
'9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
|
994 |
-
'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' .
|
995 |
-
'3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF');
|
996 |
-
$keyLength = $keyLength < 160 ? $keyLength : 160;
|
997 |
-
$hash = 'sha1';
|
998 |
-
}
|
999 |
-
|
1000 |
-
$p = new Math_BigInteger($p, 256);
|
1001 |
-
//$q = $p->bitwise_rightShift(1);
|
1002 |
-
|
1003 |
-
/* To increase the speed of the key exchange, both client and server may
|
1004 |
-
reduce the size of their private exponents. It should be at least
|
1005 |
-
twice as long as the key material that is generated from the shared
|
1006 |
-
secret. For more details, see the paper by van Oorschot and Wiener
|
1007 |
-
[VAN-OORSCHOT].
|
1008 |
-
|
1009 |
-
-- http://tools.ietf.org/html/rfc4419#section-6.2 */
|
1010 |
-
$q = new Math_BigInteger(1);
|
1011 |
-
$q = $q->bitwise_leftShift(2 * $keyLength);
|
1012 |
-
$q = $q->subtract(new Math_BigInteger(1));
|
1013 |
-
|
1014 |
-
$g = new Math_BigInteger(2);
|
1015 |
-
$x = new Math_BigInteger();
|
1016 |
-
$x->setRandomGenerator('crypt_random');
|
1017 |
-
$x = $x->random(new Math_BigInteger(1), $q);
|
1018 |
-
$e = $g->modPow($x, $p);
|
1019 |
-
|
1020 |
-
$eBytes = $e->toBytes(true);
|
1021 |
-
$data = pack('CNa*', NET_SSH2_MSG_KEXDH_INIT, strlen($eBytes), $eBytes);
|
1022 |
-
|
1023 |
-
if (!$this->_send_binary_packet($data)) {
|
1024 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1025 |
-
return false;
|
1026 |
-
}
|
1027 |
-
|
1028 |
-
$response = $this->_get_binary_packet();
|
1029 |
-
if ($response === false) {
|
1030 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1031 |
-
return false;
|
1032 |
-
}
|
1033 |
-
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
1034 |
-
|
1035 |
-
if ($type != NET_SSH2_MSG_KEXDH_REPLY) {
|
1036 |
-
user_error('Expected SSH_MSG_KEXDH_REPLY', E_USER_NOTICE);
|
1037 |
-
return false;
|
1038 |
-
}
|
1039 |
-
|
1040 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
1041 |
-
$this->server_public_host_key = $server_public_host_key = $this->_string_shift($response, $temp['length']);
|
1042 |
-
|
1043 |
-
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
1044 |
-
$public_key_format = $this->_string_shift($server_public_host_key, $temp['length']);
|
1045 |
-
|
1046 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
1047 |
-
$fBytes = $this->_string_shift($response, $temp['length']);
|
1048 |
-
$f = new Math_BigInteger($fBytes, -256);
|
1049 |
-
|
1050 |
-
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
1051 |
-
$this->signature = $this->_string_shift($response, $temp['length']);
|
1052 |
-
|
1053 |
-
$temp = unpack('Nlength', $this->_string_shift($this->signature, 4));
|
1054 |
-
$this->signature_format = $this->_string_shift($this->signature, $temp['length']);
|
1055 |
-
|
1056 |
-
$key = $f->modPow($x, $p);
|
1057 |
-
$keyBytes = $key->toBytes(true);
|
1058 |
-
|
1059 |
-
$this->exchange_hash = pack('Na*Na*Na*Na*Na*Na*Na*Na*',
|
1060 |
-
strlen($this->identifier), $this->identifier, strlen($this->server_identifier), $this->server_identifier,
|
1061 |
-
strlen($kexinit_payload_client), $kexinit_payload_client, strlen($kexinit_payload_server),
|
1062 |
-
$kexinit_payload_server, strlen($this->server_public_host_key), $this->server_public_host_key, strlen($eBytes),
|
1063 |
-
$eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes
|
1064 |
-
);
|
1065 |
-
|
1066 |
-
$this->exchange_hash = pack('H*', $hash($this->exchange_hash));
|
1067 |
-
|
1068 |
-
if ($this->session_id === false) {
|
1069 |
-
$this->session_id = $this->exchange_hash;
|
1070 |
-
}
|
1071 |
-
|
1072 |
-
for ($i = 0; $i < count($server_host_key_algorithms) && !in_array($server_host_key_algorithms[$i], $this->server_host_key_algorithms); $i++);
|
1073 |
-
if ($i == count($server_host_key_algorithms)) {
|
1074 |
-
user_error('No compatible server host key algorithms found', E_USER_NOTICE);
|
1075 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1076 |
-
}
|
1077 |
-
|
1078 |
-
if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) {
|
1079 |
-
user_error('Sever Host Key Algorithm Mismatch', E_USER_NOTICE);
|
1080 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1081 |
-
}
|
1082 |
-
|
1083 |
-
$packet = pack('C',
|
1084 |
-
NET_SSH2_MSG_NEWKEYS
|
1085 |
-
);
|
1086 |
-
|
1087 |
-
if (!$this->_send_binary_packet($packet)) {
|
1088 |
-
return false;
|
1089 |
-
}
|
1090 |
-
|
1091 |
-
$response = $this->_get_binary_packet();
|
1092 |
-
|
1093 |
-
if ($response === false) {
|
1094 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1095 |
-
return false;
|
1096 |
-
}
|
1097 |
-
|
1098 |
-
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
1099 |
-
|
1100 |
-
if ($type != NET_SSH2_MSG_NEWKEYS) {
|
1101 |
-
user_error('Expected SSH_MSG_NEWKEYS', E_USER_NOTICE);
|
1102 |
-
return false;
|
1103 |
-
}
|
1104 |
-
|
1105 |
-
switch ($encrypt) {
|
1106 |
-
case '3des-cbc':
|
1107 |
-
$this->encrypt = new Crypt_TripleDES();
|
1108 |
-
// $this->encrypt_block_size = 64 / 8 == the default
|
1109 |
-
break;
|
1110 |
-
case '3des-ctr':
|
1111 |
-
$this->encrypt = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
1112 |
-
// $this->encrypt_block_size = 64 / 8 == the default
|
1113 |
-
break;
|
1114 |
-
case 'aes256-cbc':
|
1115 |
-
case 'aes192-cbc':
|
1116 |
-
case 'aes128-cbc':
|
1117 |
-
$this->encrypt = new Crypt_AES();
|
1118 |
-
$this->encrypt_block_size = 16; // eg. 128 / 8
|
1119 |
-
break;
|
1120 |
-
case 'aes256-ctr':
|
1121 |
-
case 'aes192-ctr':
|
1122 |
-
case 'aes128-ctr':
|
1123 |
-
$this->encrypt = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
1124 |
-
$this->encrypt_block_size = 16; // eg. 128 / 8
|
1125 |
-
break;
|
1126 |
-
case 'arcfour':
|
1127 |
-
case 'arcfour128':
|
1128 |
-
case 'arcfour256':
|
1129 |
-
$this->encrypt = new Crypt_RC4();
|
1130 |
-
break;
|
1131 |
-
case 'none';
|
1132 |
-
//$this->encrypt = new Crypt_Null();
|
1133 |
-
}
|
1134 |
-
|
1135 |
-
switch ($decrypt) {
|
1136 |
-
case '3des-cbc':
|
1137 |
-
$this->decrypt = new Crypt_TripleDES();
|
1138 |
-
break;
|
1139 |
-
case '3des-ctr':
|
1140 |
-
$this->decrypt = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
1141 |
-
break;
|
1142 |
-
case 'aes256-cbc':
|
1143 |
-
case 'aes192-cbc':
|
1144 |
-
case 'aes128-cbc':
|
1145 |
-
$this->decrypt = new Crypt_AES();
|
1146 |
-
$this->decrypt_block_size = 16;
|
1147 |
-
break;
|
1148 |
-
case 'aes256-ctr':
|
1149 |
-
case 'aes192-ctr':
|
1150 |
-
case 'aes128-ctr':
|
1151 |
-
$this->decrypt = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
1152 |
-
$this->decrypt_block_size = 16;
|
1153 |
-
break;
|
1154 |
-
case 'arcfour':
|
1155 |
-
case 'arcfour128':
|
1156 |
-
case 'arcfour256':
|
1157 |
-
$this->decrypt = new Crypt_RC4();
|
1158 |
-
break;
|
1159 |
-
case 'none';
|
1160 |
-
//$this->decrypt = new Crypt_Null();
|
1161 |
-
}
|
1162 |
-
|
1163 |
-
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
|
1164 |
-
|
1165 |
-
if ($this->encrypt) {
|
1166 |
-
$this->encrypt->enableContinuousBuffer();
|
1167 |
-
$this->encrypt->disablePadding();
|
1168 |
-
|
1169 |
-
$iv = pack('H*', $hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id));
|
1170 |
-
while ($this->encrypt_block_size > strlen($iv)) {
|
1171 |
-
$iv.= pack('H*', $hash($keyBytes . $this->exchange_hash . $iv));
|
1172 |
-
}
|
1173 |
-
$this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
|
1174 |
-
|
1175 |
-
$key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id));
|
1176 |
-
while ($encryptKeyLength > strlen($key)) {
|
1177 |
-
$key.= pack('H*', $hash($keyBytes . $this->exchange_hash . $key));
|
1178 |
-
}
|
1179 |
-
$this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
|
1180 |
-
}
|
1181 |
-
|
1182 |
-
if ($this->decrypt) {
|
1183 |
-
$this->decrypt->enableContinuousBuffer();
|
1184 |
-
$this->decrypt->disablePadding();
|
1185 |
-
|
1186 |
-
$iv = pack('H*', $hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id));
|
1187 |
-
while ($this->decrypt_block_size > strlen($iv)) {
|
1188 |
-
$iv.= pack('H*', $hash($keyBytes . $this->exchange_hash . $iv));
|
1189 |
-
}
|
1190 |
-
$this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
|
1191 |
-
|
1192 |
-
$key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id));
|
1193 |
-
while ($decryptKeyLength > strlen($key)) {
|
1194 |
-
$key.= pack('H*', $hash($keyBytes . $this->exchange_hash . $key));
|
1195 |
-
}
|
1196 |
-
$this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
|
1197 |
-
}
|
1198 |
-
|
1199 |
-
/* The "arcfour128" algorithm is the RC4 cipher, as described in
|
1200 |
-
[SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream
|
1201 |
-
generated by the cipher MUST be discarded, and the first byte of the
|
1202 |
-
first encrypted packet MUST be encrypted using the 1537th byte of
|
1203 |
-
keystream.
|
1204 |
-
|
1205 |
-
-- http://tools.ietf.org/html/rfc4345#section-4 */
|
1206 |
-
if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') {
|
1207 |
-
$this->encrypt->encrypt(str_repeat("\0", 1536));
|
1208 |
-
}
|
1209 |
-
if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') {
|
1210 |
-
$this->decrypt->decrypt(str_repeat("\0", 1536));
|
1211 |
-
}
|
1212 |
-
|
1213 |
-
for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++);
|
1214 |
-
if ($i == count($mac_algorithms)) {
|
1215 |
-
user_error('No compatible client to server message authentication algorithms found', E_USER_NOTICE);
|
1216 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1217 |
-
}
|
1218 |
-
|
1219 |
-
$createKeyLength = 0; // ie. $mac_algorithms[$i] == 'none'
|
1220 |
-
switch ($mac_algorithms[$i]) {
|
1221 |
-
case 'hmac-sha1':
|
1222 |
-
$this->hmac_create = new Crypt_Hash('sha1');
|
1223 |
-
$createKeyLength = 20;
|
1224 |
-
break;
|
1225 |
-
case 'hmac-sha1-96':
|
1226 |
-
$this->hmac_create = new Crypt_Hash('sha1-96');
|
1227 |
-
$createKeyLength = 20;
|
1228 |
-
break;
|
1229 |
-
case 'hmac-md5':
|
1230 |
-
$this->hmac_create = new Crypt_Hash('md5');
|
1231 |
-
$createKeyLength = 16;
|
1232 |
-
break;
|
1233 |
-
case 'hmac-md5-96':
|
1234 |
-
$this->hmac_create = new Crypt_Hash('md5-96');
|
1235 |
-
$createKeyLength = 16;
|
1236 |
-
}
|
1237 |
-
|
1238 |
-
for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_server_to_client); $i++);
|
1239 |
-
if ($i == count($mac_algorithms)) {
|
1240 |
-
user_error('No compatible server to client message authentication algorithms found', E_USER_NOTICE);
|
1241 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1242 |
-
}
|
1243 |
-
|
1244 |
-
$checkKeyLength = 0;
|
1245 |
-
$this->hmac_size = 0;
|
1246 |
-
switch ($mac_algorithms[$i]) {
|
1247 |
-
case 'hmac-sha1':
|
1248 |
-
$this->hmac_check = new Crypt_Hash('sha1');
|
1249 |
-
$checkKeyLength = 20;
|
1250 |
-
$this->hmac_size = 20;
|
1251 |
-
break;
|
1252 |
-
case 'hmac-sha1-96':
|
1253 |
-
$this->hmac_check = new Crypt_Hash('sha1-96');
|
1254 |
-
$checkKeyLength = 20;
|
1255 |
-
$this->hmac_size = 12;
|
1256 |
-
break;
|
1257 |
-
case 'hmac-md5':
|
1258 |
-
$this->hmac_check = new Crypt_Hash('md5');
|
1259 |
-
$checkKeyLength = 16;
|
1260 |
-
$this->hmac_size = 16;
|
1261 |
-
break;
|
1262 |
-
case 'hmac-md5-96':
|
1263 |
-
$this->hmac_check = new Crypt_Hash('md5-96');
|
1264 |
-
$checkKeyLength = 16;
|
1265 |
-
$this->hmac_size = 12;
|
1266 |
-
}
|
1267 |
-
|
1268 |
-
$key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id));
|
1269 |
-
while ($createKeyLength > strlen($key)) {
|
1270 |
-
$key.= pack('H*', $hash($keyBytes . $this->exchange_hash . $key));
|
1271 |
-
}
|
1272 |
-
$this->hmac_create->setKey(substr($key, 0, $createKeyLength));
|
1273 |
-
|
1274 |
-
$key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id));
|
1275 |
-
while ($checkKeyLength > strlen($key)) {
|
1276 |
-
$key.= pack('H*', $hash($keyBytes . $this->exchange_hash . $key));
|
1277 |
-
}
|
1278 |
-
$this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
|
1279 |
-
|
1280 |
-
for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_server_to_client); $i++);
|
1281 |
-
if ($i == count($compression_algorithms)) {
|
1282 |
-
user_error('No compatible server to client compression algorithms found', E_USER_NOTICE);
|
1283 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1284 |
-
}
|
1285 |
-
$this->decompress = $compression_algorithms[$i] == 'zlib';
|
1286 |
-
|
1287 |
-
for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_client_to_server); $i++);
|
1288 |
-
if ($i == count($compression_algorithms)) {
|
1289 |
-
user_error('No compatible client to server compression algorithms found', E_USER_NOTICE);
|
1290 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1291 |
-
}
|
1292 |
-
$this->compress = $compression_algorithms[$i] == 'zlib';
|
1293 |
-
|
1294 |
-
return true;
|
1295 |
-
}
|
1296 |
-
|
1297 |
-
/**
|
1298 |
-
* Login
|
1299 |
-
*
|
1300 |
-
* The $password parameter can be a plaintext password or a Crypt_RSA object.
|
1301 |
-
*
|
1302 |
-
* @param String $username
|
1303 |
-
* @param optional String $password
|
1304 |
-
* @return Boolean
|
1305 |
-
* @access public
|
1306 |
-
* @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
|
1307 |
-
* by sending dummy SSH_MSG_IGNORE messages.
|
1308 |
-
*/
|
1309 |
-
function login($username, $password = '')
|
1310 |
-
{
|
1311 |
-
if (!($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR)) {
|
1312 |
-
return false;
|
1313 |
-
}
|
1314 |
-
|
1315 |
-
$packet = pack('CNa*',
|
1316 |
-
NET_SSH2_MSG_SERVICE_REQUEST, strlen('ssh-userauth'), 'ssh-userauth'
|
1317 |
-
);
|
1318 |
-
|
1319 |
-
if (!$this->_send_binary_packet($packet)) {
|
1320 |
-
return false;
|
1321 |
-
}
|
1322 |
-
|
1323 |
-
$response = $this->_get_binary_packet();
|
1324 |
-
if ($response === false) {
|
1325 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1326 |
-
return false;
|
1327 |
-
}
|
1328 |
-
|
1329 |
-
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
1330 |
-
|
1331 |
-
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
|
1332 |
-
user_error('Expected SSH_MSG_SERVICE_ACCEPT', E_USER_NOTICE);
|
1333 |
-
return false;
|
1334 |
-
}
|
1335 |
-
|
1336 |
-
// although PHP5's get_class() preserves the case, PHP4's does not
|
1337 |
-
if (is_object($password) && strtolower(get_class($password)) == 'crypt_rsa') {
|
1338 |
-
return $this->_privatekey_login($username, $password);
|
1339 |
-
}
|
1340 |
-
|
1341 |
-
$utf8_password = utf8_encode($password);
|
1342 |
-
$packet = pack('CNa*Na*Na*CNa*',
|
1343 |
-
NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
|
1344 |
-
strlen('password'), 'password', 0, strlen($utf8_password), $utf8_password
|
1345 |
-
);
|
1346 |
-
|
1347 |
-
if (!$this->_send_binary_packet($packet)) {
|
1348 |
-
return false;
|
1349 |
-
}
|
1350 |
-
|
1351 |
-
// remove the username and password from the last logged packet
|
1352 |
-
if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {
|
1353 |
-
$packet = pack('CNa*Na*Na*CNa*',
|
1354 |
-
NET_SSH2_MSG_USERAUTH_REQUEST, strlen('username'), 'username', strlen('ssh-connection'), 'ssh-connection',
|
1355 |
-
strlen('password'), 'password', 0, strlen('password'), 'password'
|
1356 |
-
);
|
1357 |
-
$this->message_log[count($this->message_log) - 1] = $packet;
|
1358 |
-
}
|
1359 |
-
|
1360 |
-
$response = $this->_get_binary_packet();
|
1361 |
-
if ($response === false) {
|
1362 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1363 |
-
return false;
|
1364 |
-
}
|
1365 |
-
|
1366 |
-
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
1367 |
-
|
1368 |
-
switch ($type) {
|
1369 |
-
case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed
|
1370 |
-
if (defined('NET_SSH2_LOGGING')) {
|
1371 |
-
$this->message_number_log[count($this->message_number_log) - 1] = 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ';
|
1372 |
-
}
|
1373 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1374 |
-
$this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . utf8_decode($this->_string_shift($response, $length));
|
1375 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
|
1376 |
-
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
1377 |
-
// can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
|
1378 |
-
// multi-factor authentication
|
1379 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1380 |
-
$auth_methods = explode(',', $this->_string_shift($response, $length));
|
1381 |
-
if (in_array('keyboard-interactive', $auth_methods)) {
|
1382 |
-
if ($this->_keyboard_interactive_login($username, $password)) {
|
1383 |
-
$this->bitmap |= NET_SSH2_MASK_LOGIN;
|
1384 |
-
return true;
|
1385 |
-
}
|
1386 |
-
return false;
|
1387 |
-
}
|
1388 |
-
return false;
|
1389 |
-
case NET_SSH2_MSG_USERAUTH_SUCCESS:
|
1390 |
-
$this->bitmap |= NET_SSH2_MASK_LOGIN;
|
1391 |
-
return true;
|
1392 |
-
}
|
1393 |
-
|
1394 |
-
return false;
|
1395 |
-
}
|
1396 |
-
|
1397 |
-
/**
|
1398 |
-
* Login via keyboard-interactive authentication
|
1399 |
-
*
|
1400 |
-
* See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator.
|
1401 |
-
*
|
1402 |
-
* @param String $username
|
1403 |
-
* @param String $password
|
1404 |
-
* @return Boolean
|
1405 |
-
* @access private
|
1406 |
-
*/
|
1407 |
-
function _keyboard_interactive_login($username, $password)
|
1408 |
-
{
|
1409 |
-
$packet = pack('CNa*Na*Na*Na*Na*',
|
1410 |
-
NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
|
1411 |
-
strlen('keyboard-interactive'), 'keyboard-interactive', 0, '', 0, ''
|
1412 |
-
);
|
1413 |
-
|
1414 |
-
if (!$this->_send_binary_packet($packet)) {
|
1415 |
-
return false;
|
1416 |
-
}
|
1417 |
-
|
1418 |
-
return $this->_keyboard_interactive_process($password);
|
1419 |
-
}
|
1420 |
-
|
1421 |
-
/**
|
1422 |
-
* Handle the keyboard-interactive requests / responses.
|
1423 |
-
*
|
1424 |
-
* @param String $responses...
|
1425 |
-
* @return Boolean
|
1426 |
-
* @access private
|
1427 |
-
*/
|
1428 |
-
function _keyboard_interactive_process()
|
1429 |
-
{
|
1430 |
-
$responses = func_get_args();
|
1431 |
-
|
1432 |
-
$response = $this->_get_binary_packet();
|
1433 |
-
if ($response === false) {
|
1434 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1435 |
-
return false;
|
1436 |
-
}
|
1437 |
-
|
1438 |
-
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
1439 |
-
|
1440 |
-
switch ($type) {
|
1441 |
-
case NET_SSH2_MSG_USERAUTH_INFO_REQUEST:
|
1442 |
-
// see http://tools.ietf.org/html/rfc4256#section-3.2
|
1443 |
-
if (defined('NET_SSH2_LOGGING')) {
|
1444 |
-
$this->message_number_log[count($this->message_number_log) - 1] = str_replace(
|
1445 |
-
'UNKNOWN',
|
1446 |
-
'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
|
1447 |
-
$this->message_number_log[count($this->message_number_log) - 1]
|
1448 |
-
);
|
1449 |
-
}
|
1450 |
-
|
1451 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1452 |
-
$this->_string_shift($response, $length); // name; may be empty
|
1453 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1454 |
-
$this->_string_shift($response, $length); // instruction; may be empty
|
1455 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1456 |
-
$this->_string_shift($response, $length); // language tag; may be empty
|
1457 |
-
extract(unpack('Nnum_prompts', $this->_string_shift($response, 4)));
|
1458 |
-
/*
|
1459 |
-
for ($i = 0; $i < $num_prompts; $i++) {
|
1460 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1461 |
-
// prompt - ie. "Password: "; must not be empty
|
1462 |
-
$this->_string_shift($response, $length);
|
1463 |
-
$echo = $this->_string_shift($response) != chr(0);
|
1464 |
-
}
|
1465 |
-
*/
|
1466 |
-
|
1467 |
-
/*
|
1468 |
-
After obtaining the requested information from the user, the client
|
1469 |
-
MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message.
|
1470 |
-
*/
|
1471 |
-
// see http://tools.ietf.org/html/rfc4256#section-3.4
|
1472 |
-
$packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses));
|
1473 |
-
for ($i = 0; $i < count($responses); $i++) {
|
1474 |
-
$packet.= pack('Na*', strlen($responses[$i]), $responses[$i]);
|
1475 |
-
$logged.= pack('Na*', strlen('dummy-answer'), 'dummy-answer');
|
1476 |
-
}
|
1477 |
-
|
1478 |
-
if (!$this->_send_binary_packet($packet)) {
|
1479 |
-
return false;
|
1480 |
-
}
|
1481 |
-
|
1482 |
-
if (defined('NET_SSH2_LOGGING')) {
|
1483 |
-
$this->message_number_log[count($this->message_number_log) - 1] = str_replace(
|
1484 |
-
'UNKNOWN',
|
1485 |
-
'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE',
|
1486 |
-
$this->message_number_log[count($this->message_number_log) - 1]
|
1487 |
-
);
|
1488 |
-
$this->message_log[count($this->message_log) - 1] = $logged;
|
1489 |
-
}
|
1490 |
-
|
1491 |
-
/*
|
1492 |
-
After receiving the response, the server MUST send either an
|
1493 |
-
SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another
|
1494 |
-
SSH_MSG_USERAUTH_INFO_REQUEST message.
|
1495 |
-
*/
|
1496 |
-
// maybe phpseclib should force close the connection after x request / responses? unless something like that is done
|
1497 |
-
// there could be an infinite loop of request / responses.
|
1498 |
-
return $this->_keyboard_interactive_process();
|
1499 |
-
case NET_SSH2_MSG_USERAUTH_SUCCESS:
|
1500 |
-
return true;
|
1501 |
-
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
1502 |
-
return false;
|
1503 |
-
}
|
1504 |
-
|
1505 |
-
return false;
|
1506 |
-
}
|
1507 |
-
|
1508 |
-
/**
|
1509 |
-
* Login with an RSA private key
|
1510 |
-
*
|
1511 |
-
* @param String $username
|
1512 |
-
* @param Crypt_RSA $password
|
1513 |
-
* @return Boolean
|
1514 |
-
* @access private
|
1515 |
-
* @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
|
1516 |
-
* by sending dummy SSH_MSG_IGNORE messages.
|
1517 |
-
*/
|
1518 |
-
function _privatekey_login($username, $privatekey)
|
1519 |
-
{
|
1520 |
-
// see http://tools.ietf.org/html/rfc4253#page-15
|
1521 |
-
$publickey = $privatekey->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_RAW);
|
1522 |
-
if ($publickey === false) {
|
1523 |
-
return false;
|
1524 |
-
}
|
1525 |
-
|
1526 |
-
$publickey = array(
|
1527 |
-
'e' => $publickey['e']->toBytes(true),
|
1528 |
-
'n' => $publickey['n']->toBytes(true)
|
1529 |
-
);
|
1530 |
-
$publickey = pack('Na*Na*Na*',
|
1531 |
-
strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey['e']), $publickey['e'], strlen($publickey['n']), $publickey['n']
|
1532 |
-
);
|
1533 |
-
|
1534 |
-
$part1 = pack('CNa*Na*Na*',
|
1535 |
-
NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
|
1536 |
-
strlen('publickey'), 'publickey'
|
1537 |
-
);
|
1538 |
-
$part2 = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey), $publickey);
|
1539 |
-
|
1540 |
-
$packet = $part1 . chr(0) . $part2;
|
1541 |
-
if (!$this->_send_binary_packet($packet)) {
|
1542 |
-
return false;
|
1543 |
-
}
|
1544 |
-
|
1545 |
-
$response = $this->_get_binary_packet();
|
1546 |
-
if ($response === false) {
|
1547 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1548 |
-
return false;
|
1549 |
-
}
|
1550 |
-
|
1551 |
-
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
1552 |
-
|
1553 |
-
switch ($type) {
|
1554 |
-
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
1555 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
1556 |
-
$this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $this->_string_shift($response, $length);
|
1557 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
|
1558 |
-
case NET_SSH2_MSG_USERAUTH_PK_OK:
|
1559 |
-
// we'll just take it on faith that the public key blob and the public key algorithm name are as
|
1560 |
-
// they should be
|
1561 |
-
if (defined('NET_SSH2_LOGGING')) {
|
1562 |
-
$this->message_number_log[count($this->message_number_log) - 1] = str_replace(
|
1563 |
-
'UNKNOWN',
|
1564 |
-
'NET_SSH2_MSG_USERAUTH_PK_OK',
|
1565 |
-
$this->message_number_log[count($this->message_number_log) - 1]
|
1566 |
-
);
|
1567 |
-
}
|
1568 |
-
}
|
1569 |
-
|
1570 |
-
$packet = $part1 . chr(1) . $part2;
|
1571 |
-
$privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
1572 |
-
$signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
|
1573 |
-
$signature = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($signature), $signature);
|
1574 |
-
$packet.= pack('Na*', strlen($signature), $signature);
|
1575 |
-
|
1576 |
-
if (!$this->_send_binary_packet($packet)) {
|
1577 |
-
return false;
|
1578 |
-
}
|
1579 |
-
|
1580 |
-
$response = $this->_get_binary_packet();
|
1581 |
-
if ($response === false) {
|
1582 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1583 |
-
return false;
|
1584 |
-
}
|
1585 |
-
|
1586 |
-
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
1587 |
-
|
1588 |
-
switch ($type) {
|
1589 |
-
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
1590 |
-
// either the login is bad or the server employees multi-factor authentication
|
1591 |
-
return false;
|
1592 |
-
case NET_SSH2_MSG_USERAUTH_SUCCESS:
|
1593 |
-
$this->bitmap |= NET_SSH2_MASK_LOGIN;
|
1594 |
-
return true;
|
1595 |
-
}
|
1596 |
-
|
1597 |
-
return false;
|
1598 |
-
}
|
1599 |
-
|
1600 |
-
/**
|
1601 |
-
* Execute Command
|
1602 |
-
*
|
1603 |
-
* If $block is set to false then Net_SSH2::_get_channel_packet(NET_SSH2_CHANNEL_EXEC) will need to be called manually.
|
1604 |
-
* In all likelihood, this is not a feature you want to be taking advantage of.
|
1605 |
-
*
|
1606 |
-
* @param String $command
|
1607 |
-
* @param optional Boolean $block
|
1608 |
-
* @return String
|
1609 |
-
* @access public
|
1610 |
-
*/
|
1611 |
-
function exec($command, $block = true)
|
1612 |
-
{
|
1613 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
1614 |
-
return false;
|
1615 |
-
}
|
1616 |
-
|
1617 |
-
// RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to
|
1618 |
-
// be adjusted". 0x7FFFFFFF is, at 4GB, the max size. technically, it should probably be decremented, but,
|
1619 |
-
// honestly, if you're transfering more than 4GB, you probably shouldn't be using phpseclib, anyway.
|
1620 |
-
// see http://tools.ietf.org/html/rfc4254#section-5.2 for more info
|
1621 |
-
$this->window_size_client_to_server[NET_SSH2_CHANNEL_EXEC] = 0x7FFFFFFF;
|
1622 |
-
// 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy
|
1623 |
-
// uses 0x4000, that's what will be used here, as well.
|
1624 |
-
$packet_size = 0x4000;
|
1625 |
-
|
1626 |
-
$packet = pack('CNa*N3',
|
1627 |
-
NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SSH2_CHANNEL_EXEC, $this->window_size_client_to_server[NET_SSH2_CHANNEL_EXEC], $packet_size);
|
1628 |
-
|
1629 |
-
if (!$this->_send_binary_packet($packet)) {
|
1630 |
-
return false;
|
1631 |
-
}
|
1632 |
-
|
1633 |
-
$this->channel_status[NET_SSH2_CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_OPEN;
|
1634 |
-
|
1635 |
-
$response = $this->_get_channel_packet(NET_SSH2_CHANNEL_EXEC);
|
1636 |
-
if ($response === false) {
|
1637 |
-
return false;
|
1638 |
-
}
|
1639 |
-
|
1640 |
-
// sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things
|
1641 |
-
// down. the one place where it might be desirable is if you're doing something like Net_SSH2::exec('ping localhost &').
|
1642 |
-
// with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then
|
1643 |
-
// then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but
|
1644 |
-
// neither will your script.
|
1645 |
-
|
1646 |
-
// although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by
|
1647 |
-
// SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the
|
1648 |
-
// "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates.
|
1649 |
-
$packet = pack('CNNa*CNa*',
|
1650 |
-
NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_EXEC], strlen('exec'), 'exec', 1, strlen($command), $command);
|
1651 |
-
if (!$this->_send_binary_packet($packet)) {
|
1652 |
-
return false;
|
1653 |
-
}
|
1654 |
-
|
1655 |
-
$this->channel_status[NET_SSH2_CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
1656 |
-
|
1657 |
-
$response = $this->_get_channel_packet(NET_SSH2_CHANNEL_EXEC);
|
1658 |
-
if ($response === false) {
|
1659 |
-
return false;
|
1660 |
-
}
|
1661 |
-
|
1662 |
-
$this->channel_status[NET_SSH2_CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA;
|
1663 |
-
|
1664 |
-
if (!$block) {
|
1665 |
-
return true;
|
1666 |
-
}
|
1667 |
-
|
1668 |
-
$output = '';
|
1669 |
-
while (true) {
|
1670 |
-
$temp = $this->_get_channel_packet(NET_SSH2_CHANNEL_EXEC);
|
1671 |
-
switch (true) {
|
1672 |
-
case $temp === true:
|
1673 |
-
return $output;
|
1674 |
-
case $temp === false:
|
1675 |
-
return false;
|
1676 |
-
default:
|
1677 |
-
$output.= $temp;
|
1678 |
-
}
|
1679 |
-
}
|
1680 |
-
}
|
1681 |
-
|
1682 |
-
/**
|
1683 |
-
* Creates an interactive shell
|
1684 |
-
*
|
1685 |
-
* @see Net_SSH2::read()
|
1686 |
-
* @see Net_SSH2::write()
|
1687 |
-
* @return Boolean
|
1688 |
-
* @access private
|
1689 |
-
*/
|
1690 |
-
function _initShell()
|
1691 |
-
{
|
1692 |
-
$this->window_size_client_to_server[NET_SSH2_CHANNEL_SHELL] = 0x7FFFFFFF;
|
1693 |
-
$packet_size = 0x4000;
|
1694 |
-
|
1695 |
-
$packet = pack('CNa*N3',
|
1696 |
-
NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SSH2_CHANNEL_SHELL, $this->window_size_client_to_server[NET_SSH2_CHANNEL_SHELL], $packet_size);
|
1697 |
-
|
1698 |
-
if (!$this->_send_binary_packet($packet)) {
|
1699 |
-
return false;
|
1700 |
-
}
|
1701 |
-
|
1702 |
-
$this->channel_status[NET_SSH2_CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_OPEN;
|
1703 |
-
|
1704 |
-
$response = $this->_get_channel_packet(NET_SSH2_CHANNEL_SHELL);
|
1705 |
-
if ($response === false) {
|
1706 |
-
return false;
|
1707 |
-
}
|
1708 |
-
|
1709 |
-
$terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
|
1710 |
-
$packet = pack('CNNa*CNa*N5a*',
|
1711 |
-
NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_SHELL], strlen('pty-req'), 'pty-req', 1, strlen('vt100'), 'vt100',
|
1712 |
-
80, 24, 0, 0, strlen($terminal_modes), $terminal_modes);
|
1713 |
-
|
1714 |
-
if (!$this->_send_binary_packet($packet)) {
|
1715 |
-
return false;
|
1716 |
-
}
|
1717 |
-
|
1718 |
-
|
1719 |
-
$response = $this->_get_binary_packet();
|
1720 |
-
if ($response === false) {
|
1721 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
1722 |
-
return false;
|
1723 |
-
}
|
1724 |
-
|
1725 |
-
list(, $type) = unpack('C', $this->_string_shift($response, 1));
|
1726 |
-
|
1727 |
-
switch ($type) {
|
1728 |
-
case NET_SSH2_MSG_CHANNEL_SUCCESS:
|
1729 |
-
break;
|
1730 |
-
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
1731 |
-
default:
|
1732 |
-
user_error('Unable to request pseudo-terminal', E_USER_NOTICE);
|
1733 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
1734 |
-
}
|
1735 |
-
|
1736 |
-
$packet = pack('CNNa*C',
|
1737 |
-
NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_SHELL], strlen('shell'), 'shell', 1);
|
1738 |
-
if (!$this->_send_binary_packet($packet)) {
|
1739 |
-
return false;
|
1740 |
-
}
|
1741 |
-
|
1742 |
-
$this->channel_status[NET_SSH2_CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
1743 |
-
|
1744 |
-
$response = $this->_get_channel_packet(NET_SSH2_CHANNEL_SHELL);
|
1745 |
-
if ($response === false) {
|
1746 |
-
return false;
|
1747 |
-
}
|
1748 |
-
|
1749 |
-
$this->channel_status[NET_SSH2_CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA;
|
1750 |
-
|
1751 |
-
$this->bitmap |= NET_SSH2_MASK_SHELL;
|
1752 |
-
|
1753 |
-
return true;
|
1754 |
-
}
|
1755 |
-
|
1756 |
-
/**
|
1757 |
-
* Returns the output of an interactive shell
|
1758 |
-
*
|
1759 |
-
* Returns when there's a match for $expect, which can take the form of a string literal or,
|
1760 |
-
* if $mode == NET_SSH2_READ_REGEX, a regular expression.
|
1761 |
-
*
|
1762 |
-
* @see Net_SSH2::read()
|
1763 |
-
* @param String $expect
|
1764 |
-
* @param Integer $mode
|
1765 |
-
* @return String
|
1766 |
-
* @access public
|
1767 |
-
*/
|
1768 |
-
function read($expect, $mode = NET_SSH2_READ_SIMPLE)
|
1769 |
-
{
|
1770 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
1771 |
-
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
1772 |
-
return false;
|
1773 |
-
}
|
1774 |
-
|
1775 |
-
if (!($this->bitmap & NET_SSH2_MASK_SHELL) && !$this->_initShell()) {
|
1776 |
-
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
1777 |
-
return false;
|
1778 |
-
}
|
1779 |
-
|
1780 |
-
$match = $expect;
|
1781 |
-
while (true) {
|
1782 |
-
if ($mode == NET_SSH2_READ_REGEX) {
|
1783 |
-
preg_match($expect, $this->interactiveBuffer, $matches);
|
1784 |
-
$match = $matches[0];
|
1785 |
-
}
|
1786 |
-
$pos = strpos($this->interactiveBuffer, $match);
|
1787 |
-
if ($pos !== false) {
|
1788 |
-
return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match));
|
1789 |
-
}
|
1790 |
-
$response = $this->_get_channel_packet(NET_SSH2_CHANNEL_SHELL);
|
1791 |
-
|
1792 |
-
$this->interactiveBuffer.= $response;
|
1793 |
-
}
|
1794 |
-
}
|
1795 |
-
|
1796 |
-
/**
|
1797 |
-
* Inputs a command into an interactive shell.
|
1798 |
-
*
|
1799 |
-
* @see Net_SSH1::interactiveWrite()
|
1800 |
-
* @param String $cmd
|
1801 |
-
* @return Boolean
|
1802 |
-
* @access public
|
1803 |
-
*/
|
1804 |
-
function write($cmd)
|
1805 |
-
{
|
1806 |
-
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
1807 |
-
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
1808 |
-
return false;
|
1809 |
-
}
|
1810 |
-
|
1811 |
-
if (!($this->bitmap & NET_SSH2_MASK_SHELL) && !$this->_initShell()) {
|
1812 |
-
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
1813 |
-
return false;
|
1814 |
-
}
|
1815 |
-
|
1816 |
-
return $this->_send_channel_packet(NET_SSH2_CHANNEL_SHELL, $cmd);
|
1817 |
-
}
|
1818 |
-
|
1819 |
-
/**
|
1820 |
-
* Disconnect
|
1821 |
-
*
|
1822 |
-
* @access public
|
1823 |
-
*/
|
1824 |
-
function disconnect()
|
1825 |
-
{
|
1826 |
-
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
1827 |
-
}
|
1828 |
-
|
1829 |
-
/**
|
1830 |
-
* Destructor.
|
1831 |
-
*
|
1832 |
-
* Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call
|
1833 |
-
* disconnect().
|
1834 |
-
*
|
1835 |
-
* @access public
|
1836 |
-
*/
|
1837 |
-
function __destruct()
|
1838 |
-
{
|
1839 |
-
$this->disconnect();
|
1840 |
-
}
|
1841 |
-
|
1842 |
-
/**
|
1843 |
-
* Gets Binary Packets
|
1844 |
-
*
|
1845 |
-
* See '6. Binary Packet Protocol' of rfc4253 for more info.
|
1846 |
-
*
|
1847 |
-
* @see Net_SSH2::_send_binary_packet()
|
1848 |
-
* @return String
|
1849 |
-
* @access private
|
1850 |
-
*/
|
1851 |
-
function _get_binary_packet()
|
1852 |
-
{
|
1853 |
-
if (feof($this->fsock)) {
|
1854 |
-
user_error('Connection closed prematurely', E_USER_NOTICE);
|
1855 |
-
return false;
|
1856 |
-
}
|
1857 |
-
|
1858 |
-
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
1859 |
-
$raw = fread($this->fsock, $this->decrypt_block_size);
|
1860 |
-
$stop = strtok(microtime(), ' ') + strtok('');
|
1861 |
-
|
1862 |
-
if (empty($raw)) {
|
1863 |
-
return '';
|
1864 |
-
}
|
1865 |
-
|
1866 |
-
if ($this->decrypt !== false) {
|
1867 |
-
$raw = $this->decrypt->decrypt($raw);
|
1868 |
-
}
|
1869 |
-
|
1870 |
-
extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5)));
|
1871 |
-
|
1872 |
-
$remaining_length = $packet_length + 4 - $this->decrypt_block_size;
|
1873 |
-
$buffer = '';
|
1874 |
-
while ($remaining_length > 0) {
|
1875 |
-
$temp = fread($this->fsock, $remaining_length);
|
1876 |
-
$buffer.= $temp;
|
1877 |
-
$remaining_length-= strlen($temp);
|
1878 |
-
}
|
1879 |
-
if (!empty($buffer)) {
|
1880 |
-
$raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
|
1881 |
-
$buffer = $temp = '';
|
1882 |
-
}
|
1883 |
-
|
1884 |
-
$payload = $this->_string_shift($raw, $packet_length - $padding_length - 1);
|
1885 |
-
$padding = $this->_string_shift($raw, $padding_length); // should leave $raw empty
|
1886 |
-
|
1887 |
-
if ($this->hmac_check !== false) {
|
1888 |
-
$hmac = fread($this->fsock, $this->hmac_size);
|
1889 |
-
if ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
|
1890 |
-
user_error('Invalid HMAC', E_USER_NOTICE);
|
1891 |
-
return false;
|
1892 |
-
}
|
1893 |
-
}
|
1894 |
-
|
1895 |
-
//if ($this->decompress) {
|
1896 |
-
// $payload = gzinflate(substr($payload, 2));
|
1897 |
-
//}
|
1898 |
-
|
1899 |
-
$this->get_seq_no++;
|
1900 |
-
|
1901 |
-
if (defined('NET_SSH2_LOGGING')) {
|
1902 |
-
$temp = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')';
|
1903 |
-
$this->message_number_log[] = '<- ' . $temp .
|
1904 |
-
' (' . round($stop - $start, 4) . 's)';
|
1905 |
-
if (NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {
|
1906 |
-
$this->message_log[] = substr($payload, 1);
|
1907 |
-
}
|
1908 |
-
}
|
1909 |
-
|
1910 |
-
return $this->_filter($payload);
|
1911 |
-
}
|
1912 |
-
|
1913 |
-
/**
|
1914 |
-
* Filter Binary Packets
|
1915 |
-
*
|
1916 |
-
* Because some binary packets need to be ignored...
|
1917 |
-
*
|
1918 |
-
* @see Net_SSH2::_get_binary_packet()
|
1919 |
-
* @return String
|
1920 |
-
* @access private
|
1921 |
-
*/
|
1922 |
-
function _filter($payload)
|
1923 |
-
{
|
1924 |
-
switch (ord($payload[0])) {
|
1925 |
-
case NET_SSH2_MSG_DISCONNECT:
|
1926 |
-
$this->_string_shift($payload, 1);
|
1927 |
-
extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
|
1928 |
-
$this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode($this->_string_shift($payload, $length));
|
1929 |
-
$this->bitmask = 0;
|
1930 |
-
return false;
|
1931 |
-
case NET_SSH2_MSG_IGNORE:
|
1932 |
-
$payload = $this->_get_binary_packet();
|
1933 |
-
break;
|
1934 |
-
case NET_SSH2_MSG_DEBUG:
|
1935 |
-
$this->_string_shift($payload, 2);
|
1936 |
-
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
1937 |
-
$this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode($this->_string_shift($payload, $length));
|
1938 |
-
$payload = $this->_get_binary_packet();
|
1939 |
-
break;
|
1940 |
-
case NET_SSH2_MSG_UNIMPLEMENTED:
|
1941 |
-
return false;
|
1942 |
-
case NET_SSH2_MSG_KEXINIT:
|
1943 |
-
if ($this->session_id !== false) {
|
1944 |
-
if (!$this->_key_exchange($payload)) {
|
1945 |
-
$this->bitmask = 0;
|
1946 |
-
return false;
|
1947 |
-
}
|
1948 |
-
$payload = $this->_get_binary_packet();
|
1949 |
-
}
|
1950 |
-
}
|
1951 |
-
|
1952 |
-
// see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
|
1953 |
-
if (($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR) && !($this->bitmap & NET_SSH2_MASK_LOGIN) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
|
1954 |
-
$this->_string_shift($payload, 1);
|
1955 |
-
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
1956 |
-
$this->errors[] = 'SSH_MSG_USERAUTH_BANNER: ' . utf8_decode($this->_string_shift($payload, $length));
|
1957 |
-
$payload = $this->_get_binary_packet();
|
1958 |
-
}
|
1959 |
-
|
1960 |
-
// only called when we've already logged in
|
1961 |
-
if (($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR) && ($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
1962 |
-
switch (ord($payload[0])) {
|
1963 |
-
case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
|
1964 |
-
$this->_string_shift($payload, 1);
|
1965 |
-
extract(unpack('Nlength', $this->_string_shift($payload)));
|
1966 |
-
$this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . utf8_decode($this->_string_shift($payload, $length));
|
1967 |
-
|
1968 |
-
if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) {
|
1969 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
1970 |
-
}
|
1971 |
-
|
1972 |
-
$payload = $this->_get_binary_packet();
|
1973 |
-
break;
|
1974 |
-
case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
|
1975 |
-
$this->_string_shift($payload, 1);
|
1976 |
-
extract(unpack('N', $this->_string_shift($payload, 4)));
|
1977 |
-
$this->errors[] = 'SSH_MSG_CHANNEL_OPEN: ' . utf8_decode($this->_string_shift($payload, $length));
|
1978 |
-
|
1979 |
-
$this->_string_shift($payload, 4); // skip over client channel
|
1980 |
-
extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));
|
1981 |
-
|
1982 |
-
$packet = pack('CN3a*Na*',
|
1983 |
-
NET_SSH2_MSG_REQUEST_FAILURE, $server_channel, NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, 0, '', 0, '');
|
1984 |
-
|
1985 |
-
if (!$this->_send_binary_packet($packet)) {
|
1986 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
1987 |
-
}
|
1988 |
-
|
1989 |
-
$payload = $this->_get_binary_packet();
|
1990 |
-
break;
|
1991 |
-
case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
1992 |
-
$payload = $this->_get_binary_packet();
|
1993 |
-
}
|
1994 |
-
}
|
1995 |
-
|
1996 |
-
return $payload;
|
1997 |
-
}
|
1998 |
-
|
1999 |
-
/**
|
2000 |
-
* Gets channel data
|
2001 |
-
*
|
2002 |
-
* Returns the data as a string if it's available and false if not.
|
2003 |
-
*
|
2004 |
-
* @param $client_channel
|
2005 |
-
* @return Mixed
|
2006 |
-
* @access private
|
2007 |
-
*/
|
2008 |
-
function _get_channel_packet($client_channel, $skip_extended = false)
|
2009 |
-
{
|
2010 |
-
if (!empty($this->channel_buffers[$client_channel])) {
|
2011 |
-
return array_shift($this->channel_buffers[$client_channel]);
|
2012 |
-
}
|
2013 |
-
|
2014 |
-
while (true) {
|
2015 |
-
$response = $this->_get_binary_packet();
|
2016 |
-
if ($response === false) {
|
2017 |
-
user_error('Connection closed by server', E_USER_NOTICE);
|
2018 |
-
return false;
|
2019 |
-
}
|
2020 |
-
|
2021 |
-
if (empty($response)) {
|
2022 |
-
return '';
|
2023 |
-
}
|
2024 |
-
|
2025 |
-
extract(unpack('Ctype/Nchannel', $this->_string_shift($response, 5)));
|
2026 |
-
|
2027 |
-
switch ($this->channel_status[$channel]) {
|
2028 |
-
case NET_SSH2_MSG_CHANNEL_OPEN:
|
2029 |
-
switch ($type) {
|
2030 |
-
case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
|
2031 |
-
extract(unpack('Nserver_channel', $this->_string_shift($response, 4)));
|
2032 |
-
$this->server_channels[$client_channel] = $server_channel;
|
2033 |
-
$this->_string_shift($response, 4); // skip over (server) window size
|
2034 |
-
$temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4));
|
2035 |
-
$this->packet_size_client_to_server[$client_channel] = $temp['packet_size_client_to_server'];
|
2036 |
-
return true;
|
2037 |
-
//case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
|
2038 |
-
default:
|
2039 |
-
user_error('Unable to open channel', E_USER_NOTICE);
|
2040 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
2041 |
-
}
|
2042 |
-
break;
|
2043 |
-
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
2044 |
-
switch ($type) {
|
2045 |
-
case NET_SSH2_MSG_CHANNEL_SUCCESS:
|
2046 |
-
return true;
|
2047 |
-
//case NET_SSH2_MSG_CHANNEL_FAILURE:
|
2048 |
-
default:
|
2049 |
-
user_error('Unable to request pseudo-terminal', E_USER_NOTICE);
|
2050 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
2051 |
-
}
|
2052 |
-
|
2053 |
-
}
|
2054 |
-
|
2055 |
-
switch ($type) {
|
2056 |
-
case NET_SSH2_MSG_CHANNEL_DATA:
|
2057 |
-
/*
|
2058 |
-
if ($client_channel == NET_SSH2_CHANNEL_EXEC) {
|
2059 |
-
// SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server
|
2060 |
-
// this actually seems to make things twice as fast. more to the point, the message right after
|
2061 |
-
// SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise.
|
2062 |
-
// in OpenSSH it slows things down but only by a couple thousandths of a second.
|
2063 |
-
$this->_send_channel_packet($client_channel, chr(0));
|
2064 |
-
}
|
2065 |
-
*/
|
2066 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
2067 |
-
$data = $this->_string_shift($response, $length);
|
2068 |
-
if ($client_channel == $channel) {
|
2069 |
-
return $data;
|
2070 |
-
}
|
2071 |
-
if (!isset($this->channel_buffers[$client_channel])) {
|
2072 |
-
$this->channel_buffers[$client_channel] = array();
|
2073 |
-
}
|
2074 |
-
$this->channel_buffers[$client_channel][] = $data;
|
2075 |
-
break;
|
2076 |
-
case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
|
2077 |
-
if ($skip_extended) {
|
2078 |
-
break;
|
2079 |
-
}
|
2080 |
-
/*
|
2081 |
-
if ($client_channel == NET_SSH2_CHANNEL_EXEC) {
|
2082 |
-
$this->_send_channel_packet($client_channel, chr(0));
|
2083 |
-
}
|
2084 |
-
*/
|
2085 |
-
// currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
|
2086 |
-
extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8)));
|
2087 |
-
$data = $this->_string_shift($response, $length);
|
2088 |
-
if ($client_channel == $channel) {
|
2089 |
-
return $data;
|
2090 |
-
}
|
2091 |
-
if (!isset($this->channel_buffers[$client_channel])) {
|
2092 |
-
$this->channel_buffers[$client_channel] = array();
|
2093 |
-
}
|
2094 |
-
$this->channel_buffers[$client_channel][] = $data;
|
2095 |
-
break;
|
2096 |
-
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
2097 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
2098 |
-
$value = $this->_string_shift($response, $length);
|
2099 |
-
switch ($value) {
|
2100 |
-
case 'exit-signal':
|
2101 |
-
$this->_string_shift($response, 1);
|
2102 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
2103 |
-
$this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);
|
2104 |
-
$this->_string_shift($response, 1);
|
2105 |
-
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
2106 |
-
if ($length) {
|
2107 |
-
$this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);
|
2108 |
-
}
|
2109 |
-
//case 'exit-status':
|
2110 |
-
default:
|
2111 |
-
// "Some systems may not implement signals, in which case they SHOULD ignore this message."
|
2112 |
-
// -- http://tools.ietf.org/html/rfc4254#section-6.9
|
2113 |
-
break;
|
2114 |
-
}
|
2115 |
-
break;
|
2116 |
-
case NET_SSH2_MSG_CHANNEL_CLOSE:
|
2117 |
-
$this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
|
2118 |
-
return true;
|
2119 |
-
case NET_SSH2_MSG_CHANNEL_EOF:
|
2120 |
-
break;
|
2121 |
-
default:
|
2122 |
-
user_error('Error reading channel data', E_USER_NOTICE);
|
2123 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
2124 |
-
}
|
2125 |
-
}
|
2126 |
-
}
|
2127 |
-
|
2128 |
-
/**
|
2129 |
-
* Sends Binary Packets
|
2130 |
-
*
|
2131 |
-
* See '6. Binary Packet Protocol' of rfc4253 for more info.
|
2132 |
-
*
|
2133 |
-
* @param String $data
|
2134 |
-
* @see Net_SSH2::_get_binary_packet()
|
2135 |
-
* @return Boolean
|
2136 |
-
* @access private
|
2137 |
-
*/
|
2138 |
-
function _send_binary_packet($data)
|
2139 |
-
{
|
2140 |
-
if (feof($this->fsock)) {
|
2141 |
-
user_error('Connection closed prematurely', E_USER_NOTICE);
|
2142 |
-
return false;
|
2143 |
-
}
|
2144 |
-
|
2145 |
-
//if ($this->compress) {
|
2146 |
-
// // the -4 removes the checksum:
|
2147 |
-
// // http://php.net/function.gzcompress#57710
|
2148 |
-
// $data = substr(gzcompress($data), 0, -4);
|
2149 |
-
//}
|
2150 |
-
|
2151 |
-
// 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9
|
2152 |
-
$packet_length = strlen($data) + 9;
|
2153 |
-
// round up to the nearest $this->encrypt_block_size
|
2154 |
-
$packet_length+= (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size;
|
2155 |
-
// subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length
|
2156 |
-
$padding_length = $packet_length - strlen($data) - 5;
|
2157 |
-
|
2158 |
-
$padding = '';
|
2159 |
-
for ($i = 0; $i < $padding_length; $i++) {
|
2160 |
-
$padding.= chr(crypt_random(0, 255));
|
2161 |
-
}
|
2162 |
-
|
2163 |
-
// we subtract 4 from packet_length because the packet_length field isn't supposed to include itself
|
2164 |
-
$packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding);
|
2165 |
-
|
2166 |
-
$hmac = $this->hmac_create !== false ? $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)) : '';
|
2167 |
-
$this->send_seq_no++;
|
2168 |
-
|
2169 |
-
if ($this->encrypt !== false) {
|
2170 |
-
$packet = $this->encrypt->encrypt($packet);
|
2171 |
-
}
|
2172 |
-
|
2173 |
-
$packet.= $hmac;
|
2174 |
-
|
2175 |
-
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
2176 |
-
$result = strlen($packet) == fputs($this->fsock, $packet);
|
2177 |
-
$stop = strtok(microtime(), ' ') + strtok('');
|
2178 |
-
|
2179 |
-
if (defined('NET_SSH2_LOGGING')) {
|
2180 |
-
$temp = isset($this->message_numbers[ord($data[0])]) ? $this->message_numbers[ord($data[0])] : 'UNKNOWN (' . ord($data[0]) . ')';
|
2181 |
-
$this->message_number_log[] = '-> ' . $temp .
|
2182 |
-
' (' . round($stop - $start, 4) . 's)';
|
2183 |
-
if (NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {
|
2184 |
-
$this->message_log[] = substr($data, 1);
|
2185 |
-
}
|
2186 |
-
}
|
2187 |
-
|
2188 |
-
return $result;
|
2189 |
-
}
|
2190 |
-
|
2191 |
-
/**
|
2192 |
-
* Sends channel data
|
2193 |
-
*
|
2194 |
-
* Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate
|
2195 |
-
*
|
2196 |
-
* @param Integer $client_channel
|
2197 |
-
* @param String $data
|
2198 |
-
* @return Boolean
|
2199 |
-
* @access private
|
2200 |
-
*/
|
2201 |
-
function _send_channel_packet($client_channel, $data)
|
2202 |
-
{
|
2203 |
-
while (strlen($data) > $this->packet_size_client_to_server[$client_channel]) {
|
2204 |
-
// resize the window, if appropriate
|
2205 |
-
$this->window_size_client_to_server[$client_channel]-= $this->packet_size_client_to_server[$client_channel];
|
2206 |
-
if ($this->window_size_client_to_server[$client_channel] < 0) {
|
2207 |
-
$packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$client_channel], $this->window_size);
|
2208 |
-
if (!$this->_send_binary_packet($packet)) {
|
2209 |
-
return false;
|
2210 |
-
}
|
2211 |
-
$this->window_size_client_to_server[$client_channel]+= $this->window_size;
|
2212 |
-
}
|
2213 |
-
|
2214 |
-
$packet = pack('CN2a*',
|
2215 |
-
NET_SSH2_MSG_CHANNEL_DATA,
|
2216 |
-
$this->server_channels[$client_channel],
|
2217 |
-
$this->packet_size_client_to_server[$client_channel],
|
2218 |
-
$this->_string_shift($data, $this->packet_size_client_to_server[$client_channel])
|
2219 |
-
);
|
2220 |
-
|
2221 |
-
if (!$this->_send_binary_packet($packet)) {
|
2222 |
-
return false;
|
2223 |
-
}
|
2224 |
-
}
|
2225 |
-
|
2226 |
-
// resize the window, if appropriate
|
2227 |
-
$this->window_size_client_to_server[$client_channel]-= strlen($data);
|
2228 |
-
if ($this->window_size_client_to_server[$client_channel] < 0) {
|
2229 |
-
$packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$client_channel], $this->window_size);
|
2230 |
-
if (!$this->_send_binary_packet($packet)) {
|
2231 |
-
return false;
|
2232 |
-
}
|
2233 |
-
$this->window_size_client_to_server[$client_channel]+= $this->window_size;
|
2234 |
-
}
|
2235 |
-
|
2236 |
-
return $this->_send_binary_packet(pack('CN2a*',
|
2237 |
-
NET_SSH2_MSG_CHANNEL_DATA,
|
2238 |
-
$this->server_channels[$client_channel],
|
2239 |
-
strlen($data),
|
2240 |
-
$data));
|
2241 |
-
}
|
2242 |
-
|
2243 |
-
/**
|
2244 |
-
* Closes and flushes a channel
|
2245 |
-
*
|
2246 |
-
* Net_SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server
|
2247 |
-
* and for SFTP channels are presumably closed when the client disconnects. This functions is intended
|
2248 |
-
* for SCP more than anything.
|
2249 |
-
*
|
2250 |
-
* @param Integer $client_channel
|
2251 |
-
* @return Boolean
|
2252 |
-
* @access private
|
2253 |
-
*/
|
2254 |
-
function _close_channel($client_channel)
|
2255 |
-
{
|
2256 |
-
// see http://tools.ietf.org/html/rfc4254#section-5.3
|
2257 |
-
|
2258 |
-
$packet = pack('CN',
|
2259 |
-
NET_SSH2_MSG_CHANNEL_EOF,
|
2260 |
-
$this->server_channels[$client_channel]);
|
2261 |
-
if (!$this->_send_binary_packet($packet)) {
|
2262 |
-
return false;
|
2263 |
-
}
|
2264 |
-
|
2265 |
-
while ($this->_get_channel_packet($client_channel) !== true);
|
2266 |
-
}
|
2267 |
-
|
2268 |
-
/**
|
2269 |
-
* Disconnect
|
2270 |
-
*
|
2271 |
-
* @param Integer $reason
|
2272 |
-
* @return Boolean
|
2273 |
-
* @access private
|
2274 |
-
*/
|
2275 |
-
function _disconnect($reason)
|
2276 |
-
{
|
2277 |
-
if ($this->bitmap) {
|
2278 |
-
$data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, '');
|
2279 |
-
$this->_send_binary_packet($data);
|
2280 |
-
$this->bitmap = 0;
|
2281 |
-
fclose($this->fsock);
|
2282 |
-
return false;
|
2283 |
-
}
|
2284 |
-
}
|
2285 |
-
|
2286 |
-
/**
|
2287 |
-
* String Shift
|
2288 |
-
*
|
2289 |
-
* Inspired by array_shift
|
2290 |
-
*
|
2291 |
-
* @param String $string
|
2292 |
-
* @param optional Integer $index
|
2293 |
-
* @return String
|
2294 |
-
* @access private
|
2295 |
-
*/
|
2296 |
-
function _string_shift(&$string, $index = 1)
|
2297 |
-
{
|
2298 |
-
$substr = substr($string, 0, $index);
|
2299 |
-
$string = substr($string, $index);
|
2300 |
-
return $substr;
|
2301 |
-
}
|
2302 |
-
|
2303 |
-
/**
|
2304 |
-
* Define Array
|
2305 |
-
*
|
2306 |
-
* Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of
|
2307 |
-
* named constants from it, using the value as the name of the constant and the index as the value of the constant.
|
2308 |
-
* If any of the constants that would be defined already exists, none of the constants will be defined.
|
2309 |
-
*
|
2310 |
-
* @param Array $array
|
2311 |
-
* @access private
|
2312 |
-
*/
|
2313 |
-
function _define_array()
|
2314 |
-
{
|
2315 |
-
$args = func_get_args();
|
2316 |
-
foreach ($args as $arg) {
|
2317 |
-
foreach ($arg as $key=>$value) {
|
2318 |
-
if (!defined($value)) {
|
2319 |
-
define($value, $key);
|
2320 |
-
} else {
|
2321 |
-
break 2;
|
2322 |
-
}
|
2323 |
-
}
|
2324 |
-
}
|
2325 |
-
}
|
2326 |
-
|
2327 |
-
/**
|
2328 |
-
* Returns a log of the packets that have been sent and received.
|
2329 |
-
*
|
2330 |
-
* Returns a string if NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX, an array if NET_SSH2_LOGGING == NET_SSH2_LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING')
|
2331 |
-
*
|
2332 |
-
* @access public
|
2333 |
-
* @return String or Array
|
2334 |
-
*/
|
2335 |
-
function getLog()
|
2336 |
-
{
|
2337 |
-
if (!defined('NET_SSH2_LOGGING')) {
|
2338 |
-
return false;
|
2339 |
-
}
|
2340 |
-
|
2341 |
-
switch (NET_SSH2_LOGGING) {
|
2342 |
-
case NET_SSH2_LOG_SIMPLE:
|
2343 |
-
return $this->message_number_log;
|
2344 |
-
break;
|
2345 |
-
case NET_SSH2_LOG_COMPLEX:
|
2346 |
-
return $this->_format_log($this->message_log, $this->message_number_log);
|
2347 |
-
break;
|
2348 |
-
default:
|
2349 |
-
return false;
|
2350 |
-
}
|
2351 |
-
}
|
2352 |
-
|
2353 |
-
/**
|
2354 |
-
* Formats a log for printing
|
2355 |
-
*
|
2356 |
-
* @param Array $message_log
|
2357 |
-
* @param Array $message_number_log
|
2358 |
-
* @access private
|
2359 |
-
* @return String
|
2360 |
-
*/
|
2361 |
-
function _format_log($message_log, $message_number_log)
|
2362 |
-
{
|
2363 |
-
static $boundary = ':', $long_width = 65, $short_width = 16;
|
2364 |
-
|
2365 |
-
$output = '';
|
2366 |
-
for ($i = 0; $i < count($message_log); $i++) {
|
2367 |
-
$output.= $message_number_log[$i] . "\r\n";
|
2368 |
-
$current_log = $message_log[$i];
|
2369 |
-
$j = 0;
|
2370 |
-
do {
|
2371 |
-
if (!empty($current_log)) {
|
2372 |
-
$output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 ';
|
2373 |
-
}
|
2374 |
-
$fragment = $this->_string_shift($current_log, $short_width);
|
2375 |
-
$hex = substr(
|
2376 |
-
preg_replace(
|
2377 |
-
'#(.)#es',
|
2378 |
-
'"' . $boundary . '" . str_pad(dechex(ord(substr("\\1", -1))), 2, "0", STR_PAD_LEFT)',
|
2379 |
-
$fragment),
|
2380 |
-
strlen($boundary)
|
2381 |
-
);
|
2382 |
-
// replace non ASCII printable characters with dots
|
2383 |
-
// http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
|
2384 |
-
// also replace < with a . since < messes up the output on web browsers
|
2385 |
-
$raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment);
|
2386 |
-
$output.= str_pad($hex, $long_width - $short_width, ' ') . $raw . "\r\n";
|
2387 |
-
$j++;
|
2388 |
-
} while (!empty($current_log));
|
2389 |
-
$output.= "\r\n";
|
2390 |
-
}
|
2391 |
-
|
2392 |
-
return $output;
|
2393 |
-
}
|
2394 |
-
|
2395 |
-
/**
|
2396 |
-
* Returns all errors
|
2397 |
-
*
|
2398 |
-
* @return String
|
2399 |
-
* @access public
|
2400 |
-
*/
|
2401 |
-
function getErrors()
|
2402 |
-
{
|
2403 |
-
return $this->errors;
|
2404 |
-
}
|
2405 |
-
|
2406 |
-
/**
|
2407 |
-
* Returns the last error
|
2408 |
-
*
|
2409 |
-
* @return String
|
2410 |
-
* @access public
|
2411 |
-
*/
|
2412 |
-
function getLastError()
|
2413 |
-
{
|
2414 |
-
return $this->errors[count($this->errors) - 1];
|
2415 |
-
}
|
2416 |
-
|
2417 |
-
/**
|
2418 |
-
* Return the server identification.
|
2419 |
-
*
|
2420 |
-
* @return String
|
2421 |
-
* @access public
|
2422 |
-
*/
|
2423 |
-
function getServerIdentification()
|
2424 |
-
{
|
2425 |
-
return $this->server_identifier;
|
2426 |
-
}
|
2427 |
-
|
2428 |
-
/**
|
2429 |
-
* Return a list of the key exchange algorithms the server supports.
|
2430 |
-
*
|
2431 |
-
* @return Array
|
2432 |
-
* @access public
|
2433 |
-
*/
|
2434 |
-
function getKexAlgorithms()
|
2435 |
-
{
|
2436 |
-
return $this->kex_algorithms;
|
2437 |
-
}
|
2438 |
-
|
2439 |
-
/**
|
2440 |
-
* Return a list of the host key (public key) algorithms the server supports.
|
2441 |
-
*
|
2442 |
-
* @return Array
|
2443 |
-
* @access public
|
2444 |
-
*/
|
2445 |
-
function getServerHostKeyAlgorithms()
|
2446 |
-
{
|
2447 |
-
return $this->server_host_key_algorithms;
|
2448 |
-
}
|
2449 |
-
|
2450 |
-
/**
|
2451 |
-
* Return a list of the (symmetric key) encryption algorithms the server supports, when receiving stuff from the client.
|
2452 |
-
*
|
2453 |
-
* @return Array
|
2454 |
-
* @access public
|
2455 |
-
*/
|
2456 |
-
function getEncryptionAlgorithmsClient2Server()
|
2457 |
-
{
|
2458 |
-
return $this->encryption_algorithms_client_to_server;
|
2459 |
-
}
|
2460 |
-
|
2461 |
-
/**
|
2462 |
-
* Return a list of the (symmetric key) encryption algorithms the server supports, when sending stuff to the client.
|
2463 |
-
*
|
2464 |
-
* @return Array
|
2465 |
-
* @access public
|
2466 |
-
*/
|
2467 |
-
function getEncryptionAlgorithmsServer2Client()
|
2468 |
-
{
|
2469 |
-
return $this->encryption_algorithms_server_to_client;
|
2470 |
-
}
|
2471 |
-
|
2472 |
-
/**
|
2473 |
-
* Return a list of the MAC algorithms the server supports, when receiving stuff from the client.
|
2474 |
-
*
|
2475 |
-
* @return Array
|
2476 |
-
* @access public
|
2477 |
-
*/
|
2478 |
-
function getMACAlgorithmsClient2Server()
|
2479 |
-
{
|
2480 |
-
return $this->mac_algorithms_client_to_server;
|
2481 |
-
}
|
2482 |
-
|
2483 |
-
/**
|
2484 |
-
* Return a list of the MAC algorithms the server supports, when sending stuff to the client.
|
2485 |
-
*
|
2486 |
-
* @return Array
|
2487 |
-
* @access public
|
2488 |
-
*/
|
2489 |
-
function getMACAlgorithmsServer2Client()
|
2490 |
-
{
|
2491 |
-
return $this->mac_algorithms_server_to_client;
|
2492 |
-
}
|
2493 |
-
|
2494 |
-
/**
|
2495 |
-
* Return a list of the compression algorithms the server supports, when receiving stuff from the client.
|
2496 |
-
*
|
2497 |
-
* @return Array
|
2498 |
-
* @access public
|
2499 |
-
*/
|
2500 |
-
function getCompressionAlgorithmsClient2Server()
|
2501 |
-
{
|
2502 |
-
return $this->compression_algorithms_client_to_server;
|
2503 |
-
}
|
2504 |
-
|
2505 |
-
/**
|
2506 |
-
* Return a list of the compression algorithms the server supports, when sending stuff to the client.
|
2507 |
-
*
|
2508 |
-
* @return Array
|
2509 |
-
* @access public
|
2510 |
-
*/
|
2511 |
-
function getCompressionAlgorithmsServer2Client()
|
2512 |
-
{
|
2513 |
-
return $this->compression_algorithms_server_to_client;
|
2514 |
-
}
|
2515 |
-
|
2516 |
-
/**
|
2517 |
-
* Return a list of the languages the server supports, when sending stuff to the client.
|
2518 |
-
*
|
2519 |
-
* @return Array
|
2520 |
-
* @access public
|
2521 |
-
*/
|
2522 |
-
function getLanguagesServer2Client()
|
2523 |
-
{
|
2524 |
-
return $this->languages_server_to_client;
|
2525 |
-
}
|
2526 |
-
|
2527 |
-
/**
|
2528 |
-
* Return a list of the languages the server supports, when receiving stuff from the client.
|
2529 |
-
*
|
2530 |
-
* @return Array
|
2531 |
-
* @access public
|
2532 |
-
*/
|
2533 |
-
function getLanguagesClient2Server()
|
2534 |
-
{
|
2535 |
-
return $this->languages_client_to_server;
|
2536 |
-
}
|
2537 |
-
|
2538 |
-
/**
|
2539 |
-
* Returns the server public host key.
|
2540 |
-
*
|
2541 |
-
* Caching this the first time you connect to a server and checking the result on subsequent connections
|
2542 |
-
* is recommended. Returns false if the server signature is not signed correctly with the public host key.
|
2543 |
-
*
|
2544 |
-
* @return Mixed
|
2545 |
-
* @access public
|
2546 |
-
*/
|
2547 |
-
function getServerPublicHostKey()
|
2548 |
-
{
|
2549 |
-
$signature = $this->signature;
|
2550 |
-
$server_public_host_key = $this->server_public_host_key;
|
2551 |
-
|
2552 |
-
extract(unpack('Nlength', $this->_string_shift($server_public_host_key, 4)));
|
2553 |
-
$this->_string_shift($server_public_host_key, $length);
|
2554 |
-
|
2555 |
-
switch ($this->signature_format) {
|
2556 |
-
case 'ssh-dss':
|
2557 |
-
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
2558 |
-
$p = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
2559 |
-
|
2560 |
-
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
2561 |
-
$q = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
2562 |
-
|
2563 |
-
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
2564 |
-
$g = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
2565 |
-
|
2566 |
-
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
2567 |
-
$y = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
2568 |
-
|
2569 |
-
/* The value for 'dss_signature_blob' is encoded as a string containing
|
2570 |
-
r, followed by s (which are 160-bit integers, without lengths or
|
2571 |
-
padding, unsigned, and in network byte order). */
|
2572 |
-
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
2573 |
-
if ($temp['length'] != 40) {
|
2574 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2575 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
2576 |
-
}
|
2577 |
-
|
2578 |
-
$r = new Math_BigInteger($this->_string_shift($signature, 20), 256);
|
2579 |
-
$s = new Math_BigInteger($this->_string_shift($signature, 20), 256);
|
2580 |
-
|
2581 |
-
if ($r->compare($q) >= 0 || $s->compare($q) >= 0) {
|
2582 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2583 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
2584 |
-
}
|
2585 |
-
|
2586 |
-
$w = $s->modInverse($q);
|
2587 |
-
|
2588 |
-
$u1 = $w->multiply(new Math_BigInteger(sha1($this->exchange_hash), 16));
|
2589 |
-
list(, $u1) = $u1->divide($q);
|
2590 |
-
|
2591 |
-
$u2 = $w->multiply($r);
|
2592 |
-
list(, $u2) = $u2->divide($q);
|
2593 |
-
|
2594 |
-
$g = $g->modPow($u1, $p);
|
2595 |
-
$y = $y->modPow($u2, $p);
|
2596 |
-
|
2597 |
-
$v = $g->multiply($y);
|
2598 |
-
list(, $v) = $v->divide($p);
|
2599 |
-
list(, $v) = $v->divide($q);
|
2600 |
-
|
2601 |
-
if (!$v->equals($r)) {
|
2602 |
-
user_error('Bad server signature', E_USER_NOTICE);
|
2603 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
2604 |
-
}
|
2605 |
-
|
2606 |
-
break;
|
2607 |
-
case 'ssh-rsa':
|
2608 |
-
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
2609 |
-
$e = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
2610 |
-
|
2611 |
-
$temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
|
2612 |
-
$n = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
|
2613 |
-
$nLength = $temp['length'];
|
2614 |
-
|
2615 |
-
/*
|
2616 |
-
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
2617 |
-
$signature = $this->_string_shift($signature, $temp['length']);
|
2618 |
-
|
2619 |
-
if (!class_exists('Crypt_RSA')) {
|
2620 |
-
require_once('Crypt/RSA.php');
|
2621 |
-
}
|
2622 |
-
|
2623 |
-
$rsa = new Crypt_RSA();
|
2624 |
-
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
2625 |
-
$rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
|
2626 |
-
if (!$rsa->verify($this->exchange_hash, $signature)) {
|
2627 |
-
user_error('Bad server signature', E_USER_NOTICE);
|
2628 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
2629 |
-
}
|
2630 |
-
*/
|
2631 |
-
|
2632 |
-
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
2633 |
-
$s = new Math_BigInteger($this->_string_shift($signature, $temp['length']), 256);
|
2634 |
-
|
2635 |
-
// validate an RSA signature per "8.2 RSASSA-PKCS1-v1_5", "5.2.2 RSAVP1", and "9.1 EMSA-PSS" in the
|
2636 |
-
// following URL:
|
2637 |
-
// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
|
2638 |
-
|
2639 |
-
// also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
|
2640 |
-
|
2641 |
-
if ($s->compare(new Math_BigInteger()) < 0 || $s->compare($n->subtract(new Math_BigInteger(1))) > 0) {
|
2642 |
-
user_error('Invalid signature', E_USER_NOTICE);
|
2643 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
2644 |
-
}
|
2645 |
-
|
2646 |
-
$s = $s->modPow($e, $n);
|
2647 |
-
$s = $s->toBytes();
|
2648 |
-
|
2649 |
-
$h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->exchange_hash));
|
2650 |
-
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 3 - strlen($h)) . $h;
|
2651 |
-
|
2652 |
-
if ($s != $h) {
|
2653 |
-
user_error('Bad server signature', E_USER_NOTICE);
|
2654 |
-
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
2655 |
-
}
|
2656 |
-
}
|
2657 |
-
|
2658 |
-
return $this->server_public_host_key;
|
2659 |
-
}
|
2660 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/PHP/Compat/Function/array_fill.php
DELETED
@@ -1,41 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// $Id: array_fill.php,v 1.1 2007/07/02 04:19:55 terrafrost Exp $
|
3 |
-
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Replace array_fill()
|
7 |
-
*
|
8 |
-
* @category PHP
|
9 |
-
* @package PHP_Compat
|
10 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
11 |
-
* @copyright 2004-2007 Aidan Lister <aidan@php.net>, Arpad Ray <arpad@php.net>
|
12 |
-
* @link http://php.net/function.array_fill
|
13 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
14 |
-
* @version $Revision: 1.1 $
|
15 |
-
* @since PHP 4.2.0
|
16 |
-
*/
|
17 |
-
function php_compat_array_fill($start_index, $num, $value)
|
18 |
-
{
|
19 |
-
if ($num <= 0) {
|
20 |
-
user_error('array_fill(): Number of elements must be positive', E_USER_WARNING);
|
21 |
-
|
22 |
-
return false;
|
23 |
-
}
|
24 |
-
|
25 |
-
$temp = array();
|
26 |
-
|
27 |
-
$end_index = $start_index + $num;
|
28 |
-
for ($i = (int) $start_index; $i < $end_index; $i++) {
|
29 |
-
$temp[$i] = $value;
|
30 |
-
}
|
31 |
-
|
32 |
-
return $temp;
|
33 |
-
}
|
34 |
-
|
35 |
-
// Define
|
36 |
-
if (!function_exists('array_fill')) {
|
37 |
-
function array_fill($start_index, $num, $value)
|
38 |
-
{
|
39 |
-
return php_compat_array_fill($start_index, $num, $value);
|
40 |
-
}
|
41 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/PHP/Compat/Function/bcpowmod.php
DELETED
@@ -1,66 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// $Id: bcpowmod.php,v 1.1 2007-07-02 04:19:55 terrafrost Exp $
|
3 |
-
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Replace bcpowmod()
|
7 |
-
*
|
8 |
-
* @category PHP
|
9 |
-
* @package PHP_Compat
|
10 |
-
* @license LGPL - http://www.gnu.org/licenses/lgpl.html
|
11 |
-
* @copyright 2004-2007 Aidan Lister <aidan@php.net>, Arpad Ray <arpad@php.net>
|
12 |
-
* @link http://php.net/function.bcpowmod
|
13 |
-
* @author Sara Golemon <pollita@php.net>
|
14 |
-
* @version $Revision: 1.1 $
|
15 |
-
* @since PHP 5.0.0
|
16 |
-
* @require PHP 4.0.0 (user_error)
|
17 |
-
*/
|
18 |
-
function php_compat_bcpowmod($x, $y, $modulus, $scale = 0)
|
19 |
-
{
|
20 |
-
// Sanity check
|
21 |
-
if (!is_scalar($x)) {
|
22 |
-
user_error('bcpowmod() expects parameter 1 to be string, ' .
|
23 |
-
gettype($x) . ' given', E_USER_WARNING);
|
24 |
-
return false;
|
25 |
-
}
|
26 |
-
|
27 |
-
if (!is_scalar($y)) {
|
28 |
-
user_error('bcpowmod() expects parameter 2 to be string, ' .
|
29 |
-
gettype($y) . ' given', E_USER_WARNING);
|
30 |
-
return false;
|
31 |
-
}
|
32 |
-
|
33 |
-
if (!is_scalar($modulus)) {
|
34 |
-
user_error('bcpowmod() expects parameter 3 to be string, ' .
|
35 |
-
gettype($modulus) . ' given', E_USER_WARNING);
|
36 |
-
return false;
|
37 |
-
}
|
38 |
-
|
39 |
-
if (!is_scalar($scale)) {
|
40 |
-
user_error('bcpowmod() expects parameter 4 to be integer, ' .
|
41 |
-
gettype($scale) . ' given', E_USER_WARNING);
|
42 |
-
return false;
|
43 |
-
}
|
44 |
-
|
45 |
-
$t = '1';
|
46 |
-
while (bccomp($y, '0')) {
|
47 |
-
if (bccomp(bcmod($y, '2'), '0')) {
|
48 |
-
$t = bcmod(bcmul($t, $x), $modulus);
|
49 |
-
$y = bcsub($y, '1');
|
50 |
-
}
|
51 |
-
|
52 |
-
$x = bcmod(bcmul($x, $x), $modulus);
|
53 |
-
$y = bcdiv($y, '2');
|
54 |
-
}
|
55 |
-
|
56 |
-
return $t;
|
57 |
-
}
|
58 |
-
|
59 |
-
|
60 |
-
// Define
|
61 |
-
if (!function_exists('bcpowmod')) {
|
62 |
-
function bcpowmod($x, $y, $modulus, $scale = 0)
|
63 |
-
{
|
64 |
-
return php_compat_bcpowmod($x, $y, $modulus, $scale);
|
65 |
-
}
|
66 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/PHP/Compat/Function/str_split.php
DELETED
@@ -1,59 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Replace str_split()
|
4 |
-
*
|
5 |
-
* @category PHP
|
6 |
-
* @package PHP_Compat
|
7 |
-
* @license LGPL - http://www.gnu.org/licenses/lgpl.html
|
8 |
-
* @copyright 2004-2007 Aidan Lister <aidan@php.net>, Arpad Ray <arpad@php.net>
|
9 |
-
* @link http://php.net/function.str_split
|
10 |
-
* @author Aidan Lister <aidan@php.net>
|
11 |
-
* @version $Revision: 1.1 $
|
12 |
-
* @since PHP 5
|
13 |
-
* @require PHP 4.0.0 (user_error)
|
14 |
-
*/
|
15 |
-
function php_compat_str_split($string, $split_length = 1)
|
16 |
-
{
|
17 |
-
if (!is_scalar($split_length)) {
|
18 |
-
user_error('str_split() expects parameter 2 to be long, ' .
|
19 |
-
gettype($split_length) . ' given', E_USER_WARNING);
|
20 |
-
return false;
|
21 |
-
}
|
22 |
-
|
23 |
-
$split_length = (int) $split_length;
|
24 |
-
if ($split_length < 1) {
|
25 |
-
user_error('str_split() The length of each segment must be greater than zero', E_USER_WARNING);
|
26 |
-
return false;
|
27 |
-
}
|
28 |
-
|
29 |
-
// Select split method
|
30 |
-
if ($split_length < 65536) {
|
31 |
-
// Faster, but only works for less than 2^16
|
32 |
-
preg_match_all('/.{1,' . $split_length . '}/s', $string, $matches);
|
33 |
-
return $matches[0];
|
34 |
-
} else {
|
35 |
-
// Required due to preg limitations
|
36 |
-
$arr = array();
|
37 |
-
$idx = 0;
|
38 |
-
$pos = 0;
|
39 |
-
$len = strlen($string);
|
40 |
-
|
41 |
-
while ($len > 0) {
|
42 |
-
$blk = ($len < $split_length) ? $len : $split_length;
|
43 |
-
$arr[$idx++] = substr($string, $pos, $blk);
|
44 |
-
$pos += $blk;
|
45 |
-
$len -= $blk;
|
46 |
-
}
|
47 |
-
|
48 |
-
return $arr;
|
49 |
-
}
|
50 |
-
}
|
51 |
-
|
52 |
-
|
53 |
-
// Define
|
54 |
-
if (!function_exists('str_split')) {
|
55 |
-
function str_split($string, $split_length = 1)
|
56 |
-
{
|
57 |
-
return php_compat_str_split($string, $split_length);
|
58 |
-
}
|
59 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cloner.config.php
CHANGED
@@ -39,9 +39,6 @@ $_CONFIG['sqldump']="mysqldump --quote-names ";
|
|
39 |
$_CONFIG['system_dlink']="";
|
40 |
$_CONFIG['system_ftptransfer']="0";
|
41 |
$_CONFIG['system_mdatabases']="0";
|
42 |
-
$_CONFIG['recordsPerSession']= "10000";
|
43 |
-
$_CONFIG['excludeFilesSize'] = "-1";
|
44 |
-
$_CONFIG['splitBackupSize'] = "2048"; //MB
|
45 |
|
46 |
### Defaults
|
47 |
$script_dir = str_replace("\\","/",dirname(__FILE__));
|
39 |
$_CONFIG['system_dlink']="";
|
40 |
$_CONFIG['system_ftptransfer']="0";
|
41 |
$_CONFIG['system_mdatabases']="0";
|
|
|
|
|
|
|
42 |
|
43 |
### Defaults
|
44 |
$script_dir = str_replace("\\","/",dirname(__FILE__));
|
cloner.cron.php
CHANGED
@@ -14,25 +14,10 @@
|
|
14 |
@error_reporting(E_ALL^E_NOTICE);
|
15 |
@set_time_limit('3600');
|
16 |
define( '_VALID_MOS', 1 );
|
17 |
-
header('Content-Type: text/html; charset=utf-8');
|
18 |
|
19 |
include_once("admin.cloner.html.php");
|
20 |
include_once("cloner.functions.php");
|
21 |
|
22 |
-
require_once( 'cloner.config.php' );
|
23 |
-
|
24 |
-
####### VERIFY IP ACCESS
|
25 |
-
$ip_list = @explode("\r\n", $_CONFIG['cron_ip']);
|
26 |
-
$ip_list[] = $_SERVER['SERVER_ADDR'];
|
27 |
-
$curent_ip = $_SERVER["REMOTE_ADDR"];
|
28 |
-
|
29 |
-
if(!in_array($curent_ip, $ip_list)){
|
30 |
-
|
31 |
-
echo "Access Denied for ip $curent_ip!";
|
32 |
-
exit;
|
33 |
-
|
34 |
-
}
|
35 |
-
#########################
|
36 |
|
37 |
$script_dir = str_replace("\\","/",dirname(__FILE__));
|
38 |
if(is_dir($script_dir)){
|
@@ -46,11 +31,11 @@ if($_REQUEST['config'] == ""){
|
|
46 |
if($argv[1] != ""){
|
47 |
|
48 |
$_REQUEST['config'] = $argv[1];
|
|
|
49 |
}
|
50 |
-
}
|
51 |
|
52 |
-
|
53 |
-
|
54 |
|
55 |
if($_REQUEST['config'] != ""){
|
56 |
|
@@ -97,7 +82,7 @@ else{
|
|
97 |
|
98 |
|
99 |
####### VERIFY IP ACCESS
|
100 |
-
|
101 |
$ip_list[] = $_SERVER['SERVER_ADDR'];
|
102 |
$curent_ip = $_SERVER["REMOTE_ADDR"];
|
103 |
|
@@ -106,7 +91,7 @@ if(!in_array($curent_ip, $ip_list)){
|
|
106 |
echo "Access Denied for ip $curent_ip!";
|
107 |
exit;
|
108 |
|
109 |
-
}
|
110 |
#########################
|
111 |
|
112 |
$access=1;
|
@@ -184,115 +169,89 @@ $source_file = $clonerPath."/".$file;
|
|
184 |
logxx("Backup file: ".$source_file);
|
185 |
$bsize = getFileSizeText(filesize($source_file));
|
186 |
|
187 |
-
if($_CONFIG['cron_send']==1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
{
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
$ftp_timeout = '3600';
|
200 |
-
|
201 |
-
logxx("Starting ftp transfer:");
|
202 |
-
if(!$_CONFIG[secure_ftp])
|
203 |
-
{
|
204 |
-
// set up basic connection
|
205 |
-
$conn_id = ftp_connect($fhost, (int)$fport, (int)$ftp_timeout);
|
206 |
-
$connect = "Normal";
|
207 |
-
|
208 |
-
// login with username and password
|
209 |
-
$login_result = ftp_login($conn_id, $_CONFIG[cron_ftp_user], $_CONFIG[cron_ftp_pass])
|
210 |
-
or die("Authentification failed when connecting to the ftp server for user ".$_CONFIG[cron_ftp_user]." with pass".$_CONFIG[cron_ftp_pass]);
|
211 |
-
|
212 |
-
// check connection
|
213 |
-
if ((!$conn_id) || (!$login_result)) {
|
214 |
-
echo "<b style='color:red'>FTP connection has failed!</b>";
|
215 |
-
echo "<b style='color:red'>Attempted to connect to ".$_CONFIG[cron_ftp_server]." for user ".$_CONFIG[cron_ftp_user]."</b>";
|
216 |
-
return;
|
217 |
-
} else {
|
218 |
-
#echo "Connected to $_REQUEST[ftp_server], for user $_REQUEST[ftp_user]";
|
219 |
-
}
|
220 |
-
|
221 |
-
if($_CONFIG['system_ftptransfer']==1)
|
222 |
-
{
|
223 |
-
// turn passive mode on
|
224 |
-
@ftp_pasv($conn_id, true);
|
225 |
-
$mode = "Passive";
|
226 |
-
}
|
227 |
-
else
|
228 |
-
{
|
229 |
-
// turn passive mode off
|
230 |
-
@ftp_pasv($conn_id, false);
|
231 |
-
$mode = "Active";
|
232 |
-
}
|
233 |
-
echo "Connected to $connect <b>$_CONFIG[cron_ftp_server] Mode: $mode</b><br />";
|
234 |
-
for($i=0;$i<sizeof($source_files);$i++)
|
235 |
-
{
|
236 |
-
// upload the file
|
237 |
-
$upload = ftp_put($conn_id, $destination_files[$i], $source_files[$i], FTP_BINARY);
|
238 |
-
|
239 |
-
// check upload status
|
240 |
-
if (!$upload) {
|
241 |
-
echo "<b style='color:red'>FTP upload has failed for file $source_files[$i] ! Stopping ....<br /></b>";return;
|
242 |
-
} else {
|
243 |
-
echo "<b>Upload success from file <i>$source_files[$i]</i> <br />to <i>$destination_files[$i]</i> ...<br /></b>";
|
244 |
-
}
|
245 |
-
}
|
246 |
-
|
247 |
-
// close the FTP stream
|
248 |
-
ftp_close($conn_id);
|
249 |
-
}
|
250 |
-
else //Use sftp
|
251 |
-
{
|
252 |
-
//set php path to include required sftp files
|
253 |
-
set_include_path(get_include_path() . PATH_SEPARATOR .'classes/phpseclib');
|
254 |
-
|
255 |
-
include('Net/SFTP.php');
|
256 |
-
//define('NET_SFTP_LOGGING', NET_SFTP_LOG_COMPLEX); // or NET_SFTP_LOG_SIMPLE
|
257 |
-
|
258 |
-
//connect to host and authenticate user
|
259 |
-
$sftp = new Net_SFTP($fhost);
|
260 |
-
if (!$sftp->login($_CONFIG[cron_ftp_user], $_CONFIG[cron_ftp_pass]))
|
261 |
-
{
|
262 |
-
logxx('Login Failed');
|
263 |
-
die("Login Failed");
|
264 |
-
}
|
265 |
-
logxx("Connected to $connect <b>$_CONFIG[cron_ftp_server] Successfully!><br />");
|
266 |
-
|
267 |
-
//transfere files
|
268 |
-
for($i=0;$i<sizeof($source_files);$i++)
|
269 |
-
{
|
270 |
-
// upload the file
|
271 |
-
$upload = $sftp->put($destination_files[$i], $source_files[$i], NET_SFTP_LOCAL_FILE);
|
272 |
-
|
273 |
-
// check upload status
|
274 |
-
if (!$upload) {
|
275 |
-
logxx("<b style='color:red'>FTP upload has failed for file $source_files[$i] ! Stopping ....<br /></b>");return;
|
276 |
-
} else {
|
277 |
-
logxx("<b>Upload success from file <i>$source_files[$i]</i> <br />to <i>$destination_files[$i]</i> ...<br /></b>");
|
278 |
-
}
|
279 |
-
}
|
280 |
-
|
281 |
-
//disconnect from server
|
282 |
-
unset($sftp);
|
283 |
-
}
|
284 |
-
|
285 |
-
logxx("Ftp transfer finished succesfully!");
|
286 |
-
|
287 |
-
if($_CONFIG[cron_ftp_delb]==1)
|
288 |
-
{
|
289 |
-
@unlink($source_file);
|
290 |
-
logxx("Backup succesfully deleted from the original server!");
|
291 |
-
}
|
292 |
-
##############################################################################
|
293 |
}
|
294 |
-
|
|
|
295 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
296 |
#######################################STARTING Email TRANSFER################
|
297 |
logxx("Sending mail with backup");
|
298 |
|
@@ -304,7 +263,7 @@ else if($_CONFIG['cron_send']==2)
|
|
304 |
Source Filename: $source_file
|
305 |
Server: $mosConfig_live_site
|
306 |
|
307 |
-
Powered by http://www.xcloner.com -
|
308 |
</pre>
|
309 |
|
310 |
";
|
@@ -329,14 +288,9 @@ include_once("classes/S3.php");
|
|
329 |
|
330 |
logxx();
|
331 |
|
332 |
-
|
333 |
-
$amazon_ssl = false;
|
334 |
-
else
|
335 |
-
$amazon_ssl = true;
|
336 |
-
|
337 |
-
$s3 = new S3($_CONFIG['cron_amazon_awsAccessKey'], $_CONFIG['cron_amazon_awsSecretKey'], $amazon_ssl);
|
338 |
|
339 |
-
logxx("AMAZON S3: Starting communication with the Amazon S3 server...
|
340 |
|
341 |
$buckets = $s3->listBuckets();
|
342 |
|
@@ -495,4 +449,3 @@ return $ok;
|
|
495 |
|
496 |
}
|
497 |
?>
|
498 |
-
|
14 |
@error_reporting(E_ALL^E_NOTICE);
|
15 |
@set_time_limit('3600');
|
16 |
define( '_VALID_MOS', 1 );
|
|
|
17 |
|
18 |
include_once("admin.cloner.html.php");
|
19 |
include_once("cloner.functions.php");
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
$script_dir = str_replace("\\","/",dirname(__FILE__));
|
23 |
if(is_dir($script_dir)){
|
31 |
if($argv[1] != ""){
|
32 |
|
33 |
$_REQUEST['config'] = $argv[1];
|
34 |
+
|
35 |
}
|
|
|
36 |
|
37 |
+
|
38 |
+
}
|
39 |
|
40 |
if($_REQUEST['config'] != ""){
|
41 |
|
82 |
|
83 |
|
84 |
####### VERIFY IP ACCESS
|
85 |
+
$ip_list = @explode("\r\n", $_CONFIG['cron_ip']);
|
86 |
$ip_list[] = $_SERVER['SERVER_ADDR'];
|
87 |
$curent_ip = $_SERVER["REMOTE_ADDR"];
|
88 |
|
91 |
echo "Access Denied for ip $curent_ip!";
|
92 |
exit;
|
93 |
|
94 |
+
}
|
95 |
#########################
|
96 |
|
97 |
$access=1;
|
169 |
logxx("Backup file: ".$source_file);
|
170 |
$bsize = getFileSizeText(filesize($source_file));
|
171 |
|
172 |
+
if($_CONFIG['cron_send']==1){
|
173 |
+
######################################STARTING FTP TRANSFER##################
|
174 |
+
|
175 |
+
logxx("Starting ftp transfer:");
|
176 |
+
|
177 |
+
$source_files[] = $source_file;
|
178 |
+
$destination_files[] = $_CONFIG[cron_ftp_path]."/".$file;
|
179 |
+
|
180 |
+
|
181 |
+
|
182 |
+
// set up basic connection details
|
183 |
+
list($fhost, $fport) = explode(":",$_CONFIG[cron_ftp_server]);
|
184 |
+
if($fport == "")
|
185 |
+
$fport = '21';
|
186 |
+
|
187 |
+
$ftp_timeout = '3600';
|
188 |
+
|
189 |
+
// set up basic connection
|
190 |
+
if(!$_CONFIG[secure_ftp]){
|
191 |
+
$conn_id = ftp_connect($fhost, (int)$fport, (int)$ftp_timeout);
|
192 |
+
$connect = "Normal";
|
193 |
+
}
|
194 |
+
else{
|
195 |
+
$conn_id = ftp_ssl_connect($fhost, (int)$fport, (int)$ftp_timeout);
|
196 |
+
$connect = "Secure";
|
197 |
+
}
|
198 |
+
|
199 |
+
//$conn_id = ftp_connect($_CONFIG[cron_ftp_server]) or die("Could not connect to the ftp server ".$_CONFIG[cron_ftp_server]);
|
200 |
+
|
201 |
+
// login with username and password
|
202 |
+
$login_result = ftp_login($conn_id, $_CONFIG[cron_ftp_user], $_CONFIG[cron_ftp_pass])
|
203 |
+
or die("Authentification failed when connecting to the ftp server for user ".$_CONFIG[cron_ftp_user]." with pass".$_CONFIG[cron_ftp_pass]);
|
204 |
+
|
205 |
+
// check connection
|
206 |
+
if ((!$conn_id) || (!$login_result)) {
|
207 |
+
echo "<b style='color:red'>FTP connection has failed!</b>";
|
208 |
+
echo "<b style='color:red'>Attempted to connect to ".$_CONFIG[cron_ftp_server]." for user ".$_CONFIG[cron_ftp_user]."</b>";
|
209 |
+
return;
|
210 |
+
} else {
|
211 |
+
#echo "Connected to $_REQUEST[ftp_server], for user $_REQUEST[ftp_user]";
|
212 |
+
}
|
213 |
+
|
214 |
+
if($_CONFIG['system_ftptransfer']==1)
|
215 |
{
|
216 |
+
// turn passive mode on
|
217 |
+
@ftp_pasv($conn_id, true);
|
218 |
+
$mode = "Passive";
|
219 |
+
}
|
220 |
+
else
|
221 |
+
{
|
222 |
+
// turn passive mode off
|
223 |
+
@ftp_pasv($conn_id, false);
|
224 |
+
$mode = "Active";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
}
|
226 |
+
echo "Connected to $connect <b>$_CONFIG[cron_ftp_server] Mode: $mode</b><br />";
|
227 |
+
for($i=0;$i<sizeof($source_files);$i++)
|
228 |
{
|
229 |
+
// upload the file
|
230 |
+
$upload = ftp_put($conn_id, $destination_files[$i], $source_files[$i], FTP_BINARY);
|
231 |
+
|
232 |
+
// check upload status
|
233 |
+
if (!$upload) {
|
234 |
+
echo "<b style='color:red'>FTP upload has failed for file $source_files[$i] ! Stopping ....<br /></b>";return;
|
235 |
+
} else {
|
236 |
+
echo "<b>Upload success from file <i>$source_files[$i]</i> <br />to <i>$destination_files[$i]</i> ...<br /></b>";
|
237 |
+
}
|
238 |
+
|
239 |
+
}
|
240 |
+
|
241 |
+
// close the FTP stream
|
242 |
+
ftp_close($conn_id);
|
243 |
+
|
244 |
+
logxx("Ftp transfer finished succesfully!");
|
245 |
+
|
246 |
+
if($_CONFIG[cron_ftp_delb]==1){
|
247 |
+
|
248 |
+
@unlink($source_file);
|
249 |
+
logxx("Backup succesfully deleted from the original server!");
|
250 |
+
}
|
251 |
+
|
252 |
+
##############################################################################
|
253 |
+
}
|
254 |
+
elseif($_CONFIG['cron_send']==2){
|
255 |
#######################################STARTING Email TRANSFER################
|
256 |
logxx("Sending mail with backup");
|
257 |
|
263 |
Source Filename: $source_file
|
264 |
Server: $mosConfig_live_site
|
265 |
|
266 |
+
Powered by http://www.xcloner.com - Xcloner - Backup and Restore made easy!
|
267 |
</pre>
|
268 |
|
269 |
";
|
288 |
|
289 |
logxx();
|
290 |
|
291 |
+
$s3 = new S3($_CONFIG['cron_amazon_awsAccessKey'], $_CONFIG['cron_amazon_awsSecretKey']);
|
|
|
|
|
|
|
|
|
|
|
292 |
|
293 |
+
logxx("AMAZON S3: Starting communication with the Amazon S3 server...");
|
294 |
|
295 |
$buckets = $s3->listBuckets();
|
296 |
|
449 |
|
450 |
}
|
451 |
?>
|
|
cloner.functions.php
CHANGED
@@ -20,16 +20,14 @@
|
|
20 |
* MA 02110-1301, USA.
|
21 |
*/
|
22 |
|
23 |
-
/** ensure this file is being included by a parent file */
|
24 |
-
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
|
25 |
-
|
26 |
-
|
27 |
/*
|
28 |
* Process the logout request
|
29 |
* name: doLogout()
|
30 |
* @param
|
31 |
* @return
|
32 |
*/
|
|
|
|
|
33 |
function doLogout()
|
34 |
{
|
35 |
if (function_exists('session_unregister')) {
|
@@ -123,8 +121,7 @@
|
|
123 |
|
124 |
function fdefault()
|
125 |
{
|
126 |
-
|
127 |
-
$html->_FDefault();
|
128 |
}
|
129 |
|
130 |
function config($option)
|
@@ -142,13 +139,13 @@
|
|
142 |
if ($fp = @fopen($config_file, 'w')) {
|
143 |
$cfg = '<?' . 'php' . "\n";
|
144 |
|
145 |
-
$cfg .= '$_CONFIG[\'license_code\']
|
146 |
|
147 |
$cfg .= '$_CONFIG[\'backup_path\']="' . $_REQUEST[backup_path] . '";' . "\n";
|
148 |
|
149 |
$cfg .= '$_CONFIG[\'clonerPath\']="' . $_REQUEST[clonerPath] . '";' . "\n";
|
150 |
|
151 |
-
$cfg .= '$_CONFIG[\'jcuser\']
|
152 |
|
153 |
if ($_REQUEST['jcpass'] == '') {
|
154 |
$jcpass = $_CONFIG['jcpass'];
|
@@ -162,7 +159,7 @@
|
|
162 |
|
163 |
$cfg .= '$_CONFIG[\'mysql_host\']="' . $_REQUEST[mysql_host] . '";' . "\n";
|
164 |
|
165 |
-
$cfg .= '$_CONFIG[\'mysql_user\']
|
166 |
|
167 |
$cfg .= '$_CONFIG[\'mysql_pass\']=\'' . $_REQUEST[mysql_pass] . '\';' . "\n";
|
168 |
|
@@ -190,7 +187,7 @@
|
|
190 |
|
191 |
$cfg .= '$_CONFIG[\'cron_ftp_server\']="' . $_REQUEST[cron_ftp_server] . '";' . "\n";
|
192 |
|
193 |
-
$cfg .= '$_CONFIG[\'cron_ftp_user\']
|
194 |
|
195 |
$cfg .= '$_CONFIG[\'cron_ftp_pass\']=\'' . $_REQUEST[cron_ftp_pass] . '\';' . "\n";
|
196 |
|
@@ -216,12 +213,6 @@
|
|
216 |
|
217 |
$cfg .= '$_CONFIG[\'refresh_mode\']="' . $_REQUEST[refresh_mode] . '";' . "\n";
|
218 |
|
219 |
-
$cfg .= '$_CONFIG[\'recordsPerSession\']="' . $_REQUEST[recordsPerSession] . '";' . "\n";
|
220 |
-
|
221 |
-
$cfg .= '$_CONFIG[\'excludeFilesSize\']="' . $_REQUEST[excludeFilesSize] . '";' . "\n";
|
222 |
-
|
223 |
-
$cfg .= '$_CONFIG[\'splitBackupSize\']="' . $_REQUEST[splitBackupSize] . '";' . "\n";
|
224 |
-
|
225 |
$cfg .= '$_CONFIG[\'backup_refresh_number\']="' . $_REQUEST[backup_refresh_number] . '";' . "\n";
|
226 |
|
227 |
$cfg .= '$_CONFIG[\'sql_mem\']="' . $_REQUEST[sql_mem] . '";' . "\n";
|
@@ -246,15 +237,13 @@
|
|
246 |
|
247 |
$cfg .= '$_CONFIG[\'cron_amazon_active\']="' . $_REQUEST[cron_amazon_active] . '";' . "\n";
|
248 |
|
249 |
-
$cfg .= '$_CONFIG[\'cron_amazon_awsAccessKey\']
|
250 |
|
251 |
-
$cfg .= '$_CONFIG[\'cron_amazon_awsSecretKey\']
|
252 |
|
253 |
-
$cfg .= '$_CONFIG[\'cron_amazon_bucket\']
|
254 |
|
255 |
-
$cfg .= '$_CONFIG[\'cron_amazon_dirname\']
|
256 |
-
|
257 |
-
$cfg .= '$_CONFIG[\'cron_amazon_ssl\']=\'' . $_REQUEST[cron_amazon_ssl] . '\';' . "\n";
|
258 |
|
259 |
$cfg .= '$_CONFIG[\'debug\']="' . $_REQUEST[debug] . '";' . "\n";
|
260 |
|
@@ -277,7 +266,7 @@
|
|
277 |
} else {
|
278 |
|
279 |
|
280 |
-
$msg = "Unable to save
|
281 |
}
|
282 |
}
|
283 |
|
@@ -289,8 +278,7 @@
|
|
289 |
E_print($msg);
|
290 |
}
|
291 |
}
|
292 |
-
|
293 |
-
$html->Config($option);
|
294 |
}
|
295 |
|
296 |
//## JoomlaCloner Language Manager
|
@@ -316,8 +304,7 @@
|
|
316 |
mosRedirect('index2.php?option=' . $option . "&task=lang", $msg);
|
317 |
}
|
318 |
|
319 |
-
$
|
320 |
-
$html->Translator($option, $lang_array);
|
321 |
}
|
322 |
|
323 |
function translator_add($option, $task)
|
@@ -343,9 +330,9 @@
|
|
343 |
|
344 |
mosRedirect('index2.php?option=' . $option . "&task=lang", $msg);
|
345 |
}
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
}
|
350 |
function translator_edit($option, $task)
|
351 |
{
|
@@ -427,15 +414,14 @@
|
|
427 |
|
428 |
|
429 |
if ($lang == 'english') {
|
430 |
-
$
|
431 |
-
$html->Translator_Edit_DEFAULT($option, $content, $file, $lang);
|
432 |
} else {
|
433 |
$def_data = get_lang_data($dfile);
|
434 |
$cur_data = get_lang_data($file);
|
435 |
|
436 |
$data = array_merge($def_data, $cur_data);
|
437 |
-
|
438 |
-
|
439 |
}
|
440 |
}
|
441 |
|
@@ -483,103 +469,11 @@
|
|
483 |
return $lang_arr;
|
484 |
}
|
485 |
|
486 |
-
function goRecurseDatabases(){
|
487 |
-
global $_CONFIG;
|
488 |
-
|
489 |
-
include_once("classes/mysqlBackup.class.php");
|
490 |
-
|
491 |
-
$return = array();
|
492 |
-
|
493 |
-
$data['dbHostname'] = $_CONFIG['mysql_host'];
|
494 |
-
$data['dbUsername'] = $_CONFIG['mysql_user'];
|
495 |
-
$data['dbPassword'] = $_CONFIG['mysql_pass'];
|
496 |
-
$data['dbDatabase'] = $_CONFIG['mysql_database'];
|
497 |
-
$data['excludedTables'] = "";
|
498 |
-
$data['recordsPerSession'] = $_CONFIG['recordsPerSession'];
|
499 |
-
$data['dbCompatibility'] = $_REQUEST['dbbackup_comp']; //version compatibility
|
500 |
-
$data['dbDropSyntax'] = $_REQUEST['dbbackup_drop']; //Add DROP Syntax
|
501 |
-
|
502 |
-
$data['TEMP_DUMP_FILE'] = $_CONFIG['temp_dir']."/database-sql.sql";
|
503 |
-
$data['TEMP_DBPROCESS_FILE'] = $_CONFIG['temp_dir']."/.database";
|
504 |
-
|
505 |
-
if($_REQUEST['mode'] == "start"){
|
506 |
-
//do the initial table readings
|
507 |
-
|
508 |
-
//foreach($_REQUEST['excltables'] as $value) //check if any tables are excluded, we will only export their structure
|
509 |
-
$data['excludedTables'] = $_REQUEST['excltables'];
|
510 |
-
|
511 |
-
//foreach($_REQUEST['excltables'] as $value) //check if any other databases are included
|
512 |
-
$extradb = $_REQUEST['databases_incl'];
|
513 |
-
|
514 |
-
$db = new DB();
|
515 |
-
$db->init($data, 1);
|
516 |
-
$db->writeTempFile();
|
517 |
-
$db->disconnect();
|
518 |
-
|
519 |
-
//building the .database temp file
|
520 |
-
if(is_array($extradb))
|
521 |
-
foreach($extradb as $database){
|
522 |
-
$data['dbDatabase'] = $database;
|
523 |
-
$data['TEMP_DUMP_FILE'] = $_CONFIG['temp_dir']."/".$data['dbDatabase']."-sql.sql";
|
524 |
-
$db = new DB();
|
525 |
-
$db->init($data);
|
526 |
-
$db->writeTempFile();
|
527 |
-
$db->disconnect();
|
528 |
-
|
529 |
-
}
|
530 |
-
|
531 |
-
return;
|
532 |
-
}
|
533 |
-
|
534 |
-
//we start the backup process for the actual database
|
535 |
-
|
536 |
-
$data['dbDatabase'] = "";
|
537 |
-
$dumpfile = "";
|
538 |
-
$data['dbCompatibility'] = $_REQUEST['dbbackup_comp']; //version compatibility
|
539 |
-
$data['dbDropSyntax'] = $_REQUEST['dbbackup_drop']; //Add DROP Syntax
|
540 |
-
$startAtLine = intval($_REQUEST['startAtLine']);
|
541 |
-
$startAtRecord = intval($_REQUEST['startAtRecord']);
|
542 |
-
$dumpfile = $_REQUEST['dumpfile'];
|
543 |
-
|
544 |
-
$db = new DB();
|
545 |
-
$db->init($data);
|
546 |
-
|
547 |
-
$records = $db->resetcountRecords();
|
548 |
-
|
549 |
-
while(($records < $_CONFIG['recordsPerSession']) and (!$return['finished']) and(!$return['newDump']) and(!$return['endDump'])){
|
550 |
-
|
551 |
-
$return = $db->processIncremental($startAtLine, $startAtRecord, $dumpfile);
|
552 |
-
|
553 |
-
$records = $db->getcountRecords();
|
554 |
-
$startAtLine = $return['startAtLine'];
|
555 |
-
$startAtRecord = $return['startAtRecord'];
|
556 |
-
$dumpfile = $return['dumpfile'];
|
557 |
-
|
558 |
-
}
|
559 |
-
|
560 |
-
/*if($return['newDump'])
|
561 |
-
print_r($return);*/
|
562 |
-
/*$startAtLine = $return['startAtLine'];
|
563 |
-
$startAtRecord = $return['startAtRecord'];
|
564 |
-
$dumpfile = $return['dumpfile'];*/
|
565 |
-
|
566 |
-
$return['dbbackup_comp'] = $_REQUEST['dbbackup_comp'];
|
567 |
-
$return['dbbackup_drop'] = $_REQUEST['dbbackup_drop'];
|
568 |
-
|
569 |
-
if($return['databaseName'] == "###enddump###")
|
570 |
-
$return['databaseName'] = "";
|
571 |
-
|
572 |
-
$db->disconnect();
|
573 |
-
|
574 |
-
echo json_encode($return);
|
575 |
-
exit;
|
576 |
-
|
577 |
-
}
|
578 |
|
579 |
function goRecurseFiles(){
|
580 |
|
581 |
global $_CONFIG;
|
582 |
-
|
583 |
include_once("classes/fileRecursion.php");
|
584 |
|
585 |
$status['finished'] = "1";
|
@@ -587,18 +481,16 @@
|
|
587 |
|
588 |
$handle = new fileRecursion();
|
589 |
|
590 |
-
$
|
591 |
-
$
|
592 |
-
$
|
593 |
-
$
|
594 |
-
$
|
595 |
-
$dataInit['EXCLUDE_FILES_SIZE'] = $_CONFIG['excludeFilesSize'];
|
596 |
-
$dataInit['TEMP_OVERSIZED_FILE'] = $_CONFIG['temp_dir']."/.oversized_files";
|
597 |
|
598 |
-
$handle->setData($
|
599 |
|
600 |
if($_REQUEST['mode'] == 'start')
|
601 |
-
$handle->init($_CONFIG['
|
602 |
else
|
603 |
$handle->init();
|
604 |
|
@@ -613,15 +505,10 @@
|
|
613 |
|
614 |
if(!$handle->isQueueFinished())
|
615 |
$status['finished'] = "0";
|
616 |
-
|
617 |
-
|
618 |
-
if(intval($_CONFIG['EXCLUDE_FILES_SIZE']) > -1){
|
619 |
-
$status['overlimit'] = $handle->getOverLimitFiles();
|
620 |
-
}
|
621 |
-
}
|
622 |
|
623 |
echo json_encode($status);
|
624 |
-
$handle->close();
|
625 |
exit;
|
626 |
|
627 |
}
|
@@ -650,8 +537,7 @@
|
|
650 |
getBackupFiles($d_arr, $f_arr, $s_arr, $d, $f);
|
651 |
|
652 |
// load presentation layer
|
653 |
-
$
|
654 |
-
$html->showBackups($f_arr, $s_arr, $_CONFIG['clonerPath'], $option);
|
655 |
}
|
656 |
|
657 |
function moveBackup($option)
|
@@ -667,10 +553,8 @@
|
|
667 |
if ($_REQUEST['action'] == "connect") {
|
668 |
$ret = start_connect($_REQUEST[files]);
|
669 |
}
|
670 |
-
if (!$ret)
|
671 |
-
|
672 |
-
$html->TransferForm($option, $files_out);
|
673 |
-
}
|
674 |
}
|
675 |
|
676 |
function start_connect($files)
|
@@ -902,14 +786,14 @@
|
|
902 |
}
|
903 |
|
904 |
|
905 |
-
|
906 |
-
|
907 |
}
|
908 |
function downloadBackup($file)
|
909 |
{
|
910 |
global $_CONFIG;
|
911 |
|
912 |
-
$file =
|
913 |
|
914 |
//First, see if the file exists
|
915 |
if (!is_file($file)) {
|
@@ -923,65 +807,74 @@
|
|
923 |
|
924 |
//Setam Content-Type-urile pentru fisierul in cauza
|
925 |
switch ($file_extension) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
926 |
default:
|
927 |
$ctype = "application/force-download";
|
928 |
}
|
929 |
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
{ if(!file_exists($location))
|
937 |
-
{ header ("HTTP/1.0 404 Not Found");
|
938 |
-
return;
|
939 |
-
}
|
940 |
|
941 |
-
|
942 |
-
|
943 |
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
$end=$size;
|
952 |
-
|
953 |
-
if(isset($_SERVER['HTTP_RANGE']))
|
954 |
-
{ if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches))
|
955 |
-
{ $begin=intval($matches[0]);
|
956 |
-
if(!empty($matches[1]))
|
957 |
-
$end=intval($matches[1]);
|
958 |
-
}
|
959 |
-
}
|
960 |
-
|
961 |
-
if($begin>0||$end<$size)
|
962 |
-
header('HTTP/1.0 206 Partial Content');
|
963 |
-
else
|
964 |
-
header('HTTP/1.0 200 OK');
|
965 |
-
|
966 |
-
header("Content-Type: $mimeType");
|
967 |
-
header('Cache-Control: public, must-revalidate, max-age=0');
|
968 |
-
header('Pragma: no-cache');
|
969 |
-
header('Accept-Ranges: bytes');
|
970 |
-
header('Content-Length:'.($end-$begin));
|
971 |
-
header("Content-Range: bytes $begin-$end/$size");
|
972 |
-
header("Content-Disposition: inline; filename=$filename");
|
973 |
-
header("Content-Transfer-Encoding: binary\n");
|
974 |
-
header("Last-Modified: $time");
|
975 |
-
header('Connection: close');
|
976 |
-
|
977 |
-
$cur=$begin;
|
978 |
-
fseek($fm,$begin,0);
|
979 |
-
|
980 |
-
while(!feof($fm)&&$cur<$end&&(connection_status()==0))
|
981 |
-
{ print fread($fm,min(1024*16,$end-$cur));
|
982 |
-
$cur+=1024*16;
|
983 |
}
|
984 |
-
}
|
985 |
|
986 |
|
987 |
function confirmBackup($option)
|
@@ -1032,10 +925,9 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1032 |
}
|
1033 |
|
1034 |
// load presentation layer
|
1035 |
-
if ($option != 'nohtml')
|
1036 |
-
$
|
1037 |
-
|
1038 |
-
}else
|
1039 |
return $d_arr;
|
1040 |
}
|
1041 |
|
@@ -1073,9 +965,9 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1073 |
|
1074 |
$log = "";
|
1075 |
|
1076 |
-
$backup_file = $_CONFIG['
|
1077 |
|
1078 |
-
$perm_file = $_CONFIG['
|
1079 |
|
1080 |
|
1081 |
$lines = $_REQUEST['lines'];
|
@@ -1099,6 +991,7 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1099 |
|
1100 |
$url = "index2.php?option=com_cloner&task=refresh&json=$json&startf=$endf&lines=$lines&backup=$backup_filename&excl_manual=" . $_REQUEST['excl_manual'];
|
1101 |
|
|
|
1102 |
if ($endf >= $lines)
|
1103 |
$endf = $lines;
|
1104 |
else
|
@@ -1107,6 +1000,7 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1107 |
if ((int)$lines != 0)
|
1108 |
$percent = sprintf("%d", ($endf * 100) / (int)$lines);
|
1109 |
|
|
|
1110 |
$log .= "Total process: $percent% out of $lines files<br />\n";
|
1111 |
$log .= "Processing files $startf to $endf for backup file $backup_file!<br />\n";
|
1112 |
$log .= "Current backup size: " . getFileSizeText(get_filesize($backup_file)) . "<br /><br />\n";
|
@@ -1128,23 +1022,6 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1128 |
//## appending files
|
1129 |
$log .= "file - $file";
|
1130 |
|
1131 |
-
if(intval($_CONFIG['splitBackupSize']) > 0){
|
1132 |
-
|
1133 |
-
$fileSize = intval($buffer[2]);
|
1134 |
-
$backupSize = get_filesize($backup_file);
|
1135 |
-
$limit = $_CONFIG['splitBackupSize']*1024*1024; //MB limit
|
1136 |
-
|
1137 |
-
//check if the size is bigger than $_CONFIF['splitBackupSize'] and split backup
|
1138 |
-
if(($fileSize+$backupSize) > $limit){
|
1139 |
-
|
1140 |
-
$backup_filename = getNewBackupName($backup_filename);
|
1141 |
-
//exit;
|
1142 |
-
$backup_file = $_CONFIG['backup_store_path']."/".$backup_filename;
|
1143 |
-
|
1144 |
-
}
|
1145 |
-
|
1146 |
-
}
|
1147 |
-
|
1148 |
|
1149 |
if (!$_CONFIG['mem']) {
|
1150 |
//### CREATE BACKUP USING TAR LIBRARIES
|
@@ -1178,7 +1055,7 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1178 |
}
|
1179 |
|
1180 |
//exit;
|
1181 |
-
$newFileSize = get_filesize($backup_file);
|
1182 |
$log .= "\n<br />New backup size: " . $newFileSize . "<br />\n";
|
1183 |
|
1184 |
addXLog($log);
|
@@ -1193,21 +1070,21 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1193 |
//# REDIRECTING
|
1194 |
@fclose($fperm);
|
1195 |
|
1196 |
-
$log .= "<br>All done, redirecting
|
1197 |
|
1198 |
$log .= "
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
|
1204 |
-
|
1205 |
-
//redirect();
|
1206 |
|
1207 |
-
|
1208 |
}
|
1209 |
-
|
1210 |
} else {
|
|
|
|
|
1211 |
$log .= "Unable to continue, could not open file $perm_file for reading!";
|
1212 |
}
|
1213 |
|
@@ -1221,10 +1098,10 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1221 |
$status['finished'] = 1;
|
1222 |
}
|
1223 |
|
1224 |
-
|
1225 |
-
|
1226 |
}
|
1227 |
-
|
1228 |
$status['backupSize'] = $newFileSize;
|
1229 |
$status['percent'] = $percent;
|
1230 |
$status['option'] = 'com_cloner';
|
@@ -1238,7 +1115,7 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1238 |
echo json_encode($status);
|
1239 |
exit;
|
1240 |
|
1241 |
-
|
1242 |
|
1243 |
return;
|
1244 |
}
|
@@ -1257,7 +1134,9 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1257 |
if (!$_CONFIG['enable_db_backup']) {
|
1258 |
$backupDatabase = 0;
|
1259 |
} else {
|
1260 |
-
|
|
|
|
|
1261 |
}
|
1262 |
|
1263 |
if ($_REQUEST[cron_access]) {
|
@@ -1294,6 +1173,8 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1294 |
$f_ext = '.tgz';
|
1295 |
$_CONFIG['tarcompress'] = 'z';
|
1296 |
} else {
|
|
|
|
|
1297 |
$f_ext = '.tar';
|
1298 |
$_CONFIG['tarcompress'] = '';
|
1299 |
}
|
@@ -1323,15 +1204,6 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1323 |
$filename1 = $_REQUEST['bname'] . $f_ext;
|
1324 |
}
|
1325 |
|
1326 |
-
//check if comments are set
|
1327 |
-
if($_REQUEST['backupComments'] != "")
|
1328 |
-
writeComments($_REQUEST['backupComments']);
|
1329 |
-
|
1330 |
-
//we created the backup name, but skip sql at this step, we will do it incrementally
|
1331 |
-
if(($_CONFIG['refresh_mode']) and (!$_REQUEST[cron_access]))
|
1332 |
-
//we skip the backup at this process,we will do it incrementally
|
1333 |
-
$backupDatabase = 0;
|
1334 |
-
|
1335 |
$sql_file = array();
|
1336 |
|
1337 |
if ($backupDatabase == 1) {
|
@@ -1359,7 +1231,7 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1359 |
mysql_query("USE " . $_CONFIG['mysql_database']);
|
1360 |
}
|
1361 |
} else {
|
1362 |
-
|
1363 |
}
|
1364 |
|
1365 |
|
@@ -1452,24 +1324,22 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1452 |
|
1453 |
if(($_REQUEST['cron_access']) or (!$_CONFIG['refresh_mode'])){
|
1454 |
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
for ($i = 0; $i < sizeof($excluded); $i++) {
|
1460 |
-
$excluded[$i] = str_replace("//", "/", $excluded[$i]);
|
1461 |
-
}
|
1462 |
-
|
1463 |
-
// obtain the list of files by recursing the mambo file store
|
1464 |
-
addXLog("Starting the file scanning process");
|
1465 |
|
1466 |
-
|
|
|
|
|
1467 |
|
1468 |
-
|
|
|
1469 |
|
1470 |
-
|
|
|
|
|
1471 |
|
1472 |
-
|
1473 |
|
1474 |
|
1475 |
// format total archive size
|
@@ -1525,9 +1395,6 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1525 |
|
1526 |
if ($_CONFIG['backup_refresh']) {
|
1527 |
$f_arr = array($_CONFIG['backups_dir'] . "/index.html");
|
1528 |
-
$fp=@fopen($_CONFIG['backups_dir'] . "/index.html" , "w");
|
1529 |
-
if($fp)
|
1530 |
-
fclose($fp);
|
1531 |
}
|
1532 |
|
1533 |
|
@@ -1550,10 +1417,9 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1550 |
|
1551 |
if ($_CONFIG['backup_refresh']) {
|
1552 |
// echo "Starting the manual backup process!<br />";
|
1553 |
-
|
1554 |
-
|
1555 |
-
|
1556 |
-
$html->goRefreshHtml($filename, $perm_lines, $excl_manual);
|
1557 |
return;
|
1558 |
}
|
1559 |
|
@@ -1645,8 +1511,8 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1645 |
E_print("Backup failed, please check your tar server utility support!");
|
1646 |
return;
|
1647 |
}*/
|
1648 |
-
|
1649 |
-
|
1650 |
|
1651 |
return;
|
1652 |
}
|
@@ -1688,12 +1554,11 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1688 |
|
1689 |
// load presentation layer
|
1690 |
if ($option != 'nohtml') {
|
1691 |
-
|
1692 |
-
$html->generateBackup($filename1, $archiveSize, $originalSize, $mdir, $f, $databaseResult, $option);
|
1693 |
} else {
|
1694 |
|
1695 |
-
|
1696 |
-
logxx(
|
1697 |
}
|
1698 |
|
1699 |
if (is_array($databases_incl)) {
|
@@ -1717,8 +1582,7 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
1717 |
// ----------------------------------------------------------
|
1718 |
|
1719 |
// load presentation layer
|
1720 |
-
|
1721 |
-
$html->showHelp($option);
|
1722 |
}
|
1723 |
|
1724 |
|
@@ -2061,9 +1925,9 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
2061 |
$InsertDump = "INSERT INTO `$tblval` VALUES (";
|
2062 |
$arr = $row;
|
2063 |
foreach ($arr as $key => $value) {
|
2064 |
-
$value =
|
2065 |
-
|
2066 |
-
|
2067 |
//if (@preg_match ("/\b" . $FieldType[$tblval][$key] . "\b/i", "DATE TIME DATETIME CHAR VARCHAR TEXT TINYTEXT MEDIUMTEXT LONGTEXT BLOB TINYBLOB MEDIUMBLOB LONGBLOB ENUM SET"))
|
2068 |
{
|
2069 |
$InsertDump .= "'$value',";
|
@@ -2092,46 +1956,11 @@ function smartReadFile($location, $filename, $mimeType='application/octet-stream
|
|
2092 |
}
|
2093 |
}
|
2094 |
|
2095 |
-
function getNewBackupName($backupFilename){
|
2096 |
-
|
2097 |
-
$newFilename = $backupFilename;
|
2098 |
|
2099 |
-
|
2100 |
-
|
2101 |
-
|
2102 |
-
|
2103 |
-
|
2104 |
-
|
2105 |
-
$newFilename = str_replace(".$inc.$extension", "", $backupFilename); //ex, replace .1.tar
|
2106 |
-
$newFilename = $newFilename .".$newinc.$extension";
|
2107 |
-
}else{
|
2108 |
-
//it is a first backup, no .0.tar
|
2109 |
-
$newFilename = str_replace(".".$extension, "", $backupFilename); //ex, replace .1.tar
|
2110 |
-
$newFilename = $newFilename .".1.". $extension;
|
2111 |
-
}
|
2112 |
-
|
2113 |
-
return $newFilename;
|
2114 |
-
}
|
2115 |
-
|
2116 |
-
function writeComments($comments){
|
2117 |
-
global $_CONFIG;
|
2118 |
-
|
2119 |
-
$fp = @fopen($_CONFIG['commentsfile'], "w");
|
2120 |
-
if($fp){
|
2121 |
-
fwrite($fp, stripcslashes($comments));
|
2122 |
-
fclose($fp);
|
2123 |
-
}
|
2124 |
-
else{
|
2125 |
-
addXLog("Unable to write comments to file ".$_CONFIG['commentsfile']);
|
2126 |
-
}
|
2127 |
-
|
2128 |
-
|
2129 |
-
}
|
2130 |
-
|
2131 |
-
function getVersion()
|
2132 |
-
{
|
2133 |
-
$query = mysql_query("SELECT version()");
|
2134 |
-
$row = mysql_fetch_array($query);
|
2135 |
-
return $row[0];
|
2136 |
-
}
|
2137 |
?>
|
20 |
* MA 02110-1301, USA.
|
21 |
*/
|
22 |
|
|
|
|
|
|
|
|
|
23 |
/*
|
24 |
* Process the logout request
|
25 |
* name: doLogout()
|
26 |
* @param
|
27 |
* @return
|
28 |
*/
|
29 |
+
|
30 |
+
/*processing the Logout task*/
|
31 |
function doLogout()
|
32 |
{
|
33 |
if (function_exists('session_unregister')) {
|
121 |
|
122 |
function fdefault()
|
123 |
{
|
124 |
+
HTML_cloner::_FDefault();
|
|
|
125 |
}
|
126 |
|
127 |
function config($option)
|
139 |
if ($fp = @fopen($config_file, 'w')) {
|
140 |
$cfg = '<?' . 'php' . "\n";
|
141 |
|
142 |
+
$cfg .= '$_CONFIG[\'license_code\']="' . $_REQUEST[license_code] . '";' . "\n";
|
143 |
|
144 |
$cfg .= '$_CONFIG[\'backup_path\']="' . $_REQUEST[backup_path] . '";' . "\n";
|
145 |
|
146 |
$cfg .= '$_CONFIG[\'clonerPath\']="' . $_REQUEST[clonerPath] . '";' . "\n";
|
147 |
|
148 |
+
$cfg .= '$_CONFIG[\'jcuser\']="' . $_REQUEST[jcuser] . '";' . "\n";
|
149 |
|
150 |
if ($_REQUEST['jcpass'] == '') {
|
151 |
$jcpass = $_CONFIG['jcpass'];
|
159 |
|
160 |
$cfg .= '$_CONFIG[\'mysql_host\']="' . $_REQUEST[mysql_host] . '";' . "\n";
|
161 |
|
162 |
+
$cfg .= '$_CONFIG[\'mysql_user\']="' . $_REQUEST[mysql_user] . '";' . "\n";
|
163 |
|
164 |
$cfg .= '$_CONFIG[\'mysql_pass\']=\'' . $_REQUEST[mysql_pass] . '\';' . "\n";
|
165 |
|
187 |
|
188 |
$cfg .= '$_CONFIG[\'cron_ftp_server\']="' . $_REQUEST[cron_ftp_server] . '";' . "\n";
|
189 |
|
190 |
+
$cfg .= '$_CONFIG[\'cron_ftp_user\']="' . $_REQUEST[cron_ftp_user] . '";' . "\n";
|
191 |
|
192 |
$cfg .= '$_CONFIG[\'cron_ftp_pass\']=\'' . $_REQUEST[cron_ftp_pass] . '\';' . "\n";
|
193 |
|
213 |
|
214 |
$cfg .= '$_CONFIG[\'refresh_mode\']="' . $_REQUEST[refresh_mode] . '";' . "\n";
|
215 |
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
$cfg .= '$_CONFIG[\'backup_refresh_number\']="' . $_REQUEST[backup_refresh_number] . '";' . "\n";
|
217 |
|
218 |
$cfg .= '$_CONFIG[\'sql_mem\']="' . $_REQUEST[sql_mem] . '";' . "\n";
|
237 |
|
238 |
$cfg .= '$_CONFIG[\'cron_amazon_active\']="' . $_REQUEST[cron_amazon_active] . '";' . "\n";
|
239 |
|
240 |
+
$cfg .= '$_CONFIG[\'cron_amazon_awsAccessKey\']="' . $_REQUEST[cron_amazon_awsAccessKey] . '";' . "\n";
|
241 |
|
242 |
+
$cfg .= '$_CONFIG[\'cron_amazon_awsSecretKey\']="' . $_REQUEST[cron_amazon_awsSecretKey] . '";' . "\n";
|
243 |
|
244 |
+
$cfg .= '$_CONFIG[\'cron_amazon_bucket\']="' . $_REQUEST[cron_amazon_bucket] . '";' . "\n";
|
245 |
|
246 |
+
$cfg .= '$_CONFIG[\'cron_amazon_dirname\']="' . $_REQUEST[cron_amazon_dirname] . '";' . "\n";
|
|
|
|
|
247 |
|
248 |
$cfg .= '$_CONFIG[\'debug\']="' . $_REQUEST[debug] . '";' . "\n";
|
249 |
|
266 |
} else {
|
267 |
|
268 |
|
269 |
+
$msg = "Unable to save $fcron file, please make sure the folder is writeable!";
|
270 |
}
|
271 |
}
|
272 |
|
278 |
E_print($msg);
|
279 |
}
|
280 |
}
|
281 |
+
HTML_cloner::Config($option);
|
|
|
282 |
}
|
283 |
|
284 |
//## JoomlaCloner Language Manager
|
304 |
mosRedirect('index2.php?option=' . $option . "&task=lang", $msg);
|
305 |
}
|
306 |
|
307 |
+
HTML_cloner::Translator($option, $lang_array);
|
|
|
308 |
}
|
309 |
|
310 |
function translator_add($option, $task)
|
330 |
|
331 |
mosRedirect('index2.php?option=' . $option . "&task=lang", $msg);
|
332 |
}
|
333 |
+
|
334 |
+
|
335 |
+
HTML_cloner::Translator_Add($option);
|
336 |
}
|
337 |
function translator_edit($option, $task)
|
338 |
{
|
414 |
|
415 |
|
416 |
if ($lang == 'english') {
|
417 |
+
HTML_cloner::Translator_Edit_DEFAULT($option, $content, $file, $lang);
|
|
|
418 |
} else {
|
419 |
$def_data = get_lang_data($dfile);
|
420 |
$cur_data = get_lang_data($file);
|
421 |
|
422 |
$data = array_merge($def_data, $cur_data);
|
423 |
+
|
424 |
+
HTML_cloner::Translator_Edit($option, $data, $def_data, $file, $lang);
|
425 |
}
|
426 |
}
|
427 |
|
469 |
return $lang_arr;
|
470 |
}
|
471 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
472 |
|
473 |
function goRecurseFiles(){
|
474 |
|
475 |
global $_CONFIG;
|
476 |
+
|
477 |
include_once("classes/fileRecursion.php");
|
478 |
|
479 |
$status['finished'] = "1";
|
481 |
|
482 |
$handle = new fileRecursion();
|
483 |
|
484 |
+
$TEMP_PERM = $_CONFIG['backups_dir']."/perm.txt";
|
485 |
+
$TEMP_EXCL = $_CONFIG['exfile'];
|
486 |
+
$TEMP_D_ARR = $_CONFIG['backups_dir']."/.dir";
|
487 |
+
$TEMP_DIR = $_CONFIG['clonerPath'];
|
488 |
+
$START_DIR = $_CONFIG['backup_path'];
|
|
|
|
|
489 |
|
490 |
+
$handle->setData($TEMP_PERM,$TEMP_EXCL,$TEMP_D_ARR,$TEMP_DIR, $START_DIR);
|
491 |
|
492 |
if($_REQUEST['mode'] == 'start')
|
493 |
+
$handle->init($_CONFIG['backup_path']);
|
494 |
else
|
495 |
$handle->init();
|
496 |
|
505 |
|
506 |
if(!$handle->isQueueFinished())
|
507 |
$status['finished'] = "0";
|
508 |
+
|
509 |
+
|
|
|
|
|
|
|
|
|
510 |
|
511 |
echo json_encode($status);
|
|
|
512 |
exit;
|
513 |
|
514 |
}
|
537 |
getBackupFiles($d_arr, $f_arr, $s_arr, $d, $f);
|
538 |
|
539 |
// load presentation layer
|
540 |
+
HTML_cloner::showBackups($f_arr, $s_arr, $_CONFIG['clonerPath'], $option);
|
|
|
541 |
}
|
542 |
|
543 |
function moveBackup($option)
|
553 |
if ($_REQUEST['action'] == "connect") {
|
554 |
$ret = start_connect($_REQUEST[files]);
|
555 |
}
|
556 |
+
if (!$ret)
|
557 |
+
HTML_cloner::TransferForm($option, $files_out);
|
|
|
|
|
558 |
}
|
559 |
|
560 |
function start_connect($files)
|
786 |
}
|
787 |
|
788 |
|
789 |
+
|
790 |
+
HTML_Cloner::rename($files, $option);
|
791 |
}
|
792 |
function downloadBackup($file)
|
793 |
{
|
794 |
global $_CONFIG;
|
795 |
|
796 |
+
$file = $_CONFIG['clonerPath'] . "/$file";
|
797 |
|
798 |
//First, see if the file exists
|
799 |
if (!is_file($file)) {
|
807 |
|
808 |
//Setam Content-Type-urile pentru fisierul in cauza
|
809 |
switch ($file_extension) {
|
810 |
+
case "pdf":
|
811 |
+
$ctype = "application/pdf";
|
812 |
+
break;
|
813 |
+
case "exe":
|
814 |
+
$ctype = "application/octet-stream";
|
815 |
+
break;
|
816 |
+
case "zip":
|
817 |
+
$ctype = "application/zip";
|
818 |
+
break;
|
819 |
+
case "doc":
|
820 |
+
$ctype = "application/msword";
|
821 |
+
break;
|
822 |
+
case "xls":
|
823 |
+
$ctype = "application/vnd.ms-excel";
|
824 |
+
break;
|
825 |
+
case "ppt":
|
826 |
+
$ctype = "application/vnd.ms-powerpoint";
|
827 |
+
break;
|
828 |
+
case "gif":
|
829 |
+
$ctype = "image/gif";
|
830 |
+
break;
|
831 |
+
case "png":
|
832 |
+
$ctype = "image/png";
|
833 |
+
break;
|
834 |
+
case "jpeg":
|
835 |
+
case "jpg":
|
836 |
+
$ctype = "image/jpg";
|
837 |
+
break;
|
838 |
+
case "mp3":
|
839 |
+
$ctype = "audio/mpeg";
|
840 |
+
break;
|
841 |
+
case "wav":
|
842 |
+
$ctype = "audio/x-wav";
|
843 |
+
break;
|
844 |
+
case "mpeg":
|
845 |
+
case "mpg":
|
846 |
+
case "mpe":
|
847 |
+
$ctype = "video/mpeg";
|
848 |
+
break;
|
849 |
+
case "mov":
|
850 |
+
$ctype = "video/quicktime";
|
851 |
+
break;
|
852 |
+
case "avi":
|
853 |
+
$ctype = "video/x-msvideo";
|
854 |
+
break;
|
855 |
+
|
856 |
default:
|
857 |
$ctype = "application/force-download";
|
858 |
}
|
859 |
|
860 |
+
//Writing Headers
|
861 |
+
header("Pragma: public");
|
862 |
+
header("Expires: 0");
|
863 |
+
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
864 |
+
header("Cache-Control: public");
|
865 |
+
header("Content-Description: File Transfer");
|
|
|
|
|
|
|
|
|
866 |
|
867 |
+
//Content-Type-ul
|
868 |
+
header("Content-Type: $ctype");
|
869 |
|
870 |
+
//Force Download
|
871 |
+
$header = "Content-Disposition: attachment; filename=" . $filename . ";";
|
872 |
+
header($header);
|
873 |
+
header("Content-Transfer-Encoding: binary");
|
874 |
+
header("Content-Length: " . $len);
|
875 |
+
@readfile($file);
|
876 |
+
exit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
877 |
}
|
|
|
878 |
|
879 |
|
880 |
function confirmBackup($option)
|
925 |
}
|
926 |
|
927 |
// load presentation layer
|
928 |
+
if ($option != 'nohtml')
|
929 |
+
HTML_cloner::confirmBackups($d_arr, $ds_arr, $_CONFIG['clonerPath'], $option);
|
930 |
+
else
|
|
|
931 |
return $d_arr;
|
932 |
}
|
933 |
|
965 |
|
966 |
$log = "";
|
967 |
|
968 |
+
$backup_file = $_CONFIG['clonerPath']."/".$backup_filename ;
|
969 |
|
970 |
+
$perm_file = $_CONFIG['backups_dir'] . "/perm.txt";
|
971 |
|
972 |
|
973 |
$lines = $_REQUEST['lines'];
|
991 |
|
992 |
$url = "index2.php?option=com_cloner&task=refresh&json=$json&startf=$endf&lines=$lines&backup=$backup_filename&excl_manual=" . $_REQUEST['excl_manual'];
|
993 |
|
994 |
+
|
995 |
if ($endf >= $lines)
|
996 |
$endf = $lines;
|
997 |
else
|
1000 |
if ((int)$lines != 0)
|
1001 |
$percent = sprintf("%d", ($endf * 100) / (int)$lines);
|
1002 |
|
1003 |
+
|
1004 |
$log .= "Total process: $percent% out of $lines files<br />\n";
|
1005 |
$log .= "Processing files $startf to $endf for backup file $backup_file!<br />\n";
|
1006 |
$log .= "Current backup size: " . getFileSizeText(get_filesize($backup_file)) . "<br /><br />\n";
|
1022 |
//## appending files
|
1023 |
$log .= "file - $file";
|
1024 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1025 |
|
1026 |
if (!$_CONFIG['mem']) {
|
1027 |
//### CREATE BACKUP USING TAR LIBRARIES
|
1055 |
}
|
1056 |
|
1057 |
//exit;
|
1058 |
+
$newFileSize = getFileSizeText(get_filesize($backup_file));
|
1059 |
$log .= "\n<br />New backup size: " . $newFileSize . "<br />\n";
|
1060 |
|
1061 |
addXLog($log);
|
1070 |
//# REDIRECTING
|
1071 |
@fclose($fperm);
|
1072 |
|
1073 |
+
$log .= "<br>All done, redirecting in " . $_CONFIG['refresh_time'] . " seconds, or <a href='$url'>click here </a>";
|
1074 |
|
1075 |
$log .= "
|
1076 |
+
<script language='javascript'>
|
1077 |
+
function redirect(){
|
1078 |
+
window.location = '" . $url . "';
|
1079 |
+
}
|
1080 |
|
1081 |
+
setTimeout(\"redirect()\"," . $_CONFIG['refresh_time'] . "000);
|
|
|
1082 |
|
1083 |
+
</script>";
|
1084 |
}
|
|
|
1085 |
} else {
|
1086 |
+
|
1087 |
+
|
1088 |
$log .= "Unable to continue, could not open file $perm_file for reading!";
|
1089 |
}
|
1090 |
|
1098 |
$status['finished'] = 1;
|
1099 |
}
|
1100 |
|
1101 |
+
if(!$json){
|
1102 |
+
echo $log;
|
1103 |
}
|
1104 |
+
else{
|
1105 |
$status['backupSize'] = $newFileSize;
|
1106 |
$status['percent'] = $percent;
|
1107 |
$status['option'] = 'com_cloner';
|
1115 |
echo json_encode($status);
|
1116 |
exit;
|
1117 |
|
1118 |
+
}
|
1119 |
|
1120 |
return;
|
1121 |
}
|
1134 |
if (!$_CONFIG['enable_db_backup']) {
|
1135 |
$backupDatabase = 0;
|
1136 |
} else {
|
1137 |
+
|
1138 |
+
|
1139 |
+
$backupDatabase = $_REQUEST['dbbackup'];
|
1140 |
}
|
1141 |
|
1142 |
if ($_REQUEST[cron_access]) {
|
1173 |
$f_ext = '.tgz';
|
1174 |
$_CONFIG['tarcompress'] = 'z';
|
1175 |
} else {
|
1176 |
+
|
1177 |
+
|
1178 |
$f_ext = '.tar';
|
1179 |
$_CONFIG['tarcompress'] = '';
|
1180 |
}
|
1204 |
$filename1 = $_REQUEST['bname'] . $f_ext;
|
1205 |
}
|
1206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1207 |
$sql_file = array();
|
1208 |
|
1209 |
if ($backupDatabase == 1) {
|
1231 |
mysql_query("USE " . $_CONFIG['mysql_database']);
|
1232 |
}
|
1233 |
} else {
|
1234 |
+
$databaseResult = LM_DATABASE_EXCLUDED;
|
1235 |
}
|
1236 |
|
1237 |
|
1324 |
|
1325 |
if(($_REQUEST['cron_access']) or (!$_CONFIG['refresh_mode'])){
|
1326 |
|
1327 |
+
$perm_file = $_CONFIG['backups_dir'] . "/perm.txt";
|
1328 |
+
@unlink($perm_file);
|
1329 |
+
$fperm = fopen($perm_file, "w");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1330 |
|
1331 |
+
for ($i = 0; $i < sizeof($excluded); $i++) {
|
1332 |
+
$excluded[$i] = str_replace("//", "/", $excluded[$i]);
|
1333 |
+
}
|
1334 |
|
1335 |
+
// obtain the list of files by recursing the mambo file store
|
1336 |
+
addXLog("Starting the file scanning process");
|
1337 |
|
1338 |
+
recurseFiles($d_arr, $ds_arr, $f_arr, $s_arr, $d, $f, $s, $includeFolder, '', $excluded, $fperm);
|
1339 |
+
@fclose($fperm);
|
1340 |
+
@chmod($perm_file, 0777);
|
1341 |
|
1342 |
+
}
|
1343 |
|
1344 |
|
1345 |
// format total archive size
|
1395 |
|
1396 |
if ($_CONFIG['backup_refresh']) {
|
1397 |
$f_arr = array($_CONFIG['backups_dir'] . "/index.html");
|
|
|
|
|
|
|
1398 |
}
|
1399 |
|
1400 |
|
1417 |
|
1418 |
if ($_CONFIG['backup_refresh']) {
|
1419 |
// echo "Starting the manual backup process!<br />";
|
1420 |
+
echo "<h3>Database backup: </h3>" . $databaseResult . "<br /><br />";
|
1421 |
+
|
1422 |
+
HTML_cloner::goRefreshHtml($filename, $perm_lines, $excl_manual);
|
|
|
1423 |
return;
|
1424 |
}
|
1425 |
|
1511 |
E_print("Backup failed, please check your tar server utility support!");
|
1512 |
return;
|
1513 |
}*/
|
1514 |
+
|
1515 |
+
HTML_cloner::goRefreshHtml($filename, $perm_lines, $excl_manual);
|
1516 |
|
1517 |
return;
|
1518 |
}
|
1554 |
|
1555 |
// load presentation layer
|
1556 |
if ($option != 'nohtml') {
|
1557 |
+
HTML_cloner::generateBackup($filename1, $archiveSize, $originalSize, $mdir, $f, $databaseResult, $option);
|
|
|
1558 |
} else {
|
1559 |
|
1560 |
+
|
1561 |
+
logxx(HTML_cloner::generateBackup_text($filename1, $archiveSize, $originalSize, $mdir, $f, $databaseResult, $option));
|
1562 |
}
|
1563 |
|
1564 |
if (is_array($databases_incl)) {
|
1582 |
// ----------------------------------------------------------
|
1583 |
|
1584 |
// load presentation layer
|
1585 |
+
HTML_cloner::showHelp($option);
|
|
|
1586 |
}
|
1587 |
|
1588 |
|
1925 |
$InsertDump = "INSERT INTO `$tblval` VALUES (";
|
1926 |
$arr = $row;
|
1927 |
foreach ($arr as $key => $value) {
|
1928 |
+
$value = addslashes($value);
|
1929 |
+
$value = str_replace("\n", '\r\n', $value);
|
1930 |
+
$value = str_replace("\r", '', $value);
|
1931 |
//if (@preg_match ("/\b" . $FieldType[$tblval][$key] . "\b/i", "DATE TIME DATETIME CHAR VARCHAR TEXT TINYTEXT MEDIUMTEXT LONGTEXT BLOB TINYBLOB MEDIUMBLOB LONGBLOB ENUM SET"))
|
1932 |
{
|
1933 |
$InsertDump .= "'$value',";
|
1956 |
}
|
1957 |
}
|
1958 |
|
|
|
|
|
|
|
1959 |
|
1960 |
+
function getVersion()
|
1961 |
+
{
|
1962 |
+
$query = mysql_query("SELECT version()");
|
1963 |
+
$row = mysql_fetch_array($query);
|
1964 |
+
return $row[0];
|
1965 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1966 |
?>
|
common.php
CHANGED
@@ -1,56 +1,31 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
/** ensure this file is being included by a parent file */
|
24 |
-
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
|
25 |
-
|
26 |
if ((!extension_loaded('zlib')) &&(function_exists('ob_start'))) {
|
27 |
ob_end_clean();
|
28 |
ob_start('ob_gzhandler');
|
29 |
-
}
|
30 |
|
31 |
####################################
|
32 |
|
33 |
$_CONFIG['multiple_config_dir'] = "configs";
|
34 |
-
//$strlen = strlen($_CONFIG['backup_path']);
|
35 |
-
//if((substr($_CONFIG['backup_path'], $strlen-1, $strlen) != '/') && (substr($_CONFIG['backup_path'], $strlen-1, $strlen) != '\\'))
|
36 |
-
// $_CONFIG['backup_path'] .= "/";
|
37 |
-
|
38 |
-
#$_CONFIG['backup_path'] = realpath($_CONFIG['backup_path'])."/";
|
39 |
-
#$_CONFIG['backups_dir'] = realpath($_CONFIG['backup_path'])."/administrator/backups";
|
40 |
|
41 |
-
$_CONFIG['backup_path'] = ($_CONFIG['backup_path']);
|
42 |
-
$_CONFIG['backups_dir'] =
|
43 |
|
44 |
$_CONFIG['backup_path'] = str_replace("\\","/", $_CONFIG['backup_path']);
|
45 |
$_CONFIG['backups_dir'] = str_replace("\\","/", $_CONFIG['backups_dir']);
|
46 |
|
47 |
-
|
48 |
$_CONFIG['exfile'] = $_CONFIG['backups_dir']."/.excl";
|
49 |
$_CONFIG['exfile_tar'] = $_CONFIG['backups_dir']."/.excl_tar";
|
50 |
-
|
51 |
-
$_CONFIG['logfile'] = $_CONFIG['backups_dir']."/xcloner.log";
|
52 |
-
$_CONFIG['commentsfile'] = $_CONFIG['backups_dir']."/.comments"; #$_REQUEST['backupComments']
|
53 |
-
|
54 |
$_CONFIG['script_path'] = str_replace("\\","/",dirname(__FILE__));
|
55 |
|
56 |
$lang_dir = "language";
|
@@ -62,7 +37,7 @@ $task = $_REQUEST['task'];
|
|
62 |
if($_CONFIG['enable_db_backup']){
|
63 |
|
64 |
### Connecting to the mysql server
|
65 |
-
|
66 |
E_print("Could not connect: " . mysql_error());
|
67 |
@mysql_select_db($_CONFIG['mysql_database']) or E_print("Unable to select database ".$_CONFIG['mysql_database']);
|
68 |
@mysql_query("SET NAMES 'utf8'");
|
@@ -80,20 +55,17 @@ if (file_exists( "language/".$mosConfig_lang.".php" )) {
|
|
80 |
|
81 |
@include_once( "language/english.php" );
|
82 |
|
83 |
-
}
|
84 |
|
85 |
else{
|
86 |
-
|
87 |
include_once( "language/english.php" );
|
88 |
-
|
89 |
}
|
90 |
|
91 |
$version = str_replace(".", "", phpversion());
|
92 |
-
if
|
93 |
$_CONFIG['refresh_mode']="0";
|
94 |
}
|
95 |
-
|
96 |
-
if (!$_CONFIG['backup_refresh']) {
|
97 |
$_CONFIG['refresh_mode']="0";
|
98 |
}
|
99 |
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* XCloner
|
4 |
+
* Oficial website: http://www.joomlaplug.com/
|
5 |
+
* -------------------------------------------
|
6 |
+
* Creator: Liuta Romulus Ovidiu
|
7 |
+
* License: All Rights Reserved
|
8 |
+
* Email: admin@joomlaplug.com
|
9 |
+
* Revision: 1.0
|
10 |
+
* Date: July 2007
|
11 |
+
**/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
if ((!extension_loaded('zlib')) &&(function_exists('ob_start'))) {
|
13 |
ob_end_clean();
|
14 |
ob_start('ob_gzhandler');
|
15 |
+
}
|
16 |
|
17 |
####################################
|
18 |
|
19 |
$_CONFIG['multiple_config_dir'] = "configs";
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
+
$_CONFIG['backup_path'] = realpath($_CONFIG['backup_path'])."/";
|
22 |
+
$_CONFIG['backups_dir'] = realpath($_CONFIG['backup_path'])."/administrator/backups";
|
23 |
|
24 |
$_CONFIG['backup_path'] = str_replace("\\","/", $_CONFIG['backup_path']);
|
25 |
$_CONFIG['backups_dir'] = str_replace("\\","/", $_CONFIG['backups_dir']);
|
26 |
|
|
|
27 |
$_CONFIG['exfile'] = $_CONFIG['backups_dir']."/.excl";
|
28 |
$_CONFIG['exfile_tar'] = $_CONFIG['backups_dir']."/.excl_tar";
|
|
|
|
|
|
|
|
|
29 |
$_CONFIG['script_path'] = str_replace("\\","/",dirname(__FILE__));
|
30 |
|
31 |
$lang_dir = "language";
|
37 |
if($_CONFIG['enable_db_backup']){
|
38 |
|
39 |
### Connecting to the mysql server
|
40 |
+
@mysql_connect($_CONFIG['mysql_host'], $_CONFIG['mysql_user'], $_CONFIG['mysql_pass']) or
|
41 |
E_print("Could not connect: " . mysql_error());
|
42 |
@mysql_select_db($_CONFIG['mysql_database']) or E_print("Unable to select database ".$_CONFIG['mysql_database']);
|
43 |
@mysql_query("SET NAMES 'utf8'");
|
55 |
|
56 |
@include_once( "language/english.php" );
|
57 |
|
58 |
+
}
|
59 |
|
60 |
else{
|
|
|
61 |
include_once( "language/english.php" );
|
|
|
62 |
}
|
63 |
|
64 |
$version = str_replace(".", "", phpversion());
|
65 |
+
if($version < 520){
|
66 |
$_CONFIG['refresh_mode']="0";
|
67 |
}
|
68 |
+
if($_CONFIG['backup_refresh'] == "0"){
|
|
|
69 |
$_CONFIG['refresh_mode']="0";
|
70 |
}
|
71 |
|
css/{start/jquery-ui-1.8.9.custom.css → jquery-ui.css}
RENAMED
@@ -1,7 +1,7 @@
|
|
1 |
/*
|
2 |
-
* jQuery UI CSS Framework 1.8.
|
3 |
*
|
4 |
-
* Copyright
|
5 |
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6 |
* http://jquery.org/license
|
7 |
*
|
@@ -39,48 +39,323 @@
|
|
39 |
|
40 |
/* Overlays */
|
41 |
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
|
|
|
|
44 |
/*
|
45 |
-
* jQuery UI
|
46 |
*
|
47 |
-
* Copyright
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
* Dual licensed under the MIT or GPL Version 2 licenses.
|
49 |
* http://jquery.org/license
|
50 |
*
|
51 |
* http://docs.jquery.com/UI/Theming/API
|
52 |
*
|
53 |
-
* To view and modify this theme, visit http://jqueryui.com/themeroller
|
54 |
*/
|
55 |
|
56 |
|
57 |
/* Component containers
|
58 |
----------------------------------*/
|
59 |
-
.ui-widget { font-family: Verdana,Arial,sans-serif
|
60 |
.ui-widget .ui-widget { font-size: 1em; }
|
61 |
-
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif
|
62 |
-
.ui-widget-content { border: 1px solid #
|
63 |
-
.ui-widget-content a { color: #222222
|
64 |
-
.ui-widget-header { border: 1px solid #
|
65 |
-
.ui-widget-header a { color: #
|
66 |
|
67 |
/* Interaction states
|
68 |
----------------------------------*/
|
69 |
-
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #
|
70 |
-
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #
|
71 |
-
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #
|
72 |
-
.ui-state-hover a, .ui-state-hover a:hover { color: #
|
73 |
-
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #
|
74 |
-
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #
|
75 |
.ui-widget :active { outline: none; }
|
76 |
|
77 |
/* Interaction Cues
|
78 |
----------------------------------*/
|
79 |
-
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #
|
80 |
-
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #
|
81 |
-
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a
|
82 |
-
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #
|
83 |
-
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #
|
84 |
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
|
85 |
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
86 |
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
@@ -89,14 +364,14 @@
|
|
89 |
----------------------------------*/
|
90 |
|
91 |
/* states and images */
|
92 |
-
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-
|
93 |
-
.ui-widget-content .ui-icon {background-image: url(images/ui-
|
94 |
-
.ui-widget-header .ui-icon {background-image: url(images/ui-
|
95 |
-
.ui-state-default .ui-icon { background-image: url(images/ui-
|
96 |
-
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-
|
97 |
-
.ui-state-active .ui-icon {background-image: url(images/ui-
|
98 |
-
.ui-state-highlight .ui-icon {background-image: url(images/ui-
|
99 |
-
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-
|
100 |
|
101 |
/* positioning */
|
102 |
.ui-icon-carat-1-n { background-position: 0 0; }
|
@@ -280,294 +555,16 @@
|
|
280 |
----------------------------------*/
|
281 |
|
282 |
/* Corner radius */
|
283 |
-
.ui-corner-tl { -moz-border-radius-topleft:
|
284 |
-
.ui-corner-tr { -moz-border-radius-topright:
|
285 |
-
.ui-corner-bl { -moz-border-radius-bottomleft:
|
286 |
-
.ui-corner-br { -moz-border-radius-bottomright:
|
287 |
-
.ui-corner-top { -moz-border-radius-topleft:
|
288 |
-
.ui-corner-bottom { -moz-border-radius-bottomleft:
|
289 |
-
.ui-corner-right { -moz-border-radius-topright:
|
290 |
-
.ui-corner-left { -moz-border-radius-topleft:
|
291 |
-
.ui-corner-all { -moz-border-radius:
|
292 |
|
293 |
/* Overlays */
|
294 |
-
.ui-widget-overlay { background: #aaaaaa url(images/ui-
|
295 |
-
.ui-widget-shadow { margin:
|
296 |
-
* jQuery UI Resizable 1.8.9
|
297 |
-
*
|
298 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
299 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
300 |
-
* http://jquery.org/license
|
301 |
-
*
|
302 |
-
* http://docs.jquery.com/UI/Resizable#theming
|
303 |
-
*/
|
304 |
-
.ui-resizable { position: relative;}
|
305 |
-
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
|
306 |
-
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
307 |
-
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
308 |
-
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
309 |
-
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
310 |
-
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
311 |
-
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
312 |
-
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
313 |
-
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
314 |
-
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
|
315 |
-
* jQuery UI Selectable 1.8.9
|
316 |
-
*
|
317 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
318 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
319 |
-
* http://jquery.org/license
|
320 |
-
*
|
321 |
-
* http://docs.jquery.com/UI/Selectable#theming
|
322 |
-
*/
|
323 |
-
.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
|
324 |
-
/*
|
325 |
-
* jQuery UI Accordion 1.8.9
|
326 |
-
*
|
327 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
328 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
329 |
-
* http://jquery.org/license
|
330 |
-
*
|
331 |
-
* http://docs.jquery.com/UI/Accordion#theming
|
332 |
-
*/
|
333 |
-
/* IE/Win - Fix animation bug - #4615 */
|
334 |
-
.ui-accordion { width: 100%; }
|
335 |
-
.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
|
336 |
-
.ui-accordion .ui-accordion-li-fix { display: inline; }
|
337 |
-
.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
|
338 |
-
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
|
339 |
-
.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
|
340 |
-
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
|
341 |
-
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
|
342 |
-
.ui-accordion .ui-accordion-content-active { display: block; }
|
343 |
-
/*
|
344 |
-
* jQuery UI Autocomplete 1.8.9
|
345 |
-
*
|
346 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
347 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
348 |
-
* http://jquery.org/license
|
349 |
-
*
|
350 |
-
* http://docs.jquery.com/UI/Autocomplete#theming
|
351 |
-
*/
|
352 |
-
.ui-autocomplete { position: absolute; cursor: default; }
|
353 |
-
|
354 |
-
/* workarounds */
|
355 |
-
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
|
356 |
-
|
357 |
-
/*
|
358 |
-
* jQuery UI Menu 1.8.9
|
359 |
-
*
|
360 |
-
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
361 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
362 |
-
* http://jquery.org/license
|
363 |
-
*
|
364 |
-
* http://docs.jquery.com/UI/Menu#theming
|
365 |
-
*/
|
366 |
-
.ui-menu {
|
367 |
-
list-style:none;
|
368 |
-
padding: 2px;
|
369 |
-
margin: 0;
|
370 |
-
display:block;
|
371 |
-
float: left;
|
372 |
-
}
|
373 |
-
.ui-menu .ui-menu {
|
374 |
-
margin-top: -3px;
|
375 |
-
}
|
376 |
-
.ui-menu .ui-menu-item {
|
377 |
-
margin:0;
|
378 |
-
padding: 0;
|
379 |
-
zoom: 1;
|
380 |
-
float: left;
|
381 |
-
clear: left;
|
382 |
-
width: 100%;
|
383 |
-
}
|
384 |
-
.ui-menu .ui-menu-item a {
|
385 |
-
text-decoration:none;
|
386 |
-
display:block;
|
387 |
-
padding:.2em .4em;
|
388 |
-
line-height:1.5;
|
389 |
-
zoom:1;
|
390 |
-
}
|
391 |
-
.ui-menu .ui-menu-item a.ui-state-hover,
|
392 |
-
.ui-menu .ui-menu-item a.ui-state-active {
|
393 |
-
font-weight: normal;
|
394 |
-
margin: -1px;
|
395 |
-
}
|
396 |
-
/*
|
397 |
-
* jQuery UI Button 1.8.9
|
398 |
-
*
|
399 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
400 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
401 |
-
* http://jquery.org/license
|
402 |
-
*
|
403 |
-
* http://docs.jquery.com/UI/Button#theming
|
404 |
-
*/
|
405 |
-
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
|
406 |
-
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
|
407 |
-
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
|
408 |
-
.ui-button-icons-only { width: 3.4em; }
|
409 |
-
button.ui-button-icons-only { width: 3.7em; }
|
410 |
-
|
411 |
-
/*button text element */
|
412 |
-
.ui-button .ui-button-text { display: block; line-height: 1.4; }
|
413 |
-
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
|
414 |
-
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
|
415 |
-
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
|
416 |
-
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
|
417 |
-
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
|
418 |
-
/* no icon support for input elements, provide padding by default */
|
419 |
-
input.ui-button { padding: .4em 1em; }
|
420 |
-
|
421 |
-
/*button icon element(s) */
|
422 |
-
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
|
423 |
-
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
|
424 |
-
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
|
425 |
-
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
426 |
-
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
427 |
-
|
428 |
-
/*button sets*/
|
429 |
-
.ui-buttonset { margin-right: 7px; }
|
430 |
-
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
|
431 |
-
|
432 |
-
/* workarounds */
|
433 |
-
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
|
434 |
-
/*
|
435 |
-
* jQuery UI Dialog 1.8.9
|
436 |
-
*
|
437 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
438 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
439 |
-
* http://jquery.org/license
|
440 |
-
*
|
441 |
-
* http://docs.jquery.com/UI/Dialog#theming
|
442 |
-
*/
|
443 |
-
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
|
444 |
-
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
|
445 |
-
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
|
446 |
-
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
447 |
-
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
448 |
-
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
449 |
-
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
450 |
-
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
451 |
-
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
452 |
-
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
453 |
-
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
454 |
-
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
455 |
-
/*
|
456 |
-
* jQuery UI Slider 1.8.9
|
457 |
-
*
|
458 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
459 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
460 |
-
* http://jquery.org/license
|
461 |
-
*
|
462 |
-
* http://docs.jquery.com/UI/Slider#theming
|
463 |
-
*/
|
464 |
-
.ui-slider { position: relative; text-align: left; }
|
465 |
-
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
|
466 |
-
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
|
467 |
-
|
468 |
-
.ui-slider-horizontal { height: .8em; }
|
469 |
-
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
|
470 |
-
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
|
471 |
-
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
|
472 |
-
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
|
473 |
-
|
474 |
-
.ui-slider-vertical { width: .8em; height: 100px; }
|
475 |
-
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
|
476 |
-
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
|
477 |
-
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
|
478 |
-
.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
|
479 |
-
* jQuery UI Tabs 1.8.9
|
480 |
-
*
|
481 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
482 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
483 |
-
* http://jquery.org/license
|
484 |
-
*
|
485 |
-
* http://docs.jquery.com/UI/Tabs#theming
|
486 |
-
*/
|
487 |
-
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
488 |
-
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
|
489 |
-
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
|
490 |
-
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
|
491 |
-
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
|
492 |
-
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
|
493 |
-
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
|
494 |
-
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
|
495 |
-
.ui-tabs .ui-tabs-hide { display: none !important; }
|
496 |
-
/*
|
497 |
-
* jQuery UI Datepicker 1.8.9
|
498 |
-
*
|
499 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
500 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
501 |
-
* http://jquery.org/license
|
502 |
-
*
|
503 |
-
* http://docs.jquery.com/UI/Datepicker#theming
|
504 |
-
*/
|
505 |
-
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
|
506 |
-
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
|
507 |
-
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
|
508 |
-
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
|
509 |
-
.ui-datepicker .ui-datepicker-prev { left:2px; }
|
510 |
-
.ui-datepicker .ui-datepicker-next { right:2px; }
|
511 |
-
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
|
512 |
-
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
|
513 |
-
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
|
514 |
-
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
|
515 |
-
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
|
516 |
-
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
|
517 |
-
.ui-datepicker select.ui-datepicker-month,
|
518 |
-
.ui-datepicker select.ui-datepicker-year { width: 49%;}
|
519 |
-
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
|
520 |
-
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
|
521 |
-
.ui-datepicker td { border: 0; padding: 1px; }
|
522 |
-
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
|
523 |
-
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
|
524 |
-
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
525 |
-
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
|
526 |
-
|
527 |
-
/* with multiple calendars */
|
528 |
-
.ui-datepicker.ui-datepicker-multi { width:auto; }
|
529 |
-
.ui-datepicker-multi .ui-datepicker-group { float:left; }
|
530 |
-
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
|
531 |
-
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
|
532 |
-
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
|
533 |
-
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
|
534 |
-
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
|
535 |
-
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
|
536 |
-
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
|
537 |
-
.ui-datepicker-row-break { clear:both; width:100%; }
|
538 |
-
|
539 |
-
/* RTL support */
|
540 |
-
.ui-datepicker-rtl { direction: rtl; }
|
541 |
-
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
|
542 |
-
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
|
543 |
-
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
|
544 |
-
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
|
545 |
-
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
|
546 |
-
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
|
547 |
-
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
|
548 |
-
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
|
549 |
-
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
550 |
-
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
551 |
-
|
552 |
-
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
|
553 |
-
.ui-datepicker-cover {
|
554 |
-
display: none; /*sorry for IE5*/
|
555 |
-
display/**/: block; /*sorry for IE5*/
|
556 |
-
position: absolute; /*must have*/
|
557 |
-
z-index: -1; /*must have*/
|
558 |
-
filter: mask(); /*must have*/
|
559 |
-
top: -4px; /*must have*/
|
560 |
-
left: -4px; /*must have*/
|
561 |
-
width: 200px; /*must have*/
|
562 |
-
height: 200px; /*must have*/
|
563 |
-
}/*
|
564 |
-
* jQuery UI Progressbar 1.8.9
|
565 |
-
*
|
566 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
567 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
568 |
-
* http://jquery.org/license
|
569 |
-
*
|
570 |
-
* http://docs.jquery.com/UI/Progressbar#theming
|
571 |
-
*/
|
572 |
-
.ui-progressbar { height:2em; text-align: left; }
|
573 |
-
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
|
1 |
/*
|
2 |
+
* jQuery UI CSS Framework 1.8.8
|
3 |
*
|
4 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
5 |
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6 |
* http://jquery.org/license
|
7 |
*
|
39 |
|
40 |
/* Overlays */
|
41 |
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
42 |
+
/*
|
43 |
+
* jQuery UI Accordion 1.8.8
|
44 |
+
*
|
45 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
46 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
47 |
+
* http://jquery.org/license
|
48 |
+
*
|
49 |
+
* http://docs.jquery.com/UI/Accordion#theming
|
50 |
+
*/
|
51 |
+
/* IE/Win - Fix animation bug - #4615 */
|
52 |
+
.ui-accordion { width: 100%; }
|
53 |
+
.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
|
54 |
+
.ui-accordion .ui-accordion-li-fix { display: inline; }
|
55 |
+
.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
|
56 |
+
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
|
57 |
+
.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
|
58 |
+
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
|
59 |
+
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
|
60 |
+
.ui-accordion .ui-accordion-content-active { display: block; }/*
|
61 |
+
* jQuery UI Autocomplete 1.8.8
|
62 |
+
*
|
63 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
64 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
65 |
+
* http://jquery.org/license
|
66 |
+
*
|
67 |
+
* http://docs.jquery.com/UI/Autocomplete#theming
|
68 |
+
*/
|
69 |
+
.ui-autocomplete { position: absolute; cursor: default; }
|
70 |
+
|
71 |
+
/* workarounds */
|
72 |
+
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
|
73 |
+
|
74 |
+
/*
|
75 |
+
* jQuery UI Menu 1.8.8
|
76 |
+
*
|
77 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
78 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
79 |
+
* http://jquery.org/license
|
80 |
+
*
|
81 |
+
* http://docs.jquery.com/UI/Menu#theming
|
82 |
+
*/
|
83 |
+
.ui-menu {
|
84 |
+
list-style:none;
|
85 |
+
padding: 2px;
|
86 |
+
margin: 0;
|
87 |
+
display:block;
|
88 |
+
float: left;
|
89 |
+
}
|
90 |
+
.ui-menu .ui-menu {
|
91 |
+
margin-top: -3px;
|
92 |
+
}
|
93 |
+
.ui-menu .ui-menu-item {
|
94 |
+
margin:0;
|
95 |
+
padding: 0;
|
96 |
+
zoom: 1;
|
97 |
+
float: left;
|
98 |
+
clear: left;
|
99 |
+
width: 100%;
|
100 |
+
}
|
101 |
+
.ui-menu .ui-menu-item a {
|
102 |
+
text-decoration:none;
|
103 |
+
display:block;
|
104 |
+
padding:.2em .4em;
|
105 |
+
line-height:1.5;
|
106 |
+
zoom:1;
|
107 |
+
}
|
108 |
+
.ui-menu .ui-menu-item a.ui-state-hover,
|
109 |
+
.ui-menu .ui-menu-item a.ui-state-active {
|
110 |
+
font-weight: normal;
|
111 |
+
margin: -1px;
|
112 |
+
}
|
113 |
+
/*
|
114 |
+
* jQuery UI Button 1.8.8
|
115 |
+
*
|
116 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
117 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
118 |
+
* http://jquery.org/license
|
119 |
+
*
|
120 |
+
* http://docs.jquery.com/UI/Button#theming
|
121 |
+
*/
|
122 |
+
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
|
123 |
+
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
|
124 |
+
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
|
125 |
+
.ui-button-icons-only { width: 3.4em; }
|
126 |
+
button.ui-button-icons-only { width: 3.7em; }
|
127 |
+
|
128 |
+
/*button text element */
|
129 |
+
.ui-button .ui-button-text { display: block; line-height: 1.4; }
|
130 |
+
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
|
131 |
+
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
|
132 |
+
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
|
133 |
+
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
|
134 |
+
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
|
135 |
+
/* no icon support for input elements, provide padding by default */
|
136 |
+
input.ui-button { padding: .4em 1em; }
|
137 |
|
138 |
+
/*button icon element(s) */
|
139 |
+
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
|
140 |
+
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
|
141 |
+
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
|
142 |
+
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
143 |
+
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
144 |
+
|
145 |
+
/*button sets*/
|
146 |
+
.ui-buttonset { margin-right: 7px; }
|
147 |
+
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
|
148 |
|
149 |
+
/* workarounds */
|
150 |
+
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
|
151 |
/*
|
152 |
+
* jQuery UI Datepicker 1.8.8
|
153 |
*
|
154 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
155 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
156 |
+
* http://jquery.org/license
|
157 |
+
*
|
158 |
+
* http://docs.jquery.com/UI/Datepicker#theming
|
159 |
+
*/
|
160 |
+
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
|
161 |
+
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
|
162 |
+
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
|
163 |
+
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
|
164 |
+
.ui-datepicker .ui-datepicker-prev { left:2px; }
|
165 |
+
.ui-datepicker .ui-datepicker-next { right:2px; }
|
166 |
+
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
|
167 |
+
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
|
168 |
+
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
|
169 |
+
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
|
170 |
+
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
|
171 |
+
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
|
172 |
+
.ui-datepicker select.ui-datepicker-month,
|
173 |
+
.ui-datepicker select.ui-datepicker-year { width: 49%;}
|
174 |
+
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
|
175 |
+
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
|
176 |
+
.ui-datepicker td { border: 0; padding: 1px; }
|
177 |
+
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
|
178 |
+
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
|
179 |
+
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
180 |
+
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
|
181 |
+
|
182 |
+
/* with multiple calendars */
|
183 |
+
.ui-datepicker.ui-datepicker-multi { width:auto; }
|
184 |
+
.ui-datepicker-multi .ui-datepicker-group { float:left; }
|
185 |
+
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
|
186 |
+
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
|
187 |
+
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
|
188 |
+
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
|
189 |
+
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
|
190 |
+
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
|
191 |
+
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
|
192 |
+
.ui-datepicker-row-break { clear:both; width:100%; }
|
193 |
+
|
194 |
+
/* RTL support */
|
195 |
+
.ui-datepicker-rtl { direction: rtl; }
|
196 |
+
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
|
197 |
+
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
|
198 |
+
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
|
199 |
+
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
|
200 |
+
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
|
201 |
+
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
|
202 |
+
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
|
203 |
+
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
|
204 |
+
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
205 |
+
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
206 |
+
|
207 |
+
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
|
208 |
+
.ui-datepicker-cover {
|
209 |
+
display: none; /*sorry for IE5*/
|
210 |
+
display/**/: block; /*sorry for IE5*/
|
211 |
+
position: absolute; /*must have*/
|
212 |
+
z-index: -1; /*must have*/
|
213 |
+
filter: mask(); /*must have*/
|
214 |
+
top: -4px; /*must have*/
|
215 |
+
left: -4px; /*must have*/
|
216 |
+
width: 200px; /*must have*/
|
217 |
+
height: 200px; /*must have*/
|
218 |
+
}/*
|
219 |
+
* jQuery UI Dialog 1.8.8
|
220 |
+
*
|
221 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
222 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
223 |
+
* http://jquery.org/license
|
224 |
+
*
|
225 |
+
* http://docs.jquery.com/UI/Dialog#theming
|
226 |
+
*/
|
227 |
+
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
|
228 |
+
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
|
229 |
+
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
|
230 |
+
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
231 |
+
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
232 |
+
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
233 |
+
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
234 |
+
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
235 |
+
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
236 |
+
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
237 |
+
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
238 |
+
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
239 |
+
/*
|
240 |
+
* jQuery UI Progressbar 1.8.8
|
241 |
+
*
|
242 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
243 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
244 |
+
* http://jquery.org/license
|
245 |
+
*
|
246 |
+
* http://docs.jquery.com/UI/Progressbar#theming
|
247 |
+
*/
|
248 |
+
.ui-progressbar { height:2em; text-align: left; }
|
249 |
+
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/*
|
250 |
+
* jQuery UI Resizable 1.8.8
|
251 |
+
*
|
252 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
253 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
254 |
+
* http://jquery.org/license
|
255 |
+
*
|
256 |
+
* http://docs.jquery.com/UI/Resizable#theming
|
257 |
+
*/
|
258 |
+
.ui-resizable { position: relative;}
|
259 |
+
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
|
260 |
+
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
261 |
+
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
262 |
+
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
263 |
+
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
264 |
+
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
265 |
+
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
266 |
+
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
267 |
+
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
268 |
+
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
|
269 |
+
* jQuery UI Selectable 1.8.8
|
270 |
+
*
|
271 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
272 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
273 |
+
* http://jquery.org/license
|
274 |
+
*
|
275 |
+
* http://docs.jquery.com/UI/Selectable#theming
|
276 |
+
*/
|
277 |
+
.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
|
278 |
+
/*
|
279 |
+
* jQuery UI Slider 1.8.8
|
280 |
+
*
|
281 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
282 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
283 |
+
* http://jquery.org/license
|
284 |
+
*
|
285 |
+
* http://docs.jquery.com/UI/Slider#theming
|
286 |
+
*/
|
287 |
+
.ui-slider { position: relative; text-align: left; }
|
288 |
+
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
|
289 |
+
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
|
290 |
+
|
291 |
+
.ui-slider-horizontal { height: .8em; }
|
292 |
+
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
|
293 |
+
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
|
294 |
+
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
|
295 |
+
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
|
296 |
+
|
297 |
+
.ui-slider-vertical { width: .8em; height: 100px; }
|
298 |
+
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
|
299 |
+
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
|
300 |
+
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
|
301 |
+
.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
|
302 |
+
* jQuery UI Tabs 1.8.8
|
303 |
+
*
|
304 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
305 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
306 |
+
* http://jquery.org/license
|
307 |
+
*
|
308 |
+
* http://docs.jquery.com/UI/Tabs#theming
|
309 |
+
*/
|
310 |
+
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
311 |
+
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
|
312 |
+
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
|
313 |
+
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
|
314 |
+
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
|
315 |
+
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
|
316 |
+
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
|
317 |
+
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
|
318 |
+
.ui-tabs .ui-tabs-hide { display: none !important; }
|
319 |
+
/*
|
320 |
+
* jQuery UI CSS Framework 1.8.8
|
321 |
+
*
|
322 |
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
323 |
* Dual licensed under the MIT or GPL Version 2 licenses.
|
324 |
* http://jquery.org/license
|
325 |
*
|
326 |
* http://docs.jquery.com/UI/Theming/API
|
327 |
*
|
328 |
+
* To view and modify this theme, visit http://jqueryui.com/themeroller/
|
329 |
*/
|
330 |
|
331 |
|
332 |
/* Component containers
|
333 |
----------------------------------*/
|
334 |
+
.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; }
|
335 |
.ui-widget .ui-widget { font-size: 1em; }
|
336 |
+
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; }
|
337 |
+
.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ /*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; }
|
338 |
+
.ui-widget-content a { color: #222222/*{fcContent}*/; }
|
339 |
+
.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ /*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; }
|
340 |
+
.ui-widget-header a { color: #222222/*{fcHeader}*/; }
|
341 |
|
342 |
/* Interaction states
|
343 |
----------------------------------*/
|
344 |
+
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; }
|
345 |
+
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; }
|
346 |
+
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; }
|
347 |
+
.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; }
|
348 |
+
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; }
|
349 |
+
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; }
|
350 |
.ui-widget :active { outline: none; }
|
351 |
|
352 |
/* Interaction Cues
|
353 |
----------------------------------*/
|
354 |
+
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; }
|
355 |
+
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; }
|
356 |
+
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; }
|
357 |
+
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; }
|
358 |
+
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; }
|
359 |
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
|
360 |
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
361 |
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
364 |
----------------------------------*/
|
365 |
|
366 |
/* states and images */
|
367 |
+
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
|
368 |
+
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
|
369 |
+
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; }
|
370 |
+
.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; }
|
371 |
+
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; }
|
372 |
+
.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; }
|
373 |
+
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; }
|
374 |
+
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; }
|
375 |
|
376 |
/* positioning */
|
377 |
.ui-icon-carat-1-n { background-position: 0 0; }
|
555 |
----------------------------------*/
|
556 |
|
557 |
/* Corner radius */
|
558 |
+
.ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; }
|
559 |
+
.ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; }
|
560 |
+
.ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; }
|
561 |
+
.ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; }
|
562 |
+
.ui-corner-top { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; }
|
563 |
+
.ui-corner-bottom { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; }
|
564 |
+
.ui-corner-right { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; }
|
565 |
+
.ui-corner-left { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; }
|
566 |
+
.ui-corner-all { -moz-border-radius: 4px/*{cornerRadius}*/; -webkit-border-radius: 4px/*{cornerRadius}*/; border-radius: 4px/*{cornerRadius}*/; }
|
567 |
|
568 |
/* Overlays */
|
569 |
+
.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; }
|
570 |
+
.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
css/main.css
CHANGED
@@ -155,16 +155,16 @@ a.pagenav:active {
|
|
155 |
}
|
156 |
.inputbox {
|
157 |
z-index: -3;
|
158 |
-
font-size:
|
159 |
}
|
160 |
.text_area {
|
161 |
border : 1px solid #ccc;
|
162 |
z-index: -3;
|
163 |
-
font-size:
|
164 |
}
|
165 |
input, textarea, select {
|
166 |
z-index : -3;
|
167 |
-
font-size:
|
168 |
}
|
169 |
.small {
|
170 |
color : #FF9900;
|
@@ -190,7 +190,7 @@ table.menubar {
|
|
190 |
|
191 |
}
|
192 |
td {
|
193 |
-
font-size:
|
194 |
}
|
195 |
/* header block */
|
196 |
table.adminheading {
|
@@ -309,8 +309,7 @@ table.adminlist th {
|
|
309 |
padding: 6px 4px 2px 4px;
|
310 |
height: 25px;
|
311 |
background-repeat: repeat;
|
312 |
-
font-size:
|
313 |
-
text-align: left;
|
314 |
color: #000;
|
315 |
}
|
316 |
table.adminlist th.title {
|
@@ -379,6 +378,7 @@ table.adminform th {
|
|
379 |
table.adminform td {
|
380 |
padding: 3px;
|
381 |
border: solid 1px #d5d5d5;
|
|
|
382 |
text-align: left;
|
383 |
}
|
384 |
table.adminform td.editor {
|
@@ -720,88 +720,4 @@ display:block;
|
|
720 |
.mtext {
|
721 |
font-weight: bold;
|
722 |
font-size: 16px;
|
723 |
-
display:inline;
|
724 |
-
}
|
725 |
-
|
726 |
-
#configtabinside div h3{
|
727 |
-
padding: 15px 0 5px 0;
|
728 |
-
font-weight: bold;
|
729 |
-
}
|
730 |
-
|
731 |
-
.backup_name {
|
732 |
-
font-size:16px;
|
733 |
-
}
|
734 |
-
|
735 |
-
#mysqlProcess{
|
736 |
-
|
737 |
-
padding-left: 50px;
|
738 |
-
}
|
739 |
-
|
740 |
-
#mysqlBackup{
|
741 |
-
padding-bottom: 10px;
|
742 |
-
}
|
743 |
-
|
744 |
-
#recurseFiles{
|
745 |
-
|
746 |
-
padding-left: 50px;
|
747 |
-
}
|
748 |
-
|
749 |
-
.mainText a{
|
750 |
-
font-weight: bold;
|
751 |
-
}
|
752 |
-
|
753 |
-
.mainText li{
|
754 |
-
font-weight: bold;
|
755 |
-
padding: 5px 0 5px 0;
|
756 |
-
list-style: disc inside;
|
757 |
-
}
|
758 |
-
|
759 |
-
.mainText{
|
760 |
-
padding: 5px 10px 10px 10px;
|
761 |
-
width: auto;
|
762 |
-
border: 1px solid #2e90bd;
|
763 |
-
}
|
764 |
-
|
765 |
-
.mainText h2{
|
766 |
-
padding-bottom: 5px;
|
767 |
-
}
|
768 |
-
|
769 |
-
.header a{
|
770 |
-
color: #000;
|
771 |
-
}
|
772 |
-
|
773 |
-
.adminForm textarea, .adminForm input, .adminForm select, .mainText input{
|
774 |
-
color: #000;
|
775 |
-
background: #fefefe;
|
776 |
-
border: 1px outset #2e90bd;
|
777 |
-
margin-left: 1px;
|
778 |
-
font-family: Tahoma, Arial;
|
779 |
-
}
|
780 |
-
|
781 |
-
.adminForm a, .adminform a {
|
782 |
-
font-family: Tahoma, Arial;
|
783 |
-
font-weight: bold;
|
784 |
-
}
|
785 |
-
|
786 |
-
.loginForm table {
|
787 |
-
border: 1px dashed #2e90bd;
|
788 |
-
font-size:12px;
|
789 |
-
}
|
790 |
-
.loginForm input{
|
791 |
-
color: #000;
|
792 |
-
background: #fefefe;
|
793 |
-
border: 1px outset #2e90bd;
|
794 |
-
margin-left: 1px;
|
795 |
-
font-family: Tahoma, Arial;
|
796 |
-
|
797 |
-
}
|
798 |
-
.oversizedFile{
|
799 |
-
padding-left: 25px;
|
800 |
-
}
|
801 |
-
|
802 |
-
.sliderContainer{
|
803 |
-
|
804 |
-
display: inline;
|
805 |
-
margin-bottom: 15px;
|
806 |
-
|
807 |
}
|
155 |
}
|
156 |
.inputbox {
|
157 |
z-index: -3;
|
158 |
+
font-size: 11px;
|
159 |
}
|
160 |
.text_area {
|
161 |
border : 1px solid #ccc;
|
162 |
z-index: -3;
|
163 |
+
font-size: 11px;
|
164 |
}
|
165 |
input, textarea, select {
|
166 |
z-index : -3;
|
167 |
+
font-size: 11px;
|
168 |
}
|
169 |
.small {
|
170 |
color : #FF9900;
|
190 |
|
191 |
}
|
192 |
td {
|
193 |
+
font-size: 11px;
|
194 |
}
|
195 |
/* header block */
|
196 |
table.adminheading {
|
309 |
padding: 6px 4px 2px 4px;
|
310 |
height: 25px;
|
311 |
background-repeat: repeat;
|
312 |
+
font-size: 11px;
|
|
|
313 |
color: #000;
|
314 |
}
|
315 |
table.adminlist th.title {
|
378 |
table.adminform td {
|
379 |
padding: 3px;
|
380 |
border: solid 1px #d5d5d5;
|
381 |
+
|
382 |
text-align: left;
|
383 |
}
|
384 |
table.adminform td.editor {
|
720 |
.mtext {
|
721 |
font-weight: bold;
|
722 |
font-size: 16px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
723 |
}
|
css/start/images/ui-bg_flat_55_999999_40x100.png
DELETED
Binary file
|
css/start/images/ui-bg_flat_75_aaaaaa_40x100.png
DELETED
Binary file
|
css/start/images/ui-bg_glass_45_0078ae_1x400.png
DELETED
Binary file
|
css/start/images/ui-bg_glass_55_f8da4e_1x400.png
DELETED
Binary file
|
css/start/images/ui-bg_glass_75_79c9ec_1x400.png
DELETED
Binary file
|
css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png
DELETED
Binary file
|
css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png
DELETED
Binary file
|
css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png
DELETED
Binary file
|
css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
DELETED
Binary file
|
css/start/images/ui-icons_0078ae_256x240.png
DELETED
Binary file
|
css/start/images/ui-icons_056b93_256x240.png
DELETED
Binary file
|
css/start/images/ui-icons_d8e7f3_256x240.png
DELETED
Binary file
|
css/start/images/ui-icons_e0fdff_256x240.png
DELETED
Binary file
|
css/start/images/ui-icons_f5e175_256x240.png
DELETED
Binary file
|
css/start/images/ui-icons_f7a50d_256x240.png
DELETED
Binary file
|
css/start/images/ui-icons_fcd113_256x240.png
DELETED
Binary file
|
css/tabber.css
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* $Id: example.css,v 1.5 2006/03/27 02:44:36 pat Exp $ */
|
2 |
+
|
3 |
+
/*--------------------------------------------------
|
4 |
+
REQUIRED to hide the non-active tab content.
|
5 |
+
But do not hide them in the print stylesheet!
|
6 |
+
--------------------------------------------------*/
|
7 |
+
.tabberlive .tabbertabhide {
|
8 |
+
display:none;
|
9 |
+
}
|
10 |
+
|
11 |
+
/*--------------------------------------------------
|
12 |
+
.tabber = before the tabber interface is set up
|
13 |
+
.tabberlive = after the tabber interface is set up
|
14 |
+
--------------------------------------------------*/
|
15 |
+
.tabber {
|
16 |
+
}
|
17 |
+
.tabberlive {
|
18 |
+
margin-top:1em;
|
19 |
+
}
|
20 |
+
|
21 |
+
/*--------------------------------------------------
|
22 |
+
ul.tabbernav = the tab navigation list
|
23 |
+
li.tabberactive = the active tab
|
24 |
+
--------------------------------------------------*/
|
25 |
+
ul.tabbernav
|
26 |
+
{
|
27 |
+
margin:0;
|
28 |
+
padding: 3px 0;
|
29 |
+
border-bottom: 1px solid #778;
|
30 |
+
font: bold 12px Verdana, sans-serif;
|
31 |
+
}
|
32 |
+
|
33 |
+
ul.tabbernav li
|
34 |
+
{
|
35 |
+
list-style: none;
|
36 |
+
margin: 0;
|
37 |
+
display: inline;
|
38 |
+
}
|
39 |
+
|
40 |
+
ul.tabbernav li a
|
41 |
+
{
|
42 |
+
padding: 3px 0.5em;
|
43 |
+
margin-left: 3px;
|
44 |
+
border: 1px solid #778;
|
45 |
+
border-bottom: none;
|
46 |
+
background: #DDE;
|
47 |
+
text-decoration: none;
|
48 |
+
}
|
49 |
+
|
50 |
+
ul.tabbernav li a:link { color: #448; }
|
51 |
+
ul.tabbernav li a:visited { color: #667; }
|
52 |
+
|
53 |
+
ul.tabbernav li a:hover
|
54 |
+
{
|
55 |
+
color: #000;
|
56 |
+
background: #AAE;
|
57 |
+
border-color: #227;
|
58 |
+
}
|
59 |
+
|
60 |
+
ul.tabbernav li.tabberactive a
|
61 |
+
{
|
62 |
+
background-color: #fff;
|
63 |
+
border-bottom: 1px solid #fff;
|
64 |
+
}
|
65 |
+
|
66 |
+
ul.tabbernav li.tabberactive a:hover
|
67 |
+
{
|
68 |
+
color: #000;
|
69 |
+
background: white;
|
70 |
+
border-bottom: 1px solid white;
|
71 |
+
}
|
72 |
+
|
73 |
+
/*--------------------------------------------------
|
74 |
+
.tabbertab = the tab content
|
75 |
+
Add style only after the tabber interface is set up (.tabberlive)
|
76 |
+
--------------------------------------------------*/
|
77 |
+
.tabberlive .tabbertab {
|
78 |
+
padding:5px;
|
79 |
+
border:1px solid #aaa;
|
80 |
+
border-top:0;
|
81 |
+
|
82 |
+
/* If you don't want the tab size changing whenever a tab is changed
|
83 |
+
you can set a fixed height */
|
84 |
+
|
85 |
+
/* height:200px; */
|
86 |
+
|
87 |
+
/* If you set a fix height set overflow to auto and you will get a
|
88 |
+
scrollbar when necessary */
|
89 |
+
|
90 |
+
/* overflow:auto; */
|
91 |
+
}
|
92 |
+
|
93 |
+
/* If desired, hide the heading since a heading is provided by the tab */
|
94 |
+
.tabberlive .tabbertab h2 {
|
95 |
+
display:none;
|
96 |
+
}
|
97 |
+
.tabberlive .tabbertab h3 {
|
98 |
+
display:none;
|
99 |
+
}
|
100 |
+
|
101 |
+
/* Example of using an ID to set different styles for the tabs on the page */
|
102 |
+
.tabberlive#tab1 {
|
103 |
+
}
|
104 |
+
.tabberlive#tab2 {
|
105 |
+
}
|
106 |
+
.tabberlive#tab2 .tabbertab {
|
107 |
+
height:200px;
|
108 |
+
overflow:auto;
|
109 |
+
}
|
images/logo.gif
CHANGED
Binary file
|
images/logo.png
CHANGED
Binary file
|
images/{progressBarLong.gif → progress.gif}
RENAMED
File without changes
|
install.xcloner.php
CHANGED
@@ -11,15 +11,23 @@ function com_install(){
|
|
11 |
|
12 |
if( is_callable( array( 'JFactory', 'getDBO' ))) {
|
13 |
$database = JFactory::getDBO();
|
14 |
-
$database->setQuery("UPDATE #__menu SET alias = 'XCloner Backup and Restore' WHERE path = 'xcloner-backup-and-restore'");
|
15 |
-
$database->query();
|
16 |
}
|
17 |
$mypath = dirname(__FILE__);
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
error_reporting( E_ALL ^ E_NOTICE );
|
20 |
|
21 |
//add new admin menu images
|
22 |
-
|
23 |
-
|
24 |
}
|
25 |
?>
|
11 |
|
12 |
if( is_callable( array( 'JFactory', 'getDBO' ))) {
|
13 |
$database = JFactory::getDBO();
|
|
|
|
|
14 |
}
|
15 |
$mypath = dirname(__FILE__);
|
16 |
|
17 |
+
@chmod("components/com_xcloner/cloner.config.php", 0777);
|
18 |
+
@mkdir("backups", 0777);
|
19 |
+
@chmod("backups", 0777);
|
20 |
+
@chmod("components/com_xcloner/configs", 0777);
|
21 |
+
@chmod("components/com_xcloner/browser", 0755);
|
22 |
+
@chmod("components/com_xcloner/", 0755);
|
23 |
+
@chmod("components/com_xcloner/index.php", 0755);
|
24 |
+
@chmod("components/com_xcloner/index2.php", 0755);
|
25 |
+
@chmod("components/com_xcloner/cloner.cron.php", 0755);
|
26 |
+
|
27 |
error_reporting( E_ALL ^ E_NOTICE );
|
28 |
|
29 |
//add new admin menu images
|
30 |
+
$database->setQuery("UPDATE #__components SET admin_menu_img = 'components/com_xcloner/images/xcloner.png' WHERE admin_menu_link = 'option=com_xcloner'");
|
31 |
+
$database->query();
|
32 |
}
|
33 |
?>
|
javascript/backup.js
DELETED
@@ -1,172 +0,0 @@
|
|
1 |
-
$(document).ready(function() {
|
2 |
-
|
3 |
-
var globalUrl;
|
4 |
-
var step = "r1";
|
5 |
-
var count = 0;
|
6 |
-
var counter = 0;
|
7 |
-
var counter_old = 0;
|
8 |
-
|
9 |
-
$("#progressbar").progressbar({ value: 0 });
|
10 |
-
|
11 |
-
$.ajaxSetup({
|
12 |
-
"error":function(request, status, error) {
|
13 |
-
//reset state here;
|
14 |
-
$("#error").show();
|
15 |
-
$("#errorText").append(status+" -- "+error);
|
16 |
-
$("#errorText").append("<br /><br />JSON url: "+globalUrl);
|
17 |
-
}});
|
18 |
-
|
19 |
-
function getSize(bytes, conv){
|
20 |
-
|
21 |
-
return (bytes/conv).toFixed(2);
|
22 |
-
|
23 |
-
}
|
24 |
-
function appendIcon(icon){
|
25 |
-
|
26 |
-
return '<span class="ui-icon ui-icon-'+icon+'" style="float:left;"></span>';
|
27 |
-
|
28 |
-
}
|
29 |
-
|
30 |
-
function xclonerRecurseMYSQL(url){
|
31 |
-
|
32 |
-
globalUrl = url;
|
33 |
-
step = "r1";
|
34 |
-
|
35 |
-
$.getJSON(url, function(json) {
|
36 |
-
|
37 |
-
if(!json){
|
38 |
-
$("#error").show();
|
39 |
-
$("#errorText").text(url);
|
40 |
-
}
|
41 |
-
|
42 |
-
if(json.dumpsize && !json.endDump){
|
43 |
-
$("#mysqlProcess").append(" ("+getSize(json.dumpsize, 1024*1024)+" MB) <br />");
|
44 |
-
}
|
45 |
-
|
46 |
-
if(json.newDump){
|
47 |
-
count++;
|
48 |
-
//$("#mysqlProcess").append(appendIcon("arrowthick-1-e"));
|
49 |
-
if(json.databaseName!="")
|
50 |
-
$("#mysqlProcess").append("<b>["+json.databaseName+"]</b> <span id='db"+count+"'></span> tables ");
|
51 |
-
counter = parseInt(json.startAtLine);
|
52 |
-
|
53 |
-
}else{
|
54 |
-
$("#db"+count).text(json.startAtLine - counter);
|
55 |
-
}
|
56 |
-
|
57 |
-
if(!parseInt(json.finished)){
|
58 |
-
//get next records
|
59 |
-
|
60 |
-
$("#db"+count).text(json.startAtLine - counter);
|
61 |
-
|
62 |
-
recurseUrl = "index2.php?task=recurse_database&nohtml=1&dbbackup_comp="+json.dbbackup_comp+"&dbbackup_drop="+json.dbbackup_drop+"&startAtLine="+json.startAtLine+"&startAtRecord="+json.startAtRecord+"&dumpfile="+json.dumpfile;
|
63 |
-
xclonerRecurseMYSQL(recurseUrl);
|
64 |
-
|
65 |
-
}
|
66 |
-
else{
|
67 |
-
|
68 |
-
$("#fileSystem").show();
|
69 |
-
var recurseUrl="index2.php?task=recurse_files&mode=start&nohtml=1";
|
70 |
-
xclonerRecurseJSON(recurseUrl);
|
71 |
-
|
72 |
-
}
|
73 |
-
|
74 |
-
|
75 |
-
});
|
76 |
-
}
|
77 |
-
|
78 |
-
function xclonerRecurseJSON(url){
|
79 |
-
|
80 |
-
$("#result").hide();
|
81 |
-
|
82 |
-
globalUrl = url;
|
83 |
-
step = "r2";
|
84 |
-
|
85 |
-
$.getJSON(url, function(json) {
|
86 |
-
|
87 |
-
if(!json){
|
88 |
-
$("#error").show();
|
89 |
-
$("#errorText").text(url);
|
90 |
-
}
|
91 |
-
|
92 |
-
if(!parseInt(json.finished)){
|
93 |
-
|
94 |
-
$("#recurseStatus").text(json.tfiles);
|
95 |
-
|
96 |
-
var recurseUrl = "index2.php?task=recurse_files&mode="+json.mode+"&nohtml=1";
|
97 |
-
xclonerRecurseJSON(recurseUrl);
|
98 |
-
|
99 |
-
}
|
100 |
-
else{
|
101 |
-
var size = parseFloat(json.size)/(1024*1024);
|
102 |
-
$("#recurseStatus").text(" done! (Estimated size:"+size.toFixed(2)+"MB) in "+json.tfiles+" files");
|
103 |
-
$("#result").show();
|
104 |
-
returnUrl = "index2.php?option=com_cloner&lines="+json.tfiles+"&task=refresh&backup="+backupFile+"&excl_manual=";
|
105 |
-
xclonerGetJSON(returnUrl);
|
106 |
-
|
107 |
-
}
|
108 |
-
|
109 |
-
|
110 |
-
});
|
111 |
-
}
|
112 |
-
|
113 |
-
function xclonerGetJSON(url){
|
114 |
-
|
115 |
-
globalUrl = url;
|
116 |
-
step = "r3";
|
117 |
-
|
118 |
-
$.getJSON(url, function(json) {
|
119 |
-
|
120 |
-
if(!json){
|
121 |
-
$("#error").show();
|
122 |
-
$("#errorText").append(url);
|
123 |
-
}
|
124 |
-
|
125 |
-
var percent = parseInt(json.percent);
|
126 |
-
$("#progressbar").progressbar({ value: percent });
|
127 |
-
$("#backupSize").text(json.backupSize);
|
128 |
-
$("#nFiles").text(json.startf);
|
129 |
-
$("#percent").text(json.percent);
|
130 |
-
if(!json.finished){
|
131 |
-
var url = "index2.php?option="+json.option+"&task="+json.task+"&json="+json.json+"&startf="+json.startf+"&lines="+json.lines+"&backup="+json.backup+"&excl_manual="+json.excl_manual;
|
132 |
-
xclonerGetJSON(url);
|
133 |
-
}else{
|
134 |
-
|
135 |
-
$("#complete").show();
|
136 |
-
$("#nFiles").text(json.lines);
|
137 |
-
$("#backupFiles").text(json.lines);
|
138 |
-
$("#backupSizeComplete").text(json.backupSize);
|
139 |
-
$("#backupName").text(json.backup);
|
140 |
-
$( "#dialog:ui-dialog" ).dialog( "destroy" );
|
141 |
-
$( "#dialog-message" ).dialog({
|
142 |
-
modal: true,
|
143 |
-
width: 600,
|
144 |
-
buttons: {
|
145 |
-
Close: function() {
|
146 |
-
$( this ).dialog( "close" );
|
147 |
-
}
|
148 |
-
}
|
149 |
-
});
|
150 |
-
|
151 |
-
}
|
152 |
-
|
153 |
-
});
|
154 |
-
|
155 |
-
}
|
156 |
-
|
157 |
-
$("#retry").click(function(){
|
158 |
-
$("#error").hide();
|
159 |
-
$("#errorText").empty();
|
160 |
-
if(step == "r1"){
|
161 |
-
xclonerRecurseMYSQL(globalUrl);
|
162 |
-
}
|
163 |
-
else
|
164 |
-
if(step == "r2"){
|
165 |
-
xclonerRecurseJSON(globalUrl);
|
166 |
-
}
|
167 |
-
else if(step == "r3"){
|
168 |
-
xclonerGetJSON(globalUrl);
|
169 |
-
}
|
170 |
-
});
|
171 |
-
|
172 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
javascript/jquery-ui-1.8.9.custom.min.js
DELETED
@@ -1,781 +0,0 @@
|
|
1 |
-
/*!
|
2 |
-
* jQuery UI 1.8.9
|
3 |
-
*
|
4 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
5 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6 |
-
* http://jquery.org/license
|
7 |
-
*
|
8 |
-
* http://docs.jquery.com/UI
|
9 |
-
*/
|
10 |
-
(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.9",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,
|
11 |
-
NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,
|
12 |
-
"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");
|
13 |
-
if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,
|
14 |
-
"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,
|
15 |
-
d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});
|
16 |
-
c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&
|
17 |
-
b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
|
18 |
-
;/*!
|
19 |
-
* jQuery UI Widget 1.8.9
|
20 |
-
*
|
21 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
22 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
23 |
-
* http://jquery.org/license
|
24 |
-
*
|
25 |
-
* http://docs.jquery.com/UI/Widget
|
26 |
-
*/
|
27 |
-
(function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,
|
28 |
-
a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.charAt(0)==="_")return h;
|
29 |
-
e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,
|
30 |
-
this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},
|
31 |
-
widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},
|
32 |
-
enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
|
33 |
-
;/*!
|
34 |
-
* jQuery UI Mouse 1.8.9
|
35 |
-
*
|
36 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
37 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
38 |
-
* http://jquery.org/license
|
39 |
-
*
|
40 |
-
* http://docs.jquery.com/UI/Mouse
|
41 |
-
*
|
42 |
-
* Depends:
|
43 |
-
* jquery.ui.widget.js
|
44 |
-
*/
|
45 |
-
(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(true===c.data(b.target,a.widgetName+".preventClickEvent")){c.removeData(b.target,a.widgetName+".preventClickEvent");b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=
|
46 |
-
a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=
|
47 |
-
this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);
|
48 |
-
return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;a.target==this._mouseDownEvent.target&&c.data(a.target,this.widgetName+".preventClickEvent",
|
49 |
-
true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
|
50 |
-
;/*
|
51 |
-
* jQuery UI Position 1.8.9
|
52 |
-
*
|
53 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
54 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
55 |
-
* http://jquery.org/license
|
56 |
-
*
|
57 |
-
* http://docs.jquery.com/UI/Position
|
58 |
-
*/
|
59 |
-
(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
|
60 |
-
left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
|
61 |
-
k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=
|
62 |
-
m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=
|
63 |
-
d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
|
64 |
-
a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
|
65 |
-
g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
|
66 |
-
;/*
|
67 |
-
* jQuery UI Draggable 1.8.9
|
68 |
-
*
|
69 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
70 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
71 |
-
* http://jquery.org/license
|
72 |
-
*
|
73 |
-
* http://docs.jquery.com/UI/Draggables
|
74 |
-
*
|
75 |
-
* Depends:
|
76 |
-
* jquery.ui.core.js
|
77 |
-
* jquery.ui.mouse.js
|
78 |
-
* jquery.ui.widget.js
|
79 |
-
*/
|
80 |
-
(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
|
81 |
-
"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
|
82 |
-
this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-
|
83 |
-
this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();
|
84 |
-
d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||
|
85 |
-
this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&
|
86 |
-
this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==
|
87 |
-
a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||
|
88 |
-
0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
|
89 |
-
this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-
|
90 |
-
(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment==
|
91 |
-
"parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[(a.containment=="document"?0:d(window).scrollLeft())-this.offset.relative.left-this.offset.parent.left,(a.containment=="document"?0:d(window).scrollTop())-this.offset.relative.top-this.offset.parent.top,(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?
|
92 |
-
0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),
|
93 |
-
10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}}else if(a.containment.constructor==
|
94 |
-
Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():
|
95 |
-
f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;
|
96 |
-
if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])e=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/
|
97 |
-
b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;e=this.originalPageX+Math.round((e-this.originalPageX)/b.grid[0])*b.grid[0];e=this.containment?!(e-this.offset.click.left<this.containment[0]||e-this.offset.click.left>this.containment[2])?e:!(e-this.offset.click.left<this.containment[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:g-this.offset.click.top-
|
98 |
-
this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=
|
99 |
-
this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.9"});
|
100 |
-
d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var g=d.data(this,"sortable");if(g&&!g.options.disabled){c.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=
|
101 |
-
0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=
|
102 |
-
c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=d(f).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,
|
103 |
-
true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=
|
104 |
-
0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=
|
105 |
-
a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","iframeFix",{start:function(){var a=d(this).data("draggable").options;d(a.iframeFix===true?"iframe":a.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},
|
106 |
-
stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=
|
107 |
-
document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-
|
108 |
-
c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-b.overflowOffset.left<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-
|
109 |
-
(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable",
|
110 |
-
"snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,g=b.offset.left,n=g+c.helperProportions.width,m=b.offset.top,o=m+c.helperProportions.height,h=
|
111 |
-
c.snapElements.length-1;h>=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e<g&&g<k+e&&j-e<m&&m<l+e||i-e<g&&g<k+e&&j-e<o&&o<l+e||i-e<n&&n<k+e&&j-e<m&&m<l+e||i-e<n&&n<k+e&&j-e<o&&o<l+e){if(f.snapMode!="inner"){var p=Math.abs(j-o)<=e,q=Math.abs(l-m)<=e,r=Math.abs(i-n)<=e,s=Math.abs(k-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",
|
112 |
-
{top:l,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k}).left-c.margins.left}var t=p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(j-m)<=e;q=Math.abs(l-o)<=e;r=Math.abs(i-g)<=e;s=Math.abs(k-n)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l-c.helperProportions.height,
|
113 |
-
left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[h].snapping&&(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=p||q||r||s||t}else{c.snapElements[h].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,
|
114 |
-
a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,
|
115 |
-
b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
|
116 |
-
;/*
|
117 |
-
* jQuery UI Droppable 1.8.9
|
118 |
-
*
|
119 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
120 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
121 |
-
* http://jquery.org/license
|
122 |
-
*
|
123 |
-
* http://docs.jquery.com/UI/Droppables
|
124 |
-
*
|
125 |
-
* Depends:
|
126 |
-
* jquery.ui.core.js
|
127 |
-
* jquery.ui.widget.js
|
128 |
-
* jquery.ui.mouse.js
|
129 |
-
* jquery.ui.draggable.js
|
130 |
-
*/
|
131 |
-
(function(d){d.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var a=this.options,b=a.accept;this.isover=0;this.isout=1;this.accept=d.isFunction(b)?b:function(c){return c.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};d.ui.ddmanager.droppables[a.scope]=d.ui.ddmanager.droppables[a.scope]||[];d.ui.ddmanager.droppables[a.scope].push(this);
|
132 |
-
a.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var a=d.ui.ddmanager.droppables[this.options.scope],b=0;b<a.length;b++)a[b]==this&&a.splice(b,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(a,b){if(a=="accept")this.accept=d.isFunction(b)?b:function(c){return c.is(b)};d.Widget.prototype._setOption.apply(this,arguments)},_activate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&
|
133 |
-
this.element.addClass(this.options.activeClass);b&&this._trigger("activate",a,this.ui(b))},_deactivate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);b&&this._trigger("deactivate",a,this.ui(b))},_over:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass);
|
134 |
-
this._trigger("over",a,this.ui(b))}},_out:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("out",a,this.ui(b))}},_drop:function(a,b){var c=b||d.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return false;var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var g=
|
135 |
-
d.data(this,"droppable");if(g.options.greedy&&!g.options.disabled&&g.options.scope==c.options.scope&&g.accept.call(g.element[0],c.currentItem||c.element)&&d.ui.intersect(c,d.extend(g,{offset:g.element.offset()}),g.options.tolerance)){e=true;return false}});if(e)return false;if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass);this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("drop",
|
136 |
-
a,this.ui(c));return this.element}return false},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}});d.extend(d.ui.droppable,{version:"1.8.9"});d.ui.intersect=function(a,b,c){if(!b.offset)return false;var e=(a.positionAbs||a.position.absolute).left,g=e+a.helperProportions.width,f=(a.positionAbs||a.position.absolute).top,h=f+a.helperProportions.height,i=b.offset.left,k=i+b.proportions.width,j=b.offset.top,l=j+b.proportions.height;
|
137 |
-
switch(c){case "fit":return i<=e&&g<=k&&j<=f&&h<=l;case "intersect":return i<e+a.helperProportions.width/2&&g-a.helperProportions.width/2<k&&j<f+a.helperProportions.height/2&&h-a.helperProportions.height/2<l;case "pointer":return d.ui.isOver((a.positionAbs||a.position.absolute).top+(a.clickOffset||a.offset.click).top,(a.positionAbs||a.position.absolute).left+(a.clickOffset||a.offset.click).left,j,i,b.proportions.height,b.proportions.width);case "touch":return(f>=j&&f<=l||h>=j&&h<=l||f<j&&h>l)&&(e>=
|
138 |
-
i&&e<=k||g>=i&&g<=k||e<i&&g>k);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f<c.length;f++)if(!(c[f].options.disabled||a&&!c[f].accept.call(c[f].element[0],a.currentItem||a.element))){for(var h=0;h<g.length;h++)if(g[h]==c[f].element[0]){c[f].proportions.height=0;continue a}c[f].visible=c[f].element.css("display")!=
|
139 |
-
"none";if(c[f].visible){c[f].offset=c[f].element.offset();c[f].proportions={width:c[f].element[0].offsetWidth,height:c[f].element[0].offsetHeight};e=="mousedown"&&c[f]._activate.call(c[f],b)}}},drop:function(a,b){var c=false;d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&d.ui.intersect(a,this,this.options.tolerance))c=c||this._drop.call(this,b);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],a.currentItem||
|
140 |
-
a.element)){this.isout=1;this.isover=0;this._deactivate.call(this,b)}}});return c},drag:function(a,b){a.options.refreshPositions&&d.ui.ddmanager.prepareOffsets(a,b);d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var c=d.ui.intersect(a,this,this.options.tolerance);if(c=!c&&this.isover==1?"isout":c&&this.isover==0?"isover":null){var e;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){e=
|
141 |
-
d.data(g[0],"droppable");e.greedyChild=c=="isover"?1:0}}if(e&&c=="isover"){e.isover=0;e.isout=1;e._out.call(e,b)}this[c]=1;this[c=="isout"?"isover":"isout"]=0;this[c=="isover"?"_over":"_out"].call(this,b);if(e&&c=="isout"){e.isout=0;e.isover=1;e._over.call(e,b)}}}})}}})(jQuery);
|
142 |
-
;/*
|
143 |
-
* jQuery UI Resizable 1.8.9
|
144 |
-
*
|
145 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
146 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
147 |
-
* http://jquery.org/license
|
148 |
-
*
|
149 |
-
* http://docs.jquery.com/UI/Resizables
|
150 |
-
*
|
151 |
-
* Depends:
|
152 |
-
* jquery.ui.core.js
|
153 |
-
* jquery.ui.mouse.js
|
154 |
-
* jquery.ui.widget.js
|
155 |
-
*/
|
156 |
-
(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
|
157 |
-
_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
|
158 |
-
top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
|
159 |
-
this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
|
160 |
-
nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==
|
161 |
-
String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),k=0;k=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,k);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection();
|
162 |
-
this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){e(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};
|
163 |
-
if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),
|
164 |
-
d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=
|
165 |
-
this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:
|
166 |
-
this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",
|
167 |
-
b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;
|
168 |
-
f={width:c.size.width-(f?0:c.sizeDiff.width),height:c.size.height-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",
|
169 |
-
b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(l(b.left))this.position.left=b.left;if(l(b.top))this.position.top=b.top;if(l(b.height))this.size.height=b.height;if(l(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=
|
170 |
-
a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,d=l(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=l(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=l(b.width)&&a.minWidth&&a.minWidth>b.width,h=l(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,
|
171 |
-
k=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&k)b.left=i-a.minWidth;if(d&&k)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),
|
172 |
-
c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)||0;h=parseInt(f[h],10)||0;return g+h})}e.browser.msie&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=
|
173 |
-
this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+
|
174 |
-
a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,
|
175 |
-
arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,
|
176 |
-
{version:"1.8.9"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,
|
177 |
-
function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var k=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:k.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=
|
178 |
-
(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(k.css("position"))){c._revertToRelativePosition=true;k.css({position:"absolute",top:"auto",left:"auto"})}k.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=
|
179 |
-
false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-
|
180 |
-
a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",
|
181 |
-
b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top",
|
182 |
-
"Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,
|
183 |
-
f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=
|
184 |
-
a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+
|
185 |
-
a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&
|
186 |
-
e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",
|
187 |
-
height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=
|
188 |
-
d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
|
189 |
-
;/*
|
190 |
-
* jQuery UI Selectable 1.8.9
|
191 |
-
*
|
192 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
193 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
194 |
-
* http://jquery.org/license
|
195 |
-
*
|
196 |
-
* http://docs.jquery.com/UI/Selectables
|
197 |
-
*
|
198 |
-
* Depends:
|
199 |
-
* jquery.ui.core.js
|
200 |
-
* jquery.ui.mouse.js
|
201 |
-
* jquery.ui.widget.js
|
202 |
-
*/
|
203 |
-
(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),
|
204 |
-
selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX,
|
205 |
-
c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting",
|
206 |
-
c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d=
|
207 |
-
this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.right<b||a.top>i||a.bottom<g);else if(d.tolerance=="fit")k=a.left>b&&a.right<h&&a.top>g&&a.bottom<i;if(k){if(a.selected){a.$element.removeClass("ui-selected");a.selected=false}if(a.unselecting){a.$element.removeClass("ui-unselecting");
|
208 |
-
a.unselecting=false}if(!a.selecting){a.$element.addClass("ui-selecting");a.selecting=true;f._trigger("selecting",c,{selecting:a.element})}}else{if(a.selecting)if(c.metaKey&&a.startselected){a.$element.removeClass("ui-selecting");a.selecting=false;a.$element.addClass("ui-selected");a.selected=true}else{a.$element.removeClass("ui-selecting");a.selecting=false;if(a.startselected){a.$element.addClass("ui-unselecting");a.unselecting=true}f._trigger("unselecting",c,{unselecting:a.element})}if(a.selected)if(!c.metaKey&&
|
209 |
-
!a.startselected){a.$element.removeClass("ui-selected");a.selected=false;a.$element.addClass("ui-unselecting");a.unselecting=true;f._trigger("unselecting",c,{unselecting:a.element})}}}});return false}},_mouseStop:function(c){var f=this;this.dragged=false;e(".ui-unselecting",this.element[0]).each(function(){var d=e.data(this,"selectable-item");d.$element.removeClass("ui-unselecting");d.unselecting=false;d.startselected=false;f._trigger("unselected",c,{unselected:d.element})});e(".ui-selecting",this.element[0]).each(function(){var d=
|
210 |
-
e.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");d.selecting=false;d.selected=true;d.startselected=true;f._trigger("selected",c,{selected:d.element})});this._trigger("stop",c);this.helper.remove();return false}});e.extend(e.ui.selectable,{version:"1.8.9"})})(jQuery);
|
211 |
-
;/*
|
212 |
-
* jQuery UI Sortable 1.8.9
|
213 |
-
*
|
214 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
215 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
216 |
-
* http://jquery.org/license
|
217 |
-
*
|
218 |
-
* http://docs.jquery.com/UI/Sortables
|
219 |
-
*
|
220 |
-
* Depends:
|
221 |
-
* jquery.ui.core.js
|
222 |
-
* jquery.ui.mouse.js
|
223 |
-
* jquery.ui.widget.js
|
224 |
-
*/
|
225 |
-
(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){this.containerCache={};this.element.addClass("ui-sortable");
|
226 |
-
this.refresh();this.floating=this.items.length?/left|right/.test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a==="disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,
|
227 |
-
arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=
|
228 |
-
c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,
|
229 |
-
{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();
|
230 |
-
if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",
|
231 |
-
a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");
|
232 |
-
if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+
|
233 |
-
this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()-b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+
|
234 |
-
b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+
|
235 |
-
"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,
|
236 |
-
c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==
|
237 |
-
document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var b=this.containers.length-
|
238 |
-
1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});
|
239 |
-
this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")},toArray:function(a){var b=this._getItemsAsjQuery(a&&
|
240 |
-
a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?
|
241 |
-
"width":"height"]>a[this.floating?"width":"height"]?j:g<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection();var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?
|
242 |
-
c&&c=="right"||a=="down"?2:1:a&&(a=="down"?2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;
|
243 |
-
return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=
|
244 |
-
d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});
|
245 |
-
return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element),this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=
|
246 |
-
d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&&this.helper)this.offset.parent=
|
247 |
-
this._getParentOffset();for(var b=this.items.length-1;b>=0;b--){var c=this.items[b],e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=
|
248 |
-
e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];
|
249 |
-
if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);
|
250 |
-
c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===
|
251 |
-
1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=
|
252 |
-
this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):
|
253 |
-
b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width==""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==
|
254 |
-
""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=
|
255 |
-
this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),
|
256 |
-
10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions=
|
257 |
-
{width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||
|
258 |
-
document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,
|
259 |
-
b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=
|
260 |
-
document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():
|
261 |
-
e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-
|
262 |
-
this.offset.click.left<this.containment[0])f=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<
|
263 |
-
this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&
|
264 |
-
this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=
|
265 |
-
this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem[0].parentNode&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();
|
266 |
-
this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove",f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],
|
267 |
-
this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",
|
268 |
-
g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||
|
269 |
-
this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,
|
270 |
-
originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.8.9"})})(jQuery);
|
271 |
-
;/*
|
272 |
-
* jQuery UI Accordion 1.8.9
|
273 |
-
*
|
274 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
275 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
276 |
-
* http://jquery.org/license
|
277 |
-
*
|
278 |
-
* http://docs.jquery.com/UI/Accordion
|
279 |
-
*
|
280 |
-
* Depends:
|
281 |
-
* jquery.ui.core.js
|
282 |
-
* jquery.ui.widget.js
|
283 |
-
*/
|
284 |
-
(function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");
|
285 |
-
a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
|
286 |
-
if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",
|
287 |
-
function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a=this.options;if(a.icons){c("<span></span>").addClass("ui-icon "+
|
288 |
-
a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("tabIndex");
|
289 |
-
this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();
|
290 |
-
b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target);
|
291 |
-
a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+
|
292 |
-
c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options;
|
293 |
-
if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);
|
294 |
-
if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(),
|
295 |
-
e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight||
|
296 |
-
e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false",
|
297 |
-
tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.9",animations:{slide:function(a,b){a=
|
298 |
-
c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);f[i]={value:j[1],
|
299 |
-
unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",paddingTop:"hide",
|
300 |
-
paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
|
301 |
-
;/*
|
302 |
-
* jQuery UI Autocomplete 1.8.9
|
303 |
-
*
|
304 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
305 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
306 |
-
* http://jquery.org/license
|
307 |
-
*
|
308 |
-
* http://docs.jquery.com/UI/Autocomplete
|
309 |
-
*
|
310 |
-
* Depends:
|
311 |
-
* jquery.ui.core.js
|
312 |
-
* jquery.ui.widget.js
|
313 |
-
* jquery.ui.position.js
|
314 |
-
*/
|
315 |
-
(function(d){d.widget("ui.autocomplete",{options:{appendTo:"body",delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,f;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){f=false;var e=d.ui.keyCode;
|
316 |
-
switch(c.keyCode){case e.PAGE_UP:a._move("previousPage",c);break;case e.PAGE_DOWN:a._move("nextPage",c);break;case e.UP:a._move("previous",c);c.preventDefault();break;case e.DOWN:a._move("next",c);c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:if(a.menu.active){f=true;c.preventDefault()}case e.TAB:if(!a.menu.active)return;a.menu.select(c);break;case e.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=a.element.val()){a.selectedItem=
|
317 |
-
null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(f){f=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||
|
318 |
-
"body",b)[0]).mousedown(function(c){var e=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(g){g.target!==a.element[0]&&g.target!==e&&!d.ui.contains(e,g.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,e){e=e.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:e})&&/^key/.test(c.originalEvent.type)&&a.element.val(e.value)},selected:function(c,e){var g=e.item.data("item.autocomplete"),
|
319 |
-
h=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=h;setTimeout(function(){a.previous=h;a.selectedItem=g},1)}false!==a._trigger("select",c,{item:g})&&a.element.val(g.value);a.term=a.element.val();a.close(c);a.selectedItem=g},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");
|
320 |
-
this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&&b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,f;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,e){e(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source===
|
321 |
-
"string"){f=this.options.source;this.source=function(c,e){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:f,data:c,dataType:"json",success:function(g,h,i){i===a.xhr&&e(g);a.xhr=null},error:function(g){g===a.xhr&&e([]);a.xhr=null}})}}else this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.pending++;
|
322 |
-
this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)},_response:function(a){if(!this.options.disabled&&a&&a.length){a=this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",a)}},_change:function(a){this.previous!==
|
323 |
-
this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return d.map(a,function(b){if(typeof b==="string")return{label:b,value:b};return d.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();b.show();this._resizeMenu();b.position(d.extend({of:this.element},this.options.position))},
|
324 |
-
_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(a,b){var f=this;d.each(b,function(c,e){f._renderItem(a,e)})},_renderItem:function(a,b){return d("<li></li>").data("item.autocomplete",b).append(d("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);
|
325 |
-
else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(a,b){var f=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return f.test(c.label||c.value||c)})}})})(jQuery);
|
326 |
-
(function(d){d.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(b){if(d(b.target).closest(".ui-menu-item a").length){b.preventDefault();a.select(b)}});this.refresh()},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
|
327 |
-
-1).mouseenter(function(b){a.activate(b,d(this).parent())}).mouseleave(function(){a.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var f=b.offset().top-this.element.offset().top,c=this.element.attr("scrollTop"),e=this.element.height();if(f<0)this.element.attr("scrollTop",c+f);else f>=e&&this.element.attr("scrollTop",c+f-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",a,{item:b})},
|
328 |
-
deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");this._trigger("blur");this.active=null}},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,f){if(this.active){a=this.active[a+"All"](".ui-menu-item").eq(0);
|
329 |
-
a.length?this.activate(f,a):this.activate(f,this.element.children(b))}else this.activate(f,this.element.children(b))},nextPage:function(a){if(this.hasScroll())if(!this.active||this.last())this.activate(a,this.element.children(".ui-menu-item:first"));else{var b=this.active.offset().top,f=this.element.height(),c=this.element.children(".ui-menu-item").filter(function(){var e=d(this).offset().top-b-f+d(this).height();return e<10&&e>-10});c.length||(c=this.element.children(".ui-menu-item:last"));this.activate(a,
|
330 |
-
c)}else this.activate(a,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(a){if(this.hasScroll())if(!this.active||this.first())this.activate(a,this.element.children(".ui-menu-item:last"));else{var b=this.active.offset().top,f=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-b+f-d(this).height();return c<10&&c>-10});result.length||(result=this.element.children(".ui-menu-item:first"));
|
331 |
-
this.activate(a,result)}else this.activate(a,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element.attr("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})})(jQuery);
|
332 |
-
;/*
|
333 |
-
* jQuery UI Button 1.8.9
|
334 |
-
*
|
335 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
336 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
337 |
-
* http://jquery.org/license
|
338 |
-
*
|
339 |
-
* http://docs.jquery.com/UI/Button
|
340 |
-
*
|
341 |
-
* Depends:
|
342 |
-
* jquery.ui.core.js
|
343 |
-
* jquery.ui.widget.js
|
344 |
-
*/
|
345 |
-
(function(a){var g,i=function(b){a(":ui-button",b.target.form).each(function(){var c=a(this).data("button");setTimeout(function(){c.refresh()},1)})},h=function(b){var c=b.name,d=b.form,e=a([]);if(c)e=d?a(d).find("[name='"+c+"']"):a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form});return e};a.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",
|
346 |
-
i);if(typeof this.options.disabled!=="boolean")this.options.disabled=this.element.attr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var b=this,c=this.options,d=this.type==="checkbox"||this.type==="radio",e="ui-state-hover"+(!d?" ui-state-active":"");if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",
|
347 |
-
function(){if(!c.disabled){a(this).addClass("ui-state-hover");this===g&&a(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){c.disabled||a(this).removeClass(e)}).bind("focus.button",function(){a(this).addClass("ui-state-focus")}).bind("blur.button",function(){a(this).removeClass("ui-state-focus")});d&&this.element.bind("change.button",function(){b.refresh()});if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).toggleClass("ui-state-active");
|
348 |
-
b.buttonElement.attr("aria-pressed",b.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).addClass("ui-state-active");b.buttonElement.attr("aria-pressed",true);var f=b.element[0];h(f).not(f).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed",false)});else{this.buttonElement.bind("mousedown.button",function(){if(c.disabled)return false;a(this).addClass("ui-state-active");
|
349 |
-
g=this;a(document).one("mouseup",function(){g=null})}).bind("mouseup.button",function(){if(c.disabled)return false;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(f){if(c.disabled)return false;if(f.keyCode==a.ui.keyCode.SPACE||f.keyCode==a.ui.keyCode.ENTER)a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(f){f.keyCode===a.ui.keyCode.SPACE&&a(this).click()})}this._setOption("disabled",
|
350 |
-
c.disabled)},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type==="radio"){this.buttonElement=this.element.parents().last().find("label[for="+this.element.attr("id")+"]");this.element.addClass("ui-helper-hidden-accessible");var b=this.element.is(":checked");b&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",b)}else this.buttonElement=
|
351 |
-
this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||
|
352 |
-
this.buttonElement.removeAttr("title");a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);if(b==="disabled")c?this.element.attr("disabled",true):this.element.removeAttr("disabled");this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b);if(this.type==="radio")h(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed",
|
353 |
-
true):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed",false)});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed",true):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed",false)},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
|
354 |
-
c=a("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary;if(d.primary||d.secondary){b.addClass("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary"));d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>");d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>");if(!this.options.text){b.addClass(e?"ui-button-icons-only":"ui-button-icon-only").removeClass("ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary");
|
355 |
-
this.hasTitle||b.attr("title",c)}}else b.addClass("ui-button-text-only")}}});a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass("ui-corner-left").end().filter(":last").addClass("ui-corner-right").end().end()},
|
356 |
-
destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");a.Widget.prototype.destroy.call(this)}})})(jQuery);
|
357 |
-
;/*
|
358 |
-
* jQuery UI Dialog 1.8.9
|
359 |
-
*
|
360 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
361 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
362 |
-
* http://jquery.org/license
|
363 |
-
*
|
364 |
-
* http://docs.jquery.com/UI/Dialog
|
365 |
-
*
|
366 |
-
* Depends:
|
367 |
-
* jquery.ui.core.js
|
368 |
-
* jquery.ui.widget.js
|
369 |
-
* jquery.ui.button.js
|
370 |
-
* jquery.ui.draggable.js
|
371 |
-
* jquery.ui.mouse.js
|
372 |
-
* jquery.ui.position.js
|
373 |
-
* jquery.ui.resizable.js
|
374 |
-
*/
|
375 |
-
(function(c,j){var k={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},l={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&
|
376 |
-
c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",
|
377 |
-
-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role",
|
378 |
-
"button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=
|
379 |
-
b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");a.uiDialog.remove();a.originalTitle&&
|
380 |
-
a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==b.uiDialog[0]){e=c(this).css("z-index");
|
381 |
-
isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);
|
382 |
-
d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target===f[0]&&e.shiftKey){g.focus(1);return false}}});
|
383 |
-
c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a,function(f,
|
384 |
-
h){h=c.isFunction(h)?{click:h,text:f}:h;f=c('<button type="button"></button>').attr(h,true).unbind("click").click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.fn.button&&f.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=
|
385 |
-
d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,originalSize:f.originalSize,
|
386 |
-
position:f.position,size:f.size}}a=a===j?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",f,b(h))},stop:function(f,
|
387 |
-
h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===
|
388 |
-
1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f);if(g in k)e=true;if(g in
|
389 |
-
l)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):e.removeClass("ui-dialog-disabled");
|
390 |
-
break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a=this.options,b,d,e=
|
391 |
-
this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height-b,0));this.uiDialog.is(":data(resizable)")&&
|
392 |
-
this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.9",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(a){if(this.instances.length===
|
393 |
-
0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()<c.ui.dialog.overlay.maxZ)return false})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
|
394 |
-
height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
|
395 |
-
b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,
|
396 |
-
function(){a=a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
|
397 |
-
;/*
|
398 |
-
* jQuery UI Slider 1.8.9
|
399 |
-
*
|
400 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
401 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
402 |
-
* http://jquery.org/license
|
403 |
-
*
|
404 |
-
* http://docs.jquery.com/UI/Slider
|
405 |
-
*
|
406 |
-
* Depends:
|
407 |
-
* jquery.ui.core.js
|
408 |
-
* jquery.ui.mouse.js
|
409 |
-
* jquery.ui.widget.js
|
410 |
-
*/
|
411 |
-
(function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var b=this,a=this.options;this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");a.disabled&&this.element.addClass("ui-slider-disabled ui-disabled");
|
412 |
-
this.range=d([]);if(a.range){if(a.range===true){this.range=d("<div></div>");if(!a.values)a.values=[this._valueMin(),this._valueMin()];if(a.values.length&&a.values.length!==2)a.values=[a.values[0],a.values[0]]}else this.range=d("<div></div>");this.range.appendTo(this.element).addClass("ui-slider-range");if(a.range==="min"||a.range==="max")this.range.addClass("ui-slider-range-"+a.range);this.range.addClass("ui-widget-header")}d(".ui-slider-handle",this.element).length===0&&d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");
|
413 |
-
if(a.values&&a.values.length)for(;d(".ui-slider-handle",this.element).length<a.values.length;)d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");this.handles=d(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(c){c.preventDefault()}).hover(function(){a.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(a.disabled)d(this).blur();
|
414 |
-
else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(c){d(this).data("index.ui-slider-handle",c)});this.handles.keydown(function(c){var e=true,f=d(this).data("index.ui-slider-handle"),h,g,i;if(!b.options.disabled){switch(c.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:e=
|
415 |
-
false;if(!b._keySliding){b._keySliding=true;d(this).addClass("ui-state-active");h=b._start(c,f);if(h===false)return}break}i=b.options.step;h=b.options.values&&b.options.values.length?(g=b.values(f)):(g=b.value());switch(c.keyCode){case d.ui.keyCode.HOME:g=b._valueMin();break;case d.ui.keyCode.END:g=b._valueMax();break;case d.ui.keyCode.PAGE_UP:g=b._trimAlignValue(h+(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:g=b._trimAlignValue(h-(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(h===
|
416 |
-
b._valueMax())return;g=b._trimAlignValue(h+i);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(h===b._valueMin())return;g=b._trimAlignValue(h-i);break}b._slide(c,f,g);return e}}).keyup(function(c){var e=d(this).data("index.ui-slider-handle");if(b._keySliding){b._keySliding=false;b._stop(c,e);b._change(c,e);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");
|
417 |
-
this._mouseDestroy();return this},_mouseCapture:function(b){var a=this.options,c,e,f,h,g;if(a.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:b.pageX,y:b.pageY});e=this._valueMax()-this._valueMin()+1;h=this;this.handles.each(function(i){var j=Math.abs(c-h.values(i));if(e>j){e=j;f=d(this);g=i}});if(a.range===true&&this.values(1)===a.min){g+=1;f=d(this.handles[g])}if(this._start(b,
|
418 |
-
g)===false)return false;this._mouseSliding=true;h._handleIndex=g;f.addClass("ui-state-active").focus();a=f.offset();this._clickOffset=!d(b.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:b.pageX-a.left-f.width()/2,top:b.pageY-a.top-f.height()/2-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(b,g,c);return this._animateOff=true},_mouseStart:function(){return true},
|
419 |
-
_mouseDrag:function(b){var a=this._normValueFromMouse({x:b.pageX,y:b.pageY});this._slide(b,this._handleIndex,a);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(b){var a;
|
420 |
-
if(this.orientation==="horizontal"){a=this.elementSize.width;b=b.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{a=this.elementSize.height;b=b.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}a=b/a;if(a>1)a=1;if(a<0)a=0;if(this.orientation==="vertical")a=1-a;b=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+a*b)},_start:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=
|
421 |
-
this.values(a);c.values=this.values()}return this._trigger("start",b,c)},_slide:function(b,a,c){var e;if(this.options.values&&this.options.values.length){e=this.values(a?0:1);if(this.options.values.length===2&&this.options.range===true&&(a===0&&c>e||a===1&&c<e))c=e;if(c!==this.values(a)){e=this.values();e[a]=c;b=this._trigger("slide",b,{handle:this.handles[a],value:c,values:e});this.values(a?0:1);b!==false&&this.values(a,c,true)}}else if(c!==this.value()){b=this._trigger("slide",b,{handle:this.handles[a],
|
422 |
-
value:c});b!==false&&this.value(c)}},_stop:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);c.values=this.values()}this._trigger("stop",b,c)},_change:function(b,a){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);c.values=this.values()}this._trigger("change",b,c)}},value:function(b){if(arguments.length){this.options.value=
|
423 |
-
this._trimAlignValue(b);this._refreshValue();this._change(null,0)}return this._value()},values:function(b,a){var c,e,f;if(arguments.length>1){this.options.values[b]=this._trimAlignValue(a);this._refreshValue();this._change(null,b)}if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;e=arguments[0];for(f=0;f<c.length;f+=1){c[f]=this._trimAlignValue(e[f]);this._change(null,f)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(b):this.value();
|
424 |
-
else return this._values()},_setOption:function(b,a){var c,e=0;if(d.isArray(this.options.values))e=this.options.values.length;d.Widget.prototype._setOption.apply(this,arguments);switch(b){case "disabled":if(a){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled");this.element.addClass("ui-disabled")}else{this.handles.removeAttr("disabled");this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation();
|
425 |
-
this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(c=0;c<e;c+=1)this._change(null,c);this._animateOff=false;break}},_value:function(){var b=this.options.value;return b=this._trimAlignValue(b)},_values:function(b){var a,c;if(arguments.length){a=this.options.values[b];
|
426 |
-
return a=this._trimAlignValue(a)}else{a=this.options.values.slice();for(c=0;c<a.length;c+=1)a[c]=this._trimAlignValue(a[c]);return a}},_trimAlignValue:function(b){if(b<=this._valueMin())return this._valueMin();if(b>=this._valueMax())return this._valueMax();var a=this.options.step>0?this.options.step:1,c=(b-this._valueMin())%a;alignValue=b-c;if(Math.abs(c)*2>=a)alignValue+=c>0?a:-a;return parseFloat(alignValue.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},
|
427 |
-
_refreshValue:function(){var b=this.options.range,a=this.options,c=this,e=!this._animateOff?a.animate:false,f,h={},g,i,j,l;if(this.options.values&&this.options.values.length)this.handles.each(function(k){f=(c.values(k)-c._valueMin())/(c._valueMax()-c._valueMin())*100;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";d(this).stop(1,1)[e?"animate":"css"](h,a.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(k===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},a.animate);
|
428 |
-
if(k===1)c.range[e?"animate":"css"]({width:f-g+"%"},{queue:false,duration:a.animate})}else{if(k===0)c.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},a.animate);if(k===1)c.range[e?"animate":"css"]({height:f-g+"%"},{queue:false,duration:a.animate})}g=f});else{i=this.value();j=this._valueMin();l=this._valueMax();f=l!==j?(i-j)/(l-j)*100:0;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](h,a.animate);if(b==="min"&&this.orientation==="horizontal")this.range.stop(1,
|
429 |
-
1)[e?"animate":"css"]({width:f+"%"},a.animate);if(b==="max"&&this.orientation==="horizontal")this.range[e?"animate":"css"]({width:100-f+"%"},{queue:false,duration:a.animate});if(b==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},a.animate);if(b==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:a.animate})}}});d.extend(d.ui.slider,{version:"1.8.9"})})(jQuery);
|
430 |
-
;/*
|
431 |
-
* jQuery UI Tabs 1.8.9
|
432 |
-
*
|
433 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
434 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
435 |
-
* http://jquery.org/license
|
436 |
-
*
|
437 |
-
* http://docs.jquery.com/UI/Tabs
|
438 |
-
*
|
439 |
-
* Depends:
|
440 |
-
* jquery.ui.core.js
|
441 |
-
* jquery.ui.widget.js
|
442 |
-
*/
|
443 |
-
(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading…</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&&
|
444 |
-
e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=
|
445 |
-
d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]||
|
446 |
-
(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
|
447 |
-
this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected=
|
448 |
-
this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
|
449 |
-
if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
|
450 |
-
this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+
|
451 |
-
g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",
|
452 |
-
function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};
|
453 |
-
this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected=
|
454 |
-
-1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
|
455 |
-
d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=
|
456 |
-
d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b,
|
457 |
-
e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);
|
458 |
-
j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();
|
459 |
-
if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=b}),function(h){return h>=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null,
|
460 |
-
this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this},
|
461 |
-
load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c,
|
462 |
-
"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},
|
463 |
-
url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.9"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k<a.anchors.length?k:0)},b);j&&j.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(j){j.clientX&&
|
464 |
-
a.rotate(null)}:function(){t=c.selected;h()});if(b){this.element.bind("tabsshow",h);this.anchors.bind(c.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(c.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
|
465 |
-
;/*
|
466 |
-
* jQuery UI Datepicker 1.8.9
|
467 |
-
*
|
468 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
469 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
470 |
-
* http://jquery.org/license
|
471 |
-
*
|
472 |
-
* http://docs.jquery.com/UI/Datepicker
|
473 |
-
*
|
474 |
-
* Depends:
|
475 |
-
* jquery.ui.core.js
|
476 |
-
*/
|
477 |
-
(function(d,G){function K(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
|
478 |
-
"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
|
479 |
-
"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
|
480 |
-
minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')}function E(a,b){d.extend(a,b);for(var c in b)if(b[c]==
|
481 |
-
null||b[c]==G)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.9"}});var y=(new Date).getTime();d.extend(K.prototype,{markerClassName:"hasDatepicker",log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){E(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();
|
482 |
-
f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')}},
|
483 |
-
_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&
|
484 |
-
b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==
|
485 |
-
""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,
|
486 |
-
c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),
|
487 |
-
true);this._updateDatepicker(b);this._updateAlternate(b);b.dpDiv.show()}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}E(a.settings,e||{});
|
488 |
-
b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);
|
489 |
-
this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",
|
490 |
-
this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().removeClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,
|
491 |
-
function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().addClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:
|
492 |
-
f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false},_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?d.extend({},
|
493 |
-
e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&this._hideDatepicker();var h=this._getDateDatepicker(a,true);E(e.settings,f);this._attachments(d(a),e);this._autoSize(e);this._setDateDatepicker(a,h);this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a,b);
|
494 |
-
this._updateDatepicker(a);this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass+":not(."+d.datepicker._currentClass+")",b.dpDiv);c[0]?
|
495 |
-
d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]):d.datepicker._hideDatepicker();return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target);c=a.ctrlKey||
|
496 |
-
a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,
|
497 |
-
e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b=d.datepicker._getInst(a.target);if(d.datepicker._get(b,
|
498 |
-
"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));var c=String.fromCharCode(a.charCode==G?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},
|
499 |
-
_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);d.datepicker._curInst&&d.datepicker._curInst!=b&&d.datepicker._curInst.dpDiv.stop(true,true);var c=d.datepicker._get(b,"beforeShow");E(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=
|
500 |
-
d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,
|
501 |
-
c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){d.datepicker._datepickerShowing=true;var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.effects&&
|
502 |
-
d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this,c=d.datepicker._getBorders(a.dpDiv);a.dpDiv.empty().append(this._generateHTML(a));var e=a.dpDiv.find("iframe.ui-datepicker-cover");e.length&&e.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()});a.dpDiv.find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",
|
503 |
-
function(){d(this).removeClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).removeClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).removeClass("ui-datepicker-next-hover")}).bind("mouseover",function(){if(!b._isDisabledDatepicker(a.inline?a.dpDiv.parent()[0]:a.input[0])){d(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");d(this).addClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=
|
504 |
-
-1&&d(this).addClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).addClass("ui-datepicker-next-hover")}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();c=this._getNumberOfMonths(a);e=c[1];e>1?a.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",17*e+"em"):a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");a.dpDiv[(c[0]!=1||c[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,
|
505 |
-
"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input.focus();if(a.yearshtml){var f=a.yearshtml;setTimeout(function(){f===a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);f=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},
|
506 |
-
_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-
|
507 |
-
g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1);)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?
|
508 |
-
b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();if(a=this._get(b,"onClose"))a.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},
|
509 |
-
_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):
|
510 |
-
0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=
|
511 |
-
false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var b=this._getInst(d(a)[0]);b.input&&b._selectingMonthYear&&setTimeout(function(){b.input.focus()},0);b._selectingMonthYear=!b._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=
|
512 |
-
d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);
|
513 |
-
else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=
|
514 |
-
a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,
|
515 |
-
g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=z+1<a.length&&a.charAt(z+1)==p)&&z++;return p},m=function(p){var v=o(p);p=new RegExp("^\\d{1,"+(p=="@"?14:p=="!"?20:p=="y"&&v?4:p=="o"?3:2)+"}");p=b.substring(s).match(p);if(!p)throw"Missing number at position "+s;s+=p[0].length;return parseInt(p[0],10)},n=function(p,v,H){p=o(p)?H:v;for(v=0;v<p.length;v++)if(b.substr(s,p[v].length).toLowerCase()==p[v].toLowerCase()){s+=p[v].length;return v+1}throw"Unknown name at position "+
|
516 |
-
s;},r=function(){if(b.charAt(s)!=a.charAt(z))throw"Unexpected literal at position "+s;s++},s=0,z=0;z<a.length;z++)if(k)if(a.charAt(z)=="'"&&!o("'"))k=false;else r();else switch(a.charAt(z)){case "d":l=m("d");break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":j=m("m");break;case "M":j=n("M",i,g);break;case "y":c=m("y");break;case "@":var w=new Date(m("@"));c=w.getFullYear();j=w.getMonth()+1;l=w.getDate();break;case "!":w=new Date((m("!")-this._ticksTo1970)/1E4);c=w.getFullYear();j=w.getMonth()+
|
517 |
-
1;l=w.getDate();break;case "'":if(o("'"))r();else k=true;break;default:r()}if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}w=this._daylightSavingAdjust(new Date(c,j-1,l));if(w.getFullYear()!=c||w.getMonth()+1!=j||w.getDate()!=l)throw"Invalid date";return w},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",
|
518 |
-
RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=k+1<a.length&&
|
519 |
-
a.charAt(k+1)==o)&&k++;return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length<n;)m="0"+m;return m},j=function(o,m,n,r){return i(o)?r[m]:n[m]},l="",u=false;if(b)for(var k=0;k<a.length;k++)if(u)if(a.charAt(k)=="'"&&!i("'"))u=false;else l+=a.charAt(k);else switch(a.charAt(k)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=j("D",b.getDay(),e,f);break;case "o":l+=g("o",(b.getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5,3);break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=j("M",
|
520 |
-
b.getMonth(),h,c);break;case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;case "'":if(i("'"))l+="'";else u=true;break;default:l+=a.charAt(k)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+=
|
521 |
-
"0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==G?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);var i=this._getFormatConfig(a);try{f=this.parseDate(c,e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth=
|
522 |
-
f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g=
|
523 |
-
(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,j=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,k=u.exec(h);k;){switch(k[2]||"d"){case "d":case "D":g+=parseInt(k[1],10);break;case "w":case "W":g+=parseInt(k[1],10)*7;break;case "m":case "M":l+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break;case "y":case "Y":j+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break}k=u.exec(h)}return new Date(j,
|
524 |
-
l,g)};if(b=(b=b==null||b===""?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):new Date(b.getTime()))&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=
|
525 |
-
a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),
|
526 |
-
b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=
|
527 |
-
this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&n<k?k:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a));n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', -"+j+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+
|
528 |
-
(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>";var r=this._get(a,"nextText");r=!h?r:this.formatDate(r,this._daylightSavingAdjust(new Date(m,g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', +"+j+", 'M');\" title=\""+r+'"><span class="ui-icon ui-icon-circle-triangle-'+
|
529 |
-
(c?"w":"e")+'">'+r+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+r+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+r+"</span></a>";j=this._get(a,"currentText");r=this._get(a,"gotoCurrent")&&a.currentDay?u:b;j=!h?j:this.formatDate(j,r,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+y+'.datepicker._hideDatepicker();">'+this._get(a,
|
530 |
-
"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,r)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._gotoToday('#"+a.id+"');\">"+j+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");r=this._get(a,"dayNames");this._get(a,"dayNamesShort");var s=this._get(a,"dayNamesMin"),z=
|
531 |
-
this._get(a,"monthNames"),w=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),v=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var L=this._getDefaultDate(a),I="",C=0;C<i[0];C++){for(var M="",D=0;D<i[1];D++){var N=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",x="";if(l){x+='<div class="ui-datepicker-group';if(i[1]>1)switch(D){case 0:x+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-
|
532 |
-
1:x+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:x+=" ui-datepicker-group-middle";t="";break}x+='">'}x+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&C==0?c?f:n:"")+(/all|right/.test(t)&&C==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,C>0||D>0,z,w)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var A=j?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(t=0;t<7;t++){var q=
|
533 |
-
(t+h)%7;A+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+r[q]+'">'+s[q]+"</span></th>"}x+=A+"</tr></thead><tbody>";A=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,A);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;A=l?6:Math.ceil((t+A)/7);q=this._daylightSavingAdjust(new Date(m,g,1-t));for(var O=0;O<A;O++){x+="<tr>";var P=!j?"":'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(q)+"</td>";for(t=0;t<7;t++){var F=
|
534 |
-
p?p.apply(a.input?a.input[0]:null,[q]):[true,""],B=q.getMonth()!=g,J=B&&!H||!F[0]||k&&q<k||o&&q>o;P+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(B?" ui-datepicker-other-month":"")+(q.getTime()==N.getTime()&&g==a.selectedMonth&&a._keyEvent||L.getTime()==q.getTime()&&L.getTime()==N.getTime()?" "+this._dayOverClass:"")+(J?" "+this._unselectableClass+" ui-state-disabled":"")+(B&&!v?"":" "+F[1]+(q.getTime()==u.getTime()?" "+this._currentClass:"")+(q.getTime()==b.getTime()?" ui-datepicker-today":
|
535 |
-
""))+'"'+((!B||v)&&F[2]?' title="'+F[2]+'"':"")+(J?"":' onclick="DP_jQuery_'+y+".datepicker._selectDay('#"+a.id+"',"+q.getMonth()+","+q.getFullYear()+', this);return false;"')+">"+(B&&!v?" ":J?'<span class="ui-state-default">'+q.getDate()+"</span>":'<a class="ui-state-default'+(q.getTime()==b.getTime()?" ui-state-highlight":"")+(q.getTime()==u.getTime()?" ui-state-active":"")+(B?" ui-priority-secondary":"")+'" href="#">'+q.getDate()+"</a>")+"</td>";q.setDate(q.getDate()+1);q=this._daylightSavingAdjust(q)}x+=
|
536 |
-
P+"</tr>"}g++;if(g>11){g=0;m++}x+="</tbody></table>"+(l?"</div>"+(i[0]>0&&D==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");M+=x}I+=M}I+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='<div class="ui-datepicker-title">',
|
537 |
-
o="";if(h||!j)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+a.id+"');\">";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&(!m||n<=f.getMonth()))o+='<option value="'+n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(k+=o+(h||!(j&&
|
538 |
-
l)?" ":""));a.yearshtml="";if(h||!l)k+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+
|
539 |
-
a.id+"', this, 'Y');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+a.id+"');\">";b<=g;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";a.yearshtml+="</select>";if(d.browser.mozilla)k+='<select class="ui-datepicker-year"><option value="'+c+'" selected="selected">'+c+"</option></select>";else{k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="</div>";return k},_adjustInstDate:function(a,b,c){var e=
|
540 |
-
a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,
|
541 |
-
"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);
|
542 |
-
c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,
|
543 |
-
"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=
|
544 |
-
function(a){if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));
|
545 |
-
return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.9";window["DP_jQuery_"+y]=d})(jQuery);
|
546 |
-
;/*
|
547 |
-
* jQuery UI Progressbar 1.8.9
|
548 |
-
*
|
549 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
550 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
551 |
-
* http://jquery.org/license
|
552 |
-
*
|
553 |
-
* http://docs.jquery.com/UI/Progressbar
|
554 |
-
*
|
555 |
-
* Depends:
|
556 |
-
* jquery.ui.core.js
|
557 |
-
* jquery.ui.widget.js
|
558 |
-
*/
|
559 |
-
(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
|
560 |
-
this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*
|
561 |
-
this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.9"})})(jQuery);
|
562 |
-
;/*
|
563 |
-
* jQuery UI Effects 1.8.9
|
564 |
-
*
|
565 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
566 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
567 |
-
* http://jquery.org/license
|
568 |
-
*
|
569 |
-
* http://docs.jquery.com/UI/Effects/
|
570 |
-
*/
|
571 |
-
jQuery.effects||function(f,j){function n(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
|
572 |
-
16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return o.transparent;return o[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return n(b)}function p(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
|
573 |
-
a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function q(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
|
574 |
-
a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function m(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
|
575 |
-
"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=n(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var o={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
|
576 |
-
0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
|
577 |
-
211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},r=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,
|
578 |
-
d){if(f.isFunction(b)){d=b;b=null}return this.queue("fx",function(){var e=f(this),g=e.attr("style")||" ",h=q(p.call(this)),l,v=e.attr("className");f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});l=q(p.call(this));e.attr("className",v);e.animate(u(h,l),a,b,function(){f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)});h=f.queue(this);l=h.splice(h.length-1,1)[0];
|
579 |
-
h.splice(1,0,l);f.dequeue(this)})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,
|
580 |
-
a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.9",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";return a},getBaseline:function(c,
|
581 |
-
a){var b;switch(c[0]){case "top":b=0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",
|
582 |
-
border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);
|
583 |
-
return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(m(c))return this._show.apply(this,arguments);
|
584 |
-
else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(m(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(m(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),
|
585 |
-
b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,
|
586 |
-
a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,
|
587 |
-
a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==
|
588 |
-
e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=
|
589 |
-
g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/
|
590 |
-
h);if(a<1)return-0.5*h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,
|
591 |
-
a,b,d,e){return d-f.easing.easeOutBounce(c,e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
|
592 |
-
;/*
|
593 |
-
* jQuery UI Effects Blind 1.8.9
|
594 |
-
*
|
595 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
596 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
597 |
-
* http://jquery.org/license
|
598 |
-
*
|
599 |
-
* http://docs.jquery.com/UI/Effects/Blind
|
600 |
-
*
|
601 |
-
* Depends:
|
602 |
-
* jquery.effects.core.js
|
603 |
-
*/
|
604 |
-
(function(b){b.effects.blind=function(c){return this.queue(function(){var a=b(this),g=["position","top","bottom","left","right"],f=b.effects.setMode(a,c.options.mode||"hide"),d=c.options.direction||"vertical";b.effects.save(a,g);a.show();var e=b.effects.createWrapper(a).css({overflow:"hidden"}),h=d=="vertical"?"height":"width";d=d=="vertical"?e.height():e.width();f=="show"&&e.css(h,0);var i={};i[h]=f=="show"?d:0;e.animate(i,c.duration,c.options.easing,function(){f=="hide"&&a.hide();b.effects.restore(a,
|
605 |
-
g);b.effects.removeWrapper(a);c.callback&&c.callback.apply(a[0],arguments);a.dequeue()})})}})(jQuery);
|
606 |
-
;/*
|
607 |
-
* jQuery UI Effects Bounce 1.8.9
|
608 |
-
*
|
609 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
610 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
611 |
-
* http://jquery.org/license
|
612 |
-
*
|
613 |
-
* http://docs.jquery.com/UI/Effects/Bounce
|
614 |
-
*
|
615 |
-
* Depends:
|
616 |
-
* jquery.effects.core.js
|
617 |
-
*/
|
618 |
-
(function(e){e.effects.bounce=function(b){return this.queue(function(){var a=e(this),l=["position","top","bottom","left","right"],h=e.effects.setMode(a,b.options.mode||"effect"),d=b.options.direction||"up",c=b.options.distance||20,m=b.options.times||5,i=b.duration||250;/show|hide/.test(h)&&l.push("opacity");e.effects.save(a,l);a.show();e.effects.createWrapper(a);var f=d=="up"||d=="down"?"top":"left";d=d=="up"||d=="left"?"pos":"neg";c=b.options.distance||(f=="top"?a.outerHeight({margin:true})/3:a.outerWidth({margin:true})/
|
619 |
-
3);if(h=="show")a.css("opacity",0).css(f,d=="pos"?-c:c);if(h=="hide")c/=m*2;h!="hide"&&m--;if(h=="show"){var g={opacity:1};g[f]=(d=="pos"?"+=":"-=")+c;a.animate(g,i/2,b.options.easing);c/=2;m--}for(g=0;g<m;g++){var j={},k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing);c=h=="hide"?c*2:c/2}if(h=="hide"){g={opacity:0};g[f]=(d=="pos"?"-=":"+=")+c;a.animate(g,i/2,b.options.easing,function(){a.hide();e.effects.restore(a,l);e.effects.removeWrapper(a);
|
620 |
-
b.callback&&b.callback.apply(this,arguments)})}else{j={};k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing,function(){e.effects.restore(a,l);e.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments)})}a.queue("fx",function(){a.dequeue()});a.dequeue()})}})(jQuery);
|
621 |
-
;/*
|
622 |
-
* jQuery UI Effects Clip 1.8.9
|
623 |
-
*
|
624 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
625 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
626 |
-
* http://jquery.org/license
|
627 |
-
*
|
628 |
-
* http://docs.jquery.com/UI/Effects/Clip
|
629 |
-
*
|
630 |
-
* Depends:
|
631 |
-
* jquery.effects.core.js
|
632 |
-
*/
|
633 |
-
(function(b){b.effects.clip=function(e){return this.queue(function(){var a=b(this),i=["position","top","bottom","left","right","height","width"],f=b.effects.setMode(a,e.options.mode||"hide"),c=e.options.direction||"vertical";b.effects.save(a,i);a.show();var d=b.effects.createWrapper(a).css({overflow:"hidden"});d=a[0].tagName=="IMG"?d:a;var g={size:c=="vertical"?"height":"width",position:c=="vertical"?"top":"left"};c=c=="vertical"?d.height():d.width();if(f=="show"){d.css(g.size,0);d.css(g.position,
|
634 |
-
c/2)}var h={};h[g.size]=f=="show"?c:0;h[g.position]=f=="show"?0:c/2;d.animate(h,{queue:false,duration:e.duration,easing:e.options.easing,complete:function(){f=="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);e.callback&&e.callback.apply(a[0],arguments);a.dequeue()}})})}})(jQuery);
|
635 |
-
;/*
|
636 |
-
* jQuery UI Effects Drop 1.8.9
|
637 |
-
*
|
638 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
639 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
640 |
-
* http://jquery.org/license
|
641 |
-
*
|
642 |
-
* http://docs.jquery.com/UI/Effects/Drop
|
643 |
-
*
|
644 |
-
* Depends:
|
645 |
-
* jquery.effects.core.js
|
646 |
-
*/
|
647 |
-
(function(c){c.effects.drop=function(d){return this.queue(function(){var a=c(this),h=["position","top","bottom","left","right","opacity"],e=c.effects.setMode(a,d.options.mode||"hide"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a);var f=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var g=d.options.distance||(f=="top"?a.outerHeight({margin:true})/2:a.outerWidth({margin:true})/2);if(e=="show")a.css("opacity",0).css(f,b=="pos"?-g:g);var i={opacity:e==
|
648 |
-
"show"?1:0};i[f]=(e=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
|
649 |
-
;/*
|
650 |
-
* jQuery UI Effects Explode 1.8.9
|
651 |
-
*
|
652 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
653 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
654 |
-
* http://jquery.org/license
|
655 |
-
*
|
656 |
-
* http://docs.jquery.com/UI/Effects/Explode
|
657 |
-
*
|
658 |
-
* Depends:
|
659 |
-
* jquery.effects.core.js
|
660 |
-
*/
|
661 |
-
(function(j){j.effects.explode=function(a){return this.queue(function(){var c=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3,d=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3;a.options.mode=a.options.mode=="toggle"?j(this).is(":visible")?"hide":"show":a.options.mode;var b=j(this).show().css("visibility","hidden"),g=b.offset();g.top-=parseInt(b.css("marginTop"),10)||0;g.left-=parseInt(b.css("marginLeft"),10)||0;for(var h=b.outerWidth(true),i=b.outerHeight(true),e=0;e<c;e++)for(var f=
|
662 |
-
0;f<d;f++)b.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+
|
663 |
-
e*(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|