XCloner – Backup and Restore - Version 3.0.5

Version Description

Download this release

Release Info

Developer xcloner
Plugin Icon 128x128 XCloner – Backup and Restore
Version 3.0.5
Comparing to
See all releases

Code changes from version 3.0.8 to 3.0.5

Files changed (56) hide show
  1. admin.cloner.html.php +1083 -1586
  2. admin.cloner.php +198 -222
  3. admin.xcloner-backupandrestore.php +0 -5
  4. classes/error.class.php → administrator/backups/.excl +0 -0
  5. browser/files_inpage.php +3 -10
  6. browser/files_xml.php +14 -21
  7. browser/xmlhttp.js +5 -5
  8. classes/S3.php +1 -4
  9. classes/fileRecursion.php +8 -57
  10. classes/index.html +0 -0
  11. classes/main.class.php +0 -116
  12. classes/mysqlBackup.class.php +0 -488
  13. classes/phpseclib/Crypt/AES.php +0 -594
  14. classes/phpseclib/Crypt/DES.php +0 -1245
  15. classes/phpseclib/Crypt/Hash.php +0 -824
  16. classes/phpseclib/Crypt/RC4.php +0 -505
  17. classes/phpseclib/Crypt/RSA.php +0 -2356
  18. classes/phpseclib/Crypt/Random.php +0 -133
  19. classes/phpseclib/Crypt/Rijndael.php +0 -1424
  20. classes/phpseclib/Crypt/TripleDES.php +0 -1009
  21. classes/phpseclib/Math/BigInteger.php +0 -3551
  22. classes/phpseclib/Net/SFTP.php +0 -1609
  23. classes/phpseclib/Net/SSH1.php +0 -1408
  24. classes/phpseclib/Net/SSH2.php +0 -2660
  25. classes/phpseclib/PHP/Compat/Function/array_fill.php +0 -41
  26. classes/phpseclib/PHP/Compat/Function/bcpowmod.php +0 -66
  27. classes/phpseclib/PHP/Compat/Function/str_split.php +0 -59
  28. cloner.config.php +0 -3
  29. cloner.cron.php +88 -135
  30. cloner.functions.php +154 -325
  31. common.php +17 -45
  32. css/{start/jquery-ui-1.8.9.custom.css → jquery-ui.css} +316 -319
  33. css/main.css +6 -90
  34. css/start/images/ui-bg_flat_55_999999_40x100.png +0 -0
  35. css/start/images/ui-bg_flat_75_aaaaaa_40x100.png +0 -0
  36. css/start/images/ui-bg_glass_45_0078ae_1x400.png +0 -0
  37. css/start/images/ui-bg_glass_55_f8da4e_1x400.png +0 -0
  38. css/start/images/ui-bg_glass_75_79c9ec_1x400.png +0 -0
  39. css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png +0 -0
  40. css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png +0 -0
  41. css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png +0 -0
  42. css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  43. css/start/images/ui-icons_0078ae_256x240.png +0 -0
  44. css/start/images/ui-icons_056b93_256x240.png +0 -0
  45. css/start/images/ui-icons_d8e7f3_256x240.png +0 -0
  46. css/start/images/ui-icons_e0fdff_256x240.png +0 -0
  47. css/start/images/ui-icons_f5e175_256x240.png +0 -0
  48. css/start/images/ui-icons_f7a50d_256x240.png +0 -0
  49. css/start/images/ui-icons_fcd113_256x240.png +0 -0
  50. css/tabber.css +109 -0
  51. images/logo.gif +0 -0
  52. images/logo.png +0 -0
  53. images/{progressBarLong.gif → progress.gif} +0 -0
  54. install.xcloner.php +12 -4
  55. javascript/backup.js +0 -172
  56. 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 id=\"tabs\">";
35
 
36
  }
37
 
38
  function startTab($name, $class){
39
 
40
- echo "<div id=\"tabs-$class\"><p>";
41
 
42
 
43
  }
44
 
45
  function endTab(){
46
 
47
- echo "</pp></div>";
48
 
49
  }
50
 
