web/lib/Zend/Form/Element/Hash.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Form
       
    17  * @subpackage Element
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  */
       
    21 
       
    22 /** Zend_Form_Element_Xhtml */
       
    23 require_once 'Zend/Form/Element/Xhtml.php';
       
    24 
       
    25 /**
       
    26  * CSRF form protection
       
    27  *
       
    28  * @category   Zend
       
    29  * @package    Zend_Form
       
    30  * @subpackage Element
       
    31  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    32  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    33  * @version    $Id: Hash.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    34  */
       
    35 class Zend_Form_Element_Hash extends Zend_Form_Element_Xhtml
       
    36 {
       
    37     /**
       
    38      * Use formHidden view helper by default
       
    39      * @var string
       
    40      */
       
    41     public $helper = 'formHidden';
       
    42 
       
    43     /**
       
    44      * Actual hash used.
       
    45      *
       
    46      * @var mixed
       
    47      */
       
    48     protected $_hash;
       
    49 
       
    50     /**
       
    51      * Salt for CSRF token
       
    52      * @var string
       
    53      */
       
    54     protected $_salt = 'salt';
       
    55 
       
    56     /**
       
    57      * @var Zend_Session_Namespace
       
    58      */
       
    59     protected $_session;
       
    60 
       
    61     /**
       
    62      * TTL for CSRF token
       
    63      * @var int
       
    64      */
       
    65     protected $_timeout = 300;
       
    66 
       
    67     /**
       
    68      * Constructor
       
    69      *
       
    70      * Creates session namespace for CSRF token, and adds validator for CSRF
       
    71      * token.
       
    72      *
       
    73      * @param  string|array|Zend_Config $spec
       
    74      * @param  array|Zend_Config $options
       
    75      * @return void
       
    76      */
       
    77     public function __construct($spec, $options = null)
       
    78     {
       
    79         parent::__construct($spec, $options);
       
    80 
       
    81         $this->setAllowEmpty(false)
       
    82              ->setRequired(true)
       
    83              ->initCsrfValidator();
       
    84     }
       
    85 
       
    86     /**
       
    87      * Set session object
       
    88      *
       
    89      * @param  Zend_Session_Namespace $session
       
    90      * @return Zend_Form_Element_Hash
       
    91      */
       
    92     public function setSession($session)
       
    93     {
       
    94         $this->_session = $session;
       
    95         return $this;
       
    96     }
       
    97 
       
    98     /**
       
    99      * Get session object
       
   100      *
       
   101      * Instantiate session object if none currently exists
       
   102      *
       
   103      * @return Zend_Session_Namespace
       
   104      */
       
   105     public function getSession()
       
   106     {
       
   107         if (null === $this->_session) {
       
   108             require_once 'Zend/Session/Namespace.php';
       
   109             $this->_session = new Zend_Session_Namespace($this->getSessionName());
       
   110         }
       
   111         return $this->_session;
       
   112     }
       
   113 
       
   114     /**
       
   115      * Initialize CSRF validator
       
   116      *
       
   117      * Creates Session namespace, and initializes CSRF token in session.
       
   118      * Additionally, adds validator for validating CSRF token.
       
   119      *
       
   120      * @return Zend_Form_Element_Hash
       
   121      */
       
   122     public function initCsrfValidator()
       
   123     {
       
   124         $session = $this->getSession();
       
   125         if (isset($session->hash)) {
       
   126             $rightHash = $session->hash;
       
   127         } else {
       
   128             $rightHash = null;
       
   129         }
       
   130 
       
   131         $this->addValidator('Identical', true, array($rightHash));
       
   132         return $this;
       
   133     }
       
   134 
       
   135     /**
       
   136      * Salt for CSRF token
       
   137      *
       
   138      * @param  string $salt
       
   139      * @return Zend_Form_Element_Hash
       
   140      */
       
   141     public function setSalt($salt)
       
   142     {
       
   143         $this->_salt = (string) $salt;
       
   144         return $this;
       
   145     }
       
   146 
       
   147     /**
       
   148      * Retrieve salt for CSRF token
       
   149      *
       
   150      * @return string
       
   151      */
       
   152     public function getSalt()
       
   153     {
       
   154         return $this->_salt;
       
   155     }
       
   156 
       
   157     /**
       
   158      * Retrieve CSRF token
       
   159      *
       
   160      * If no CSRF token currently exists, generates one.
       
   161      *
       
   162      * @return string
       
   163      */
       
   164     public function getHash()
       
   165     {
       
   166         if (null === $this->_hash) {
       
   167             $this->_generateHash();
       
   168         }
       
   169         return $this->_hash;
       
   170     }
       
   171 
       
   172     /**
       
   173      * Get session namespace for CSRF token
       
   174      *
       
   175      * Generates a session namespace based on salt, element name, and class.
       
   176      *
       
   177      * @return string
       
   178      */
       
   179     public function getSessionName()
       
   180     {
       
   181         return __CLASS__ . '_' . $this->getSalt() . '_' . $this->getName();
       
   182     }
       
   183 
       
   184     /**
       
   185      * Set timeout for CSRF session token
       
   186      *
       
   187      * @param  int $ttl
       
   188      * @return Zend_Form_Element_Hash
       
   189      */
       
   190     public function setTimeout($ttl)
       
   191     {
       
   192         $this->_timeout = (int) $ttl;
       
   193         return $this;
       
   194     }
       
   195 
       
   196     /**
       
   197      * Get CSRF session token timeout
       
   198      *
       
   199      * @return int
       
   200      */
       
   201     public function getTimeout()
       
   202     {
       
   203         return $this->_timeout;
       
   204     }
       
   205 
       
   206     /**
       
   207      * Override getLabel() to always be empty
       
   208      *
       
   209      * @return null
       
   210      */
       
   211     public function getLabel()
       
   212     {
       
   213         return null;
       
   214     }
       
   215 
       
   216     /**
       
   217      * Initialize CSRF token in session
       
   218      *
       
   219      * @return void
       
   220      */
       
   221     public function initCsrfToken()
       
   222     {
       
   223         $session = $this->getSession();
       
   224         $session->setExpirationHops(1, null, true);
       
   225         $session->setExpirationSeconds($this->getTimeout());
       
   226         $session->hash = $this->getHash();
       
   227     }
       
   228 
       
   229     /**
       
   230      * Render CSRF token in form
       
   231      *
       
   232      * @param  Zend_View_Interface $view
       
   233      * @return string
       
   234      */
       
   235     public function render(Zend_View_Interface $view = null)
       
   236     {
       
   237         $this->initCsrfToken();
       
   238         return parent::render($view);
       
   239     }
       
   240 
       
   241     /**
       
   242      * Generate CSRF token
       
   243      *
       
   244      * Generates CSRF token and stores both in {@link $_hash} and element
       
   245      * value.
       
   246      *
       
   247      * @return void
       
   248      */
       
   249     protected function _generateHash()
       
   250     {
       
   251         $this->_hash = md5(
       
   252             mt_rand(1,1000000)
       
   253             .  $this->getSalt()
       
   254             .  $this->getName()
       
   255             .  mt_rand(1,1000000)
       
   256         );
       
   257         $this->setValue($this->_hash);
       
   258     }
       
   259 }