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

时间:2014-07-22 20:34:45

标签: php api curl cpanel libcurl

我在这一方面重新发挥作用,我知道已经编写了类,但我只需要一小部分功能,所以我决定编写自己的类。

最终我的目标是获取在cpanel中创建的所有电子邮件地址的列表。我计划通过卷曲电子邮件地址"页面并检查"下一页"链接。

我可以登录确定,但当我对/frontend/x3/mail/pops.html进行第二次卷曲调用时,我从服务器返回了buncha gobbledegook,而不是电子邮件页面的源代码。

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 个答案:

答案 0 :(得分:1)

我意识到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;
    }
}