Initial commit: Atomaste website

This commit is contained in:
2025-12-10 12:17:30 -05:00
commit 0b9e5d1605
19260 changed files with 5206382 additions and 0 deletions

View File

@@ -0,0 +1,259 @@
<?php
/**
* @package CloudWays
* @author Rogier Lankhorst
* @copyright Copyright (C) 2021, Rogier Lankhorst
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3
* @link https://really-simple-ssl.com
* @since Class available since Release 5.0.0
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
require_once rsssl_path . 'lib/admin/class-encryption.php';
use RSSSL\lib\admin\Encryption;
class rsssl_Cloudways {
use Encryption;
private $email;
private $api_key;
public $ssl_installation_url;
/**
* Initiates the cloudways class.
*
* @param string $email
* @param string $api_key
*/
public function __construct( ) {
$this->email = rsssl_get_option('cloudways_user_email');
$this->api_key = $this->decrypt_if_prefixed( rsssl_get_option('cloudways_api_key') );
$this->ssl_installation_url = "";
}
/**
*
* @param string $method GET|POST|PUT|DELETE
* @param string $url relative URL for the call
* @param string $accessToken Access token generated using OAuth Call
* @param array $post Optional post data for the call
*
* @return RSSSL_RESPONSE
*/
private function callCloudwaysAPI( $method, $url, $accessToken, $post = [] ) {
$baseURL = 'https://api.cloudways.com/api/v1/';
try {
$ch = curl_init();
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method );
curl_setopt( $ch, CURLOPT_URL, $baseURL . $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
if ( $accessToken ) {
curl_setopt( $ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $accessToken ] );
}
//ssl_domains[]=fungibleownership.com&ssl_domains[]=www.fungibleownership.com
$encoded = '';
if ( count( $post ) ) {
foreach ( $post as $name => $value ) {
if ( is_array( $value) ) {
foreach ( $value as $sub_value ) {
$encoded .= $name.'[]='.urlencode( $sub_value) . '&';
}
} else {
$encoded .= urlencode( $name ) . '=' . urlencode( $value ) . '&';
}
}
$encoded = substr( $encoded, 0, strlen( $encoded ) - 1 );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $encoded );
curl_setopt( $ch, CURLOPT_POST, 1 );
}
$output = curl_exec( $ch );
$httpcode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
if ($output && isset($output->error_description)) {
return new RSSSL_RESPONSE( 'error', 'stop', $output->error_description, false );
} else if ($httpcode != '200' && $output && isset($output->message) ){
return new RSSSL_RESPONSE( 'error', 'stop', $output->message );
} else if ( $httpcode != '200' ) {
$message = $httpcode . ' output: ' . substr( $output, 0, 10000 );
return new RSSSL_RESPONSE( 'error', 'stop', $message );
}
curl_close( $ch );
return new RSSSL_RESPONSE( 'success', 'continue', '', json_decode( $output ) );
} catch(Exception $e) {
return new RSSSL_RESPONSE( 'error', 'stop', $e->getMessage() );
}
}
/**
* Get an access token
* @return RSSSL_RESPONSE
*/
private function getAccessToken() {
$accessToken = get_transient('rsssl_cw_t');
if (!$accessToken) {
$response = $this->callCloudwaysAPI( 'POST', '/oauth/access_token', null, [ 'email' => $this->email, 'api_key' => $this->api_key ] );
if ($response->status === 'success' ) {
$accessToken = $response->output->access_token;
set_transient('rsssl_cw_t', $accessToken, 1800);
} else {
return new RSSSL_RESPONSE( 'error', 'stop', $response->message );
}
}
return new RSSSL_RESPONSE( 'success', 'continue','', $accessToken );
}
/**
* @param array $domains
*
* @return RSSSL_RESPONSE
*/
public function installSSL($domains){
$response = $this->getAccessToken();
if ( $response->status !== 'success' ) {
return new RSSSL_RESPONSE('error','stop',$response->message);
}
$accessToken = $response->output;
$response = $this->getServerInfo();
if ($response->status === 'success' ) {
$server_id = get_transient('rsssl_cw_server_id' );
$app_id = get_transient('rsssl_cw_app_id');
$args = [
'server_id' => $server_id,
'app_id' => $app_id,
'ssl_email' => $this->email,
'wild_card' => RSSSL_LE()->letsencrypt_handler->is_wildcard(),
'ssl_domains' => $domains,
];
$response = $this->callCloudWaysAPI( 'POST', 'security/lets_encrypt_install', $accessToken, $args );
}
return $response;
}
/**
*
* @return RSSSL_RESPONSE
*/
public function enableAutoRenew(){
$response = $this->getAccessToken();
if ( $response->status !== 'success' ) {
return new RSSSL_RESPONSE('error','stop', __("Failed retrieving access token","really-simple-ssl"));
}
$accessToken = $response->output;
$response = $this->getServerInfo();
if ($response->status === 'success' ) {
$app_id = get_transient('rsssl_cw_app_id');
$server_id = get_transient('rsssl_cw_server_id' );
$response = $this->callCloudWaysAPI( 'POST', 'security/lets_encrypt_auto', $accessToken,
[
'server_id' => $server_id,
'app_id' => $app_id,
'auto' => true,
]
);
}
if ( $response->status === 'success' ) {
$status = 'success';
$action = 'continue';
$message = __("Successfully installed Let's Encrypt","really-simple-ssl");
} elseif ($response->status === 'error') {
//in some cases, the process is already started, which also signifies success.
if ( strpos($response->message, 'An operation is already in progress for this server')) {
$status = 'success';
$action = 'continue';
$message = __("Successfully installed Let's Encrypt","really-simple-ssl");
} else {
$status = $response->status;
$action = $response->action;
$message = $response->message;
}
} else {
$status = $response->status;
$action = $response->action;
$message = __("Error enabling auto renew for Let's Encrypt","really-simple-ssl");
}
return new RSSSL_RESPONSE( $status, $action, $message );
}
/**
* Get the server id and app id
*
* @return RSSSL_RESPONSE
*/
public function getServerInfo(){
if ( get_transient('rsssl_cw_app_id') && get_transient('rsssl_cw_server_id' ) ) {
$status = 'success';
$action = 'continue';
$message = __("Successfully retrieved server id and app id","really-simple-ssl");
return new RSSSL_RESPONSE( $status, $action, $message );
}
$response = $this->getAccessToken();
if ( $response->status !== 'success' ) {
return new RSSSL_RESPONSE('error','stop', $response->message);
}
$accessToken = $response->output;
$response = $this->callCloudwaysAPI('GET', '/server', $accessToken );
$success = false;
if ($response->status === 'success') {
$serverList = $response->output;
$servers = $serverList->servers;
foreach ($servers as $server ){
$apps = $server->apps;
foreach ($apps as $app ){
$app_domain = $app->cname;
$this_site_domain = str_replace(array('https://', 'http://', 'www.'), '',site_url());
if (strpos($app_domain, $this_site_domain) !== false ) {
$success = true;
set_transient('rsssl_cw_app_id', $app->id, WEEK_IN_SECONDS);
set_transient('rsssl_cw_server_id', $server->id, WEEK_IN_SECONDS);
break 2;
}
}
}
}
if ( $success ) {
$status = 'success';
$action = 'continue';
$message = __("Successfully retrieved server id and app id","really-simple-ssl");
} else {
$status = 'error';
$action = 'stop';
if ( isset($serverList->error_description) ) {
$message = $serverList->error_description;
} else {
$message = __("Could not retrieve server list","really-simple-ssl");
}
}
return new RSSSL_RESPONSE( $status, $action, $message );
}
}

