
    ɯei6d                       d dl m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 d dlmZmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZ ddlmZ  ej<                  e      Z e G d d             Z! G d de
      Z" G d de"      Z# G d de"      Z$ G d de"      Z% G d d      Z& G d d      Z'ddZ(ddZ)y)    )annotationsN)ABCabstractmethod)	dataclass)datetime	timedeltatimezone)Path)x509)default_backend)serialization)BaseFileLockFileLock   )
IS_WINDOWSc                  >    e Zd ZU dZded<   ded<   d
dZddZddZy	)CRLCacheEntryz8Cache entry containing a CRL and its download timestamp.x509.CertificateRevocationListcrlr   download_timec                b    t        | j                  dd      xs t        | j                  dd      S )z/A compatibility wrapper around crl.next_update.next_update_utcNnext_update)getattrr   selfs    _/var/www/html/glpi_dashboard/venv/lib/python3.12/site-packages/snowflake/connector/crl_cache.py_next_updatezCRLCacheEntry._next_update!   s/    txx!2D9 
WHHmT>
 	
    c                8    | j                         }|duxr ||k  S )z
        Check if the CRL has expired.

        Args:
            ts: Time to check against

        Returns:
            True if the CRL has expired, False otherwise
        N)r   )r   tsr   s      r   is_crl_expired_byzCRLCacheEntry.is_crl_expired_by'   s'     '')$&;;+;;r   c                *    | j                   |z   }||k  S )a/  
        Check if the cache entry should be evicted based on cache validity time.

        Args:
            ts: Current time to check against
            cache_validity_time: How long cache entries remain valid

        Returns:
            True if the entry should be evicted, False otherwise
        )r   )r   r!   cache_validity_timeexpiry_times       r   is_evicted_byzCRLCacheEntry.is_evicted_by4   s      ((+>>Rr   N)returnzdatetime | None)r!   r   r'   bool)r!   r   r$   r   r'   r(   )__name__
__module____qualname____doc____annotations__r   r"   r&    r   r   r   r      s     B	''
< r   r   c                  F    e Zd ZdZedd       Zedd       Zedd       Zy)	CRLCachez-
    Abstract base class for CRL caches.
    c                    t               )z
        Get a CRL cache entry by URL.

        Args:
            crl_url: The CRL URL

        Returns:
            The cache entry if found, None otherwise
        NotImplementedErrorr   crl_urls     r   getzCRLCache.getH   s     "##r   c                    t               )z
        Store a CRL cache entry.

        Args:
            crl_url: The CRL URL
            entry: The cache entry to store
        r2   r   r5   entrys      r   putzCRLCache.putU   s     "##r   c                    t               )z2Remove expired and evicted entries from the cache.r2   r   s    r   cleanupzCRLCache.cleanup`   s     "##r   Nr5   strr'   zCRLCacheEntry | Noner5   r>   r9   r   r'   Noner'   r@   )r)   r*   r+   r,   r   r6   r:   r<   r.   r   r   r0   r0   C   sC     
$ 
$ $ $ $ $r   r0   c                  >     e Zd ZdZdZ fdZddZddZd	dZ xZ	S )
NoopCRLCachez=
    No-operation CRL cache that doesn't store anything.
    Nc                \    | j                   t        | 	  |       | _         | j                   S )N)INSTANCEsuper__new__)cls	__class__s    r   rG   zNoopCRLCache.__new__n   s'    << 7?3/CL||r   c                     y)zAlways returns None.Nr.   r4   s     r   r6   zNoopCRLCache.gets   s    r   c                     yzDoes nothing.Nr.   r8   s      r   r:   zNoopCRLCache.putw       r   c                     yrL   r.   r   s    r   r<   zNoopCRLCache.cleanup{   rM   r   r=   r?   rA   )
r)   r*   r+   r,   rE   rG   r6   r:   r<   __classcell__)rI   s   @r   rC   rC   f   s#    
 H
r   rC   c                  0    e Zd ZdZddZddZd	dZd
dZy)CRLInMemoryCachez=
    In-memory CRL cache using a thread-safe dictionary.
    c                R    i | _         || _        t        j                         | _        y)z
        Initialize the in-memory cache.

        Args:
            cache_validity_time: How long cache entries remain valid
        N)_cache_cache_validity_time	threadingRLock_lock)r   r$   s     r   __init__zCRLInMemoryCache.__init__   s!     13$7!__&
