U
    Mf                     @   sZ  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 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/m0Z0 dd	l1m2Z2 dd
l3m4Z4 dddddddhZ5e5ddhB Z6G dd de2Z7dd Z8dd Z9de7 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-ZBG d.d/ d/eAZCG d0d1 d1eAZDG d2d3 d3eAZEd4d5 ZFG d6d7 d7eGZHG d8d9 d9ZId:d; ZJd<d= ZKd>d? ZLd@dA ZMde7 fdBdCZNG dDdE dEeZOG dFdG dGeZPePjQR ZSdHdI ZTdJdK ZUdLdM ZVdNdO ZWdPdQ ZXdRdS ZYdTdU ZZdVdW Z[dXdY Z\dud[d\Z]d]d^ Z^d_d` Z_dadb Z`dcdd Zadedf Zbdgdh Zcdidj Zddkdl Zedmdn ZfdvdodpZgG dqdr dre	jhjiZjG dsdt dte	jkjlZmdS )w    N)Enumauto   )aes_cbc_decrypt_bytes aes_gcm_decrypt_and_verify_bytesunpad_pkcs7)compat_os_name)!_SECRETSTORAGE_UNAVAILABLE_REASONsecretstoragesqlite3)MultilinePrinterQuietMultilinePrinter)	DownloadErrorPopenerror_to_strexpand_pathis_path_likesanitize_urlstr_or_nonetry_callwrite_string)
_YDLLogger)normalize_urlbravechromechromiumedgeoperavivaldiwhale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__ 2/tmp/pip-unpacked-wheel-zk9bgjdq/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   s4   t   | j | jkr0| d| d t   | _d S )Nz
[Cookies] r   )time_timer_DELAYZprint_at_line)r&   r'   r+   r+   r,   print<   s    zYDLLogger.ProgressBar.printN)__name__
__module____qualname__r/   r.   r0   r+   r+   r+   r,   ProgressBar9   s   r4   c                 C   sh   | j r"| j jds"| j jdr&dS | j jj}z| s@W dS W n tk
rX   Y dS X | j|ddS )z8Return a context manager with a print method. (Optional)Z
noprogressloggerNF)Zpreserve_output)Z_ydlparamsgetZ
_out_fileserrorisattyBaseExceptionr4   )r&   filer+   r+   r,   progress_barA   s    "

zYDLLogger.progress_bar)F)r1   r2   r3   r%   r   r4   r<   __classcell__r+   r+   r)   r,   r"   5   s   r"   c                 C   s.   t | dr|  }|r|S t }dd |_|S )Nr<   c                 S   s   d S Nr+   )_r+   r+   r,   <lambda>U       z&_create_progress_bar.<locals>.<lambda>)hasattrr<   r   r0   )r5   printerr+   r+   r,   _create_progress_barO   s    

rD   c           
   	   C   s   g }|d k	r8t | \}}}}|t||t|||d | d k	rt| }|rTt| } t| }	|rnt| tj	rv|	
  ||	 t|S )Nkeyring	container)_parse_browser_specificationappendextract_cookies_from_browserr"   r   r   YoutubeDLCookieJarosaccessR_OKload_merge_cookie_jars)
