Skip to content
This repository has been archived by the owner on Aug 9, 2021. It is now read-only.

WIP Broker Auth API #507

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions front/mosquittoauth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* LICENSE
*
* Copyright © 2016-2018 Teclib'
* Copyright © 2010-2018 by the FusionInventory Development Team.
*
* This file is part of Flyve MDM Plugin for GLPI.
*
* Flyve MDM Plugin for GLPI is a subproject of Flyve MDM. Flyve MDM is a mobile
* device management software.
*
* Flyve MDM Plugin for GLPI is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Flyve MDM Plugin for GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with Flyve MDM Plugin for GLPI. If not, see http://www.gnu.org/licenses/.
* ------------------------------------------------------------------------------
* @author Thierry Bugier
* @copyright Copyright © 2018 Teclib
* @license AGPLv3+ http://www.gnu.org/licenses/agpl.txt
* @link https://github.com/flyve-mdm/glpi-plugin
* @link https://flyve-mdm.com/
* ------------------------------------------------------------------------------
*/

// Workaround CSRF checks
$postData = $_POST;
unset($_POST);

include '../../../inc/includes.php';
$plugin = new Plugin();
if (!$plugin->isActivated('flyvemdm')) {
http_response_code(404);
}

// Restore POST data
$_POST = $postData;
$flyvemdmM2mApi = new PluginFlyvemdmMosquittoAuth();

if (isset($_GET['authenticate'])) {
$answer = $flyvemdmM2mApi->authenticate($_POST);
http_response_code($answer);
die();
}
if (isset($_GET['superuser'])) {
$answer = $flyvemdmM2mApi->isSuperuser($_POST);
http_response_code($answer);
die();
}
if (isset($_GET['authorize'])) {
$answer = $flyvemdmM2mApi->authorize($_POST);
http_response_code($answer);
die();
}

http_response_code(404);
58 changes: 58 additions & 0 deletions inc/m2mauth.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* LICENSE
*
* Copyright © 2016-2018 Teclib'
* Copyright © 2010-2018 by the FusionInventory Development Team.
*
* This file is part of Flyve MDM Plugin for GLPI.
*
* Flyve MDM Plugin for GLPI is a subproject of Flyve MDM. Flyve MDM is a mobile
* device management software.
*
* Flyve MDM Plugin for GLPI is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Flyve MDM Plugin for GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with Flyve MDM Plugin for GLPI. If not, see http://www.gnu.org/licenses/.
* ------------------------------------------------------------------------------
* @author Thierry Bugier
* @copyright Copyright © 2018 Teclib
* @license AGPLv3+ http://www.gnu.org/licenses/agpl.txt
* @link https://github.com/flyve-mdm/glpi-plugin
* @link https://flyve-mdm.com/
* ------------------------------------------------------------------------------
*/

if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}

abstract class PluginFlyvemdmM2mAuth implements PluginFlyvemdmM2mAuthInterface {

/**
* Checks the remote IP address matches the configured M2M server
*/
protected function checkRemote() {
$remoteIp = Toolbox::getRemoteIpAddress();
$config = Config::getConfigurationValues('flyvemdm', ['mqtt_broker_internal_address']);

// Try assuming the internal address is an IP Address
if ($config['mqtt_broker_internal_address'] == $remoteIp) {
return true;
}

foreach (gethostbynamel($config['mqtt_broker_internal_address']) as $validIp) {
if ($remoteIp == $validIp) {
return true;
}
}

return false;
}
}
48 changes: 48 additions & 0 deletions inc/m2mauthinterface.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/**
* LICENSE
*
* Copyright © 2016-2018 Teclib'
* Copyright © 2010-2018 by the FusionInventory Development Team.
*
* This file is part of Flyve MDM Plugin for GLPI.
*
* Flyve MDM Plugin for GLPI is a subproject of Flyve MDM. Flyve MDM is a mobile
* device management software.
*
* Flyve MDM Plugin for GLPI is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Flyve MDM Plugin for GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with Flyve MDM Plugin for GLPI. If not, see http://www.gnu.org/licenses/.
* ------------------------------------------------------------------------------
* @author Thierry Bugier
* @copyright Copyright © 2018 Teclib
* @license AGPLv3+ http://www.gnu.org/licenses/agpl.txt
* @link https://github.com/flyve-mdm/glpi-plugin
* @link https://flyve-mdm.com/
* ------------------------------------------------------------------------------
*/

if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}

interface PluginFlyvemdmM2mAuthInterface {
/**
* Challenges an authentication attempt from Mosquitto
* @see https://github.com/rabbitmq/rabbitmq-auth-backend-http/blob/v3.7.5/README.md
*
* @param array $input POST data
*
* @return integer HTTP response code
*/
public function authenticate($input);

public function authorize($input);
}
109 changes: 109 additions & 0 deletions inc/mosquittoauth.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
/**
* LICENSE
*
* Copyright © 2016-2018 Teclib'
* Copyright © 2010-2018 by the FusionInventory Development Team.
*
* This file is part of Flyve MDM Plugin for GLPI.
*
* Flyve MDM Plugin for GLPI is a subproject of Flyve MDM. Flyve MDM is a mobile
* device management software.
*
* Flyve MDM Plugin for GLPI is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Flyve MDM Plugin for GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with Flyve MDM Plugin for GLPI. If not, see http://www.gnu.org/licenses/.
* ------------------------------------------------------------------------------
* @author Thierry Bugier
* @copyright Copyright © 2018 Teclib
* @license AGPLv3+ http://www.gnu.org/licenses/agpl.txt
* @link https://github.com/flyve-mdm/glpi-plugin
* @link https://flyve-mdm.com/
* ------------------------------------------------------------------------------
*/