View File

@@ -0,0 +1,62 @@
<?php defined( 'ABSPATH' ) or die();
function rsssl_cloudways_server_data(){
require_once( rsssl_le_path . 'integrations/cloudways/cloudways.php' );
$cloudways = new rsssl_Cloudways();
return $cloudways->getServerInfo();
}
function rsssl_cloudways_install_ssl(){
if (rsssl_is_ready_for('installation')) {
require_once( rsssl_le_path . 'integrations/cloudways/cloudways.php' );
$domains = RSSSL_LE()->letsencrypt_handler->get_subjects();
$cloudways = new rsssl_Cloudways();
$response = $cloudways->installSSL($domains);
if ($response->status === 'success') {
update_option('rsssl_le_certificate_installed_by_rsssl', 'cloudways', false);
}
return $response;
} else {
$status = 'error';
$action = 'stop';
$message = __("The system is not ready for the installation yet. Please run the wizard again.", "really-simple-ssl");
return new RSSSL_RESPONSE($status, $action, $message);
}
}
function rsssl_cloudways_auto_renew(){
require_once( rsssl_le_path . 'integrations/cloudways/cloudways.php' );
$cloudways = new rsssl_Cloudways();
return $cloudways->enableAutoRenew();
}
function rsssl_cloudways_add_condition_actions($fields){
$index = array_search('installation',array_column($fields,'id'));
$fields[$index]['actions'] = array(
array(
'description' => __("Retrieving Cloudways server data...", "really-simple-ssl"),
'action'=> 'rsssl_cloudways_server_data',
'attempts' => 5,
'status' => 'inactive',
),
array(
'description' => __("Installing SSL certificate...", "really-simple-ssl"),
'action'=> 'rsssl_cloudways_install_ssl',
'attempts' => 5,
'status' => 'inactive',
),
array(
'description' => __("Enabling auto renew...", "really-simple-ssl"),
'action'=> 'rsssl_cloudways_auto_renew',
'attempts' => 5,
'status' => 'inactive',
),
);
//drop store credentials field
$creds_index = array_search('store_credentials',array_column($fields,'id'));
unset($fields[$creds_index]);
return $fields;
}
add_filter( 'rsssl_fields', 'rsssl_cloudways_add_condition_actions' );

View File

