代码之家  ›  专栏  ›  技术社区  ›  I wrestled a bear once.

cURLing cPanel,登录后未进行身份验证

  •  0
  • I wrestled a bear once.  · 技术社区  · 12 年前

    我正在重新设计这个轮子,我知道已经编写了一些类,但我只需要这些功能的一小部分,所以我决定编写自己的类。

    最终,我的目标是获得cpanel中创建的所有电子邮件地址的列表。我计划通过卷曲“电子邮件地址”页面并检查“下一页”链接来实现这一点。

    我可以登录,但当我第二次调用 /frontend/x3/mail/pops.html 我从服务器上得到了一个buncha官样文章,而不是电子邮件页面的源代码。

    libcurl生成的cookie文件工作,写入cookie并将其发送回去,那么还有什么问题呢?

    这是我正在进行的代码:

    class cpanel {
        var $cpanelHost;
        var $cpanelPort;
        var $username;
        var $password;
        var $loggedin = false;
        var $logcurl = true;
        var $cookiefile = "cpanel_cookie.txt";
        var $curlfile = "cpanel_curl.txt";
        var $cpsess;
        var $homepage;
    
        function __construct($user,$pass,$host,$port="2083"){
            $this->cpanelHost = $host;
            $this->cpanelPort = $port;
            $this->username = $user;
            $this->password = $pass;
            $this->LogIn($user,$pass);
        }
    
        function LogIn($username,$password){
            $params = 'user='.$username.'&pass='.$password;
            $url = 'https://'.$this->cpanelHost.":".$this->cpanelPort."/login/?login_only=1";
            $headers = array(
                "Host: ".$this->cpanelHost,
                "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
                "Accept-Language: en-US,en;q=0.5",
                "Accept-Encoding: gzip, deflate",
                "Connection: keep-alive",
                "Content-Type: application/x-www-form-urlencoded"
            );
    
            $answer = $this->Request($url,$headers,$params);
            //echo $answer; exit; //{"status":1,"redirect":"/cpsess8791005960/frontend/x3/index.html?post_login=92098211063688","security_token":"/cpsess8791005960"}
            $answer = json_decode($answer, true);
            $loggedin = (isset($answer['status']) && $answer['status'] == 1) ? true : false;
            $this->loggedin = $loggedin;
            if($this->loggedin){
                $this->cpsess = $answer['security_token'];
                $this->homepage = 'https://'.$this->cpanelHost.":".$this->cpanelPort.$answer['redirect'];
            }
        }
    
        function getEmails(){
            $params = '';
            $url = "https://".$this->cpanelHost.":".$this->cpanelPort.$this->cpsess."/frontend/x3/mail/pops.html";
            $headers = array(
                "Host: ".$this->homepage,
                "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
                "Accept-Language: en-US,en;q=0.5",
                "Accept-Encoding: gzip, deflate",
                "Connection: keep-alive",
                "Content-Type: application/x-www-form-urlencoded"
            );
            $referrer = $this->homepage;
            $answer = $this->Request($url,$headers,$params);
            echo $answer; exit;
        }
    
        function Request($url,$headers=array(),$params=array(),$referrer=""){
            if($this->logcurl){
                $curl_log = fopen($this->curlfile, 'a+');
            }
            if(!file_exists($this->cookiefile)){
                echo 'Cookie file missing.'; exit;
            }else if(!is_writable($this->cookiefile)){
                echo 'Cookie file not writable.'; exit;
            }
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0');
            if(!empty($headers)){
                curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            }
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            if(!empty($params)){
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
            }
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_COOKIEJAR, realpath($this->cookiefile));
            curl_setopt($ch, CURLOPT_COOKIEFILE, realpath($this->cookiefile));
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            if($this->logcurl){
                curl_setopt($ch, CURLOPT_STDERR, $curl_log);
            }
            curl_setopt($ch, CURLOPT_FAILONERROR, false);
            curl_setopt($ch, CURLOPT_VERBOSE, true);
            if(!empty($referrer)){
               curl_setopt($ch, CURLOPT_REFERER, $referrer);  
            }
            $answer = curl_exec($ch);
            if (curl_error($ch)) {
                $loggedin = curl_error($ch);
            }
            curl_close($ch);
            if($this->logcurl){
                fclose($curl_log);
            }
            return $answer;
        }
    
    }
    
    1 回复  |  直到 12 年前
        1
  •  1
  •   I wrestled a bear once.    12 年前

    我在意识到cPanel的JSON API需要用户名和密码以及每次API调用的GET参数后才得以解决。如果这对任何人都有帮助,我的课可以上 here .

    /**
     * cPanelMailManager
     * PHP Library for the email module of cPanel's JSON API
     * @author Rob Parham 
     * @copyright Copyright (c) 2014, Rob Parham
     * @license http://www.wtfpl.net/ WTF Public License
     */
    class cPanelMailManager {
        public $cookiefile;
        private $cpanelHost;
        private $cpanelPort;
        private $username;
        private $password;
        private $logcurl;
        private $curlfile;
        private $emailArray;
        private $cpsess;
    
        /**
         * Constructor
         * @param string $user cPanel username
         * @param string $pass cPanel password
         * @param string $host cPanel domain
         * @param int $port cPanel domain
        */
        public function __construct($user,$pass,$host,$port=2083){
            $this->cpanelHost = $host;
            $this->cpanelPort = $port;
            $this->username = $user;
            $this->password = $pass;
            $this->logcurl = false;
            $this->cookiefile = "cpmm/cpmm_cookie_".rand(99999, 9999999).".txt";
            $this->LogIn();
        }
    
        /**
         * Checks if an email address exists
         * @param string $Needle Email address to check
         * @param bool $FullEmailOnly If false, will return true with or without the domain attached
         * @return bool
        */
        public function emailExists($Needle, $FullEmailOnly = false){
            $Haystack = empty($this->emailArray) ? $this->getEmails() : $this->emailArray;
            foreach($Haystack as $H){
                if($FullEmailOnly === true && $H['email'] == $Needle){
                    return true;
                }else if($FullEmailOnly !== true && ($H['user'] == $Needle || $H['email'] == $Needle)){
                    return true;
                }
            }
            return false;
        }
    
        /**
         * Creates a new email address
         * @param string $email Complete mail address to create, ie. myemail@mydomain.com
         * @param string $password Password for new email
         * @param string $quota Disk Space Quota, 0 for unlimited
         * @return bool
        */
        public function createEmail($email,$password,$quota = 0){
            if($this->emailExists($email,true)){
                return "Email address ".$email." already exist";
            }
            $e = explode("@",$email);
            $params = 'user='.$this->username.'&pass='.$this->password;;
            $url = "https://".$this->cpanelHost.":".$this->cpanelPort.$this->cpsess."/json-api/cpanel".
            "?cpanel_jsonapi_version=2".
            "&cpanel_jsonapi_func=addpop".
            "&cpanel_jsonapi_module=Email&".
            "email=".$e[0]."&".
            "domain=".$e[1]."&".
            "password=".urlencode($password)."&".
            "quota=".$quota;
            $answer = json_decode($this->Request($url,$params), true);
            $this->getEmails(true);
            return ($answer["cpanelresult"]["data"][0]['result'] === 1) ? true : false;
        }
    
        /**
         * Deletes an email address
         * @param string $email Complete mail address to delete, ie. myemail@mydomain.com
         * @return bool
        */
        public function deleteEmail($email){
            if(!$this->emailExists($email,true)){
                return "Email address ".$email." does not exist";
            }
            $e = explode("@",$email);
            $params = 'user='.$this->username.'&pass='.$this->password;;
            $url = "https://".$this->cpanelHost.":".$this->cpanelPort.$this->cpsess."/json-api/cpanel".
            "?cpanel_jsonapi_version=2".
            "&cpanel_jsonapi_func=delpop".
            "&cpanel_jsonapi_module=Email&".
            "email=".$e[0]."&".
            "domain=".$e[1];
            $answer = json_decode($this->Request($url,$params), true);
            $this->getEmails(true);
            return ($answer["cpanelresult"]["data"][0]['result'] === 1) ? true : false;
        }
    
        /**
         * Changes a password
         * @param string $email Complete email of account, ie. myemail@mydomain.com
         * @param string $newPW New password
         * @return bool
        */
        public function changePW($email, $newPW){
            if(!$this->emailExists($email,true)){
                return "Email address ".$email." does not exist";
            }
            $e = explode("@",$email);
            $params = 'user='.$this->username.'&pass='.$this->password;;
            $url = "https://".$this->cpanelHost.":".$this->cpanelPort.$this->cpsess."/json-api/cpanel".
            "?cpanel_jsonapi_version=2".
            "&cpanel_jsonapi_func=passwdpop".
            "&cpanel_jsonapi_module=Email&".
            "email=".$e[0]."&".
            "domain=".$e[1]."&".
            "password=".urlencode($newPW);
            $answer = json_decode($this->Request($url,$params), true);
            $this->getEmails(true);
            return ($answer["cpanelresult"]["data"][0]['result'] === 1) ? true : false;
        }
    
        /**
         * Lists all email accounts and their properties
         * @param int $pageSize Number of results per page
         * @param int $currentPage Page number to start from
         * @param bool $paginate Return in pages
         * @param bool $sort Sort the results
         * @param bstring $sortby Column to sort by, ie. "email", "_diskused", "mtime", or "domain"
         * @return array
        */
        public function listEmails($pageSize = 10, $currentPage = 1, $paginate = true, $sort = true, $sortby = "user"){
            $params = 'user='.$this->username.'&pass='.$this->password;;
            $url = "https://".$this->cpanelHost.":".$this->cpanelPort.$this->cpsess."/json-api/cpanel".
            "?cpanel_jsonapi_version=2".
            "&cpanel_jsonapi_func=listpopswithdisk".
            "&cpanel_jsonapi_module=Email".
            "&api2_paginate=".($paginate === false ? 0 : 1).
            "&api2_paginate_size=".$pageSize.
            "&api2_paginate_start=".$currentPage.
            "&api2_sort=".($sort === false ? 0 : 1).
            "&api2_sort_column=".$sortby.
            "&api2_sort_method=alphabet".
            "&api2_sort_reverse=0";
            $answer = $this->Request($url,$params);
            $emails = json_decode($answer, true);
            $this->emailArray = $emails["cpanelresult"]["data"];
            return $this->emailArray;
        }
    
        /**
         * Turns cURL logging on
         * @param int $curlfile Path to curl log file
         * @return array
        */
        public function logCurl($curlfile = "cpmm/cpmm_curl_log.txt"){
            if(!file_exists($curlfile)){
                try{
                    fopen($curlfile, "w");
                }catch(Exception $ex){
                    if(!file_exists($curlfile)){
                        return $ex.'Cookie file missing.'; exit;
                    }
                    return true;
                }
            }else if(!is_writable($curlfile)){
                return 'Cookie file not writable.'; exit;
            }
            $this->logcurl = true;
            return true;
        }
    
        /**
         * Returns a complete list of emails and their properties
         * @access private
        */
        private function getEmails($refresh = false){
            if(!empty($this->emailArray) && !$refresh){
                return $this->emailArray;
            }
            $params = 'user='.$this->username.'&pass='.$this->password;;
            $url = "https://".$this->cpanelHost.":".$this->cpanelPort.$this->cpsess."/json-api/cpanel".
            "?cpanel_jsonapi_version=2".
            "&cpanel_jsonapi_func=listpopswithdisk".
            "&cpanel_jsonapi_module=Email";
            $answer = $this->Request($url,$params);
            $emails = json_decode($answer, true);
            $this->emailArray = $emails["cpanelresult"]["data"];
            return $this->emailArray;
        }
    
        /**
         * Starts a session on the cPanel server
         * @access private
        */
        private function LogIn(){
            $url = 'https://'.$this->cpanelHost.":".$this->cpanelPort."/login/?login_only=1";
            $url .= "&user=".$this->username."&pass=".urlencode($this->password);
            $answer = $this->Request($url);
            $answer = json_decode($answer, true);
            if(isset($answer['status']) && $answer['status'] == 1){
                $this->cpsess = $answer['security_token'];
                $this->homepage = 'https://'.$this->cpanelHost.":".$this->cpanelPort.$answer['redirect'];
            }
        }
    
        /**
         * Makes an HTTP request
         * @access private
        */
        private function Request($url,$params=array()){
            if($this->logcurl){
                $curl_log = fopen($this->curlfile, 'a+');
            }
            if(!file_exists($this->cookiefile)){
                @fopen($this->cookiefile, "w");
                if(!file_exists($this->cookiefile)){
                    echo 'Cookie file missing. '.$this->cookiefile; exit;
                }
            }else if(!is_writable($this->cookiefile)){
                echo 'Cookie file not writable. '.$this->cookiefile; exit;
            }
            $ch = curl_init();
            $curlOpts = array(
                CURLOPT_URL             => $url,
                CURLOPT_USERAGENT       => 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0',
                CURLOPT_SSL_VERIFYPEER  => false,
                CURLOPT_RETURNTRANSFER  => true,
                CURLOPT_COOKIEJAR       => realpath($this->cookiefile),
                CURLOPT_COOKIEFILE      => realpath($this->cookiefile),
                CURLOPT_FOLLOWLOCATION  => true,
                CURLOPT_HTTPHEADER      => array(
                    "Host: ".$this->cpanelHost,
                    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
                    "Accept-Language: en-US,en;q=0.5",
                    "Accept-Encoding: gzip, deflate",
                    "Connection: keep-alive",
                    "Content-Type: application/x-www-form-urlencoded")
            );
            if(!empty($params)){
                $curlOpts[CURLOPT_POST] = true;
                $curlOpts[CURLOPT_POSTFIELDS] = $params;
            }
            if($this->logcurl){
                $curlOpts[CURLOPT_STDERR] = $curl_log;
                $curlOpts[CURLOPT_FAILONERROR] = false;
                $curlOpts[CURLOPT_VERBOSE] = true;
            }
            curl_setopt_array($ch,$curlOpts);
            $answer = curl_exec($ch);
            if (curl_error($ch)) {
                echo curl_error($ch); exit;
            }
            curl_close($ch);
            if($this->logcurl){
                fclose($curl_log);
            }
            return (@gzdecode($answer)) ? gzdecode($answer) : $answer;
        }
    }