<?php
/*
 DirectAdmin Script by Wouter de Vries.
 Mail: info@afilas.nl
 WWW: http://www.afilas.nl
 Version: 1.0
 Created for ClientExec 2.1
*/

require_once 'newedge/classes/NE_MailGateway.php';

/*****************************************************************/
// function plugin_directadmin_variables - required function
/*****************************************************************/
require_once 'modules/admin/models/ServerPlugin.php';
/**
* @package Plugins
*/
class PluginDirectAdmin extends ServerPlugin
{
    function getVariables()
    {
        /* Specification
              itemkey     - used to identify variable in your other functions
              type        - text,textarea,yesno,password,hidden ( type hidden are variables used by CE and are required )
              description - description of the variable, displayed in ClientExec
              encryptable - used to indicate the variable's value must be encrypted in the database
        */
    
        $variables = array (
                   /*T*/"Name"/*/T*/ => array (
                                        "type"=>"hidden",
                                        "description"=>"Used By CE to show plugin - must match how you call the action function names",
                                        "value"=>"DirectAdmin"
                                       ),
                   /*T*/"Description"/*/T*/ => array (
                                        "type"=>"hidden",
                                        "description"=>/*T*/"Description viewable by admin in server settings"/*/T*/,
                                        "value"=>/*T*/"DirectAdmin control panel integration"/*/T*/
                                       ),
                   /*T*/"Username"/*/T*/ => array (
                                        "type"=>"text",
                                        "description"=>/*T*/"Username used to connect to server"/*/T*/,
                                        "value"=>""
                                       ),
                   /*T*/"Password"/*/T*/ => array (
                                        "type"=>"password",
                                        "description"=>/*T*/"Password used to connect to server"/*/T*/,
                                        "value"=>"",
                                        "encryptable"=>true
                                       ),
                   /*T*/"Failure E-mail"/*/T*/ => array (
                                        "type"=>"text",
                                        "description"=>/*T*/"An E-mail will be sent to this E-mail address in case of a failure"/*/T*/,
                                        "value"=>""
                                       ),
                   /*T*/"Use SSL"/*/T*/ => array (
                                        "type"=>"yesno",
                                        "description"=> /*T*/''/*/T*/,
                                        "value"=>"1"
                                       ),
                   /*T*/'reseller'/*/T*/  => array(
                                        'type'          => 'hidden',
                                        'description'   => /*T*/'Whether this server plugin can set reseller accounts'/*/T*/,
                                        'value'         => '1',
                                       ),
                   /*T*/"Actions"/*/T*/ => array (
                                        "type"=>"hidden",
                                        "description"=>/*T*/"Current actions that are active for this plugin per server"/*/T*/,
                                        "value"=>"Create,Delete,Update,Suspend,UnSuspend"
                                       )
        );
        return $variables;
    }
    
    //plugin function called after new account is activated
    function Create($args)
    {
        $errormsg = "";

        //Determine what package name to use.  If server variable package name is entered then use that
        $packagename = ($args['PackageNameOnServer']==null) ? $args['PackageName'] : $args['PackageNameOnServer'];

        //try to create the account
        if (@$args['is_reseller']) {
            $cmd = '/CMD_ACCOUNT_RESELLER';
            $ip = 'shared';
        } else {
            $cmd = '/CMD_ACCOUNT_USER';
            $ip = $args['DomainIP'];
        }
        $sock = new HTTPSocket;
        $sock->connect($args['ServerHostName'],2222, $args['plugin_directadmin_Use_SSL']);
        $sock->set_login($args['plugin_directadmin_Username'],$args['plugin_directadmin_Password']);
        $sock->set_method('POST');
        $tArray = array(  'action' => 'create',
                'add' => 'Submit',
                'username' => $args['DomainUsername'],
                'email' => $args['UserEmail'],
                'passwd' => $args['DomainPassword'],
                'passwd2' => $args['DomainPassword'],
                'domain' => $args['DomainName'],
                'package' => $packagename,
                'ip' => $ip,
                'notify' => 'no'
        );

        $sock->query($cmd, $tArray);
        $result = $sock->fetch_body();

        // Log the result
        $this->logger->log(4, "Directadmin::create::result:: ".$result);

        // Start the mailer
        $mailGateway = new NE_MailGateway();

        // Check the results
        if ($result == "") {

            // connection failed (wrong ip/hostname)
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while connecting to the DA server. Please check if your server hostname + IP address is correct! Please note that your query has not been executed on the server.",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Connection to DA server failed");

            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while connecting to the DA server. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].". Please note that your query has not been executed on the server.";
            $this->logger->log(4, "plugin_directadmin::create::error: ".$errormsg);