r   c                    | j                   5  | j                  j                  |      }|t        j	                  d|        |cddd       S # 1 sw Y   yxY w)z
        Get a CRL cache entry from memory.

        Args:
            crl_url: The CRL URL

        Returns:
            The cache entry if found, None otherwise
        NzFound CRL in memory cache for )rW   rS   r6   loggerdebugr8   s      r   r6   zCRLInMemoryCache.get   sO     ZZ 	KKOOG,E =gYGH		 	 	s   7AAc                d    | j                   5  || j                  |<   ddd       y# 1 sw Y   yxY w)z
        Store a CRL cache entry in memory.

        Args:
            crl_url: The CRL URL
            entry: The cache entry to store
        N)rW   rS   r8   s      r   r:   zCRLInMemoryCache.put   s.     ZZ 	)#(DKK 	) 	) 	)s   &/c           
     @   t        j                  t        j                        }t        j                  d|        | j                  5  g }| j                  j                         D ]f  \  }}|j                  |      }|j                  || j                        }|s|s8t        j                  d| d| d|        |j                  |       h |D ]  }| j                  |=  t        |      }|dkD  rt        j                  d| d       ddd       y# 1 sw Y   yxY w)	z5Remove expired and evicted entries from memory cache.z#Cleaning up in-memory CRL cache at z'Removing in-memory CRL cache entry for z
: expired=z
, evicted=r   zRemoved z1 expired/evicted entries from in-memory CRL cacheN)r   nowr	   utcrZ   r[   rW   rS   itemsr"   r&   rT   appendlen)r   r^   urls_to_removeurlr9   expiredevictedremoved_counts           r   r<   zCRLInMemoryCache.cleanup   s   ll8<<(:3%@AZZ 	N"kk//1 	/
U11#6--c43L3LMgLLA# G##*):gY@ #))#.	/ & %KK$%  /Mq }o-^_'	 	 	s   ADA.DDN)r$   r   r=   r?   rA   )r)   r*   r+   r,   rX   r6   r:   r<   r.   r   r   rQ   rQ      s    	' 	)r   rQ   c                      e Zd ZdZ	 	 	 d	 	 	 	 	 ddZddZddZddZ	 	 	 	 	 	 	 	 ddZddZ	dd	Z
	 	 	 	 	 	 dd
ZddZy)CRLFileCachez:
    File-based CRL cache that persists CRLs to disk.
    Nc                    d| _         |xs
 t               | _        |xs t        d      | _        || _        | j                          y)ac  
        Initialize the file cache.

        Args:
            cache_dir: Directory to store cached CRLs
            removal_delay: How long to wait before removing expired files
            unsafe_skip_file_permissions_check: Skip file permission validation for security

        Raises:
            OSError: If cache directory cannot be created
              @   daysN)_cache_file_lock_timeout_get_default_crl_cache_path
_cache_dirr   _removal_delay#_unsafe_skip_file_permissions_check_ensure_cache_directory_exists)r   	cache_dirremoval_delay"unsafe_skip_file_permissions_checks       r   rX   zCRLFileCache.__init__   sB    " ),%#D'B'D+@ya/@3U0++-r   c                B   	 | j                   j                  ddd       | j                  s| j                  | j                   dd       t        j                  d| j                           y	# t        $ r  t        $ r }t        d| j                    d|       d	}~ww xY w)
zGCreate the cache directory if it doesn't exist with secure permissions.Ti  )parentsexist_okmode	directory0o700z"Cache directory created/verified: z!Failed to create cache directory : N)rq   mkdirrs   _check_permissionsrZ   r[   PermissionErrorOSError)r   es     r   rt   z+CRLFileCache._ensure_cache_directory_exists   s    	VOO!!$E!J ;;''gNLL=doo=NOP 	 	V=doo=NbQRPSTUU	Vs   A)A, ,B>BBc                    t        j                  |j                               j                         }| j                  d| dz  S )z
        Generate a file path for the given CRL URL.

        Args:
            crl_url: The CRL URL

        Returns:
            Path to the cache file
        crl_z.der)hashlibsha256encode	hexdigestrq   )r   r5   url_hashs      r   _get_crl_file_pathzCRLFileCache._get_crl_file_path   s:     >>'.."23==?4z!666r   c                P    t        |j                  d      d| j                        S )z3Return a lock instance for the given CRL cache filez.lockT)thread_localtimeout)r   with_suffixro   )r   crl_cache_files     r   _get_crl_file_lockzCRLFileCache._get_crl_file_lock  s)    &&w/11
 	