Zcookie_fileZbrowser_specificationZydlZcookie_jarsbrowser_nameprofilerF   rG   is_filenamejarr+   r+   r,   load_cookiesY   s    
rU   rE   c                C   sN   | dkrt |||S | dkr&t||S | tkr<t| |||S td|  d S )Nr    r!   zunknown browser: )_extract_firefox_cookies_extract_safari_cookiesCHROMIUM_BASED_BROWSERS_extract_chrome_cookies
ValueError)rQ   rR   r5   rF   rG   r+   r+   r,   rJ   m   s    
rJ   c                    s  | d ts|d t S d kr2tt }n$trBg}nfddt D }dtt	|}t
t|}|d krtd| |d| d d } d	krDtjtj|d
}tj|rt|tjstd| t|dd}t|dg }	W 5 Q R X t fdd|	D d }t|tsDtd  dtjddl}
d }zHt ||
}t|tr|d  d|  |!dd| d| df n* dkr|d |!d n
|!d t }t"|}|# }t$|}t%|D ]t\}\}}}}}}|&d|dd |d t'j(j)d!||d d"|t*||+d#|t*|||d"d d i d$}|,| qW 5 Q R X | d%t$| d& |W W  5 Q R  S |d k	r|j  X W 5 Q R X d S )'Nz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+   )rL   pathjoin).0r[   )rR   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   s6   | ].   d t fddfkr  dV  qdS )namec                      s   t d d  S )NzuserContext([^\.]+)\.labelZl10nID)re	fullmatchgroupr+   contextr+   r,   r@      rA   z4_extract_firefox_cookies.<locals>.<genexpr>.<lambda>ZuserContextIdN)r7   r   )r]   )rG   rj   r,   	<genexpr>   s      z+_extract_firefox_cookies.<locals>.<genexpr>z"could not find firefox container "z" in containers.jsonyt_dlpprefixz-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&%ra   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/r   F.versionrf   valueportport_specifieddomaindomain_specifieddomain_initial_dotr[   path_specifiedsecureexpiresdiscardcommentcomment_urlrest
Extracted z cookies from firefox)-infor   r%   rK   list_firefox_browser_dirs_is_pathr\   maprepr_newest_firefox_cookie_dbsFileNotFoundErrordebugrL   r[   dirnameisfilerM   rN   openjsonrO   r7   next
isinstanceintrZ   tempfileTemporaryDirectory
connectionclose_open_database_copyexecuterD   fetchalllen	enumerater0   http	cookiejarCookiebool
startswith
set_cookie)rR   rG   r5   Zsearch_rootssearch_rootcookie_database_pathZcontainer_idZcontainers_pathZ
containersre   tmpdircursorrT   r<   tabletotal_cookie_countihostrf   rv   r[   Zexpiry	is_securecookier+   )rG   rR   r,   rV   x   s    







            
rV   c                   c   sL   t jdkrtjdV  n.t jdkr4tjdV  nttjjdE d H  d S )Ncygwinwin32z"%APPDATA%\Mozilla\Firefox\Profilesdarwinz.~/Library/Application Support/Firefox/Profiles)z~/.mozilla/firefoxz&~/snap/firefox/common/.mozilla/firefoxz/~/.var/app/org.mozilla.firefox/.mozilla/firefox)sysplatformrL   r[   
expandvars
expanduserr   r+   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   rL   r[   abspathglobiglobr\   )rootsrootpatternr+   r+   r,   r      s    r   c              
   C   s  t jdkrt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|  }nt jdkrtjd}tj|dtj|dtj|dtj|dtj|dtj|dtj|dd|  }ndt }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rrdndt jdkrdndt jdkrdnddd|  }dh}||| |k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/ChromeZChromiumzMicrosoft Edgezcom.operasoftware.OperaZVivaldizNaver/Whalezgoogle-chromer   zmicrosoft-edger   r   znaver-whaleZBraveZChromeZOperaZWhale)browser_dirkeyring_namesupports_profiles)r   r   rL   r[   r   r\   r   _config_home)rQ   Zappdata_localZappdata_roamingr   Zappdataconfigr   Zbrowsers_without_profilesr+   r+   r,   $_get_chromium_based_browser_settings   sf    



r   c                 C   s  | d|   ts,|d|  d t S t| }|d krF|d }n^t|rp|}|d rftj|n||d< n4|d rtj	|d |}n|
|  d |d }tt|d|}|d krtd|  d	| d
|d| d
 t|d |d ||d}tjdd}d }	zzPt||}	t|	j_t|	d}
d|
krBdnd}|	d| d t }d}d}t|}|	 }t|}t|D ]b\}}|d|dd|d t|f| \}}|s|d7 }qn|s|d7 }|| qW 5 Q R X |dkrd| d}nd}| dt| d|  |  |j ! }||d< |d |  |W W dW  5 Q R  S  t"k
r } z2t#d!kr|j$d"krd#}|
| t%| W 5 d }~X Y nX W 5 |	d k	r|	j  X W 5 Q R X 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 profilesZCookieszcould not find z cookies database in "r`   r_   r   rF   rm   rn   cookiesr   r}   zBSELECT host_key, name, value, encrypted_value, path, expires_utc, z FROM cookiesr   rp   rq   rr   r    (z could not be decrypted)r   r   z cookies from Z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%   rK   r   r   rL   r[   r   r\   r8   r   _find_filesr   r   get_cookie_decryptorr   r   r   r   r   bytesZtext_factory_get_column_namesr   rD   r   r   r   r0   _process_chrome_cookier   _cookie_countscopyPermissionErrorr   errnor   )rQ   rR   rF   r5   r   r   r   	decryptorr   r   Zcolumn_namesZsecure_columnrT   Zfailed_cookiesZunencrypted_cookiesr<   r   r   r   lineis_encryptedr   Zfailed_messagecountsr8   r'   r+   r+   r,   rY     st    







