Author: jfthomps
Date: Wed May 24 20:52:38 2017
New Revision: 1796099
URL: http://svn.apache.org/viewvc?rev=1796099&view=rev
Log:
VCL-1045 - Method of encrypting sensitive database entries
addomain.php:
-added submitToggleDeleteResourceExtra: needed to be able to delete entries
from cryptsecret before deleting entries from addomain
-modified AJsaveResource and addResource: added code to encrypt password field
and set secretid field for entry corresponding to encrypted password
secrets-default.php:
-changed description for $cryptkey to generate a 32 byte string instead of 16
-removed $cryptiv: this should be random for every encrypted piece of data
utils.php:
-moved require_once for phpseclib files to initGlobals and only if needed
-modified initGlobals: added check for existance of openssl_encrypt function;
if exists, set USE_PHPSECLIB to 0 and base64 decode $cryptkey, otherwise,
require_once needed files and set USE_PHPSECLIB to 1; set global $ivsize to 16
-added checkCryptkey
-modified encryptData: made more generic; accepts $cryptkey as an argument,
randomly generates $iv each call, changed cypher to be 256 bit, if encryption
fails, return NULL, prepend $iv to encrypted data before base64 encoding it
-modified decryptDAta: made more generic; accepts $cryptkey as an argument,
splits base64 decoded data in to $iv and $cryptdata, changed cypher to be 256
bit, return false if decryption failes
-added encryptDBdata
-added decryptSecret
-added getSecretID
-added deleteSecrets
-added getCryptKeyID
-added encryptSecret
-added encryptSecrets
-modified getADdomains: added secretid to returned data
-modified addContinuationsEntry: pulled in $cryptkey global; pass $cryptkey to
encryptData
-modified getContinuationsData: pulled in $cryptkey global; pass $cryptkey to
decryptData
-modified xmlrpccall: added registration for XMLRPCupdateSecrets
xmlrpcWrappers.php: added XMLRPCupdateSecrets
Modified:
vcl/trunk/web/.ht-inc/addomain.php
vcl/trunk/web/.ht-inc/secrets-default.php
vcl/trunk/web/.ht-inc/utils.php
vcl/trunk/web/.ht-inc/xmlrpcWrappers.php
Modified: vcl/trunk/web/.ht-inc/addomain.php
URL:
http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/addomain.php?rev=1796099&r1=1796098&r2=1796099&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/addomain.php (original)
+++ vcl/trunk/web/.ht-inc/addomain.php Wed May 24 20:52:38 2017
@@ -125,6 +125,25 @@ class ADdomain extends Resource {
/////////////////////////////////////////////////////////////////////////////
///
+ /// \fn submitToggleDeleteResourceExtra($rscid, $deleted)
+ ///
+ /// \param $rscid - id of a resource (from table specific to that
resource,
+ /// not from the resource table)
+ /// \param $deleted - (optional, default=0) 1 if resource was previously
+ /// deleted; 0 if not
+ ///
+ /// \brief function to do any extra stuff specific to a resource type
when
+ /// toggling delete for a resource; to be implemented by inheriting
class if
+ /// needed
+ ///
+
/////////////////////////////////////////////////////////////////////////////
+ function submitToggleDeleteResourceExtra($rscid, $deleted=0) {
+ $data = $this->getData(array('rscid' => $rscid));
+ deleteSecrets($data[$rscid]['secretid']);
+ }
+
+
/////////////////////////////////////////////////////////////////////////////
+ ///
/// \fn AJsaveResource()
///
/// \brief saves changes to a resource; must be implemented by
inheriting
@@ -166,8 +185,22 @@ class ADdomain extends Resource {
$updates[] = "username = '{$data['username']}'";
# password
if(strlen($data['password'])) {
- $esc_pass =
mysql_real_escape_string($data['password']);
- $updates[] = "password = '$esc_pass'";
+ if($olddata['secretid'] == 0) {
+ $olddata['secretid'] =
getSecretID('addomain', 'secretid', $data['rscid']);
+ if($olddata['secretid'] == NULL) {
+ $ret = array('status' =>
'error', 'msg' => "Error encountered while updating password");
+ sendJSON($ret);
+ return;
+ }
+ $updates[] = "secretid =
'{$olddata['secretid']}'";
+ }
+ $encpass = encryptDBdata($data['password'],
$olddata['secretid']);
+ if($encpass == NULL) {
+ $ret = array('status' => 'error', 'msg'
=> "Error encountered while updating password");
+ sendJSON($ret);
+ return;
+ }
+ $updates[] = "password = '$encpass'";
}
# dnsservers
if($data['dnsservers'] != $olddata['dnsservers'])
@@ -261,27 +294,26 @@ class ADdomain extends Resource {
global $user;
$ownerid = getUserlistID($data['owner']);
- $esc_pass = mysql_real_escape_string($data['password']);
$query = "INSERT INTO addomain"
. "(name, "
. "ownerid, "
. "domainDNSName, "
. "username, "
- . "password, "
+ . "secretid, "
. "dnsServers) "
. "VALUES ('{$data['name']}', "
. "$ownerid, "
. "'{$data['domaindnsname']}', "
. "'{$data['username']}', "
- . "'$esc_pass', "
+ . "0, "
. "'{$data['dnsservers']}')";
doQuery($query);
$rscid = dbLastInsertID();
- if($rscid == 0) {
+ if($rscid == 0)
return 0;
- }
+
// add entry in resource table
$query = "INSERT INTO resource "
. "(resourcetypeid, "
@@ -289,6 +321,16 @@ class ADdomain extends Resource {
. "VALUES ((SELECT id FROM resourcetype WHERE
name = 'addomain'), "
. "$rscid)";
doQuery($query);
+
+ $secretid = getSecretID('addomain', 'secretid', $rscid);
+ $encpass = encryptDBdata($data['password'], $secretid);
+
+ $query = "UPDATE addomain "
+ . "SET password = '$encpass', "
+ . "secretid = $secretid "
+ . "WHERE id = $rscid";
+ doQuery($query);
+
return $rscid;
}
Modified: vcl/trunk/web/.ht-inc/secrets-default.php
URL:
http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/secrets-default.php?rev=1796099&r1=1796098&r2=1796099&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/secrets-default.php (original)
+++ vcl/trunk/web/.ht-inc/secrets-default.php Wed May 24 20:52:38 2017
@@ -21,8 +21,7 @@ $vcldb = 'vcl'; # name of mysql
$vclusername = 'vcluser'; # username to access database
$vclpassword = ''; # password to access database
-$cryptkey = ''; # generate with "openssl rand 16 | base64"
-$cryptiv = ''; # generate with "openssl rand 16 | base64"
+$cryptkey = ''; # generate with "openssl rand 32 | base64"
$pemkey = ''; # random passphrase - won't ever have to type it so make it long
?>
Modified: vcl/trunk/web/.ht-inc/utils.php
URL:
http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/utils.php?rev=1796099&r1=1796098&r2=1796099&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/utils.php (original)
+++ vcl/trunk/web/.ht-inc/utils.php Wed May 24 20:52:38 2017
@@ -19,7 +19,6 @@
require_once(".ht-inc/secrets.php");
@include_once("itecsauth/itecsauth.php");
require_once(".ht-inc/authentication.php");
-require_once(".ht-inc/phpseclib/Crypt/AES.php");
require_once(".ht-inc/spyc-0.5.1/Spyc.php");
if(file_exists(".ht-inc/vcldocs.php"))
require_once(".ht-inc/vcldocs.php");
@@ -63,7 +62,7 @@ function initGlobals() {
global $passwdArray, $skin, $contdata, $lastmode, $inContinuation;
global $ERRORS, $actions;
global $affilValFunc, $addUserFunc, $updateUserFunc, $addUserFuncArgs;
- global $uniqid;
+ global $uniqid, $cryptkey, $ivsize;
define("SECINDAY", 86400);
define("SECINWEEK", 604800);
@@ -77,6 +76,20 @@ function initGlobals() {
$tmp = explode('.', $pathdata[1]);
$_GET["mode"] = $tmp[0];
}
+
+ if(function_exists('openssl_encrypt')) {
+ define('USE_PHPSECLIB', 0);
+ $crytpkey = base64_decode($cryptkey);
+ }
+ else {
+ define('USE_PHPSECLIB', 1);
+ require_once(".ht-inc/phpseclib/Crypt/Base.php");
+ require_once(".ht-inc/phpseclib/Crypt/Rijndael.php");
+ require_once(".ht-inc/phpseclib/Crypt/AES.php");
+ require_once(".ht-inc/phpseclib/Crypt/Random.php");
+ }
+ $ivsize = 16;
+
$mode = processInputVar("mode", ARG_STRING, 'main');
$inContinuation = 0;
$contdata = array();
@@ -597,6 +610,87 @@ function checkAccess() {
////////////////////////////////////////////////////////////////////////////////
///
+/// \fn checkCryptkey()
+///
+/// \brief checks for an entry in cryptkey; if missing, generates keys
+///
+////////////////////////////////////////////////////////////////////////////////
+function checkCryptkey() {
+ global $pemkey;
+ $reg = "|" . SCRIPT . "$|";
+ $filebase = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']);
+ $filebase .= "/.ht-inc/cryptkey";
+ $idfile = "$filebase/cryptkeyid";
+
+ if(is_file($idfile)) {
+ $fh = fopen($idfile, 'r');
+ $id = fread($fh, 50);
+ fclose($fh);
+ $_id = mysql_real_escape_string($id);
+
+ $query = "SELECT id "
+ . "FROM cryptkey "
+ . "WHERE id = '$_id'";
+ $qh = doQuery($query);
+ if($row = mysql_fetch_assoc($qh))
+ return;
+ }
+
+ # no id file or no matching entry in cryptkey, create new key
+ if(! is_writable($filebase))
+ return;
+
+ $keyfile = "$filebase/private.pem";
+
+ $args = array('private_key_bits' => 4096,
+ 'private_key_type' => OPENSSL_KEYTYPE_RSA,
+ 'digest_alg' => 'sha512');
+ # open and lock id file before generating key
+ $fh = fopen($idfile, 'w');
+ if(! flock($fh, LOCK_EX | LOCK_NB)) {
+ # assume collision with another web server generating a key
+ # return because when the key is needed, it should exist from
+ # the other server
+ fclose($fh);
+ return;
+ }
+ # generate key pair
+ $prikeyobj = openssl_pkey_new($args);
+ # create and secure private key file
+ touch($keyfile);
+ chmod($keyfile, 0600);
+ # save private key to file
+ $rc = openssl_pkey_export_to_file($prikeyobj, $keyfile, $pemkey);
+ if(! $rc) {
+ # release lock, close and delete file, return
+ flock($fh, LOCK_UN);
+ fclose($fh);
+ unlink($keyfile);
+ return;
+ }
+ # save public key to database
+ $tmp = openssl_pkey_get_details($prikeyobj);
+ $pubkey = $tmp['key'];
+ $query = "INSERT INTO cryptkey "
+ . "(hostid, "
+ . "hosttype, "
+ . "pubkey) "
+ . "SELECT COALESCE(MAX(hostid), 0) + 1, "
+ . "'web', "
+ . "'$pubkey' "
+ . "FROM cryptkey "
+ . "WHERE hosttype = 'web'";
+ doQuery($query);
+ $cryptkeyid = dbLastInsertID();
+ # save cryptkey id to file
+ fwrite($fh, $cryptkeyid);
+ # unlock file
+ flock($fh, LOCK_UN);
+ fclose($fh);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
/// \fn maintenanceCheck()
///
/// \brief checks for site being in maintenance; if so, read user message from
@@ -2555,61 +2649,71 @@ function getKey($data) {
////////////////////////////////////////////////////////////////////////////////
///
-/// \fn encryptData($data)
+/// \fn encryptData($data, $cryptkey)
///
/// \param $data - a string
+/// \param $cryptkey - key for encryption
///
-/// \return an encrypted form of the string that has been base64 encoded
+/// \return an encrypted form of $data that has been base64 encoded or NULL if
+/// encryption failed
///
-/// \brief encrypts $data with blowfish and base64 encodes it
+/// \brief encrypts $data with AES and base64 encodes it; IV is generated and
+/// prepended to encrypted data before base64 encoding
///
////////////////////////////////////////////////////////////////////////////////
-function encryptData($data) {
- global $cryptkey, $cryptiv;
+function encryptData($data, $cryptkey) {
+ global $ivsize;
if(! $data)
return false;
- if(! function_exists('openssl_encrypt')) {
+ if(USE_PHPSECLIB) {
+ $iv = crypt_random_string($ivsize);
$aes = new Crypt_AES();
$aes->setKey($cryptkey);
+ $aes->setIV($iv);
+ $aes->setKeyLength(256);
$cryptdata = $aes->encrypt($data);
}
else {
- static $key;
- static $iv;
- $key = base64_decode($cryptkey);
- $iv = base64_decode($cryptiv);
- $cryptdata = openssl_encrypt($data, 'AES-128-CBC', $key, 1,
$iv);
+ $iv = openssl_random_pseudo_bytes($ivsize);
+ $cryptdata = openssl_encrypt($data, 'AES-256-CBC', $cryptkey,
1, $iv);
+ if($cryptdata === FALSE)
+ return NULL;
}
+ $cryptdata = $iv . $cryptdata;
return trim(base64_encode($cryptdata));
}
////////////////////////////////////////////////////////////////////////////////
///
-/// \fn decryptData($data)
+/// \fn decryptData($data, $cryptkey)
///
/// \param $data - a string
+/// \param $cryptkey - key for decryption
///
-/// \return decrypted form of $data
+/// \return decrypted form of $data or false on error
///
-/// \brief base64 decodes $data and decrypts it
+/// \brief base64 decodes $data and decrypts it; $data is split into IV and
+/// encrypted data after base64 decoding
///
////////////////////////////////////////////////////////////////////////////////
-function decryptData($data) {
- global $cryptkey, $cryptiv;
+function decryptData($data, $cryptkey) {
+ global $ivsize;
if(! $data)
return false;
$cryptdata = base64_decode($data);
- if(! function_exists('openssl_encrypt')) {
+ $iv = substr($cryptdata, 0, $ivsize);
+ $cryptdata = substr($cryptdata, $ivsize);
+ if(USE_PHPSECLIB) {
$aes = new Crypt_AES();
$aes->setKey($cryptkey);
+ $aes->setIV($iv);
+ $aes->setKeyLength(256);
$decryptdata = $aes->decrypt($cryptdata);
}
else {
- static $key;
- static $iv;
- $key = base64_decode($cryptkey);
- $iv = base64_decode($cryptiv);
- $decryptdata = openssl_decrypt($cryptdata, 'AES-128-CBC', $key,
1, $iv);
+ $decryptdata = openssl_decrypt($cryptdata, 'AES-256-CBC',
$cryptkey, 1, $iv);
+ if($decryptdata === FALSE)
+ return false;
}
return trim($decryptdata);
}
@@ -2644,6 +2748,260 @@ function encryptDataAsymmetric($data, $p
////////////////////////////////////////////////////////////////////////////////
///
+/// \fn encryptDBdata($data, $secretid)
+///
+/// \param $data - a string
+/// \param $secretid - secretid from cryptsecret table
+///
+/// \return base64-encoded, encrypted form of $data or NULL on error
+///
+/// \brief encrypts $data with secret key from cryptsecret table
+///
+////////////////////////////////////////////////////////////////////////////////
+function encryptDBdata($data, $secretid) {
+ # fetch cryptsecret from db
+ $cryptkeyid = getCryptKeyID();
+ if($cryptkeyid == NULL)
+ return NULL;
+ $query = "SELECT cryptsecret "
+ . "FROM cryptsecret "
+ . "WHERE cryptkeyid = $cryptkeyid AND "
+ . "secretid = $secretid";
+ $qh = doQuery($query);
+ if(! ($row = mysql_fetch_assoc($qh)))
+ return NULL;
+ $secret = decryptSecret($row['cryptsecret']);
+ if($secret === NULL)
+ return NULL;
+ # encrypt $data using secret
+ if(USE_PHPSECLIB)
+ $iv = crypt_random_string(32);
+ else {
+ $iv = openssl_random_pseudo_bytes(32);
+ if($iv === FALSE)
+ return NULL;
+ }
+ $edata = encryptData($data, $secret, $iv);
+ return $edata;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn decryptSecret($encsecret)
+///
+/// \param $encsecret - encrypted secret
+///
+/// \return string that is decrypted form of $encsecret or NULL on error
+///
+/// \brief decrypts $encsecret using web server's secret key
+///
+////////////////////////////////////////////////////////////////////////////////
+function decryptSecret($encsecret) {
+ global $pemkey;
+ $cryptsecret = base64_decode($encsecret);
+ # read private key from file
+ $reg = "|" . SCRIPT . "$|";
+ $file = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']);
+ $file .= "/.ht-inc/cryptkey/private.pem";
+ $prikey = openssl_pkey_get_private("file://$file", $pemkey);
+ # decrypt secret using private key
+ $savehdlr = set_error_handler(create_function('', ''));
+ if(! openssl_private_decrypt($cryptsecret, $secret, $prikey,
OPENSSL_PKCS1_OAEP_PADDING)) {
+ set_error_handler($savehdlr);
+ return NULL;
+ }
+ return $secret;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getSecretID($table, $field, $recordid)
+///
+/// \param $table - name of a database table having a secret
+/// \param $field - name of field in table referencing secretid
+/// \param $recordid - id for record in table
+///
+/// \return id corresponding to a cryptsecret.secretid value; if value not
found
+/// and function failed to generate a new secret ID, NULL is returned
+///
+/// \brief gets the id for a cryptsecret.secretid entry from a table containing
+/// an encrypted value; if no entry is found, a new secret is generated and
+/// saved in cryptsecret
+///
+////////////////////////////////////////////////////////////////////////////////
+function getSecretID($table, $field, $recordid) {
+ $query = "SELECT $field FROM $table WHERE id = $recordid";
+ $qh = doQuery($query);
+ if(($row = mysql_fetch_row($qh)) && $row[0] != 0)
+ return $row[0];
+
+ # generate secret key
+ if(USE_PHPSECLIB)
+ $key = crypt_random_string(32);
+ else {
+ $key = openssl_random_pseudo_bytes(32);
+ if($key === FALSE)
+ return NULL;
+ }
+ # encrypt with my public key
+ $cryptkeyid = getCryptKeyID();
+ if($cryptkeyid === NULL)
+ return NULL;
+ $encdata = encryptSecret($key, $cryptkeyid);
+ if($encdata === NULL)
+ return NULL;
+ # write to cryptsecret
+ $query = "INSERT INTO cryptsecret "
+ . "(cryptkeyid, "
+ . "secretid, "
+ . "cryptsecret) "
+ . "SELECT $cryptkeyid, "
+ . "COALESCE(MAX(secretid), 0) + 1, "
+ . "'$encdata' "
+ . "FROM cryptsecret";
+ doQuery($query);
+ $id = dbLastInsertID();
+ $query = "SELECT secretid FROM cryptsecret WHERE id = $id";
+ $qh = doQuery($query);
+ if(! ($row = mysql_fetch_assoc($qh)))
+ return NULL;
+ # encrypt with all other public keys and write to cryptsecret
+ encryptSecrets($key, $row['secretid'], $cryptkeyid);
+ return $row['secretid'];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn deleteSecrets($secretid)
+///
+/// \param $secretid - secretid value corresponding to cryptsecret.secretid
+///
+/// \brief deletes all entries in cryptsecret for $secretid
+///
+////////////////////////////////////////////////////////////////////////////////
+function deleteSecrets($secretid) {
+ $query = "DELETE FROM cryptsecret WHERE secretid = $secretid";
+ doQuery($query);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getCryptKeyID()
+///
+/// \return id from cryptkey table corresponding to this web server's file
+/// space; returns NULL on error
+///
+/// \brief reads id from cryptkeyid file in web server's file space; if not
+/// found, calls checkCryptkey to generate a key and then returns it
+///
+////////////////////////////////////////////////////////////////////////////////
+function getCryptKeyID() {
+ $reg = "|" . SCRIPT . "$|";
+ $filebase = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']);
+ $filebase .= "/.ht-inc/cryptkey";
+ $idfile = "$filebase/cryptkeyid";
+
+ static $create = 1; # set flag so that recursion only goes one level
deep
+
+ if(! is_file($idfile)) {
+ if($create) {
+ $create = 0; # set to 0, subsequent calls to function
should never need to create a key
+ checkCryptkey();
+ return getCryptKeyID();
+ }
+ else
+ return NULL;
+ }
+
+ $fh = fopen($idfile, 'r');
+ $id = fread($fh, 50);
+ fclose($fh);
+ $_id = mysql_real_escape_string($id);
+
+ $query = "SELECT id "
+ . "FROM cryptkey "
+ . "WHERE id = '$_id'";
+ $qh = doQuery($query);
+ if($row = mysql_fetch_assoc($qh))
+ return $row['id'];
+
+ if($create) {
+ $create = 0; # set to 0, subsequent calls to function should
never need to create a key
+ checkCryptkey();
+ return getCryptKeyID();
+ }
+
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn encryptSecret($secret, $cryptkey)
+///
+/// \param $secret - secret key to encrypt
+/// \param $cryptkey - id from cryptkey table for public key to use or public
+/// key itself
+///
+/// \return encrypted data; returns NULL on error
+///
+/// \brief encrypts $secret with key for $cryptkeyid
+///
+////////////////////////////////////////////////////////////////////////////////
+function encryptSecret($secret, $cryptkey) {
+ if(is_numeric($cryptkey)) {
+ $query = "SELECT pubkey "
+ . "FROM cryptkey "
+ . "WHERE id = $cryptkey";
+ $qh = doQuery($query);
+ if(! ($row = mysql_fetch_assoc($qh)))
+ return NULL;
+ $cryptkey = $row['pubkey'];
+ }
+ $savehdlr = set_error_handler(create_function('', ''));
+ if(@openssl_public_encrypt($secret, $encdata, $cryptkey,
OPENSSL_PKCS1_OAEP_PADDING)) {
+ set_error_handler($savehdlr);
+ $b64data = base64_encode($encdata);
+ return $b64data;
+ }
+ set_error_handler($savehdlr);
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn encryptSecrets($secret, $secretid, $skipkeyid=0)
+///
+/// \param $secret - secret key to encrypt
+/// \param $secretid - id for secret from cryptsecret.secretid
+/// \param $skipkeyid - (optional, default=0) a cryptkey.id to skip (used if
+/// calling from a function that just encrypted $secret for a given cryptkey)
+///
+/// \brief encrypts $secret using any existing cryptkeys in database
+///
+////////////////////////////////////////////////////////////////////////////////
+function encryptSecrets($secret, $secretid, $skipkeyid=0) {
+ $query = "SELECT id, pubkey FROM cryptkey WHERE id != $skipkeyid";
+ $qh = doQuery($query);
+ $values = array();
+ while($row = mysql_fetch_assoc($qh)) {
+ $cryptsecret = encryptSecret($secret, $row['pubkey']);
+ if($cryptsecret === NULL)
+ continue;
+ $values[] = "({$row['id']}, $secretid, '$cryptsecret')";
+ }
+ if(! empty($values)) {
+ $allvalues = implode(',', $values);
+ $query = "INSERT INTO cryptsecret "
+ . "(cryptkeyid, "
+ . "secretid, "
+ . "cryptsecret) "
+ . "VALUES $allvalues";
+ doQuery($query);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
/// \fn getParentNodes($node)
///
/// \param $node - a privnode id
@@ -8871,7 +9229,8 @@ function getNATports($resid) {
/// \b owner\n
/// \b domaindnsname\n
/// \b username\n
-/// \b dnsservers
+/// \b dnsservers\n
+/// \b secretid
///
/// \brief builds an array of AD domains
///
@@ -8884,7 +9243,8 @@ function getADdomains($addomainid=0) {
. "CONCAT(u.unityid, '@', a.name) AS owner, "
. "ad.domainDNSName AS domaindnsname, "
. "ad.username, "
- . "ad.dnsServers AS dnsservers "
+ . "ad.dnsServers AS dnsservers, "
+ . "ad.secretid "
. "FROM addomain ad, "
. "affiliation a, "
. "user u, "
@@ -11549,7 +11909,7 @@ function getENUMvalues($table, $field) {
function addContinuationsEntry($nextmode, $data=array(), $duration=SECINWEEK,
$deleteFromSelf=1, $multicall=1,
$repeatProtect=0) {
- global $user, $mode, $inContinuation, $continuationid;
+ global $user, $mode, $inContinuation, $continuationid, $cryptkey;
if($repeatProtect)
$data['______parent'] = $continuationid;
$serdata = serialize($data);
@@ -11617,7 +11977,7 @@ function addContinuationsEntry($nextmode
$salt = generateString(8);
$now = time();
$data = "$salt:$contid:{$user['id']}:$now";
- $edata = encryptData($data);
+ $edata = encryptData($data, $cryptkey);
$udata = urlencode($edata);
return $udata;
}
@@ -11638,12 +11998,12 @@ function addContinuationsEntry($nextmode
///
////////////////////////////////////////////////////////////////////////////////
function getContinuationsData($data) {
- global $user, $continuationid, $noHTMLwrappers;
+ global $user, $continuationid, $noHTMLwrappers, $cryptkey;
if(array_key_exists('continuation', $_POST))
$edata = urldecode($data);
else
$edata = $data;
- if(! ($ddata = decryptData($edata)))
+ if(! ($ddata = decryptData($edata, $cryptkey)))
return array('error' => 'invalid input');
$items = explode(':', $ddata);
$now = time();
@@ -12079,6 +12439,7 @@ function xmlrpccall() {
xmlrpc_server_register_method($xmlrpc_handle,
"XMLRPCaddImageGroupToComputerGroup", "xmlRPChandler");
xmlrpc_server_register_method($xmlrpc_handle,
"XMLRPCremoveImageGroupFromComputerGroup", "xmlRPChandler");
xmlrpc_server_register_method($xmlrpc_handle,
"XMLRPCfinishBaseImageCapture", "xmlRPChandler");
+ xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCupdateSecrets",
"xmlRPChandler");
print xmlrpc_server_call_method($xmlrpc_handle, $HTTP_RAW_POST_DATA,
'');
xmlrpc_server_destroy($xmlrpc_handle);
Modified: vcl/trunk/web/.ht-inc/xmlrpcWrappers.php
URL:
http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php?rev=1796099&r1=1796098&r2=1796099&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/xmlrpcWrappers.php (original)
+++ vcl/trunk/web/.ht-inc/xmlrpcWrappers.php Wed May 24 20:52:38 2017
@@ -3739,6 +3739,73 @@ function XMLRPCfinishBaseImageCapture($o
////////////////////////////////////////////////////////////////////////////////
///
+/// \fn XMLRPCupdateSecrets()
+///
+/// \return an array with at least one index named 'status' which will have
+/// one of these values:\n
+/// \b error - error occurred; there will be 2 additional elements in the
array:\n
+/// \li \b errorcode - error number\n
+/// \li \b errormsg - error string\n
+/// \b success - indicates all secrets were successfully
+/// updated\n
+/// \b noupdate - indicates no missing values were found to be added to
+/// cryptsecret table
+///
+/// \brief checks for any entries in cryptkey that don't have corresponding
+/// entries in cryptsecret and adds them to cryptsecret
+///
+////////////////////////////////////////////////////////////////////////////////
+function XMLRPCupdateSecrets() {
+ global $user, $xmlrpcBlockAPIUsers;
+ if(! in_array($user['id'], $xmlrpcBlockAPIUsers)) {
+ return array('status' => 'error',
+ 'errorcode' => 99,
+ 'errormsg' => 'access denied for call to
XMLRPCupdateSecrets');
+ }
+ # query to find any cryptkeys that don't have values in cryptsecret
+ $self = "{$_SERVER['SERVER_ADDR']}::{$_SERVER['SERVER_NAME']}";
+ $mycryptkeyid = getCryptKeyID($self, 'web');
+ if($mycryptkeyid === NULL) {
+ return array('status' => 'error',
+ 'errorcode' => 100,
+ 'errormsg' => 'Encryption key missing for this web
server');
+ }
+ $query = "SELECT ck.id as cryptkeyid, "
+ . "ck.pubkey as cryptkey, "
+ . "s.id as secretid, "
+ . "cs.cryptsecret, "
+ . "mycs.cryptsecret AS mycryptsecret "
+ . "FROM cryptkey ck "
+ . "JOIN (SELECT DISTINCT secretid AS id FROM cryptsecret) AS s "
+ . "JOIN (SELECT cryptsecret, secretid FROM cryptsecret WHERE
cryptkeyid = $mycryptkeyid) AS mycs "
+ . "LEFT JOIN cryptsecret cs ON (s.id = cs.secretid AND ck.id =
cs.cryptkeyid) "
+ . "WHERE mycs.secretid = s.id AND "
+ . "cs.id IS NULL";
+ $qh = doQuery($query);
+ $values = array();
+ while($row = mysql_fetch_assoc($qh)) {
+ # decrypt secret
+ $secret = decryptSecret($row['mycryptsecret']);
+ # encrypt secret with any missing cryptkeys
+ $encsecret = encryptSecret($secret, $row['cryptkey']);
+ # save to cryptsecret
+ $values[] = "({$row['cryptkeyid']}, {$row['secretid']},
'$encsecret')";
+ }
+ if(! empty($values)) {
+ $allvalues = implode(',', $values);
+ $query = "INSERT INTO cryptsecret "
+ . "(cryptkeyid, "
+ . "secretid, "
+ . "cryptsecret) "
+ . "VALUES $allvalues";
+ doQuery($query);
+ return array('status' => 'success');
+ }
+ return array('status' => 'noupdate');
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
/// \fn XMLRPCgetOneClickParams($oneclickid)
///
/// \param $oneclickid - id of the one click