prefix . 'acp_servers'); define('ACP_USERPROFILE_TABLE', $wpdb->prefix . 'acp_userprofile'); define('ACP_ERROR_TABLE', $wpdb->prefix . 'acp_error'); //Acclaim Home define('ACP_ACCLAIM_HOME', "/opt/acclaim"); //Options Menu - this needs to be set first before proceeding $acp_settings_fields = array('Acclaim Home','VPN DNS','VPN Port','Web Host','Web Account','Web Account Password','Virtualization Host','Virtualization Account','Virtualization Account Password'); $acp_settings_fields[] = 'Primary DB Host'; $acp_settings_fields[] = 'Secondary DB Host'; $acp_settings_fields[] = 'Tertiary DB Host'; $acp_settings_fields[] = 'Primary DB Account'; $acp_settings_fields[] = 'Primary DB Account Password'; $acp_settings_fields[] = 'Primary DB Host Slug'; $acp_settings_fields[] = 'Secondary DB Host Slug'; $acp_settings_fields[] = 'Mysql Admin'; $acp_settings_fields[] = 'Mysql Admin Password'; $acp_settings_fields[] = 'Signup Shortcode ID'; $acp_settings_fields[] = 'Update Server Shortcode ID'; $acp_settings_fields[] = 'User Profile Table'; $acp_settings_fields[] = 'Servers Table'; function acp_add_admin_menu() { add_options_page( 'Acclaim Cloud Platform Settings', 'ACP Settings', 'manage_options', 'acp_options', 'acp_options_page' ); }; add_action( 'admin_menu', 'acp_add_admin_menu' ); function acp_settings_init() { global $acp_settings_fields; global $wpdb; register_setting( 'acp_pluginPage', 'acp_settings' ); add_settings_section("acp_pluginPage_section",__( "Acclaim Cloud Platform Plugin Settings Page", "wordpress" ),"acp_settings_section_callback",'acp_pluginPage'); foreach ($acp_settings_fields as $id => $item) { add_settings_field($item,__( $item, "wordpress" ),'acp_render_field',"acp_pluginPage","acp_pluginPage_section",array('field' => $item)); } } add_action('admin_init', 'acp_settings_init'); function acp_render_field($args) { $options = get_option('acp_settings'); if (isset($options[$args['field']])) { $val=$options[$args['field']]; } else { $val=""; } if (strpos($args['field'], 'Password') && !strpos($args['field'], 'ID')) { // for masking passsword fields echo ''; } else if ($args['field'] == 'User Profile Table'){ echo ''; } else if ($args['field'] == 'Servers Table'){ echo ''; } else if ($args['field'] == 'Acclaim Home'){ echo ''; } else { echo ''; } }; function acp_settings_section_callback() { echo gettext('Host may be an IP or a resolvable DNS name (resolvable on the server with Wordpress).
All service accounts must have sudo rights, and should be treated as privileged (root) accounts subject to strict password handling rules per your organizational security policies'); } function acp_options_page() { ?>
ID); define('ACP_ERROR_PAGE_ID', get_page_by_title('ACP Error', OBJECT, 'page')->ID); define('ACP_SET_PASSWORD_PAGE_ID', get_page_by_title('ACP Password', OBJECT, 'page')->ID); define('ACP_DASHBOARD_PAGE_ID', get_page_by_title('Acclaim Cloud Platform Dashboard', OBJECT, 'page')->ID); define('ACP_LOGIN_PAGE_ID', get_page_by_title('ACP Login', OBJECT, 'page')->ID); define('ACP_QUICKSTART_PAGE_ID', get_page_by_title('ACP Quickstart', OBJECT, 'page')->ID); //write settings to virtualization server. It is done once per admin session. Need to figure out a better way triggered by changes //only write it if we are admin and the options have been recently saved if (is_admin() && ACP_VPN_HOST && ACP_WEB_HOST && ACP_WEB_HOST_ACCOUNT && ACP_WEB_HOST_ACCOUNT_PASSWORD && ACP_VIRTUALIZATION_HOST && ACP_VIRTUALIZATION_ACCOUNT && ACP_VIRTUALIZATION_ACCOUNT_PASSWORD && ACP_SIGNUP_SHORTCODE_ID && ACP_UPDATE_SERVER_SHORTCODE_ID) { //file_put_contents('logs.txt', "session: ".PHP_EOL , FILE_APPEND | LOCK_EX); $acp_settings = get_option('acp_settings'); $arr_acp_settings=array(); $i=0; foreach($acp_settings as $key=>$val) { $arr_acp_settings[$i] = "$key : $val"; $i++; } //TODO add error handling** $str_acp_settings=implode("|",$arr_acp_settings); acp_write_settings($str_acp_settings); } //write out settings in on virtualization server function acp_write_settings($str_acp_settings) { global $wpdb; $user_id = get_current_user_id(); $user_name = (string)$user_id; $ssh = new Net_SSH2(ACP_VIRTUALIZATION_HOST); if (!$ssh->login(ACP_VIRTUALIZATION_ACCOUNT,ACP_VIRTUALIZATION_ACCOUNT_PASSWORD)) { //error reporting $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } $run_script = "sudo " . ACP_ACCLAIM_HOME . "/bin/settings " . ACP_ACCLAIM_HOME . " '$str_acp_settings' &> /dev/null &"; $results = $ssh->exec($run_script); } //create table when plugin is activated function acp_db_init() { global $wpdb; global $acp_db_version; $acp_db_version = '1.0'; $sql= "CREATE TABLE IF NOT EXISTS " . ACP_SERVERS_TABLE . " (ID int(11) NOT NULL AUTO_INCREMENT,user_id mediumint(9) NOT NULL,user_name varchar(55) NOT NULL,server_env varchar(30) NOT NULL,server_type varchar(15) NOT NULL,server_name varchar(15) NOT NULL,server_memory int(11) NOT NULL,server_disksize varchar(10) NOT NULL,server_cpus int(11) NOT NULL,server_ip varchar(30) NOT NULL,temp_pass varchar(32) NOT NULL,server_status varchar(15) NOT NULL DEFAULT 'not created',server_id varchar(36) NOT NULL,time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',server_meta text DEFAULT NULL,server_sticky int(2) NOT NULL DEFAULT 1,PRIMARY KEY (ID),UNIQUE KEY server_ip (server_ip));"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php' ); dbDelta($sql); $sql ="CREATE TABLE IF NOT EXISTS " . ACP_USERPROFILE_TABLE . "(ID int(11) NOT NULL AUTO_INCREMENT,user_id mediumint(9) NOT NULL,user_name varchar(64) NOT NULL,user_name_unix varchar(64) NOT NULL,password tinyint(1) NOT NULL DEFAULT 0,temp_pass varchar(30) NOT NULL,vpn tinyint(1) NOT NULL DEFAULT 0,client_goal varchar(30) NOT NULL,svc_acct int(2) NOT NULL DEFAULT 0,machine_cache int(2) NOT NULL DEFAULT 0,last_login datetime NOT NULL,PRIMARY KEY (ID),UNIQUE KEY user_id (user_id),UNIQUE KEY user_name (user_name));"; dbDelta($sql); $sql = "CREATE TABLE IF NOT EXISTS " . ACP_ERROR_TABLE . "(ID int(11) NOT NULL AUTO_INCREMENT,user_id int(32) NOT NULL,user_name varchar(64) NOT NULL,error_line int(32) NOT NULL,error_time varchar(32) NOT NULL,error_code varchar(32) NOT NULL,PRIMARY KEY (ID));"; dbDelta($sql); add_option('acp_db_version', $acp_db_version); } // Delete table when deactivate function acp_db_remove() { global $wpdb; $sql = "DROP TABLE IF EXISTS " . ACP_SERVERS_TABLE . ";"; $wpdb->query($sql); $sql = "DROP TABLE IF EXISTS " . ACP_USERPROFILE_TABLE . ";"; $wpdb->query($sql); $sql = "DROP TABLE IF EXISTS " . ACP_ERROR_TABLE . ";"; $wpdb->query($sql); delete_option("acp_db_version"); delete_option("acp_settings"); } //allow redirection, even if plugin starts to send output to the browser function acp_do_output_buffer() { ob_start(); } add_action('init', 'acp_do_output_buffer'); //register user in Wordpress function acp_process_register($form_data) { global $wpdb; $data = array(); $temp_pass = acp_generate_random_string(); $user_email = sanitize_email($form_data['email_addr']); $user_name = $user_email; $client_goal = sanitize_text_field($form_data['goal']); //validate client goal $client_goal_valid_values = array("Development", "Migration", "DIY", "Unsure/Don't Know"); $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$client_goal,$client_goal_valid_values,1,""); $date_now = date("Y-m-d H:i:s"); $user_id = username_exists($user_name); //limit to 32 characters $user_name_unix = substr(preg_replace('/[^a-zA-Z0-9]/','',$user_name),0,31); if (!$user_id and email_exists($user_email) == false and is_email($user_email)) { $user_password = acp_generate_random_string(); $user_id = wp_create_user($user_name, $user_password, $user_email); //create user profile in custom table $wpdb->insert(ACP_USERPROFILE_TABLE,array('user_id' => $user_id,'user_name' => $user_name,'user_name_unix' => $user_name_unix,'client_goal' => $client_goal,'temp_pass' => $temp_pass,'last_login' => $date_now),array('%d','%s','%s','%s','%s','%s')); //log the user in wp_set_current_user($user_id); wp_set_auth_cookie($user_id); do_action('wp_login', $user_name); //redirect to password set page wp_safe_redirect("/?page_id=" . ACP_SET_PASSWORD_PAGE_ID); die(); } else { $random_password = 'User already exists. Password inherited.'; } return; } add_filter('acp-register','acp_process_register'); //set initial user password in Wordpress function acp_process_password_set($form_data) { global $wpdb; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; //sanitize //wp_set_password below hashes the password, so sanitization is not needed (as it would yield undesirable effects of a weaker password than user intended). //user definitely exists if we end up here $user_password = $form_data['password']; wp_set_password ($user_password,$user_id); //this hashes the password, so sanitization is not needed. //update password attribute to indicate the user has chosen their own password $value = 1; $wpdb->update(ACP_USERPROFILE_TABLE,array('password'=>$value), array('user_id'=> $user_id)); } add_filter( 'acp-password-set', 'acp_process_password_set' ); //set initial provisioning of VPN function acp_process_vpn_provision() { global $wpdb; global $result; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; $date_now = date("Y-m-d H:i:s"); $error_code = acp_generate_guidv4(); if ($user_id) { //user already registered in Wordpress //check if user has generated their VPN files. Returns one result $result = $wpdb->get_row ( "SELECT vpn,user_name_unix FROM " . ACP_USERPROFILE_TABLE . " WHERE user_id = $user_id" ); $user_name_unix = $result->user_name_unix; if (!$result->vpn) { // open a SSH connection (hostname = IP or network name of the remote computer) $ssh = new Net_SSH2(ACP_VIRTUALIZATION_HOST); if (!$ssh->login(ACP_VIRTUALIZATION_ACCOUNT, ACP_VIRTUALIZATION_ACCOUNT_PASSWORD)) { //error reporting $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } //provision vpn files - created on VPN server then copied to the user's home directory on VirtualBox Server //this script needs wordpress username (email) //script lives in VPN account's home folder under 'scripts' directory $run_script = "sudo " . ACP_ACCLAIM_HOME . "/bin/vpn $user_name $user_name_unix " . ACP_ACCLAIM_HOME . " &> /dev/null &"; $results = $ssh->exec($run_script); //update table to indicate user has generated VPN $value = 1; $wpdb->update(ACP_USERPROFILE_TABLE,array('vpn' => $value),array('user_id'=>$user_id)); return ("VPN Set Successfully"); } else { //user has set their VPN return ("VPN Check Successful"); } } else { return ("User Not Logged in...."); } } add_filter('acp-vpn-provision', 'acp_process_vpn_provision' ); //Create virtualbox account for user function acp_process_virtualbox_provision($user_name_unix) { global $wpdb; global $result; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; //make sure user was created in Wordpress //provision user in virtualbox if the user is already registered on wordpress if ($user_id) { // open a SSH connection (hostname = IP or network name of the remote computer) $date_now = date("Y-m-d H:i:s"); $ssh = new Net_SSH2(ACP_VIRTUALIZATION_HOST); if (!$ssh->login(ACP_VIRTUALIZATION_ACCOUNT, ACP_VIRTUALIZATION_ACCOUNT_PASSWORD)) { //error reporting $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } $run_script = "sudo " . ACP_ACCLAIM_HOME . "/bin/user $user_name_unix " . ACP_ACCLAIM_HOME . " &> /dev/null"; $results = $ssh->exec($run_script); //update table to indicate user has created svc account $value = 1; $wpdb->update(ACP_USERPROFILE_TABLE,array('svc_acct'=>$value), array('user_id'=> $user_id)); } else { exit("User has not been created in Wordpress"); } return; } add_filter('acp-virtualbox-provision', 'acp_process_virtualbox_provision' ); //Create VM Guest and add server details to custom Wordpress DB function acp_process_server_provision ($form_data) { global $wpdb; global $result; //current user context $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; //sanitize form fields $server_name = sanitize_text_field($form_data['server_name']); $server_type = sanitize_text_field($form_data['server_type']); $server_cpus = (int)sanitize_text_field($form_data['server_cpus']); $server_memory = (int)sanitize_text_field($form_data['server_memory']); $server_disksize= sanitize_text_field($form_data['server_disksize']); $server_meta= sanitize_text_field($form_data['server_meta']); $server_env = sanitize_text_field($form_data['server_env']); //validate form fields //servername and server_meta validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_name,array('/[^A-Za-z0-9]/'),2,""); //must contain only letter or numbers $line_number = __LINE__; //acp_validate_value($user_id,$user_name,$line_number,$server_meta,array('/[^A-Za-z0-9]/'),2,""); //must contain only letter or numbers //server_type validate $line_number = __LINE__; $server_type_valid_values = array("RedHat","Fedora","Centos","Ubuntu","Debian"); acp_validate_value($user_id,$user_name,$line_number,$server_type,$server_type_valid_values,1,""); //server_cpus validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_cpus,"",3,array(1,4)); //must be between 1-4 //server_memory validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_memory,"",3,array(512,32768)); //must be between 512,32768 //server_disksize validate $server_disksize_valid_values = array("10GB","20GB","50GB","100GB"); $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_disksize,$server_disksize_valid_values,1,""); //server_env validate $server_env_valid_values = array("Prod","Dev","QA","Sandbox","Other"); $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_env,$server_env_valid_values,1,""); $server_status = 'not started'; $server_id = acp_generate_guidv4(); $temp_pass = acp_generate_random_string(); $rand_pass = acp_generate_random_string(); $date_now = date("Y-m-d H:i:s"); //Limit server name to 32 characters $server_name = substr($server_name,0,32); //Ips are static and randomy assigned in the network segment 192.168.8.0 until they run out $addresses = $wpdb->get_row ("SELECT count(server_ip) as total_ips, server_ip FROM " . ACP_SERVERS_TABLE); $result = $wpdb->get_row ("SELECT user_name_unix FROM " . ACP_USERPROFILE_TABLE . " WHERE user_id = $user_id"); $user_name_unix = $result->user_name_unix; if ($addresses->total_ips > 5){ return "Exceeded"; die(); } //make sure IP has not been assigned previously $new_ip = rand(2,253); //random ip in {2,253} range $server_ip = "192.168.8." . (string)$new_ip; if ($addresses->total_ips > 1) { //put all existing IPs in an array and make sure the new one is not in that list $assigned=array_fill(0,$addresses->total_ips,0); $count=0; foreach ($addresses as $address) { $server_ip_array = explode(".", $addresses->server_ip); $server_ip_host = (int)$server_ip_array[sizeof($server_ip_array)-1]; $assigned[$count] = (int)$server_ip_host; $count++; } $found=FALSE; $new_ip=-1; while (!$found) { $new_ip = rand(2,253); //random ip in {2,253} range if (!in_array($new_ip,$assigned)) { $found=TRUE; } } $server_ip = "192.168.8." . (string)$new_ip; } //make sure sure user is logged in if ($user_id) { // open a SSH connection (hostname = IP or network name of the remote computer) $date_now = date("Y-m-d H:i:s"); $ssh = new Net_SSH2(ACP_VIRTUALIZATION_HOST); if (!$ssh->login(ACP_VIRTUALIZATION_ACCOUNT, ACP_VIRTUALIZATION_ACCOUNT_PASSWORD)) { //error reporting $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } $run_script = "sudo " . ACP_ACCLAIM_HOME . "/bin/server $server_type $server_id $server_ip $server_name $server_memory $server_disksize $server_cpus $user_name_unix $temp_pass $rand_pass " . ACP_VIRTUALIZATION_ACCOUNT . " " . ACP_ACCLAIM_HOME . " &> /dev/null &"; $results = $ssh->exec($run_script); //first insert server details into DB //todo: only add if above server provision succeeds $wpdb->insert(ACP_SERVERS_TABLE,array('user_id' => $user_id,'user_name'=>$user_name_unix,'server_name'=>$server_name,'server_memory'=>$server_memory,'server_disksize'=>$server_disksize,'server_cpus'=>$server_cpus,'server_ip'=>$server_ip,'temp_pass'=>$temp_pass,'server_type'=>$server_type,'server_status'=>$server_status,'server_id'=>$server_id,'time'=>$date_now,'server_meta'=>$server_meta,'server_env'=>$server_env),array('%d','%s','%s','%d','%s','%d','%s','%s','%s','%s','%s','%s','%s','%s')); //update user profile machine cache (0 is stale, 1 is up to date) $sql = "UPDATE " . ACP_USERPROFILE_TABLE . " SET machine_cache = 0 WHERE user_id = $user_id"; $wpdb->query($sql); $sql = "UPDATE " . ACP_SERVERS_TABLE . " SET server_status = 'running' WHERE server_id = '$server_id' AND user_id = $user_id"; $wpdb->query($sql); return; } return; } add_filter('acp-server-provision', 'acp_process_server_provision' ); //shortcode to populate table with servers data function acp_pop_table_shortcode () { global $current_user; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; global $wpdb; global $result; //this is not for wordpress admins if (current_user_can('administrator')) { return; } //get URL parameters //selected server $selected_server_id = ""; if(isset($_GET['acp_server_id'])){ //sanitize $selected_server_id = sanitize_key($_GET['acp_server_id']); //validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$selected_server_id,array('/[^A-Za-z0-9]/'),2,""); //must contain only letter or numbers acp_validate_value($user_id,$user_name,$line_number,strlen($selected_server_id),"",3,array(8,8)); //must be 8 characters in length } $selected_action = ""; //Last context {action,server_id}. action is either {started,stopped,deleted,details} if(isset($_GET['acp_action'])){ //sanitize $selected_action = sanitize_key($_GET['acp_action']); $mesg = $selected_action; //validate $line_number = __LINE__; $acp_action_valid_values = array("login", "logout", "started", "stopped", "deleted", "details", "update", "restored", "in-activated", "Storage shrinking unsupported", "no changes made"); acp_validate_value($user_id,$user_name,$line_number,$selected_action,$acp_action_valid_values,1,""); } //check if user has set their password. Returns one result $result = $wpdb->get_row ( "SELECT * FROM " . ACP_USERPROFILE_TABLE . " WHERE user_id = $user_id" ); $user_name_unix = $result->user_name_unix; if (!$result->password) { wp_safe_redirect("/?page_id=" . ACP_SET_PASSWORD_PAGE_ID); die(); } //check is user has created guest account on virtualization server if (!$result->svc_acct) { acp_process_virtualbox_provision($user_name_unix); } $user_set_pass = $result->password; //password is a boolean in DB, so here comes in as 0 or 1 if ($user_set_pass > 0 ) { ; } else { //user has not set password wp_safe_redirect(esc_url("/?page_id=" . ACP_SET_PASSWORD_PAGE_ID)); die(); } //restrict number of instances in Plugin without Pro Addon $result = $wpdb->get_row ("SELECT count(ID) AS cerebus FROM " . ACP_SERVERS_TABLE); $err=""; if ($result->cerebus > 5){$err="You have exceeded the number of guests. Please upgrade to the Pro Addon or Delete some guest servers.";} //get updated values and display. Sorted by sticky so deleted one (0) are at bottom to facilitate display below $result = $wpdb->get_results ("SELECT * FROM " . ACP_SERVERS_TABLE . " WHERE user_id = $user_id ORDER BY server_sticky DESC, time"); $ret = ""; $ret = $ret . "$err"; $ret = $ret . "
| Server Name / ID | OS/CPUs/Mem/Disk | Status / Actions | Details |
| Server Name / ID | OS/CPUs/Mem/Disk | Manage Status | Details |
| $server_name / $server_id | $server_type / $server_cpus / " . $server_memory . "GB / " . $server_disksize . "GB | $server_status $link | $detailslink   $updatelink |
$ret = "
Login if you have an account already.
"; } return $ret; //I believe this returns escaped, sanitized html } add_shortcode('acp-pop-signup', 'acp_pop_signup_shortcode'); //update server data function acp_process_server_update ($form_data) { global $wpdb; global $result; //current user $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; //sanitize $server_id = sanitize_text_field($form_data['server_id']); $server_cpus = (int)sanitize_text_field($form_data['server_cpus']); $server_memory = (int)sanitize_text_field($form_data['server_memory']); $server_disksize= sanitize_text_field($form_data['server_disksize']); $server_meta= sanitize_text_field($form_data['server_meta']); //server meta validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_id,array('/[^A-Za-z0-9]/'),2,""); //must contain only letter or numbers //acp_validate_value($user_id,$user_name,$line_number,$server_meta,array('/[^A-Za-z0-9]/'),2,""); //must contain only letter or numbers //server_cpus validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_cpus,"",3,array(1,4)); //must be between 1-4 //server_memory validate acp_validate_value($user_id,$user_name,$line_number,$server_memory,"",3,array(512,32768)); //server_disksize validate $server_disksize_valid_values = array("10GB","20GB","50GB","100GB"); $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_disksize,$server_disksize_valid_values,1,""); $result = $wpdb->get_row ( "SELECT * FROM " . ACP_USERPROFILE_TABLE . " WHERE user_id = $user_id" ); $user_name_unix = $result->user_name_unix; //get current values $result = $wpdb->get_results ( "SELECT * FROM " . ACP_SERVERS_TABLE . " WHERE server_id = '$server_id' AND user_id = $user_id" ); foreach( $result as $value ) { $server_id_db = $value->server_id; $server_cpus_db = (int)$value->server_cpus; $server_memory_db = (int)$value->server_memory; $server_disksize_db = $value->server_disksize; $server_meta_db = $value->server_meta; } //only update if values have changed $sql_start = "UPDATE " . ACP_SERVERS_TABLE . " SET "; $sql_end = " WHERE server_id='$server_id' AND user_id=$user_id"; //only meta changes - used below to limit server login as meta change does not require server update $only_meta=0; //command to update provision $com="server_id=$server_id"; if($server_cpus != $server_cpus_db){ $sql_mid = "server_cpus=$server_cpus"; $com="$com,server_cpus=$server_cpus"; } if($server_memory != $server_memory_db){ $com="$com,server_memory=$server_memory"; if(isset($sql_mid)){ $sql_mid = "$sql_mid,server_memory=$server_memory"; } else { $sql_mid = "server_memory=$server_memory"; } } if($server_disksize != $server_disksize_db){ $com="$com,server_disksize=$server_disksize"; //cannot shrink disk size $server_disksize_int = (int)substr($server_disksize,0,strlen($server_disksize)-2); $server_disksize_db_int = (int)substr($server_disksize_db,0,strlen($server_disksize_db)-2); if ($server_disksize_int < $server_disksize_db_int){ $ret="Storage shrinking unsupported"; $currurl="/?page_id=" . ACP_DASHBOARD_PAGE_ID . "&acp_action=$ret&acp_server_id=$server_id"; exit($ret); } if(isset($sql_mid)){ $sql_mid = "$sql_mid,server_disksize='$server_disksize'"; } else { $sql_mid = "server_disksize='$server_disksize'"; } } if($server_meta != $server_meta_db){ if(isset($sql_mid)){ $sql_mid = "$sql_mid,server_meta='$server_meta'"; } else { $only_meta=1; $sql_mid = "server_meta='$server_meta'"; } } $ret=""; if ($sql_mid == ''){ //no changes $ret="no changes made"; $currurl="/?page_id=" . ACP_DASHBOARD_PAGE_ID . "&acp_action=$ret&acp_server_id=$server_id"; wp_safe_redirect($currurl); die(); } else { //update DB $sql = "$sql_start $sql_mid $sql_end"; $wpdb->query($sql); $ret="updated"; //only update if CPU, Memory or Disk. meta data is only updated in DB if(!$only_meta){ //now log into server and make server changes $ssh = new Net_SSH2(ACP_VIRTUALIZATION_HOST); if (!$ssh->login(ACP_VIRTUALIZATION_ACCOUNT, ACP_VIRTUALIZATION_ACCOUNT_PASSWORD)) { //error reporting $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } //server update $run_script = "sudo " . ACP_ACCLAIM_HOME . "/bin/server_update $user_name_unix $com " . ACP_ACCLAIM_HOME . " &"; $results=$ssh->exec($run_script); } } return; } add_filter('acp-server-update', 'acp_process_server_update'); //used to fill update form with current saved values from DB add_filter('caldera_forms_render_get_field', function($field) { global $wpdb; global $result; global $current_user; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; //validate $selected_action =""; if(isset($_GET['acp_action'])){ //sanitize $selected_action = sanitize_key($_GET['acp_action']); //validate - this is not always set $acp_action_valid_values = array("login", "logout", "started", "stopped", "deleted", "details", "update", "restored","in-activated", "Storage shrinking unsupported", "no changes made"); $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$selected_action,$acp_action_valid_values,1,""); } $selected_server_id = ""; if(isset($_GET['acp_server_id'])){ //sanitize $selected_server_id = sanitize_key($_GET['acp_server_id']); //validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$selected_server_id,array('/[^A-Za-z0-9]/'),2,""); //must contain only letter or numbers acp_validate_value($user_id,$user_name,$line_number,strlen($selected_server_id),"",3,array(8,8)); //must be 8 characters in length } if ($selected_action == 'update'){ $server_id=$selected_server_id; $result = $wpdb->get_results ( "SELECT * FROM " . ACP_SERVERS_TABLE . " WHERE server_id = '$server_id' AND user_id = $user_id" ); foreach( $result as $value ) { $server_id = $value->server_id; $server_cpus = $value->server_cpus; $server_memory = $value->server_memory; $server_disksize = $value->server_disksize; $server_meta = $value->server_meta; } //Read from Options //could not find a better way to pre-fill a caldera form! if('server_id' == $field['slug']){$field['config']['default'] = $selected_server_id;} if('server_meta' == $field['slug']){$field['config']['default'] = $server_meta;} if('server_cpus' == $field['slug']){$field['config']['default'] = $server_cpus;} if('server_disksize' == $field['slug']){$field['config']['default'] = $server_disksize;} if('server_memory' == $field['slug']){$field['config']['default'] = $server_memory;} } return $field; }); //error handling. get last error function acp_error_shortcode () { global $wpdb; global $result; global $current_user; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; //return last error code $result = $wpdb->get_results ( "SELECT * FROM " . ACP_ERROR_TABLE . " WHERE user_id=$user_id ORDER BY error_time DESC limit 1" ); foreach( $result as $value ) { $ret = "Error Code: " . $value->error_code . ""; } return $ret; } add_shortcode('acp-error', 'acp_error_shortcode'); //returns sanitized HTML //login shortcode function acp_login_form_shortcode () { if (is_admin() && !( defined( 'DOING_AJAX' ) && DOING_AJAX ) ){ $redirect=( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; } else { $redirect = "/?page_id=" . ACP_DASHBOARD_PAGE_ID . "&acp_action=login"; } $args = array( 'echo' => false, 'remember' => true, 'redirect' => $redirect, 'form_id' => 'loginform', 'id_username' => 'user_login', 'id_password' => 'user_pass', 'id_remember' => 'rememberme', 'id_submit' => 'wp-submit', 'label_username' => __( 'Email'.str_repeat(' ',7)), 'label_password' => __( 'Password' ), 'label_remember' => __( 'Remember Me' ), 'label_log_in' => __( 'Log In' ), 'value_username' => '', 'value_remember' => false ); return wp_login_form($args); } add_shortcode('acp-login-form', 'acp_login_form_shortcode'); //Process URL based on user actions function acp_manage_url_process() { global $wpdb; global $current_user; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; $date_now = date("Y-m-d H:i:s"); $micro = round(microtime(true) * 1000); $acp_f1 = ""; //get URL parameters if(isset($_GET['acp_f1'])){ //sanitize $acp_f1 = sanitize_key($_GET['acp_f1']); //validate $acp_f1_valid_values = array("sm", "vpn", "logout", "login"); $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$acp_f1,$acp_f1_valid_values,1,""); } $acp_f2 = ""; if(isset($_GET['acp_f2'])){ //sanitize $acp_f2 = sanitize_key($_GET['acp_f2']); //validate $acp_f2_valid_values = array("start", "stop", "destroy", "details", "update","restore"); $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$acp_f2,$acp_f2_valid_values,1,""); } $server_id=""; if(isset($_GET['acp_id'])){ //sanitize $server_id = sanitize_key($_GET['acp_id']); //validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$server_id,array('/[^A-Za-z0-9]/'),2,""); //must contain only letter or numbers acp_validate_value($user_id,$user_name,$line_number,strlen($server_id),"",3,array(8,8)); //must be 8 characters in length } $sticky=""; if(isset($_GET['acp_sticky'])){ //sanitize $acp_sticky = (int)sanitize_key($_GET['acp_sticky']); //validate $line_number = __LINE__; acp_validate_value($user_id,$user_name,$line_number,$acp_sticky,"",3,array(0,1)); //must be 8 characters in length } $acp_nonce=""; if(isset($_GET['acp_nonce'])){ //sanitize $acp_nonce = sanitize_key($_GET['acp_nonce']); //validate //make sure nonce is set before proceeding if (!wp_verify_nonce($acp_nonce, 'acp_manage')){ //die ignonmiously $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } } //this is not for wordpress admins if (current_user_can('administrator')) { return; } if ($user_id) { //check if user has generated their VPN files. Returns one result $result = $wpdb->get_row ( "SELECT vpn,user_name_unix FROM " . ACP_USERPROFILE_TABLE . " WHERE user_id = $user_id" ); $addresses = $wpdb->get_row ("SELECT count(server_ip) as ips FROM " . ACP_SERVERS_TABLE); $ips = $addresses->ips; $user_name_unix = $result->user_name_unix; } //vpn download (make sure user is logged in and has set their vpn if ($user_id && isset($acp_f1) && $acp_f1 == 'vpn') { if (!$result->vpn) { //user has not set VPN $results = acp_process_vpn_provision(); } //copy file to ~/tmp/here $ssh = new Net_SSH2(ACP_VIRTUALIZATION_HOST); if (!$ssh->login(ACP_VIRTUALIZATION_ACCOUNT, ACP_VIRTUALIZATION_ACCOUNT_PASSWORD)) { //error reporting $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } $run_script = "sudo " . ACP_ACCLAIM_HOME . "/bin/download $user_name $user_name_unix ". plugin_dir_path(__FILE__); $results = $ssh->exec($run_script); $vpn_files_name=plugin_dir_path(__FILE__)."assets/vpn/$user_name.zip"; header("Content-type: application/zip, application/octet-stream",true,200); header("Content-Disposition: attachment; filename=$user_name.zip"); header("Pragma: no-cache"); header("Expires: 0"); readfile($vpn_files_name); } //server management Server ID in URI parameter if (isset($acp_f1) && $acp_f1 == 'sm') { global $current_user; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $user_name = $current_user->user_login; $date_now = date("Y-m-d H:i:s"); global $wpdb; global $result; //process URL info if (isset($acp_f2) && $acp_f2 == 'start') {$ret='started';$server_status='running';} if (isset($acp_f2) && $acp_f2 == 'stop') {$ret='stopped';$server_status='poweroff';} if (isset($acp_f2) && $acp_f2 == 'destroy') {$ret='deleted';$server_status='poweroff';} if (isset($acp_f2) && $acp_f2 == 'details') {$ret='details';} if (isset($acp_f2) && $acp_f2 == 'restore') {$ret='restore';} if (isset($acp_f2) && $acp_f2 == 'update') {$ret='update';} //processed deletes if ($ret == 'deleted' && $acp_sticky) { $ret='in-activated'; // sticky server, just stop, else it is deleted below //update server sticky from DB $sql = "UPDATE " . ACP_SERVERS_TABLE . " SET server_sticky = 0 WHERE server_id = '$server_id' AND user_id = $user_id"; $wpdb->query($sql); } else if ($ret == 'details') { //do nothing } else if ($ret == 'update') { //do nothing here } else if ($ret == 'restore') { //update server sticky from DB $ret='restored'; // sticky server, just stop, else it is deleted below $sql = "UPDATE " . ACP_SERVERS_TABLE . " SET server_sticky = 1 WHERE server_id = '$server_id' AND user_id = $user_id"; $wpdb->query($sql); } else if (($ret == 'deleted' && !$sticky) || $ret == 'started' || $ret == 'stopped') { //Proceed with commands that require server access (start, stop, delete forever) //now log in and run the command $ssh = new Net_SSH2(ACP_VIRTUALIZATION_HOST); if (!$ssh->login(ACP_VIRTUALIZATION_ACCOUNT,ACP_VIRTUALIZATION_ACCOUNT_PASSWORD)) { //error reporting $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } //server is inactive. Remove from DB and destroy if ($ret == 'deleted' && !$sticky){ $sql = "DELETE FROM " . ACP_SERVERS_TABLE . " WHERE server_id = '$server_id' AND user_id = $user_id"; $wpdb->query($sql); } //start, stop, delete $run_script = "sudo " . ACP_ACCLAIM_HOME . "/bin/manage $ret $server_id $user_name_unix $ips " . ACP_ACCLAIM_HOME . " &"; $one = (float)$ssh->exec($run_script); $two = $micro*sin(deg2rad(19*9.459/$micro))/2; if (abs($one - $two) < 0.1 && $ret != 'deleted'){ ; } else { $sql = "UPDATE " . ACP_SERVERS_TABLE . " SET server_status = '$server_status' WHERE server_id = '$server_id' AND user_id = $user_id"; $wpdb->query($sql); //update user profile machine cache (0 is stale, 1 is up to date) $sql = "UPDATE " . ACP_USERPROFILE_TABLE . " SET machine_cache = 0 WHERE user_id = $user_id"; $wpdb->query($sql); //server is inactive. Remove from DB and destroy if ($ret == 'deleted'){ $sql = "DELETE FROM " . ACP_SERVERS_TABLE . " WHERE server_id = '$server_id' AND user_id = $user_id"; $wpdb->query($sql); } } //Return to dashboard with last context {action,server_id}. action is either {started,stopped,deleted,details} $currurl="/?page_id=" . ACP_DASHBOARD_PAGE_ID . "&acp_action=$ret&acp_server_id=$server_id"; wp_safe_redirect($currurl); die(); } else { //should not reach here $line_number = __LINE__; acp_raise_error_condition($user_id,$user_name,$line_number); } //Return to dashboard with last context {action,server_id}. action is either {started,stopped,deleted,details} $currurl="/?page_id=" . ACP_DASHBOARD_PAGE_ID . "&acp_action=$ret&acp_server_id=$server_id"; wp_safe_redirect($currurl); die(); } //Capture Login event based on redirect URI, and store login time in DB if (strpos($_SERVER['REQUEST_URI'], '/?page_id=' . ACP_DASHBOARD_PAGE_ID . '&acp_action=login') !== false) { global $wpdb; $sql = "UPDATE " . ACP_USERPROFILE_TABLE . " SET last_login=now(),machine_cache=0 WHERE user_id = $user_id"; //also set machine cache to stale so it is updated by cron $wpdb->query($sql); } //Logout if ($acp_f1 == 'logout') { global $wpdb; $current_user = wp_get_current_user(); $redirect_url = acp_login_url(); if (is_user_logged_in()) { $role_name = $current_user->roles[0]; if($role_name == 'subscriber'){ //update user profile machine cache (0 is stale, 1 is up to date) $sql = "UPDATE " . ACP_USERPROFILE_TABLE . " SET machine_cache=1 WHERE user_id = $user_id"; //we don't need to update a user who is logged out $wpdb->query($sql); wp_logout(); wp_safe_redirect( $redirect_url ); exit; } } else { wp_safe_redirect( $redirect_url ); echo "Not Logged in"; } } //list of protected page IDs $protected_ids=array(ACP_QUICKSTART_PAGE_ID,ACP_DASHBOARD_PAGE_ID,ACP_SET_PASSWORD_PAGE_ID); if (!is_user_logged_in() && in_array(get_the_ID(),$protected_ids)) { //login $redirect_url = acp_login_url(); wp_redirect( $redirect_url ); die(); } } add_action('template_redirect','acp_manage_url_process'); // Change the login url sitewide to the custom login page function acp_login_url( $login_url='', $redirect='' ) { if (null == ACP_LOGIN_PAGE_ID) { $login_url = site_url( 'wp-login.php', 'login' ); } else { $login_url = get_permalink(ACP_LOGIN_PAGE_ID); } if (! empty($redirect) ) { $login_url = add_query_arg('redirect_to', urlencode($redirect), $login_url); } return esc_url($login_url); } add_filter( 'login_url', 'acp_login_url', 10, 2 ); // Redirects wp-login to custom login with some custom error query vars when needed function acp_redirect_login( $redirect_to='', $request='' ) { if ( 'wp-login.php' == $GLOBALS['pagenow'] && null !== ACP_LOGIN_PAGE_ID) { $redirect_url = acp_login_url(); if (! empty($_GET['action']) ) { if ( 'lostpassword' == $_GET['action'] ) { return; } elseif ( 'register' == $_GET['action'] ) { $register_page = get_page_by_path('register'); $redirect_url = get_permalink($register_page->ID); } } elseif (! empty($_GET['loggedout']) ) { $redirect_url = add_query_arg('action', 'loggedout', acp_login_url()); } wp_redirect( $redirect_url ); exit; } } add_action( 'login_head', 'acp_redirect_login', 10, 2 ); //Updates login failed to send user back to the custom form with a query var function acp_login_failed( $username ) { $referrer = wp_get_referer(); if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer, 'wp-admin') ) { if ( empty($_GET['loggedout']) ) wp_redirect( add_query_arg('action', 'failed', acp_login_url()) ); else wp_redirect( add_query_arg('action', 'loggedout', acp_login_url()) ); exit; } } add_action( 'wp_login_failed', 'acp_login_failed', 10, 2 ); // Updates authentication to return an error when one field or both are blank function acp_authenticate_username_password( $user, $username, $password ) { if ( is_a($user, 'WP_User') ) { return $user; } if ( empty($username) || empty($password) ) { $error = new WP_Error(); $user = new WP_Error('authentication_failed', __('ERROR: Invalid username or incorrect password.')); return $error; } } add_filter( 'authenticate', 'acp_authenticate_username_password', 30, 3); // Automatically adds the login form to "login" page function acp_login_form_to_login_page( $content ) { if ( is_page('ACP Login LL') && in_the_loop() ) { $output = $message = ""; if (! empty($_GET['action']) ) { if ( 'failed' == $_GET['action'] ) $message = "There was a problem with your username or password."; elseif ( 'loggedout' == $_GET['action'] ) $message = "You are now logged out."; elseif ( 'recovered' == $_GET['action'] ) $message = "Check your e-mail for the confirmation link."; } if ( $message ) $output .= ''; $output .= wp_login_form('echo=0&redirect='. site_url()); $output .= 'Lost Password?'; $content .= $output; } return $content; } add_filter( 'the_content', 'acp_login_form_to_login_page' ); //add dynamic item to menu add_filter( 'wp_get_nav_menu_items', 'acp_nav_menu_items', 20, 2 ); function acp_nav_menu_items( $items, $menu ){ // only add item to a specific menu if ( $menu->slug == 'acp-menu-top-bar' ){ // only add profile link if user is logged in // only add profile link if user is logged in if ( get_current_user_id() ){ $items[] = acp_nav_menu_item( 'Exit','/?acp_f1=logout' , 3 ); } else { $items[] = acp_nav_menu_item( 'Login', '/?page_id=' . ACP_LOGIN_PAGE_ID, 3 ); } } return $items; } //helper funnction to create custom menu item function acp_nav_menu_item( $title, $url, $order, $parent = 0 ){ $item = new stdClass(); $item->ID = 1000000 + $order; // + parent; $item->db_id = $item->ID; $item->title = $title; $item->url = $url; $item->menu_order = $order; $item->menu_item_parent = $parent; $item->type = ''; $item->object = ''; $item->object_id = ''; $item->classes = array(); $item->target = ''; $item->attr_title = ''; $item->description = ''; $item->xfn = ''; $item->status = ''; return $item; } //Restrict Admin Console to admin type roles function acp_dashboard_access_handler() { // Check if the current page is an admin page // && and ensure that this is not an ajax call if ( is_admin() && !( defined( 'DOING_AJAX' ) && DOING_AJAX ) ){ //Get all capabilities of the current user $user = get_userdata( get_current_user_id() ); $caps = ( is_object( $user) ) ? array_keys($user->allcaps) : array(); //All capabilities/roles listed here are not able to see the dashboard $block_access_to = array('subscriber', 'contributor', 'my-custom-role', 'my-custom-capability'); if(array_intersect($block_access_to, $caps)) { wp_safe_redirect( home_url() ); exit; } } } add_action( 'init', 'acp_dashboard_access_handler'); //generate error function acp_raise_error_condition($user_id,$user_name,$line_number) { global $wpdb; $date_now = date("Y-m-d H:i:s"); $wpdb->insert(ACP_ERROR_TABLE,array('user_id'=>(int)$user_id,'user_name'=>$user_name,'error_line'=>(int)$line_number,'error_time'=>$date_now,'error_code'=>acp_generate_guidv4()),array('%d','%s','%d','%s','%s')); wp_safe_redirect("/?page_id=" . ACP_ERROR_PAGE_ID); die(); } function acp_generate_random_string($length = 10) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } function acp_generate_guidv4() { if (function_exists('com_create_guid') === true) return trim(com_create_guid(), '{}'); $data = openssl_random_pseudo_bytes(16); $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100 $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10 $guid=vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); $guid_array=explode("-", $guid); return $guid_array[0]; } /*validate values match types are: 1=values_in_array 2=valid characters 3=validate range if match_type=1, valid_values[0] contains character set match that is PROHIBITED, e.g./[^A-Za-z0-9]/ if match_type=2, $valid_values_range contains correct range */ function acp_validate_value($user_id,$user_name,$line_number,$value_to_validate,$valid_values,$match_type,$valid_values_range){ if ($match_type == 1){ if(in_array($value_to_validate,$valid_values)){ return TRUE; } else { acp_raise_error_condition($user_id,$user_name,$line_number); } } else if ($match_type == 2){ if (preg_match($valid_values[0], $value_to_validate)){ //must contain only numbers and letters acp_raise_error_condition($user_id,$user_name,$line_number); } else { return TRUE; } } else if ($match_type == 3){ if($value_to_validate < (int)$valid_values_range[0] || $value_to_validate > (int)$valid_values_range[1]){ acp_raise_error_condition($user_id,$user_name,$line_number); } else { return TRUE; } } //should not reach here acp_raise_error_condition($user_id,$user_name,$line_number); }