xcat-core/xCAT-UI/lib/functions.php

325 lines
9.0 KiB
PHP
Raw Normal View History

<?php
/**
* Contains all common PHP functions needed by most pages
*/
// Retain session variables across page requests
session_start();
session_write_close(); // Do not block HTTP requests
// The settings below display error on the screen,
// instead of giving blank pages.
error_reporting(E_ALL);
ini_set('display_errors', true);
/**
* Run a command using the xCAT client/server protocol
*
* @param $cmd The xCAT command
* @param $nr Node range or group
* @param $args_array Command arguments
* @param $opts_array Command options
* @return A tree of SimpleXML objects.
* See perl-xCAT/xCAT/Client.pm for the format
*/
function docmd($cmd, $nr, $args_array, $opts_array){
// If we are not logged in,
// do not try to communicate with xcatd
if (!is_logged()) {
echo "<p>You are not logged in! Failed to run command.</p>";
return simplexml_load_string('<xcat></xcat>', 'SimpleXMLElement', LIBXML_NOCDATA);
}
// Create xCAT request
// Add command, node range, and arguments to request
$request = simplexml_load_string('<xcatrequest></xcatrequest>');
$request->addChild('command', $cmd);
if(!empty($nr)) { $request->addChild('noderange', $nr); }
if (!empty($args_array)) {
foreach ($args_array as $a) {
$request->addChild('arg',$a);
}
}
// Add user and password to request
$usernode=$request->addChild('becomeuser');
$usernode->addChild('username',$_SESSION["username"]);
$usernode->addChild('password',getpassword());
$xml = submit_request($request, 0, $opts_array);
return $xml;
}
/**
* Used by docmd() to submit request to xCAT
*
* @param $req Tree of SimpleXML objects
* @param $opts_array Request options
* @return A tree of SimpleXML objects
*/
function submit_request($req, $skipVerify, $opts_array){
$xcathost = "localhost";
$port = "3001";
$rsp = FALSE;
$response = '';
$cleanexit = 0;
// Determine whether to flush output or not
$flush = false;
if ($opts_array && in_array("flush", $opts_array)) {
$flush = true;
}
// Determine how to handle the flush output
// You can specify a function name, in place of TBD, to handle the flush output
$flush_format = "";
if ($opts_array && in_array("flush-format=TBD", $opts_array)) {
$flush_format = "TBD";
}
// Open syslog, include the process ID and also send
// the log to standard error, and use a user defined
// logging mechanism
openlog("xCAT-UI", LOG_PID | LOG_PERROR, LOG_LOCAL0);
// Open a socket to xcatd
syslog(LOG_INFO, "Opening socket to xcatd...");
if($fp = stream_socket_client('ssl://'.$xcathost.':'.$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT)){
$reqXML = $req->asXML();
$nr = $req->noderange;
$cmd = $req->command;
syslog(LOG_INFO, "Sending request: $cmd $nr");
stream_set_blocking($fp, 0); // Set as non-blocking
fwrite($fp,$req->asXML()); // Send XML to xcatd
set_time_limit(900); // Set 15 minutes timeout (for long running requests)
// The default is 30 seconds which is too short for some requests
// Turn on output buffering
ob_start();
while(!feof($fp)) { // Read until there is no more
// Remove newlines and add it to the response
$str = fread($fp, 8192);
if ($str) {
$response .= preg_replace('/>\n\s*</', '><', $str);
// Flush output to browser
if ($flush) {
// Strip HTML tags from output
if ($tmp = trim(strip_tags($str))) {
// Format the output based on what was given for $flush_format
if ($flush_format == "TDB") {
format_TBD($tmp);
} else {
// Print out output by default
echo '<pre style="font-size: 10px;">' . $tmp . '</pre>';
ob_flush();
flush();
}
}
}
}
// Look for serverdone response
$fullpattern = '/<xcatresponse>\s*<serverdone>\s*<\/serverdone>\s*<\/xcatresponse>/';
$mixedpattern = '/<serverdone>\s*<\/serverdone>.*<\/xcatresponse>/';
$recentpattern = '/<\/xcatresponse>/';
if(preg_match($recentpattern,$str) && preg_match($mixedpattern,$response)) {
// Transaction is done,
// Package up XML and return it
// Remove the serverdone response and put an xcat tag around the rest
$count = 0;
$response = preg_replace($fullpattern,'', $response, -1, $count); // 1st try to remove the long pattern
if (!$count) { $response = preg_replace($mixedpattern,'', $response) . '</xcatresponse>/'; } // if its not there, then remove the short pattern
$response = "<xcat>$response</xcat>";
//delete the \n between '>' and '<'
$response = preg_replace('/>\n\s*</', '><', $response);
//replace the '\n' by ':|:' in the data area.
$response = preg_replace('/\n/', ':|:', $response);
$rsp = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);
$cleanexit = 1;
break;
}
} // End of while(!feof($fp))
syslog(LOG_INFO, "($cmd $nr) Sending response");
fclose($fp);
} else {
echo "<p>xCAT submit request socket error: $errno - $errstr</p>";
}
// Flush (send) the output buffer and turn off output buffering
ob_end_flush();
// Close syslog
closelog();
if(! $cleanexit) {
if (preg_match('/^\s*<xcatresponse>.*<\/xcatresponse>\s*$/',$response)) {
// Probably an error message
$response = "<xcat>$response</xcat>";
$rsp = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);
}
elseif(!$skipVerify) {
echo "<p>(Error) xCAT response ended prematurely: ", htmlentities($response), "</p>";
$rsp = FALSE;
}
}
return $rsp;
}
/**
* Enable password storage to split between cookie and session variable
*
* @param $data
* @param $key
* @return
*/
function xorcrypt($data, $key) {
$datalen = strlen($data);
$keylen = strlen($key);
for ($i=0;$i<$datalen;$i++) {
$data[$i] = chr(ord($data[$i])^ord($key[$i]));
}
return $data;
}
/**
* Get password
*
* @param Nothing
* @return
*/
function getpassword() {
if (isset($GLOBALS['xcatauthsecret'])) {
$cryptext = $GLOBALS['xcatauthsecret'];
} else if (isset($_COOKIE["xcatauthsecret"])) {
$cryptext = $_COOKIE["xcatauthsecret"];
} else {
return false;
}
return xorcrypt($_SESSION["secretkey"], base64_decode($cryptext));
}
/**
* Get the password splitting knowledge between server
* and client side persistant storage. Caller should regenerate
* session ID when contemplating a new user/password, to preclude
* session fixation, though fixation is limited without the secret.
*
* @param $password Password
* @return Nothing
*/
function setpassword($password) {
$randlen = strlen($password);
$key = getrandchars($randlen);
$cryptext = xorcrypt($password,$key);
// Non-ascii characters, encode it in base64
$cryptext = base64_encode($cryptext);
setcookie("xcatauthsecret",$cryptext,0,'/');
$GLOBALS["xcatauthsecret"] = $cryptext;
$_SESSION["secretkey"] = $key;
}
/**
* Get RAND characters
*
* @param $length Length of characters
* @return RAND characters
*/
function getrandchars($length) {
$charset = '0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*';
$charsize = strlen($charset);
srand();
$chars = '';
for ($i=0;$i<$length;$i++) {
$num=rand()%$charsize;
$chars=$chars.substr($charset,$num,1);
}
return $chars;
}
/**
* Determine if a user/password session exists
*
* @param Nothing
* @return True If user has a session.
* False Otherwise
*/
function is_logged() {
if (isset($_SESSION["username"]) and !is_bool(getpassword())) {
return true;
} else {
return false;
}
}
/**
* Determine if a user is currently logged in successfully
*
* @param Nothing
* @return True If the user is currently logged in successfully
* False Otherwise
*/
function isAuthenticated() {
if (is_logged()) {
if ($_SESSION["xcatpassvalid"] != 1) {
$testcred = docmd("authcheck", "", NULL, NULL);
if (isset($testcred->{'xcatresponse'}->{'data'})) {
$result = "".$testcred->{'xcatresponse'}->{'data'};
if (is_numeric(strpos("Authenticated",$result))) {
// Logged in successfully
$_SESSION["xcatpassvalid"] = 1;
} else {
// Not logged in
$_SESSION["xcatpassvalid"] = 0;
}
}
}
}
if (isset($_SESSION["xcatpassvalid"]) and $_SESSION["xcatpassvalid"]==1) {
return true;
} else {
return false;
}
}
/**
* Log out of the current user session
*
* @param Nothing
* @return Nothing
*/
function logout() {
// Clear the secret cookie from browser
if (isset($_COOKIE["xcatauthsecret"])) {
setcookie("xcatauthsecret",'',time()-86400*7,'/');
}
// Expire session cookie
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(),"",time()-86400*7,"/");
}
// Clear server store of data
$_SESSION=array();
}
/**
* Format a given string and echo it back to the browser
*
* @param $str String
* @return Nothing
*/
function format_TBD($str) {
// Format a given string however you want it
echo $tmp . '<br/>';
flush();
}
?>