[TASK] Encrypt password transmission in user setup
authorHelmut Hummel <helmut.hummel@typo3.org>
Mon, 22 Aug 2011 06:36:56 +0000 (08:36 +0200)
committerHelmut Hummel <typo3@helmut-hummel.de>
Wed, 7 Sep 2011 20:07:30 +0000 (22:07 +0200)
If extension rsaauth is enabled, the password transmission
when saving the user settings form should be encrypted.

Resolves: #29143
Releases: 4.6

Change-Id: Icdbc63306289387690a5a71b96eb481c9515d233
Reviewed-on: http://review.typo3.org/4462
Reviewed-by: Georg Ringer
Tested-by: Georg Ringer
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
typo3/sysext/rsaauth/ext_localconf.php
typo3/sysext/rsaauth/hooks/class.tx_rsaauth_usersetuphook.php [new file with mode: 0644]
typo3/sysext/rsaauth/resources/rsaauth.js
typo3/sysext/rsaauth/resources/rsaauth_min.js
typo3/sysext/setup/mod/index.php

index f3ea7fe..f3168f7 100644 (file)
@@ -27,6 +27,10 @@ t3lib_extMgm::addService($_EXTKEY,  'auth' /* sv type */,  'tx_rsaauth_sv1' /* s
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/index.php']['loginFormHook'][$_EXTKEY] = 'EXT:' . $_EXTKEY . '/hooks/class.tx_rsaauth_loginformhook.php:tx_rsaauth_loginformhook->getLoginFormTag';
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/index.php']['loginScriptHook'][$_EXTKEY] = 'EXT:' . $_EXTKEY . '/hooks/class.tx_rsaauth_loginformhook.php:tx_rsaauth_loginformhook->getLoginScripts';
 
+// Add hook for user setup module
+$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['setupScriptHook'][$_EXTKEY] = 'EXT:' . $_EXTKEY . '/hooks/class.tx_rsaauth_usersetuphook.php:tx_rsaauth_usersetuphook->getLoginScripts';
+$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['modifyUserDataBeforeSave'][$_EXTKEY] = 'EXT:' . $_EXTKEY . '/hooks/class.tx_rsaauth_usersetuphook.php:tx_rsaauth_usersetuphook->decryptPassword';
+
 // Add a hook to the FE login form (felogin system extension)
 $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['loginFormOnSubmitFuncs'][$_EXTKEY] = 'EXT:' . $_EXTKEY . '/hooks/class.tx_rsaauth_feloginhook.php:tx_rsaauth_feloginhook->loginFormHook';
 
diff --git a/typo3/sysext/rsaauth/hooks/class.tx_rsaauth_usersetuphook.php b/typo3/sysext/rsaauth/hooks/class.tx_rsaauth_usersetuphook.php
new file mode 100644 (file)
index 0000000..abf205c
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2011 Helmut Hummel <helmut.hummel@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project 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 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script 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.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+
+/**
+ * This class provides a hook to the login form to add extra javascript code
+ * and supply a proper form tag.
+ *
+ * @author     Helmut Hummel <helmut.hummel@typo3.org>
+ * @package    TYPO3
+ * @subpackage tx_rsaauth
+ */
+class tx_rsaauth_usersetuphook {
+
+       /**
+        * Decrypt the password fields if they are filled.
+        *
+        * @param array $parameters Parameters to the script
+        * @return void
+        */
+       public function decryptPassword(array $parameters) {
+
+               if ($this->isRsaAvailable()) {
+                       $be_user_data = &$parameters['be_user_data'];
+
+                       if (substr($be_user_data['password'], 0, 4) === 'rsa:' && substr($be_user_data['password2'], 0, 4) === 'rsa:') {
+                               $backend = tx_rsaauth_backendfactory::getBackend();
+                               $storage = tx_rsaauth_storagefactory::getStorage();
+                               /* @var $storage tx_rsaauth_abstract_storage */
+
+                               $key = $storage->get();
+
+                               $password = $backend->decrypt($key, substr($be_user_data['password'], 4));
+                               $password2 = $backend->decrypt($key, substr($be_user_data['password2'], 4));
+
+                               $be_user_data['password'] = $password ? $password : $be_user_data['password'];
+                               $be_user_data['password2'] = $password2 ? $password2 : $be_user_data['password2'];
+                       }
+               }
+       }
+
+
+       /**
+        * Provides form code and javascript for the user setup.
+        *
+        * @param array $parameters Parameters to the script
+        * @param SC_index $userSetupObject Calling object: user setup module
+        * @return string The code for the user setup
+        */
+       public function getLoginScripts(array $parameters, SC_mod_user_setup_index $userSetupObject) {
+               $content = '';
+               if ($this->isRsaAvailable()) {
+                               // If we can get the backend, we can proceed
+                       $backend = tx_rsaauth_backendfactory::getBackend();
+
+                       $javascriptPath = t3lib_extMgm::siteRelPath('rsaauth') . 'resources/';
+                       $files = array(
+                               'jsbn/jsbn.js',
+                               'jsbn/prng4.js',
+                               'jsbn/rng.js',
+                               'jsbn/rsa.js',
+                               'jsbn/base64.js',
+                               'rsaauth_min.js'
+                       );
+
+                       $content = '';
+                       foreach ($files as $file) {
+                               $content .= '<script type="text/javascript" src="' .
+                                       t3lib_div::getIndpEnv('TYPO3_SITE_URL') .
+                                       $javascriptPath . $file . '"></script>';
+                       }
+                       // Generate a new key pair
+                       $keyPair = $backend->createNewKeyPair();
+
+                       // Save private key
+                       $storage = tx_rsaauth_storagefactory::getStorage();
+                       /* @var $storage tx_rsaauth_abstract_storage */
+                       $storage->put($keyPair->getPrivateKey());
+
+                       // Add form tag
+                       $form = '<form action="index.php" method="post" name="usersetup" enctype="application/x-www-form-urlencoded" onsubmit="tx_rsaauth_encryptUserSetup();">';
+                       // Add RSA hidden fields
+                       $form .= '<input type="hidden" id="rsa_n" name="n" value="' . htmlspecialchars($keyPair->getPublicKeyModulus()) . '" />';
+                       $form .= '<input type="hidden" id="rsa_e" name="e" value="' . sprintf('%x', $keyPair->getExponent()) . '" />';
+
+                       $userSetupObject->doc->form = $form;
+               }
+               return $content;
+       }
+
+       /**
+        * Rsa is available if security_level is set and rsa backend is working.
+        *
+        * @return bool
+        */
+       protected function isRsaAvailable() {
+               return ($GLOBALS['BE_USER']->security_level === 'rsa') && (tx_rsaauth_backendfactory::getBackend() !== NULL);
+       }
+
+
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rsaauth/hooks/class.tx_rsaauth_loginformhook.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rsaauth/hooks/class.tx_rsaauth_loginformhook.php']);
+}
+
+?>
\ No newline at end of file
index 5601688..86d2103 100644 (file)
@@ -35,3 +35,21 @@ function tx_rsaauth_feencrypt(form) {
                form.pass.value = 'rsa:' + hex2b64(res);
        }
 }