            return new NE_Error($errormsg, 200);

        } elseif (strpos($result, "Please enter your Username and Password")) {

            // connection failed (wrong login info)
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while connecting to the DA server. Please check if your server login info is correct! Please note that your query has not been executed on the server.",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Connection to DA server failed");

            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while connecting to the DA server. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].". Please note that your query has not been executed on the server.";
            $this->logger->log(4, "plugin_directadmin::create::error: ".$errormsg);

            return new NE_Error($errormsg, 200);

        } elseif (!strpos($result, "Domain Created Successfully")) {

            // something else went wrong
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while adding user ".$args['DomainUsername'].", please check if the package exists on your server, that the username is 4-8 characters long and that the e-mail address + domainname is correctly formatted. Also make sure that the chosen IP address is available on the server and that your password doesn't contain any illegal characters.",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Failure on adding user");
            
            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while adding user. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].".";
            $this->logger->log(4, "plugin_directadmin::create::error: ".$errormsg);

            return new NE_Error($errormsg, 200);
        }

        // All went well, so return nothing.
        return;
    }

    function Delete($args)
    {

        $errormsg = "";

        // Start the connections
        $sock = new HTTPSocket;
        $sock->connect($args['ServerHostName'],2222, $args['plugin_directadmin_Use_SSL']);
        $sock->set_login($args['plugin_directadmin_Username'],$args['plugin_directadmin_Password']);
        $sock->set_method('GET');
        $tArray = array( 'confirmed' => 'Confirm',
                'delete' => 'yes',
                'select0' => $args['DomainUsername']
        );
        $sock->query('/CMD_SELECT_USERS',$tArray);
        $result = $sock->fetch_body();

        // Log the result
        $this->logger->log(4, "Directadmin::delete::result:: ".$result);

        // Start the mailer
        $mailGateway = new NE_MailGateway();

        // Check the results
        if ($result == "") {

            // connection failed (wrong ip/hostname)
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while connecting to the DA server. Please check if your server hostname + IP address is correct! Please note that your query has not been executed on the server.",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Connection to DA server failed");
            
            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while connecting to the DA server. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].". Please note that your query has not been executed on the server.";
            $this->logger->log(4, "plugin_directadmin::delete::error: ".$errormsg);

            return new NE_Error($errormsg, 200);

        } elseif (strpos($result, "Please enter your Username and Password")) {

            // connection failed (wrong login info)
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while connecting to the DA server. Please check if your server login info is correct! Please note that your query has not been executed on the server.",             $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Connection to DA server failed");

            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while connecting to the DA server. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].". Please note that your query has not been executed on the server.";
            $this->logger->log(4, "plugin_directadmin::delete::error: ".$errormsg);

            return new NE_Error($errormsg, 200);

        } elseif (!strpos($result, "Users deleted")) {

            // something went wrong
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while deleting user ".$args['DomainUsername'].", please check if the username is correct.",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Failure during deleting user");

            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while deleting user. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].".";
            $this->logger->log(4, "plugin_directadmin::delete::error: ".$errormsg);

            return new NE_Error($errormsg, 200);
        }

        // All went well, so return nothing.
        return;
    }

    
    function CreateUserName($args)
    {
          //function used to determine how you want CE to create usernames on this server
          //if it does not matter on this server you can return $args['DomainUsername']
          if (isset($args['PassedUserName']) && $args['PassedUserName'] != "") {
            $username = $args['PassedUserName'];
          } else {
            $username = str_replace(".","",$args['DomainName']);
            $username = mb_substr($username,0,8);
            $username = str_replace('-','',$username); //make sure there are no - characters in the username
          }
          //Should check to see if directadmin already has an account with this username
          return $username;
    }
    
    
    function Update($args)
    {
        $errormsg = "";
    
        //Determine what package name to use.  If server variable package name is entered then use that
        $packagename = ($args['PackageNameOnServer']==null) ? $args['PackageName'] : $args['PackageNameOnServer'];

        // Start the connections
        $sock = new HTTPSocket;
        $sock->connect($args['ServerHostName'],2222, $args['plugin_directadmin_Use_SSL']);
        $sock->set_login($args['plugin_directadmin_Username'],$args['plugin_directadmin_Password']);
        $result = $sock->fetch_body();
        $sock->set_method('POST');
    
        $tArray = array(  'action' => 'ip',
                          'user' => $args['DomainUsername'],
                          'ip' => $args['DomainIP']
        );
    
        $sock->query('/CMD_MODIFY_USER',$tArray);
        $result = $sock->fetch_body();

        // Log the result
        $this->logger->log(4, "Directadmin::update::user::result:: ".$result);

        // Start the mailer
        $mailGateway = new NE_MailGateway();

        // Check the result
        if ($result == "") {

            // connection failed (wrong ip/hostname)
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while connecting to the DA server. Please check if your server hostname + IP address is correct! Please note that your query has not been executed on the server.",
                $args['plugin_directadmin_Failure_E-mail'],
                "DirectAdmin Plugin",
                $args['plugin_directadmin_Failure_E-mail'],
                "",
                "[CE] DirectAdmin plugin: Connection to DA server failed");

            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while connecting to the DA server. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].". Please note that your query has not been executed on the server.";
            $this->logger->log(4, "plugin_directadmin::update::error: ".$errormsg);

            return new NE_Error($errormsg, 200);

        } elseif (strpos($result, "Please enter your Username and Password")) {

            // connection failed (wrong login info)
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while connecting to the DA server. Please check if your server login info is correct! Please note that your query has not been executed on the server.",
                $args['plugin_directadmin_Failure_E-mail'],
                "DirectAdmin Plugin",
                $args['plugin_directadmin_Failure_E-mail'],
                "",
                "[CE] DirectAdmin plugin: Connection to DA server failed");
            
            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while connecting to the DA server. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].". Please note that your query has not been executed on the server.";
            $this->logger->log(4, "plugin_directadmin::update::error: ".$errormsg);

            return new NE_Error($errormsg, 200);

        } elseif (!strpos($result, "has been updated with the new ip")) {

            // something went wrong
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while changing the IP of user ".$args['DomainUsername'].", please check whether or not the IP address is available on the server.",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Failure on changing IP");

            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while changing the IP. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].".";
            $this->logger->log(4, "plugin_directadmin::update::error: ".$errormsg);

            return new NE_Error($errormsg, 200);
        }
    
        $tArray = array(  'action' => 'package',
                          'user' => $args['DomainUsername'],
                          'package' => $packagename
        );
    
        $sock->query('/CMD_MODIFY_USER',$tArray);
        $result = $sock->fetch_body();

        // Log the result
        $this->logger->log(4, "Directadmin::update::package::result:: ".$result);

        // Check the result
        if (!strpos($result, "User Modified")) {

            // something went wrong
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while changing the package of user ".$args['DomainUsername'].", please check if the package is available on your server.",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Failure on changing package");

            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while changing the package. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].".";
            $this->logger->log(4, "plugin_directadmin::update::error: ".$errormsg);

            return new NE_Error($errormsg, 200);
        }
    
        $tArray = array(  'username' => $args['DomainUsername'],
                          'passwd' => $args['DomainPassword'],
                          'passwd2' => $args['DomainPassword']
        );
        $sock->query('/CMD_USER_PASSWD',$tArray);
        $result = $sock->fetch_body();

        // Log the result
        $this->logger->log(4, "Directadmin::update::password::result:: ".$result);

        // Check the result
        if (!strpos($result, "Password successfully changed")) {

            // something went wrong
            $mailGateway->mailMessageEmail("DirectAdmin plugin: A failure occurred while changing the password of ".$args['DomainUsername'].", please check the ClientExec knowledge base for any possible solutions.",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "DirectAdmin Plugin",
                    $args['plugin_directadmin_Failure_E-mail'],
                    "",
                    "[CE] DirectAdmin plugin: Failure on changing password");

            // Create and log the error. Then throw an error.
            $errormsg = "A failure occurred while changing the password. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].".";
            $this->logger->log(4, "plugin_directadmin::update::error: ".$errormsg);

            return new NE_Error($errormsg, 200);
        }

        // All went well, so return nothing.
        return;
    }
    
    function Suspend($args)
    {

        // Start the connections
        $sock = new HTTPSocket;
        $sock->connect($args['ServerHostName'],2222, $args['plugin_directadmin_Use_SSL']);
        $sock->set_login($args['plugin_directadmin_Username'],$args['plugin_directadmin_Password']);
        $sock->set_method('GET');
        $tArray = array( 'location' => 'CMD_SELECT_USERS',
                         'suspend'  => 'Suspend/Unsuspend',
                         'select0'  => $args['DomainUsername']
                       );
        $sock->query('/CMD_SELECT_USERS',$tArray);
        $result = $sock->fetch_body();

        // Log the result
        $this->logger->log(4, "Directadmin::(un)suspend::result:: ".$result);
        
        // DirectAdmin doesn't seem to be returning anything at all for me when suspending/unsuspending.
        
        /*if ($result == "") {
            // connection failed (wrong ip/hostname)
            MailMessageEmail("DirectAdmin plugin: A failure occurred while connecting to the DA server. Please check if your server hostname + IP address is correct! Please note that your query has not been executed on the server.",
                             $args['plugin_directadmin_Failure_E-mail'],
                             "DirectAdmin Plugin",
                             $args['plugin_directadmin_Failure_E-mail'],
                             "",
                             "[CE] DirectAdmin plugin: Connection to DA server failed",
                             "",
                             "");
            $errormsg .= "A failure occurred while connecting to the DA server. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].". Please note that your query has not been executed on the server.";
        }
        if (strpos($result, "Please enter your Username and Password")) {
            // connection failed (wrong login info)
            MailMessageEmail("DirectAdmin plugin: A failure occurred while connecting to the DA server. Please check if your server login info is correct! Please note that your query has not been executed on the server.",
                             $args['plugin_directadmin_Failure_E-mail'],
                             "DirectAdmin Plugin",
                             $args['plugin_directadmin_Failure_E-mail'],
                             "",
                             "[CE] DirectAdmin plugin: Connection to DA server failed",
                             "",
                             "");
            $errormsg .= "A failure occurred while logging in to the DA server. An E-mail with details has been sent to ".$args['plugin_directadmin_Failure_E-mail'].". Please note that your query has not been executed on the server.";
        }
    
        // Can't actually check the status of this since it just redirects to another page.
    
        $GLOBALS['logger']->log(4, "plugin_directadmin::(un)suspend::error:".$errormsg);
        */

        // All went well, so return nothing.
        return;
    }
    
    function UnSuspend($args) {
        // Suspend/Unsuspend are the same, they just alternate the account status
        return $this->Suspend($args);
    }
}