rY   c           	      C   s   |  }|  }|  }|  }| o(|}|rH| |}|d krH|d fS |sPd }|tjjd||d d|t||d|t|||dd d i dfS )Nr   Frs   rt   )decodedecryptr   r   r   r   r   )	r   Zhost_keyrf   rv   encrypted_valuer[   Zexpires_utcr   r   r+   r+   r,   r   V  s:    

            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d S )Nz"Must be implemented by sub classes)NotImplementedError)r&   r   r+   r+   r,   r     s    zChromeCookieDecryptor.decryptN)r1   r2   r3   __doc__r   r   r+   r+   r+   r,   r   n  s   r   r   c                C   s6   t jdkrt||S t jdkr(t| |S t|||dS )Nr   )r   r   r   )r   r   MacChromeCookieDecryptorWindowsChromeCookieDecryptorLinuxChromeCookieDecryptor)browser_rootbrowser_keyring_namer5   rF   r+   r+   r,   r     s
    



r   c                   @   s<   e Zd ZddddZejdd Zedd Zd	d
 Z	dS )r   Nr   c                C   s<   || _ | d| _| d| _dddd| _|| _|| _d S )Ns   peanutsrA   r   )v10v11other)_logger
derive_key_v10_key
_empty_keyr   _browser_keyring_name_keyring)r&   r   r5   rF   r+   r+   r,   __init__  s    z#LinuxChromeCookieDecryptor.__init__c                 C   s(   t | j| j| j}|d krd S | |S r>   )_get_linux_keyring_passwordr   r   r   r   )r&   passwordr+   r+   r,   _v11_key  s    z#LinuxChromeCookieDecryptor._v11_keyc                 C   s   t | ddddS )N	   saltysaltr      salt
iterations
key_lengthpbkdf2_sha1r   r+   r+   r,   r     s    z%LinuxChromeCookieDecryptor.derive_keyc                 C   s   |dd }|dd }|dkrH| j d  d7  < t|| j| jf| jS |dkr| j d  d7  < | jdkr| jjdd	d
 dS t|| j| jf| jS | jjd| dd	d
 | j d  d7  < dS 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   s   v11r   z(cannot decrypt v11 cookies: no key foundTr(   zunknown cookie version: "r`   r   )r   _decrypt_aes_cbc_multir   r   r   r   r%   r&   r   ru   
ciphertextr+   r+   r,   r     s    
z"LinuxChromeCookieDecryptor.decrypt)
r1   r2   r3   r   	functoolscached_propertyr   staticmethodr   r   r+   r+   r+   r,   r     s   

r   c                   @   s(   e Zd Zdd Zedd Zdd ZdS )r   c                 C   s8   || _ t||}|d krd n| || _ddd| _d S Nr   )r   r   )r   _get_mac_keyring_passwordr   r   r   )r&   r   r5   r   r+   r+   r,   r     s    
z!MacChromeCookieDecryptor.__init__c                 C   s   t | ddddS )Nr   i  r   r   r   r   r+   r+   r,   r     s    z#MacChromeCookieDecryptor.derive_keyc                 C   s|   |d d }|dd  }|dkrb| j d  d7  < | jd krP| jjddd d S t|| jf| jS | j d  d7  < |S d S )	Nr   r   r   r   (cannot decrypt v10 cookies: no key foundTr   r   )r   r   r   r%   r   r   r+   r+   r,   r     s    
z MacChromeCookieDecryptor.decryptN)r1   r2   r3   r   r   r   r   r+   r+   r+   r,   r     s   
r   c                   @   s   e Zd Zdd Zdd ZdS )r   c                 C   s"   || _ t||| _ddd| _d S r   )r   _get_windows_v10_keyr   r   )r&   r   r5   r+   r+   r,   r     s    z%WindowsChromeCookieDecryptor.__init__c           	      C   s   |d d }|dd  }|dkr| j d  d7  < | jd krP| jjddd d S d}d	}|}|d | }|||  }|| d  }t|| j||| jS | j d
  d7  < t|| j S d S )Nr   r   r   r   r  Tr      r   r   )r   r   r   r%   _decrypt_aes_gcm_decrypt_windows_dpapir   )	r&   r   ru   r   Znonce_lengthZauthentication_tag_lengthZraw_ciphertextnonceauthentication_tagr+   r+   r,   r     s     
