def decrypt(self, pyfile): fs_filename = encode(pyfile.url) with open(fs_filename) as dlc: data = dlc.read().strip() data += '=' * (-len(data) % 4) dlc_key = data[-88:] dlc_data = base64.b64decode(smart_bytes(data[:-88])) dlc_content = self.load(self.API_URL % dlc_key) try: rc = re.search(r'<rc>(.+)</rc>', dlc_content, re.S).group(1) decoded_rc = base64.b64decode(smart_bytes(rc))[:16] except AttributeError: self.fail(_("Container is corrupted")) key = iv = Cryptodome.Cipher.AES.new(self.KEY, Cryptodome.Cipher.AES.MODE_CBC, self.IV).decrypt(decoded_rc) self.data = base64.b64decode( smart_bytes( Cryptodome.Cipher.AES.new(key, Cryptodome.Cipher.AES.MODE_CBC, iv).decrypt(dlc_data))) self.packages = [(name or pyfile.name, links, name or pyfile.name) for name, links in self.get_packages()]
def save_config(self, config, filename): """Save configuration `config` to a file with `filename` name.""" with open(filename, 'wb') as f: chmod(filename, 0o600) f.write(smart_bytes('version: {0} \n'.format(CONF_VERSION))) for section in sorted(six.iterkeys(config)): f.write( smart_bytes('\n{0} - "{1}":\n'.format( section, config[section]["desc"]))) for option, data in sorted(config[section].items(), key=lambda _x: _x[0]): if option in ("desc", "outline"): continue if isinstance(data["value"], list): value = "[ \n" for x in data["value"]: value += "\t\t" + str(x) + ",\n" value += "\t\t]\n" else: value = '{val}\n'.format(val=smart_text(data["value"])) f.write( smart_bytes(u'\t{0} {1} : "{2}" = {3}'.format( data["type"], option, data["desc"], value, )))
def _checkVersion(self): """ check db version and delete it if needed""" if not exists("files.version"): f = open("files.version", "wb") f.write(smart_bytes(DB_VERSION)) f.close() return f = open("files.version", "rb") v = int(f.read().strip()) f.close() if v < DB_VERSION: if v < 2: try: self.manager.core.log.warning( _("Filedatabase was deleted due to incompatible version." )) except: print( "Filedatabase was deleted due to incompatible version." ) remove("files.version") move(settings.DATABASE_FILENAME, "files.backup.db") f = open("files.version", "wb") f.write(smart_bytes(DB_VERSION)) f.close() return v
def handle_free(self, pyfile): m = re.search(self.LINK_FREE_PATTERN, self.data) if m is None: self.error(_("Download url not found")) link = urljoin("https://fileshark.pl/", m.group(1)) self.data = self.load(link) m = re.search(self.WAIT_PATTERN, self.data) if m is not None: seconds = int(m.group(1)) self.log_debug("Wait %s seconds" % seconds) self.wait(seconds) action, inputs = self.parse_html_form('name="form" method="post"') m = re.search(self.TOKEN_PATTERN, self.data) if m is None: self.retry(msg=_("Captcha form not found")) inputs['form[_token]'] = m.group(1) m = re.search(self.CAPTCHA_PATTERN, self.data) if m is None: self.retry(msg=_("Captcha image not found")) inputs['form[captcha]'] = self.captcha.decrypt_image( base64.b64decode(smart_bytes(m.group(1))), input_type='jpeg', ) inputs['form[start]'] = "" self.download(link, post=inputs, disposition=True)
def decrypt(self, pyfile): fs_filename = encode(pyfile.url) opener = build_opener(MultipartPostHandler.MultipartPostHandler) dlc_content = opener.open( 'http://service.jdownloader.net/dlcrypt/getDLC.php', { 'src': "ccf", 'filename': "test.ccf", 'upload': open(fs_filename, "rb") }).read() dl_folder = self.pyload.config.get('general', 'download_folder') dlc_file = fsjoin(dl_folder, "tmp_%s.dlc" % pyfile.name) try: dlc = re.search( r'<dlc>(.+)</dlc>', dlc_content, re.S, ).group(1) decoded_dlc = base64.b64decode(smart_bytes(dlc)) except AttributeError: self.fail(_("Container is corrupted")) with open(dlc_file, "w") as tempdlc: tempdlc.write(decoded_dlc) self.links = [dlc_file]
def parse_links(self, startNode): return [ base64.b64decode( smart_bytes( node.getElementsByTagName("url")[0].firstChild.data)) for node in startNode.getElementsByTagName("file") ]
def decrypt(self, pyfile): KEY = binascii.unhexlify(self.KEY) IV = binascii.unhexlify(self.IV) iv = Cryptodome.Cipher.AES.new(KEY, Cryptodome.Cipher.AES.MODE_ECB).encrypt(IV) cipher = Cryptodome.Cipher.AES.new(KEY, Cryptodome.Cipher.AES.MODE_CFB, iv) try: fs_filename = encode(pyfile.url) with open(fs_filename, 'r') as rsdf: data = rsdf.read() except IOError as e: self.fail(e.message) if re.search(r'<title>404 - Not Found</title>', data): pyfile.setStatus("offline") else: try: raw_links = binascii.unhexlify( ''.join(data.split())).splitlines() except TypeError: self.fail(_("Container is corrupted")) for link in raw_links: if not link: continue link = cipher.decrypt(base64.b64decode(smart_bytes(link))).replace('CCF: ', '') self.links.append(link)
def loadAccounts(self): """loads all accounts available""" if not exists("accounts.conf"): with open("accounts.conf", "wb") as f: f.write(smart_bytes('version: {0}'.format(ACC_VERSION))) with open("accounts.conf", "rb") as f: content = f.readlines() version = content[0].split(b":")[1].strip() if content else "" if not version or int(version) < ACC_VERSION: copy("accounts.conf", "accounts.backup") with open("accounts.conf", "wb") as f: f.write(smart_bytes('version: {0}'.format(ACC_VERSION))) self.core.log.warning( _("Account settings deleted, due to new config format.")) return plugin = "" name = "" for line in content[1:]: line = smart_text(line.strip()) if (not line or line.startswith('#') or line.startswith('version')): continue if line.endswith(':') and line.count(':') == 1: plugin = line[:-1] self.accounts[plugin] = {} elif line.startswith('@'): options = line[1:].split() if options: self.accounts[plugin][name]['options'][ options[0]] = options[1:] elif ':' in line: name, sep, pw = line.partition(':') self.accounts[plugin][name] = { 'password': pw, 'options': {}, 'valid': True }
def checkVersion(self): """determines if config need to be copied""" MAX_ITERATIONS = 4 for iteration in range(1, MAX_ITERATIONS + 1): try: if not exists("pyload.conf"): copy(join(pypath, "module", "config", "default.conf"), "pyload.conf") chmod("pyload.conf", 0o600) if not exists("plugin.conf"): with open("plugin.conf", "wb") as f: f.write( smart_bytes("version: {0}".format(CONF_VERSION))) chmod("plugin.conf", 0o600) with open("pyload.conf", "rb") as f: v = f.readline() v = v[v.find(b":") + 1:].strip() if not v or int(v) < CONF_VERSION: copy(join(pypath, "module", "config", "default.conf"), "pyload.conf") print("Old version of config was replaced") with open("plugin.conf", "rb") as f: v = f.readline() v = v[v.find(b":") + 1:].strip() if not v or int(v) < CONF_VERSION: with open("plugin.conf", "wb") as f: f.write( smart_bytes("version: {0}".format(CONF_VERSION))) print("Old version of plugin-config replaced") return except Exception: if iteration < MAX_ITERATIONS: sleep(0.3) else: raise
def _get_cipher_params(self): #: Request CNL2 code = re.search(r'javascript:_getm\(\'(.+?)\', 0, \'cnl\'', self.data).group(1) url = "%s/get/cnl2/%s" % (self.base_url, code) res = self.load(url) params = res.split(";;") #: Get jk strlist = list(base64.b64decode(smart_bytes(params[1]))) jk = "".join(strlist[::-1]) #: Get crypted strlist = list(base64.b64decode(smart_bytes(params[2]))) crypted = "".join(strlist[::-1]) #: Log and return return crypted, jk
def changePassword(db, user, oldpw, newpw): db.c.execute('SELECT id, name, password FROM users WHERE name=?', (user, )) r = db.c.fetchone() if not r: return False salt = r[2][:5] pw = r[2][5:] h = sha1(smart_bytes(salt + oldpw)) if h.hexdigest() == pw: salt = reduce(lambda x, y: x + y, [str(random.randint(0, 9)) for i in range(0, 5)]) h = sha1(smart_bytes(salt + newpw)) password = salt + h.hexdigest() db.c.execute("UPDATE users SET password=? WHERE name=?", (password, user)) return True return False
def addUser(db, user, password): salt = reduce(lambda x, y: x + y, [str(random.randint(0, 9)) for i in range(0, 5)]) h = sha1(smart_bytes(salt + password)) password = salt + h.hexdigest() c = db.c c.execute('SELECT name FROM users WHERE name=?', (user, )) if c.fetchone() is not None: c.execute('UPDATE users SET password=? WHERE name=?', (password, user)) else: c.execute('INSERT INTO users (name, password) VALUES (?, ?)', (user, password))
def saveAccounts(self): """save all account information""" with open("accounts.conf", "wb") as f: f.write(smart_bytes('version: {0}\n'.format(ACC_VERSION))) for plugin, accounts in six.iteritems(self.accounts): f.write(smart_bytes('\n{0}:\n'.format(plugin))) for name, data in six.iteritems(accounts): f.write( smart_bytes('\n\t{0}:{1}\n'.format( name, data['password']))) if data['options']: for option, values in six.iteritems(data['options']): f.write( smart_bytes('\t@{0} {1}\n'.format( option, b' '.join(values)))) chmod(f.name, 0o600)
def decode(value, encoding=None, errors='strict'): """ Encoded string (default to own system encoding) -> unicode string """ if isinstance(value, six.binary_type): res = smart_text( value, encoding=encoding or get_console_encoding(sys.stdout.encoding), errors=errors, ) elif isinstance(value, six.text_type): res = value else: res = smart_text(value) # Hotfix UnicodeDecodeError try: smart_bytes(res, encoding='ascii') except UnicodeEncodeError: return normalize(res) return res
def encode(value, encoding='utf-8', errors='backslashreplace'): """ Unicode string -> encoded string (default to UTF-8) """ if isinstance(value, six.text_type): return value.encode(encoding, errors) if isinstance(value, six.binary_type): decoding = get_console_encoding(sys.stdin.encoding) if encoding == decoding: return value return transcode(value, decoding, encoding) return smart_bytes(value)
def test_smart_bytes(self): value_to_expected_tuples = ( (b'testing', b'testing'), (u'testing', b'testing'), (b'A\xc3\xb1o', b'A\xc3\xb1o'), (u'Año', b'A\xc3\xb1o'), (123, b'123'), (None, b'None'), ) for value, expected in value_to_expected_tuples: result = smart_bytes(value) self.assertEqual(result, expected) self.assertIsInstance(result, six.binary_type)
def checkAuth(db, user, password): c = db.c c.execute('SELECT id, name, password, role, permission, template, email FROM "users" WHERE name=?', (user, )) r = c.fetchone() if not r: return {} salt = r[2][:5] pw = r[2][5:] h = sha1(smart_bytes(salt + password)) if h.hexdigest() == pw: return {"id": r[0], "name": r[1], "role": r[3], "permission": r[4], "template": r[5], "email": r[6]} else: return {}
def handle_free(self, pyfile): self.wait(3) self.data = self.load("%s/free/" % pyfile.url, post={'dl_free': "1", 'choice': "free"}) self.check_errors() res = self.handle_captcha() self.link = base64.b64decode(smart_bytes(res)) if not self.link.startswith("http://"): self.error(_("Invalid url")) self.wait()
def _get_links(self, crypted, jk): #: Get key key = binascii.unhexlify(str(jk)) #: Decrypt #Key = key #IV = key obj = Cryptodome.Cipher.AES.new(key, Cryptodome.Cipher.AES.MODE_CBC, key) text = obj.decrypt(base64.b64decode(smart_bytes(crypted))) #: Extract links text = text.replace("\x00", "").replace("\r", "") links = list(filter(None, text.split('\n'))) return links
def eval(self, script): if not self.init: if ENGINE == "pyv8" or (DEBUG and PYV8): import PyV8 global PyV8 self.init = True script = smart_bytes(script) if not ENGINE: raise Exception("No JS Engine") if not DEBUG: if ENGINE == "pyv8": return self.eval_pyv8(script) elif ENGINE == "js": return self.eval_js(script) elif ENGINE == "rhino": return self.eval_rhino(script) else: results = [] if PYV8: res = self.eval_pyv8(script) print("PyV8:", res) results.append(res) if JS: res = self.eval_js(script) print("JS:", res) results.append(res) if RHINO: res = self.eval_rhino(script) print("Rhino:", res) results.append(res) warning = False for x in results: for y in results: if x != y: warning = True if warning: print("### WARNING ###: Different results") return results[0]
def _get_links(self, crypted, jk): #: Get key jreturn = self.js.eval("%s f()" % jk) self.log_debug("JsEngine returns value [%s]" % jreturn) key = binascii.unhexlify(jreturn) #: Decrypt Key = key IV = key obj = Cryptodome.Cipher.AES.new(Key, Cryptodome.Cipher.AES.MODE_CBC, IV) text = obj.decrypt(base64.b64decode(smart_bytes(crypted))) #: Extract links text = text.replace("\x00", "").replace("\r", "") links = list(filter(None, text.split('\n'))) #: Log and return self.log_debug("Package has %d links" % len(links)) return links
def handle_free(self, pyfile): #: Download button m = re.search(r'<a class="stahnoutSoubor".*?href="(.*?)"', self.data) if m is None: self.error(_("Page 1 URL not found")) url = "http://bezvadata.cz%s" % m.group(1) #: Captcha form self.data = self.load(url) self.check_errors() action, inputs = self.parse_html_form('frm-stahnoutFreeForm') if not inputs: self.error(_("FreeForm")) m = re.search(r'<img src="data:image/png;base64,(.*?)"', self.data) if m is None: self.retry_captcha() inputs['captcha'] = self.captcha.decrypt_image( base64.b64decode(smart_bytes(m.group(1))), input_type='png', ) #: Download url self.data = self.load("http://bezvadata.cz%s" % action, post=inputs) self.check_errors() m = re.search(r'<a class="stahnoutSoubor2" href="(.*?)">', self.data) if m is None: self.error(_("Page 2 URL not found")) url = "http://bezvadata.cz%s" % m.group(1) self.log_debug("DL URL %s" % url) #: countdown m = re.search(r'id="countdown">(\d\d):(\d\d)<', self.data) wait_time = (int(m.group(1)) * 60 + int(m.group(2))) if m else 120 self.wait(wait_time, False) self.link = url
def parse_packages(self, startNode): return [( base64.b64decode(smart_bytes(node.getAttribute("name"))), self.parse_links(node), ) for node in startNode.getElementsByTagName("package")]
def str_to_a32(s): # Add padding, we need a string with a length multiple of 4 s = smart_bytes(s) s += b'\0' * (-len(s) % 4) #: big-endian, unsigned int return struct.unpack(">%dI" % (len(s) / 4), s)
def base64_decode(data): #: Add padding, we need a string with a length multiple of 4 data = smart_bytes(data) data += b'=' * (-len(data) % 4) return base64.b64decode(data, b'-_')
def base64_encode(data): return base64.b64encode(smart_bytes(data), b'-_')
def writePidFile(self): self.deletePidFile() pid = os.getpid() f = open(self.pidfile, "wb") f.write(smart_bytes(pid)) f.close()
def decrypt(self, pyfile): self.links.extend( base64.b64decode(smart_bytes(self.info['pattern']['LIST'])).split(',') )
def load(self, url, get={}, post={}, ref=True, cookies=True, just_header=False, decode=False): """Load content at url and returns it :param url: :param get: :param post: :param ref: :param cookies: :param just_header: if True only the header will be retrieved and returned as dict :param decode: Wether to decode the output according to http header, should be True in most cases :return: Loaded content """ if self.pyfile.abort: raise Abort url = smart_bytes(url) res = self.req.load(url, get, post, ref, cookies, just_header, decode=decode) if self.core.debug: from inspect import currentframe frame = currentframe() if not exists(join("tmp", self.__name__)): makedirs(join("tmp", self.__name__)) f = open( join( "tmp", self.__name__, "%s_line%s.dump.html" % (frame.f_back.f_code.co_name, frame.f_back.f_lineno)), "wb") del frame # delete the frame or it wont be cleaned try: tmp = res.encode("utf8") except: tmp = res f.write(tmp) f.close() if just_header: #parse header header = {"code": self.req.code} for line in res.splitlines(): line = line.strip() if not line or ":" not in line: continue key, none, value = line.partition(":") key = key.lower().strip() value = value.strip() if key in header: if type(header[key]) == list: header[key].append(value) else: header[key] = [header[key], value] else: header[key] = value res = header return res