HEX
Server: LiteSpeed
System: Linux ws4.angoweb.net 5.14.0-611.13.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 11 04:57:59 EST 2025 x86_64
User: tswangoe (2287)
PHP: 8.1.33
Disabled: show_source, system, shell_exec, passthru, exec, phpinfo, popen, proc_open
Upload Files
File: //opt/alt/python37/lib/python3.7/site-packages/xray/internal/__pycache__/utils.cpython-37.pyc
B

�*Ud�[�@s�dZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mmZ
ddlmZddlmZmZddlmZddlmZddlmZmZmZmZmZmZmZddlmZdd	lm Z m!Z!m"Z"ddl#Z#dd
l$m%Z%ddl&m'Z'ddl(m)Z)dd
l*m+Z+ddl,m-Z-m.Z.m/Z/ddl0m1Z1ddl2m3Z3ddl4m5Z5ddl6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<ddl=m>Z>e�?d�Z@eAeBejCfZDe.jEjFe.jGjFe.jHjFgZIe e d�dd�ZJe e d�dd�ZKe e d�dd�ZLeMd�dd�ZNed�d d!�ZOeMed"�d#d$�ZPeQd�d%d&�ZRe!eSeQd'�d(d)�ZTe!eSeQd'�d*d+�ZUeQd�d,d-�ZVeQdd.�d/d0�ZWeQd�d1d2�ZXdreQe"eYd3�d4d5�ZZeLeQd�d6d7��Z[dd�d8d9�Z\eQe"eQd:�d;d<�Z]eQeQdd=�d>d?�Z^eQd@dA�dBdC�Z_eMeMdD�dEdF�Z`eQe"eadG�dHdI�ZbeQe"eQdG�dJdK�ZcdseQddG�dLdM�ZdeQeYdG�dNdO�ZeeYd�dPdQ�ZfeYd�dRdS�ZgeYddT�dUdV�ZheYd�dWdX�ZieYd�dYdZ�ZjeYd�d[d\�ZkeQeYd]�d^d_�Zld`da�Zmedbddc�ddde��ZnedteQeYdg�dhdi��ZoedueMddj�dkdl��ZpedveMeMeMddo�dpdq��ZqdS)wzB
This module contains helpful utility functions for X-Ray Manager
�N)�contextmanager)�date�	timedelta)�wraps)�glob)�socket�fromfd�AF_UNIX�SOCK_STREAM�
SOCK_DGRAM�AF_INET�AF_INET6)�current_thread)�Callable�List�Optional)�AtexitIntegration)�LoggingIntegration)�Feature)�is_panel_feature_supported)�
CLEditions�SupportedEditions�CLEditionDetectionError)�UIConfig)�drop_privileges)�php_get_vhost_versions_user�)�
sentry_dsn�local_tasks_storage�
agent_file�
logging_level�jwt_token_location�user_agent_sock)�	XRayErrorZutils)�func�returncs"dd��t����fdd��}|S)zf
    Decorator aimed to update ini file in cagefs-skeleton
    Applies to task.add nd task.remove
    c
Ws<tj�|djd�}|�d�r>td�r>tj�d|dd��}nT|�d�r�td	�r�tj�d	|dd��}tj�tj�|��s�t�tj�|��ndStj�|�s�yt�	|�Wn:t
k
r�}ztjd
|t
|�d�d�Wdd}~XYnXnNyt�||�Wn<t
k
�r6}ztjd
|t
|�d�d�Wdd}~XYnXdS)zd
        Copy ini file to cagefs-skeleton
        Action takes place for cPanel ea-php only
        rzxray.iniz/opt/cpanelz/usr/share/cagefsz"/usr/share/cagefs/.cpanel.multiphprNz