@@ -63,16 +63,8 @@ class HTML_cloner {
63
 
64
  function header(){
65
 
66
- global $mosConfig_live_site, $task;
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/start/jquery-ui-1.8.9.custom.css" type="text/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-1.8.9.custom.min.js"></script>
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
- <div class="status" >
111
- <table width='100%' bgcolor='white' class="header">
112
  <tr>
113
- <td width='auto'>
114
- <table><tr><td>
115
- <img src="images/backup.png" align="middle">&nbsp;
116
- </td><td>
117
- <a href="index.php"><h2><?php echo LM_COM_TITLE.$_SERVER['HTTP_HOST']; ?></h2>
118
- <h1>Backup and Restore</h1>
119
- </a>
120
- </td></tr>
121
- </table>
122
- </td>
123
- <td align="right">
124
- <div id="toolbar" style="display:none">
125
- <?php
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>".strip_tags($_REQUEST['mosmsg'])."</h2></center>";
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>. Backup and Restore Made Easy!</p></center>
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 "<h2>Initializing backup...</h2>";
238
- echo "<h3 >Backup <b>$filename</b> created, we may continue!</h3><br />";
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
- //scan file system
339
  $("#result").hide();
340
 
341
  globalUrl = url;
342
- step = "r2";
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) in "+json.tfiles+" files");
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
- //create backup archive
385
  globalUrl = url;
386
- step = "r3";
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(getSize(json.backupSize, 1024*1024));
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 == "r3"){
459
  xclonerGetJSON(globalUrl);
460
  }
461
  });
462
 