r   c                   t         ry	 |j                         }t        j                  |j                        }|dz  dk7  r2t	        d| d| dt        |       d|j                          d| d	      y# t        $ r Y yw xY w)
aF  
        Check that a CRL cache resource has secure permissions (owner-only access).

        Note: This check is only performed on Unix-like systems. Windows file
        permissions work differently and are not checked.

        Args:
            path: Path to the resource (file or directory) to check
            resource_type: Description of the resource type (e.g., "file", "directory")
            expected_perms: Description of expected permissions (e.g., "0o600 or 0o400", "0o700")

        Raises:
            PermissionError: If resource permissions are too wide
        N?   r   z
CRL cache  z has insecure permissions: z. z' must be accessible only by the owner (z).)r   statS_IMODEst_moder   oct
capitalizeFileNotFoundError)r   pathresource_typeexpected_perms	stat_infoactual_permissionss         r   r   zCRLFileCache._check_permissions  s    $ 			I!%i.?.?!@ #U*a/% q6QRUVhRiQjjl$//122YZhYiikm  0 ! 		s   A)A3 3	A?>A?c                H   | j                  |      }| j                  |      5  	 |j                         rt        j	                  d|        | j
                  s| j                  |dd       nt        j                  d|        |j                         }t        j                  |j                  t        j                        }t        |d      5 }|j                         }ddd       t!        j"                  t%                     }t'        ||      cddd       S 	 ddd       y# 1 sw Y   GxY w# t(        $ r-}t        j+                  d	| d
|        Y d}~ddd       yd}~wt,        $ r%}t        j                  d| d
|        Y d}~rd}~ww xY w# 1 sw Y   yxY w)z
        Get a CRL cache entry from disk.

        Args:
            crl_url: The CRL URL

        Returns:
            The cache entry if found, None otherwise
        zFound CRL on disk for filez0o600 or 0o400z$Skipping file permissions check for tzrbN)backendz1Permission error reading CRL from disk cache for r~   z'Failed to read CRL from disk cache for )r   r   existsrZ   r[   rs   r   warningr   r   fromtimestampst_mtimer	   r_   openreadr   load_der_x509_crlr   r   r   error	Exception)	r   r5   crl_file_pathr   r   fcrl_datar   r   s	            r   r6   zCRLFileCache.get2  s    //8$$]3  	YY '')LL#9-!IJ  CC//vGWXB=/R
 !. 2 2 4I$,$:$:!**x||%M
 mT2 ,a#$668, 00?CTUC(m<1 	Y  	Y) 	YD , , # GyPRSTRUV = 	Y  	Y>  Y!H	QSTUSVWXXY? 	YD s_   FB+D3D'!2D3F'D0	,D33	F<E$F$F0FFFFF!c                    | j                  |      }| j                  |      5  	 |j                  j                  t        j
                  j                        }t        j                  t        j                  z  t        j                  z  }t        r|t        j                  z  }t        j                  ||d      }	 t        j                  ||       t        j                  |       |j                   j#                         }t        j$                  |||f       t&        j)                  d|        ddd       y# t        j                  |       w xY w# t*        $ r%}t&        j-                  d| d|        Y d}~Ld}~ww xY w# 1 sw Y   yxY w)z
        Store a CRL cache entry to disk.

        Args:
            crl_url: The CRL URL
            entry: The cache entry to store
        i  zStored CRL to disk cache: z&Failed to write CRL to disk cache for r~   N)r   r   r   public_bytesr   EncodingDERosO_WRONLYO_CREATO_TRUNCr   O_BINARYr   writecloser   	timestamputimerZ   r[   r   r   )	r   r5   r9   r   r   flagsfddownload_timestampr   s	            r   r:   zCRLFileCache.puta  sG    //8$$]3 	XX 9911-2H2H2L2LM bjj02::=R[[(EWW]E59!HHR*HHRL &+%8%8%B%B%D");=O(PQ9-IJ+	X 	X HHRL  X!GyPRSTRUVWWX/	X 	XsH   FBE;D9AE9EE	FE<7F<FFFc                   	 |j                         }t        j                  |j                  t        j
                        }|| j                  z   }||kD  S # t        $ r%}t        j                  d| d|        Y d}~yd}~ww xY w)z5Check if the given CRL cache file is by its lifetime.r   zError processing cache file r~   NF)