/usr/localz/usr/share/cagefs-skeletonz'Failed to unlink ini in cagefs-skeleton)Zxray_ini�err)�extraz'Failed to copy ini into cagefs-skeleton)�os�path�joinZini_location�
startswithr�exists�dirname�mkdir�unlink�OSError�logger�warning�str�shutil�copy)�argsZoriginal_iniZskeleton_ini�e�r8�D/opt/alt/python37/lib/python3.7/site-packages/xray/internal/utils.py�updateMs2$zskeleton_update.<locals>.updatecs�||��|�dS)z
        Wraps func
        Nr8)r6�kwargs)r$r:r8r9�wrapperos
z skeleton_update.<locals>.wrapper)r)r$r<r8)r$r:r9�skeleton_updateGs"r=cs,dd��dd��t�����fdd��}|S)zs
    Decorator aimed to update DBM storage with fake_id:real_id mapping
    Applies to task.add nd task.remove
    c	Ws,|d}tt��}|j||j<WdQRXdS)z-
        Update DBM storage contents
        rN)�dbm_storagerZtask_id�fake_id)r6Z
task_instance�task_storager8r8r9r:�s
z"dbm_storage_update.<locals>.updatec	WsBtt��0}y||dj��=Wntk
r2YnXWdQRXdS)z.
        Remove task from DBM storage
        rN)r>rr?�encode�KeyError)r6r@r8r8r9�remove�s

z"dbm_storage_update.<locals>.removec
s�y�jdkr�|�Wn.tk
rD}ztt|���Wdd}~XYnXy�||�Wn(tk
r|�jdkrv�|��YnXy�jdkr��|�Wn.tk
r�}ztt|���Wdd}~XYnXdS)z
        Wraps func
        �addNrC)�__name__�RuntimeErrorr#r3�	Exception)r6r;r7)r$rCr:r8r9r<�s 


z#dbm_storage_update.<locals>.wrapper)r)r$r<r8)r$rCr:r9�dbm_storage_updatezsrHcs"dd��t����fdd��}|S)z5
    Decorator aimed to validate given JWT token
    cSst|�dS)z7
        Check if retrieved JWT token is valid
        N)�is_edition_supported)�_tokenr8r8r9�check�szcheck_jwt.<locals>.checkcs�||�}�|�|S)z
        Wraps func
        r8)r6r;�token)rKr$r8r9r<�s
zcheck_jwt.<locals>.wrapper)r)r$r<r8)rKr$r9�	check_jwt�s	rM)r%cCstt���S)zJ
    Get current epoch timestamp as int
    :return: timestamp as int
    )�int�timer8r8r8r9�	timestamp�srPcCst��tdd�S)zC
    Pick a yesterday date
    :return: a datetime.date object
    r)Zdays)rZtodayrr8r8r8r9�	prev_date�srQ)�tsr%cCs
t�|�S)zy
    Get the datetime.date object for given int timestamp
    :param ts: timestamp
    :return: datetime.date object
    )rZ
fromtimestamp)rRr8r8r9�date_of_timestamp�srScCst��d�S)zj
    Get a formatted representation of yesterday date
    :return: str date in the form of dd/mm/YYYY
    z%d/%m/%Y)rQ�strftimer8r8r8r9�get_formatted_date�srU)�linksr%cs"d�d��fdd�t|d�D��S)z
    HTML formatted links
    z)<p>{num}) <a href={link}>{domain}</a></p>�
