Example #1
0
 def test_malformed_cookies(self):
     cookiejar = YoutubeDLCookieJar(
         './test/testdata/cookies/malformed_cookies.txt')
     cookiejar.load(ignore_discard=True, ignore_expires=True)
     # Cookies should be empty since all malformed cookie file entries
     # will be ignored
     self.assertFalse(cookiejar._cookies)
Example #2
0
def _merge_cookie_jars(jars):
    output_jar = YoutubeDLCookieJar()
    for jar in jars:
        for cookie in jar:
            output_jar.set_cookie(cookie)
        if jar.filename is not None:
            output_jar.filename = jar.filename
    return output_jar
Example #3
0
def _extract_firefox_cookies(profile, logger):
    logger.info('Extracting cookies from firefox')
    if not SQLITE_AVAILABLE:
        logger.warning(
            'Cannot extract cookies from firefox without sqlite3 support. '
            'Please use a python interpreter compiled with sqlite3 support')
        return YoutubeDLCookieJar()

    if profile is None:
        search_root = _firefox_browser_dir()
    elif _is_path(profile):
        search_root = profile
    else:
        search_root = os.path.join(_firefox_browser_dir(), profile)

    cookie_database_path = _find_most_recently_used_file(
        search_root, 'cookies.sqlite')
    if cookie_database_path is None:
        raise FileNotFoundError(
            'could not find firefox cookies database in {}'.format(
                search_root))
    logger.debug('extracting from: "{}"'.format(cookie_database_path))

    with tempfile.TemporaryDirectory(prefix='youtube_dl') as tmpdir:
        cursor = None
        try:
            cursor = _open_database_copy(cookie_database_path, tmpdir)
            cursor.execute(
                'SELECT host, name, value, path, expiry, isSecure FROM moz_cookies'
            )
            jar = YoutubeDLCookieJar()
            for host, name, value, path, expiry, is_secure in cursor.fetchall(
            ):
                cookie = compat_cookiejar_Cookie(
                    version=0,
                    name=name,
                    value=value,
                    port=None,
                    port_specified=False,
                    domain=host,
                    domain_specified=bool(host),
                    domain_initial_dot=host.startswith('.'),
                    path=path,
                    path_specified=bool(path),
                    secure=is_secure,
                    expires=expiry,
                    discard=False,
                    comment=None,
                    comment_url=None,
                    rest={})
                jar.set_cookie(cookie)
            logger.info('Extracted {} cookies from firefox'.format(len(jar)))
            return jar
        finally:
            if cursor is not None:
                cursor.connection.close()
Example #4
0
    def test_strip_httponly_prefix(self):
        cookiejar = YoutubeDLCookieJar(
            './test/testdata/cookies/httponly_cookies.txt')
        cookiejar.load(ignore_discard=True, ignore_expires=True)

        def assert_cookie_has_value(key):
            self.assertEqual(
                cookiejar._cookies['www.foobar.foobar']['/'][key].value,
                key + '_VALUE')

        assert_cookie_has_value('HTTPONLY_COOKIE')
        assert_cookie_has_value('JS_ACCESSIBLE_COOKIE')
Example #5
0
def load_cookies(cookie_file, browser_specification, ydl):
    cookie_jars = []
    if browser_specification is not None:
        browser_name, profile = _parse_browser_specification(
            *browser_specification)
        cookie_jars.append(
            extract_cookies_from_browser(browser_name, profile,
                                         YDLLogger(ydl)))

    if cookie_file is not None:
        cookie_file = expand_path(cookie_file)
        jar = YoutubeDLCookieJar(cookie_file)
        if os.access(cookie_file, os.R_OK):
            jar.load(ignore_discard=True, ignore_expires=True)
        cookie_jars.append(jar)

    return _merge_cookie_jars(cookie_jars)
Example #6
0
def parse_safari_cookies(data, jar=None, logger=YDLLogger()):
    """
    References:
        - https://github.com/libyal/dtformats/blob/main/documentation/Safari%20Cookies.asciidoc
            - this data appears to be out of date but the important parts of the database structure is the same
            - there are a few bytes here and there which are skipped during parsing
    """
    if jar is None:
        jar = YoutubeDLCookieJar()
    page_sizes, body_start = _parse_safari_cookies_header(data, logger)
    p = DataParser(data[body_start:], logger)
    for page_size in page_sizes:
        _parse_safari_cookies_page(p.read_bytes(page_size), jar, logger)
    p.skip_to_end('footer')
    return jar
