public function create($capabilityType, $options = array()) { global $Opt; $contactId = defval($options, "contactId", 0); if (!$contactId && ($user = @$options["user"])) { $contactId = $this->prefix === "U" ? $user->contactDbId : $user->contactId; } $paperId = defval($options, "paperId", 0); $timeExpires = defval($options, "timeExpires", time() + 259200); $data = defval($options, "data"); $capid = false; for ($tries = 0; !$capid && $tries < 4; ++$tries) { if (($salt = hotcrp_random_bytes(16)) !== false) { Dbl::ql($this->dblink, "insert into Capability set capabilityType={$capabilityType}, contactId=?, paperId=?, timeExpires=?, salt=?, data=?", $contactId, $paperId, $timeExpires, $salt, $data); $capid = $this->dblink->insert_id; } } if (!$capid) { return false; } return $this->prefix . "1" . str_replace(array("+", "/", "="), array("-a", "-b", ""), base64_encode($salt)); }
function hotcrp_random_password($length = 14) { global $Opt; $bytes = hotcrp_random_bytes($length + 10, true); if ($bytes === false) { $bytes = ""; while (strlen($bytes) < $length) { $bytes .= sha1($Opt["conferenceKey"] . pack("V", mt_rand())); } } $l = "a e i o u y a e i o u y a e i o u y a e i o u y a e i o u y b c d g h j k l m n p r s t u v w trcrbrfrthdrchphwrstspswprslcl2 3 4 5 6 7 8 9 - @ _ + = "; $pw = ""; $nvow = 0; for ($i = 0; $i < strlen($bytes) && strlen($pw) < $length + max(0, ($nvow - 3) / 3); ++$i) { $x = ord($bytes[$i]) % (strlen($l) / 2); if ($x < 30) { ++$nvow; } $pw .= rtrim(substr($l, 2 * $x, 2)); } return $pw; }
private static function hash_password($input, $iscdb) { $method = self::password_hash_method(); if ($method === false) { return $input; } else { if (is_int($method)) { return " \$" . password_hash($input, $method); } else { $keyid = self::preferred_password_keyid($iscdb); $key = self::password_hmac_key($keyid); $salt = hotcrp_random_bytes(16); return " " . $method . " " . $keyid . " " . $salt . hash_hmac($method, $salt . $input, $key, true); } } }
function load_settings() { global $Opt, $OptOverride, $Now, $OK; // load settings from database $this->settings = array(); $this->settingTexts = array(); $result = $this->q("select name, value, data from Settings"); while ($result && ($row = $result->fetch_row())) { $this->settings[$row[0]] = (int) $row[1]; if ($row[2] !== null) { $this->settingTexts[$row[0]] = $row[2]; } if (substr($row[0], 0, 4) == "opt.") { $okey = substr($row[0], 4); if (!array_key_exists($okey, $OptOverride)) { $OptOverride[$okey] = get($Opt, $okey); } $Opt[$okey] = $row[2] === null ? (int) $row[1] : $row[2]; } } Dbl::free($result); // update schema $this->sversion = $this->settings["allowPaperOption"]; if ($this->sversion < 132) { require_once "updateschema.php"; $oldOK = $OK; updateSchema($this); $OK = $oldOK; } if ($this->sversion < 73) { self::msg_error("Warning: The database could not be upgraded to the current version; expect errors. A system administrator must solve this problem."); } // invalidate caches after loading from backup if (isset($this->settings["frombackup"]) && $this->invalidateCaches()) { $this->qe("delete from Settings where name='frombackup' and value=" . $this->settings["frombackup"]); unset($this->settings["frombackup"]); } else { $this->invalidateCaches(array("rf" => true)); } // update options if (isset($Opt["ldapLogin"]) && !$Opt["ldapLogin"]) { unset($Opt["ldapLogin"]); } if (isset($Opt["httpAuthLogin"]) && !$Opt["httpAuthLogin"]) { unset($Opt["httpAuthLogin"]); } // set conferenceKey if (!isset($Opt["conferenceKey"])) { if (!isset($this->settingTexts["conf_key"]) && ($key = hotcrp_random_bytes(32)) !== false) { $this->save_setting("conf_key", 1, $key); } $Opt["conferenceKey"] = defval($this->settingTexts, "conf_key", ""); } // set capability key if (!get($this->settings, "cap_key") && !get($Opt, "disableCapabilities") && !(($key = hotcrp_random_bytes(16)) !== false && ($key = base64_encode($key)) && $this->save_setting("cap_key", 1, $key))) { $Opt["disableCapabilities"] = true; } // GC old capabilities if (defval($this->settings, "__capability_gc", 0) < $Now - 86400) { foreach (array($this->dblink, Contact::contactdb()) as $db) { if ($db) { Dbl::ql($db, "delete from Capability where timeExpires>0 and timeExpires<{$Now}"); } } $this->q("insert into Settings (name, value) values ('__capability_gc', {$Now}) on duplicate key update value=values(value)"); $this->settings["__capability_gc"] = $Now; } $this->crosscheck_settings(); $this->crosscheck_options(); }
function load_settings() { global $Now; // load settings from database $this->settings = array(); $this->settingTexts = array(); foreach ($this->opt_override ?: [] as $k => $v) { if ($v === null) { unset($this->opt[$k]); } else { $this->opt[$k] = $v; } } $this->opt_override = []; $this->_pc_seeall_cache = null; $this->deadlineCache = null; $result = $this->q_raw("select name, value, data from Settings"); while ($result && ($row = $result->fetch_row())) { $this->settings[$row[0]] = (int) $row[1]; if ($row[2] !== null) { $this->settingTexts[$row[0]] = $row[2]; } if (substr($row[0], 0, 4) == "opt.") { $okey = substr($row[0], 4); $this->opt_override[$okey] = get($this->opt, $okey); $this->opt[$okey] = $row[2] === null ? (int) $row[1] : $row[2]; } } Dbl::free($result); // update schema $this->sversion = $this->settings["allowPaperOption"]; if ($this->sversion < 108) { require_once "updateschema.php"; $old_nerrors = Dbl::$nerrors; updateSchema($this); Dbl::$nerrors = $old_nerrors; } // invalidate all caches after loading from backup if (isset($this->settings["frombackup"]) && $this->invalidate_caches()) { $this->qe_raw("delete from Settings where name='frombackup' and value=" . $this->settings["frombackup"]); unset($this->settings["frombackup"]); } else { $this->invalidate_caches(["rf" => true]); } // update options if (isset($this->opt["ldapLogin"]) && !$this->opt["ldapLogin"]) { unset($this->opt["ldapLogin"]); } if (isset($this->opt["httpAuthLogin"]) && !$this->opt["httpAuthLogin"]) { unset($this->opt["httpAuthLogin"]); } // set conferenceKey if (!isset($this->opt["conferenceKey"])) { if (!isset($this->settingTexts["conf_key"]) && ($key = hotcrp_random_bytes(32)) !== false) { $this->save_setting("conf_key", 1, $key); } $this->opt["conferenceKey"] = get($this->settingTexts, "conf_key", ""); } // set capability key if (!get($this->settings, "cap_key") && !get($this->opt, "disableCapabilities") && !(($key = hotcrp_random_bytes(16)) !== false && ($key = base64_encode($key)) && $this->save_setting("cap_key", 1, $key))) { $this->opt["disableCapabilities"] = true; } // GC old capabilities if (defval($this->settings, "__capability_gc", 0) < $Now - 86400) { foreach (array($this->dblink, Contact::contactdb()) as $db) { if ($db) { Dbl::ql($db, "delete from Capability where timeExpires>0 and timeExpires<{$Now}"); } } $this->q_raw("insert into Settings (name, value) values ('__capability_gc', {$Now}) on duplicate key update value=values(value)"); $this->settings["__capability_gc"] = $Now; } $this->crosscheck_settings(); $this->crosscheck_options(); }
public function create_capability($capabilityType, $options = array()) { $contactId = defval($options, "contactId", 0); $paperId = defval($options, "paperId", 0); $timeExpires = defval($options, "timeExpires", time() + 259200); $salt = hotcrp_random_bytes(24); $data = defval($options, "data"); $this->q("insert into Capability (capabilityType, contactId, paperId, timeExpires, salt, data) values ({$capabilityType}, {$contactId}, {$paperId}, {$timeExpires}, '" . sqlq($salt) . "', " . ($data === null ? "null" : "'" . sqlq($data) . "'") . ")"); $capid = $this->dblink->insert_id; if (!$capid || !function_exists("hash_hmac")) { return false; } return $this->encode_capability($capid, $salt, $timeExpires, true); }