r   r   r   r   r	   r_   rr   r   rZ   r   )r   r   r!   r   r   removal_timer   s          r   _is_cached_crl_file_for_removalz,CRLFileCache._is_cached_crl_file_for_removal  s|    
	&++-I$2293E3E(,,WM )4+>+>>L$$ 	NN9.9IA3OP	s   AA 	BA>>Bc                   t        j                  t        j                        }t        j                  d|        d}	 | j                  j                  d      D ]p  }| j                  ||      s| j                  |      5  | j                  ||      r/|j                  d       |dz  }t        j                  d|        ddd       r y# 1 sw Y   }xY w# t        $ r"}t        j                  d	|        Y d}~yd}~ww xY w)
z%Remove expired files from disk cache.z$Cleaning up file-based CRL cache at r   z	crl_*.derT)
missing_okr   zRemoved expired file: Nz!Error during file cache cleanup: )r   r^   r	   r_   rZ   r[   rq   globr   r   unlinkr   r   )r   r^   rg   crl_filer   s        r   r<   zCRLFileCache.cleanup  s    ll8<<(;C5AB
	B OO00= N77#F00: N??#N$OOtO<)Q.M"LL+A()LM	N NNN N
  	BLL<QC@AA	Bs6   0C 0C AC
C C	C 	D#D  DNNF)ru   Path | Nonerv   timedelta | Nonerw   r(   rA   )r5   r>   r'   r
   )r   r
   r'   r   )r   r
   r   r>   r   r>   r'   r@   r=   r?   )r   r
   r!   r   r'   r(   )r)   r*   r+   r,   rX   rt   r   r   r   r6   r:   r   r<   r.   r   r   ri   ri      s     "&*.38	.. (. -1	.0V"7
$$),$>A$	$L-^!XF"(0	 Br   ri   c                  R    e Zd ZdZ	 	 	 	 ddZedd       Zd	dZ	 	 	 	 	 	 	 	 d
dZy)CRLCacheManagerzU
    Cache manager that coordinates between in-memory and file-based CRL caches.
    c                     || _         || _        y)z
        Initialize the cache manager.

        Args:
            memory_cache: In-memory cache implementation
            file_cache: File-based cache implementation
        N)_memory_cache_file_cache)r   memory_cache
file_caches      r   rX   zCRLCacheManager.__init__  s     *%r   c                4     | t               t                     S )zCreate noop cache manager.)rC   rH   s    r   noopzCRLCacheManager.noop  s     <><>22r   c                    | j                   j                  |      }||S | j                  j                  |      }|| j                   j                  ||       |S t        j                  d|        y)z
        Get a CRL cache entry, checking memory cache first, then file cache.

        Args:
            crl_url: The CRL URL

        Returns:
            The cache entry if found, None otherwise
        NzCRL not found in cache for )r   r6   r   r:   rZ   r[   r8   s      r   r6   zCRLCacheManager.get  su     ""&&w/L   $$W-""7E2L27)<=r   c                    t        ||      }| j                  j                  ||       | j                  j                  ||       y)z
        Store a CRL in both memory and file caches.

        Args:
            crl_url: The CRL URL
            crl: The CRL to store
            download_time: When the CRL was downloaded
        N)r   r   r:   r   )r   r5   r   r   r9   s        r   r:   zCRLCacheManager.put  s<     c=1w.We,r   N)r   r0   r   r0   )r'   r   r=   )r5   r>   r   r   r   r   r'   r@   )	r)   r*   r+   r,   rX   classmethodr   r6   r:   r.   r   r   r   r     s\    && & 3 32--!?-PX-	-r   r   c                  8   e Zd ZU dZdZdZ ej                         ZdZ	de