@@ -0,0 +1,336 @@
<?php
defined( 'ABSPATH' ) or die();
require_once rsssl_path . 'lib/admin/class-encryption.php';
use RSSSL\lib\admin\Encryption;
require_once( rsssl_le_path . 'integrations/cpanel/functions.php' );
/**
* Completely rebuilt and improved on the FreeSSL.tech Auto CPanel class by Anindya Sundar Mandal
*/
class rsssl_cPanel
{
use Encryption;
public $host;
private $username;
private $password;
public $ssl_installation_url;
/**
* Initiates the cPanel class.
*/
public function __construct()
{
$username = rsssl_get_option('cpanel_username');
$password = $this->decrypt_if_prefixed( rsssl_get_option('cpanel_password') );
$host = rsssl_get_option('cpanel_host');
$this->host = str_replace( array('http://', 'https://', ':2083',':'), '', $host );
$this->username = $username;
$this->password = $password;
$this->ssl_installation_url = 'https://'.$this->host.":2083/frontend/jupiter/ssl/install.html";
}
/**
* Check if all creds are available
* @return bool
*/
public function credentials_available(){
if (!empty($this->host) && !empty($this->password) && !empty($this->username)) {
return true;
}
return false;
}
/**
* Install SSL for all passed domains
* @param array $domains
*
* @return RSSSL_RESPONSE
*/
public function installSSL($domains) {
$response = false;
if ( is_array($domains) && count($domains)>0 ) {
foreach( $domains as $domain ) {
$response_item = $this->installSSLPerDomain($domain);
//set on first iteration
if ( !$response ) {
$response = $response_item;
}
//override if not successfull, to always get the error.
if ( $response->status !== 'success' ) {
$response = $response_item;
}
}
}
if ( !$response ) {
$response = new RSSSL_RESPONSE('error', 'stop', __("No valid list of domains.", "really-simple-ssl"));
}
if ( $response->status === 'success' ) {
update_option('rsssl_le_certificate_installed_by_rsssl', 'cpanel:default', false);
}
return $response;
}
/**
* Install an SSL certificate on the domain provided - using cPanel UAPI.
*
* @param string $domain
*
* @return RSSSL_RESPONSE
*/
public function installSSLPerDomain($domain)
{
$shell_addon_active = defined('rsssl_shell_path');
$key_file = get_option('rsssl_private_key_path');
$cert_file = get_option('rsssl_certificate_path');
$cabundle_file = get_option('rsssl_intermediate_path');
$request_uri = 'https://'.$this->host.':2083/execute/SSL/install_ssl';
$payload = [
'domain' => $domain,
'cert' => file_get_contents($cert_file),
'key' => file_get_contents($key_file),
'cabundle' => file_get_contents($cabundle_file),
];
$response_raw = $this->connectUapi($request_uri, $payload);
$isIpBlock = $this->isIpBlock($response_raw);
$isLoginError = !$isIpBlock && $this->isLoginError($response_raw);
$response = json_decode($response_raw);
//Validate $response
if ($isIpBlock) {
update_option( 'rsssl_installation_error', 'cpanel:autossl', false );
$status = 'error';
$action = 'stop';
$message = __( "Your website's ip address is blocked. Please add your domain's ip address to the security policy in CPanel", "really-simple-ssl" );
} else if ($isLoginError) {
update_option('rsssl_installation_error', 'cpanel:autossl', false);
$status = 'error';
$action = 'stop';
$message = __("Login credentials incorrect. Please check your login credentials for cPanel.","really-simple-ssl");
} else if ( empty($response) ) {
update_option('rsssl_installation_error', 'cpanel:default', false);
$status = 'warning';
$action = $shell_addon_active ? 'skip' : 'continue';
$message = rsssl_get_manual_instructions_text($this->ssl_installation_url);
} else if ($response->status) {
delete_option('rsssl_installation_error' );
$status = 'success';
$action = 'continue';
$message = sprintf(__("SSL successfully installed on %s","really-simple-ssl"), $domain);
} else {
update_option('rsssl_installation_error', 'cpanel:default', false);
$status = 'error';
$action = $shell_addon_active ? 'skip' : 'continue';
$message = __("Errors were reported during installation.","really-simple-ssl").'<br> '.$response->errors[0];
}
return new RSSSL_RESPONSE($status, $action, $message);
}
/**
* Based on the known output of an ip block html page, check if the user should whitelist their own website ip.
* @param $raw
*
* @return bool
*/
public function isIpBlock($raw){
$triggers = [
'security_policy',
'You appear to be logging in from an unknown location',
'unrecognized IP address',
];
foreach($triggers as $key => $trigger ) {
if (strpos($raw,$trigger)!==false) {
return true;
}
}
return false;
}
/**
* Based on the known output of an ip block html page, check if the user has entered incorrect login creds
* @param $raw
*
* @return bool
*/
public function isLoginError($raw){
$triggers = [
'input-field-login icon password',
'name="pass" id="pass"',
];
foreach($triggers as $key => $trigger ) {
if (strpos($raw,$trigger)!==false) {
return true;
}
}
return false;
}
/**
* @param $domains
*
* @return RSSSL_RESPONSE
*/
public function enableAutoSSL($domains){
$domains = implode(',', $domains);
$request_uri = 'https://'.$this->host.':2083/execute/SSL/remove_autossl_excluded_domains';
$payload = [
'domains' => $domains,
];
$response_raw = $this->connectUapi($request_uri, $payload);
$isIpBlock = $this->isIpBlock($response_raw);
$response = json_decode($response_raw);
//Validate $response
if ($isIpBlock) {
update_option('rsssl_installation_error', 'cpanel:autossl', false);
$status = 'error';
$action = 'stop';
$message = __("Your website's ip address is blocked. Please add your domain's ip address to the security policy in CPanel","really-simple-ssl");
} else if (empty($response)) {
update_option('rsssl_installation_error', 'cpanel:autossl', false);
$status = 'error';
$action = 'skip';
$message = rsssl_get_manual_instructions_text($this->ssl_installation_url);
} else if ($response->status) {
delete_option('rsssl_installation_error');
$status = 'success';
$action = 'finalize';
$message = __("SSL successfully installed on $domains","really-simple-ssl");
} else {
update_option('rsssl_installation_error', 'cpanel:autossl', false);
$status = 'error';
$action = 'skip';//we try the default next
$message = __("Errors were reported during installation.","really-simple-ssl").'<br> '.$response->errors[0];
}
return new RSSSL_RESPONSE($status, $action, $message);
}
/**
* Connect to the cPanel using UAPI.
*
* @param string $request_uri
* @param null|array $payload
*
* @return mixed
*/
public function connectUapi($request_uri, $payload = null)
{
// Set up the cURL request object.
$ch = curl_init($request_uri);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $this->username.':'.$this->password);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 131072);
if (null !== $payload) {
// Set up a POST request with the payload.
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Make the call, and then terminate the cURL caller object.
$curl_response = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
curl_close($ch);
//return output.
return $curl_response;
}
/**
* Set DNS TXT record using Json API through cPanel XMLAPI.
*
* @param string $domain
* @param string $value
*
* @return RSSSL_RESPONSE
*/
public function set_txt_record($domain, $value)
{
$args = [
'domain' => $domain,
'name' => '_acme-challenge',
'type' => 'TXT',
'txtdata' => $value,
'ttl' => '600',
'class' => 'IN',
'cpanel_jsonapi_user' => $this->username,
'cpanel_jsonapi_module' => 'ZoneEdit',
'cpanel_jsonapi_func' => 'add_zone_record',
'cpanel_jsonapi_apiversion' => '2',
];
$args = http_build_query($args, '', '&');
$url = 'https://'.$this->host.':2083/json-api/cpanel';
$authstr = 'Authorization: Basic '.base64_encode($this->username.':'.$this->password)."\r\n";
$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_BUFFERSIZE, 131072);
$header[0] = $authstr.
"Content-Type: application/x-www-form-urlencoded\r\n".
'Content-Length: '.\strlen($args)."\r\n"."\r\n".$args;
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_POST, 1);
$response = curl_exec($curl);
curl_close($curl);
if (false === $response) {
return new RSSSL_RESPONSE('error', 'stop', __("Unable to connect to cPanel", "really-simple-ssl").' '.curl_error($curl));
}
if (true === stristr($response, '<html>')) {
return new RSSSL_RESPONSE('error', 'stop', __("Login credentials incorrect", "really-simple-ssl"));
}
$response_array = json_decode($response, true);
if ( isset($response_array['cpanelresult']['data'][0]['result']['status']) ) {
if ($response_array['cpanelresult']['data'][0]['result']['status']) {
$status = 'success';
$action = 'continue';
$message = __("Successfully added TXT record.","really-simple-ssl");
} else {
$status = 'warning';
$action = 'continue';
$message = __("Could not automatically add TXT record. Please proceed manually, following the steps below.","really-simple-ssl");
if (isset($response_array['cpanelresult']['data'][0]['result']['statusmsg'])) {
$message .= '<br>'.$response_array['cpanelresult']['data'][0]['result']['statusmsg'];
}
}
return new RSSSL_RESPONSE($status, $action, $message);
}
$event_result = (bool) $response_array['cpanelresult']['event']['result'];
$preevent_result = isset($response_array['cpanelresult']['preevent']) ? (bool) $response_array['cpanelresult']['preevent']['result'] : true; //Some cPanel doesn't provide this key. In that case, ignore it by setting 'true'.
$postevent_result = isset($response_array['cpanelresult']['postevent']) ? (bool) $response_array['cpanelresult']['postevent']['result'] : true; //Some cPanel doesn't provide this key. In that case, ignore it by setting 'true'.
if ($event_result && $preevent_result && $postevent_result) {
$status = 'success';
$action = 'continue';
$message = __("Successfully added TXT record.","really-simple-ssl");
} else {
$status = 'warning';
$action = 'continue';
$message = __("Could not automatically add TXT record. Please proceed manually, following the steps below.","really-simple-ssl");
}
return new RSSSL_RESPONSE($status, $action, $message);
}
}