z$WindowsChromeCookieDecryptor.decryptN)r1   r2   r3   r   r   r+   r+   r+   r,   r     s   r   c              	   C   s   t jdkrtdt j | r@tj| }tj|stdnBtjd}tj|s|d tjd}tj|stdt	|d}|
 }W 5 Q R X t||d	}|d
t| d |S )Nr   z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)r5   r   z cookies from safari)r   r   rZ   rL   r[   r   r   r   r   r   readparse_safari_cookiesr   r   )rR   r5   Zcookies_pathfZcookies_datarT   r+   r+   r,   rW     s"    


rW   c                   @   s   e Zd ZdS )ParserErrorN)r1   r2   r3   r+   r+   r+   r,   r  *  s   r  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&   datar5   r+   r+   r,   r   /  s    zDataParser.__init__c                 C   sR   |dk rt d| d| j| }|t| jkr8t d| j| j| }|| _|S )Nr   zinvalid read of  byteszreached end of input)r  r   r   r  )r&   	num_bytesendr  r+   r+   r,   
read_bytes4  s    
zDataParser.read_bytesc                 C   s6   |  t|}||kr2td| d| d| dd S )Nzunexpected value: z != r   ))r  r   r  )r&   Zexpected_valuer'   rv   r+   r+   r,   expect_bytes>  s    zDataParser.expect_bytesFc                 C   s"   |rdnd}t || dd S )Nz>Iz<I   r   structunpackr  r&   
big_endianZdata_formatr+   r+   r,   	read_uintC  s    zDataParser.read_uintc                 C   s"   |rdnd}t || dd S )Nz>dz<d   r   r  r  r+   r+   r,   read_doubleG  s    zDataParser.read_doublec                 C   s4   g }|  d}|dkr$d| S || qd S )Nr       rA   )r  r\   r   rI   )r&   buffercr+   r+   r,   read_cstringK  s
    
zDataParser.read_cstringunknownc              
   C   sJ   |dkr.| j d| d| d| | n|dk rFtd| dd S )Nr   z	skipping z bytes (z): zinvalid skip of r  )r   r   r  r  )r&   r  descriptionr+   r+   r,   skipT  s    &zDataParser.skipc                 C   s   |  || j | d S r>   )r%  r   )r&   offsetr$  r+   r+   r,   skip_toZ  s    zDataParser.skip_toc                 C   s   |  t| j| d S r>   )r'  r   r  )r&   r$  r+   r+   r,   skip_to_end]  s    zDataParser.skip_to_endN)F)F)r#  )r#  )r#  )r1   r2   r3   r   r  r  r  r  r"  r%  r'  r(  r+   r+   r+   r,   r  .  s   


	

r  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)r0  r+   r+   r,   _mac_absolute_time_to_posixa  s    r1  c                    sB   t | |  dd  jdd} fddt|D }| jfS )Ns   cookzdatabase signatureTr  c                    s   g | ]} j d dqS )Tr2  r  r]   r?   pr+   r,   r^   i  s     z0_parse_safari_cookies_header.<locals>.<listcomp>)r  r  r  ranger   )r  r5   Znumber_of_pages
page_sizesr+   r5  r,   _parse_safari_cookies_headere  s
    
r9  c           	   	      s   t | |  dd   } fddt|D }|dkrV|dt|  d d S  |d d t|\}t|D ]L\}}|	d	|d
d|d
  |d t