Example #7
0
 def test_keep_session_cookies(self):
     cookiejar = YoutubeDLCookieJar(
         './test/testdata/cookies/session_cookies.txt')
     cookiejar.load(ignore_discard=True, ignore_expires=True)
     tf = tempfile.NamedTemporaryFile(delete=False)
     try:
         cookiejar.save(filename=tf.name,
                        ignore_discard=True,
                        ignore_expires=True)
         temp = tf.read().decode('utf-8')
         self.assertTrue(
             re.search(
                 r'www\.foobar\.foobar\s+FALSE\s+/\s+TRUE\s+0\s+YoutubeDLExpiresEmpty\s+YoutubeDLExpiresEmptyValue',
                 temp))
         self.assertTrue(
             re.search(
                 r'www\.foobar\.foobar\s+FALSE\s+/\s+TRUE\s+0\s+YoutubeDLExpires0\s+YoutubeDLExpires0Value',
                 temp))
     finally:
         tf.close()
         os.remove(tf.name)
Example #8
0
def _extract_chrome_cookies(browser_name, profile, logger):
    logger.info('Extracting cookies from {}'.format(browser_name))

    if not SQLITE_AVAILABLE:
        logger.warning(
            ('Cannot extract cookies from {} without sqlite3 support. '
             'Please use a python interpreter compiled with sqlite3 support'
             ).format(browser_name))
        return YoutubeDLCookieJar()

    config = _get_chromium_based_browser_settings(browser_name)

    if profile is None:
        search_root = config['browser_dir']
    elif _is_path(profile):
        search_root = profile
        config['browser_dir'] = os.path.dirname(
            profile) if config['supports_profiles'] else profile
    else:
        if config['supports_profiles']:
            search_root = os.path.join(config['browser_dir'], profile)
        else:
            logger.error('{} does not support profiles'.format(browser_name))
            search_root = config['browser_dir']

    cookie_database_path = _find_most_recently_used_file(
        search_root, 'Cookies')
    if cookie_database_path is None:
        raise FileNotFoundError(
            'could not find {} cookies database in "{}"'.format(
                browser_name, search_root))
    logger.debug('extracting from: "{}"'.format(cookie_database_path))

    decryptor = get_cookie_decryptor(config['browser_dir'],
                                     config['keyring_name'], logger)

    with tempfile.TemporaryDirectory(prefix='youtube_dl') as tmpdir:
        cursor = None
        try:
            cursor = _open_database_copy(cookie_database_path, tmpdir)
            cursor.connection.text_factory = bytes
            column_names = _get_column_names(cursor, 'cookies')
            secure_column = 'is_secure' if 'is_secure' in column_names else 'secure'
            cursor.execute(
                'SELECT host_key, name, value, encrypted_value, path, '
                'expires_utc, {} FROM cookies'.format(secure_column))
            jar = YoutubeDLCookieJar()
            failed_cookies = 0
            for host_key, name, value, encrypted_value, path, expires_utc, is_secure in cursor.fetchall(
            ):
                host_key = host_key.decode('utf-8')
                name = name.decode('utf-8')
                value = value.decode('utf-8')
                path = path.decode('utf-8')

                if not value and encrypted_value:
                    value = decryptor.decrypt(encrypted_value)
                    if value is None:
                        failed_cookies += 1
                        continue

                cookie = compat_cookiejar_Cookie(
                    version=0,
                    name=name,
                    value=value,
                    port=None,
                    port_specified=False,
                    domain=host_key,
                    domain_specified=bool(host_key),
                    domain_initial_dot=host_key.startswith('.'),
                    path=path,
                    path_specified=bool(path),
                    secure=is_secure,
                    expires=expires_utc,
                    discard=False,
                    comment=None,
                    comment_url=None,
                    rest={})
                jar.set_cookie(cookie)
            if failed_cookies > 0:
                failed_message = ' ({} could not be decrypted)'.format(
                    failed_cookies)
            else:
                failed_message = ''
            logger.info('Extracted {} cookies from {}{}'.format(
                len(jar), browser_name, failed_message))
            return jar
        finally:
            if cursor is not None:
                cursor.connection.close()