cs2g|]*\}}|��D]\}}�j|||d��qqS))�num�link�domain)�items�format)�.0�i�l�k�v)�	html_itemr8r9�
<listcomp>�sz,get_html_formatted_links.<locals>.<listcomp>r)r*�	enumerate)rVr8)rbr9�get_html_formatted_links�srecs"d�d��fdd�t|d�D��S)z
    Formatted links
    z{num}) {dom}: {link}rWcs2g|]*\}}|��D]\}}�j|||d��qqS))rXZdomrY)r[r\)r]r^r_r`ra)�	text_itemr8r9rc�sz,get_text_formatted_links.<locals>.<listcomp>r)r*rd)rVr8)rfr9�get_text_formatted_links�srgc
Cs�yHt�d�}|��}|�d�j}t���}|�d|�WdQRX|�d�St	tj
fk
rz}ztd�|�Wdd}~XYnXdS)ze
    Obtain system ID from /etc/sysconfig/rhn/systemid
    :return: system ID without ID- prefix
    z/etc/sysconfig/rhn/systemidz(.//member[name='system_id']/value/string�	system_idNzID-zFailed to retrieve system_id)�ET�parseZgetroot�find�text�
sentry_sdk�configure_scopeZset_tag�lstripr0Z
ParseErrorr#)Ztree�rootZwhole_id�scoper7r8r8r9�read_sys_id�s


rr)�sys_idr%c	Cs$ttd��}|�|�WdQRXdS)zH
    Write system_id into file /usr/share/alt-php-xray/agent_sys_id
    �wN)�openr�write)rs�outr8r8r9�write_sys_idsrxc
Cs`y tt��}|����SQRXWn:tk
rZ}ztjddt|�id�t�Sd}~XYnXdS)zA
    Read system_id saved by agent during its initialization
    Nz8Failed to retrieve agent's system_id, returning real oner&)r')	rur�read�stripr0r1�errorr3rr)Zagent_sysid_filer7r8r8r9�read_agent_sys_ids
r|)rJr%c
Csfytj|dd�}Wn.tk
r@}zt|j�|�Wdd}~XYnX|tkrbtdt|����d���dS)z9Raise XRayError in case of detected non-supported editionT)Zraw_jwtZskip_marker_checkNzCL z" edition is not supported by X-Ray)rZget_cl_editionrr#�message�SUPPORTED_EDITIONSr3�
capitalize)rJZeditionr7r8r8r9rI&srIc	CsNy tt��}|����SQRXWn(ttfk
rHtdt�d���YnXdS)zT
    Obtain jwt token from /etc/sysconfig/rhn/jwt.token
    :return: token read
    Nz	JWT file z read error)rur!ryrzr0�IOErrorr#)Z
token_filer8r8r9�read_jwt_token3s

r�c	s�tttd�dd�}dd�dd�}dd	��td��fd
d�}ttjtjd�}t|d
�}tjt	|d||gd�t�
��}d|�i|_WdQRXdS)u�
    Initialize Sentry client
    shutdown_timeout=0 disables Atexit integration as stated in docs:
    'it’s easier to disable it by setting the shutdown_timeout to 0'
    https://docs.sentry.io/platforms/python/default-integrations/#atexit
    On the other hand, docs say, that
    'Setting this value too low will most likely cause problems
    for sending events from command line applications'
    https://docs.sentry.io/error-reporting/configuration/?platform=python#shutdown-timeout
    )�event�hintr%cSs|d�ddi�|S)z�
        Add extra data into sentry event
        :param event: original event
        :param hint: additional data caught
        :return: updated event
        r'zxray.versionz
0.5-17.el9)r:)r�r�r8r8r9�add_infoLszsentry_init.<locals>.add_infoN)r%cSsdS)Nr8)�pending�timeoutr8r8r9�nopeVszsentry_init.<locals>.nopec	SsRt|t��>}y|�|df�|��d}Wntk
rBd}YnXWdQRX|S)aI
        address_family - we can choose constants represent the address
                           (and protocol) families
                           (AF_INET for ipv4 and AF_INET6 for ipv6)
        private_ip - specify some private ip address. For instance:
                     ipv4 -> 10.255.255.255 or ipv6 -> fc00::
        rrN)rr�connectZgetsocknamerG)Zaddress_familyZ
