From 6ea47cac34fd28b9d8157ceb1d643f7bfc6a4379 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Sun, 22 Jun 2008 14:44:07 +0000 Subject: [PATCH] Graphical code CAPTCHA partly finished, crypto class supports encryption/decryption via mcrypt functions, assertions added --- .gitattributes | 11 ++ application/ship-simu/config.php | 12 ++ application/ship-simu/exceptions.php | 27 +++- .../main/login/class_ShipSimuGuestLogin.php | 2 +- .../main/login/class_ShipSimuUserLogin.php | 2 +- .../personell/class_SimulatorPersonell.php | 21 +-- .../class_ShipSimuRegistration.php | 5 +- .../templates/de/code/login_form.ctp | 2 + .../templates/de/code/register_form.ctp | 1 + .../main/class_AssertionException.php | 39 +++++ .../main/class_FatalErrorException.php | 4 +- inc/classes/interfaces/captcha/.htaccess | 1 + .../captcha/class_SolveableCaptcha.php | 41 +++++ inc/classes/interfaces/crypto/.htaccess | 1 + .../interfaces/crypto/class_Cryptable.php | 55 +++++++ inc/classes/main/class_Base | 42 ++++++ .../main/class_BaseFrameworkSystem.php | 7 +- .../commands/web/class_WebRegisterCommand.php | 5 +- .../main/crypto/class_CryptoHelper.php | 70 +++++++-- .../filter/change/class_EmailChangeFilter.php | 1 + .../change/class_PasswordChangeFilter.php | 1 + .../class_AccountPasswordVerifierFilter.php | 2 +- inc/classes/main/helper/captcha/.htaccess | 1 + inc/classes/main/helper/captcha/class_ | 82 ++++++++++ .../main/helper/captcha/class_BaseCaptcha.php | 67 +++++++++ inc/classes/main/helper/captcha/web/.htaccess | 1 + .../web/class_GraphicalCodeCaptcha.php | 141 ++++++++++++++++++ .../main/helper/web/class_WebFormHelper.php | 28 +++- .../main/rng/class_RandomNumberGenerator.php | 28 ++-- inc/classes/main/user/class_Guest.php | 1 + inc/classes/main/user/class_User.php | 3 +- inc/config/class_FrameworkConfiguration.php | 7 +- 32 files changed, 664 insertions(+), 47 deletions(-) create mode 100644 inc/classes/exceptions/main/class_AssertionException.php create mode 100644 inc/classes/interfaces/captcha/.htaccess create mode 100644 inc/classes/interfaces/captcha/class_SolveableCaptcha.php create mode 100644 inc/classes/interfaces/crypto/.htaccess create mode 100644 inc/classes/interfaces/crypto/class_Cryptable.php create mode 100644 inc/classes/main/class_Base create mode 100644 inc/classes/main/helper/captcha/.htaccess create mode 100644 inc/classes/main/helper/captcha/class_ create mode 100644 inc/classes/main/helper/captcha/class_BaseCaptcha.php create mode 100644 inc/classes/main/helper/captcha/web/.htaccess create mode 100644 inc/classes/main/helper/captcha/web/class_GraphicalCodeCaptcha.php diff --git a/.gitattributes b/.gitattributes index 218bc6e..96837fa 100644 --- a/.gitattributes +++ b/.gitattributes @@ -219,6 +219,7 @@ inc/classes/exceptions/language/class_LanguagePathReadProtectedException.php -te inc/classes/exceptions/language/class_MissingFileIoHandlerException.php -text inc/classes/exceptions/language/class_MissingLanguageHandlerException.php -text inc/classes/exceptions/main/.htaccess -text +inc/classes/exceptions/main/class_AssertionException.php -text inc/classes/exceptions/main/class_ClassMismatchException.php -text inc/classes/exceptions/main/class_ClassNotFoundException.php -text inc/classes/exceptions/main/class_ConfigEntryIsEmptyException.php -text @@ -269,6 +270,8 @@ inc/classes/interfaces/auth/.htaccess -text inc/classes/interfaces/auth/class_Authorizeable.php -text inc/classes/interfaces/cache/.htaccess -text inc/classes/interfaces/cache/class_Cacheable.php -text +inc/classes/interfaces/captcha/.htaccess -text +inc/classes/interfaces/captcha/class_SolveableCaptcha.php -text inc/classes/interfaces/class_ -text inc/classes/interfaces/class_FrameworkInterface.php -text inc/classes/interfaces/compressor/.htaccess -text @@ -281,6 +284,8 @@ inc/classes/interfaces/criteria/extended/.htaccess -text inc/classes/interfaces/criteria/extended/class_LocalSearchCriteria.php -text inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php -text inc/classes/interfaces/criteria/extended/class_StoreableCriteria.php -text +inc/classes/interfaces/crypto/.htaccess -text +inc/classes/interfaces/crypto/class_Cryptable.php -text inc/classes/interfaces/database/.htaccess -text inc/classes/interfaces/database/class_FrameworkDatabaseInterface.php -text inc/classes/interfaces/database/frontend/.htaccess -text @@ -352,6 +357,7 @@ inc/classes/main/auth/class_CookieAuth.php -text inc/classes/main/cache/.htaccess -text inc/classes/main/cache/class_MemoryCache.php -text inc/classes/main/class_ -text +inc/classes/main/class_Base -text inc/classes/main/class_BaseFrameworkSystem.php -text inc/classes/main/class_FrameworkArrayObject.php -text inc/classes/main/commands/.htaccess -text @@ -449,6 +455,11 @@ inc/classes/main/filter/verifier/class_UserNameVerifierFilter.php -text inc/classes/main/filter/verifier/class_UserStatusVerifierFilter.php -text inc/classes/main/filter/verifier/class_UserUnconfirmedVerifierFilter.php -text inc/classes/main/helper/.htaccess -text +inc/classes/main/helper/captcha/.htaccess -text +inc/classes/main/helper/captcha/class_ -text +inc/classes/main/helper/captcha/class_BaseCaptcha.php -text +inc/classes/main/helper/captcha/web/.htaccess -text +inc/classes/main/helper/captcha/web/class_GraphicalCodeCaptcha.php -text inc/classes/main/helper/class_ -text inc/classes/main/helper/class_BaseHelper.php -text inc/classes/main/helper/login/.htaccess -text diff --git a/application/ship-simu/config.php b/application/ship-simu/config.php index 5fbe876..53071ac 100644 --- a/application/ship-simu/config.php +++ b/application/ship-simu/config.php @@ -163,8 +163,20 @@ $cfg->setConfigEntry('login_logout_action_class', "ShipSimuLogoutAction"); // CFG: LOGIN-PROFILE-ACTION-CLASS $cfg->setConfigEntry('login_profile_action_class', "ShipSimuProfileAction"); +// CFG: SHIPSIMU-REGISTER-CAPTCHA +$cfg->setConfigEntry('shipsimu_register_captcha', "GraphicalCodeCaptcha"); + // CFG: LOGOUT-IMMEDIATE $cfg->setConfigEntry('logout_immediate', "N"); +// CFG: CAPTCHA-STRING-LENGTH +$cfg->setConfigEntry('captcha_string_length', 5); + +// CFG: CAPTCHA-SEARCH-CHARS +$cfg->setConfigEntry('captcha_search_chars', "+/="); + +// CFG: RANDOM-STRING-LENGTH +$cfg->setConfigEntry('random_string_length', 100); + // [EOF] ?> diff --git a/application/ship-simu/exceptions.php b/application/ship-simu/exceptions.php index 3b021f6..b5b8bdc 100644 --- a/application/ship-simu/exceptions.php +++ b/application/ship-simu/exceptions.php @@ -33,7 +33,7 @@ function __exceptionHandler (FrameworkException $e) { $e->getMessage(), $e->getPrintableBackTrace() )); -} +} // END - function // Set the new handler set_exception_handler('__exceptionHandler'); @@ -50,10 +50,33 @@ function __errorHandler ($errno, $errstr, $errfile, $errline, array $errcontext) // Throw an exception here throw new FatalErrorException($message, BaseFrameworkSystem::EXCEPTION_FATAL_ERROR); -} +} // END - function // Set error handler set_error_handler('__errorHandler'); +// Assertion handler +function __assertHandler ($file, $line, $code) { + // Empty code? + if ($code === "") $code = "Unknown"; + + // Create message + $message = sprintf("File: %s, Line: %s, Code: %s", + basename($file), + $line, + $code + ); + + // Throw an exception here + throw new AssertionException($message, BaseFrameworkSystem::EXCEPTION_ASSERTION_FAILED); +} // END - function + +// Init assert handling +assert_options(ASSERT_ACTIVE, 1); +assert_options(ASSERT_WARNING, 0); +assert_options(ASSERT_BAIL, 0); +assert_options(ASSERT_QUIET_EVAL, 0); +assert_options(ASSERT_CALLBACK, '__assertHandler'); + // [EOF] ?> diff --git a/application/ship-simu/main/login/class_ShipSimuGuestLogin.php b/application/ship-simu/main/login/class_ShipSimuGuestLogin.php index 198f74c..4fe5915 100644 --- a/application/ship-simu/main/login/class_ShipSimuGuestLogin.php +++ b/application/ship-simu/main/login/class_ShipSimuGuestLogin.php @@ -160,7 +160,7 @@ class ShipSimuGuestLogin extends BaseFrameworkSystem implements LoginableUser { $userInstance = Registry::getRegistry()->getInstance('user'); // Get a crypto helper and hash the password - $this->hashedPassword = ObjectFactory::createObjectByConfiguredName('crypto_class')->hashPassword($plainPassword, $userInstance->getPasswordHash()); + $this->hashedPassword = ObjectFactory::createObjectByConfiguredName('crypto_class')->hashString($plainPassword, $userInstance->getPasswordHash()); // Store the hash back in the request $this->getRequestInstance()->setRequestElement('pass_hash', $this->hashedPassword); diff --git a/application/ship-simu/main/login/class_ShipSimuUserLogin.php b/application/ship-simu/main/login/class_ShipSimuUserLogin.php index 72471e5..47dd7d9 100644 --- a/application/ship-simu/main/login/class_ShipSimuUserLogin.php +++ b/application/ship-simu/main/login/class_ShipSimuUserLogin.php @@ -141,7 +141,7 @@ class ShipSimuUserLogin extends BaseFrameworkSystem implements LoginableUser { $userInstance = Registry::getRegistry()->getInstance('user'); // Get a crypto helper and hash the password - $this->hashedPassword = ObjectFactory::createObjectByConfiguredName('crypto_class')->hashPassword($plainPassword, $userInstance->getPasswordHash()); + $this->hashedPassword = ObjectFactory::createObjectByConfiguredName('crypto_class')->hashString($plainPassword, $userInstance->getPasswordHash()); // Store the hash back in the request $this->getRequestInstance()->setRequestElement('pass_hash', $this->hashedPassword); diff --git a/application/ship-simu/main/personell/class_SimulatorPersonell.php b/application/ship-simu/main/personell/class_SimulatorPersonell.php index 724980b..9cc0adb 100644 --- a/application/ship-simu/main/personell/class_SimulatorPersonell.php +++ b/application/ship-simu/main/personell/class_SimulatorPersonell.php @@ -344,10 +344,11 @@ class SimulatorPersonell extends BasePersonell { * Getter for surname. If no surname is set then default surnames are set * for male and female personells. * - * @return $surname The personell' surname + * @return $surname The personell' surname */ public final function getSurname () { $surname = parent::getSurname(); + // Make sure every one has a surname... if (empty($surname)) { if ($this->isMale()) { @@ -360,7 +361,9 @@ class SimulatorPersonell extends BasePersonell { // Set typical family name parent::setFamily("Smith"); - } + } // END - if + + // Return surname return $surname; } @@ -376,22 +379,22 @@ class SimulatorPersonell extends BasePersonell { /** * Loads the mostly pre-cached personell list * - * @param $idNumber The ID number we shall use for looking up + * @param $idNumber The ID number we shall use for looking up * the right data. * @return void * @throws ContainerItemIsNullException If a container item is null * @throws ContainerItemIsNoArrayException If a container item is - * not an array + * not an array * @throws ContainerMaybeDamagedException If the container item - * is missing the indexes - * 'name' and/or 'value' + * is missing the indexes + * 'name' and/or 'value' * @see SerializationContainer A special container class which - * helps storing only some attributes - * of a class. + * helps storing only some attributes + * of a class. */ public function loadPersonellList ($idNumber) { // Cleared because old code - $this->partialStub("Clear because of old lost code was usaged."); + $this->partialStub("Cleared because old lost code was used."); } } diff --git a/application/ship-simu/main/registration/class_ShipSimuRegistration.php b/application/ship-simu/main/registration/class_ShipSimuRegistration.php index 9dc9fb3..87a4429 100644 --- a/application/ship-simu/main/registration/class_ShipSimuRegistration.php +++ b/application/ship-simu/main/registration/class_ShipSimuRegistration.php @@ -90,10 +90,13 @@ class ShipSimuRegistration extends BaseRegistration { if ($this->getRequestInstance()->isRequestElementSet($requestKey)) { // So encrypt the password and store it for later usage in // the request: + // 1.: Get the plain password $plainPassword = $this->getRequestInstance()->getRequestElement($requestKey); + // 2. Get a crypto helper and hash the password - $this->hashedPassword = ObjectFactory::createObjectByConfiguredName('crypto_class')->hashPassword($plainPassword); + $this->hashedPassword = ObjectFactory::createObjectByConfiguredName('crypto_class')->hashString($plainPassword); + // 3. Store the hash back in the request $this->getRequestInstance()->setRequestElement('pass_hash', $this->hashedPassword); } diff --git a/application/ship-simu/templates/de/code/login_form.ctp b/application/ship-simu/templates/de/code/login_form.ctp index 8c94148..6d926e8 100644 --- a/application/ship-simu/templates/de/code/login_form.ctp +++ b/application/ship-simu/templates/de/code/login_form.ctp @@ -32,6 +32,7 @@ if ($helper->ifLoginIsEnabled()) { $helper->addInputPasswordField("pass"); $helper->addFormGroup("buttons", "Alles richtig eingegeben?"); $helper->addInputResetButton("Formular leeren"); + $helper->addCaptcha(); $helper->addInputSubmitButton("Zum Spiel einloggen"); } else { // Formular deaktiviert @@ -49,6 +50,7 @@ if ($helper->ifGuestLoginAllowed()) { $helper->addInputHiddenField("username", $this->getConfigInstance()->readConfig('guest_login_username')); $helper->addInputHiddenField("pass", $this->getConfigInstance()->readConfig('guest_login_password')); $helper->addFormGroup("buttons", "Gastlogins sind in der Funkionsweise eingeschränkt. Mehr dazu unter "Gastlogin"."); + $helper->addCaptcha(); $helper->addInputSubmitButton("Als Gast einloggen"); $helper->flushContent(); } diff --git a/application/ship-simu/templates/de/code/register_form.ctp b/application/ship-simu/templates/de/code/register_form.ctp index a2221fa..30ea9f1 100644 --- a/application/ship-simu/templates/de/code/register_form.ctp +++ b/application/ship-simu/templates/de/code/register_form.ctp @@ -94,6 +94,7 @@ $helper->addInputCheckboxField("rules", false); // Abschliessender Hinweis und Abschluss des Formulars $helper->addFormGroup("buttons", "Wenn du alle benötigten Felder korrekt ausgefüt hast, kannst du die Anmeldung abschliessen."); +$helper->addCaptcha(); $helper->addInputResetButton("Alles nochmal eingeben"); $helper->addInputSubmitButton("Anmeldung zum Spiel abschliessen"); $helper->addFormNote("Deine Daten werden nach den gültigen Datenschutzgesetzten gespeichert und werden nicht an Dritte weitergegeben. Weiteres dazu siehe Link "Datenschutz"."); diff --git a/inc/classes/exceptions/main/class_AssertionException.php b/inc/classes/exceptions/main/class_AssertionException.php new file mode 100644 index 0000000..b9403cd --- /dev/null +++ b/inc/classes/exceptions/main/class_AssertionException.php @@ -0,0 +1,39 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class AssertionException extends FrameworkException { + /** + * The constructor + * + * @param $message Message from the exception + * @param $code Code number for the exception + * @return void + */ + public function __construct ($message, $code) { + // Call parent constructor + parent::__construct($message, $code); + } +} + +// [EOF] +?> diff --git a/inc/classes/exceptions/main/class_FatalErrorException.php b/inc/classes/exceptions/main/class_FatalErrorException.php index b9bc217..320dae7 100644 --- a/inc/classes/exceptions/main/class_FatalErrorException.php +++ b/inc/classes/exceptions/main/class_FatalErrorException.php @@ -25,8 +25,8 @@ class FatalErrorException extends FrameworkException { /** * The constructor * - * @param $message Message from the exception - * @param $code Code number for the exception + * @param $message Message from the exception + * @param $code Code number for the exception * @return void */ public function __construct ($message, $code) { diff --git a/inc/classes/interfaces/captcha/.htaccess b/inc/classes/interfaces/captcha/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/inc/classes/interfaces/captcha/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/inc/classes/interfaces/captcha/class_SolveableCaptcha.php b/inc/classes/interfaces/captcha/class_SolveableCaptcha.php new file mode 100644 index 0000000..eddc5ea --- /dev/null +++ b/inc/classes/interfaces/captcha/class_SolveableCaptcha.php @@ -0,0 +1,41 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +interface SolveableCaptcha extends FrameworkInterface { + /** + * Initiates the CAPTCHA + * + * @return void + */ + function initiateCaptcha (); + + /** + * Render the CAPTCHA code + * + * @return void + */ + function renderCode (); +} + +// +?> diff --git a/inc/classes/interfaces/crypto/.htaccess b/inc/classes/interfaces/crypto/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/inc/classes/interfaces/crypto/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/inc/classes/interfaces/crypto/class_Cryptable.php b/inc/classes/interfaces/crypto/class_Cryptable.php new file mode 100644 index 0000000..8df0bbd --- /dev/null +++ b/inc/classes/interfaces/crypto/class_Cryptable.php @@ -0,0 +1,55 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +interface Cryptable extends FrameworkInterface { + /** + * Hashes a string with salt and returns the hash. If an old previous hash + * is supplied the method will use the first X chars of that hash for hashing + * the password. This is useful if you want to check if the password is + * identical for authorization purposes. + * + * @param $str Unhashed string + * @param $oldHash A hash from previous hashed string + * @return $hashed The hashed and salted string + */ + function hashString ($str, $oldHash = ""); + + /** + * Encrypt the string with fixed salt + * + * @param $str The unencrypted string + * @return $encrypted Encrypted string + */ + function encryptString ($str); + + /** + * Decrypt the string with fixed salt + * + * @param $encrypted Encrypted string + * @return $str The unencrypted string + */ + function decryptString ($encrypted); +} + +// [EOF] +?> diff --git a/inc/classes/main/class_Base b/inc/classes/main/class_Base new file mode 100644 index 0000000..755759c --- /dev/null +++ b/inc/classes/main/class_Base @@ -0,0 +1,42 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class Base??? extends BaseFrameworkSystem { + /** + * Protected constructor + * + * @param $className Name of the class + * @return void + */ + protected function __construct ($className) { + // Call parent constructor + parent::__construct($className); + + // Clean up a little + $this->removeNumberFormaters(); + $this->removeSystemArray(); + } +} + +// [EOF] +?> diff --git a/inc/classes/main/class_BaseFrameworkSystem.php b/inc/classes/main/class_BaseFrameworkSystem.php index ea3201f..3b0a939 100644 --- a/inc/classes/main/class_BaseFrameworkSystem.php +++ b/inc/classes/main/class_BaseFrameworkSystem.php @@ -146,6 +146,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface { const EXCEPTION_REQUIRED_INTERFACE_MISSING = 0x034; const EXCEPTION_FATAL_ERROR = 0x035; const EXCEPTION_FILE_NOT_FOUND = 0x036; + const EXCEPTION_ASSERTION_FAILED = 0x037; /** * In the super constructor these system classes shall be ignored or else @@ -272,7 +273,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface { } // Output stub message - $this->getDebugInstance()->output(sprintf("[%s::%s] Stub! Args: %s", + $this->getDebugInstance()->output(sprintf("[%s->%s] Stub! Args: %s", $this->__toString(), $methodName, $argsString @@ -961,9 +962,9 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface { $backtrace = debug_backtrace(); // Generate the class::method string - $methodName = "UnknownClass::unknownMethod"; + $methodName = "UnknownClass->unknownMethod"; if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) { - $methodName = $backtrace[1]['class']."::".$backtrace[1]['function']; + $methodName = $backtrace[1]['class']."->".$backtrace[1]['function']; } // Construct the full message diff --git a/inc/classes/main/commands/web/class_WebRegisterCommand.php b/inc/classes/main/commands/web/class_WebRegisterCommand.php index bc10daf..0ad939d 100644 --- a/inc/classes/main/commands/web/class_WebRegisterCommand.php +++ b/inc/classes/main/commands/web/class_WebRegisterCommand.php @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class WebRegisterCommand extends BaseCommand implements Commandable { +class WebRegisterCommand extends BaseCommand implements Commandable, Registerable { /** * Protected constructor * @@ -66,6 +66,9 @@ class WebRegisterCommand extends BaseCommand implements Commandable { * @return void */ public function execute (Requestable $requestInstance, Responseable $responseInstance) { + // Set request instance as extra instance + Registry::getRegistry()->addInstance('extra', $this); + // Get the application instance $appInstance = $this->getResolverInstance()->getApplicationInstance(); diff --git a/inc/classes/main/crypto/class_CryptoHelper.php b/inc/classes/main/crypto/class_CryptoHelper.php index 182d870..2765abd 100644 --- a/inc/classes/main/crypto/class_CryptoHelper.php +++ b/inc/classes/main/crypto/class_CryptoHelper.php @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class CryptoHelper extends BaseFrameworkSystem { +class CryptoHelper extends BaseFrameworkSystem implements Cryptable { /** * An instance of this own clas */ @@ -64,7 +64,7 @@ class CryptoHelper extends BaseFrameworkSystem { */ public final static function createCryptoHelper () { // Get a new instance - $cryptoInstance = self::getInstance(); + $cryptoInstance = new CryptoHelper(); // Initialize the hasher $cryptoInstance->initHasher(); @@ -82,7 +82,7 @@ class CryptoHelper extends BaseFrameworkSystem { // Is no instance there? if (is_null(self::$selfInstance)) { // Then get a new one - self::$selfInstance = new CryptoHelper(); + self::$selfInstance = self::createCryptoHelper(); } // Return the instance @@ -109,7 +109,7 @@ class CryptoHelper extends BaseFrameworkSystem { */ private function generateSalt () { // Get a random string from the RNG - $randomString = $this->rngInstance->makeRandomString(); + $randomString = $this->rngInstance->randomString(); // Get config entry for salt length $length = $this->getConfigInstance()->readConfig('salt_length'); @@ -119,16 +119,19 @@ class CryptoHelper extends BaseFrameworkSystem { } /** - * Hashes a password with salt and returns the hash. If an old previous hash + * Hashes a string with salt and returns the hash. If an old previous hash * is supplied the method will use the first X chars of that hash for hashing * the password. This is useful if you want to check if the password is * identical for authorization purposes. * - * @param $plainPassword The plain password to use - * @param $oldHash A previously hashed password - * @return $hashed The hashed and salted password + * @param $str Unhashed string + * @param $oldHash A hash from previous hashed string + * @return $hashed The hashed and salted string */ - public function hashPassword ($plainPassword, $oldHash = "") { + public function hashString ($str, $oldHash = "") { + // Cast the string + $str = (string) $str; + // Is the old password set? if (empty($oldHash)) { // No, then use the current salt @@ -142,16 +145,61 @@ class CryptoHelper extends BaseFrameworkSystem { } // Hash the password with salt - //* DEBUG: */ echo "salt=".$salt."/plain=".$plainPassword."
\n"; + //* DEBUG: */ echo "salt=".$salt."/plain=".$str."
\n"; $hashed = $salt . md5(sprintf($this->getConfigInstance()->readConfig('hash_mask'), $salt, $this->rngInstance->getFixedSalt(), - $plainPassword + $str )); // And return it return $hashed; } + + /** + * Encrypt the string with fixed salt + * + * @param $str The unencrypted string + * @return $encrypted Encrypted string + */ + public function encryptString ($str) { + // Init crypto module + $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); + + // Get key + $key = md5($this->rngInstance->getFixedSalt()); + + // Encrypt the string + $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $str, MCRYPT_MODE_ECB, $iv); + + // Return the string + return $encrypted; + } + + /** + * Decrypt the string with fixed salt + * + * @param $encrypted Encrypted string + * @return $str The unencrypted string + */ + public function decryptString ($encrypted) { + // Init crypto module + $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); + + // Get key + $key = md5($this->rngInstance->getFixedSalt()); + + // Encrypt the string + $str = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_ECB, $iv); + + // Trim trailing nulls away + $str = rtrim($str, "\0"); + + // Return the string + return $str; + } } // [EOF] diff --git a/inc/classes/main/filter/change/class_EmailChangeFilter.php b/inc/classes/main/filter/change/class_EmailChangeFilter.php index 7e1dd57..6748781 100644 --- a/inc/classes/main/filter/change/class_EmailChangeFilter.php +++ b/inc/classes/main/filter/change/class_EmailChangeFilter.php @@ -61,6 +61,7 @@ class EmailChangeFilter extends BaseFrameworkSystem implements Filterable { * @param $requestInstance An instance of a class with an Requestable interface * @param $responseInstance An instance of a class with an Responseable interface * @return void + * @todo Implement email change of the user here. HINT: Use the User class! */ public function execute (Requestable $requestInstance, Responseable $responseInstance) { // Get both emails diff --git a/inc/classes/main/filter/change/class_PasswordChangeFilter.php b/inc/classes/main/filter/change/class_PasswordChangeFilter.php index 9c306bf..940107d 100644 --- a/inc/classes/main/filter/change/class_PasswordChangeFilter.php +++ b/inc/classes/main/filter/change/class_PasswordChangeFilter.php @@ -61,6 +61,7 @@ class PasswordChangeFilter extends BaseFrameworkSystem implements Filterable { * @param $requestInstance An instance of a class with an Requestable interface * @param $responseInstance An instance of a class with an Responseable interface * @return void + * @todo Finished updating user password hash here. HINT: Use the User class again. */ public function execute (Requestable $requestInstance, Responseable $responseInstance) { // Get both passwords diff --git a/inc/classes/main/filter/verifier/class_AccountPasswordVerifierFilter.php b/inc/classes/main/filter/verifier/class_AccountPasswordVerifierFilter.php index 1525973..c85d948 100644 --- a/inc/classes/main/filter/verifier/class_AccountPasswordVerifierFilter.php +++ b/inc/classes/main/filter/verifier/class_AccountPasswordVerifierFilter.php @@ -92,7 +92,7 @@ class AccountPasswordVerifierFilter extends BaseFilter implements Filterable { $oldHash = $userInstance->getField('pass_hash'); // Get an encryption helper and encrypt the password - $passHash = ObjectFactory::createObjectByConfiguredName('crypto_class')->hashPassword($password, $oldHash); + $passHash = ObjectFactory::createObjectByConfiguredName('crypto_class')->hashString($password, $oldHash); // Does it match? if ($oldHash != $passHash) { diff --git a/inc/classes/main/helper/captcha/.htaccess b/inc/classes/main/helper/captcha/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/inc/classes/main/helper/captcha/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/inc/classes/main/helper/captcha/class_ b/inc/classes/main/helper/captcha/class_ new file mode 100644 index 0000000..17dcaf7 --- /dev/null +++ b/inc/classes/main/helper/captcha/class_ @@ -0,0 +1,82 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class ???Captcha extends BaseCaptcha implements SolveableCaptcha { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Set part description + $this->setObjectDescription("A solveable CAPTCHA"); + + // Create unique ID number + $this->generateUniqueId(); + } + + /** + * Creates an instance of this captcha class + * + * @param $templateInstance An instance of a template engine + * @param $extraInstance An extra instance, just for better hash data + * @return $captchaInstance An instance of this captcha class + */ + public final static function create???Captcha (CompileableTemplate $templateInstance, FrameworkInterface $extraInstance = null) { + // Get a new instance + $captchaInstance = new ???Captcha(); + + // Set template instance + $captchaInstance->setTemplateInstance($templateInstance); + + // Initialize the RNG + $captchaInstance->initializeRandomNumberGenerator($extraInstance); + + // Return the instance + return $captchaInstance; + } + + /** + * Initiates the CAPTCHA + * + * @return void + */ + public function initiateCaptcha () { + $this->partialStub("Please implement this method."); + } + + /** + * Render the CAPTCHA code + * + * @return void + */ + public function renderCode () { + $this->partialStub("Please implement this method."); + } +} + +// [EOF] +?> diff --git a/inc/classes/main/helper/captcha/class_BaseCaptcha.php b/inc/classes/main/helper/captcha/class_BaseCaptcha.php new file mode 100644 index 0000000..2da834e --- /dev/null +++ b/inc/classes/main/helper/captcha/class_BaseCaptcha.php @@ -0,0 +1,67 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class BaseCaptcha extends BaseHelper { + /** + * Instance of an RNG + */ + private $rngInstance = null; + + /** + * Protected constructor + * + * @param $className Name of the class + * @return void + */ + protected function __construct ($className) { + // Call parent constructor + parent::__construct($className); + + // Clean up a little + $this->removeNumberFormaters(); + $this->removeSystemArray(); + } + + /** + * Initializes the random number generator (RNG) + * + * @param $extraInstance An extra instance, just for better hash data + * @return void + */ + protected final function initializeRandomNumberGenerator (FrameworkInterface $extraInstance = null) { + // Get an RNG from factory + $this->rngInstance = ObjectFactory::createObjectByConfiguredName('rng_class', array($extraInstance)); + } + + /** + * Protected getter for RNG instance + * + * @return $rngInstance An instance of a random number generator (RNG) + */ + protected final function getRngInstance () { + return $this->rngInstance; + } +} + +// [EOF] +?> diff --git a/inc/classes/main/helper/captcha/web/.htaccess b/inc/classes/main/helper/captcha/web/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/inc/classes/main/helper/captcha/web/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/inc/classes/main/helper/captcha/web/class_GraphicalCodeCaptcha.php b/inc/classes/main/helper/captcha/web/class_GraphicalCodeCaptcha.php new file mode 100644 index 0000000..b3e3b55 --- /dev/null +++ b/inc/classes/main/helper/captcha/web/class_GraphicalCodeCaptcha.php @@ -0,0 +1,141 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class GraphicalCodeCaptcha extends BaseCaptcha implements SolveableCaptcha { + /** + * Hash of the CAPTCHA string + */ + private $hashedString = ""; + + /** + * Encrypted string + */ + private $encryptedString = ""; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Set part description + $this->setObjectDescription("A solveable graphical code CAPTCHA"); + + // Create unique ID number + $this->generateUniqueId(); + } + + /** + * Creates an instance of this captcha class + * + * @param $templateInstance An instance of a template engine + * @param $extraInstance An extra instance, just for better hash data + * @return $captchaInstance An instance of this captcha class + */ + public final static function createGraphicalCodeCaptcha (CompileableTemplate $templateInstance, FrameworkInterface $extraInstance = null) { + // Get a new instance + $captchaInstance = new GraphicalCodeCaptcha(); + + // Set template instance + $captchaInstance->setTemplateInstance($templateInstance); + + // Initialize the RNG + $captchaInstance->initializeRandomNumberGenerator($extraInstance); + + // Return the instance + return $captchaInstance; + } + + /** + * Initiates the CAPTCHA + * + * @return void + */ + public function initiateCaptcha () { + // Get total length + $captchaLength = $this->getConfigInstance()->readConfig('captcha_string_length'); + + // Get max string length + $strLength = $this->getConfigInstance()->readConfig('random_string_length'); + + // Calculate starting position based on random place + $start = $this->getRngInstance()->randomNumber(0, ($strLength - $captchaLength)); + + // Test it + assert($start >= 0); + + // Generate a random string for confirmation + $randomString = $this->getRngInstance()->randomString($strLength); + + // Encode the string with BASE64 + $base64String = base64_encode($randomString); + + // Make this string a bit more readable for humans + $captchaString = substr($base64String, $start, $captchaLength); + + // Get all characters we want to replace + $searchChars = $this->getConfigInstance()->readConfig('captcha_search_chars'); + + // Get fixed salt and use it as "replacement characters" + $replaceChars = $this->getRngInstance()->getFixedSalt(); + + // Remove any plus, equals or slashes + for ($searchIdx = 0; $searchIdx < strlen($searchChars); $searchIdx++) { + // Get search character + $search = substr($searchChars, $searchIdx, 1); + + // Random array index + $charIdx = $this->getRngInstance()->randomNumber(0, (strlen($replaceChars) - 1)); + + // Get replacement + $replace = substr($replaceChars, $charIdx, 1); + + // Replace character + $captchaString = str_replace($search, $replace, $captchaString, $captchaLength); + } // END - foreach + + // Get crypto instance + $cryptoInstance = ObjectFactory::createObjectByConfiguredName('crypto_class'); + + // Encrypt the string for later usage + $this->encryptedString = $cryptoInstance->encryptString($captchaString); + + // Hash the encrypted string for later comparison + $this->hashedString = $cryptoInstance->hashString($this->encryptedString); + } + + /** + * Render the CAPTCHA code + * + * @return void + */ + public function renderCode () { + $this->partialStub("Please implement this method."); + } +} + +// [EOF] +?> diff --git a/inc/classes/main/helper/web/class_WebFormHelper.php b/inc/classes/main/helper/web/class_WebFormHelper.php index 32d635a..7ba0343 100644 --- a/inc/classes/main/helper/web/class_WebFormHelper.php +++ b/inc/classes/main/helper/web/class_WebFormHelper.php @@ -218,7 +218,7 @@ class WebFormHelper extends BaseHelper { */ public function addInputTextFieldWithDefault ($fieldName) { // Get the value from instance - $fieldValue = call_user_func_array(array($this->valueInstance, "getField"), array($fieldName)); + $fieldValue = $this->getField($fieldName); //* DEBUG: */ echo __METHOD__.":".$fieldName."=".$fieldValue."
\n"; // Add the text field @@ -286,7 +286,7 @@ class WebFormHelper extends BaseHelper { */ public function addInputHiddenFieldWithDefault ($fieldName) { // Get the value from instance - $fieldValue = call_user_func_array(array($this->valueInstance, "getField"), array($fieldName)); + $fieldValue = $this->getField($fieldName); //* DEBUG: */ echo __METHOD__.":".$fieldName."=".$fieldValue."
\n"; // Add the text field @@ -746,11 +746,33 @@ class WebFormHelper extends BaseHelper { */ public function getField ($fieldName) { // Get the field value - $fieldValue = call_user_func_array(array($this->valueInstance, "getField"), array($fieldName)); + $fieldValue = call_user_func_array(array($this->valueInstance, 'getField'), array($fieldName)); // Return it return $fieldValue; } + + /** + * Adds a pre-configured CAPTCHA + * + * @return void + */ + public function addCaptcha () { + // Get last executed pre filter + $extraInstance = Registry::getRegistry()->getInstance('extra'); + + // Get a configured instance + $captchaInstance = ObjectFactory::createObjectByConfiguredName("{$this->formName}_captcha", array($this->getTemplateInstance(), $extraInstance)); + + // Initiate the CAPTCHA + $captchaInstance->initiateCaptcha(); + + // Render the CAPTCHA code + $captchaInstance->renderCode(); + + // Get the content and add it to the helper + $this->addContent($captchaInstance->getContent()); + } } // [EOF] diff --git a/inc/classes/main/rng/class_RandomNumberGenerator.php b/inc/classes/main/rng/class_RandomNumberGenerator.php index 9177393..1e702c9 100644 --- a/inc/classes/main/rng/class_RandomNumberGenerator.php +++ b/inc/classes/main/rng/class_RandomNumberGenerator.php @@ -71,14 +71,15 @@ class RandomNumberGenerator extends BaseFrameworkSystem { /** * Creates an instance of this class * + * @param $extraInstance An extra instance for more salt (default: null) * @return $rngInstance An instance of this random number generator */ - public final static function createRandomNumberGenerator () { + public final static function createRandomNumberGenerator (FrameworkInterface $extraInstance = null) { // Get a new instance $rngInstance = new RandomNumberGenerator(); // Initialize the RNG now - $rngInstance->initRng(); + $rngInstance->initRng($extraInstance); // Return the instance return $rngInstance; @@ -87,13 +88,11 @@ class RandomNumberGenerator extends BaseFrameworkSystem { /** * Initializes the random number generator * + * @param $extraInstance An extra instance for more salt (default: null) * @return void * @todo Add site key for stronger salt! */ - protected function initRng () { - // Seed mt_rand() - mt_srand((double) microtime() * 1000000); - + protected function initRng ($extraInstance) { // Get the prime number from config $this->prime = $this->getConfigInstance()->readConfig('math_prime'); @@ -101,6 +100,9 @@ class RandomNumberGenerator extends BaseFrameworkSystem { // a better prime number $this->extraNumber = ($this->prime * $this->prime / (pi() ^ 2)); + // Seed mt_rand() + mt_srand((double) sqrt(microtime() * 100000000 * $this->extraNumber)); + // Set the server IP to cluster $serverIp = "cluster"; @@ -111,7 +113,13 @@ class RandomNumberGenerator extends BaseFrameworkSystem { } // END - if // Yet-another fixed salt. This is not dependend on server software or date - $this->fixedSalt = sha1($serverIp . ":" . serialize($this->getDatabaseInstance()->getConnectionData())); + if ($extraInstance instanceof FrameworkInterface) { + // With extra instance information + $this->fixedSalt = sha1($serverIp . ":" . $extraInstance->__toString() . ":" . serialize($this->getDatabaseInstance()->getConnectionData()) . ":" . $extraInstance->getObjectDescription()); + } else { + // Without extra information + $this->fixedSalt = sha1($serverIp . ":" . serialize($this->getDatabaseInstance()->getConnectionData())); + } // One-way data we need for "extra-salting" the random number $this->extraSalt = sha1($this->fixedSalt . ":" . getenv('SERVER_SOFTWARE') . ":" . $this->getConfigInstance()->readConfig('date_key')); @@ -126,7 +134,7 @@ class RandomNumberGenerator extends BaseFrameworkSystem { * @param $length Length of the string, default: 128 * @return $randomString The pseudo-random string */ - public function makeRandomString ($length = -1) { + public function randomString ($length = -1) { // Is the number <1, then fix it to default length if ($length < 1) $length = $this->rndStrLen; @@ -136,7 +144,7 @@ class RandomNumberGenerator extends BaseFrameworkSystem { // And generate it for ($idx = 0; $idx < $length; $idx++) { // Add a random character and add it to our string - $randomString .= chr($this->randomNumnber(0, 255)); + $randomString .= chr($this->randomNumber(0, 255)); } // Return the random string a little mixed up @@ -151,7 +159,7 @@ class RandomNumberGenerator extends BaseFrameworkSystem { * @return $num Pseudo-random number * @todo I had a better random number generator here but now it is somewhere lost :( */ - public function randomNumnber ($min, $max) { + public function randomNumber ($min, $max) { return mt_rand($min, $max); } diff --git a/inc/classes/main/user/class_Guest.php b/inc/classes/main/user/class_Guest.php index aa8878e..ffe6772 100644 --- a/inc/classes/main/user/class_Guest.php +++ b/inc/classes/main/user/class_Guest.php @@ -300,6 +300,7 @@ class Guest extends BaseFrameworkSystem implements ManageableGuest, Registerable * @param $column Column we want to update * @param $value New value to store in database * @return void + * @todo 0% done */ public function addUpdateData ($column, $value) { $this->partialStub("Column={$column}, value={$value}"); diff --git a/inc/classes/main/user/class_User.php b/inc/classes/main/user/class_User.php index d82f5ab..62b0d55 100644 --- a/inc/classes/main/user/class_User.php +++ b/inc/classes/main/user/class_User.php @@ -127,7 +127,7 @@ class User extends BaseFrameworkSystem implements ManageableUser, Registerable { } else { // Unsupported mode $userInstance = new User(); - $userInstance->partialStub("We need to add more ways of creating user accounts here."); + $userInstance->partialStub("We need to add more ways of creating user classes here."); $userInstance->debugBackTrace(); exit(); } @@ -326,6 +326,7 @@ class User extends BaseFrameworkSystem implements ManageableUser, Registerable { * @param $column Column we want to update * @param $value New value to store in database * @return void + * @todo 0% done */ public function addUpdateData ($column, $value) { $this->partialStub("Column={$column}, value={$value}"); diff --git a/inc/config/class_FrameworkConfiguration.php b/inc/config/class_FrameworkConfiguration.php index 50a4ac1..493af36 100644 --- a/inc/config/class_FrameworkConfiguration.php +++ b/inc/config/class_FrameworkConfiguration.php @@ -44,6 +44,8 @@ class FrameworkConfiguration implements Registerable { /** * Protected constructor + * + * @return void */ protected function __construct () { // Empty for now @@ -51,6 +53,9 @@ class FrameworkConfiguration implements Registerable { /** * "Create" a configuration instance + * + * @param $enableDebug Wether enable debug mode (default: off) + * @return $cfgInstance An instance of this configuration class */ public final static function createFrameworkConfiguration ($enableDebug = false) { /** @@ -58,7 +63,7 @@ class FrameworkConfiguration implements Registerable { * through the initial configuration. */ if (is_null(self::$cfgInstance)) { - // CFG: DEBUG-LEVEL + // CFG: ERROR-REPORTING @error_reporting(E_ALL | E_STRICT); /** -- 2.39.5