+
+function tx_rsaauth_encryptUserSetup() {
+
+       var rsa = new RSAKey();
+       rsa.setPublic(document.usersetup.n.value, document.usersetup.e.value);
+
+       var password = document.getElementById('field_password').value;
+       var password2 = document.getElementById('field_password2').value;
+
+       if (password || password2) {
+               var res = rsa.encrypt(password);
+               var res2 = rsa.encrypt(password2);
+               if (res && res2) {
+                       document.getElementById('field_password').value = 'rsa:' + hex2b64(res);
+                       document.getElementById('field_password2').value = 'rsa:' + hex2b64(res2);
+               }
+       }       return false;
+}
\ No newline at end of file
index 8f20fb5..086beb0 100644 (file)
@@ -1,2 +1,3 @@
 function tx_rsaauth_encrypt(){var rsa=new RSAKey();rsa.setPublic(document.loginform.n.value,document.loginform.e.value);var username=document.loginform.username.value;var password=document.loginform.p_field.value;var res=rsa.encrypt(password);document.loginform.p_field.value="";document.loginform.e.value="";document.loginform.n.value="";if(res){document.loginform.userident.value='rsa:'+hex2b64(res);}}
-function tx_rsaauth_feencrypt(form){var rsa=new RSAKey();rsa.setPublic(form.n.value,form.e.value);var username=form.user.value;var password=form.pass.value;var res=rsa.encrypt(password);form.pass.value="";form.e.value="";form.n.value="";if(res){form.pass.value='rsa:'+hex2b64(res);}}
\ No newline at end of file
+function tx_rsaauth_feencrypt(form){var rsa=new RSAKey();rsa.setPublic(form.n.value,form.e.value);var username=form.user.value;var password=form.pass.value;var res=rsa.encrypt(password);form.pass.value="";form.e.value="";form.n.value="";if(res){form.pass.value='rsa:'+hex2b64(res);}}
+function tx_rsaauth_encryptUserSetup() {var rsa = new RSAKey();rsa.setPublic(document.usersetup.n.value, document.usersetup.e.value);var password = document.getElementById('field_password').value;var password2 = document.getElementById('field_password2').value;if (password || password2) {var res = rsa.encrypt(password);var res2 = rsa.encrypt(password2);if (res && res2) {document.getElementById('field_password').value = 'rsa:' + hex2b64(res);document.getElementById('field_password2').value = 'rsa:' + hex2b64(res2);}}      return false;}
\ No newline at end of file
index 0af69c2..d5835ec 100755 (executable)
@@ -135,7 +135,7 @@ class SC_mod_user_setup_index {
         */
        public function storeIncomingData() {
 
-                       // First check if something is submittet in the data-array from POST vars
+                       // First check if something is submitted in the data-array from POST vars
                $d = t3lib_div::_POST('data');
                $columns = $GLOBALS['TYPO3_USER_SETTINGS']['columns'];
                $beUserId = $GLOBALS['BE_USER']->user['uid'];
@@ -199,6 +199,14 @@ class SC_mod_user_setup_index {
                                        // If email and name is changed, set it in the users record:
                                $be_user_data = $d['be_users'];
 
+                                       // Possibility to modify the transmitted values. Useful to do transformations, like RSA password decryption
+                               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['modifyUserDataBeforeSave'])) {
+                                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['modifyUserDataBeforeSave'] as $function) {
+                                               $params = array('be_user_data' => &$be_user_data);
+                                               t3lib_div::callUserFunction($function, $params, $this);
+                                       }
+                               }
+
                                $this->passwordIsSubmitted = (strlen($be_user_data['password']) > 0);
                                $passwordIsConfirmed = ($this->passwordIsSubmitted && $be_user_data['password'] === $be_user_data['password2']);
 
@@ -252,16 +260,6 @@ class SC_mod_user_setup_index {
        }
 
 
-
-
-
-
-
-
-
-
-
-
        /******************************
         *
         * Rendering module
@@ -308,6 +306,24 @@ class SC_mod_user_setup_index {
                );
                $this->doc->table_TR = '<tr>';
                $this->doc->table_TABLE = '<table border="0" cellspacing="1" cellpadding="2" class="typo3-usersettings">';
+               $this->doc->JScode .= $this->getJavaScript();
+       }
+
+       /**
+        * Generate necessary JavaScript
+        *
+        * @return string
+        */
+       protected function getJavaScript() {
+               $javaScript = '';
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['setupScriptHook'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['setupScriptHook'] as $function) {
+                               $params = array();
+                               $javaScript .= t3lib_div::callUserFunction($function, $params, $this);
+                       }
+               }
+
+               return $javaScript;
        }
 
        /**