View File

@@ -0,0 +1,117 @@
<?php
defined( 'ABSPATH' ) or die();
function rsssl_install_cpanel_autossl(){
if ( rsssl_is_ready_for('installation') ) {
$cpanel = new rsssl_cPanel();
$domains = RSSSL_LE()->letsencrypt_handler->get_subjects();
$response = $cpanel->enableAutoSSL($domains);
if ( $response->status === 'success' ) {
update_option('rsssl_le_certificate_installed_by_rsssl', 'cpanel:autossl', false);
}
return $response;
}
$status = 'error';
$action = 'stop';
$message = __("The system is not ready for the installation yet. Please run the wizard again.", "really-simple-ssl");
return new RSSSL_RESPONSE($status, $action, $message);
}
function rsssl_install_cpanel_default(){
if (rsssl_is_ready_for('installation')) {
$cpanel = new rsssl_cPanel();
$domains = RSSSL_LE()->letsencrypt_handler->get_subjects();
$response = $cpanel->installSSL($domains);
if ( $response->status === 'success' ) {
update_option('rsssl_le_certificate_installed_by_rsssl', 'cpanel:default', false);
}
return $response;
}
$status = 'error';
$action = 'stop';
$message = __("The system is not ready for the installation yet. Please run the wizard again.", "really-simple-ssl");
return new RSSSL_RESPONSE($status, $action, $message);
}
function rsssl_cpanel_set_txt_record(){
if ( rsssl_is_ready_for('dns-verification') ) {
$cpanel = new rsssl_cPanel();
$tokens = get_option('rsssl_le_dns_tokens');
if ( !$tokens) {
$status = 'error';
$action = 'stop';
$message = __('Token not generated. Please complete the previous step.',"really-simple-ssl");
return new RSSSL_RESPONSE($status, $action, $message);
}
foreach ($tokens as $domain => $token){
if (strpos($domain, '*') !== false) continue;
$response = $cpanel->set_txt_record($domain, $token);
}
if ( $response->status === 'success' ) {
update_option('rsssl_le_dns_configured_by_rsssl', true, false);
}
return $response;
} else {
$status = 'error';
$action = 'stop';
$message = __("The system is not ready for the DNS verification yet. Please run the wizard again.", "really-simple-ssl");
return new RSSSL_RESPONSE($status, $action, $message);
}
}
/**
* Add actions for cpanel
* @param array $fields
*
* @return array
*/
function rsssl_cpanel_add_condition_actions($fields){
$cpanel = new rsssl_cPanel();
if ( $cpanel->credentials_available() ) {
//this defaults to true, if not known.
$auto_ssl = RSSSL_LE()->hosts->host_api_supported( 'cpanel:autossl' );
$default_ssl = RSSSL_LE()->hosts->host_api_supported( 'cpanel:default' );
$installation_index = array_search( 'installation', array_column( $fields, 'id' ) );
$dns_index = array_search( 'dns-verification', array_column( $fields, 'id' ) );
//clear existing array
if ( $auto_ssl || $default_ssl ) {
$fields[ $installation_index ]['actions'] = array();
}
if ( $auto_ssl ) {
$fields[ $installation_index ]['actions'][] = [
'description' => __( "Attempting to install certificate using AutoSSL...", "really-simple-ssl" ),
'action' => 'rsssl_install_cpanel_autossl',
'attempts' => 1,
'status' => 'inactive',
];
}
if ( $default_ssl ) {
$fields[ $dns_index ]['actions'][] = [
'description' => __( "Attempting to set DNS txt record...", "really-simple-ssl" ),
'action' => 'rsssl_cpanel_set_txt_record',
'attempts' => 1,
'status' => 'inactive',
];
$fields[ $installation_index ]['actions'][] = [
'description' => __( "Attempting to install certificate...", "really-simple-ssl" ),
'action' => 'rsssl_install_cpanel_default',
'attempts' => 1,
'status' => 'inactive',
];
}
}
return $fields;
}
add_filter("rsssl_fields", "rsssl_cpanel_add_condition_actions");

