| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- <?php
- App::uses('ModelBehavior', 'Model');
- /**
- * MasterPassword Behavior for admin views
- *
- * Uses
- * - Tools.Hash Shell to hash password
- * - master_password element of Tools plugin for Form input
- *
- * Usage:
- * In the controller:
- * $this->ModelName->Behaviors->load('Tools.MasterPassword');
- * In the view:
- * echo $this->element('master_password', array(), array('plugin'=>'tools'));
- * Put this into your private configs:
- * Configure::write('MasterPassword.password', 'your_hashed_pwd_string');
- * You can also use an array to store multiple passwords
- *
- * Note:
- * sha1 is the default hashing algorithm
- *
- * Use Configure::write('MasterPassword.password', false) to deactivate
- *
- * Copyright 2011, dereuromark (http://www.dereuromark.de)
- *
- * @author Mark Scherer
- * @link http://github.com/dereuromark/
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
- /**
- * 2011-12-22 ms
- */
- class MasterPasswordBehavior extends ModelBehavior {
- protected $_defaults = array(
- 'message' => 'Incorrect Master Password',
- 'field' => 'master_pwd',
- 'model' => null,
- 'before' => 'validate',
- 'hash' => 'sha1',
- 'salt' => false, //TODO: maybe allow to use core salt for additional security?
- 'log' => false //TODO: log the usage of pwds to a log file `master_password`
- );
- public function setup(Model $Model, $settings = array()) {
- if (!isset($this->settings[$Model->alias])) {
- $this->settings[$Model->alias] = $this->_defaults;
- }
- $this->settings[$Model->alias] = array_merge($this->settings[$Model->alias], is_array($settings) ? $settings : array());
- # deactivate dynamically
- if (Configure::read('MasterPassword.password') === false) {
- $this->settings[$Model->alias]['before'] = '';
- }
- }
- public function beforeValidate(Model $Model) {
- $return = parent::beforeValidate($Model);
- if ($this->settings[$Model->alias]['before'] == 'validate') {
- # we dont want to return the value, because other fields might then not be validated
- # (save will not continue with errors, anyway)
- $this->confirm($Model, $return);
- }
- return $return;
- }
- public function beforeSave(Model $Model) {
- $return = parent::beforeSave($Model);
- if ($this->settings[$Model->alias]['before'] == 'save') {
- return $this->confirm($Model, $return);
- }
- return $return;
- }
- /**
- * Run before a model is saved, used...
- *
- * @param object $Model Model about to be saved.
- * @return boolean true if save should proceed, false otherwise
- * @access public
- */
- public function confirm(Model $Model, $return = true) {
- $field = $this->settings[$Model->alias]['field'];
- $message = $this->settings[$Model->alias]['message'];
- if (!$this->isAuthorized($Model, $field)) {
- $Model->invalidate($field, $message);
- return false;
- }
- return $return;
- }
- /**
- * checks a string against the stored hash values of master passwords
- * @param string $pwd: plain password string (not hashed etc)
- * @return bool $success
- * 2011-12-22 ms
- */
- public function isAuthorized(Model $Model, $field) {
- if (empty($Model->data[$Model->alias][$field])) {
- return false;
- }
- $masterPwds = (array)Configure::read('MasterPassword.password');
- $pwd = $this->_hash($Model->data[$Model->alias][$field], $this->settings[$Model->alias]['hash'], $this->settings[$Model->alias]['salt']);
- foreach ($masterPwds as $masterPwd) {
- if ($masterPwd === $pwd) {
- return true;
- }
- }
- return false;
- }
- /**
- * @retur string $hash or FALSE on failure
- */
- protected function _hash($string, $algorithm, $salt) {
- if ($salt) {
- if (is_string($salt)) {
- $string = $salt . $string;
- } else {
- $string = Configure::read('Security.salt') . $string;
- }
- }
- if ($algorithm == 'sha1') {
- return sha1($string);
- }
- if ($algorithm == 'md5') {
- return md5($string);
- }
- # mcrypt installed?
- if (function_exists('hash') && in_array($algorithm, hash_algos())) {
- return hash($algorithm, $string);
- }
- trigger_error('Hash method not available');
- return false;
- }
- }
|