private_ip�s�IPr8r8r9�
try_get_ipYszsentry_init.<locals>.try_get_ipcs8tdftdff}x"|D]\}}�||�}|r|SqWdS)z&
        Retrieve server's IP
        z10.255.255.255zfc00::z	127.0.0.1)rr
)Z
ipversionsZaddr_famZpriv_ipZip)r�r8r9�ip_addris
zsentry_init.<locals>.ip_addr)�levelZevent_level)�callbackzalt-php-xray@0.5-17.el9)ZdsnZbefore_send�releaseZintegrationsZ
ip_address)�dictr3r�logging�INFO�WARNINGrrmZinitrrn�user)r�r�r�Zsentry_loggingZ
silent_atexitrqr8)r�r9�sentry_init@s



r�)�lognamer%cCs�tjtjtjtjtjd�}t�y tj||�t	tj�ddd�Wn&t
k
rftjt��gd�dSXyt�
|d�Wntk
r�YnX|S)z[
    Configure logging and Sentry
    :param logname: path to log
    :return: logpath
    )�debug�infor2r{�criticalz%(asctime)s %(message)sz%m/%d/%Y %I:%M:%S %p)�filenamer�r\�datefmt)�handlersNi�)r��DEBUGr�r��ERROR�CRITICALr��basicConfig�getr r0�NullHandlerr(�chmod�PermissionError)r�Zlevelsr8r8r9�configure_logging~s&
r�)�src�dstr%cCsXyt�||�WnBtk
rR}z$td|�d|�dt|����|�Wdd}~XYnXdS)zZ
    Move file with error catching
    :param src: source
    :param dst: destination
    zFailed to move file z to z: N)r4Zmover0r#r3)r�r�r7r8r8r9�	safe_move�sr�z
socket object)�
sock_locationr%c	Cs`ttj�dd��}|dkrHt�� tt�}|�|�|��WdQRXnt	dtt
�}|��|S)z�
    Create world-writable socket in given sock_location
    or reuse existing one
    :param sock_location: socket address
    :return: socket object
    �
LISTEN_FDSrN�)rNr(�environr��umask_0rr	ZbindZlistenrr
)r�r�Zsockobjr8r8r9�
create_socket�s
r�)�lve_idr%c
Cs�ttj�sdSd}d|�d�}y\t|��J}xB|D]:}|�|�r0t�dt�j|�t	|�
��|�d�
��Sq0WWdQRXWn4tk
r�}zt�
d|t|��Wdd}~XYnXdS)	zX
    Retrieve current value of CPU throttled time.
    Return 0 in case of failures
    rZthrottled_timez/sys/fs/cgroup/cpu,cpuacct/lvez	/cpu.statz[%s] %s���NzFailed to open %s: %s)rr�LVErur+r1r�r�namerNrz�splitr0r{r3)r�ZmarkerZ	stat_fileZstat_values�valuer7r8r8r9�get_current_cpu_throttling_time�s



,$r�)�usernamer%c
Cs�d}tj�|�sdSy.tj|d|dgdddd�}|j��|j��fStjk
r|}zt	j
ddt|�id	�Wdd}~XYn2tk
r�}zt	�
d
t|��Wdd}~XYnXdS)z�
    'selectorctl -u username --user-current' command
    :param username: name of user
    :return: tuple(stdout, stderr) or None if command fails
    z/usr/bin/selectorctlNz-uz--user-currentT)�capture_outputrlrKz&Failed to get selectorctl user-currentr&)r'z%selectorctl --user-current failed: %s)r(r)�isfile�
subprocess�run�stdoutrz�stderr�CalledProcessErrorr1r2r3�subprocess_errorsr{)r�Z_selectorctl�resultr7r8r8r9�_selectorctl_get_version�s  r�c
Cs�d}tj�|�sdSy"tj|d|gdddd�}|j��Stjk
rp}ztj	ddt
|�id�Wdd}~XYn2tk
r�}zt�d	t
|��Wdd}~XYnXdS)
z�
    'cagefsctl --get-prefix username' command
    :param username: name of user
    :return: cagefsctl prefix for given username
            or None if command fails
    z/usr/sbin/cagefsctlNz--getprefixT)r�rlrKzFailed to get cagefsctl prefixr&)r'z cagefsctl --getprefix failed: %s)
r(r)r�r�r�r�rzr�r1r2r3r�r{)r��
_cagefsctlr�r7r8r8r9�_cagefsctl_get_prefix�s
 r�c
Cs�d}tj�|�sdS|dkr(|ddg}n
|d|g}y tj|ddd�t�d|�Wnjtjk
r�}ztjd	d
t	|�id�Wdd}~XYn2t
k
r�}zt�dt	|��Wdd}~XYnXdS)
z�
    'cagefsctl --remount username' or 'cagefsctl --remount-all' command
    :param username: name of user or None (for remount-all)
    z/usr/sbin/cagefsctlNz--wait-lockz
--remount-allz	--remountT)rKr�zRemounted %szFailed to remount cagefsr&)r'zcagefsctl --remount failed: %s)r(r)r�r�r�r1r�r�r2r3r�r{)r�r�r6r7r8r8r9�_cagefsctl_remounts
 r�c
Cspd}tj�|�sdSy$tj|d|gddd�}d|j��kStk
rj}zt�	dt
|��Wdd}~XYnXdS)	z�
    'cagefsctl --user-status username' command
    :param username: name of user
    :return: True if user has Enabled status, False otherwise
    z/usr/sbin/cagefsctlFz
--user-statusT)r�rlZEnabledz"cagefsctl --user-status failed: %sN)r(r)r�r�r�r�rzr�r1r{r3)r�r�r�r7r8r8r9�_is_cagefs_enableds
r�c	Cs>y td��}|��}WdQRXWntk
r4dSXd|kS)z`
    Check if there is php.d.location = selector
    set in /etc/cl.selector/symlinks.rules
    z/etc/cl.selector/symlinks.rulesNFZselector)ruryr0)Z