View File

@@ -0,0 +1,146 @@
<?php
defined( 'ABSPATH' ) or die();
require_once rsssl_path . 'lib/admin/class-encryption.php';
use RSSSL\lib\admin\Encryption;
/**
* @package DirectAdmin
* @author Rogier Lankhorst
* @copyright Copyright (C) 2021, Rogier Lankhorst
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3
* @link https://really-simple-ssl.com
* @since Class available since Release 5.0.0
*
*/
require_once( rsssl_le_path . 'integrations/directadmin/httpsocket.php' );
require_once( rsssl_le_path . 'integrations/directadmin/functions.php' );
class rsssl_directadmin {
use Encryption;
public $host;
private $login;
private $password;
public $ssl_installation_url;
/**
* Initiates the directadmin class.
*
*/
public function __construct() {
$password = $this->decrypt_if_prefixed( rsssl_get_option( 'directadmin_password' ) );
$host = rsssl_get_option( 'directadmin_host' );
$this->host = str_replace( array( 'http://', 'https://', ':2222' ), '', $host );
$this->login = rsssl_get_option( 'directadmin_username' );
$this->password = $password;
$this->ssl_installation_url = 'https://' . $this->host . "";
}
/**
* Check if all creds are available
* @return bool
*/
public function credentials_available(){
if (!empty($this->host) && !empty($this->password) && !empty($this->login)) {
return true;
}
return false;
}
public function installSSL( $domains ) {
$response = false;
if ( is_array($domains) && count($domains)>0 ) {
foreach( $domains as $domain ) {
$response_item = $this->installSSLPerDomain($domain);
//set on first iteration
if ( !$response ) {
$response = $response_item;
}
//override if not successfull, to always get the error.
if ( $response->status !== 'success' ) {
$response = $response_item;
}
}
}
if ( !$response ) {
$response = new RSSSL_RESPONSE('error', 'stop', __("No valid list of domains.", "really-simple-ssl"));
}
return $response;
}
/**
* Install certificate
*
* @param string $domain
*
* @return RSSSL_RESPONSE
*/
public function installSSLPerDomain( $domain ) {
$key_file = get_option( 'rsssl_private_key_path' );
$cert_file = get_option( 'rsssl_certificate_path' );
$cabundle_file = get_option( 'rsssl_intermediate_path' );
try {
$server_ssl=true;
$server_port=2222;
$sock = new HTTPSocket;
if ($server_ssl){
$sock->connect("ssl://".$this->host, $server_port);
} else {
$sock->connect($this->host, $server_port);
}
$sock->set_login($this->login, $this->password);
$sock->method = "POST";
$sock->query('/CMD_API_SSL',
array(
'domain' => $domain,
'action' => 'save',
'type' => 'paste',
'certificate' => file_get_contents( $key_file ) . file_get_contents( $cert_file )
));
$response = $sock->fetch_parsed_body();
//set a default error response
$status = 'warning';
$action = 'continue';
$message = rsssl_get_manual_instructions_text($this->ssl_installation_url);
//if successful, proceed to next step
if ( empty($response['details']) && stripos($response[0], 'Error' ) ) {
$sock->query('/CMD_SSL',
array(
'domain' => $domain,
'action' => 'save',
'type' => 'cacert',
'active' => 'yes',
'cacert' => file_get_contents( $cabundle_file )
));
$response = $sock->fetch_parsed_body();
if ( empty($response['details']) && stripos($response[0], 'Error' ) ) {
$status = 'success';
$action = 'finalize';
$message = sprintf(__("SSL successfully installed on %s","really-simple-ssl"), $domain);
update_option( 'rsssl_le_certificate_installed_by_rsssl', 'directadmin', false );
delete_option( 'rsssl_installation_error' );
}
}
} catch ( Exception $e ) {
update_option( 'rsssl_installation_error', 'directadmin', false );
$status = 'warning';
$action = 'continue';
$message = $e->getMessage();
}
return new RSSSL_RESPONSE( $status, $action, $message );
}
}