d<    ej                         Zde
d<   dZde
d<   d	Zd
e
d<   edd       Ze	 	 	 d	 	 	 	 	 	 	 dd       Zedd       Zedd       Zedd       Zedd       Zedd       Zedd       Zy)CRLCacheFactorya*  
    Factory class for creating singleton instances of CRL caches.

    This factory ensures that only one instance of each cache type exists,
    providing warnings when attempting to create instances with different parameters.
    Also manages background cleanup of existing cache instances.
    Nzthreading.Thread | None_cleanup_threadzthreading.Event_cleanup_shutdownr   _cleanup_intervalFr(   _atexit_registeredc                (   | j                   5  | j                  t        |      | _        nH| j                  j                  |k7  r/t        j                  d| j                  j                   d|        | j                  cddd       S # 1 sw Y   yxY w)z
        Get or create a singleton CRLInMemoryCache instance.

        Args:
            cache_validity_time: How long cache entries remain valid

        Returns:
            The singleton CRLInMemoryCache instance
        NzNCRLs in-memory cache has already been initialized with cache validity time of z&, ignoring new cache validity time of )_instance_lock_memory_cache_instancerQ   rT   rZ   r   )rH   r$   s     r   get_memory_cachez CRLCacheFactory.get_memory_cache  s      	.))1-=>Q-R*++@@DWWdehee  fU  fU  eV V;;N:OQ --	. 	. 	.s   A1BBc                   | j                   5  | j                  t        |||      | _        n| j                  j                  }| j                  j                  }| j                  j
                  }|xs
 t               }|xs t        d      }||k7  rt        j                  d| d| d       ||k7  rt        j                  d| d|        ||k7  rt        j                  d	| d
|        | j                  cddd       S # 1 sw Y   yxY w)ap  
        Get or create a singleton CRLFileCache instance.

        Args:
            cache_dir: Directory to store cached CRLs
            removal_delay: How long to wait before removing expired files
            unsafe_skip_file_permissions_check: Skip file permission validation for security

        Returns:
            The singleton CRLFileCache instance
        Nrl   rm   zCCRLs file cache has already been initialized with cache directory 'z!', ignoring new cache directory ''zCCRLs file cache has already been initialized with removal delay of z , ignoring new removal delay of zUCRLs file cache has already been initialized with unsafe_skip_file_permissions_check=z, ignoring new value )
r   _file_cache_instanceri   rq   rr   rs   rp   r   rZ   r   )	rH   ru   rv   rw   existing_cache_direxisting_removal_delayexisting_skip_checkrequested_cache_dirrequested_removal_delays	            r   get_file_cachezCRLCacheFactory.get_file_cache  sG   $  	,''/+7}.P,(
 &)%=%=%H%H"),)A)A)P)P&,,PP $ '0&P3N3P#*7*L9!;L'%)<<NN]^p]q r99L8MQP *-DDNN]^t]u v99P8QS '*LLNNo  qD  pE E..P-QS ++=	, 	, 	,s   C,DDc                   | j                   5  | j                         r%t        j                  d       | j	                          || _        t        j                  | j                  dd      | _	        | j                  s&t        j                  | j                         d| _
        | j                  j                          t        j                  d|j                          d       ddd       y# 1 sw Y   yxY w)z
        Start the periodic cleanup task for existing cache instances.

        Args:
            cleanup_interval: How often to run cleanup tasks
        zPPeriodic cleanup already running, so it will first be stopped before restarting.zcrl-cache-cleanupT)targetnamedaemonz.Scheduled CRL cache cleanup task to run every z	 seconds.N)r   is_periodic_cleanup_runningrZ   r[   stop_periodic_cleanupr   rU   Thread_cleanup_loopr   r   atexitregister_atexit_cleanup_handlerstarttotal_seconds)rH   cleanup_intervals     r   start_periodic_cleanupz&CRLCacheFactory.start_periodic_cleanupD  s      	..0f ))+$4C!"+"2"2(((#C )) ; ;<)-& %%'LL@AQA_A_Aa@bbkl-	 	 	s   CC--C6c                   d}| j                   5  | j                  | j                  j                         r
	 ddd       y| j                  j	                          | j                  }ddd       |"|j                         r|j                  d       | j                   5  | j                  j                          d| _        d| _        ddd       y# 1 sw Y   kxY w# 1 sw Y   yxY w)zStop the periodic cleanup task.Nrk   r   )	r   r   r   is_setsetis_alivejoinclearr   )rH   thread_to_joins     r   r   z%CRLCacheFactory.stop_periodic_cleanupf  s      	1""*c.C.C.J.J.L	1 	1 !!%%' 00N	1 %.*A*A*C, 	)!!'')"&C$(C!	) 	)	1 	1	) 	)s   (C &C)CCC%c                    | j                   5  | j                  duxr | j                  j                         cddd       S # 1 sw Y   yxY w)z*Check if periodic cleanup task is running.N)r   r   r   r   s    r   r   z+CRLCacheFactory.is_periodic_cleanup_running{  sH      	V&&d2Us7J7J7S7S7U	V 	V 	Vs   *AA