rules_file�contentsr8r8r9�_is_selector_phpd_location_set,s
r�c	Cs$tt��}t|���dkSQRXdS)z:Check if there are no active tasks (== empty task storage)rN)r>r�len�keys)r@r8r8r9�no_active_tasks9s
r�)�enabledr%c
Csxttj�sdSy0tdddd��}|�|r,dnd�WdQRXWn4tk
rr}zt�d|t|��Wdd}~XYnXdS)	zb
    Switch on/off throttle statistics gathering by kmodlve
    :param enabled: True or False
    Nz!/proc/sys/kernel/sched_schedstats�wbr)�mode�	buffering�1�0z(Failed to set sched_schedstats to %s: %s)	rrr�rurvr0r1r�r3)r��fr7r8r8r9�switch_schedstats?s

 r�cCst��dd�dkS)zG
    Check if end-users have access to X-Ray UI of End-User plugin
    ZhideXrayAppZ
uiSettingsF)rZ	get_paramr8r8r8r9�is_xray_app_availableQsr�c
CsBttt��.}y|�t�Wnttfk
r2dSXWdQRXdS)z Check if User Agent is listeningFNT)rr	r
r�r"�ConnectionErrorr0)r�r8r8r9�is_xray_user_agent_activeXsr�cCstj�d�S)z2Check if SSA is disabled by its internal flag-filez/usr/share/clos_ssa/ssa_enabled)r(r)r�r8r8r8r9�ssa_disabledbsr�)�filepathr%cCs0yt�t�|�jdkStk
r*dSXdS)z.Check is file was modified during the last dayi�QFN)rPr(�stat�st_mtimer0)r�r8r8r9�is_file_recently_modifiedgsr�c	Cst|��t�}WdQRX|S)N)rr)r�r�r8r8r9�get_user_php_versionps
r�z'file object providing a fileno() method)�fdr%ccs�x�td�D]z}y$t�|tjtjB�t�d�PWq
tk
r�}z2t�dt|��|j	t	j
t	jfkrh�t�
d�Wdd}~XYq
Xq
Wtddd��dVt�|tj�dS)	uq
    Context manager for locking given file object
    :param fd: а file object providing a fileno() method
    �xzFile lockedzFailed to lock: %sg�?Nz%Failed to lock at all. Exiting threadr2)�flag)�range�fcntlZflockZLOCK_EXZLOCK_NBr1r�r0r3�errnoZEAGAINZEACCESrO�sleepr#ZLOCK_UN)r��_r7r8r8r9�filelockxs
 r�F)r��	is_shelveccs�tj�|�}d}x�td�D]v}y.|r0t�|�}nt�|d�}t�d|�PWqtj	k