View File

@@ -0,0 +1,46 @@
<?php
defined( 'ABSPATH' ) or die();
function rsssl_install_directadmin(){
if (rsssl_is_ready_for('installation')) {
$directadmin = new rsssl_directadmin();
$domains = RSSSL_LE()->letsencrypt_handler->get_subjects();
$response = $directadmin->installSSL($domains);
if ( $response->status === 'success' ) {
update_option('rsssl_le_certificate_installed_by_rsssl', 'directadmin', false );
}
return $response;
} else {
$status = 'error';
$action = 'stop';
$message = __("The system is not ready for the installation yet. Please run the wizard again.", "really-simple-ssl");
return new RSSSL_RESPONSE($status, $action, $message);
}
}
/**
* Add actions for direct admin
* @param array $fields
*
* @return array
*/
function rsssl_directadmin_add_condition_actions($fields){
$directadmin = new rsssl_directadmin();
if ( $directadmin->credentials_available() ) {
$index = array_search( 'installation', array_column( $fields, 'id' ) );
//clear existing array
$fields[ $index ]['actions'] = [];
$fields[ $index ]['actions'][]
= array(
'description' => __( "Attempting to install certificate...", "really-simple-ssl" ),
'action' => 'rsssl_install_directadmin',
'attempts' => 1,
'status' => 'inactive',
);
}
return $fields;
}
add_filter( 'rsssl_fields', 'rsssl_directadmin_add_condition_actions' );

View File