| |d  ||} | qxW 5 Q R X  d d S )Ns      zpage signaturec                    s   g | ]}   qS r+   r3  r4  r5  r+   r,   r^   q  s     z._parse_safari_cookies_page.<locals>.<listcomp>r   za cookies page of size z has no cookieszunknown page header fieldrp   rq   rr   zspace between recordszspace in between pages)r  r  r  r7  r   r   r'  rD   r   r0   _parse_safari_cookies_recordr  r(  )	r  rT   r5   Znumber_of_cookiesZrecord_offsetsr<   r   Zrecord_offsetZrecord_lengthr+   r5  r,   _parse_safari_cookies_pagem  s    

r;  c                 C   sJ  t | |}| }|dd | }t|d@ }|dd | }| }| }	| }
|dd t| }t| }zL|| | }|| | }||	 | }||
 | }W n& tk
r   |j	ddd	 | Y S X ||d
 t
jjd||d d|t||d|t|||dd d i d}|| |S )Nr  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   Frs   rt   )r  r  r%  r   r1  r  r'  r"  UnicodeDecodeErrorr%   r   r   r   r   r   )r  rT   r5   r6  Zrecord_sizeflagsr   Zdomain_offsetZname_offsetZpath_offsetZvalue_offsetZexpiration_dateZ_creation_datery   rf   r[   rv   r   r+   r+   r,   r:    s\    





            
r:  c                 C   sX   |dkrt  }t| |\}}t| |d |}|D ]}t|||| q2|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)rK   r9  r  r;  r  r(  )r  rT   r5   r8  Z
body_startr6  Z	page_sizer+   r+   r,   r
    s    
r
  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)r1   r2   r3   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)
r1   r2   r3   r   r   KWALLETKWALLET5KWALLET6GNOMEKEYRING	BASICTEXTr+   r+   r+   r,   rM    s   rM  c                 C   s<  |  dd}|  dd}|dk	rlttj|dD ] }|dkrh|dk	r\d|kr\tj  S tj  S q4|dkrztj  S |dkrtj  S |d	krtj	  S |d
kr|  dd}|dkrtj
  S |dkrtj  S |dkrtj  S |d| d tj  S q4|dkrtj  S |dkr0tj  S |dkrDtj  S |dkr4tj  S q4|d| d n|dk	r|dkrtjS |dkrtjS |dkrtjS |dkrd| krtjS tjS n<d|ks|dkrtjS |dkrtjS |d| d n0d| krtjS d | kr6d| kr0tjS tjS tjS )!zy
    https://chromium.googlesource.com/chromium/src/+/refs/heads/main/base/nix/xdg_util.cc
    GetDesktopEnvironment
    ZXDG_CURRENT_DESKTOPNZDESKTOP_SESSION:ZUnityzgnome-fallbackZDeepinrC  z
X-CinnamonZKDEZKDE_SESSION_VERSION564zunknown KDE version: "z". Assuming KDE4ZPantheonrK  rI  ZLXQtz1XDG_CURRENT_DESKTOP is set to an unknown value: "r`   Zdeepin)ZmateZgnome)Zkde4z
kde-plasmaZkdeZxfceZxubuntuZukuiz-DESKTOP_SESSION is set to an unknown value: "ZGNOME_DESKTOP_SESSION_IDZKDE_FULL_SESSION)r7   r   strstripsplitr?  rC  rJ  rB  rA  rF  rG  rE  r   rH  rK  rI  rL  rD  r@  )envr5   Zxdg_current_desktopZdesktop_sessionpartZkde_versionr+   r+   r,   _get_linux_desktop_environment  sp    
























r\  c                 C   sz   t tj| }| d|j  |tjkr0tj}nF|tj	krBtj
}n4|tjkrTtj}n"|tjtjtjfkrptj}n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\  rL   environr   rf   r?  rE  rM  rN  rF  rO  rG  rP  rD  rL  r@  rR  rQ  )r5   Zdesktop_environmentZlinux_keyringr+   r+   r,   _choose_linux_keyring&  s     


  r^  c           	   
   C   s   d}z| t jkrd}d}n0| t jkr.d}d}n| t jkrBd}d}nt| tjdd	d
d| |dgdtjtj	d\}}}|r|
d |W S |d|  d | W S W n: tk
r } z|
d|  | W Y S d}~X Y nX dS )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
    Z	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 = "r`   z)exception while obtaining NetworkWallet: N)rM  rN  rO  rP  rZ   r   run
