JFIF ( %!1"%)-...383.7(-.+  -%&--------------------------------------------------"J !1"AQaq2BR#r3Sbs4T$Dd(!1"2AQaq# ?q& JX"-` Es?Bl 1( H6fX[vʆEiB!j{hu85o%TI/*T `WTXط8%ɀt*$PaSIa9gkG$t h&)ٞ)O.4uCm!w*:K*I&bDl"+ ӹ=<Ӷ|FtI{7_/,/T ̫ԷC ȷMq9[1w!R{ U<?СCԀdc8'124,I'3-G s4IcWq$Ro瓩!"j']VӤ'B4H8n)iv$Hb=B:B=YݚXZILcA g$ΕzuPD? !զIEÁ $D'l"gp`+6֏$1Ľ˫EjUpܣvDت\2Wڰ_iIْ/~'cŧE:ɝBn9&rt,H`*Tf֙LK$#d "p/n$J oJ@'I0B+NRwj2GH.BWLOiGP W@#"@ę| 2@P D2[Vj!VE11pHn,c~T;U"H㤑EBxHClTZ7:х5,w=.`,:Lt1tE9""@pȠb\I_IƝpe &܏/ 3, WE2aDK &cy(3nI7'0W էΠ\&@:נ!oZIܻ1j@=So LJ{5UĜiʒP H{^iaH?U2j@<'13nXkdP&%ɰ&-(<]Vlya7 6c1HJcmǸ!˗GB3Ԏߏ\=qIPNĉA)JeJtEJbIxWbdóT V'0 WH*|D u6ӈHZh[8e  $v>p!rIWeB,i '佧 )g#[)m!tahm_<6nL/ BcT{"HSfp7|ybi8'.ih%,wm  403WebShell
403Webshell
Server IP : 88.223.91.197  /  Your IP : 216.73.216.122
Web Server : LiteSpeed
System : Linux id-dci-web1986.main-hosting.eu 5.14.0-611.26.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jan 29 05:24:47 EST 2026 x86_64
User : u686484674 ( 686484674)
PHP Version : 8.0.30
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /proc/self/root/opt/cloudlinux/venv/lib64/python3.11/site-packages/clcommon/lib/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/self/root/opt/cloudlinux/venv/lib64/python3.11/site-packages/clcommon/lib/whmapi_lib.py
# -*- coding: utf-8 -*-

# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2018 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
#

"""
Everything that is related to whmapi calls
"""

import json
from clcommon import FormattedException
from clcommon.utils import run_command
from urllib.parse import urlencode

__all__ = ('WhmApiRequest', 'WhmApiError')


class WhmApiError(FormattedException):
    """
    An error that is raised in case of an error
    in communication with whmapi.
    """

    def __init__(self, message, **context):
        FormattedException.__init__(self, {
            'message': message,
            'context': context
        })


class WhmLicenseError(WhmApiError):
    """A license-related error raised by whmapi."""
    pass


class WhmNoPhpBinariesError(WhmApiError):
    """
    An error when there are no installed php binaries
    """
    pass


class WhmApiRequest:
    """
    Wrapper over cpanel's whm command-line api tool
    that allows us to easily build complex requests (filter, sorting, etc)

    See details in the official cpanel docs (link below)
    https://documentation.cpanel.net/display/DD/Guide+to+WHM+API+1
    """
    WHMAPI = '/usr/sbin/whmapi1'

    API_RESULT_OK = 1

    def __init__(self, command):
        self._command = command
        self._filters = {}
        self._args = {}
        self._extra_args = ['--output', 'json']

    def _run_whmapi(self, command):
        exitcode, output, _ = run_command(
            command, return_full_output=True)
        if exitcode != 0:
            raise WhmApiError(
                'whmapi exited with code %(code)i',
                code=exitcode
            )

        try:
            response = json.loads(output)
            # TODO: PTCCLIB-196
            # Starting with cPanel v86.0 whmapi1 returns empty reason
            # if we try to revome nonexistent package.
            # It's temporary solution until cPanel provides another one.
            if ('metadata' in response)\
                    and ('reason' in response['metadata'])\
                    and (response['metadata']['reason'] is None):
                response['metadata']['reason'] = ''
        except (TypeError, ValueError) as e:
            raise WhmApiError(
                'whmapi returned invalid response that '
                'cannot be parsed with json, output: %(output)s',
                output=output
            ) from e
        self._validate(response)
        return response

    @classmethod
    def _validate(cls, response):
        """
        Check response metadata
        """
        if cls._is_license_error(response):
            raise WhmLicenseError(
                'whmapi license error: %(response)s', response=response['statusmsg']
            )
        if cls._is_no_php_binaries_error(response):
            raise WhmNoPhpBinariesError(
                'Php binaries error: %(response)s', response=response['metadata']['reason']
            )
        try:
            result, reason = \
                response['metadata']['result'], response['metadata']['reason']
        except KeyError as e:
            raise WhmApiError(
                'whmapi metadata section is broken, output: %(response)s',
                response=response
            ) from e

        # in 'ideal' world this should never happen as we check whmapi exitcode
        if result != WhmApiRequest.API_RESULT_OK:
            raise WhmApiError(
                'whmapi failed to execute request, reason: %(reason)s',
                reason=reason
            )

    @staticmethod
    def _is_license_error(response):
        """
        Distinguish license-related WHM API errors from others.
        License errors are on the client's side, and should not be logged to sentry.
        An error is considered license-related if the API returns status 0
        and the error message contains the word 'license'
        """
        return ('statusmsg' in response and
                response['status'] == 0 and
                'license' in response['statusmsg'].lower())

    @staticmethod
    def _is_no_php_binaries_error(response):
        """
        No binaries error can be detected by  checking special message
        '“PHP” is not installed on the system' whmapi output
        """
        return ('metadata' in response and
                'reason' in response['metadata'] and
                '“PHP” is not installed on the system' in response['metadata']['reason'])

    def with_arguments(self, **kwargs):
        """
        Add some extra arguments to subprocess call
        Useful for methods like createacct, removeacct
        :param kwargs: arguments that will be added to cmd
        :rtype: WhmApiRequest
        """
        self._args.update(kwargs)
        return self

    # TODO: enable in the future and add some unittests
    # def filter(self, **kwargs):
    #     """
    #     Implements output filtering, see the following url for details
    #     https://documentation.cpanel.net/display/DD/WHM+API+1+-+Filter+Output
    #     :param kwargs: dict
    #     """
    #     self._filters.update(kwargs)
    #     return self

    def call(self):
        """
        Run subprocess, run output validation and
        return json-loaded response
        :return:
        """
        cmd = [
            self.WHMAPI,
            self._command
        ]
        for k, v in list(self._args.items()):
            # https://documentation.cpanel.net/display/DD/Guide+to+WHM+API+1
            if isinstance(v, bool):
                # the term "boolean" in our documentation refers
                # to parameters that accept values of 1 or 0.
                # cPanel & WHM's APIs do not support the literal
                # values of true and false.
                v = int(v)
            argument = urlencode({k: v})
            cmd.append(argument)

        # TODO: enable in the future and add some unittests
        # for key, value in self._filters.items():
        #     cmd.extend('api.filter.{}={}'.format(key, value))

        cmd.extend(self._extra_args)

        result = self._run_whmapi(cmd)

        if 'data' in result:
            # for getting method
            return result['data']
        elif 'output' in result:
            # for setting method
            return result['output']
        else:
            return result

Youez - 2016 - github.com/yon3zu
LinuXploit