View source
<?php
define('DRD_SERVER_API_VERSION', '2.4.0');
define('DRD_SERVER_ERROR_WRONG_API', 1001);
define('DRD_SERVER_ERROR_WRONG_REFERER', 1002);
define('DRD_SERVER_ERROR_NO_REFERER', 1003);
define('DRD_SERVER_ERROR_NO_OP', 1004);
define('DRD_SERVER_ERROR_NO_FUNC', 1005);
define('DRD_SERVER_ERROR_NO_LOG_PHP', 1006);
define('DRD_SERVER_ERROR_MISSING_AES', 1007);
define('DRD_SERVER_ERROR_WRONG_KEYS', 1999);
include 'drd_server.aes.inc';
function drd_server_xmlrpc() {
include_once 'drd_server.domain.inc';
include_once 'drd_server.server.inc';
return array(
'drd.key' => 'drd_server_key',
'drd.execute' => 'drd_server_execute',
'drd.status' => 'drd_server_status',
'drd.heartbeat' => 'drd_server_heartbeat',
'drd.config.server.read' => 'drd_server_config_server_read',
'drd.config.server.save' => 'drd_server_config_server_save',
'drd.config.domain.read' => 'drd_server_config_domain_read',
'drd.config.domain.save' => 'drd_server_config_domain_save',
'drd.retrieve.blocks' => 'drd_server_render_blocks',
);
}
function drd_server_menu_site_status_alter(&$menu_site_status, $path) {
if (strpos($path, 'admin/drd_server/') !== FALSE) {
$menu_site_status = MENU_SITE_ONLINE;
}
}
function drd_server_drd_server_actions() {
return array(
'drd.server.install' => array(
'category' => t('Domain'),
'label' => t('DRD: remotely install/uninstall'),
'callback' => 'drd_install_drd_server',
'mode' => 'domain',
'remote' => FALSE,
'queue' => TRUE,
'fields' => array(
'attention' => array(
'#markup' => t('ATTENTION: This will flush all caches on your remote site, so please be aware and use this with care, especially if you have a lot of traffic on your remote site.'),
),
'reset' => array(
'#type' => 'checkbox',
'#title' => t('Install'),
'#default_value' => TRUE,
),
),
),
'drd.server.domains' => array(
'category' => t('Server'),
'label' => t('Update server domains'),
'callback' => 'drd_server_server_domains',
'mode' => 'server',
'remote' => TRUE,
'queue' => TRUE,
'follower' => array(
'a' => 'drd.actions',
),
),
'drd.info' => array(
'label' => t('Update info'),
'callback' => 'drd_server_domain_info',
'mode' => 'domain',
'remote' => TRUE,
'queue' => TRUE,
'refresh' => TRUE,
),
'drd.cache.flush' => array(
'label' => t('Flush Cache'),
'callback' => 'drd_server_domain_flush_cache',
'mode' => 'domain',
'remote' => TRUE,
'queue' => TRUE,
),
'drd.run.cron' => array(
'label' => t('Run Cron'),
'callback' => 'drd_server_domain_run_cron',
'mode' => 'domain',
'remote' => TRUE,
'queue' => TRUE,
'follower' => array(
'a' => 'drd.info',
),
),
'drd.switch.maintenance' => array(
'label' => t('Maintenance Mode'),
'callback' => 'drd_server_domain_switch_maintenance',
'mode' => 'domain',
'remote' => TRUE,
'queue' => TRUE,
'fields' => array(
'maintenancemode' => array(
'#type' => 'checkbox',
'#title' => t('On'),
'#default_value' => TRUE,
),
),
),
'drd.list.updates' => array(
'label' => t('List new modules and themes'),
'callback' => 'drd_server_domain_list_updates',
'mode' => 'domain',
'remote' => TRUE,
'queue' => TRUE,
'follower' => array(
'a' => 'drd.info',
),
),
'drd.server.list.updates' => array(
'label' => t('List new modules and themes (including disabled)'),
'callback' => 'drd_server_server_list_updates',
'mode' => 'server',
'remote' => TRUE,
'queue' => TRUE,
),
'drd.run.update' => array(
'label' => t('Run Database Updates'),
'callback' => 'drd_server_domain_run_update',
'mode' => 'domain',
'remote' => TRUE,
'queue' => TRUE,
'follower' => array(
'a' => 'drd.info',
),
),
'drd.update.translation' => array(
'label' => t('Update Translations'),
'callback' => 'drd_server_domain_update_translation',
'mode' => 'domain',
'remote' => TRUE,
'queue' => TRUE,
'follower' => array(
'a' => 'drd.info',
),
),
'drd.server.php.error.log' => array(
'category' => t('Server'),
'label' => t('PHP Error Log'),
'callback' => 'drd_server_server_php_error_log',
'mode' => 'server',
'remote' => TRUE,
'queue' => TRUE,
),
'drd.set.user1' => array(
'label' => t('Reset User 1 Credentials'),
'callback' => 'drd_server_domain_reset_user1',
'mode' => 'domain',
'remote' => TRUE,
'queue' => FALSE,
'fields' => array(
'username' => array(
'#type' => 'textfield',
'#title' => t('Username'),
'#default_value' => '',
),
'userpass' => array(
'#type' => 'password',
'#title' => t('Password'),
'#default_value' => '',
),
'userpassrepeat' => array(
'#type' => 'password',
'#title' => t('Repeat password'),
'#default_value' => '',
),
),
),
'drd.php' => array(
'label' => t('Execute PHP code'),
'callback' => 'drd_server_domain_php',
'mode' => 'domain',
'remote' => TRUE,
'queue' => TRUE,
'fields' => array(
'php' => array(
'#type' => 'textarea',
'#title' => t('PHP-Code'),
'#default_value' => '',
'#description' => t('The PHP code to be executed, wrapped in php tags. Note: The PHP module needs to be enabled on the remote domain.'),
),
),
),
);
}
function drd_server_block_info() {
$blocks = array();
if (module_exists('admin')) {
$blocks['drd'] = array(
'info' => t('Admin Extras Dashboard'),
'cache' => DRUPAL_CACHE_PER_ROLE,
'admin' => TRUE,
);
}
return $blocks;
}
function drd_server_block_view($delta) {
switch ($delta) {
case 'drd':
module_load_include('inc', 'drd_server', 'drd_server.admin');
return drd_server_admin_block();
}
return FALSE;
}
function drd_server_navbar() {
$items = array();
module_load_include('inc', 'drd_server', 'drd_server.admin');
$items['drd_server'] = array(
'#type' => 'navbar_item',
'tab' => array(
'#type' => 'link',
'#title' => t('Extra Admin'),
'#href' => 'admin',
'#options' => array(
'attributes' => array(
'title' => t('Extra Admin'),
'class' => array(
'navbar-icon',
'navbar-icon-configuration',
),
),
),
),
'tray' => array(
'#heading' => t('Extra Admin'),
'extra_admin' => array(
'#theme' => 'item_list',
'#items' => drd_server_admin_menu(),
'#attributes' => array(
'class' => array(
'drd-server-extra-admin',
'menu',
'nav',
'navbar-menu-root',
'navbar-root',
),
),
),
),
'#weight' => 150,
);
drupal_add_css(drupal_get_path('module', 'drd_server') . '/drd_server.css');
return $items;
}
function drd_server_permission() {
return array(
'flush cache' => array(
'title' => t('Flush Cache'),
),
);
}
function drd_server_menu() {
$items['admin/drd_server/%'] = array(
'title' => 'Check if DRD Server is installed',
'page callback' => 'drd_server_check',
'page arguments' => array(
2,
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['admin/config/system/drd_settings'] = array(
'title' => 'DRD Remote Settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'drd_server_settings',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'drd_server.admin.inc',
);
$items['admin/config/system/drd_settings/%'] = array(
'title' => 'DRD Remote Settings: Keys',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'drd_server_settings_keys',
4,
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'drd_server.admin.inc',
);
$items['admin/drd_server/flush/cache'] = array(
'title' => 'Flush Cache',
'page callback' => 'drd_server_domain_flush_cache',
'page arguments' => array(
TRUE,
),
'access arguments' => array(
'flush cache',
),
'file' => 'drd_server.domain.inc',
'type' => MENU_CALLBACK,
);
$items['admin/drd_server/rebuild_scheduler'] = array(
'title' => 'Rebuild Scheduler',
'page callback' => 'drd_server_domain_rebuild_scheduler',
'access arguments' => array(
'administer site configuration',
),
'file' => 'drd_server.domain.inc',
'type' => MENU_CALLBACK,
);
$items['admin/drd_server/update/translation'] = array(
'title' => 'Update translation',
'page callback' => 'drd_server_admin_update_translation',
'access arguments' => array(
'translate interface',
),
'file' => 'drd_server.admin.inc',
'type' => MENU_CALLBACK,
);
return $items;
}
function drd_server_drd_config_domain() {
$form = array();
if (!module_exists('block')) {
$form['drd_server_blocks'] = array(
'#type' => 'checkboxes',
'#options' => array(),
'#disabled' => TRUE,
'#title' => t('Blocks to display (unavailable)'),
'#description' => t('Block module disabled on the remote server.'),
);
return $form;
}
$block_list = array();
foreach (module_implements('block_info') as $module) {
foreach (module_invoke($module, 'block_info') as $key => $block) {
$block_list[$module . ':' . $key] = $block['info'];
}
}
$form['drd_server_blocks'] = array(
'#type' => 'checkboxes',
'#title' => t('Blocks to display'),
'#options' => $block_list,
'#default_value' => variable_get('drd_server_blocks', array()),
);
return $form;
}
function drd_server_file_download($uri) {
if (strpos(file_uri_target($uri), 'drd_server_debug_') === 0) {
if (user_access('administer site configuration')) {
return array(
'Pragma' => 'public',
'Expires' => 0,
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Content-Type' => 'application/force-download',
);
}
}
return NULL;
}
function drd_server_key($api, $timestamp, $langcode, $debug, $domainurl, $aes_key = '', $aes_cipher = '', $aes_iv = '', $aes_impl = '', $cluster_token = '') {
if ($timestamp != REQUEST_TIME) {
}
global $language;
$language->language = $langcode;
_drd_server_debug_mode($debug);
_drd_server_watchdog('AES key change request.');
$allowed = variable_get('drd_allowed_referer', '');
$referer = empty($cluster_token) ? ip_address() : $cluster_token;
if (empty($allowed)) {
return drd_server_error(t('Referer (%referer) not allowed, nothing configured yet.', array(
'%referer' => $referer,
)), DRD_SERVER_ERROR_NO_REFERER);
}
if (strpos($allowed, $referer) === FALSE) {
_drd_server_watchdog('AES key change request unauthorized.', array(), WATCHDOG_ALERT);
return drd_server_error(t('Referer (%referer) not allowed.', array(
'%referer' => $referer,
)), DRD_SERVER_ERROR_WRONG_REFERER);
}
$aes_keys = variable_get('drd_aes_keys', array());
if (!empty($cluster_token)) {
if (empty($aes_keys[$cluster_token]['cluster_mode']) || empty($aes_keys[$cluster_token]['cluster_ips']) || strpos($aes_keys[$cluster_token]['cluster_ips'], ip_address()) === FALSE) {
_drd_server_watchdog('AES key change request unauthorized due to ip address mismatch.', array(), WATCHDOG_ALERT);
return drd_server_error(t('Referer (%referer) not allowed from %address.', array(
'%referer' => $referer,
'%address' => ip_address(),
)), DRD_SERVER_ERROR_WRONG_REFERER);
}
}
if ($api !== DRD_SERVER_API_VERSION) {
_drd_server_watchdog('Wrong API: %api.', array(
'%api' => $api,
), WATCHDOG_ALERT);
return drd_server_error(t('Wrong API.'), DRD_SERVER_ERROR_WRONG_API);
}
$sites = drd_server_read_sites();
if (empty($domainurl)) {
$aes_keys[$referer] = array(
'key' => $aes_key,
'cipher' => $aes_cipher,
'iv' => $aes_iv,
'impl' => $aes_impl,
'cluster_mode' => !empty($cluster_token),
'cluster_ips' => empty($aes_keys[$cluster_token]['cluster_ips']) ? ip_address() : $aes_keys[$cluster_token]['cluster_ips'],
);
variable_set('drd_aes_keys', $aes_keys);
$domainurls = $sites;
}
else {
$domainurls = array(
$domainurl => $sites[$domainurl],
);
}
drd_server_key_remote($domainurls, $aes_keys);
return drd_server_result('drd.key', TRUE);
}
function drd_server_execute() {
$args = func_get_args();
$action_name = array_shift($args);
$valid = _drd_server_validate_request($args, $action_name);
if ($valid !== TRUE) {
return $valid;
}
$action_name = array_pop($args);
$actions = module_invoke_all('drd_server_actions');
if ($action_name == 'drd.actions') {
return drd_server_result('drd.actions', $actions);
}
if (!isset($actions[$action_name])) {
return drd_server_error(t('Action %action_name does not exist.', array(
'%action_name' => $action_name,
)), DRD_SERVER_ERROR_NO_OP);
}
$action = $actions[$action_name];
if (!function_exists($action['callback'])) {
return drd_server_error(t('Action %action_name does not have any callback.', array(
'%action_name' => $action_name,
)), DRD_SERVER_ERROR_NO_FUNC);
}
return call_user_func_array($action['callback'], $args);
}
function drd_server_status() {
$args = func_get_args();
$valid = _drd_server_validate_request($args);
if ($valid !== TRUE) {
return $valid;
}
if (module_exists('update')) {
module_load_include('inc', 'update', 'update.compare');
$projects = array();
foreach (update_get_projects() as $project_name => $full_info) {
$projects[$project_name] = $full_info['info']['version'];
}
}
else {
$projects = db_select('system', 's')
->fields('s', array(
'name',
'schema_version',
))
->condition('s.status', 1)
->execute()
->fetchAllKeyed(0, 1);
}
$status = array(
'maintenance_mode' => variable_get('maintenance_mode', FALSE),
'projects_enabled' => $projects,
'drupal_root' => DRUPAL_ROOT,
);
drupal_alter('drd_server_status', $status);
return drd_server_result('drd.status', $status);
}
function drd_server_heartbeat() {
$args = func_get_args();
$valid = _drd_server_validate_request($args);
if ($valid !== TRUE) {
return $valid;
}
$period = array_shift($args);
$interval = REQUEST_TIME - variable_get('user_block_seconds_online', 900);
$heartbeat = array(
'count' => array(
'user' => array(
'all' => _drd_server_count('users', 'uid'),
'sessions' => _drd_server_count_session($interval, TRUE),
'auth' => _drd_server_count_session($interval, FALSE),
),
'content' => array(
'node' => _drd_server_count('node', 'nid'),
'comment' => _drd_server_count('comment', 'cid'),
),
),
'file' => array(
'temp' => _drd_server_count_file(0),
'perm' => _drd_server_count_file(1),
),
'watchdog' => array(
'emergency' => _drd_server_count_watchdog(WATCHDOG_EMERGENCY, $period),
'alert' => _drd_server_count_watchdog(WATCHDOG_ALERT, $period),
'critical' => _drd_server_count_watchdog(WATCHDOG_CRITICAL, $period),
'error' => _drd_server_count_watchdog(WATCHDOG_ERROR, $period),
'warning' => _drd_server_count_watchdog(WATCHDOG_WARNING, $period),
'notice' => _drd_server_count_watchdog(WATCHDOG_NOTICE, $period),
'info' => _drd_server_count_watchdog(WATCHDOG_INFO, $period),
'debug' => _drd_server_count_watchdog(WATCHDOG_DEBUG, $period),
),
);
$heartbeat['detail'] = array(
'user' => array(
'title' => t('User'),
'content' => array(
format_plural($heartbeat['count']['user']['auth'], '@count authenticated user', '@count authenticated users'),
format_plural($heartbeat['count']['user']['sessions'], '@count user session', '@count user sessions'),
format_plural($heartbeat['count']['user']['all'], '@count registered user', '@count registered users'),
),
),
'content' => array(
'title' => t('Content'),
'content' => array(
format_plural($heartbeat['count']['content']['node'], '@count node', '@count nodes'),
format_plural($heartbeat['count']['content']['comment'], '@count comment', '@count comments'),
),
),
'file' => array(
'title' => t('Files'),
'content' => array(
format_plural($heartbeat['file']['temp']['count'], '@count temporary file with %size', '@count temporary files with %size', array(
'%size' => format_size($heartbeat['file']['temp']['size']),
)),
format_plural($heartbeat['file']['perm']['count'], '@count permanent file with %size', '@count permanent files with %size', array(
'%size' => format_size($heartbeat['file']['perm']['size']),
)),
),
),
'watchdog' => array(
'title' => t('Watchdog'),
'content' => array(),
),
);
foreach ($heartbeat['watchdog'] as $key => $value) {
$heartbeat['detail']['watchdog']['content'][$key] = format_plural($value, '@count %severity entry', '@count %severity entries', array(
'%severity' => $key,
));
}
drupal_alter('drd_server_heartbeat', $heartbeat);
return drd_server_result('drd.heartbeat', $heartbeat);
}
function drd_server_render_blocks() {
$args = func_get_args();
$valid = _drd_server_validate_request($args);
if ($valid !== TRUE) {
return $valid;
}
if (!module_exists('block')) {
return drd_server_result('drd.render.blocks', '');
}
$result = '';
foreach (variable_get('drd_server_blocks', array()) as $def) {
if ($def) {
list($module, $delta) = explode(':', $def);
$block = block_load($module, $delta);
$block_content = _block_render_blocks(array(
$block,
));
$build = _block_get_renderable_array($block_content);
$result .= drupal_render($build);
}
}
return drd_server_result('drd.render.blocks', $result);
}
function drd_server_config_server_read() {
$args = func_get_args();
$valid = _drd_server_validate_request($args);
if ($valid !== TRUE) {
return $valid;
}
$form = module_invoke_all('drd_config_server');
return drd_server_result('drd.config.read.server', $form);
}
function drd_server_config_server_save() {
$args = func_get_args();
$valid = _drd_server_validate_request($args);
if ($valid !== TRUE) {
return $valid;
}
$values = drupal_json_decode(array_shift($args));
$form = module_invoke_all('drd_config_server');
return drd_server_config_save($form, $values);
}
function drd_server_config_domain_read() {
$args = func_get_args();
$valid = _drd_server_validate_request($args);
if ($valid !== TRUE) {
return $valid;
}
$form = module_invoke_all('drd_config_domain');
return drd_server_result('drd.config.read.domain', $form);
}
function drd_server_config_domain_save() {
$args = func_get_args();
$valid = _drd_server_validate_request($args);
if ($valid !== TRUE) {
return $valid;
}
$values = drupal_json_decode(array_shift($args));
$form = module_invoke_all('drd_config_domain');
return drd_server_config_save($form, $values);
}
function drd_server_config_save($form, $values, $return = TRUE) {
foreach ($form as $key => $element) {
if (is_array($element) && substr($key, 0, 1) != '#') {
drd_server_config_save($element, $values, FALSE);
}
if (!empty($values[$key])) {
variable_set($key, $values[$key]);
}
}
if ($return) {
return drd_server_result('drd.config.save', TRUE);
}
return '';
}
function _drd_server_read_settings($shortname, $file) {
$databases = array();
try {
$php = php_strip_whitespace($file);
$php = str_replace('<?php', '', $php);
$php = str_replace('<?', '', $php);
$php = str_replace('?>', '', $php);
$php = str_replace('ini_set', '@ini_set', $php);
$php = str_replace('@@ini_set', '@ini_set', $php);
eval($php);
} catch (Exception $e) {
_drd_server_watchdog('Read Settings - Exception occured:<pre>@exception</pre>', array(
'@exception' => print_r($e, TRUE),
), WATCHDOG_ERROR);
return array(
'',
'',
);
}
if (empty($base_url)) {
if ($shortname == 'default') {
$base_url = $GLOBALS['base_url'];
}
else {
$base_url = $shortname;
}
}
return array(
$base_url,
$databases,
);
}
function drd_server_key_remote($domainurls, $aes_keys) {
$done = array();
foreach ($domainurls as $url => $shortname) {
if (in_array($shortname, $done)) {
continue;
}
$done[] = $shortname;
$databases = NULL;
$file = DRUPAL_ROOT . '/sites/' . $shortname . '/settings.php';
if (file_exists($file)) {
list($base_url, $databases) = _drd_server_read_settings($shortname, $file);
if (!empty($databases['default']['default'])) {
try {
$shortname = 'drd' . $shortname;
Database::addConnectionInfo($shortname, $shortname, $databases['default']['default']);
$db = Database::getConnection($shortname, $shortname);
$db
->merge('variable')
->key(array(
'name' => 'drd_aes_keys',
))
->fields(array(
'value' => serialize($aes_keys),
))
->execute();
$db
->query("DELETE FROM {cache_bootstrap} WHERE cid='variables'");
Database::closeConnection($shortname, $shortname);
} catch (Exception $ex) {
watchdog_exception('DRD Server', $ex, 'Tried updating key for %shortname', array(
'%shortname' => $shortname,
));
}
}
}
}
}
function drd_server_read_sites() {
$sites = array();
if (file_exists(DRUPAL_ROOT . '/sites/sites.php')) {
try {
include DRUPAL_ROOT . '/sites/sites.php';
} catch (Exception $e) {
}
}
if (empty($sites)) {
foreach (scandir(DRUPAL_ROOT . '/sites') as $shortname) {
if (is_dir(DRUPAL_ROOT . '/sites/' . $shortname) && !in_array($shortname, array(
'.',
'..',
'all',
))) {
$sites[$shortname] = $shortname;
}
}
}
if (!empty($sites)) {
foreach ($sites as $key => $shortname) {
if (is_dir(DRUPAL_ROOT . '/sites/' . $shortname)) {
$file = DRUPAL_ROOT . '/sites/' . $shortname . '/settings.php';
if (file_exists($file)) {
list($base_url, $databases) = _drd_server_read_settings($shortname, $file);
if (empty($base_url) && $key == $shortname) {
_drd_server_watchdog('Reading Sites - Failed as url is empty: @shortname', array(
'@shortname' => $shortname,
), WATCHDOG_ERROR);
continue;
}
$pos = strpos($base_url, '://');
if ($pos > 0) {
$base_url = substr($base_url, $pos + 3);
}
if ($base_url != $key && $base_url != $shortname) {
$sites[$base_url] = $shortname;
unset($sites[$key]);
}
}
}
}
}
_drd_server_watchdog('Reading Sites - Found @n entries: <pre>@list</pre>', array(
'@n' => count($sites),
'@list' => print_r($sites, TRUE),
));
return $sites;
}
function drd_get_allowed_referers($refs = NULL) {
if (!isset($refs)) {
$refs = variable_get('drd_allowed_referer', '');
}
$refs = str_replace(',', ' ', $refs);
$refs = str_replace(';', ' ', $refs);
return explode(' ', $refs);
}
function drd_server_aes() {
$cluster_mode = !empty($_SERVER['HTTP_X_DRD_AUTH_TOKEN']);
$referer = $cluster_mode ? $_SERVER['HTTP_X_DRD_AUTH_TOKEN'] : ip_address();
$aes_keys = variable_get('drd_aes_keys', array());
if (empty($aes_keys[$referer])) {
return FALSE;
}
if (!empty($aes_keys[$referer]['cluster_mode']) && (empty($aes_keys[$referer]['cluster_ips']) || strpos($aes_keys[$referer]['cluster_ips'], ip_address()) === FALSE)) {
return FALSE;
}
return $aes_keys[$referer];
}
function drd_server_result($mode, $drd_result) {
$args = func_get_args();
$mode = array_shift($args);
$drd_result = array_shift($args);
foreach (module_implements('drd_server_result') as $module) {
$drd_result = module_invoke($module, 'drd_server_result', $mode, $drd_result, $args);
}
drupal_alter('drd_server_result', $drd_result);
$result = new stdClass();
$result->message = $drd_result;
$result->messages = drupal_get_messages();
return drd_server_output($result);
}
function drd_server_error($message, $code = 1) {
if (is_object($message)) {
$message = (array) $message;
}
if (is_array($message)) {
$message = implode(' ', $message);
}
$encrypt = !in_array($code, array(
DRD_SERVER_ERROR_WRONG_REFERER,
DRD_SERVER_ERROR_NO_REFERER,
DRD_SERVER_ERROR_MISSING_AES,
DRD_SERVER_ERROR_WRONG_KEYS,
));
return drd_server_output(xmlrpc_error($code, strip_tags($message)), $encrypt);
}
function drd_server_output($output, $encrypt = TRUE) {
if (!empty($output)) {
$output = drupal_json_encode($output);
if ($encrypt) {
$aes = drd_server_aes();
if (!empty($aes)) {
$output = drd_server_aes_encrypt($output, TRUE, $aes['key'], $aes['cipher'], _drd_server_iv(), $aes['impl']);
}
}
}
return $output;
}
function drd_server_check($var) {
drupal_add_http_header('charset', 'utf-8');
drupal_add_http_header('content-type', 'text/plain');
drupal_send_headers();
print _drd_server_get_check_token($GLOBALS['base_url'], $var);
exit;
}
function _drd_server_get_check_token($url, $var) {
return md5(implode('-', array(
$var,
$url,
$var / 2,
)));
}
function _drd_server_debug_mode($debug = NULL) {
static $debug_mode = FALSE;
if (isset($debug)) {
$debug_mode = $debug;
}
return $debug_mode;
}
function _drd_server_watchdog($message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) {
if (_drd_server_debug_mode()) {
watchdog('DRD Server', $message, $variables, $severity, $link);
}
}
function _drd_server_iv() {
static $iv;
if (!isset($iv)) {
if (empty($_SERVER['HTTP_X_DRD_IV'])) {
$iv = empty($_SERVER['HTTP_X_DRD_IV']);
}
else {
$iv = base64_decode($_SERVER['HTTP_X_DRD_IV']);
}
}
return $iv;
}
function _drd_server_validate_request(&$args, $action_name = '') {
$langcode = $args[2];
$debug = $args[3];
global $language;
$language->language = $langcode;
_drd_server_debug_mode($debug);
$aes = drd_server_aes();
if (empty($aes)) {
_drd_server_watchdog('Execution request unauthorized.', array(), WATCHDOG_ALERT);
return drd_server_error(t('Referer (%ip) not allowed.', array(
'%ip' => ip_address(),
)), DRD_SERVER_ERROR_WRONG_REFERER);
}
array_push($args, $action_name);
$iv = _drd_server_iv();
foreach ($args as $i => $value) {
if (!empty($value) && !in_array($i, array(
2,
3,
))) {
$args[$i] = drd_server_aes_decrypt($value, TRUE, $aes['key'], $aes['cipher'], $iv, $aes['impl']);
}
}
$api = array_shift($args);
$timestamp = array_shift($args);
$langcode = array_shift($args);
$debug = array_shift($args);
if (!_drd_server_validate_timestamp($timestamp)) {
_drd_server_watchdog('Wrong encryption keys.', array(), WATCHDOG_EMERGENCY);
return drd_server_error(t('Wrong encryption keys.'), DRD_SERVER_ERROR_WRONG_KEYS);
}
if ($api !== DRD_SERVER_API_VERSION) {
_drd_server_watchdog('Wrong API: %api.', array(
'%api' => $api,
), WATCHDOG_ALERT);
return drd_server_error(t('Wrong API.'), DRD_SERVER_ERROR_WRONG_API);
}
$action_name = empty($args[0]) ? t('simple') : $args[0];
if (sizeof($args) < 2) {
_drd_server_watchdog('Remote execution request: !action_name', array(
'!action_name' => $action_name,
));
}
else {
_drd_server_watchdog('Remote execution request: !action_name <pre>!args</pre>', array(
'!action_name' => $action_name,
'!args' => print_r($args, TRUE),
));
}
return TRUE;
}
function _drd_server_validate_timestamp($timestamp) {
for ($i = 0; $i < strlen($timestamp); $i++) {
if (strpos('0123456789', $timestamp[$i]) === FALSE) {
return FALSE;
}
}
return TRUE;
}
function _drd_server_count($table, $primary) {
if (db_table_exists($table)) {
$query = db_select($table);
$query
->addExpression('COUNT(' . $primary . ')', 'count');
return $query
->execute()
->fetchField();
}
return 0;
}
function _drd_server_count_session($timestamp = 0, $anonymous = TRUE) {
$query = db_select('sessions');
$query
->addExpression('COUNT(sid)', 'count');
$query
->condition('timestamp', $timestamp, '>=');
$query
->condition('uid', 0, $anonymous ? '=' : '>');
return $query
->execute()
->fetchField();
}
function _drd_server_count_file($status) {
$count_query = db_select('file_managed');
$count_query
->addExpression('COUNT(fid)', 'count');
$count = $count_query
->condition('status', $status)
->execute()
->fetchField();
$size_query = db_select('file_managed');
$size_query
->addExpression('SUM(filesize)', 'size');
$size = $size_query
->condition('status', $status)
->execute()
->fetchField();
return array(
'count' => $count,
'size' => $size,
);
}
function _drd_server_count_watchdog($severity, $period) {
if (!module_exists('dblog')) {
return 0;
}
$query = db_select('watchdog');
$query
->addExpression('COUNT(wid)', 'count');
$query
->condition('severity', $severity);
if ($period) {
$query
->condition('timestamp', REQUEST_TIME - $period, '>=');
}
return $query
->execute()
->fetchField();
}