daily pastebin goal
84%
SHARE
TWEET

[rapidleech][d] mega_co_nz.php

Th3-822 Feb 25th, 2013 (edited) 5,070 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. if (!defined('RAPIDLEECH')) {
  3.     require_once('index.html');
  4.     exit;
  5. }
  6. // Using functions from: http://julien-marchand.fr/blog/using-the-mega-api-with-php-examples/
  7. class mega_co_nz extends DownloadClass {
  8.     private $useOpenSSL, $seqno, $cookie;
  9.     public function Download($link) {
  10.         if (!extension_loaded('mcrypt') || !in_array('rijndael-128', mcrypt_list_algorithms(), true)) html_error("Mcrypt module isn't installed or it doesn't have support for the needed encryption.");
  11.         $this->useOpenSSL = (version_compare(PHP_VERSION, '5.4.0', '>=') && extension_loaded('openssl') && in_array('AES-128-CBC', openssl_get_cipher_methods(), true));
  12.  
  13.         $this->seqno = mt_rand();
  14.         $this->changeMesg(lang(300).'<br />Mega.co.nz plugin by Th3-822'); // Please, do not remove or change this line contents. - Th3-822
  15.  
  16.         $fragment = parse_url($link, PHP_URL_FRAGMENT);
  17.         if (preg_match('@^F!([^!]{8})!([\w\-\,]{22})(?:!([^!#]{8}))?(!less$)?@i', $fragment, $fid)) return $this->Folder($fid[1], $fid[2], (!empty($fid[3]) && $fid[3] != $fid[1] ? $fid[3] : 0), (empty($fid[4]) ? 1 : 0));
  18.         if (!preg_match('@^(T8|N)?!([^!]{8})!([\w\-\,]{43})(?:(?:!|=###n=)([^!#]{8})(?:!|$))?@i', $fragment, $fid)) html_error('FileID or Key not found at link.');
  19.  
  20.         $pA = (empty($_REQUEST['premium_user']) || empty($_REQUEST['premium_pass']) ? false : true);
  21.         if (!empty($_REQUEST['premium_acc']) && $_REQUEST['premium_acc'] == 'on' && ($pA || (!empty($GLOBALS['premium_acc']['mega_co_nz']['user']) && !empty($GLOBALS['premium_acc']['mega_co_nz']['pass'])))) {
  22.             $user = ($pA ? $_REQUEST['premium_user'] : $GLOBALS['premium_acc']['mega_co_nz']['user']);
  23.             $pass = ($pA ? $_REQUEST['premium_pass'] : $GLOBALS['premium_acc']['mega_co_nz']['pass']);
  24.             if ($pA && !empty($_POST['pA_encrypted'])) {
  25.                 $user = decrypt(urldecode($user));
  26.                 $pass = decrypt(urldecode($pass));
  27.                 unset($_POST['pA_encrypted']);
  28.             }
  29.         }
  30.  
  31.         do {
  32.             $reply = $this->apiReq(array('a' => 'g', 'g' => 1, (empty($fid[1]) ? 'p' : 'n') => $fid[2], 'ssl' => 0), (!empty($fid[1]) && !empty($fid[4]) ? $fid[4] : ''));
  33.             if (is_numeric($reply[0])) $this->CheckErr($reply[0]);
  34.             if (!empty($reply[0]['e']) && is_numeric($reply[0]['e'])) $this->CheckErr($reply[0]['e']);
  35.             $tLimit = $this->checkTrafficLimit($reply[0]['g']);
  36.         } while (!empty($user) && !empty($pass) && empty($this->cookie['sid']) && $tLimit && $this->cJar_load($user, $pass));
  37.  
  38.         if ($tLimit) {
  39.             if (empty($this->cookie['sid'])) html_error('Anonymous Traffic Limit Reached, add an account then try again.');
  40.             else html_error('Traffic Limit Reached.');
  41.         }
  42.  
  43.         $key = $this->base64_to_a32($fid[3]);
  44.         $key = array($key[0] ^ $key[4], $key[1] ^ $key[5], $key[2] ^ $key[6], $key[3] ^ $key[7]);
  45.         $attr = $this->dec_attr($this->base64url_decode($reply[0]['at']), $key);
  46.         if (empty($attr)) html_error((!empty($fid[1]) ? 'Folder Error: ' : '').'File\'s key isn\'t correct.');
  47.  
  48.         $this->RedirectDownload($reply[0]['g'], $attr['n'], 0, 0, $link, 0, 0, array('T8[fkey]' => $fid[3]));
  49.     }
  50.  
  51.     // It's seems to not work properly with a HEAD request neither with a GET with a small Range (TODO: Add here a small copy of geturl that stops after getting the headers or add a parameter to geturl that does that)
  52.     private function checkTrafficLimit($link) {
  53.         if (extension_loaded('curl') && function_exists('curl_init') && function_exists('curl_exec')) {
  54.             $page = cURL($link, 0, 0, 0, 0, array(CURLOPT_NOBODY => true));
  55.         } else if (function_exists('readCustomHeaders')) {
  56.             $page = $this->GetPage($link, 0, 0, "https://mega.nz/\r\n:HEAD " . parse_url($link, PHP_URL_PATH) . " HTTP/1.1");
  57.         } else html_error('Your rapidleech is outdated and doesn\'t support a required check.');
  58.         return (intval(substr($page, 9, 3)) == 509);
  59.     }
  60.  
  61.     private function CheckErr($code, $prefix = 'Error') {
  62.         $isLogin = (stripos($prefix, 'login') !== false);
  63.         switch ($code) {
  64.             default: $msg = '*No message for this error*';break;
  65.             case -1: $msg = 'An internal error has occurred';break;
  66.             case -2: $msg = 'You have passed invalid arguments to this command, your rapidleech is outdated?';break;
  67.             case -3: $msg = 'A temporary congestion or server malfunction prevented your request from being processed';break;
  68.             case -4: $msg = 'You have exceeded your command weight per time quota. Please wait a few seconds, then try again';break;
  69.             case -9: $msg = ($isLogin ? 'Email/Password incorrect' : 'File/Folder not found');break;
  70.             case -11: $msg = 'Access violation';break;
  71.             case -13: $msg = ($isLogin ? 'Account not Activated yet' : 'Trying to access an incomplete file');break;
  72.             case -14: $msg = 'A decryption operation failed';break;
  73.             case -15: $msg = 'Invalid or expired user session, please relogin';break;
  74.             case -16: $msg = ($isLogin ? 'Account blocked' : 'File/Folder not available, uploader\'s account is banned');break;
  75.             case -17: $msg = 'Request over quota';break;
  76.             case -18: $msg = ($isLogin ? 'Login service' : 'File/Folder') . ' temporarily not available, please try again later';break;
  77.             // Confirmed at page:
  78.             case -6: $msg = 'File not found, account was deleted';break;
  79.         }
  80.         html_error("$prefix: [$code] $msg.");
  81.     }
  82.  
  83.     private function apiReq($atrr, $node = '') {
  84.         $try = 0;
  85.         do {
  86.             if ($try > 0) sleep(2);
  87.             $ret = $this->doApiReq($atrr, $node);
  88.             $try++;
  89.         } while ($try < 6 && $ret[0] == -3);
  90.         return $ret;
  91.     }
  92.  
  93.     private function doApiReq($atrr, $node='') {
  94.         if (!function_exists('json_encode')) html_error('Error: Please enable JSON in php.');
  95.         $page = $this->GetPage('https://g.api.mega.co.nz/cs?id=' . ($this->seqno++) . (!empty($node) ? "&n=$node" : '') . (!empty($this->cookie['sid']) ? "&sid={$this->cookie['sid']}" : ''), 0, json_encode((!empty($atrr[0]) && is_array($atrr[0])) ? $atrr : array($atrr)), "https://mega.nz/\r\nContent-Type: application/json");
  96.         if (in_array(intval(substr($page, 9, 3)), array(500, 503))) return array(-3); //  500 Server Too Busy
  97.         list ($header, $page) = array_map('trim', explode("\r\n\r\n", $page, 2));
  98.         if (is_numeric($page)) return array(intval($page));
  99.         return $this->json2array($page);
  100.     }
  101.  
  102.     private function str_to_a32($b) {
  103.         // Add padding, we need a string with a length multiple of 4
  104.         $b = str_pad($b, 4 * ceil(strlen($b) / 4), "\0");
  105.         return array_values(unpack('N*', $b));
  106.     }
  107.  
  108.     private function a32_to_str($hex) {
  109.         return call_user_func_array('pack', array_merge(array('N*'), $hex));
  110.     }
  111.  
  112.     private function base64url_encode($data) {
  113.         return strtr(rtrim(base64_encode($data), '='), '+/', '-_');
  114.     }
  115.  
  116.     private function a32_to_base64($a) {
  117.         return $this->base64url_encode($this->a32_to_str($a));
  118.     }
  119.  
  120.     private function base64url_decode($data) {
  121.         if (($s = (2 - strlen($data) * 3) % 4) < 2) $data .= substr(',,', $s);
  122.         return base64_decode(strtr($data, '-_,', '+/='));
  123.     }
  124.  
  125.     private function base64_to_a32($s) {
  126.         return $this->str_to_a32($this->base64url_decode($s));
  127.     }
  128.  
  129.     private function aes_cbc_encrypt($data, $key) {
  130.         if ($this->useOpenSSL) {
  131.             $data = str_pad($data, 16 * ceil(strlen($data) / 16), "\0"); // OpenSSL needs this padded.
  132.             return openssl_encrypt($data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
  133.         } else return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
  134.     }
  135.  
  136.     private function aes_cbc_decrypt($data, $key) {
  137.         if ($this->useOpenSSL) {
  138.             $data = str_pad($data, 16 * ceil(strlen($data) / 16), "\0"); // OpenSSL needs this padded.
  139.             return openssl_decrypt($data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
  140.         } else return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
  141.     }
  142.  
  143.     private function aes_cbc_encrypt_a32($data, $key) {
  144.         return $this->str_to_a32($this->aes_cbc_encrypt($this->a32_to_str($data), $this->a32_to_str($key)));
  145.     }
  146.  
  147.     private function aes_cbc_decrypt_a32($data, $key) {
  148.         return $this->str_to_a32($this->aes_cbc_decrypt($this->a32_to_str($data), $this->a32_to_str($key)));
  149.     }
  150.  
  151.     private function stringhash($s, $aeskey) {
  152.         $s32 = $this->str_to_a32($s);
  153.         $h32 = array(0, 0, 0, 0);
  154.         for ($i = 0; $i < count($s32); $i++) $h32[$i % 4] ^= $s32[$i];
  155.         for ($i = 0; $i < 0x4000; $i++) $h32 = $this->aes_cbc_encrypt_a32($h32, $aeskey);
  156.         return $this->a32_to_base64(array($h32[0], $h32[2]));
  157.     }
  158.  
  159.     private function prepare_key($a) {
  160.         $pkey = array(0x93C467E3, 0x7DB0C7A4, 0xD1BE3F81, 0x0152CB56);
  161.         $count_a = count($a);
  162.         for ($r = 0; $r < 0x10000; $r++) {
  163.             for ($j = 0; $j < $count_a; $j += 4) {
  164.                 $key = array(0, 0, 0, 0);
  165.                 for ($i = 0; $i < 4; $i++) if ($i + $j < $count_a) $key[$i] = $a[$i + $j];
  166.                 $pkey = $this->aes_cbc_encrypt_a32($pkey, $key);
  167.             }
  168.         }
  169.         return $pkey;
  170.     }
  171.  
  172.     private function decrypt_key($a, $key) {
  173.         $x = array();
  174.         for ($i = 0; $i < count($a); $i += 4) $x = array_merge($x, $this->aes_cbc_decrypt_a32(array_slice($a, $i, 4), $key));
  175.         return $x;
  176.     }
  177.  
  178.     private function mpi2bc($s) {
  179.         $s = bin2hex(substr($s, 2));
  180.         $len = strlen($s);
  181.         $n = 0;
  182.         for ($i = 0; $i < $len; $i++) $n = bcadd($n, bcmul(hexdec($s[$i]), bcpow(16, $len - $i - 1)));
  183.         return $n;
  184.     }
  185.  
  186.     private function bin2int($str) {
  187.         $result = 0;
  188.         $n = strlen($str);
  189.         do {
  190.             $result = bcadd(bcmul($result, 256), ord($str[--$n]));
  191.         } while ($n > 0);
  192.         return $result;
  193.     }
  194.  
  195.     private function int2bin($num) {
  196.         $result = '';
  197.         do {
  198.             $result .= chr(bcmod($num, 256));
  199.             $num = bcdiv($num, 256);
  200.         } while (bccomp($num, 0));
  201.         return $result;
  202.     }
  203.  
  204.     private function bitOr($num1, $num2, $start_pos) {
  205.         $start_byte = intval($start_pos / 8);
  206.         $start_bit = $start_pos % 8;
  207.         $tmp1 = $this->int2bin($num1);
  208.         $num2 = bcmul($num2, 1 << $start_bit);
  209.         $tmp2 = $this->int2bin($num2);
  210.         if ($start_byte < strlen($tmp1)) {
  211.             $tmp2 |= substr($tmp1, $start_byte);
  212.             $tmp1 = substr($tmp1, 0, $start_byte) . $tmp2;
  213.         } else $tmp1 = str_pad($tmp1, $start_byte, "\0") . $tmp2;
  214.         return $this->bin2int($tmp1);
  215.     }
  216.  
  217.     private function bitLen($num) {
  218.         $tmp = $this->int2bin($num);
  219.         $bit_len = strlen($tmp) * 8;
  220.         $tmp = ord($tmp[strlen($tmp) - 1]);
  221.         if (!$tmp) $bit_len -= 8;
  222.         else while (!($tmp & 0x80)) {
  223.             $bit_len--;
  224.             $tmp <<= 1;
  225.         }
  226.         return $bit_len;
  227.     }
  228.  
  229.     private function rsa_decrypt($enc_data, $p, $q, $d) {
  230.         $enc_data = $this->int2bin($enc_data);
  231.         $exp = $d;
  232.         $modulus = bcmul($p, $q);
  233.         $data_len = strlen($enc_data);
  234.         $chunk_len = $this->bitLen($modulus) - 1;
  235.         $block_len = intval(ceil($chunk_len / 8));
  236.         $curr_pos = 0;
  237.         $bit_pos = 0;
  238.         $plain_data = 0;
  239.         while ($curr_pos < $data_len) {
  240.             $tmp = $this->bin2int(substr($enc_data, $curr_pos, $block_len));
  241.             $tmp = bcpowmod($tmp, $exp, $modulus);
  242.             $plain_data = $this->bitOr($plain_data, $tmp, $bit_pos);
  243.             $bit_pos += $chunk_len;
  244.             $curr_pos += $block_len;
  245.         }
  246.         return $this->int2bin($plain_data);
  247.     }
  248.  
  249.     private function dec_attr($attr, $key) {
  250.         $attr = trim($this->aes_cbc_decrypt($attr, $this->a32_to_str($key)));
  251.         if (substr($attr, 0, 6) != 'MEGA{"') return false;
  252.         $attr = substr($attr, 4);$attr = substr($attr, 0, strrpos($attr, '}') + 1);
  253.         return $this->json2array($attr);
  254.     }
  255.  
  256.     public function CheckBack($header) {
  257.         if (($statuscode = intval(substr($header, 9, 3))) != 200) {
  258.             switch ($statuscode) {
  259.                 case 509: html_error('[Mega_co_nz] Transfer quota exceeded.');
  260.                 case 503: html_error('[Mega_co_nz] Too many connections for this download.');
  261.                 case 403: html_error('[Mega_co_nz] Link used/expired.');
  262.                 case 404: html_error('[Mega_co_nz] Link expired.');
  263.                 default : html_error('[Mega_co_nz][HTTP] '.trim(substr($header, 9, strpos($header, "\n") - 8)));
  264.             }
  265.         }
  266.  
  267.         global $fp, $sFilters;
  268.         if (empty($fp) || !is_resource($fp)) html_error("Error: Your rapidleech version is outdated and it doesn't support this plugin.");
  269.         if (!empty($_GET['T8']['fkey'])) $key = $this->base64_to_a32(urldecode($_GET['T8']['fkey']));
  270.         elseif (preg_match('@^(T8|N)?!([^!]{8})!([\w\-\,]{43})@i', parse_url($_GET['referer'], PHP_URL_FRAGMENT), $dat)) $key = $this->base64_to_a32($dat[2]);
  271.         else html_error("[CB] File's key not found.");
  272.         $iv = array_merge(array_slice($key, 4, 2), array(0, 0));
  273.         $key = array($key[0] ^ $key[4], $key[1] ^ $key[5], $key[2] ^ $key[6], $key[3] ^ $key[7]);
  274.         $opts = array('iv' => $this->a32_to_str($iv), 'key' => $this->a32_to_str($key));
  275.  
  276.         if (!stream_filter_register('MegaDlDecrypt', 'Th3822_MegaDlDecrypt') && !in_array('MegaDlDecrypt', stream_get_filters())) html_error('Error: Cannot register "MegaDlDecrypt" filter.');
  277.  
  278.         if (!isset($sFilters) || !is_array($sFilters)) $sFilters = array();
  279.         if (empty($sFilters['MegaDlDecrypt'])) $sFilters['MegaDlDecrypt'] = stream_filter_append($fp, 'MegaDlDecrypt', STREAM_FILTER_READ, $opts);
  280.         if (!$sFilters['MegaDlDecrypt']) html_error('Error: Unknown error while initializing MegaDlDecrypt filter, cannot continue download.');
  281.     }
  282.  
  283.     private function FSort($a, $b) {
  284.         return strcmp($a['n'], $b['n']);
  285.     }
  286.  
  287.     private function Folder($fnid, $fnk, $sfolder, $recursive) {
  288.         $files = $this->apiReq(array('a' => 'f', 'c' => 1, 'r' => (!empty($sfolder) || $recursive ? 1 : 0)), $fnid);
  289.         if (is_numeric($files[0])) $this->CheckErr($files[0], 'Cannot get folder contents');
  290.         $sfolder = (!empty($sfolder) ? array($sfolder => 1) : array());
  291.  
  292.         foreach ($files[0]['f'] as $file) {
  293.             switch ($file['t']) {
  294.                 case 0: // File
  295.                     if (!empty($sfolder) && empty($sfolder[$file['p']])) break;
  296.                     $keys = array();
  297.                     foreach (explode('/', $file['k']) as $key) if (strpos($key, ':') !== false && $key = explode(':', $key, 2)) $keys[$key[0]] = $key[1];
  298.                     if (empty($keys)) {
  299.                         $key = $this->base64_to_a32($fnk);
  300.                         $attr = $this->dec_attr($this->base64url_decode($file['a']), array($key[0] ^ $key[4], $key[1] ^ $key[5], $key[2] ^ $key[6], $key[3] ^ $key[7]));
  301.                         if (!empty($attr)) textarea($attr);
  302.                         break;
  303.                     }
  304.                     $key = $this->decrypt_key($this->base64_to_a32(reset($keys)), $this->base64_to_a32($fnk));
  305.                     if (empty($key)) break;
  306.                     $attr = $this->dec_attr($this->base64url_decode($file['a']), array($key[0] ^ $key[4], $key[1] ^ $key[5], $key[2] ^ $key[6], $key[3] ^ $key[7]));
  307.                     if (!empty($attr)) $dfiles[$file['h']] = array('k' => $this->a32_to_base64($key), 'n' => $attr['n'], 'p' => $file['p']);
  308.                     break;
  309.                 case 1: // Folder
  310.                     if (!empty($sfolder) && $recursive && !empty($sfolder[$file['p']])) $sfolder[$file['h']] = 1;
  311.                     break;
  312.             }
  313.         }
  314.  
  315.         if (empty($dfiles)) html_error('Error while decoding folder: Empty'.(!empty($sfolder) ? ' or Inexistent Sub-' : ' ').'Folder? [Subfolders: '.(!empty($sfolder) || $recursive ? 'Yes' : 'No').']');
  316.         uasort($dfiles, array($this, 'FSort'));
  317.  
  318.         $files = array();
  319.         foreach ($dfiles as $file => $key) $files[] = "https://mega.nz/#N!$file!{$key['k']}!$fnid!Rapidleech";
  320.         $this->moveToAutoDownloader($files);
  321.     }
  322.  
  323.     private function cJar_encrypt($data, $key = 0) {
  324.         if (empty($data)) return false;
  325.         if (!empty($key)) {
  326.             global $secretkey;
  327.             $_secretkey = $secretkey;
  328.             $secretkey = $key;
  329.         }
  330.         if (is_array($data)) {
  331.             $data = array_combine(array_map('base64_encode', array_map('encrypt', array_keys($data))), array_map('base64_encode', array_map('encrypt', array_values($data))));
  332.         } else {
  333.             $data = base64_encode(encrypt($data));
  334.         }
  335.         if (!empty($key)) $secretkey = $_secretkey;
  336.         return $data;
  337.     }
  338.  
  339.     private function cJar_decrypt($data, $key = 0) {
  340.         if (empty($data)) return false;
  341.         if (!empty($key)) {
  342.             global $secretkey;
  343.             $_secretkey = $secretkey;
  344.             $secretkey = $key;
  345.         }
  346.         if (is_array($data)) {
  347.             $data = array_combine(array_map('decrypt', array_map('base64_decode', array_keys($data))), array_map('decrypt', array_map('base64_decode', array_values($data))));
  348.         } else {
  349.             $data = decrypt(base64_decode($data));
  350.         }
  351.         if (!empty($key)) $secretkey = $_secretkey;
  352.         return $data;
  353.     }
  354.  
  355.     private function cJar_load($user, $pass, $filename = 'mega_dl.php') {
  356.         if (empty($user) || empty($pass)) html_error('Login Failed: User or Password is empty.');
  357.  
  358.         $user = strtolower($user);
  359.         $filename = DOWNLOAD_DIR . basename($filename);
  360.         if (!file_exists($filename) || !($savedcookies = file($filename)) || !is_array($savedcookies = unserialize($savedcookies[1]))) return $this->Login($user, $pass);
  361.  
  362.         $hash = sha1("$user$pass");
  363.         if (array_key_exists($hash, $savedcookies)) {
  364.             $key = substr(base64_encode(hash('sha512', "$user$pass", true)), 0, 56); // 56 chars cropped base64 encoded key to avoid blowfish issues with \0
  365.             $testCookie = ($this->cJar_decrypt($savedcookies[$hash]['enc'], $key) == 'OK') ? $this->cJar_decrypt($savedcookies[$hash]['cookie'], $key) : 0;
  366.             if (!empty($testCookie)) return $this->cJar_test($user, $pass, $testCookie, true);
  367.         }
  368.         return $this->Login($user, $pass);
  369.     }
  370.  
  371.     private function cJar_test($user, $pass, $cookie, $preLogin = false) {
  372.         $this->cookie = array('sid' => $cookie['sid']);
  373.         $quota = $this->apiReq(array('a' => 'uq')); // I'm using the 'User quota details' request for validating the session id.
  374.         if (is_numeric($quota[0]) && $quota[0] < 0) {
  375.             if ($quota[0] == -15) { // Session code expired... We need to get a newer one.
  376.                 if (!extension_loaded('bcmath')) html_error('This plugin needs BCMath extension for re-login.');
  377.                 $this->cookie['sid'] = $cookie['sid'] = false; // Do not send old sid or it will get '-15' error.
  378.                 $res = $this->apiReq(array('a' => 'us', 'user' => $user, 'uh' => $cookie['user_handle']));
  379.                 if (is_numeric($res[0])) $this->CheckEr($res[0], 'Cannot re-login');
  380.                 $rsa_priv_key = explode('/T8\\', $cookie['rsa_priv_key']);
  381.                 $cookie['sid'] = $this->base64url_encode(substr(strrev($this->rsa_decrypt($this->mpi2bc($this->base64url_decode($res[0]['csid'])), $rsa_priv_key[0], $rsa_priv_key[1], $rsa_priv_key[2])), 0, 43));
  382.             } else $this->CheckEr($quota[0], 'Cannot validate saved-login');
  383.         }
  384.         $this->cookie = $cookie;
  385.         $this->cJar_save($user, $pass); // Update last used time.
  386.         return true;
  387.     }
  388.  
  389.     private function cJar_save($user, $pass, $filename = 'mega_dl.php') {
  390.         $maxTime = 31 * 86400; // Max time to keep unused cookies saved (31 days)
  391.         $filename = DOWNLOAD_DIR . basename($filename);
  392.         if (file_exists($filename) && ($savedcookies = file($filename)) && is_array($savedcookies = unserialize($savedcookies[1]))) {
  393.             // Remove old cookies
  394.             foreach ($savedcookies as $k => $v) if (time() - $v['time'] >= $maxTime) unset($savedcookies[$k]);
  395.         } else $savedcookies = array();
  396.         $hash = sha1("$user$pass");
  397.         $key = substr(base64_encode(hash('sha512', "$user$pass", true)), 0, 56); // 56 chars cropped base64 encoded key to avoid blowfish issues with \0
  398.         $savedcookies[$hash] = array('time' => time(), 'enc' => $this->cJar_encrypt('OK', $key), 'cookie' => $this->cJar_encrypt($this->cookie, $key));
  399.  
  400.         file_put_contents($filename, "<?php exit(); ?>\r\n" . serialize($savedcookies), LOCK_EX);
  401.     }
  402.  
  403.     private function Login($user, $pass) {
  404.         if (!extension_loaded('bcmath')) html_error('This plugin needs BCMath extension for login.');
  405.         $this->cookie = array();
  406.         $password_aes = $this->prepare_key($this->str_to_a32($pass));
  407.         $this->cookie['user_handle'] = $this->stringhash($user, $password_aes);
  408.         $res = $this->apiReq(array('a' => 'us', 'user' => $user, 'uh' => $this->cookie['user_handle']));
  409.         if (is_numeric($res[0])) $this->CheckEr($res[0], 'Cannot login');
  410.         $master_key = $this->decrypt_key($this->base64_to_a32($res[0]['k']), $password_aes);
  411.         $privk = $this->a32_to_str($this->decrypt_key($this->base64_to_a32($res[0]['privk']), $master_key));
  412.         $rsa_priv_key = array(0, 0, 0, 0);
  413.         for ($i = 0; $i < 4; $i++) {
  414.             $l = ((ord($privk[0]) * 256 + ord($privk[1]) + 7) / 8) + 2;
  415.             $rsa_priv_key[$i] = $this->mpi2bc(substr($privk, 0, $l));
  416.             $privk = substr($privk, $l);
  417.         }
  418.         unset($privk, $rsa_priv_key[3]);
  419.         $this->cookie['sid'] = $this->base64url_encode(substr(strrev($this->rsa_decrypt($this->mpi2bc($this->base64url_decode($res[0]['csid'])), $rsa_priv_key[0], $rsa_priv_key[1], $rsa_priv_key[2])), 0, 43));
  420.         $this->cookie['rsa_priv_key'] = implode('/T8\\', $rsa_priv_key);
  421.         $this->cJar_save($user, $pass); // Update cookies file.
  422.         return true;
  423.     }
  424. }
  425.  
  426. class Th3822_MegaDlDecrypt extends php_user_filter {
  427.     private $td;
  428.     public function onCreate() {
  429.         if (empty($this->params['iv']) || empty($this->params['key'])) return false;
  430.         $this->td = mcrypt_module_open('rijndael-128', '', 'ctr', '');
  431.         $iv = $this->params['iv'];
  432.         if (!empty($this->params['startFrom']) && is_numeric($this->params['startFrom']) && $this->params['startFrom'] > 0) {
  433.             $blocks = floor($this->params['startFrom'] / 16);
  434.             $waste = $this->params['startFrom'] - ($blocks * 16);
  435.             if ($blocks > 0) $this->increaseIV($iv, $blocks);
  436.         } else $waste = 0;
  437.         $init = mcrypt_generic_init($this->td, $this->params['key'], $iv);
  438.         if ($init === false || $init < 0) return false;
  439.         if ($waste > 0) mdecrypt_generic($this->td, str_repeat('*', min($waste, 16)));
  440.         return true;
  441.     }
  442.  
  443.     public function filter($in, $out, &$consumed, $stop) {
  444.         while ($bucket = stream_bucket_make_writeable($in)) {
  445.             if ($bucket->datalen > 0) {
  446.                 $bucket->data = mdecrypt_generic($this->td, $bucket->data);
  447.                 $consumed += $bucket->datalen;
  448.                 stream_bucket_append($out, $bucket);
  449.             }
  450.         }
  451.         return PSFS_PASS_ON;
  452.     }
  453.  
  454.     public function onClose() {
  455.         mcrypt_generic_deinit($this->td);
  456.         mcrypt_module_close($this->td);
  457.     }
  458.  
  459.     private function increaseIV(&$iv, $inc = 1) {
  460.         $i = 16;
  461.         while ($inc > 0 && --$i >= 0) {
  462.             $sum = ord($iv{$i}) + $inc;
  463.             $iv{$i} = chr($sum & 0xFF);
  464.             $inc = $sum >> 8;
  465.         }
  466.     }
  467. }
  468.  
  469. //[24-2-2013] Written by Th3-822. (Rapidleech r415 or newer required)
  470. //[02-3-2013] Added "checks" for validating rapidleech version & added 2 error msg. - Th3-822
  471. //[27-3-2013] Simplified Stream decrypt function (The other one was not working well... After many tests looks like it's better now :D). - Th3-822
  472. //[20-7-2013] Fixed link regexp. - Th3-822
  473. //[09-8-2013] Added folder support and small fixes from upload plugin. (Download links that are fetched from a folder link are not public and only can be downloaded with this plugin.) - Th3-822
  474. //[30-1-2014] Fixed download from folders. - Th3-822
  475. //[09-2-2014] Fixed issues at link parsing. - Th3-822
  476. //[29-1-2015] Replaced 'T8' prefix at folder->file links for support on third-party downloaders using links with 'N' as prefix. - Th3-822
  477. //[04-2-2016] Added sub-folders support (fully) and added support for link suffix "!less" to disable recursive sub-folder download. - Th3-822
  478. //[27-12-2016] Added Login support for increase traffic limits & forced SSL on downloads to avoid corrupted downloads. - Th3-822
  479. //[12-11-2017] Removed SSL from downloads to increase download speed & updated Th3822_MegaDlDecrypt class. - Th3-822
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top