// Class for communicating through sockets with DA. (by Phi1 'l0rdphi1' Stier <l0rdphi1@liquenox.net>)
class HTTPSocket {

        /* all vars are private except $error */

        var $method = 'GET';

        var $remote_host;
        var $remote_port;
        var $remote_uname;
        var $remote_passwd;

        var $result;
        var $result_header;
        var $result_body;

        var $error = array();

        /**
         * Create server "connection".
         *
         */
        function connect($host,$port, $useSSL)
        {
                if (strpos($host, 'ssl://') === false && $useSSL) {
                    $this->remote_host = "ssl://$host";
                } else {
                    $this->remote_host = $host;
                }
                $this->remote_port = $port;

        }

        /**
         * Change the method being used to communicate.
         *
         * @param string|null request method. supports GET, POST, and HEAD. default is GET
         */
        function set_method( $method = 'GET' )
        {
                $this->method = strtoupper($method);
        }

        /**
         * Specify a username and password.
         *
         * @param string|null username. defualt is null
         * @param string|null password. defualt is null
         */
        function set_login( $uname = NULL, $passwd = NULL )
        {
                $this->remote_uname = $uname;
                $this->remote_passwd = $passwd;
        }

        /**
         * Query the server
         *
         * @param string containing properly formatted server API. See DA API docs and examples
         * @param string|array query to pass to url
         */
        function query( $request, $content = '' )
        {
                $array_headers = array( 'Host' => "$this->remote_host:$this->remote_port" );
                $this->result = $this->result_header = $this->result_body = '';

                // was content sent as an array? if so, turn it into a string
                if (is_array($content))
                {
                        $pairs = array();

                        foreach ( $content as $key => $value )
                        {
                                $pairs[] = "$key=".urlencode($value);
                        }

                        $content = join('&',$pairs);
                        unset($pairs);
                }

                // instance connection
                $fp = @fsockopen( $this->remote_host, $this->remote_port, $sock_errno, $sock_errstr, 30 );

                if (!$fp)
                {
                        $this->error[] = "$sock_errno - $sock_errstr";
                        return 0;
                }

                // if we have a username and password, add the header
                if ( isset($this->remote_uname) && isset($this->remote_passwd) )
                {
                        $array_headers['Authorization'] = 'Basic '.base64_encode("$this->remote_uname:$this->remote_passwd");
                }

                // for DA skins: if $this->remote_passwd is NULL, try to use the login key system
                if ( $this->remote_passwd == NULL )
                {
                        $array_headers['Cookie'] = "session={$_SERVER['SESSION_ID']}; key={$_SERVER['SESSION_KEY']}";
                }

                // if method is POST, add content length & type headers
                if ( $this->method == 'POST' )
                {
                        $array_headers['Content-type'] = 'application/x-www-form-urlencoded';
                        $array_headers['Content-length'] = strlen($content);
                }
                // else method is GET or HEAD. we don't support anything else right now.
                else
                {
                        $request .= "?$content";
                }

                // prepare query
                $query = "$this->method $request HTTP/1.1\r\n";
                foreach ( $array_headers as $key => $value )
                {
                        $query .= "$key: $value\r\n";
                }
                $query .= "\r\n";

                // if POST we need to append our content
                if ( $this->method == 'POST' && $content )
                {
                        $query .= "$content\r\n\r\n";
                }

                // query connection
                fwrite( $fp, $query, strlen($query) );

                // now load results
                while (!feof($fp))
                {
                        $this->result .= fgets($fp,1024);
                }

                list($this->result_header,$this->result_body) = explode("\r\n\r\n",$this->result,2);

                fclose($fp);
        }

        /**
         * Return the result of a query.
         *
         * @return string result
         */
        function fetch_result()
        {
                return $this->result;
        }

        /**
         * Return the header of result (stuff before body).
         *
         * @return array result header
         */
        function fetch_header()
        {
                $array_headers = explode("\r\n",$this->result_header);

                $array_return = array( 0 => $array_headers[0] );
                unset($array_headers[0]);

                foreach ( $array_headers as $pair )
                {
                        list($key,$value) = explode(": ",$pair,2);
                        $array_return[$key] = $value;
                }

                return $array_return;
        }

        /**
         * Return the body of result (stuff after header).
         *
         * @return string result body
         */
        function fetch_body()
        {
                return $this->result_body;
        }

        /**
         * Return parsed body in array format.
         *
         * @return array result parsed
         */
        function fetch_parsed_body()
        {
                parse_str($this->result_body,$x);
                return $x;
        }

}

?>
