Th3-822

[rapidleech][d] GenericXFS_DL.php

Mar 19th, 2015
1,291
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 25.11 KB | None | 0 0
  1. <?php
  2. /*
  3.     /hosts/download/GenericXFS_DL.php
  4.  
  5.      GenericXFS_DL (alpha)
  6.     Written by Th3-822.
  7. */
  8. if (!defined('RAPIDLEECH')) {
  9.     require_once('index.html');
  10.     exit();
  11. }
  12.  
  13. class GenericXFS_DL extends DownloadClass {
  14.     protected $page, $cookie, $baseCookie = array('lang' => 'english'), $scheme, $wwwDomain, $domain, $port, $host, $purl, $httpsOnly = false, $sslLogin = false, $cname = 'xfss', $cookieSave = false, $cJar = array(), $form, $lpass, $fid, $enableDecoders = false, $embedDL = false, $unescaper = false, $customDecoder = false, $reverseForms = true, $cErrsFDL = array(), $DLregexp = '@https?://(?:[\w\-]+\.)+[\w\-]+(?:\:\d+)?/(?:files|dl?|cgi-bin/dl\.cgi|[\da-zA-Z]{30,})/(?:[^\?\'\"\t<>\r\n\\\]{15,}|v(?:id(?:eo)?)?\.(?:flv|mp4))@i';
  15.     private $classVer = 24;
  16.     public $pluginVer, $pA;
  17.  
  18.     public function Download($link) {
  19.         html_error('[GenericXFS_DL] This plugin can\'t be called directly.');
  20.     }
  21.  
  22.     protected function onLoad() {} // Placeholder
  23.  
  24.     protected function onLoad_Post() {} // Placeholder
  25.  
  26.     protected function Start($link, $cErrs = array(), $cErrReplace = true) {
  27.         if ($this->pluginVer > $this->classVer) html_error('GenericXFS_DL class is outdated, please install last version from: https://pastebin.com/e5TZcfQ2 ');
  28.  
  29.         $this->cookie = $this->baseCookie = empty($this->cookie) ? $this->baseCookie : array_merge($this->cookie, $this->baseCookie);
  30.         $link = explode('|', str_ireplace('%7C', '|', $link), 2);
  31.         if (count($link) > 1) $this->lpass = rawurldecode($link[1]);
  32.         if (!preg_match('@https?://(?:[\w\-]+\.)+[\w\-]+(?:\:\d+)?/(\w{12})(?=(?:[/\.]|(?:\.html?))?)@i', str_ireplace('/embed-', '/', $link[0]), $url)) html_error('Invalid link?.');
  33.         $this->fid = $url[1];
  34.         $url = parse_url($url[0]);
  35.         $url['scheme'] =  ($this->httpsOnly ? 'https' : strtolower($url['scheme']));
  36.         $url['host'] = strtolower($url['host']);
  37.  
  38.         if ($this->wwwDomain && strpos($url['host'], 'www.') !== 0) $url['host'] = 'www.' . $url['host'];
  39.         elseif (!$this->wwwDomain && strpos($url['host'], 'www.') === 0) $url['host'] = substr($url['host'], 4);
  40.  
  41.         $this->scheme = $url['scheme'];
  42.         $this->domain = $url['host'];
  43.         $this->port = (!empty($url['port']) && $url['port'] > 0 && $url['port'] < 65536) ? $url['port'] : 0;
  44.         $this->host = $this->domain . (!empty($this->port) ? ':'.$this->port : '');
  45.         $this->purl = $this->scheme.'://'.$this->host.'/';
  46.         $this->link = $GLOBALS['Referer'] = rebuild_url($url);
  47.         unset($url, $link);
  48.  
  49.         $this->enableDecoders = $this->embedDL || $this->unescaper || $this->customDecoder;
  50.  
  51.         $this->onLoad();
  52.  
  53.         if (empty($_POST['step']) || empty($_POST['captcha_type'])) {
  54.             $this->page = $this->GetPage($this->link, $this->cookie);
  55.             if ($this->scheme != 'https') is_present($this->page, "\nLocation: https://", '[GenericXFS_DL] Please Set "$this->httpsOnly" to true or add https:// to your link.');
  56.             if (!empty($cErrs) && is_array($cErrs)) {
  57.                 foreach ($cErrs as $cErr) {
  58.                     if (is_array($cErr)) is_present($this->page, $cErr[0], $cErr[1]);
  59.                     else is_present($this->page, $cErr);
  60.                 }
  61.                 if ($cErrReplace) {
  62.                     $this->onLoad_Post();
  63.                     return $this->Login();
  64.                 }
  65.             }
  66.             is_present($this->page, 'The file you were looking for could not be found');
  67.             is_present($this->page, 'The file was removed by administrator');
  68.             is_present($this->page, 'The file was deleted by its owner');
  69.             is_present($this->page, 'The file was deleted by administration');
  70.             is_present($this->page, 'No such file with this filename', 'Error: Invalid filename, check your link and try again.'); // With the regexp i removed the filename part of the link, this error shouldn't be showed
  71.         }
  72.  
  73.         $this->onLoad_Post();
  74.         return $this->Login();
  75.     }
  76.  
  77.     protected function FindPost($formOp = 'download[1-3]') {
  78.         //if (!preg_match_all('@<form(?:[\s\t][^\>]*)?\>(?:[^<]+(?!\<form)<[^<]+)*</form>@i', $this->page, $forms)) return false;
  79.         if (!preg_match_all('@(?><form(?:\s[^\>]*)?\>)(?>.*?</form>)@is', $this->page, $forms)) return false;
  80.         $forms = ($this->reverseForms ? array_reverse($forms[0]) : $forms[0]); // In some hosts the freedl form is before the "premium" form so $this->reverseForms must be on false on those hosts.
  81.         $found = false;
  82.         foreach ($forms as $form) {
  83.             if (preg_match('@<input\s*[^>]*\sname="op"[^>]*\svalue="' . $formOp . '"@i', $form)) {
  84.                 $found = true;
  85.                 break;
  86.             }
  87.         }
  88.         if (!$found) return false;
  89.  
  90.         // Remove html commented inputs.
  91.         while ($comment = cut_str($form, '<!--', '-->')) $form = str_replace('<!--'.$comment.'-->', '', $form);
  92.  
  93.         $this->form = $form;
  94.         unset($forms, $form, $ret);
  95.  
  96.         preg_match_all('@<input\s*[^>]*\stype="hidden"[^>]*\sname="(\w+)"[^>]*\svalue="([^"]*)"@i', $this->form, $inputs);
  97.         $data = array_map('html_entity_decode', array_combine($inputs[1], $inputs[2]));
  98.  
  99.         if (($pos = stripos($this->form, '<textarea')) !== false && preg_match_all('@<textarea\s+(?:[^>]*\s)?name="(\w+)"[^>]*>([^<]*)</textarea>@i', substr($this->form, $pos), $inputs)) $data = array_merge($data, array_map('html_entity_decode', array_combine($inputs[1], $inputs[2])));
  100.  
  101.         if ((stripos($this->form, 'type="submit"') !== false || stripos($this->form, 'type="image"') !== false || stripos($this->form, 'type="button"') !== false || stripos($this->form, '</button>') !== false) && preg_match_all('@<(?:input\s*[^>]*\stype="(?:submit|image|button)"|button)[^>]*\sname="(\w+)"[^>]*\svalue="([^"]*)"@i', $this->form, $inputs)) {
  102.             $data = array_merge($data, array_map('html_entity_decode', array_combine($inputs[1], $inputs[2])));
  103.             if (!empty($data['method_free']) && !empty($data['method_premium'])) $data['method_premium'] = '';
  104.         }
  105.  
  106.         $this->post = $data;
  107.         return true;
  108.     }
  109.  
  110.     // Custom page decoder placeholder
  111.     protected function pageDecoder() {
  112.         html_error('[GenericXFS_DL] $this->customDecoder is enabled but there is no pageDecoder() function.');
  113.     }
  114.  
  115.     protected function runDecoders() {
  116.         // Packed embedded video decoder
  117.         if (!empty($this->embedDL) && preg_match_all('@eval\s*\(\s*function\s*\(p,a,c,k,e,d\)\s*\{.+\}\s*\(\s*\'([^\r|\n]*)\'\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*\'([^\']+)\'\.split\([\'|\"](.)[\'|\"]\)(?:\s*,\s*\d\s*,\s*\{\})?\)\)@', $this->page, $js)) {
  118.             $cnt = count($js[0]);
  119.             for ($i = 0; $i < $cnt; $i++) {
  120.                 $this->page = str_replace($js[0][$i], $this->XFSUnpacker($js[1][$i], $js[2][$i], $js[3][$i], $js[4][$i], $js[5][$i]), $this->page);
  121.             }
  122.         }
  123.         // JS unescape decoder
  124.         if (!empty($this->unescaper) && preg_match_all('@eval\s*\(unescape\s*\(\s*(\"|\')([%\da-fA-F]+)\1\s*\)\s*\)\s*;?@', $this->page, $js)) {
  125.             $cnt = count($js[0]);
  126.             for ($i = 0; $i < $cnt; $i++) {
  127.                 $this->page = str_replace($js[0][$i], urldecode($js[2][$i]), $this->page);
  128.             }
  129.         }
  130.         // Custom decoder function
  131.         if (!empty($this->customDecoder)) $this->pageDecoder();
  132.     }
  133.  
  134.     // (Placeholder) Returns video title if available to use on stream video downloads.
  135.     protected function getVideoTitle() {
  136.         return false;
  137.     }
  138.  
  139.     protected function getFileName($url) {
  140.         $fname = basename(parse_url($url, PHP_URL_PATH));
  141.         if (preg_match("@^(?:v(?:id(?:eo)?)?|{$this->fid})?\.(mp4|flv)$@i", $fname, $vExt)) { // Possible video/stream
  142.             // Try to get original filename or title for renaming the file.
  143.             if (!empty($this->post['fname'])) $newname = $this->post['fname'];
  144.             else if (($title = $this->getVideoTitle())) $newname = $title;
  145.             else $newname = false;
  146.  
  147.             // I always like to add a letter to mark it as a reconverted video stream and remove the original video .ext
  148.             if (!empty($newname)) $fname = preg_replace('@(?:\.(?:mp4|flv|mkv|webm|wmv|(m2)?ts|rm(vb)?|mpe?g?|vob|avi|[23]gp))+$@i', '', basename($newname)) . '_S.' . strtolower($vExt[1]);
  149.         }
  150.         return $fname;
  151.     }
  152.  
  153.     protected function testDL() {
  154.         if (!empty($this->enableDecoders)) $this->runDecoders();
  155.  
  156.         if (preg_match($this->DLregexp, $this->page, $DL)) {
  157.             $this->RedirectDownload($DL[0], basename($this->getFileName($DL[0])));
  158.             return true;
  159.         }
  160.         return false;
  161.     }
  162.  
  163.     protected function XFSUnpacker($p,$a,$c,$k,$ed) {
  164.         $k = explode($ed, $k);
  165.         while ($c--) if ($k[$c]) $p = preg_replace('@\b'.base_convert($c, 10, $a).'\b@', $k[$c], $p);
  166.         return $p;
  167.     }
  168.  
  169.     protected function findCaptcha() {
  170.         if (!empty($this->captcha)) return false;
  171.         if (($pos = stripos($this->page, $this->scheme . '://' . $this->host . '/captchas/')) !== false && preg_match('@(https?://(?:[\w\-]+\.)+[\w\-]+(?:\:\d+)?)?/captchas/[\w\-]+\.(?:jpe?g|png|gif)@i', substr($this->page, $pos), $gdCaptcha)) {
  172.             // gd Captcha
  173.             if (empty($gdCaptcha[1])) $gdCaptcha[0] = $this->scheme . '://' . $this->host . $gdCaptcha[0];
  174.             $this->captcha = array('type' => 1, 'url' => $gdCaptcha[0]);
  175.         } elseif (substr_count($this->form, "<span style='position:absolute;padding-left:") > 3 && preg_match_all("@<span style='[^\'>]*padding-left\s*:\s*(\d+)[^\'>]*'[^>]*>((?:&#\w+;)|(?:\d))</span>@i", $this->form, $txtCaptcha)) {
  176.             // Text Captcha (decodeable)
  177.             $txtCaptcha = array_combine($txtCaptcha[1], $txtCaptcha[2]);
  178.             ksort($txtCaptcha, SORT_NUMERIC);
  179.             $txtCaptcha = trim(html_entity_decode(implode($txtCaptcha), ENT_QUOTES, 'UTF-8'));
  180.             $this->captcha = array('type' => 2, 'key' => $txtCaptcha);
  181.         } elseif ((stripos($this->page, 'google.com/recaptcha/api/') !== false || stripos($this->page, 'recaptcha.net/') !== false) && preg_match('@(?:https?:)?//(?:[\w\-]+\.)?(?:google\.com/recaptcha/api|recaptcha\.net)/(?:challenge|noscript)\?k=([\w\.\-]+)@i', $this->page, $reCaptcha)) {
  182.             // Old reCAPTCHA
  183.             $this->captcha = array('type' => 3, 'key' => $reCaptcha[1]);
  184.         } elseif (preg_match('@(?:https?:)?//api(?:-secure)?\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=([\w\.\-]+)@i', $this->page, $smCaptcha)) {
  185.             // SolveMedia Captcha
  186.             $this->captcha = array('type' => 4, 'key' => $smCaptcha[1]);
  187.         } elseif (preg_match('@(?:class|id)=["\']g-recaptcha["\']\s+data-sitekey=["\']([\w\.\-]+)["\']@i', $this->page, $reCaptcha2)) {
  188.             // reCAPTCHA2
  189.             $this->captcha = array('type' => 5, 'key' => $reCaptcha2[1]);
  190.         }
  191.         return (!empty($this->captcha));
  192.     }
  193.  
  194.     protected function showCaptcha($step) {
  195.         if (!empty($this->captcha)) {
  196.             if (!empty($this->cookie[$this->cname])) {
  197.                 $data = $this->DefaultParamArr($this->link, $this->cookie, 1, 1);
  198.                 $data['cookie_encrypted'] = 1;
  199.             } else {
  200.                 $data = $this->DefaultParamArr($this->link);
  201.             }
  202.             if (!empty($this->post)) foreach ($this->post as $k => $v) $data["T8gXFS[$k]"] = $v;
  203.             $data['step'] = $step;
  204.             $data['captcha_type'] = $this->captcha['type'];
  205.             switch ($this->captcha['type']) {
  206.                 default: return html_error('Unknown captcha type.');
  207.                 case 1:
  208.                     list($headers, $imgBody) = explode("\r\n\r\n", $this->GetPage($this->captcha['url']), 2);
  209.                     if (substr($headers, 9, 3) != '200') html_error('[1] Error downloading CAPTCHA img.');
  210.                     $mimetype = (preg_match('@image/[\w+]+@', $headers, $mimetype) ? $mimetype[0] : 'image/jpg');
  211.                     return $this->EnterCaptcha("data:$mimetype;base64,".base64_encode($imgBody), $data);
  212.                 case 2:
  213.                     $this->post['code'] = $this->captcha['key'];
  214.                     // postCaptcha won't be needed on this case.
  215.                     return true;
  216.                 case 3: return $this->reCAPTCHA($this->captcha['key'], $data);
  217.                 case 4: return $this->SolveMedia($this->captcha['key'], $data);
  218.                 case 5: return $this->reCAPTCHAv2($this->captcha['key'], $data);
  219.             }
  220.         }
  221.         return false;
  222.     }
  223.  
  224.     protected function postCaptcha(&$step) {
  225.         if (empty($_POST['step']) || empty($_POST['captcha_type'])) return false;
  226.         $post = (!empty($_POST['T8gXFS']) && is_array($_POST['T8gXFS']) ? array_map('urlencode', $_POST['T8gXFS']) : array());
  227.         switch ($_POST['captcha_type']) {
  228.             default:
  229.                 return html_error('Invalid captcha type.');
  230.             case '1': // Image (gd) Captcha
  231.                 $this->captcha = array('type' => 1);
  232.                 if (empty($_POST['captcha'])) html_error('[1] You didn\'t enter the image verification code.');
  233.                 $post['code'] = urlencode($_POST['captcha']);
  234.                 break;
  235.             case '3': // Old reCAPTCHA
  236.                 $this->captcha = array('type' => 3);
  237.                 if (empty($_POST['recaptcha_response_field'])) html_error('[3] You didn\'t enter the image verification code.');
  238.                 if (empty($_POST['recaptcha_challenge_field'])) html_error('[3] Empty reCAPTCHA challenge.');
  239.                 $post['recaptcha_challenge_field'] = urlencode($_POST['recaptcha_challenge_field']);
  240.                 $post['recaptcha_response_field'] = urlencode($_POST['recaptcha_response_field']);
  241.                 break;
  242.             case '4': // Solvemedia
  243.                 $this->captcha = array('type' => 4);
  244.                 $post = array_merge($post, $this->verifySolveMedia());
  245.                 break;
  246.             case '5': // reCAPTCHA2
  247.                 $this->captcha = array('type' => 5);
  248.                 $post = array_merge($post, $this->verifyReCaptchav2());
  249.                 break;
  250.         }
  251.         $step = intval($_POST['step']);
  252.         $_POST['step'] = $_POST['captcha_type'] = false;
  253.         $this->page = $this->GetPage($this->link, $this->cookie, $post);
  254.         $this->cookie = GetCookiesArr($this->page, $this->cookie);
  255.         return true;
  256.     }
  257.  
  258.     // Finds FreeDL countdown on $this->page and calls $this->CountDown(X) for it.
  259.     // return true if there is a countdown, false otherwise.
  260.     protected function findCountdown() {
  261.         if (preg_match('@<span[^>]*>(?>.*?<span\s+id=[\'"][\w\-]+[\'"][^>]*>)\s*(\d+)\s*</span>(?>.*?</span>)@sim', $this->page, $count) || preg_match('@<span[^>]*>(?>[\w\s]*?<span\s+class=[\'\"](?:[\w-]+\s+)*seconds(?:\s+\w+)*[\'\"][^>]*>)\s*(\d+)\s*</span>(?>[\w\s]*?</span>)@sim', $this->form, $count)) {
  262.             if ($count[1] > 0) $this->CountDown($count[1] + 2);
  263.             return true;
  264.         }
  265.         return false;
  266.     }
  267.  
  268.     protected function checkCaptcha($step) {
  269.         if (preg_match('@>\s*Wrong captcha\s*<@i', $this->page)) {
  270.             if (empty($this->captcha)) html_error("Error: Unknown captcha. [$step]");
  271.             else if ($this->captcha['type'] == 2) html_error("Error: Error Decoding Captcha. [$step]");
  272.             else html_error("Error: Wrong Captcha Entered. [$step]");
  273.         }
  274.     }
  275.  
  276.     protected function FreeDL($step = 1) {
  277.         if (!$this->postCaptcha($step) && $step == 1 && !empty($this->cookie[$this->cname])) {
  278.             // Member DL: We need to reload the page with the user's cookies.
  279.             $this->page = $this->GetPage($this->link, $this->cookie);
  280.             $this->cookie = GetCookiesArr($this->page, $this->cookie);
  281.         }
  282.         if ((($pos = stripos($this->page, 'You have to wait')) !== false || ($pos = stripos($this->page, 'Please wait ')) !== false) && preg_match('@(?:You have to|Please) wait[\W\S]?(?:(?:\s*|\s*<br\s*/?\s*>\s*)?\d+ \w+,?\s){0,2}\d+ \w+(?:\s*|\s*<br\s*/?\s*>\s*)?(?:un)?till? (?:the )?next download@i', substr($this->page, $pos), $err)) html_error('Error: '.strip_tags($err[0]));
  283.         if (($pos = stripos($this->page, 'You can download files up to ')) !== false && preg_match('@You can download files up to \d+ [KMG]b only.@i', substr($this->page, $pos), $err)) html_error('Error: '.$err[0]);
  284.         if (($pos = stripos($this->page, 'You have reached the download')) !== false && preg_match('@You have reached the download[- ]limit(?: of|:) \d+ [KMGT]b for(?: the)? last \d+ days?@i', substr($this->page, $pos), $err)) html_error('Error: '.$err[0]);
  285.         if ($this->testDL()) return true;
  286.         if (!$this->FindPost()) {
  287.             is_present($this->page, 'Downloads are disabled for your country:', 'Downloads are disabled for your server\'s country.');
  288.             is_present($this->page, 'This server is in maintenance mode. Refresh this page in some minutes.', 'File is not available at this moment, try again later.');
  289.             is_present($this->page, 'This file is available for Premium Users only.');
  290.             is_present($this->page, 'This file reached max downloads limit', 'Error: This file reached max downloads limit.');
  291.             is_present($this->page, 'Error happened when generating Download Link.', 'Error: Download server is not available at this moment, try again later.');
  292.             if (!empty($this->cErrsFDL) && is_array($this->cErrsFDL)) {
  293.                 foreach ($this->cErrsFDL as $cErr) {
  294.                     if (is_array($cErr)) is_present($this->page, $cErr[0], $cErr[1]);
  295.                     else is_present($this->page, $cErr);
  296.                 }
  297.             }
  298.             return html_error('Non aceptable form found.');
  299.         }
  300.         if (preg_match('@>\s*Skipped countdown@i', $this->page)) html_error("Error: Skipped countdown? [$step].");
  301.         $this->checkCaptcha($step);
  302.         switch ($this->post['op']) {
  303.             default: html_error('Unknown form op.');
  304.             case 'download1':
  305.                 $fstep = 1;
  306.                 break;
  307.             case 'download2':
  308.                 $fstep = 2;
  309.                 break;
  310.         }
  311.         if ($step > $fstep) html_error("Loop Detected [$fstep]");
  312.         is_present($this->page, '>Expired session<', "Error: Expired Download Session. [$fstep]");
  313.         $this->findCaptcha();
  314.         $this->findCountdown();
  315.         $this->showCaptcha($fstep);
  316.         $this->page = $this->GetPage($this->link, $this->cookie, array_map('urlencode', $this->post));
  317.         $this->cookie = GetCookiesArr($this->page, $this->cookie);
  318.         return $this->FreeDL($fstep + 1);
  319.     }
  320.  
  321.     protected function PremiumDL() {
  322.         $this->page = $this->GetPage($this->link, $this->cookie);
  323.         if (($pos = stripos($this->page, 'You have reached the download')) !== false && preg_match('@You have reached the download[- ]limit(?: of|:) \d+ [TGMK]b for(?: the)? last \d+ days?@i', substr($this->page, $pos), $err)) html_error('Error: '.$err[0]);
  324.  
  325.         if (!$this->testDL()) {
  326.             if (!$this->FindPost()) {
  327.                 is_present($this->page, 'Downloads are disabled for your country:', 'Downloads are disabled for your server\'s country.');
  328.                 is_present($this->page, 'This server is in maintenance mode. Refresh this page in some minutes.', 'File is not available at this moment, try again later.');
  329.                 is_present($this->page, 'Error happened when generating Download Link.', 'Error: Download server is not available at this moment, try again later.');
  330.                 html_error('[PremiumDL] Non aceptable form found.');
  331.             }
  332.             if (!isset($this->post['method_premium']) || $this->post['method_premium'] === '') $this->post['method_premium'] = 1;
  333.             sleep(1); // This should avoid errors at massive usage.
  334.             $this->page = $this->GetPage($this->link, $this->cookie, array_map('urlencode', $this->post));
  335.             if (($pos = stripos($this->page, 'You have reached the download')) !== false && preg_match('@You have reached the download[- ]limit(?: of|:) \d+ [TGMK]b for(?: the)? last \d+ days?@i', substr($this->page, $pos), $err)) html_error('Error: '.$err[0]);
  336.             if (!$this->testDL()) html_error('Error: Download-link not found.');
  337.         } else return true;
  338.     }
  339.  
  340.     // Allow Custom Login Post.
  341.     protected function sendLogin($post) {
  342.         $page = $this->GetPage((!empty($this->sslLogin) ? 'https://'.$this->host.'/' : $this->purl) . '?op=login', $this->cookie, $post, $this->purl);
  343.         return $page;
  344.     }
  345.  
  346.     protected function Login() {
  347.         $this->pA = (empty($_REQUEST['premium_user']) || empty($_REQUEST['premium_pass']) ? false : true);
  348.         $pkey = str_ireplace(array('www.', '.'), array('', '_'), $this->domain);
  349.         if (empty($_POST['cookie']) && ($_REQUEST['premium_acc'] != 'on' || (!$this->pA && (empty($GLOBALS['premium_acc'][$pkey]['user']) || empty($GLOBALS['premium_acc'][$pkey]['pass'])) && empty($GLOBALS['premium_acc'][$pkey]['cookie'])))) return $this->FreeDL();
  350.  
  351.         if (!empty($_POST['cookie']) || !empty($GLOBALS['premium_acc'][$pkey]['cookie'])) {
  352.             if (!empty($_POST['cookie'])) {
  353.                 if (!empty($_POST['cookie_encrypted'])) {
  354.                     $_POST['cookie'] = decrypt(urldecode($_POST['cookie']));
  355.                     unset($_POST['cookie_encrypted']);
  356.                 }
  357.                 $this->cookie = StrToCookies($_POST['cookie']);
  358.                 $_POST['cookie'] = false;
  359.             } else {
  360.                 $cookie = $GLOBALS['premium_acc'][$pkey]['cookie'];
  361.                 $this->cookie = (is_array($cookie) ? $cookie : StrToCookies($cookie));
  362.             }
  363.         } else {
  364.             $user = ($this->pA ? $_REQUEST['premium_user'] : $GLOBALS['premium_acc'][$pkey]['user']);
  365.             $pass = ($this->pA ? $_REQUEST['premium_pass'] : $GLOBALS['premium_acc'][$pkey]['pass']);
  366.             if ($this->pA && !empty($_POST['pA_encrypted'])) {
  367.                 $user = decrypt(urldecode($user));
  368.                 $pass = decrypt(urldecode($pass));
  369.                 unset($_POST['pA_encrypted']);
  370.             }
  371.  
  372.             if (empty($user) || empty($pass)) html_error('Login Failed: User or Password is empty. Please check login data.');
  373.            
  374.             if ($this->cookieSave && ($page = $this->cJar_load($user, $pass))) {
  375.                 if ($page === true) $page = $this->GetPage($this->purl.'?op=my_account', $this->cookie, 0, $this->purl);
  376.                 return $this->checkAccount($page);
  377.             } else {
  378.                 $post = array();
  379.                 $post['op'] = 'login';
  380.                 $post['redirect'] = '';
  381.                 $post['login'] = urlencode($user);
  382.                 $post['password'] = urlencode($pass);
  383.  
  384.                 $page = $this->sendLogin($post);
  385.                 if (empty($this->sslLogin) && $this->scheme != 'https') is_present($page, "\nLocation: https://", '[GenericXFS_DL] Please Set "$this->sslLogin" to true.');
  386.  
  387.                 if (!$this->checkLogin($page)) html_error('Login Error: checkLogin() returned false.');
  388.                 $this->cookie = GetCookiesArr($page);
  389.             }
  390.         }
  391.  
  392.         if (empty($this->cookie[$this->cname])) html_error('Login Error: Cannot find session cookie.');
  393.         $this->cookie = array_merge($this->cookie, $this->baseCookie);
  394.  
  395.         $page = $this->isLoggedIn();
  396.         if (!$page) html_error('Login Error: isLoggedIn() returned false.');
  397.  
  398.         if ($this->cookieSave && !empty($this->cJar)) $this->cJar_save();
  399.  
  400.         if ($page === true) $page = $this->GetPage($this->purl.'?op=my_account', $this->cookie, 0, $this->purl);
  401.         return $this->checkAccount($page);
  402.     }
  403.  
  404.     private function cJar_encrypt($data, $key) {
  405.         if (empty($data)) return false;
  406.         global $secretkey;
  407.         $_secretkey = $secretkey;
  408.         $secretkey = $key;
  409.         $data = base64_encode(encrypt(json_encode($data)));
  410.         $secretkey = $_secretkey;
  411.         return $data;
  412.     }
  413.  
  414.     private function cJar_decrypt($data, $key) {
  415.         if (empty($data)) return false;
  416.         global $secretkey;
  417.         $_secretkey = $secretkey;
  418.         $secretkey = $key;
  419.         $data = json_decode(decrypt(base64_decode($data)), true);
  420.         $secretkey = $_secretkey;
  421.         return (!empty($data) ? $data : false);
  422.     }
  423.  
  424.     private function cJar_load($user, $pass) {
  425.         if (empty($user) || empty($pass)) return html_error('Login Failed: User or Password is empty.');
  426.  
  427.         $user = strtolower($user);
  428.         $this->cJar['file'] = DOWNLOAD_DIR . get_class($this) . '_dl.php';
  429.         $this->cJar['hash'] = base64_encode(sha1("$user$pass", true));
  430.         $this->cJar['key'] = substr(base64_encode(hash('sha512', "$user$pass", true)), 0, 56);
  431.  
  432.         if (file_exists($this->cJar['file']) && ($cFile = file($this->cJar['file'])) && is_array($cFile = unserialize($cFile[1])) && array_key_exists($this->cJar['hash'], $cFile) && ($testCookie = $this->cJar_decrypt($cFile[$this->cJar['hash']]['cookie'], $this->cJar['key']))) {
  433.             return $this->cJar_test($testCookie);
  434.         } else return false;
  435.     }
  436.  
  437.     private function cJar_test($cookie) {
  438.         if (empty($this->cJar) || empty($cookie[$this->cname])) return false;
  439.         $oldCookie = $this->cookie;
  440.         $this->cookie = array_merge($cookie, $this->baseCookie);
  441.  
  442.         if (!($page = $this->isLoggedIn())) {
  443.             $this->cookie = $oldCookie;
  444.             return false;
  445.         }
  446.         $this->cJar_save(); // Update last used time.
  447.         return $page;
  448.     }
  449.  
  450.     private function cJar_save() {
  451.         if (empty($this->cJar)) return;
  452.         $maxTime = 31 * 86400; // Max time to keep unused cookies saved (31 days)
  453.         if (file_exists($this->cJar['file']) && ($savedcookies = file($this->cJar['file'])) && is_array($savedcookies = unserialize($savedcookies[1]))) {
  454.             // Remove old cookies
  455.             foreach ($savedcookies as $k => $v) if (time() - $v['time'] >= $maxTime) unset($savedcookies[$k]);
  456.         } else $savedcookies = array();
  457.         $savedcookies[$this->cJar['hash']] = array('time' => time(), 'cookie' => $this->cJar_encrypt($this->cookie, $this->cJar['key']));
  458.  
  459.         file_put_contents($this->cJar['file'], "<?php exit(); ?>\r\n" . serialize($savedcookies), LOCK_EX);
  460.     }
  461.  
  462.     // Checks For Login Errors on $page and Calls html_error() For Them.
  463.     // return true if there are no login errors, false otherwise.
  464.     protected function checkLogin($page) {
  465.         is_present($page, 'op=resend_activation', 'Login failed: Your account isn\'t confirmed yet.');
  466.         is_present($page, 'Your account was banned by administrator.', 'Login failed: Account is Banned.');
  467.         is_present($page, 'Your IP is banned', 'Login Error: IP banned temporally for too many wrong logins.');
  468.         if (preg_match('@Incorrect (Username|Login) or Password@i', $page)) html_error('Login failed: User/Password incorrect.');
  469.         return true;
  470.     }
  471.  
  472.     // Checks if account is logged in.
  473.     // return $page - If it's logged in and the $page loaded is usable for checkAccount() too, if not, return true or false
  474.     protected function isLoggedIn() {
  475.         $page = $this->GetPage($this->purl.'?op=my_account', $this->cookie, 0, $this->purl);
  476.         if (stripos($page, '/?op=logout') === false && stripos($page, '/logout') === false) return false;
  477.         return $page;
  478.     }
  479.  
  480.     // A simpler function for check if account is premium in $page contents, easier to override on plugins for specific hosts.
  481.     // return true if user is premium, false otherwise.
  482.     protected function isAccPremium($page) {
  483.         if (stripos($page, 'Premium account expire') !== false || stripos($page, 'Premium-account expire') !== false || stripos($page, 'Premium Expires') !== false || stripos($page, 'Expiration date') !== false) return true;
  484.         return false;
  485.     }
  486.  
  487.     protected function checkAccount($page) {
  488.         is_present($page, 'Your account was banned by administrator.', '[checkAccount] Account is Banned.');
  489.         if ($this->isAccPremium($page)) return $this->PremiumDL();
  490.  
  491.         // FreeDL() shouldn't have issues using it with a premium account... But PremiumDL() uses less checks.
  492.         $this->changeMesg('<br /><b>Account isn\'t premium?</b>', true);
  493.         return $this->FreeDL();
  494.     }
  495.  
  496. }
  497.  
  498. // GenericXFS_DL (alpha)
  499. // Written by Th3-822.
Add Comment
Please, Sign In to add comment