463
- $("#result").hide();
464
- $("#fileSystem").hide();
 
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
- <?php
480
-
481
- if($_REQUEST['dbbackup']){
482
- //lets start the incremental procedure
483
- ?>
484
 
485
- <div id="mysqlBackup">
486
- <h2>Database backup...</h2><br />
487
- <div id="mysqlProcess"></div><div id="counter"></div>
 
488
  </div>
489
 
490
- <?php
491
- }
492
- ?>
493
-
494
- <div id="fileSystem">
495
- <h2>Filesystem backup...</h2>
496
-
497
- <div id="recurseFiles">
498
- <br /><strong>Scanning files system...</strong> <span id="recurseStatus"></span>
499
- <br /><div id="overlimit" style="display:none"><b>Excluded oversized files:</b><br /> </div>
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, $html;
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
- $html = new HTML_cloner();
660
- $stat = $html->path_check($_CONFIG[backup_start_path]);
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
- if(!is_dir($_CONFIG[backup_start_path]."/administrator/backups")){
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 = $html->path_check($_CONFIG[backup_store_path]);
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 = $html->path_check($_CONFIG[temp_dir]);
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 Authentication form*/
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>&nbsp;</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
- <input type="hidden" name="task" value="dologin" />
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
- <script>
817
- $(function() {
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
- <?php echo LM_CRON_HELP?>
850
- </div>
851
 
852
- </p></div>
853
- </div>
 
 
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
- <form action="index2.php" method="post" name="adminForm">
996
- <div id="checklist">
997
  <table class="adminlist">
998
  <tr>
999
- <th align="center">
1000
- <input id="toggle" type="checkbox" name="toggle" value="" /><label for="toggle">Check All</label>
 
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
- <!--<td width="5" align="left"><?php echo ($i+1);?></td>-->
1014
- <td align="center" width="100">
1015
- <label for="cb<?php echo $i ?>"><?php echo $i ?></label>
1016
- <input type="checkbox" id="cb<?php echo $i ?>" name="cid[<?php echo $i?>]" value="<?php echo $i ?>" />
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
- </table></div>
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="100">
1090
- <input type="checkbox" id="toggle" name="toggle" value="" /><label for="toggle">Check All</label>
1091
- </th>
1092
- <th align="left" width="100px;">
1093
- <?php echo LM_COL_DOWNLOAD ?>
1094
  </th>
1095
- <th width="50%" class="title">
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
- <label for="cb<?php echo $i ?>"><?php echo $i ?></label>
1115
- <input type="checkbox" id="cb<?php echo $i ?>" name="cid[<?php echo $i?>]" value="<?php echo $i ?>" />
1116
- <input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $files[$i] ?>" />
1117
  </td>
1118
- <td align="left">
1119
- <a target='_blank' href="<?php echo $url ?>"><img src="images/filesave.png" border="0" title="<?php echo LM_DOWNLOAD_TITLE." - ".$files[$i] ?>" /></a>
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
- <?php echo $sizes[$i]; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1128
  </td >
1129
  <td align="left">
1130
- <?php echo $date; ?>
1131
  </td>
1132
  </tr>
1133
  <?php
@@ -1135,7 +854,7 @@ function showBackups( &$files, &$sizes, $path, $option ) {
1135
  }
1136
  ?>
1137
  </table>
1138
- </div>
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->startTab(LM_TAB_GENERAL,"1");
 
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
- <div id="configtabinside">
1451
- <div>
1452
- <h3><a href="#"><?php echo LM_CONFIG_DISPLAY?></a></h3>
1453
- <div><p>
1454
- <table class='adminform'>
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
- </div>
1646
- <?php
1647
- $tabs->endTab();
1648
- $tabs->startTab(LM_TAB_CRON,"5");
1649
- ?>
1650
- <div id="configtabinside">
1651
-
1652
- <div>
1653
- <h3><a href="#"> <?php echo LM_CRON_SETTINGS_M?> - all configs are saved in directory configs/ </a></h3>
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
- <tr>
1843
- <td>
1844
- <?php echo LM_AMAZON_S3_AWSACCESSKEY;?>
1845
- </td>
1846
- <td>
1847
- <input type=text size=50 name='cron_amazon_awsAccessKey' value="<?php echo $_CONFIG['cron_amazon_awsAccessKey'];?>">
1848
- </td>
1849
- </tr>
 
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
- <tr>
1870
- <td>
1871
- <?php echo LM_AMAZON_S3_DIRNAME;?>
1872
- </td>
1873
- <td>
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
- </select><br />
1944
- <?php echo LM_DATABASE_INCLUDE_DATABASES_SUB?>
1945
- </td></tr>
1946
- <?php
1947
- }
1948
- ?>
1949
- </table>
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
- <div id="configtabinside">
2022
- <div>
2023
- <h3><a href="#"><?php echo LM_CONFIG_INFO_PHP?></a></h3>
2024
- <div><p>
2025
-
2026
- <table class='adminform'>
2027
-
2028
- <tr>
2029
- <td width='250'>
2030
- <?php echo LM_CONFIG_INFO_T_VERSION?>
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
- $val = ($out != "")? "ENABLED":"<font color='red'>DISABLED</font>";
2108
- echo HTML_cloner::get_color($val, 'DISABLED');
2109
- ?> </b>
2110
- <br />
2111
- <?php echo LM_CONFIG_INFO_EXEC?>
2112
- </td>
2113
- </tr>
2114
- </table>
2115
- </p></div>
2116
- </div>
2117
- <div>
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
- </table>
2192
- </p></div>
 
 
 
 
 
 
 
 
 
2193
 
2194
- </div></div>
 
 
 
 
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
- <?php
2206
- }
 
 
 
 
 
 
 
2207
 
2208
- function get_color($val, $comp){
 
 
 
 
2209
 
2210
- if(!stristr($val, $comp))
2211
- echo "<span style='color:green'>$val</span>";
2212
- else
2213
- echo "<span style='color:red'>$val</span>";
2214
 
2215
- }
2216
 
2217
- function TransferForm($option, $files){
2218
- global $baDownloadPath, $mosConfig_absolute_path, $clonerPath, $task;
 
 
2219
 
2220
- ?>
2221
- <form action="index2.php" method="GET" name="adminForm">
2222
- <script language="javascript" type="text/javascript">
2223
 
 
2224
 
2225
- function submitbutton(pressbutton) {
2226
- var form = document.adminForm;
2227
- if (pressbutton == 'cancel') {
2228
- submitform( pressbutton );
2229
- return;
2230
- }
2231
 
2232
- submitform( pressbutton );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2233
 
2234
- }
2235
 
2236
- function gotocontact( id ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- <div id="radio_dbbackup">
2353
  <table class="adminform">
2354
- <!--<tr>
2355
  <th colspan=2>
2356
- <b><?php #echo LM_DATABASE_ARCHIVE; ?></b>
2357
  </th>
2358
- </tr>-->
2359
  <tr>
2360
- <td>
2361
- <label for="radio_dbbackup1"><?php echo LM_CONFIRM_DATABASE; ?></label>
2362
- <input id="radio_dbbackup1" type="checkbox" id="dbbackup" name="dbbackup" checked value="1" />
2363
- &nbsp;<label for="radio_dbbackup2">Add DROP SYNTAX</label>
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"; ?> &nbsp;
@@ -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 $_CONFIG['mysql_database'];?></b><br />
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
- if($_CONFIG['mysql_database'] != $row[0])
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=100><br/>
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
- <script>
2562
- $(function() {
2563
- $( "#tabs" ).tabs();
2564
- });
2565
- </script>
2566
-
2567
- <div id="tabs" >
2568
- <ul>
2569
- <li><a href="#tabs-1"><?php echo LM_CREDIT_TOP?></a></li>
2570
- </ul>
2571
- <div id="tabs-1" >
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
- <script>
2593
- $(function() {
2594
- $( "#tabs" ).tabs();
2595
- });
2596
- </script>
2597
-
2598
- <div id="tabs">
2599
- <ul>
2600
- <li><a href="#tabs-1"><?php echo LM_RESTORE_TOP?></a></li>
2601
- </ul>
2602
- <div id="tabs-1"><p class="mainText">
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
- <script>
2625
- $(function() {
2626
- $( "#tabs" ).tabs();
2627
- });
2628
- </script>
2629
-
2630
- <div id="tabs">
2631
- <ul>
2632
- <li><a href="#tabs-1"><?php echo LM_CREDIT_TOP?></a></li>
2633
- </ul>
2634
- <div id="tabs-1"><p class="mainText">
2635
- <table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
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">&nbsp;
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" />&nbsp;<?php echo LM_CONFIRM_DATABASE; ?></td>
1894
+ </tr>
1895
+ <tr>
1896
+ <td><input type="checkbox" id="dbbackup_drop" name="dbbackup_drop" value="1" />&nbsp;<?php echo "Add DROP SYNTAX"; ?></td>
 
 
1897
  </tr>
1898
  <tr>
1899
  <td><?php echo "Mysql Compatibility"; ?> &nbsp;
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
- @mysql_close($link);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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; charset=utf-8");
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 +"&amp;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='450'><tr><td align='right'><b>" + "Excluded items list:" + "</b><br />"+ message+"</td></tr></table>" + stringHTML ;
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 +"&amp;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($data) {
49
 
50
- self::$TEMP_PERM = $data['TEMP_PERM'];
51
- self::$TEMP_EXCL = $data['TEMP_EXCL'];
52
- self::$TEMP_D_ARR = $data['TEMP_D_ARR'];
53
- self::$TEMP_DIR = $data['TEMP_DIR'];
54
- self::$START_DIR = $data['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
- $sizeLimit = (self::$EXCLUDE_FILES_SIZE)*1024*1024; // we limit by MB
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
- //filter the config request path
53
- $_REQUEST['config'] = str_replace(array("..","/","\\"), array("","",""), trim($_REQUEST['config']));
54
 
55
  if($_REQUEST['config'] != ""){
56
 
@@ -97,7 +82,7 @@ else{
97
 
98
 
99
  ####### VERIFY IP ACCESS
100
- /*$ip_list = @explode("\r\n", $_CONFIG['cron_ip']);
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
- ######################################STARTING FTP TRANSFER##################
190
-
191
- $source_files[] = $source_file;
192
- $destination_files[] = $_CONFIG[cron_ftp_path]."/".$file;
193
-
194
- // set up basic connection details
195
- list($fhost, $fport) = explode(":",$_CONFIG[cron_ftp_server]);
196
- if($fport == "")
197
- $fport = '21';
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
- else if($_CONFIG['cron_send']==2)
 
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 - XCloner - Backup and Restore made easy!
308
  </pre>
309
 
310
  ";
@@ -329,14 +288,9 @@ include_once("classes/S3.php");
329
 
330
  logxx();
331
 
332
- if(!$_CONFIG['cron_amazon_ssl'])
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...ssl mode ".(int)$amazon_ssl);
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
- $html = new HTML_cloner();
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\']=\'' . $_REQUEST[license_code] . '\';' . "\n";
146
 
147
  $cfg .= '$_CONFIG[\'backup_path\']="' . $_REQUEST[backup_path] . '";' . "\n";
148
 
149
  $cfg .= '$_CONFIG[\'clonerPath\']="' . $_REQUEST[clonerPath] . '";' . "\n";
150
 
151
- $cfg .= '$_CONFIG[\'jcuser\']=\'' . $_REQUEST[jcuser] . '\';' . "\n";
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\']=\'' . $_REQUEST[mysql_user] . '\';' . "\n";
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\']=\'' . $_REQUEST[cron_ftp_user] . '\';' . "\n";
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\']=\'' . $_REQUEST[cron_amazon_awsAccessKey] . '\';' . "\n";
250
 
251
- $cfg .= '$_CONFIG[\'cron_amazon_awsSecretKey\']=\'' . $_REQUEST[cron_amazon_awsSecretKey] . '\';' . "\n";
252
 
253
- $cfg .= '$_CONFIG[\'cron_amazon_bucket\']=\'' . $_REQUEST[cron_amazon_bucket] . '\';' . "\n";
254
 
255
- $cfg .= '$_CONFIG[\'cron_amazon_dirname\']=\'' . $_REQUEST[cron_amazon_dirname] . '\';' . "\n";
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 ".$fcron." file, please make sure the folder is writeable!";
281
  }
282
  }
283
 
@@ -289,8 +278,7 @@
289
  E_print($msg);
290
  }
291
  }
292
- $html = new HTML_cloner();
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
- $html = new HTML_cloner();
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
- $html = new HTML_cloner();
348
- $html->Translator_Add($option);
349
  }
350
  function translator_edit($option, $task)
351
  {
@@ -427,15 +414,14 @@
427
 
428
 
429
  if ($lang == 'english') {
430
- $html = new HTML_cloner();
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
- $html = new HTML_cloner();
438
- $html->Translator_Edit($option, $data, $def_data, $file, $lang);
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
- $dataInit['TEMP_PERM'] = $_CONFIG['temp_dir']."/perm.txt";
591
- $dataInit['TEMP_EXCL'] = $_CONFIG['exfile'];
592
- $dataInit['TEMP_D_ARR'] = $_CONFIG['temp_dir']."/.dir";
593
- $dataInit['TEMP_DIR'] = $_CONFIG['clonerPath'];
594
- $dataInit['START_DIR'] = $_CONFIG['backup_path'];
595
- $dataInit['EXCLUDE_FILES_SIZE'] = $_CONFIG['excludeFilesSize'];
596
- $dataInit['TEMP_OVERSIZED_FILE'] = $_CONFIG['temp_dir']."/.oversized_files";
597
 
598
- $handle->setData($dataInit);
599
 
600
  if($_REQUEST['mode'] == 'start')
601
- $handle->init($_CONFIG['backup_start_path']);
602
  else
603
  $handle->init();
604
 
@@ -613,15 +505,10 @@
613
 
614
  if(!$handle->isQueueFinished())
615
  $status['finished'] = "0";
616
- else{
617
- //recurse finished, lets return the excluded files by size
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
- $html = new HTML_cloner();
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
- $html = new HTML_cloner();
672
- $html->TransferForm($option, $files_out);
673
- }
674
  }
675
 
676
  function start_connect($files)
@@ -902,14 +786,14 @@
902
  }
903
 
904
 
905
- $html = new HTML_cloner();
906
- $html->rename($files, $option);
907
  }
908
  function downloadBackup($file)
909
  {
910
  global $_CONFIG;
911
 
912
- $file = realpath($_CONFIG['clonerPath'] . "/$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
- smartReadFile($file, $filename);
931
-
932
- exit;
933
- }
934
-
935
- function smartReadFile($location, $filename, $mimeType='application/octet-stream')
936
- { if(!file_exists($location))
937
- { header ("HTTP/1.0 404 Not Found");
938
- return;
939
- }
940
 
941
- $size=filesize($location);
942
- $time=date('r',filemtime($location));
943
 
944
- $fm=@fopen($location,'r');
945
- if(!$fm)
946
- { header ("HTTP/1.0 505 Internal server error");
947
- return;
948
- }
949
-
950
- $begin=0;
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
- $html = new HTML_cloner();
1037
- $html->confirmBackups($d_arr, $ds_arr, $_CONFIG['clonerPath'], $option);
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['backup_store_path']."/".$backup_filename;
1077
 
1078
- $perm_file = $_CONFIG['temp_dir'] . "/perm.txt";
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... or <a href='$url'>click here </a>";
1197
 
1198
  $log .= "
1199
- <script language='javascript'>
1200
- function redirect(){
1201
- window.location = '" . $url . "';
1202
- }
1203
 
1204
- setTimeout(\"redirect()\",parseInt(" . $_CONFIG['refresh_time'] . "));
1205
- //redirect();
1206
 
1207
- </script>";
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
- if(!$json){
1225
- echo $log;
1226
  }
1227
- else{
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
- $backupDatabase = $_REQUEST['dbbackup'];
 
 
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
- #$databaseResult = LM_DATABASE_EXCLUDED;
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
- $perm_file = $_CONFIG['backups_dir'] . "/perm.txt";
1456
- @unlink($perm_file);
1457
- $fperm = fopen($perm_file, "w");
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
- recurseFiles($d_arr, $ds_arr, $f_arr, $s_arr, $d, $f, $s, $includeFolder, '', $excluded, $fperm);
 
 
1467
 
1468
- @fclose($fperm);
 
1469
 
1470
- @chmod($perm_file, 0777);
 
 
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
- if((!$_CONFIG['refresh_mode']) and ($_CONFIG['enable_db_backup']))
1554
- echo "<h2>Database backup: </h2>" . $databaseResult . "<br /><br />";
1555
- $html = new HTML_cloner();
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
- $html = new HTML_cloner();
1649
- $html->goRefreshHtml($filename, $perm_lines, $excl_manual);
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
- $html = new HTML_cloner();
1692
- $html->generateBackup($filename1, $archiveSize, $originalSize, $mdir, $f, $databaseResult, $option);
1693
  } else {
1694
 
1695
- $html = new HTML_cloner();
1696
- logxx($html->generateBackup_text($filename1, $archiveSize, $originalSize, $mdir, $f, $databaseResult, $option));
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
- $html = new HTML_cloner();
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 = mysql_real_escape_string($value);
2065
- #$value = str_replace("\n", '\r\n', $value);
2066
- #$value = str_replace("\r", '', $value);
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
- $tmp = explode(".",$backupFilename);
2100
- $extension = $tmp[sizeof($tmp)-1];
2101
- $inc = $tmp[sizeof($tmp)-2];
2102
-
2103
- if(strlen($inc)<3){
2104
- $newinc = $inc+1;
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
- * common.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
- /** 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'] = str_replace("//administrator","/administrator",($_CONFIG['backup_path'])."/administrator/backups");
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
- $link = @mysql_connect($_CONFIG['mysql_host'], $_CONFIG['mysql_user'], $_CONFIG['mysql_pass']) or
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 (version_compare(PHP_VERSION, '5.2.3') < 0) {
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.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
  *
@@ -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 CSS Framework 1.8.9
46
  *
47
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=2191c0&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=75&borderColorHeader=4297d7&fcHeader=eaf5f7&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=0078ae&bgColorDefault=0078ae&bgTextureDefault=02_glass.png&bgImgOpacityDefault=45&borderColorDefault=77d5f7&fcDefault=ffffff&iconColorDefault=e0fdff&bgColorHover=79c9ec&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=448dae&fcHover=026890&iconColorHover=056b93&bgColorActive=6eac2c&bgTextureActive=12_gloss_wave.png&bgImgOpacityActive=50&borderColorActive=acdd4a&fcActive=ffffff&iconColorActive=f5e175&bgColorHighlight=f8da4e&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcd113&fcHighlight=915608&iconColorHighlight=f7a50d&bgColorError=e14f1c&bgTextureError=12_gloss_wave.png&bgImgOpacityError=45&borderColorError=cd0a0a&fcError=ffffff&iconColorError=fcd113&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=75&opacityOverlay=30&bgColorShadow=999999&bgTextureShadow=01_flat.png&bgImgOpacityShadow=55&opacityShadow=45&thicknessShadow=0px&offsetTopShadow=5px&offsetLeftShadow=5px&cornerRadiusShadow=5px
54
  */
55
 
56
 
57
  /* Component containers
58
  ----------------------------------*/
59
- .ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
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; font-size: 1em; }
62
- .ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; }
63
- .ui-widget-content a { color: #222222; }
64
- .ui-widget-header { border: 1px solid #4297d7; background: #2191c0 url(images/ui-bg_gloss-wave_75_2191c0_500x100.png) 50% 50% repeat-x; color: #eaf5f7; font-weight: bold; }
65
- .ui-widget-header a { color: #eaf5f7; }
66
 
67
  /* Interaction states
68
  ----------------------------------*/
69
- .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #77d5f7; background: #0078ae url(images/ui-bg_glass_45_0078ae_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; }
70
- .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #ffffff; text-decoration: none; }
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 #448dae; background: #79c9ec url(images/ui-bg_glass_75_79c9ec_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #026890; }
72
- .ui-state-hover a, .ui-state-hover a:hover { color: #026890; text-decoration: none; }
73
- .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #acdd4a; background: #6eac2c url(images/ui-bg_gloss-wave_50_6eac2c_500x100.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; }
74
- .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; }
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 #fcd113; background: #f8da4e url(images/ui-bg_glass_55_f8da4e_1x400.png) 50% 50% repeat-x; color: #915608; }
80
- .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #915608; }
81
- .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #e14f1c url(images/ui-bg_gloss-wave_45_e14f1c_500x100.png) 50% top repeat-x; color: #ffffff; }
82
- .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
83
- .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
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-icons_0078ae_256x240.png); }
93
- .ui-widget-content .ui-icon {background-image: url(images/ui-icons_0078ae_256x240.png); }
94
- .ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); }
95
- .ui-state-default .ui-icon { background-image: url(images/ui-icons_e0fdff_256x240.png); }
96
- .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_056b93_256x240.png); }
97
- .ui-state-active .ui-icon {background-image: url(images/ui-icons_f5e175_256x240.png); }
98
- .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_f7a50d_256x240.png); }
99
- .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_fcd113_256x240.png); }
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: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; }
284
- .ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; }
285
- .ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
286
- .ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
287
- .ui-corner-top { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; }
288
- .ui-corner-bottom { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
289
- .ui-corner-right { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
290
- .ui-corner-left { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
291
- .ui-corner-all { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
292
 
293
  /* Overlays */
294
- .ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_75_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
295
- .ui-widget-shadow { margin: 5px 0 0 5px; padding: 0px; background: #999999 url(images/ui-bg_flat_55_999999_40x100.png) 50% 50% repeat-x; opacity: .45;filter:Alpha(Opacity=45); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*
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: 12px;
159
  }
160
  .text_area {
161
  border : 1px solid #ccc;
162
  z-index: -3;
163
- font-size: 12px;
164
  }
165
  input, textarea, select {
166
  z-index : -3;
167
- font-size: 14px;
168
  }
169
  .small {
170
  color : #FF9900;
@@ -190,7 +190,7 @@ table.menubar {
190
 
191
  }
192
  td {
193
- font-size: 12px;
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: 13px;
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||"&#160;",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||"&#160;"));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&#8230;</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?"&#xa0;":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)?"&#xa0;":""));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)?"&#xa0;":"")+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*(