o
    i                     @   s\  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZ	d dl
Z	d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlmZmZ ddlmZmZmZ ddlmZm Z m!Z! ddl"m#Z#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1 dd	l2m3Z3 h d
Z4e4ddhB Z5G dd de1Z6dd Z7G dd de'Z8dd Z9de6 fdddddZ:dd Z;dd Z<dd Z=dd Z>d d! Z?d"d# Z@G d$d% d%ZAddd&d'd(ZBG d)d* d*eAZCG d+d, d,eAZDG d-d. d.eAZEd/d0 ZFG d1d2 d2eGZHG d3d4 d4ZId5d6 ZJd7d8 ZKd9d: ZLd;d< ZMde6 fd=d>ZNG d?d@ d@eZOG dAdB dBeZPePjQR ZSdCdD ZTdEdF ZUdGdH ZVdIdJ ZWdKdL ZXdMdN ZYdOdP ZZdQdR Z[dSdT Z\dqdWdXZ]drdYdZZ^d[d\ Z_d]d^ Z`d_d` Zadadb Zbdcdd Zcdedf Zddgdh Zedidj ZfdsdkdlZgG dmdn dne	jhjiZjG dodp dpe	jkjlZmdS )t    N)Enumauto   )aes_cbc_decrypt_bytes aes_gcm_decrypt_and_verify_bytesunpad_pkcs7)!_SECRETSTORAGE_UNAVAILABLE_REASONsecretstoragesqlite3)MultilinePrinterQuietMultilinePrinter)
DownloadErrorYoutubeDLErrorPopenerror_to_strexpand_pathis_path_likesanitize_urlstr_or_nonetry_callwrite_string)
_YDLLogger)normalize_url>   edgebraveoperawhalechromevivaldichromiumfirefoxsafaric                       s6   e Zd Zd fdd	ZG dd deZdd Z  ZS )		YDLLoggerFc                    s   t  j||dS )N)once)superwarning)selfmessage	only_once	__class__ B/home/ubuntu/.local/lib/python3.10/site-packages/yt_dlp/cookies.pyr%   6   s   zYDLLogger.warningc                   @   s   e Zd Zd\ZZdd ZdS )zYDLLogger.ProgressBar)g?r   c                 C   s8   t   | j | jkr| d| d t   | _d S d S )Nz
[Cookies] r   )time_timer_DELAYprint_at_line)r&   r'   r+   r+   r,   print<   s   zYDLLogger.ProgressBar.printN)__name__
__module____qualname__r/   r.   r1   r+   r+   r+   r,   ProgressBar9   s    r5   c                 C   sf   | j r| j jds| j jdrdS | j jj}z	| s W dS W n
 ty+   Y dS w | j|ddS )z8Return a context manager with a print method. (Optional)
noprogressloggerNF)preserve_output)_ydlparamsget
_out_fileserrorisattyBaseExceptionr5   )r&   filer+   r+   r,   progress_barA   s   "
zYDLLogger.progress_barF)r2   r3   r4   r%   r   r5   rA   __classcell__r+   r+   r)   r,   r"   5   s    r"   c                 C   s.   t | dr|  }|r|S t }dd |_|S )NrA   c                 S   s   d S Nr+   )_r+   r+   r,   <lambda>U   s    z&_create_progress_bar.<locals>.<lambda>)hasattrrA   r   r1   )r7   printerr+   r+   r,   _create_progress_barO   s   

rI   c                   @      e Zd ZdS )CookieLoadErrorNr2   r3   r4   r+   r+   r+   r,   rK   Y       rK   c           
   	   C   s   zEg }|d urt | \}}}}|t||t|||d | d urAt| }|r+t| } t| }	|r8t| tj	r<|	
  ||	 t|W S  tyP   tdw )Nkeyring	containerzfailed to load cookies)_parse_browser_specificationappendextract_cookies_from_browserr"   r   r   YoutubeDLCookieJarosaccessR_OKload_merge_cookie_jars	ExceptionrK   )
cookie_filebrowser_specificationydlcookie_jarsbrowser_nameprofilerO   rP   is_filenamejarr+   r+   r,   load_cookies]   s&   