subprocessPIPEDEVNULLr%   r   rX  	Exception)	rF   r5   Zdefault_walletZservice_nameZwallet_pathr`  r?   
returncodeer+   r+   r,   _get_kwallet_network_walletC  s@    	


    
ri  c              
   C   s  | d|j  tdd kr.|d dS t||}ztjdd|  dd|  d|gtj	tj
d	\}}}|r|d
| d W dS | dr| d W dS | d |dW S W n> tk
 r } z|dt|  W Y dS d }~X Y nX d S )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 distributionrA   z--read-password Safe Storagez--folderz Keysr`  ra  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   rf   shutilwhichr8   ri  r   rb  rc  rd  re  lowerr   rstriprf  r%   r   )r   rF   r5   Znetwork_walletr`  r?   rg  rh  r+   r+   r,   _get_kwallet_passwordl  s8    

   
	
rq  c              
   C   s   t s|dt  dS tt  \}t |}| D ].}| |  dkr:|	   W  5 Q R  S q:|d W 5 Q R  dS Q R X d S )Nzsecretstorage not available rA   rj  zfailed to read from keyring)
r
   r8   r	   
contextlibclosingZ	dbus_initZget_default_collectionZget_all_itemsZ	get_labelZ
get_secret)r   r5   concolitemr+   r+   r,   _get_gnome_keyring_password  s    

rw  c                 C   s~   |rt | nt|}|d|j  |t jt jt jfkrFt| ||S |t jkrZt	| |S |t j
krhd S dsztd| d S )NzChosen keyring: FzUnknown keyring )rM  r^  r   rf   rN  rO  rP  rq  rQ  rw  rR  AssertionError)r   rF   r5   r+   r+   r,   r     s    


r   c              
   C   s   | d zNtjdddd| d|  dgtjtjd\}}}|rN|d	 W d S |d
W S  tk
r } z|dt	|  W Y d S d }~X Y nX d S )Nz@using find-generic-password to obtain password from OSX keychainsecurityzfind-generic-passwordz-wz-az-srj  rk  zfind-generic-password failedrl  z)exception running find-generic-password: )
r   r   rb  rc  rd  re  r%   rp  rf  r   )r   r5   r`  r?   rg  rh  r+   r+   r,   r     s(    
   
r   c              	   C   s   t t| d|}|dkr&|d dS |d| d t|dd}t|}W 5 Q R X z|d d	 }W n  tk
r   |d
 Y dS X t	|}d}|
|s|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 "r`   rb   rc   Zos_cryptencrypted_keyzno encrypted key in Local States   DPAPIzinvalid key)r   r   r8   r   r   r   rO   KeyErrorbase64	b64decoder   r  r   )r   r5   r[   r  r  Z
base64_keyrz  ro   r+   r+   r,   r    s$    




r  c                 C   s   t d| |||S )Nsha1)hashlibpbkdf2_hmac)r   r   r   r   r+   r+   r,   r     s    r                      c              	   C   sP   |D ]8}t t| ||}z| W   S  tk
r:   Y qX q|jddd d S )Nz\failed to decrypt cookie (AES-CBC) because UTF-8 decoding failed. Possibly the key is wrong?Tr   )r   r   r   r<  r%   )r   keysr5   Zinitialization_vectorkey	plaintextr+   r+   r,   r     s    r   c                 C   sl   zt | |||}W n$ tk
r6   |jddd Y d S X z
| W S  tk
rf   |jddd Y d S X d S )Nz[failed to decrypt cookie (AES-GCM) because the MAC check failed. Possibly the key is wrong?Tr   z\failed to decrypt cookie (AES-GCM) because UTF-8 decoding failed. Possibly the key is wrong?)r   rZ   r%   r   r<  )r   r  r  r  r5   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 |}|s|j	ddd dS  
|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)r1   r2   r3   ZwintypesZDWORDPOINTERc_char_fields_r+   ctypesr+   r,   	DATA_BLOB  s   
r  zfailed to decrypt with DPAPITr   )r  Zctypes.wintypes	Structurecreate_string_buffersizeofwindllZcrypt32ZCryptUnprotectDatabyrefr%   	string_atr  r  kernel32Z	LocalFree)r   r5   r  r   Zblob_inZblob_outretresultr+   r  r,   r    s*    
	r  c                   C   s   t jdt jdS )NXDG_CONFIG_HOMEz	~/.config)rL   r]  r7   r[   r   r+   r+   r+   r,   r   (  s    r   c                 C   s,   t j|d}t| | t|}| S )Nztemporary.sqlite)rL   r[   r\   rm  r   r   connectr   )Zdatabase_pathr   Zdatabase_copy_pathconnr+   r+   r,   r   ,  s    