@@ -0,0 +1,441 @@
<?php
/**
* Socket communication class.
*
* Originally designed for use with DirectAdmin's API, this class will fill any HTTP socket need.
*
* Very, very basic usage:
* $Socket = new HTTPSocket;
* echo $Socket->get('http://user:pass@somesite.com/somedir/some.file?query=string&this=that');
*
* @author Phi1 'l0rdphi1' Stier <l0rdphi1@liquenox.net>
* @package HTTPSocket
* @version 3.0.4
*/
class HTTPSocket {
var $version = '3.0.4';
/* all vars are private except $error, $query_cache, and $doFollowLocationHeader */
var $method = 'GET';
var $remote_host;
var $remote_port;
var $remote_uname;
var $remote_passwd;
var $result;
var $result_header;
var $result_body;
var $result_status_code;
var $lastTransferSpeed;
var $bind_host;
var $error = array();
var $warn = array();
var $query_cache = array();
var $doFollowLocationHeader = TRUE;
var $redirectURL;
var $max_redirects = 5;
var $ssl_setting_message = 'DirectAdmin appears to be using SSL. Change your script to connect to ssl://';
var $extra_headers = array();
var $proxy = false;
var $proxy_headers = array();
/**
* Create server "connection".
*
*/
function connect($host, $port = '' )
{
if (!is_numeric($port))
{
$port = 80;
}
$this->remote_host = $host;
$this->remote_port = $port;
}
function bind( $ip = '' )
{
if ( $ip == '' )
{
$ip = $_SERVER['SERVER_ADDR'];
}
$this->bind_host = $ip;
}
/**
* 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 = '', $passwd = '' )
{
if ( strlen($uname) > 0 )
{
$this->remote_uname = $uname;
}
if ( strlen($passwd) > 0 )
{
$this->remote_passwd = $passwd;
}
}
/**
* For pass through, this function writes the data in chunks.
*/
private function stream_chunk($ch, $data)
{
echo($data);
return strlen($data);
}
private function stream_header($ch, $data)
{
if (!preg_match('/^HTTP/i', $data))
{
header($data);
}
return strlen($data);
}
/**
* Query the server
*
* @param string containing properly formatted server API. See DA API docs and examples. Http:// URLs O.K. too.
* @param string|array query to pass to url
* @param int if connection KB/s drops below value here, will drop connection
*/
function query( $request, $content = '', $doSpeedCheck = 0 )
{
$this->error = $this->warn = array();
$this->result_status_code = NULL;
$is_ssl = FALSE;
// is our request a http:// ... ?
if (preg_match('!^http://!i',$request) || preg_match('!^https://!i',$request))
{
$location = parse_url($request);
if (preg_match('!^https://!i',$request))
{
$this->connect('https://'.$location['host'],$location['port']);
}
else
$this->connect('http://'.$location['host'],$location['port']);
$this->set_login($location['user'],$location['pass']);
$request = $location['path'];
$content = $location['query'];
if ( strlen($request) < 1 )
{
$request = '/';
}
}
if (preg_match('!^ssl://!i', $this->remote_host))
$this->remote_host = 'https://'.substr($this->remote_host, 6);
if (preg_match('!^tcp://!i', $this->remote_host))
$this->remote_host = 'http://'.substr($this->remote_host, 6);
if (preg_match('!^https://!i', $this->remote_host))
$is_ssl = TRUE;
$array_headers = array(
'Host' => ( $this->remote_port == 80 ? $this->remote_host : "$this->remote_host:$this->remote_port" ),
'Accept' => '*/*',
'Connection' => 'Close' );
foreach ( $this->extra_headers as $key => $value )
{
$array_headers[$key] = $value;
}
$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);
}
$OK = TRUE;
if ($this->method == 'GET' && isset($content) && $content != '')
$request .= '?'.$content;
$ch = curl_init($this->remote_host.':'.$this->remote_port.$request);
if ($is_ssl)
{
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //1
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //2
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
}
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_USERAGENT, "HTTPSocket/$this->version");
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_HEADER, 1);
if ($this->proxy)
{
curl_setopt($ch, CURLOPT_RETURNTRANSFER,false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 8192); // 8192
curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, "stream_chunk"));
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, "stream_header"));
}
curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 512);
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 120);
// instance connection
if ($this->bind_host)
{
curl_setopt($ch, CURLOPT_INTERFACE, $this->bind_host);
}
// if we have a username and password, add the header
if ( isset($this->remote_uname) && isset($this->remote_passwd) )
{
curl_setopt($ch, CURLOPT_USERPWD, $this->remote_uname.':'.$this->remote_passwd);
}
// for DA skins: if $this->remote_passwd is NULL, try to use the login key system
if ( isset($this->remote_uname) && $this->remote_passwd == NULL )
{
curl_setopt($ch, CURLOPT_COOKIE, "session={$_SERVER['SESSION_ID']}; key={$_SERVER['SESSION_KEY']}");
}
// if method is POST, add content length & type headers
if ( $this->method == 'POST' )
{
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
//$array_headers['Content-type'] = 'application/x-www-form-urlencoded';
$array_headers['Content-length'] = strlen($content);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $array_headers);
if( !($this->result = curl_exec($ch)) )
{
$this->error[] .= curl_error($ch);
$OK = FALSE;
}
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$this->result_header = substr($this->result, 0, $header_size);
$this->result_body = substr($this->result, $header_size);
$this->result_status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$this->lastTransferSpeed = curl_getinfo($ch, CURLINFO_SPEED_DOWNLOAD) / 1024;
curl_close($ch);
$this->query_cache[] = $this->remote_host.':'.$this->remote_port.$request;
$headers = $this->fetch_header();
// did we get the full file?
if ( !empty($headers['content-length']) && $headers['content-length'] != strlen($this->result_body) )
{
$this->result_status_code = 206;
}
// now, if we're being passed a location header, should we follow it?
if ($this->doFollowLocationHeader)
{
//dont bother if we didn't even setup the script correctly
if (isset($headers['x-use-https']) && $headers['x-use-https']=='yes')
die($this->ssl_setting_message);
if (isset($headers['location']))
{
if ($this->max_redirects <= 0)
die("Too many redirects on: ".$headers['location']);
$this->max_redirects--;
$this->redirectURL = $headers['location'];
$this->query($headers['location']);
}
}
}
function getTransferSpeed()
{
return $this->lastTransferSpeed;
}
/**
* The quick way to get a URL's content :)
*
* @param string URL
* @param boolean return as array? (like PHP's file() command)
* @return string result body
*/
function get($location, $asArray = FALSE )
{
$this->query($location);
if ( $this->get_status_code() == 200 )
{
if ($asArray)
{
return preg_split("/\n/",$this->fetch_body());
}
return $this->fetch_body();
}
return FALSE;
}
/**
* Returns the last status code.
* 200 = OK;
* 403 = FORBIDDEN;
* etc.
*
* @return int status code
*/
function get_status_code()
{
return $this->result_status_code;
}
/**
* Adds a header, sent with the next query.
*
* @param string header name
* @param string header value
*/
function add_header($key,$value)
{
$this->extra_headers[$key] = $value;
}
/**
* Clears any extra headers.
*
*/
function clear_headers()
{
$this->extra_headers = array();
}
/**
* Return the result of a query.
*
* @return string result
*/
function fetch_result()
{
return $this->result;
}
/**
* Return the header of result (stuff before body).
*
* @param string (optional) header to return
* @return array result header
*/
function fetch_header( $header = '' )
{
if ($this->proxy)
return $this->proxy_headers;
$array_headers = preg_split("/\r\n/",$this->result_header);
$array_return = array( 0 => $array_headers[0] );
unset($array_headers[0]);
foreach ( $array_headers as $pair )
{
if ($pair == '' || $pair == "\r\n") continue;
list($key,$value) = preg_split("/: /",$pair,2);
$array_return[strtolower($key)] = $value;
}
if ( $header != '' )
{
return $array_return[strtolower($header)];
}
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;
}
/**
* Set a specifc message on how to change the SSL setting, in the event that it's not set correctly.
*/
function set_ssl_setting_message($str)
{
$this->ssl_setting_message = $str;
}
}

