diff --git a/action.php b/action.php index bf14b95..0ae4e7c 100644 --- a/action.php +++ b/action.php @@ -3,16 +3,11 @@ /** * Make things happen when buttons are pressed and forms submitted. */ -use LdapTools\LdapManager; -use LdapTools\Object\LdapObjectType; require_once __DIR__ . "/required.php"; dieifnotloggedin(); -require_once __DIR__ . "/lib/login.php"; -require_once __DIR__ . "/lib/worst_passwords.php"; - function returnToSender($msg, $arg = "") { global $VARS; if ($arg == "") { @@ -28,35 +23,4 @@ switch ($VARS['action']) { session_destroy(); header('Location: index.php'); die("Logged out."); - case "chpasswd": - if ($_SESSION['password'] == $VARS['oldpass']) { - if ($VARS['newpass'] == $VARS['conpass']) { - $passrank = checkWorst500List($VARS['newpass']); - if ($passrank !== FALSE) { - returnToSender("password_500", $passrank); - } - if (strlen($VARS['newpass']) < MIN_PASSWORD_LENGTH) { - returnToSender("weak_password"); - } - - $database->update('accounts', ['password' => encryptPassword($VARS['newpass'])], ['uid' => $_SESSION['uid']]); - $_SESSION['password'] = $VARS['newpass']; - returnToSender("password_updated"); - } else { - returnToSender("new_password_mismatch"); - } - } else { - returnToSender("old_password_mismatch"); - } - break; - case "add2fa": - if (is_empty($VARS['secret'])) { - returnToSender("invalid_parameters"); - } - $database->update('accounts', ['authsecret' => $VARS['secret']], ['uid' => $_SESSION['uid']]); - returnToSender("2fa_enabled"); - case "rm2fa": - $database->update('accounts', ['authsecret' => ""], ['uid' => $_SESSION['uid']]); - returnToSender("2fa_removed"); - break; } \ No newline at end of file diff --git a/app.php b/app.php index 9b6a630..bf9adc1 100644 --- a/app.php +++ b/app.php @@ -125,7 +125,7 @@ if (!is_empty($_GET['page'])) { if (is_empty($_GET['arg'])) { $alertmsg = lang(MESSAGES[$_GET['msg']]['string'], false); } else { - $alertmsg = lang2(MESSAGES[$_GET['msg']]['string'], ["arg" => $_GET['arg']], false); + $alertmsg = lang2(MESSAGES[$_GET['msg']]['string'], ["arg" => strip_tags($_GET['arg'])], false); } $alerttype = MESSAGES[$_GET['msg']]['type']; $alerticon = "square-o"; diff --git a/composer.json b/composer.json index 6a29d8c..36b4e67 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,9 @@ { - "name": "netsyms/web-app-template", - "description": "Simple framework for rapid webapp development", + "name": "netsyms/business-app-template", + "description": "Template for a webapp integrated with a Portal server for authentication.", "type": "project", "require": { "catfan/medoo": "^1.2", - "spomky-labs/otphp": "^8.3", "guzzlehttp/guzzle": "^6.2" }, "license": "MIT", diff --git a/composer.lock b/composer.lock index 3b20699..b155599 100644 --- a/composer.lock +++ b/composer.lock @@ -4,63 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "e0730a4c33d1a1cbf8738481ba9a1f1e", + "content-hash": "1c8b61c5d506ae016285b99b20040cf0", "packages": [ - { - "name": "beberlei/assert", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/beberlei/assert.git", - "reference": "3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/beberlei/assert/zipball/3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a", - "reference": "3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=5.3" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.1.1", - "phpunit/phpunit": "^4|^5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Assert\\": "lib/Assert" - }, - "files": [ - "lib/Assert/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de", - "role": "Lead Developer" - }, - { - "name": "Richard Quadling", - "email": "rquadling@gmail.com", - "role": "Collaborator" - } - ], - "description": "Thin assertion library for input validation in business models.", - "keywords": [ - "assert", - "assertion", - "validation" - ], - "time": "2017-03-14T18:06:52+00:00" - }, { "name": "catfan/medoo", "version": "v1.2.1", @@ -116,60 +61,6 @@ ], "time": "2017-02-17T16:05:35+00:00" }, - { - "name": "christian-riesen/base32", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/ChristianRiesen/base32.git", - "reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ChristianRiesen/base32/zipball/0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa", - "reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "4.*", - "satooshi/php-coveralls": "0.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Base32\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Riesen", - "email": "chris.riesen@gmail.com", - "homepage": "http://christianriesen.com", - "role": "Developer" - } - ], - "description": "Base32 encoder/decoder according to RFC 4648", - "homepage": "https://github.com/ChristianRiesen/base32", - "keywords": [ - "base32", - "decode", - "encode", - "rfc4648" - ], - "time": "2016-05-05T11:49:03+00:00" - }, { "name": "guzzlehttp/guzzle", "version": "6.2.3", @@ -348,54 +239,6 @@ ], "time": "2017-03-20T17:10:46+00:00" }, - { - "name": "paragonie/random_compat", - "version": "v2.0.10", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d", - "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d", - "shasum": "" - }, - "require": { - "php": ">=5.2.0" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "autoload": { - "files": [ - "lib/random.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "pseudorandom", - "random" - ], - "time": "2017-03-13T16:27:32+00:00" - }, { "name": "psr/http-message", "version": "1.0.1", @@ -445,237 +288,6 @@ "response" ], "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "spomky-labs/otphp", - "version": "v8.3.0", - "source": { - "type": "git", - "url": "https://github.com/Spomky-Labs/otphp.git", - "reference": "8c90e16ba48fe7c306832611e22c5bad2d663a98" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/8c90e16ba48fe7c306832611e22c5bad2d663a98", - "reference": "8c90e16ba48fe7c306832611e22c5bad2d663a98", - "shasum": "" - }, - "require": { - "beberlei/assert": "^2.4", - "christian-riesen/base32": "^1.1", - "paragonie/random_compat": "^2.0", - "php": "^5.5|^7.0", - "symfony/polyfill-mbstring": "^1.1", - "symfony/polyfill-php56": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "~4.0|^5.0", - "satooshi/php-coveralls": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "8.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "OTPHP\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Florent Morselli", - "homepage": "https://github.com/Spomky" - }, - { - "name": "All contributors", - "homepage": "https://github.com/Spomky-Labs/otphp/contributors" - } - ], - "description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator", - "homepage": "https://github.com/Spomky-Labs/otphp", - "keywords": [ - "FreeOTP", - "RFC 4226", - "RFC 6238", - "google authenticator", - "hotp", - "otp", - "totp" - ], - "time": "2016-12-08T10:46:02+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2016-11-14T01:06:16+00:00" - }, - { - "name": "symfony/polyfill-php56", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php56.git", - "reference": "1dd42b9b89556f18092f3d1ada22cb05ac85383c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/1dd42b9b89556f18092f3d1ada22cb05ac85383c", - "reference": "1dd42b9b89556f18092f3d1ada22cb05ac85383c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/polyfill-util": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php56\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2016-11-14T01:06:16+00:00" - }, - { - "name": "symfony/polyfill-util", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-util.git", - "reference": "746bce0fca664ac0a575e465f65c6643faddf7fb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/746bce0fca664ac0a575e465f65c6643faddf7fb", - "reference": "746bce0fca664ac0a575e465f65c6643faddf7fb", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Util\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony utilities for portability of PHP codes", - "homepage": "https://symfony.com", - "keywords": [ - "compat", - "compatibility", - "polyfill", - "shim" - ], - "time": "2016-11-14T01:06:16+00:00" } ], "packages-dev": [], diff --git a/index.php b/index.php index 8de8dd3..1eab30a 100644 --- a/index.php +++ b/index.php @@ -6,48 +6,52 @@ require_once __DIR__ . "/lib/login.php"; /* Authenticate user */ $userpass_ok = false; $multiauth = false; -if ($VARS['progress'] == "1") { - if (authenticate_user($VARS['username'], $VARS['password'])) { - switch (get_account_status($VARS['username'])) { - case "LOCKED_OR_DISABLED": - $alert = lang("account locked", false); - break; - case "TERMINATED": - $alert = lang("account terminated", false); - break; - case "CHANGE_PASSWORD": - $alert = lang("password expired", false); - case "NORMAL": - $userpass_ok = true; - break; - case "ALERT_ON_ACCESS": - sendLoginAlertEmail($VARS['username']); - $userpass_ok = true; - break; +if (checkLoginServer()) { + if ($VARS['progress'] == "1") { + if (authenticate_user($VARS['username'], $VARS['password'])) { + switch (get_account_status($VARS['username'])) { + case "LOCKED_OR_DISABLED": + $alert = lang("account locked", false); + break; + case "TERMINATED": + $alert = lang("account terminated", false); + break; + case "CHANGE_PASSWORD": + $alert = lang("password expired", false); + case "NORMAL": + $userpass_ok = true; + break; + case "ALERT_ON_ACCESS": + sendLoginAlertEmail($VARS['username']); + $userpass_ok = true; + break; + } + if ($userpass_ok) { + if (userHasTOTP($VARS['username'])) { + $multiauth = true; + } else { + doLoginUser($VARS['username'], $VARS['password']); + header('Location: app.php'); + die("Logged in, go to app.php"); + } + } + } else { + $alert = lang("login incorrect", false); } - if ($userpass_ok) { - if (userHasTOTP($VARS['username'])) { - $multiauth = true; - } else { - doLoginUser($VARS['username'], $VARS['password']); + } else if ($VARS['progress'] == "2") { + if (verifyTOTP($VARS['username'], $VARS['authcode'])) { + if (doLoginUser($VARS['username'])) { header('Location: app.php'); die("Logged in, go to app.php"); + } else { + $alert = lang("login server user data error", false); } - } - } else { - $alert = lang("login incorrect", false); - } -} else if ($VARS['progress'] == "2") { - if (verifyTOTP($VARS['username'], $VARS['authcode'])) { - if (doLoginUser($VARS['username'])) { - header('Location: app.php'); - die("Logged in, go to app.php"); } else { - $alert = lang("login server user data error", false); + $alert = lang("2fa incorrect", false); } - } else { - $alert = lang("2fa incorrect", false); } +} else { + $alert = lang("login server unavailable", false); } ?> @@ -60,6 +64,7 @@ if ($VARS['progress'] == "1") { <?php echo SITE_TITLE; ?> + @@ -83,7 +88,7 @@ if ($VARS['progress'] == "1") { if (!is_empty($alert)) { ?>
- +
"Enter the six-digit code from your mobile authenticator app.", "2fa incorrect" => "Authentication code incorrect.", "login incorrect" => "Login incorrect.", + "login server unavailable" => "Login server unavailable. Try again later or contact technical support.", "account locked" => "This account has been disabled. Contact technical support.", "password expired" => "You must change your password before continuing.", "account terminated" => "Account terminated. Access denied.", diff --git a/lang/messages.php b/lang/messages.php index 419a2c2..8ac0b7a 100644 --- a/lang/messages.php +++ b/lang/messages.php @@ -1,38 +1,10 @@ [ - "string" => "current password incorrect", - "type" => "danger" - ], - "new_password_mismatch" => [ - "string" => "new password mismatch", - "type" => "danger" - ], - "weak_password" => [ - "string" => "weak password", - "type" => "danger" - ], - "password_updated" => [ - "string" => "password updated", - "type" => "success" - ], - "2fa_removed" => [ - "string" => "2fa removed", - "type" => "success" - ], - "2fa_enabled" => [ - "string" => "2fa enabled", - "type" => "success" - ], "invalid_parameters" => [ "string" => "invalid parameters", "type" => "danger" ], - "password_500" => [ - "string" => "password on 500 list", - "type" => "danger" - ], "account_state_error" => [ "string" => "account state error", "type" => "danger" diff --git a/lib/login.php b/lib/login.php index a9e635b..ed138b8 100644 --- a/lib/login.php +++ b/lib/login.php @@ -3,6 +3,38 @@ /** * Authentication and account functions. Connects to a Portal instance. */ + +/** + * Check the login server API for sanity + * @return boolean true if OK, else false + */ +function checkLoginServer() { + try { + $client = new GuzzleHttp\Client(); + + $response = $client + ->request('POST', PORTAL_API, [ + 'form_params' => [ + 'key' => PORTAL_KEY, + 'action' => "ping" + ] + ]); + + if ($response->getStatusCode() != 200) { + return false; + } + + $resp = json_decode($response->getBody(), TRUE); + if ($resp['status'] == "OK") { + return true; + } else { + return false; + } + } catch (Exception $e) { + return false; + } +} + //////////////////////////////////////////////////////////////////////////////// // Account handling // //////////////////////////////////////////////////////////////////////////////// diff --git a/lib/worst_passwords.php b/lib/worst_passwords.php deleted file mode 100644 index 049e42f..0000000 --- a/lib/worst_passwords.php +++ /dev/null @@ -1,522 +0,0 @@ -