summaryrefslogtreecommitdiffstats
path: root/library/Director/Util.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Director/Util.php')
-rw-r--r--library/Director/Util.php175
1 files changed, 175 insertions, 0 deletions
diff --git a/library/Director/Util.php b/library/Director/Util.php
new file mode 100644
index 0000000..22ad5fc
--- /dev/null
+++ b/library/Director/Util.php
@@ -0,0 +1,175 @@
+<?php
+
+namespace Icinga\Module\Director;
+
+use Icinga\Authentication\Auth;
+use Icinga\Data\ResourceFactory;
+use Icinga\Module\Director\Web\Form\QuickForm;
+use Icinga\Exception\NotImplementedError;
+use Icinga\Exception\ProgrammingError;
+use ipl\Html\Html;
+use gipfl\IcingaWeb2\Link;
+
+class Util
+{
+ protected static $auth;
+
+ protected static $allowedResources;
+
+ /**
+ * PBKDF2 - Password-Based Cryptography Specification (RFC2898)
+ *
+ * This method strictly follows examples in php.net's documentation
+ * comments. Hint: RFC6070 would be a good source for related tests
+ *
+ * @param string $alg Desired hash algorythm (sha1, sha256...)
+ * @param string $secret Shared secret, password
+ * @param string $salt Hash salt
+ * @param int $iterations How many iterations to perform. Please use at
+ * least 1000+. More iterations make it slower
+ * but more secure.
+ * @param int $length Desired key length
+ * @param bool $raw Returns the binary key if true, hex string otherwise
+ *
+ * @throws NotImplementedError when asking for an unsupported algorightm
+ * @throws ProgrammingError when passing invalid parameters
+ *
+ * @return string A $length byte long key, derived from secret and salt
+ */
+ public static function pbkdf2($alg, $secret, $salt, $iterations, $length, $raw = false)
+ {
+ if (! in_array($alg, hash_algos(), true)) {
+ throw new NotImplementedError('No such hash algorithm found: "%s"', $alg);
+ }
+
+ if ($iterations <= 0 || $length <= 0) {
+ throw new ProgrammingError('Positive iterations and length required');
+ }
+
+ $hashLength = strlen(hash($alg, '', true));
+ $blocks = ceil($length / $hashLength);
+
+ $out = '';
+
+ for ($i = 1; $i <= $blocks; $i++) {
+ // $i encoded as 4 bytes, big endian.
+ $last = $salt . pack('N', $i);
+ // first iteration
+ $last = $xorsum = hash_hmac($alg, $last, $secret, true);
+ // perform the other $iterations - 1 iterations
+ for ($j = 1; $j < $iterations; $j++) {
+ $xorsum ^= ($last = hash_hmac($alg, $last, $secret, true));
+ }
+ $out .= $xorsum;
+ }
+
+ if ($raw) {
+ return substr($out, 0, $length);
+ }
+
+ return bin2hex(substr($out, 0, $length));
+ }
+
+ public static function auth()
+ {
+ if (self::$auth === null) {
+ self::$auth = Auth::getInstance();
+ }
+ return self::$auth;
+ }
+
+ public static function hasPermission($name)
+ {
+ return self::auth()->hasPermission($name);
+ }
+
+ public static function getRestrictions($name)
+ {
+ return self::auth()->getRestrictions($name);
+ }
+
+ public static function resourceIsAllowed($name)
+ {
+ if (self::$allowedResources === null) {
+ $restrictions = self::getRestrictions('director/resources/use');
+ $list = array();
+ foreach ($restrictions as $restriction) {
+ foreach (preg_split('/\s*,\s*/', $restriction, -1, PREG_SPLIT_NO_EMPTY) as $key) {
+ $list[$key] = $key;
+ }
+ }
+
+ self::$allowedResources = $list;
+ } else {
+ $list = self::$allowedResources;
+ }
+
+ if (empty($list) || array_key_exists($name, $list)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public static function enumDbResources()
+ {
+ return self::enumResources('db');
+ }
+
+ public static function enumLdapResources()
+ {
+ return self::enumResources('ldap');
+ }
+
+ protected static function enumResources($type)
+ {
+ $resources = array();
+ foreach (ResourceFactory::getResourceConfigs() as $name => $resource) {
+ if ($resource->get('type') === $type && self::resourceIsAllowed($name)) {
+ $resources[$name] = $name;
+ }
+ }
+
+ return $resources;
+ }
+
+ public static function addDbResourceFormElement(QuickForm $form, $name)
+ {
+ static::addResourceFormElement($form, $name, 'db');
+ }
+
+ public static function addLdapResourceFormElement(QuickForm $form, $name)
+ {
+ static::addResourceFormElement($form, $name, 'ldap');
+ }
+
+ protected static function addResourceFormElement(QuickForm $form, $name, $type)
+ {
+ $list = self::enumResources($type);
+
+ $form->addElement('select', $name, array(
+ 'label' => 'Resource name',
+ 'multiOptions' => $form->optionalEnum($list),
+ 'required' => true,
+ ));
+
+ if (empty($list)) {
+ if (self::hasPermission('config/application/resources')) {
+ $form->addHtmlHint(Html::sprintf(
+ $form->translate('Please click %s to create new resources'),
+ Link::create(
+ $form->translate('here'),
+ 'config/resource',
+ null,
+ ['data-base-target' => '_main']
+ )
+ ));
+ $msg = sprintf($form->translate('No %s resource available'), $type);
+ } else {
+ $msg = $form->translate('Please ask an administrator to grant you access to resources');
+ }
+
+ $form->getElement($name)->addError($msg);
+ }
+ }
+}