View File

@@ -0,0 +1,7 @@
<?php
defined( 'ABSPATH' ) or die();
/**
* On hostgator, we don't have the cpanel api, so remove these steps.
* This is managed in the config, in the hosts array
*/

View File

@@ -0,0 +1 @@
<?php // You don't belong here. ?>

View File

@@ -0,0 +1,17 @@
<?php defined( 'ABSPATH' ) or die();
$other_host = rsssl_get_other_host();
if (file_exists( rsssl_le_path . "integrations/$other_host/$other_host.php" )) {
require_once( rsssl_le_path . "integrations/$other_host/$other_host.php" );
}
if (file_exists( rsssl_le_path . "integrations/$other_host/functions.php" )){
require_once( rsssl_le_path . "integrations/$other_host/functions.php" );
}
if ( rsssl_is_cpanel() ) {
require_once( rsssl_le_path . 'integrations/cpanel/cpanel.php' );
} else if ( rsssl_is_plesk() ) {
require_once( rsssl_le_path . 'integrations/plesk/plesk.php' );
} else if ( rsssl_is_directadmin() ) {
require_once( rsssl_le_path . 'integrations/directadmin/directadmin.php' );
}

View File

@@ -0,0 +1,43 @@
<?php
defined( 'ABSPATH' ) or die();
function rsssl_plesk_install(){
if (rsssl_is_ready_for('installation')) {
$cpanel = new rsssl_plesk();
$domains = RSSSL_LE()->letsencrypt_handler->get_subjects();
$response = $cpanel->installSSL($domains);
if ( $response->status === 'success' ) {
update_option('rsssl_le_certificate_installed_by_rsssl', 'cpanel:default', false);
}
return $response;
} else {
$status = 'error';
$action = 'stop';
$message = __("The system is not ready for the installation yet. Please run the wizard again.", "really-simple-ssl");
return new RSSSL_RESPONSE($status, $action, $message);
}
}
/**
* Add the step to install SSL using Plesk
* @param array $fields
*
* @return array
*/
function rsssl_plesk_add_installation_step($fields){
$plesk = new rsssl_plesk();
if ( $plesk->credentials_available() ) {
$index = array_search( 'installation', array_column( $fields, 'id' ) );
$fields[ $index ]['actions'] = array_merge(array(
array(
'description' => __("Installing SSL certificate using PLESK API...", "really-simple-ssl"),
'action'=> 'rsssl_plesk_install',
'attempts' => 1,
'status' => 'inactive',
)
) , $fields[ $index ]['actions'] );
}
return $fields;
}
add_filter( 'rsssl_fields', 'rsssl_plesk_add_installation_step' );

View File

@@ -0,0 +1,101 @@
<?php
/**
* @package PLESK
* @author Rogier Lankhorst
* @copyright Copyright (C) 2021, Rogier Lankhorst
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3
* @link https://really-simple-ssl.com
* @since Class available since Release 5.0.0
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use PleskX\Api\Client;
require_once rsssl_path . 'lib/admin/class-encryption.php';
use RSSSL\lib\admin\Encryption;
require_once rsssl_le_path . 'vendor/autoload.php';
require_once( rsssl_le_path . 'integrations/plesk/functions.php' );
class rsssl_plesk
{
use Encryption;
public $host;
private $login;
private $password;
public $ssl_installation_url;
/**
* Initiates the Plesk class.
*
*/
public function __construct()
{
$password = $this->decrypt_if_prefixed( rsssl_get_option('plesk_password') );
$host = rsssl_get_option('plesk_host');
$this->host = str_replace(array('http://', 'https://', ':8443'), '', $host);
$this->login = rsssl_get_option('plesk_username');
$this->password = $password;
$this->ssl_installation_url = 'https://'.$this->host.":8443/smb/ssl-certificate/list/id/21";
}
/**
* Check if all creds are available
* @return bool
*/
public function credentials_available(){
if (!empty($this->host) && !empty($this->password) && !empty($this->login)) {
return true;
}
return false;
}
/**
* Install certificate
* @param $domains
*
* @return RSSSL_RESPONSE
*/
public function installSSL($domains){
$key_file = get_option('rsssl_private_key_path');
$cert_file = get_option('rsssl_certificate_path');
$cabundle_file = get_option('rsssl_intermediate_path');
try {
$client = new Client($this->host);
$client->setCredentials($this->login, $this->password);
$response = $client->certificate()->install($domains, [
'csr' => '',
'pvt' => file_get_contents($key_file),
'cert' => file_get_contents($cert_file),
'ca' => file_get_contents($cabundle_file),
]);
update_option('rsssl_le_certificate_installed_by_rsssl', 'plesk', false);
delete_option('rsssl_installation_error' );
$status = 'success';
$action = 'continue';
$message = __('Successfully installed SSL',"really-simple-ssl");
} catch(Exception $e) {
update_option('rsssl_installation_error', 'plesk', false);
$status = 'warning';
$action = 'continue';
$message = $e->getMessage();
}
return new RSSSL_RESPONSE($status, $action, $message);
}
}