if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}

class PluginFlyvemdmMosquittoAuth extends PluginFlyvemdmM2mAuth {
public function authenticate($input) {
if (!$this->checkRemote()) {
return 403;
}

if (!isset($input['username']) || !isset($input['password'])) {
// No credentials or credentials incomplete
return 404;
}

$mqttUser = new PluginFlyvemdmMqttUser();
if (!$mqttUser->getByUser($input['username'])) {
return 404;
}
if ($mqttUser->getField('enabled') == '0') {
return 404;
}
$input['password'] = Toolbox::stripslashes_deep($input['password']);
if ($mqttUser->comparePasswords($input['password'])) {
return 200;
}

return 404;
}

public function authorize($input) {
$mqttUser = new PluginFlyvemdmMqttUser();
if (!$mqttUser->getByUser($input['username'])) {
return 403;
}
if ($mqttUser->getField('enabled') == '0') {
return 403;
}

$mqttUserId = $mqttUser->getID();
$acc = (int) $input['acc'];
$requestedTopic = explode('/', $input['topic']);
$mqttAcl = new PluginFlyvemdmMqttAcl();
$rows = $mqttAcl->find("`plugin_flyvemdm_mqttusers_id`='$mqttUserId'
AND `access_level` & $acc");
foreach ($rows as $row) {
$topic = explode('/', $row['topic']);
$match = true;
foreach ($topic as $index => $pathItem) {
if ($pathItem === '+') {
// This path item matches a joker
continue;
}
if ($pathItem === '#' && $index === count($topic) - 1) {
continue;
}
if (!isset($requestedTopic[$index])) {
$match = false;
break;
}
if ($pathItem !== $requestedTopic[$index]) {
// This topic does not match, try the next one
$match = false;
break;
}
}
if ($match) {
return 200;
}
}

return 403;
}

public function isSuperuser($input) {
return 403;
}
}
64 changes: 49 additions & 15 deletions inc/mqttuser.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
*/
class PluginFlyvemdmMqttuser extends CommonDBTM {

private $pbdkf2Settings = [
'algorithm' => 'sha256',
'iterations' => 901,
'saltSize' => 12,
'keyLength' => 48,
];

/**
* @see CommonDBTM::prepareInputForAdd()
*/
Expand Down Expand Up @@ -112,34 +119,61 @@ public function post_updateItem($history = 1) {
}
}


/**
* Hash a password
* @param string $clearPassword
* @return string PBKDF2 hashed password
*/
protected function hashPassword($clearPassword) {
public function hashPassword($clearPassword) {
// These parameters may be added to the function as a future improvement
$algorithm = 'sha256';
$saltSize = 12;
$keyLength = 24;
$salt = base64_encode(openssl_random_pseudo_bytes($saltSize));
$iterations = 901;
$rawOutput = true;

if ($rawOutput) {
$keyLength *= 2;
}
$algorithm = $this->pbdkf2Settings['algorithm'];
$keyLength = $this->pbdkf2Settings['keyLength'];
$salt = base64_encode(openssl_random_pseudo_bytes($this->pbdkf2Settings['saltSize']));
$iterations = $this->pbdkf2Settings['iterations'];

$hashed = hash_pbkdf2('sha256', $clearPassword, $salt, $iterations, $keyLength, true);

return implode(
'$',
[
'PBKDF2',
$algorithm,
$iterations,
$salt,
base64_encode($hashed)
]
);
}

$hashed = hash_pbkdf2('sha256', $clearPassword, $salt, $iterations, $keyLength, $rawOutput);
/**
* Challenge a password against tha hashed password stored in database
*
* @param string $challenged
*
* @return boolean true if the password matches the hashed password
*/
public function comparePasswords($challenged) {
if ($this->isNewItem()) {
return false;
}

return 'PBKDF2$' . $algorithm . '$' . $iterations . '$' . $salt . '$' . base64_encode($hashed);
$pbdkf2 = explode('$', $this->fields['password']);
$algorithm = $pbdkf2[1];
$salt = $pbdkf2[3];
$iterations = $pbdkf2[2];
$keyLength = strlen(base64_decode($pbdkf2[4]));
$hashed = hash_pbkdf2($algorithm, $challenged, $salt, $iterations, $keyLength, true);
return $hashed === base64_decode($pbdkf2[4]);
}

/**
* Generate a random password havind a determined set pf chars
* http://stackoverflow.com/a/31284266
* Generate a random password havind a determined set of chars
* @see http://stackoverflow.com/a/31284266
*
* @param integer $length password length to generate
* @param string $keyspace characters available to build the password
*
* @return string
* @throws Exception
*/
Expand Down
Loading