c                   | j                   j                         s| j                  yt        j	                  d| j                  j                          d       | j                  	 | j                  j                          | j                  	 | j                  j                          | j                   j                  | j                  j                               }|rt        j	                  d       y| j                   j                         syy# t        $ r"}t        j                  d|        Y d}~d}~ww xY w# t        $ r"}t        j                  d|        Y d}~d}~ww xY w)z)Main cleanup loop that runs periodically.Nz1Running periodic CRL cache cleanup with interval z secondsz=An error occurred during scheduled CRL memory cache cleanup: z;An error occurred during scheduled CRL disk cache cleanup: r   z9CRL cache cleanup stopped gracefully by a shutdown event.)r   r   r   rZ   r[   r   r   r<   r   r   r   wait)rH   r   shutdowns      r   r   zCRLCacheFactory._cleanup_loop  sR    ''..0$$,LLCCDYDYDgDgDiCjjrs
 ))5..668 ''3,,446 ,,11--;;= 2 H O C ''..0 ! LLWXYWZ[  ! LLUVWUXY s0   &D D> 	D;D66D;>	E)E$$E)c                    	 | j                          t        j                  d       y# t        $ r"}t        j	                  d|        Y d}~yd}~ww xY w)za
        Atexit handler to ensure graceful shutdown of periodic cleanup on program exit.
        z5CRL cache cleanup stopped gracefully on program exit.z2Error stopping CRL cache cleanup on program exit: N)r   rZ   r[   r   r   )rH   r   s     r   r   z'CRLCacheFactory._atexit_cleanup_handler  sJ    
	S%%'LLPQ 	SLLMaSQRR	Ss   %( 	AAAc                    | j                   5  | j                          d| _        d| _        d| _        ddd       y# 1 sw Y   yxY w)z
        Reset the factory, clearing all singleton instances and stopping cleanup.
        This is primarily useful for testing purposes.
        NF)r   r   r   r   r   r   s    r   resetzCRLCacheFactory.reset  sF      	+%%')-C&'+C$%*C"		+ 	+ 	+s	   &<A)r$   r   r'   rQ   r   )ru   r   rv   r   rw   r(   r'   ri   )r   r   r'   r@   rA   )r'   r(   )r)   r*   r+   r,   r   r   rU   rV   r   r   r-   Eventr   r   r   r   r   r   r   r   r   r   r   r
  r.   r   r   r   r     s1    "$Y__&N 04O,3)8)::*.'.$$. .(  "&*.38	/,/, (/, -1	/,
 
/, /,b  B ) )( V V
 # #J 	S 	S 	+ 	+r   r   c                 l   	 t        j                         S # t        $ r Y nw xY wdt        j                  v rt        t        j                  d         S dt        j                  v rBdt        j                  v r0t        t        j                  d         t        j                  d   z  S dt        j                  v r0t        t        j                  d         j
                  j
                  S dt        j                  v r0t        t        j                  d         j
                  j
                  S t        d      S )NUSERPROFILE	HOMEDRIVEHOMEPATHLOCALAPPDATAAPPDATA~)r
   homeRuntimeErrorr   environparentr.   r   r   _get_windows_home_pathr    s    yy{ 

"BJJ}-..bjj Z2::%=BJJ{+,rzz*/EEE#BJJ~./66===BJJBJJy)*118889s    	""c                 
   t        j                         dk(  rt               dz  dz  dz  dz  dz  S t        j                         dk(  r t        j                         dz  dz  dz  dz  S t        j                         d	z  dz  dz  S )
z/Return the default path to persist cached CRLs.WindowsAppDataLocal	SnowflakeCachescrlsDarwinLibraryz.cache)platformsystemr  r
   r  r.   r   r   rp   rp     s    I%"$  	
 	
 
	h	&yy{Y&1K?&HHyy{X%3f<<r   )r'   r
   )*
__future__r   r   r   loggingr   r!  r   rU   abcr   r   dataclassesr   r   r   r	   pathlibr
   cryptographyr   cryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   filelockr   r   compatr   	getLoggerr)   rZ   r   r0   rC   rQ   ri   r   r   r  rp   r.   r   r   <module>r.     s    "    	    # ! 2 2   8 8 + 			8	$ %  %  % P $s  $F8 4Ex EP\B8 \B~?- ?-DT+ T+n =r   