r�}z"t�d|||�|}t
�d�Wdd}~XYqXqWtd|�d|����|V|�
�t�d	|�dS)
a1
    Context manager for waiting for lock to be released for DBM file storage,
    either plain DBM or a Shelf object
    (desired return value is controlled by _shelve_instance flag)
    :param filename: a DBM file to open
    :param is_shelve: if a shelve file should be opened instead of plain DBM
    N�d�czStorage %s openedz#[#%i] Failed to open storage %s: %sg333333�?zFailed to open z
 storage: zStorage %s closed)r(r)�basenamer��shelveru�dbmr1r�r{rOr�rF�close)r�r�Z_fileZ_errr�Zstorager7r8r8r9r>�s&	 r>)�maskr%ccst�|�}dVt�|�dS)z,
    Context manager for dropping umask
    N)r(�umask)r��prevr8r8r9r��s
r��.T)�
target_uid�
target_gidr�r%c	csdt��}t��}yt�|�}Wntk
r6d}YnX|dkrT|dkrN|}n|j}|dkrp|dkrj|}n|j}|dk	r�t�|�}||kr�t�|�t	�
d|�|r�t��|kr�td��||k�rt�
|�t	�
d|�|�rt��|k�r||kr�t�|�td��dV||k�r,t�
|�t	�
d|�||k�rLt�|�t	�
d|�|dk	�r`t�|�dS)aH
    Context manager to drop privileges during some operation
    and then restore them back.
    If target_uid or target_gid are given, use input values.
    Otherwise, stat target_uid and target_gid from given target_path.
    If no target_path given, use current directory.
    Use mask if given.
    :param target_uid: uid to set
    :param target_gid: gid to set
    :param target_path: directory or file to stat for privileges,
                       default -- current directory
    :param mask: umask to use
    :param with_check: check the result of switching privileges
    NzDropped GID privs to %sz6Unable to execute required operation: permission issuezDropped UID privs to %szRestored UID privs to %szRestored GID privs to %s)r(�getuid�getgidr�r0�st_uid�st_gidr��setegidr1r��getegidr#�seteuid�geteuid)	r�r�Ztarget_pathr�Z
with_checkZprev_uidZprev_gid�	stat_infor�r8r8r9�set_privileges�sN










r�)N)N)F)r)NNr�NT)r�__doc__r�r�r�r�r(r�r4r�rOZxml.etree.ElementTreeZetreeZElementTreeriZ
contextlibrZdatetimerr�	functoolsrrrrr	r
rrr
�	threadingr�typingrrrrmZsentry_sdk.integrations.atexitrZsentry_sdk.integrations.loggingrZclcommon.constrZclcommon.cpapirZclcommon.lib.cleditionrrrZclcommon.ui_configrZclcommon.clpwdrZclwpos.papirZ	constantsrrrr r!r"Z
exceptionsr#�	getLoggerr1r0�
ValueErrorZSubprocessErrorr�Z
SHARED_PROr�ZSOLOZADMINr~r=rHrMrNrPrQrSr3rUr�rergrrrxr|�boolrIr�r�r�r�r�r��tupler�r�r�r�r�r�r�r�r�r�r�r�r�r>r�r�r8r8r8r9�<module>
s�$ 

38			
>