r   c                 C   s$   |  d| d }dd |D S )NzPRAGMA table_info(r  c                 S   s   g | ]}|d    qS )r   )r   )r]   rowr+   r+   r,   r^   6  s     z%_get_column_names.<locals>.<listcomp>)r   r   )r   Z
table_nameZ
table_infor+   r+   r,   r   4  s    r   c                 C   s   t | dd d dS )Nc                 S   s   t | jS r>   )rL   lstatst_mtime)r[   r+   r+   r,   r@   :  rA   z_newest.<locals>.<lambda>)r  default)max)filesr+   r+   r,   r   9  s    r   c           	   
   c   sv   d}t |`}t| D ]N\}}}|D ]>}|d7 }|d| d|dd ||kr&tj||V  q&qW 5 Q R X d S )Nr   r   zSearching for "z": rq   z files searched)rD   rL   walkr0   r[   r\   )	r   filenamer5   r   r<   Z	curr_rootr?   r  r;   r+   r+   r,   r   =  s    
r   c                 C   s:   t  }| D ]*}|D ]}|| q|jd k	r
|j|_q
|S r>   )rK   r   r  )ZjarsZ
output_jarrT   r   r+   r+   r,   rP   I  s    

rP   c                    s"   t  fddtjjtjjfD S )Nc                 3   s   | ]}|r| kV  qd S r>   r+   )r]   seprv   r+   r,   rl   T  s      z_is_path.<locals>.<genexpr>)anyrL   r[   r  altsepr  r+   r  r,   r   S  s    r   c                 C   s\   | t krtd|  d|dtkr4td| d|d k	rPtt|rPt|}| |||fS )Nzunsupported browser: "r`   zunsupported keyring: ")N)SUPPORTED_BROWSERSrZ   SUPPORTED_KEYRINGSr   r   )rQ   rR   rF   rG   r+   r+   r,   rH   W  s    rH   c                	       s~   e Zd ZdZded Zeed Zddddd	d
dddh	Zd
dhZ	e
de d e d ejejB Z fddZ  ZS )LenientSimpleCookiez1More lenient version of http.cookies.SimpleCookiez\w\dz!#$%&'*+-.:^_`|~z(),/<=>?@[]{}r~   r[   r   ry   zmax-ager}   httponlyru   samesitez
        \s*                            # Optional whitespace at start of cookie
        (?P<key>                       # Start of group 'key'
        [au  ]+?# Any word of at least one letter
        )                              # End of group 'key'
        (                              # Optional group: there may not be a value.
        \s*=\s*                          # Equal Sign
        (                                # Start of potential value
        (?P<val>                           # Start of group 'val'
        "(?:[^\\"]|\\.)*"                    # Any doublequoted string
        |                                    # or
        \w{3},\s[\w\d\s-]{9,11}\s[\d:]{8}\sGMT # 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
        \s*                            # Any number of spaces.
        (\s+|;|$)                      # Ending either at space, semicolon, or EOS.
        c                    s  t |tst |S d }| j|D ]}|dr:d }q&|dd\}}d}|drh|dd  }d}| }|| j	kr|d krq&|d kr|| j
krd }q&d}n| |\}}|||< q&|rd }q&|d k	r| |tj }| |\}	}
|||	|
 || |< q&d }q&d S )Nbadr  valF$r   T)r   rW  r$   rO   _COOKIE_PATTERNfinditerri   r   ro  	_RESERVED_FLAGSvalue_decoder7   r   r   Morselset)r&   r  morselmatchr  rv   Zis_attributeZ	lower_keyr?   
real_valuecoded_valuer)   r+   r,   rO     s>    







zLenientSimpleCookie.load)r1   r2   r3   r   rg   escapeZ_LEGAL_KEY_CHARSZ_LEGAL_VALUE_CHARSr  r  compileASCIIVERBOSEr  rO   r=   r+   r+   r)   r,   r  a  s4   
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 ) rK   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.

