OwlCyberSecurity - MANAGER
Edit File: ApiSocket.php
<?php /** * Copyright (с) Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2022 All Rights Reserved * * Licensed under CLOUD LINUX LICENSE AGREEMENT * https://www.cloudlinux.com/legal/ */ namespace CloudLinux\SmartAdvice\App\Advice; /** * SmartAdvice socket. */ class ApiSocket extends Api { /** * Sock. * * @var string */ private $sock = 'unix:///opt/alt/php-xray/run/xray-user.sock'; /** * Socket resource. * * @var resource */ private $resource = null; /** * Connect. * * @return bool */ private function connect() { $this->resource = stream_socket_client( $this->sock, $error_code, $error_msg, 10 ); if ( ! $this->resource ) { // @phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error, WordPress.Security.EscapeOutput.OutputNotEscaped trigger_error( "Can't connect to socket [$error_code]: $error_msg", E_USER_WARNING ); return false; } return true; } /** * Send. * * @param array $data params. * * @return bool */ private function send( $data ) { $json = wp_json_encode( $data ); if ( false === stream_socket_sendto( $this->resource, $json ) ) { // @phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error, WordPress.Security.EscapeOutput.OutputNotEscaped trigger_error( "Can't send data to " . $this->sock, E_USER_WARNING ); return false; } return true; } /** * Read. * * @return bool|string */ private function read() { $response = stream_get_contents( $this->resource, 4, 0 ); if ( empty( $response ) ) { // @phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error, WordPress.Security.EscapeOutput.OutputNotEscaped trigger_error( "Can't read 4b", E_USER_WARNING ); return false; } $unpack = unpack( 'N', $response ); if ( ! is_array( $unpack ) || ! array_key_exists( 1, $unpack ) ) { // @phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error, WordPress.Security.EscapeOutput.OutputNotEscaped trigger_error( "Can't unpack response", E_USER_WARNING ); return false; } $length = $unpack[1]; $json = stream_get_contents( $this->resource, $length, 4 ); if ( false === $json ) { // @phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error, WordPress.Security.EscapeOutput.OutputNotEscaped trigger_error( "Can't read response", E_USER_WARNING ); return false; } return $json; } /** * Close. * * @return void */ private function close() { if ( is_resource( $this->resource ) ) { // @phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose fclose( $this->resource ); } } /** * Exec command. * * @param array $data send. * @param bool $read response. * * @return string|bool */ public function exec( $data, $read = false ) { $result = false; do_action( 'cl_smart_advice_set_error_handler' ); if ( ! function_exists( 'stream_socket_client' ) ) { // @phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error, WordPress.Security.EscapeOutput.OutputNotEscaped trigger_error( "Function stream_socket_client doesn't exist", E_USER_WARNING ); } else { if ( $this->connect() && $this->send( $data ) ) { $result = true; if ( true === $read ) { $result = $this->read(); } $this->close(); } elseif ( true === $read ) { $result = '{"result": "X-Ray User Plugin is not enabled. Please, contact your server administrator"}'; } } do_action( 'cl_smart_advice_restore_error_handler' ); return $result; } /** * Apply advice. * * @param string $advice_id Advice ID. * * @return string */ public function apply( $advice_id ) { /** * Allows filtering of data before sending it to X-Ray socket. * * @param array $data Data to send to socket. * @param string $method Method name. * @param array $args Original method arguments. * * @return array */ $data = apply_filters( 'cl_smart_advice_socket_data', array( 'runner' => 'smart_advice', 'command' => 'apply', 'advice_id' => (string) $advice_id, 'async_mode' => true, 'source' => 'WORDPRESS_PLUGIN', 'accept_license_terms' => true, ), 'apply', func_get_args() ); return $this->exec( $data, true ); } /** * Rollback advice. * * @param string $advice_id Advice ID. * @param ?string $reason Advice rollback reason. * * @return string */ public function rollback( $advice_id, $reason ) { /** * Allows filtering of data before sending it to X-Ray socket. * * @param array $data Data to send to socket. * @param string $method Method name. * @param array $args Original method arguments. * * @return array */ $data = apply_filters( 'cl_smart_advice_socket_data', array( 'runner' => 'smart_advice', 'command' => 'rollback', 'advice_id' => (string) $advice_id, 'async_mode' => true, 'source' => 'WORDPRESS_PLUGIN', 'reason' => (string) $reason, ), 'rollback', func_get_args() ); return $this->exec( $data, true ); } /** * Status advice. * * @param string $advice_id id. * * @return string */ public function status( $advice_id ) { $data = array( 'runner' => 'smart_advice', 'command' => 'status', 'advice_id' => (string) $advice_id, ); return $this->exec( $data, true ); } /** * Details advice. * * @param string $advice_id id. * * @return string */ public function details( $advice_id ) { $data = array( 'runner' => 'smart_advice', 'command' => 'details', 'advice_id' => (string) $advice_id, ); return $this->exec( $data, true ); } /** * Subscription. * * @param string $advice_id id. * * @return string */ public function subscription( $advice_id ) { $data = array( 'runner' => 'smart_advice', 'command' => 'subscription', 'advice_id' => (string) $advice_id, 'listen' => true, ); return $this->exec( $data ); } /** * Agreement. * * @param string $type advice type string, e.g. 'cdn'. * * @return string */ public function agreement( $type ) { $data = array( 'runner' => 'smart_advice', 'command' => 'agreement', 'text' => (string) $type, ); return $this->exec( $data ); } /** * Get options. * * @param string $user system name. * * @return string */ public function get_options( $user ) { $data = array( 'runner' => 'smart_advice', 'command' => 'get-options', 'username' => (string) $user, ); return $this->exec( $data, true ); } }