rc   rN   c                C   sJ   | dkr
t |||S | dkrt||S | tv rt| |||S td|  )Nr    r!   zunknown browser: )_extract_firefox_cookies_extract_safari_cookiesCHROMIUM_BASED_BROWSERS_extract_chrome_cookies
ValueError)r_   r`   r7   rO   rP   r+   r+   r,   rS   t   s   
rS   c                    s  d}| d ts|d t S d u rtt }ntr#g}n
fddt D }dtt	|}t
t|}|d u rFtd| |d| d	 d } d
vrtjtj|d}tj|rmt|tjsttd| t|dd}	t|	dg }
W d    n1 sw   Y  t fdd|
D d }t|tstd  dtjdd}t||}t |j! |"d# d }||kr|d|  n|d|  t|tr|d  d|  |"dd| d| df n dkr|d  |"d! n|"d" t }t$|~}|% }t&|}t'|D ]i\}\}}}}}}|(d#|d$d%|d$ |d&krL|d urL|d' }t)j*j+d<i d(dd)|d*|d+d d,d-d.|d/t,|d0|-d1d2|d3t,|d4|d5|d6d-d7d d8d d9i }|.| q'W d    n	1 sw   Y  | d:t&| d; |W  d    W  d    S 1 sw   Y  W d    d S 1 sw   Y  d S )=N   zExtracting cookies from firefoxzzCannot extract cookies from firefox without sqlite3 support. Please use a Python interpreter compiled with sqlite3 supportc                    s   g | ]	}t j| qS r+   )rU   pathjoin).0rj   )r`   r+   r,   
<listcomp>   s    z,_extract_firefox_cookies.<locals>.<listcomp>z, z+could not find firefox cookies database in Extracting cookies from: "")Nnonezcontainers.jsonz"could not read containers.json in utf8encoding
identitiesc                 3   s8    | ]   d t fddfv r  dV  qdS )namec                      s   t d d  S )NzuserContext([^\.]+)\.labell10nID)re	fullmatchgroupr+   contextr+   r,   rF          z4_extract_firefox_cookies.<locals>.<genexpr>.<lambda>userContextIdN)r;   r   )rl   )rP   rz   r,   	<genexpr>   s
    z+_extract_firefox_cookies.<locals>.<genexpr>z"could not find firefox container "z" in containers.jsonyt_dlpprefixzPRAGMA user_version;r   z7Possibly unsupported firefox cookies database version: z"Firefox cookies database version: z-Only loading cookies from firefox container "z", ID zzSELECT host, name, value, path, expiry, isSecure FROM moz_cookies WHERE originAttributes LIKE ? OR originAttributes LIKE ?z%userContextId=z&%rp   z3Only loading cookies not belonging to any containerztSELECT host, name, value, path, expiry, isSecure FROM moz_cookies WHERE NOT INSTR(originAttributes,"userContextId=")zASELECT host, name, value, path, expiry, isSecure FROM moz_cookiesLoading cookie  6d/   i  versionru   valueportport_specifiedFdomaindomain_specifieddomain_initial_dot.rj   path_specifiedsecureexpiresdiscardcommentcomment_urlrest
Extracted z cookies from firefoxr+   )/infor
   r%   rT   list_firefox_browser_dirs_is_pathrk   maprepr_newest_firefox_cookie_dbsFileNotFoundErrordebugrU   rj   dirnameisfilerV   rW   openjsonrX   r;   next
isinstanceintrh   tempfileTemporaryDirectory_open_database_copy
contextlibclosing
connectionexecutefetchonerI   fetchalllen	enumerater1   http	cookiejarCookiebool
startswith
set_cookie)r`   rP   r7   MAX_SUPPORTED_DB_SCHEMA_VERSIONsearch_rootssearch_rootcookie_database_pathcontainer_idcontainers_path
containersrt   tmpdircursordb_schema_versionrb   rA   tabletotal_cookie_countihostru   r   rj   expiry	is_securecookier+   )rP   r`   r,   rd      s   









$rd   c                   c   sn    t jdv rttjjdE d H  d S t jdkr tjdV  d S ttjjtjt ddddd	fE d H  d S )
Ncygwinwin32)z"%APPDATA%\Mozilla\Firefox\Profilesza%LOCALAPPDATA%\Packages\Mozilla.Firefox_n80bbvh6b1yt2\LocalCache\Roaming\Mozilla\Firefox\Profilesdarwinz.~/Library/Application Support/Firefox/Profileszmozilla/firefoxz~/.mozilla/firefoxz5~/.var/app/org.mozilla.firefox/config/mozilla/firefoxz/~/.var/app/org.mozilla.firefox/.mozilla/firefoxz&~/snap/firefox/common/.mozilla/firefox)	sysplatformr   rU   rj   
expandvars
expanduserrk   _config_homer+   r+   r+   r,   r      s   