ZCookieFileEntry)Zdomain_nameZinclude_subdomainsr[   Z
https_only
expires_atrf   rv   Nc                    s.   t  jd|| t|r$t|}|| _d S )N)N)r$   r   r   rL   fspathr  )r&   r  argskwargsr)   r+   r,   r     s    
zYoutubeDLCookieJar.__init__c                 C   s   | rdS dS )NTRUEFALSEr+   )Zcndnr+   r+   r,   _true_or_false  s    z!YoutubeDLCookieJar._true_or_falseFwritec             	   c   sJ   t |r2t||rdnddd}|V  W 5 Q R X n|r@|d |V  d S )Nwrzutf-8rc   r   )r   r   truncate)r&   r;   r  r  r+   r+   r,   r     s    
zYoutubeDLCookieJar.openc                 C   s   t   }| D ]}|s|js|s*||r*q|j|j }}|d krJd| }}|dd|j| 	|j
d|j| 	|jt|jdd||f qd S )Nr   z{}
	rs   )r  )r-   r   
is_expiredrf   rv   r  formatr\   ry   r  r   r[   r}   r   r~   )r&   r  ignore_discardignore_expiresnowr   rf   rv   r+   r+   r,   _really_save  s(    


 zYoutubeDLCookieJar._really_saveTc              	   C   sx   |dkr&| j dk	r| j }nttjj| D ]}|jdkr*d|_q*| j|dd }|| j | 	||| W 5 Q R X 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   Tr  )
r  rZ   r   r   MISSING_FILENAME_TEXTr~   r   r  _HEADERr  )r&   r  r  r  r   r  r+   r+   r,   save  s    

zYoutubeDLCookieJar.savec           
         s  |dkr& j dk	r j }nttjj fdd}t } |}|D ]~}z||| W qJ tjj	k
r } zD|
  dd dkrtj	dtd| d	|d
 W Y qJW 5 d}~X Y qJX qJW 5 Q R X |d  ||||  D ]}	|	jdkrd|	_d|	_qdS )zLoad cookies from a file.Nc                    s   |   jr| t jd  } |  ds0|  s4| S | d}t| jkrbtjdt|  j	| }|j
r|j
 stjd|j
 | S )N#r  zinvalid length zinvalid expires at )r   _HTTPONLY_PREFIXr   rX  rY  
_ENTRY_LENr   r   	LoadError_CookieFileEntryr  isdigit)r   Zcookie_listr   r&   r+   r,   prepare_line  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  rZ   r   r   r  ioStringIOr   r  r  rX  r   seek_really_loadr~   r   )
r&   r  r  r  r  cfr  r   rh  r   r+   r  r,   rO   
  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&   urlZ
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_requestr  r  r  r   r   )r&   r  r+   r+   r,   get_cookies_for_urlC  s    z&YoutubeDLCookieJar.get_cookies_for_urlc              
      s0   t t t j||W  5 Q R  S Q R X d S r>   )rr  suppressr{  r$   clear)r&   r  r  r)   r+   r,   r  J  s    zYoutubeDLCookieJar.clear)N)NTT)NTT)r1   r2   r3   r   r  r  r  collections
namedtupler  r   r   r  rr  contextmanagerr   r  r  rO   r  r  r  r=   r+   r+   r)   r,   rK     s&   
	

3rK   )r  )NNN)nr|  r  rr  r,  r+  r   r   r  http.cookiejarr   http.cookiesr  r   rL   rg   rm  r  rc  r   r   r-   urllib.requestr  enumr   r   Zaesr   r   r   compatr   Zdependenciesr	   r
   r   Z
minicursesr   r   utilsr   r   r   r   r   r   r   r   r   Zutils._utilsr   Zutils.networkingr   rX   r  r"   rD   rU   rJ   rV   r   r   r   rY   r   r   r   r   r   r   rW   rf  r  r  r1  r9  r;  r:  r
  r?  rM  __members__r  r  r\  r^  ri  rq  rw  r   r   r  r   r   r  r  r   r   r   r   r   rP   r   rH   r   SimpleCookier  r   MozillaCookieJarrK   r+   r+   r+   r,   <module>   s   ,
E<H"3 %3*
G)+
"


[