r   c              	   c   s@    t tjj| D ]}dD ]}ttj||dE d H  qqd S )N) z*/zProfiles/*/zcookies.sqlite)r   rU   rj   abspathglobiglobrk   )rootsrootpatternr+   r+   r,   r      s   r   c              
   C   s  t jdv rAtjd}tjd}tj|dtj|dtj|dtj|dtj|dtj|d	tj|d
d|  }nmt jdkr|tjd}tj|dtj|dtj|dtj|dtj|dtj|dtj|dd|  }n2t }tj|dtj|dtj|dtj|dtj|dtj|dtj|dd|  }dddt jdkrdndt jdkrdndt jdkrdnddd|  }dh}||| |vdS ) Nr   z%LOCALAPPDATA%z	%APPDATA%z%BraveSoftware\Brave-Browser\User DatazGoogle\Chrome\User DatazChromium\User DatazMicrosoft\Edge\User DatazOpera Software\Opera StablezVivaldi\User DatazNaver\Naver Whale\User Data)r   r   r   r   r   r   r   r   z~/Library/Application SupportzBraveSoftware/Brave-BrowserzGoogle/ChromeChromiumzMicrosoft Edgezcom.operasoftware.OperaVivaldizNaver/Whalezgoogle-chromer   zmicrosoft-edger   r   znaver-whaleBraveChromeOperaWhale)browser_dirkeyring_namesupports_profiles)r   r   rU   rj   r   rk   r   r   )r_   appdata_localappdata_roamingr   appdataconfigr   browsers_without_profilesr+   r+   r,   $_get_chromium_based_browser_settings   sf   



r   c                 C   s  | d|   ts|d|  d t S t| }|d u r#|d }n/t|r8|}|d r3tj|n||d< n|d rFtj	|d |}n|
|  d |d }tt|d|}|d u ritd|  d	| d
|d| d
 tjdd}d }zzt||}t|d d }	t|d |d |||	d}
t|j_t|d}d|v rdnd}|d| d t }d}d}t|B}| }t|}t|D ]-\}}|d|dd|d t|
g|R  \}}|s|d7 }q|s|d7 }| | qW d    n	1 sw   Y  |dkrd| d}nd}| dt| d|  |  |
j!" }||d < |d!|  |W W |d urF|j#  W  d    S  t$yr } ztj%d"krm|j&d#krmd$}|
| t'| d }~ww |d ur~|j#  w w 1 sw   Y  d S )%NzExtracting cookies from zCannot extract cookies from zW without sqlite3 support. Please use a Python interpreter compiled with sqlite3 supportr   r   z does not support profilesCookieszcould not find z cookies database in "ro   rn   r   r   z,SELECT value FROM meta WHERE key = "version"r   r   rO   meta_versioncookiesr   r   zBSELECT host_key, name, value, encrypted_value, path, expires_utc, z FROM cookiesr   r   r   r    (z could not be decrypted)r   r   z cookies from unencryptedzcookie version breakdown: nt   zgCould not copy Chrome cookie database. See  https://github.com/yt-dlp/yt-dlp/issues/7271  for more info)(r   r
   r%   rT   r   r   rU   rj   r   rk   r=   r   _find_filesr   r   r   r   r   r   r   r   get_cookie_decryptorbytesr   text_factory_get_column_namesrI   r   r   r   r1   _process_chrome_cookier   _cookie_countscopyclosePermissionErrorru   errnor   )r_   r`   rO   r7   r   r   r   r   r   r   	decryptorcolumn_namessecure_columnrb   failed_cookiesunencrypted_cookiesrA   r   r   r   lineis_encryptedr   failed_messagecountsr=   r'   r+   r+   r,   rg   &  s   







(

rg   c           	      C   s   |  }|  }|  }|  }| o|}|r$| |}|d u r$|d fS |s(d }|tjjdi ddd|d|dd ddd|d	t|d
|dd|dt|d|d|dddd dd di fS )Nr   r   ru   r   r   r   Fr   r   r   r   rj   r   r   r   r   r   r   r   r+   )decodedecryptr   r   r   r   r   )	r   host_keyru   r   encrypted_valuerj   expires_utcr   r  r+   r+   r,   r   t  sX   


r   c                   @   s   e Zd ZdZi Zdd ZdS )ChromeCookieDecryptoraf  
    Overview:

        Linux:
        - cookies are either v10 or v11
            - v10: AES-CBC encrypted with a fixed key
                - also attempts empty password if decryption fails
            - v11: AES-CBC encrypted with an OS protected key (keyring)
                - also attempts empty password if decryption fails
            - v11 keys can be stored in various places depending on the activate desktop environment [2]

        Mac:
        - cookies are either v10 or not v10
            - v10: AES-CBC encrypted with an OS protected key (keyring) and more key derivation iterations than linux
            - not v10: 'old data' stored as plaintext

        Windows:
        - cookies are either v10 or not v10
            - v10: AES-GCM encrypted with a key which is encrypted with DPAPI
            - not v10: encrypted with DPAPI

    Sources:
    - [1] https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/
    - [2] https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/key_storage_linux.cc
        - KeyStorageLinux::CreateService
    c                 C   s   t d)Nz"Must be implemented by sub classes)NotImplementedError)r&   r  r+   r+   r,   r    s   zChromeCookieDecryptor.decryptN)r2   r3   r4   __doc__r   r  r+   r+   r+   r,   r	    s    r	  r   c                C   s@   t jdkrt|||dS t jdv rt| ||dS t||||dS )Nr   )r   )r   r   r   )r   r   MacChromeCookieDecryptorWindowsChromeCookieDecryptorLinuxChromeCookieDecryptor)browser_rootbrowser_keyring_namer7   rO   r   r+   r+   r,   r     s
   

r   c                   @   s>   e Zd ZdddddZejdd Zedd Zd	d
 Z	dS )r  Nr   c                C   sF   || _ | d| _| d| _dddd| _|| _|| _|pd| _d S )Ns   peanuts    r   )v10v11other)_logger
derive_key_v10_key
_empty_keyr   _browser_keyring_name_keyring_meta_version)r&   r  r7   rO   r   r+   r+   r,   __init__  s   z#LinuxChromeCookieDecryptor.__init__c                 C   s(   t | j| j| j}|d u rd S | |S rD   )_get_linux_keyring_passwordr  r  r  r  )r&   passwordr+   r+   r,   _v11_key  s   z#LinuxChromeCookieDecryptor._v11_keyc                 C      t | ddddS )N	   saltysaltr   r   salt
iterations
key_lengthpbkdf2_sha1r  r+   r+   r,   r       z%LinuxChromeCookieDecryptor.derive_keyc                 C   s   |dd }|dd }|dkr)| j d  d7  < t|| j| jf| j| jdkdS |dkrU| j d	  d7  < | jdu rE| jjd
dd dS t|| j| jf| j| jdkdS | jjd| ddd | j d  d7  < dS )a  

        following the same approach as the fix in [1]: if cookies fail to decrypt then attempt to decrypt
        with an empty password. The failure detection is not the same as what chromium uses so the
        results won't be perfect

        References:
            - [1] https://chromium.googlesource.com/chromium/src/+/bbd54702284caca1f92d656fdcadf2ccca6f4165%5E%21/
                - a bugfix to try an empty password as a fallback
        N      v10r  r      hash_prefixs   v11r  z(cannot decrypt v11 cookies: no key foundTr(   zunknown cookie version: "ro   r  )r   _decrypt_aes_cbc_multir  r  r  r  r  r%   r&   r  r   
ciphertextr+   r+   r,   r    s(   
z"LinuxChromeCookieDecryptor.decrypt)
r2   r3   r4   r  	functoolscached_propertyr  staticmethodr  r  r+   r+   r+   r,   r    s    	

r  c                   @   s*   e Zd ZdddZedd Zdd ZdS )	r  Nc                 C   sB   || _ t||}|d u rd n| || _ddd| _|pd| _d S Nr   )r  r  )r  _get_mac_keyring_passwordr  r  r   r  )r&   r  r7   r   r  r+   r+   r,   r    s
   
z!MacChromeCookieDecryptor.__init__c                 C   r   )Nr!  i  r   r"  r&  r(  r+   r+   r,   r    r)  z#MacChromeCookieDecryptor.derive_keyc                 C   s   |d d }|dd  }|dkr6| j d  d7  < | jd u r(| jjddd d S t|| jf| j| jdkd	S | j d
  d7  < |S )Nr*  r+  r  r   (cannot decrypt v10 cookies: no key foundTr/  r,  r-  r  )r   r  r  r%   r0  r  r1  r+   r+   r,   r    s   
z MacChromeCookieDecryptor.decryptrD   )r2   r3   r4   r  r5  r  r  r+   r+   r+   r,   r    s
    

r  c                   @   s   e Zd ZdddZdd ZdS )r  Nc                 C   s,   || _ t||| _ddd| _|pd| _d S r6  )r  _get_windows_v10_keyr  r   r  )r&   r  r7   r   r+   r+   r,   r    s   z%WindowsChromeCookieDecryptor.__init__c           	      C   s   |d d }|dd  }|dkrQ| j d  d7  < | jd u r(| jjddd d S d}d	}|}|d | }|||  }|| d  }t|| j||| j| jd
kdS | j d  d7  < t|| j S )Nr*  r+  r  r   r8  Tr/     r   r,  r-  r  )r   r  r  r%   _decrypt_aes_gcmr  _decrypt_windows_dpapir  )	r&   r  r   r2  nonce_lengthauthentication_tag_lengthraw_ciphertextnonceauthentication_tagr+   r+   r,   r    s&   
z$WindowsChromeCookieDecryptor.decryptrD   )r2   r3   r4   r  r  r+   r+   r+   r,   r    s    
r  c                 C   s   t jdvrtdt j | r tj| }tj|stdn!tjd}tj|sA|d tjd}tj|sAtdt	|d}|
 }W d    n1 sUw   Y  t||d	}|d
t| d |S )N)r   ioszunsupported platform: z(custom safari cookies database not foundz'~/Library/Cookies/Cookies.binarycookiesz Trying secondary cookie locationzP~/Library/Containers/com.apple.Safari/Data/Library/Cookies/Cookies.binarycookiesz&could not find safari cookies databaserb)r7   r   z cookies from safari)r   r   rh   rU   rj   r   r   r   r   r   readparse_safari_cookiesr   r   )r`   r7   cookies_pathfcookies_datarb   r+   r+   r,   re   8  s&   


re   c                   @   rJ   )ParserErrorNrL   r+   r+   r+   r,   rI  R  rM   rI  c                   @   s^   e Zd Zdd Zdd Zdd Zddd	Zdd
dZdd ZdddZ	dddZ
dddZdS )
DataParserc                 C   s   || _ d| _|| _d S )Nr   )_datar   r  )r&   datar7   r+   r+   r,   r  W  s   
zDataParser.__init__c                 C   sR   |dk rt d| d| j| }|t| jkrt d| j| j| }|| _|S )Nr   zinvalid read of  byteszreached end of input)rI  r   r   rK  )r&   	num_bytesendrL  r+   r+   r,   
read_bytes\  s   
zDataParser.read_bytesc                 C   s6   |  t|}||krtd| d| d| dd S )Nzunexpected value: z != r   ))rP  r   rI  )r&   expected_valuer'   r   r+   r+   r,   expect_bytesf  s   zDataParser.expect_bytesFc                 C   "   |rdnd}t || dd S )Nz>Iz<I   r   structunpackrP  r&   
big_endiandata_formatr+   r+   r,   	read_uintk     zDataParser.read_uintc                 C   rT  )Nz>dz<d   r   rV  rY  r+   r+   r,   read_doubleo  r]  zDataParser.read_doublec                 C   s2   g }	 |  d}|dkrd| S || q)NTr       r  )rP  rk   r  rR   )r&   buffercr+   r+   r,   read_cstrings  s   

zDataParser.read_cstringunknownc              
   C   sL   |dkr| j d| d| d| | d S |dk r$td| dd S )Nr   z	skipping z bytes (z): zinvalid skip of rM  )r  r   rP  rI  )r&   rN  descriptionr+   r+   r,   skip|  s
   (zDataParser.skipc                 C   s   |  || j | d S rD   )rf  r   )r&   offsetre  r+   r+   r,   skip_to     zDataParser.skip_toc                 C   s   |  t| j| d S rD   )rh  r   rK  )r&   re  r+   r+   r,   skip_to_end  ri  zDataParser.skip_to_endNrB   )rd  )r2   r3   r4   r  rP  rS  r\  r_  rc  rf  rh  rj  r+   r+   r+   r,   rJ  V  s    



	
rJ  c              	   C   s.   t tjdddddtjjdtj| d  S )Ni  r   r   )tzinfo)seconds)r   dtdatetimetimezoneutc	timedelta	timestamp)rr  r+   r+   r,   _mac_absolute_time_to_posix  s   .rs  c                    sB   t | |  dd  jdd} fddt|D }| jfS )Ns   cookzdatabase signatureTrZ  c                    s   g | ]} j d dqS )Trt  r\  rl   rE   pr+   r,   rm         z0_parse_safari_cookies_header.<locals>.<listcomp>)rJ  rS  r\  ranger   )rL  r7   number_of_pages
page_sizesr+   rw  r,   _parse_safari_cookies_header  s
   

r}  c           	   	      s   t | |  dd   } fddt|D }|dkr+|dt|  d d S  |d d t|3}t|D ]&\}}|	d	|d
d|d
  |d t
| |d  ||} | q<W d    n1 smw   Y   d d S )Ns      zpage signaturec                    s   g | ]}   qS r+   ru  rv  rw  r+   r,   rm     r|   z._parse_safari_cookies_page.<locals>.<listcomp>r   za cookies page of size z has no cookieszunknown page header fieldr   r   r   zspace between recordszspace in between pages)rJ  rS  r\  rz  r   r   rh  rI   r   r1   _parse_safari_cookies_recordrP  rj  )	rL  rb   r7   number_of_cookiesrecord_offsetsrA   r   record_offsetrecord_lengthr+   rw  r,   _parse_safari_cookies_page  s"   

r  c                 C   s  t | |}| }|dd | }t|d@ }|dd | }| }| }	| }
|dd t| }t| }z&|| | }|| | }||	 | }||
 | }W n tyy   |j	ddd	 | Y S w ||d
 t
jjdi ddd|d|dd ddd|dt|d|dd|dt|d|d|dddd dd di }|| |S )NrU  zunknown record field 1r   zunknown record field 2r^  zunknown record field 3z;failed to parse Safari cookie because UTF-8 decoding failedTr/  zspace at the end of the recordr   r   ru   r   r   r   Fr   r   r   r   rj   r   r   r   r   r   r   r   r+   )rJ  r\  rf  r   rs  r_  rh  rc  UnicodeDecodeErrorr%   r   r   r   r   r   )rL  rb   r7   rx  record_sizeflagsr   domain_offsetname_offsetpath_offsetvalue_offsetexpiration_date_creation_dater   ru   rj   r   r   r+   r+   r,   r~    s|   






r~  c                 C   sX   |du rt  }t| |\}}t| |d |}|D ]}t|||| q|d |S )a9  
    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
    Nfooter)rT   r}  rJ  r  rP  rj  )rL  rb   r7   r|  
body_startrx  	page_sizer+   r+   r,   rE    s   
rE  c                   @   s^   e Zd ZdZe Ze Ze Ze Ze Z	e Z
e Ze Ze Ze Ze Ze Ze ZdS )_LinuxDesktopEnvironmentzu
    https://chromium.googlesource.com/chromium/src/+/refs/heads/main/base/nix/xdg_util.h
    DesktopEnvironment
    N)r2   r3   r4   r  r   OTHERCINNAMONDEEPINGNOMEKDE3KDE4KDE5KDE6PANTHEONUKUIUNITYXFCELXQTr+   r+   r+   r,   r    s    
r  c                   @   s.   e Zd ZdZe Ze Ze Ze Ze Z	dS )_LinuxKeyringz
    https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/key_storage_util_linux.h
    SelectedLinuxBackend
    N)
r2   r3   r4   r  r   KWALLETKWALLET5KWALLET6GNOMEKEYRING	BASICTEXTr+   r+   r+   r,   r    s    
r  c                 C   s  |  dd}|  dd}|durttj|dD ]}|dkr-d|v r(tj  S tj  S |dkr6tj  S |d	kr?tj  S |d
krHtj	  S |dkr{|  dd}|dkr[tj
  S |dkrdtj  S |dkrmtj  S |d| d tj  S |dkrtj  S |dkrtj  S |dkrtj  S |dkrtj  S q|d| d |dkrtjS |dv rtjS |dv rtjS |dkrd| v rtjS tjS d|v s|dkrtjS |dkrtjS |d| d d | v rtjS d!| v rd| v rtjS tjS tjS )"zy
    https://chromium.googlesource.com/chromium/src/+/refs/heads/main/base/nix/xdg_util.cc
    GetDesktopEnvironment
    XDG_CURRENT_DESKTOPNDESKTOP_SESSIONr   :Unityzgnome-fallbackDeepinr  z
X-CinnamonKDEKDE_SESSION_VERSION564zunknown KDE version: "z". Assuming KDE4Pantheonr  r  LXQtz1XDG_CURRENT_DESKTOP is set to an unknown value: "ro   deepin)mategnome)kde4z
kde-plasmakdexfcexubuntuukuiz-DESKTOP_SESSION is set to an unknown value: "GNOME_DESKTOP_SESSION_IDKDE_FULL_SESSION)r;   r   strstripsplitr  r  r  r  r  r  r  r  r   r  r  r  r  r   r  r  )envr7   xdg_current_desktopdesktop_sessionpartkde_versionr+   r+   r,   _get_linux_desktop_environment  sp   












r  c                 C   s   t tj| }| d|j  |tjkrtj}|S |tj	kr#tj
}|S |tjkr-tj}|S |tjtjtjfv r<tj}|S tj}|S )aG  
    SelectBackend in [1]

    There is currently support for forcing chromium to use BASIC_TEXT by creating a file called
    `Disable Local Encryption` [1] in the user data dir. The function to write this file (`WriteBackendUse()` [1])
    does not appear to be called anywhere other than in tests, so the user would have to create this file manually
    and so would be aware enough to tell yt-dlp to use the BASIC_TEXT keyring.

    References:
        - [1] https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/key_storage_util_linux.cc
    zdetected desktop environment: )r  rU   environr   ru   r  r  r  r  r  r  r  r  r  r  r  r  r  )r7   desktop_environmentlinux_keyringr+   r+   r,   _choose_linux_keyringM  s$   

	
r  c           	   
   C   s   d}zS| t jkrd}d}n| t jkrd}d}n| t jkr!d}d}nt| tjdd	d
d| |dgdtjtj	d\}}}|rF|
d |W S |d|  d | W S  tyq } z|
d|  |W  Y d}~S d}~ww )ag   The name of the wallet used to store network passwords.

    https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/kwallet_dbus.cc
    KWalletDBus::NetworkWallet
    which does a dbus call to the following function:
    https://api.kde.org/frameworks/kwallet/html/classKWallet_1_1Wallet.html
    Wallet::NetworkWallet
    	kdewalletzorg.kde.kwalletdz/modules/kwalletdzorg.kde.kwalletd5z/modules/kwalletd5zorg.kde.kwalletd6z/modules/kwalletd6z	dbus-sendz	--sessionz--print-reply=literalz--dest=zorg.kde.KWallet.networkWalletT)textstdoutstderrzfailed to read NetworkWalletzNetworkWallet = "ro   z)exception while obtaining NetworkWallet: N)r  r  r  r  rh   r   run
subprocessPIPEDEVNULLr%   r   r  rZ   )	rO   r7   default_walletservice_namewallet_pathr  rE   
returncodeer+   r+   r,   _get_kwallet_network_walletj  s<   	





r  c              
   C   s   | d|j  tdd u r|d dS t||}zAtjdd|  dd|  d|gtj	tj
d	\}}}|rD|d
| d W dS | drS| d W dS | d |dW S  tyz } z|dt|  W Y d }~dS d }~ww )Nz,using kwallet-query to obtain password from zkwallet-queryzkwallet-query command not found. KWallet and kwallet-query must be installed to read from KWallet. kwallet-query should beincluded in the kwallet package for your distributionr  z--read-password Safe Storagez--folderz Keysr  r  z&kwallet-query failed with return code z7. Please consult the kwallet-query man page for detailss   failed to readz@failed to read password from kwallet. Using empty string insteadzpassword found   
z!exception running kwallet-query: )r   ru   shutilwhichr=   r  r   r  r  r  r  lowerr   rstriprZ   r%   r   )r  rO   r7   network_walletr  rE   r  r  r+   r+   r,   _get_kwallet_password  s6   




	
r  c                 C   s   t s|dt  dS tt  1}t |}| D ]}| |  dkr5|	   W  d    S q|d 	 W d    dS 1 sGw   Y  d S )Nzsecretstorage not available r  r  zfailed to read from keyring)
r	   r=   r   r   r   	dbus_initget_default_collectionget_all_items	get_label
get_secret)r  r7   concolitemr+   r+   r,   _get_gnome_keyring_password  s   


$r  c                 C   sv   |rt | nt|}|d|j  |t jt jt jfv r#t| ||S |t jkr-t	| |S |t j
kr4d S J d| )NzChosen keyring: FzUnknown keyring )r  r  r   ru   r  r  r  r  r  r  r  )r  rO   r7   r+   r+   r,   r    s   


r  c              
   C   s   | d z'tjdddd| d|  dgtjtjd\}}}|r'|d	 W d S |d
W S  tyI } z|dt	|  W Y d }~d S d }~ww )Nz@using find-generic-password to obtain password from OSX keychainsecurityzfind-generic-passwordz-wz-az-sr  r  zfind-generic-password failedr  z)exception running find-generic-password: )
r   r   r  r  r  r  r%   r  rZ   r   )r  r7   r  rE   r  r  r+   r+   r,   r7    s&   


r7  c                 C   s   t t| d|}|du r|d dS |d| d t|dd}t|}W d   n1 s2w   Y  z|d d	 }W n tyN   |d
 Y dS w t	|}d}|
|sb|d dS t|t|d |S )z
    References:
        - [1] https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/os_crypt_win.cc
    zLocal StateNzcould not find local state filezFound local state file at "ro   rq   rr   os_cryptencrypted_keyzno encrypted key in Local States   DPAPIzinvalid key)r   r   r=   r   r   r   rX   KeyErrorbase64	b64decoder   r<  r   )r  r7   rj   rG  rL  
base64_keyr  r   r+   r+   r,   r9    s(   




r9  c                 C   s   t d| |||S )Nsha1)hashlibpbkdf2_hmac)r  r#  r$  r%  r+   r+   r,   r'       r'                     Fc              	   C   sf   |D ]'}t t| ||}z|r|dd   W   S | W   S  ty)   Y qw |jddd d S )N    z\failed to decrypt cookie (AES-CBC) because UTF-8 decoding failed. Possibly the key is wrong?Tr/  )r   r   r  r  r%   )r2  keysr7   initialization_vectorr.  key	plaintextr+   r+   r,   r0    s   r0  c                 C   sz   z	t | |||}W n ty   |jddd Y d S w z|r'|dd   W S | W S  ty<   |jddd Y d S w )Nz[failed to decrypt cookie (AES-GCM) because the MAC check failed. Possibly the key is wrong?Tr/  r  z\failed to decrypt cookie (AES-GCM) because UTF-8 decoding failed. Possibly the key is wrong?)r   rh   r%   r  r  )r2  r  r@  rA  r7   r.  r  r+   r+   r,   r;  !  s   
r;  c           	         s   ddl  ddl G  fddd j} | }| ||}| } jj |ddddd |}|sCd}|	| t
| |j|j} jj|j |S )zt
    References:
        - https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata
    r   Nc                       s(   e Zd Zd jjfd  jfgZdS )z)_decrypt_windows_dpapi.<locals>.DATA_BLOBcbDatapbDataN)r2   r3   r4   wintypesDWORDPOINTERc_char_fields_r+   ctypesr+   r,   	DATA_BLOB:  s    
r  z_Failed to decrypt with DPAPI. See  https://github.com/yt-dlp/yt-dlp/issues/10927  for more info)r   ctypes.wintypes	Structurecreate_string_buffersizeofwindllcrypt32CryptUnprotectDatabyrefr=   r   	string_atr  r  kernel32	LocalFree)	r2  r7   r  ra  blob_inblob_outretr'   resultr+   r  r,   r<  1  s,   
	
r<  c                   C   s   t jdt jdS )NXDG_CONFIG_HOMEz	~/.config)rU   r  r;   rj   r   r+   r+   r+   r,   r   T  ri  r   c                 C   s,   t j|d}t| | t|}| S )Nztemporary.sqlite)rU   rj   rk   r  r   r
   connectr   )database_pathr   database_copy_pathconnr+   r+   r,   r   X  s   
r   c                 C   s$   |  d| d }dd |D S )NzPRAGMA table_info(rQ  c                 S   s   g | ]}|d    qS )r   )r  )rl   rowr+   r+   r,   rm   b  ry  z%_get_column_names.<locals>.<listcomp>)r   r   )r   
table_name
table_infor+   r+   r,   r   `  s   r   c                 C   s   t | dd d dS )Nc                 S   s   t | jS rD   )rU   lstatst_mtime)rj   r+   r+   r,   rF   f  s    z_newest.<locals>.<lambda>)r  default)max)filesr+   r+   r,   r   e  r  r   c           	   
   c   s    d}t |6}t| D ]'\}}}|D ]}|d7 }|d| d|dd ||kr3tj||V  qqW d    d S 1 s@w   Y  d S )Nr   r   zSearching for "z": r   z files searched)rI   rU   walkr1   rj   rk   )	r   filenamer7   r   rA   	curr_rootrE   r  r@   r+   r+   r,   r   i  s   
"r   c                 C   s:   t  }| D ]}|D ]}|| q	|jd ur|j|_q|S rD   )rT   r   r  )jars
output_jarrb   r   r+   r+   r,   rY   u  s   
rY   c                    s"   t  fddtjjtjjfD S )Nc                 3   s    | ]	}|r| v V  qd S rD   r+   )rl   sepr   r+   r,   r~     s    z_is_path.<locals>.<genexpr>)anyrU   rj   r#  altsepr$  r+   r$  r,   r     s   "r   c                 C   s`   | t vrtd|  d|d gtR vrtd| d|d ur*tt|r*t|}| |||fS )Nzunsupported browser: "ro   zunsupported keyring: ")SUPPORTED_BROWSERSrh   SUPPORTED_KEYRINGSr   r   )r_   r`   rO   rP   r+   r+   r,   rQ     s   rQ   c                       s   e Zd ZdZded Zeed Zede dej	Z
h dZdd	hZed
e d ej	ejB ZedZ fddZ  ZS )LenientSimpleCookiez1More lenient version of http.cookies.SimpleCookiez\w\dz!#$%&'*+-.:^_`|~z(),/<=>?@[]{}[z]+>	   max-agerj   r   r   r   r   r   httponlysamesiter   r,  a>  
        [ ]*                           # Optional whitespace at start of cookie
        (?P<key>                       # Start of group 'key'
        [^ =;]+                        # Match almost anything here for now and validate later
        )                              # End of group 'key'
        (                              # Optional group: there may not be a value.
        [ ]*=[ ]*                        # Equal Sign
        (                                # Start of potential value
        (?P<val>                           # Start of group 'val'
        "(?:[^\\"]|\\.)*"                    # Any doublequoted string
        |                                    # or
        \w{3},\ [\w\d -]{9,11}\ [\d:]{8}\ GMT  # Special case for "expires" attr
        |                                    # or
        [a  ]*     # Any word or empty string
        )                                  # End of group 'val'
        |                                  # or
        (?P<bad>(?:\\;|[^;])*?)            # 'bad' group fallback for invalid values
        )                                # End of potential value
        )?                             # End of optional value group
        [ ]*                            # Any number of spaces.
        ([ ]+|;|$)                      # Ending either at space, semicolon, or EOS.
        z[\x00-\x1F\x7F]c                    sR  t |tst |S d }| j|D ]}|drd }q|dd\}}| j|s.d }qd}|	dr=|dd  }d}|
 }|| jv rv|d u rKq|d u rZ|| jvrWd }qd}n| |\}}| j|rq| |jd  d }q|||< q|r{d }q|d ur| |tj }| |\}	}
| j|	rd }q|||	|
 || |< qd }qd S )Nbadr  valF$r   T)r   r  r$   rX   _COOKIE_PATTERNfinditerry   _LEGAL_KEY_RErx   r   r  	_RESERVED_FLAGSvalue_decode_CONTROL_CHARACTER_REsearchpopr  r;   r   r   Morselset)r&   rL  morselmatchr  r   is_attribute	lower_keyrE   
real_valuecoded_valuer)   r+   r,   rX     sT   






zLenientSimpleCookie.load)r2   r3   r4   r  rw   escape_LEGAL_KEY_CHARS_LEGAL_VALUE_CHARScompileASCIIr3  r4  r5  VERBOSEr1  r7  rX   rC   r+   r+   r)   r,   r)    s     

r)  c                       s   e Zd ZdZdZdZdZeddZ	d fdd		Z
ed
d ZejddddZdd ZdddZdddZdd Zdd Z fddZ  ZS )rT   z]
    See [1] for cookie file format.

    1. https://curl.haxx.se/docs/http-cookies.html
    z
#HttpOnly_   zO# Netscape HTTP Cookie File
# This file is generated by yt-dlp.  Do not edit.

CookieFileEntry)domain_nameinclude_subdomainsrj   
https_only
expires_atru   r   Nc                    s6   t  jd g|R i | t|rt|}|| _d S rD   )r$   r  r   rU   fspathr  )r&   r  argskwargsr)   r+   r,   r    s   

zYoutubeDLCookieJar.__init__c                 C   s   | rdS dS )NTRUEFALSEr+   )cndnr+   r+   r,   _true_or_false  s   z!YoutubeDLCookieJar._true_or_falseFwritec                c   sd    t |r&t||rdnddd}|V  W d    d S 1 sw   Y  d S |r-|d |V  d S )Nwrzutf-8rr   r   )r   r   truncate)r&   r@   rV  rG  r+   r+   r,   r     s   "

zYoutubeDLCookieJar.openc                 C   s   t   }| D ]C}|s|js|s||rq|j|j}}|d u r%d|}}|dd|j| 	|j
d|j| 	|jt|jdd||f qd S )Nr   z{}
	r   )r  )r-   r   
is_expiredru   r   rV  formatrk   r   rT  r   rj   r   r   r   )r&   rG  ignore_discardignore_expiresnowr   ru   r   r+   r+   r,   _really_save   s(   


zYoutubeDLCookieJar._really_saveTc                 C   s   |du r| j dur| j }nttjj| D ]
}|jdu rd|_q| j|dd}|| j | 	||| W d   dS 1 s@w   Y  dS )z
        Save cookies to a file.
        Code is taken from CPython 3.6
        https://github.com/python/cpython/blob/8d999cbf4adea053be6dbb612b9844635c4dfb8e/Lib/http/cookiejar.py#L2091-L2117 Nr   TrU  )
r  rh   r   r   MISSING_FILENAME_TEXTr   r   rV  _HEADERr`  )r&   r  r]  r^  r   rG  r+   r+   r,   save5  s   

"zYoutubeDLCookieJar.savec           
         s  |du r j dur j }nttjj fdd}t } |F}|D ];}z	||| W q% tjj	y` } z"|
  dd dv rKtj	dtd| d	|d
 W Y d}~q%d}~ww W d   n1 skw   Y  |d  ||||  D ]}	|	jdkrd|	_d|	_qdS )zLoad cookies from a file.Nc                    s   |   jr| t jd  } |  ds|  s| S | d}t| jkr1tjdt|  j	| }|j
rJtd|j
sJtjd|j
 | S )N#rZ  zinvalid length z[0-9]+(?:\.[0-9]+)?zinvalid expires at )r   _HTTPONLY_PREFIXr   r  r  
_ENTRY_LENr   r   	LoadError_CookieFileEntryrM  rw   rx   )r   cookie_listr   r&   r+   r,   prepare_lineR  s   

z-YoutubeDLCookieJar.load.<locals>.prepare_line r   z[{"zCookies file must be Netscape formatted, not JSON. See  https://github.com/yt-dlp/yt-dlp/wiki/FAQ#how-do-i-pass-cookies-to-yt-dlpz+WARNING: skipping cookie file entry due to z: 
T)r  rh   r   r   ra  ioStringIOr   rV  rg  r  r   seek_really_loadr   r   )
r&   r  r]  r^  rk  cfrG  r   r  r   r+   rj  r,   rX   J  s:   



zYoutubeDLCookieJar.loadc                 C   s(   t jtt|}| | |dS )z-Generate a Cookie HTTP header for a given urlr   )urllibrequestRequestr   r   add_cookie_header
get_header)r&   url
cookie_reqr+   r+   r,   get_cookie_header}  s   

z$YoutubeDLCookieJar.get_cookie_headerc                 C   s0   t t  | j_| _| tjtt	|S )z1Generate a list of Cookie objects for a given url)
r   r-   _policy_now_cookies_for_requestrs  rt  ru  r   r   )r&   rx  r+   r+   r,   get_cookies_for_url  s   z&YoutubeDLCookieJar.get_cookies_for_urlc                    s@   t t t j|i |W  d    S 1 sw   Y  d S rD   )r   suppressr  r$   clear)r&   rO  rP  r)   r+   r,   r    s   $zYoutubeDLCookieJar.clearrD   )NTT)r2   r3   r4   r  re  rf  rb  collections
namedtuplerh  r  r5  rT  r   contextmanagerr   r`  rc  rX   rz  r~  r  rC   r+   r+   r)   r,   rT     s(    
	

3rT   )r  FrB   )NNN)nr  r  r   rn  rm  r3  r   r  http.cookiejarr   http.cookiesrn  r   rU   rw   r  rW  r  r   r   r-   urllib.requestrs  enumr   r   aesr   r   r   dependenciesr   r	   r
   
minicursesr   r   utilsr   r   r   r   r   r   r   r   r   r   utils._utilsr   utils.networkingr   rf   r'  r"   rI   rK   rc   rS   rd   r   r   r   rg   r   r	  r   r  r  r  re   rZ   rI  rJ  rs  r}  r  r~  rE  r  r  __members__r  r(  r  r  r  r  r  r  r7  r9  r'  r0  r;  r<  r   r   r   r   r   rY   r   rQ   r   SimpleCookier)  r   MozillaCookieJarrT   r+   r+   r+   r,   <module>   s    0
L<N"8"(3*
F)+

#


o