prevent CSRF for setup and admin site configuration

This commit is contained in:
Ralf Becker 2014-05-01 06:41:27 +00:00
commit 98d22299c9
14 changed files with 755 additions and 4 deletions

View File

@ -18,6 +18,11 @@
function index()
{
// for POST requests validate CSRF token (or terminate request)
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
egw_csrf::validate($_POST['csrf_token'], __CLASS__);
}
if ($GLOBALS['egw']->acl->check('site_config_access',1,'admin'))
{
$GLOBALS['egw']->redirect_link('/index.php');
@ -179,7 +184,9 @@
$t->set_var('th_text', $GLOBALS['egw_info']['theme']['th_text']);
$t->set_var('row_on', $GLOBALS['egw_info']['theme']['row_on']);
$t->set_var('row_off', $GLOBALS['egw_info']['theme']['row_off']);
$t->set_var('hidden_vars','<input type="hidden" name="referer" value="'.$referer.'">');
$t->set_var('hidden_vars', html::input_hidden('referer', $referer).
html::input_hidden('csrf_token', egw_csrf::token(__CLASS__)));
$t->pparse('out','header');
$vars = $t->get_undefined('body');

View File

@ -0,0 +1,71 @@
<?php
/**
* EGroupware API: CSRF (Cross Site Request Forgery) protection
*
* @link http://www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @author Ralf Becker <rb@stylite.de>
* @copyright (c) 2014 by Ralf Becker <rb@stylite.de>
* @version $Id$
*/
/**
* Class supplying methods to prevent successful CSRF by requesting a random token,
* stored on server and validated when request get posted.
*
* CSRF token generation used openssl_random_pseudo_bytes, if available, otherwise
* mt_rand based auth::randomstring is used.
*
* CSRF tokens are stored (incl. optional purpose) in user session.
*
* If a token does not validate (incl. purpose, if specified in generation)
* the request will be imediatly terminated.
*/
class egw_csrf
{
/**
* Get a CSRF token for an optional $purpose, which can be validated
*
* @param mixed $_purpose=true if given it need to be used in validate too! (It must NOT be NULL)
* @return string CSRF token
*/
public static function token($_purpose=true)
{
if (is_null($_purpose))
{
throw new egw_exception_wrong_parameter(__METHOD__.'(NULL) $_purspose must NOT be NULL!');
}
// generate random token (using oppenssl if available otherwise mt_rand based auth::randomstring)
$token = function_exists('openssl_random_pseudo_bytes') ?
base64_encode(openssl_random_pseudo_bytes(64)) :
auth::randomstring(64);
// store it in session for later validation
egw_cache::setSession(__CLASS__, $token, $_purpose);
return $token;
}
/**
* Validate a CSRF token or teminate the request
*
* @param string $_token CSRF token generated with egw_csfr::token()
* @param string $_purpose=true optional purpose string passed to token method
* @param boolean $_delete_token=true true if token should be deleted after validation, it will validate no second time
*/
public static function validate($_token, $_purpose=true, $_delete_token=true)
{
$stored_purpose = egw_cache::getSession(__CLASS__, $_token);
// if token and purpose dont validate, log and terminate request
if (!isset($stored_purpose) || $stored_purpose !== $_purpose)
{
error_log('CSRF detected from IP '.$_SERVER['REMOTE_ADDR'].' to '.$_SERVER['REQUEST_METHOD'].' '.$_SERVER['REQUEST_URI']);
if ($_POST) error_log(array2string($_POST));
// we are not throwing an exception here, but die, to not allow catching it!
die("CSRF detected, request terminated!");
}
if ($_delete_token) egw_cache::unsetTree (__CLASS__, $_token);
}
}

View File

@ -29,6 +29,13 @@ $setup_tpl->set_file(array(
'T_footer' => 'footer.tpl',
'T_alert_msg' => 'msg_alert_msg.tpl'
));
$setup_tpl->set_var('hidden_vars', html::input_hidden('csrf_token', egw_csrf::token(__FILE__)));
// check CSRF token for POST requests with any content (setup uses empty POST to call it's modules!)
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST)
{
egw_csrf::validate($_POST['csrf_token'], __FILE__);
}
// determine from where we migrate to what
if (!is_object($GLOBALS['egw_setup']->db))

View File

@ -26,6 +26,12 @@ if (strpos($_SERVER['PHP_SELF'],'admin_account.php') !== false)
$error = '';
if ($_POST['submit'])
{
// for POST (not GET or cli call via setup_cmd_admin) validate CSRF token
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
egw_csrf::validate($_POST['csrf_token'], __FILE__);
}
/* Posted admin data */
$passwd = get_var('passwd',Array('POST'));
$passwd2 = get_var('passwd2',Array('POST'));
@ -83,6 +89,8 @@ if(!$_POST['submit'] || $error)
$setup_tpl->set_var('create_demo_accounts',lang('Create demo accounts'));
$setup_tpl->set_var('demo_desc',lang('The username/passwords are: demo/guest, demo2/guest and demo3/guest.'));
$setup_tpl->set_var('hidden_vars', html::input_hidden('csrf_token', egw_csrf::token(__FILE__)));
$setup_tpl->set_var('lang_submit',lang('Save'));
$setup_tpl->set_var('lang_cancel',lang('Cancel'));
$setup_tpl->pparse('out','T_admin_account');

View File

@ -40,6 +40,13 @@ $setup_tpl->set_file(array(
'T_login_stage_header' => 'login_stage_header.tpl',
'T_setup_main' => 'applications.tpl'
));
$setup_tpl->set_var('hidden_vars', html::input_hidden('csrf_token', egw_csrf::token(__FILE__)));
// check CSRF token for POST requests with any content (setup uses empty POST to call it's modules!)
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST)
{
egw_csrf::validate($_POST['csrf_token'], __FILE__);
}
$setup_tpl->set_block('T_login_stage_header','B_multi_domain','V_multi_domain');
$setup_tpl->set_block('T_login_stage_header','B_single_domain','V_single_domain');

View File

@ -32,6 +32,13 @@ $setup_tpl->set_file(array(
'T_config_pre_script' => 'config_pre_script.tpl',
'T_config_post_script' => 'config_post_script.tpl'
));
$setup_tpl->set_var('hidden_vars', html::input_hidden('csrf_token', egw_csrf::token(__FILE__)));
// check CSRF token for POST requests with any content (setup uses empty POST to call it's modules!)
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST)
{
egw_csrf::validate($_POST['csrf_token'], __FILE__);
}
/* Following to ensure windows file paths are saved correctly */
if (function_exists('get_magic_quotes_runtime') && get_magic_quotes_runtime())
@ -130,16 +137,14 @@ $setup_tpl->pparse('out','T_config_pre_script');
/* Now parse each of the templates we want to show here */
class phpgw
{
var $common;
var $accounts;
var $applications;
var $db;
}
$GLOBALS['egw'] = new phpgw;
$GLOBALS['egw']->common =& CreateObject('phpgwapi.common');
$GLOBALS['egw']->db =& $GLOBALS['egw_setup']->db;
$t = CreateObject('phpgwapi.Template',$GLOBALS['egw']->common->get_tpl_dir('setup'));
$t = CreateObject('phpgwapi.Template', common::get_tpl_dir('setup'));
$t->set_unknowns('keep');
$t->set_file(array('config' => 'config.tpl'));

View File

@ -49,6 +49,13 @@ $setup_tpl->set_file(array(
'T_footer' => 'footer.tpl',
'T_db_backup' => 'db_backup.tpl',
));
$setup_tpl->set_var('hidden_vars', html::input_hidden('csrf_token', egw_csrf::token(__FILE__)));
// check CSRF token for POST requests with any content (setup uses empty POST to call it's modules!)
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST)
{
egw_csrf::validate($_POST['csrf_token'], __FILE__);
}
$setup_tpl->set_block('T_db_backup','schedule_row','schedule_rows');
$setup_tpl->set_block('T_db_backup','set_row','set_rows');

View File

@ -268,6 +268,7 @@ switch($GLOBALS['egw_info']['setup']['stage']['db'])
$setup_tpl->set_var('V_db_filled_block',$db_filled_block);
break;
case 5:
$setup_tpl->set_var('hidden_vars', html::input_hidden('csrf_token', egw_csrf::token(__FILE__)));
$setup_tpl->set_var('are_you_sure',lang('ARE YOU SURE?'));
$setup_tpl->set_var('really_uninstall_all_applications',lang('REALLY Uninstall all applications'));
$setup_tpl->set_var('dropwarn',lang('Your tables will be dropped and you will lose data'));
@ -293,6 +294,7 @@ switch($GLOBALS['egw_info']['setup']['stage']['db'])
$GLOBALS['egw_setup']->db->create_database($_POST['db_root'], $_POST['db_pass'],'utf8'); // create all new db's with utf8
break;
case 'drop':
egw_csrf::validate($_POST['csrf_token'], __FILE__);
$setup_info = $GLOBALS['egw_setup']->detection->get_versions($setup_info);
$setup_info = $GLOBALS['egw_setup']->process->droptables($setup_info);
break;

View File

@ -1,5 +1,6 @@
<!-- BEGIN header -->
<form action="{action_url}" method="post">
{hidden_vars}
<table border="0" align="center" width="70%">
<tr bgcolor="#486591">
<td colspan="2" align="center"><b><font color="#fefefe">{description}</font></b></td>

View File

@ -0,0 +1,63 @@
<!-- BEGIN admin_account -->
<form method="post" action="{action_url}">
{hidden_vars}
<table border="0" width="90%" cellspacing="0" cellpadding="2">
<tr>
<td>
<p><b>{description}</b></p>
<p><input type="checkbox" name="delete_all" />{lang_deleteall}</p>
<font color="red">{error}</font>
</td>
</tr>
<tr>
<td align="left" bgcolor="#cccccc">{detailadmin}</td>
</tr>
<tr>
<td>
<table border="0">
<tr>
<td>{adminusername}</td>
<td colspan="2"><input type="text" name="username" value="{username}" /></td>
</tr>
<tr>
<td>{adminfirstname}</td>
<td colspan="2"><input type="text" name="fname" value="{fname}" /></td>
</tr>
<tr>
<td>{adminlastname}</td>
<td colspan="2"><input type="text" name="lname" value="{lname}" /></td>
</tr>
<tr>
<td>{adminemail}</td>
<td colspan="2"><input type="text" name="email" value="{email}" /></td>
</tr>
<tr>
<td>{adminpassword}</td>
<td colspan="2"><input type="password" name="passwd" /></td>
</tr>
<tr>
<td>{adminpassword2}</td>
<td colspan="2"><input type="password" name="passwd2" /></td>
</tr>
<tr>
<td>{admin_all_apps}</td>
<td><input type="checkbox" name="admin_all_aps" /></td>
<td >{all_apps_desc}</td>
</tr>
<tr>
<td>{create_demo_accounts}</td>
<td><input type="checkbox" name="create_demo" /></td>
<td >{demo_desc}</td>
</tr>
<tr>
</tr>
<tr>
<td><input type="submit" name="submit" value="{lang_submit}" /></td>
<td colspan="2"><input type="submit" name="cancel" value="{lang_cancel}" /></td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<!-- END admin_account -->

View File

@ -0,0 +1,149 @@
<!-- BEGIN header -->
<script type="text/javascript">
<!--
function check_all(which)
{
for (i=0; i<document.apps.elements.length; i++)
{
if (document.apps.elements[i].type == "checkbox" && document.apps.elements[i].name.substring(0,which.length) == which)
{
if (document.apps.elements[i].checked)
{
document.apps.elements[i].checked = false;
}
else
{
document.apps.elements[i].checked = true;
}
}
}
}
// -->
</script>
<br />
<div align="center">
<table border="0" width="100%" cellspacing="0" cellpadding="2">
<tr>
<td align="center">{description}</td>
</tr>
</table>
<form name="apps" method="post" action="{action_url}">
{hidden_vars}
<table width="90%" cellspacing="0" cellpadding="2">
<!-- END header -->
<!-- BEGIN app_header -->
<tr class="th">
<td colspan="5" align="center">{appdata}</td>
<td colspan="4" align="center">{actions}</td>
</tr>
<tr bgcolor="#99cccc">
<td colspan="2">{app_info}</td>
<td align="center">{app_title}</td>
<td align="center">{app_currentver}</td>
<td align="center">{app_version}</td>
<td align="center">{app_install}</td>
<td align="center">{app_upgrade}</td>
<td align="center">{app_resolve}</td>
<td align="center">{app_remove}</td>
</tr>
<tr>
<td bgcolor="{bg_color}" colspan="5">&nbsp;</td>
<td bgcolor="{bg_color}" align="center">
<a href="javascript:check_all('install')"><img src="templates/default/images/{check}" border="0" height="16" width="21" alt="{install_all}" /></a>
</td>
<td bgcolor="{bg_color}" align="center">
<a href="javascript:check_all('upgrade')"><img src="templates/default/images/{check}" border="0" height="16" width="21" alt="{upgrade_all}" /></a>
</td>
<td bgcolor="{bg_color}">&nbsp;</td>
<td bgcolor="{bg_color}" align="center">
<a href="javascript:check_all('remove')"><img src="templates/default/images/{check}" border="0" height="16" width="21" alt="{remove_all}" /></a>
</td>
</tr>
<!-- END app_header -->
<!-- BEGIN apps -->
<tr bgcolor="{bg_color}">
<td><a href="applications.php?detail={appname}"><img src="templates/default/images/{instimg}" alt="{instalt}" title="{instalt}" border="0" /></a></td>
<td>{appinfo}&nbsp;</td>
<td>{apptitle}&nbsp;</td>
<td>{currentver}&nbsp;</td>
<td>{version}&nbsp;</td>
<td bgcolor="#CCFFCC" align="center">{install}</td>
<td bgcolor="#CCCCFF" align="center">{upgrade}</td>
<td align="center">{resolution}&nbsp;</td>
<td bgcolor="#CCAAAA" align="center">{remove}</td>
</tr>
<!-- END apps -->
<!-- BEGIN detail -->
<tr bgcolor="{bg_color}">
<td>{name}&nbsp;</td>
<td>{details}&nbsp;</td>
</tr>
<!-- END detail -->
<!-- BEGIN table -->
<tr bgcolor="{bg_color}">
<td>{tables}</td>
</tr>
<!-- END table -->
<!-- BEGIN hook -->
<tr bgcolor="{bg_color}">
<td>{hooks}</td>
</tr>
<!-- END hook -->
<!-- BEGIN dep -->
<tr bgcolor="{bg_color}">
<td>{deps}</td>
</tr>
<!-- END dep -->
<!-- BEGIN resolve -->
<tr bgcolor="{bg_color}">
<td>{resolution}</td>
</tr>
<!-- END resolve -->
<!-- BEGIN submit -->
{goback}
<!-- END submit -->
<!-- BEGIN app_footer -->
<tr>
<td bgcolor="{bg_color}" colspan="5">{debug} {lang_debug}</td>
<td bgcolor="{bg_color}" align="center">
<a href="javascript:check_all('install')"><img src="templates/default/images/{check}" border="0" height="16" width="21" alt="{install_all}" /></a>
</td>
<td bgcolor="{bg_color}" align="center">
<a href="javascript:check_all('upgrade')"><img src="templates/default/images/{check}" border="0" height="16" width="21" alt="{upgrade_all}" /></a>
</td>
<td bgcolor="{bg_color}">&nbsp;</td>
<td bgcolor="{bg_color}" align="center">
<a href="javascript:check_all('remove')"><img src="templates/default/images/{check}" border="0" height="16" width="21" alt="{remove_all}" /></a>
</td>
</tr>
</table>
<table border="0" width="70%" cellspacing="0" cellpadding="2">
<tr>
<td colspan="2" align="center">
<input type="submit" name="submit" value="{submit}" />
<input type="submit" name="cancel" value="{cancel}" />
</td>
</tr>
</table>
</form>
<!-- END app_footer -->
<!-- BEGIN footer -->
<br />
<table width="100%" cellspacing="0">
<tr class="banner">
<td>&nbsp;</td>
</tr>
</table>
</div>
<!-- END footer -->

View File

@ -0,0 +1,6 @@
<!-- begin config_pre_script.tpl -->
<form method="post" action="config.php">
{hidden_vars}
<table border="0" align="center" cellspacing="0" width="90%">
<!-- end config_pre_script.tpl -->

View File

@ -0,0 +1,176 @@
<!-- begin db_backup.tpl -->
<p align="center"><font color="red">{error_msg}</font></p>
<script language="JavaScript1.2">
Array.prototype.contains = function(value)
{
for(var i = 0;i < this.length;i++)
if(this[i] == value)
return(true);
return(false);
}
function Numsort(a,b)
{
return a-b;
}
function sort_table(id)
{
var sortedby = document.getElementById('sortedby').value;
var table = document.getElementById('files_table');
var rows = table.rows;
var l = rows.length;
if(l < 2) return;
var sort_columns = Array();
var rows_content = Array();
for(var i = 1;i < l;i++)
{
var value = rows[i].cells[id].innerHTML.toUpperCase();
if (id == 2)
{
start = value.search(/\(/)+1;
stop = value.search(/\)/);
value = value.substring(start,stop);
}
var index = 0;
while(sort_columns.contains(value + (index != 0 ? '_' + index : '')))
index++;
value = value + (index != 0 ? '_' + index : '');
sort_columns[i - 1] = value;
rows_content[value] = rows[i].innerHTML;
}
if (id == 2)
{
sort_columns.sort(Numsort);
}
else
{
sort_columns.sort();
}
if (sortedby == id)
{
sort_columns.reverse();
document.getElementById('sortedby').value = -1;
}
else
{
document.getElementById('sortedby').value = id;
}
for(var i = 1;i < l;i++)
table.deleteRow(-1);
for(var i = 1;i < l;i++)
{
var new_row = table.insertRow(-1);
new_row.align = 'center';
new_row.innerHTML = rows_content[sort_columns[i - 1]];
}
}
</script>
<form method="post" name="backup_form" action="{self}" enctype="multipart/form-data">
{hidden_vars}
<input name="sortedby" id="sortedby" type="hidden" />
<table border="0" align="center" width="98%" cellpadding="5">
<!-- BEGIN setup_header -->
<tr bgcolor="#486591">
<td colspan="2">
&nbsp;<font color="#fefefe"><b>{stage_title}</b></font>
</td>
</tr>
<tr bgcolor="#e6e6e6">
<td colspan="2">
{stage_desc}
</td>
</tr>
<!-- END setup_header -->
<tr bgcolor="#e6e6e6">
<td>
<b>{lang_scheduled_backups}</b>
</td>
<td align="right">
{backup_now_button}
</td>
</tr>
<tr bgcolor="#e6e6e6">
<td colspan="2">
<table style="border: 1px solid black; border-collapse: collapse;" border="1" width="100%">
<tr align="center">
<td>{lang_year}</td>
<td>{lang_month}</td>
<td>{lang_day}</td>
<td>{lang_dow}</td>
<td>{lang_hour}</td>
<td>{lang_minute}</td>
<td>{lang_next_run}</td>
<td>{lang_actions}</td>
</tr>
<!-- BEGIN schedule_row -->
<tr align="center">
<td>{year}</td>
<td>{month}</td>
<td>{day}</td>
<td>{dow}</td>
<td>{hour}</td>
<td>{min}</td>
<td>{next_run}</td>
<td>{actions}</td>
</tr>
<!-- END schedule_row -->
</table>
</td>
</tr>
<tr bgcolor="#e6e6e6">
<td>
<b>{lang_backup_sets}</b> {backup_dir}
</td>
<td align="right">
{upload}
</td>
</tr>
<tr bgcolor="#e6e6ee">
<td>
{lang_backup_cleanup}
</td>
<td align="right">
{lang_backup_mincount} {backup_mincount}
</td>
</tr>
<tr bgcolor="#e6e6e6">
<td>
{lang_backup_files_info}
</td>
<td align="right">
{lang_backup_files} {backup_files}
</td>
</tr>
<tr bgcolor="#e6e6ee">
<td colspan="2" align="right">
{backup_save_settings}
</td>
</tr>
<tr bgcolor="#e6e6e6">
<td colspan="2">
<table id="files_table" style="border: 1px solid black; border-collapse: collapse;" border="1" width="100%">
<tr align="center">
<td><a href="#" onClick="sort_table(0);">{lang_filename}</a></td>
<td><a href="#" onClick="sort_table(1);">{lang_mod}</a></td>
<td><a href="#" onClick="sort_table(2);">{lang_size}</a></td>
<td>{lang_actions}</td>
</tr>
<!-- BEGIN set_row -->
<tr align="center">
<td>{filename}</td>
<td>{mod}</td>
<td>{size}</td>
<td>{actions}</td>
</tr>
<!-- END set_row -->
</table>
</td>
</tr>
</table>
</form>
<!-- end db_backup.tpl -->

View File

@ -0,0 +1,242 @@
<!-- begin setup_db_blocks.tpl -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- BEGIN B_db_stage_1 -->
<tr>
<td align="center">
<img src="{img_incomplete}" alt="{notcomplete}" border="0" />
</td>
<td>
<form action="index.php" method="post">
<p>{lang_system_charset}<br />{system_charset}</p>
<p>{dbnotexist}<br />{makesure}.</p>
<p>{instr}</p>
<p>{createdb}<br />
DB root username: <input type="text" name="db_root" value="root" /><br />
DB root password: <input type="password" name="db_pass" /><br />
<input type="hidden" name="action" value="Create Database" />
<input type="submit" name="label" value="{create_database}" /></p>
</form>
<form method="post" action="index.php"> <br />
<input type="submit" value="Re-Check my database" />
</form>
</td>
</tr>
<!-- END B_db_stage_1 -->
<!-- BEGIN B_db_stage_1a -->
<tr>
<td align="center">
<img src="{img_incomplete}" alt="{notcomplete}" border="0" />
</td>
<td>
<p>{dbnotexist}<br />{makesure}.</p>
<p>{instr}</p>
<form method="post" action="index.php">
<input type="submit" value="Re-Check my database" />
</form><br />
</td>
</tr>
<!-- END B_db_stage_1a -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- BEGIN B_db_stage_2 -->
<tr>
<td align="center">
<img src="{img_incomplete}" alt="{notcomplete}" border="0" />
</td>
<td>
{prebeta}
</td>
</tr>
<!-- END B_db_stage_2 -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- BEGIN B_db_stage_3 -->
<tr>
<td align="center">
<img src="{img_incomplete}" alt="{Complete}" border="0" />
</td>
<td>
<form action="index.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="oldversion" value="new" />
<p>{dbexists}</p>
<input type="hidden" name="action" value="Install" />
<p>{lang_system_charset}<br />{system_charset}</p>
<input type="checkbox" name="debug" value="1" /> {lang_debug}<br />
<input type="submit" name="label" value="{install}" /> {coreapps}
<hr />
{lang_restore}<br />
{upload}<br />
{convert_checkbox} {lang_convert_charset}
</form>
</td>
</tr>
<!-- END B_db_stage_3 -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- BEGIN B_db_stage_4 -->
<tr>
<td align="center">
<img src="{img_incomplete}" alt="not complete" border="0" />
</td>
<td>
{oldver}.<br />
{automatic}
{backupwarn}<br />
<form method="post" action="index.php">
<input type="hidden" name="oldversion" value="{oldver}" />
<input type="hidden" name="useglobalconfigsettings" />
<input type="hidden" name="action" value="Upgrade" />
<input type="checkbox" name="backup" value="1" checked="checked" /> {lang_backup}<br />
<input type="checkbox" name="debug" value="1" /> {lang_debug}<br />
<input type="submit" name="label" value="{upgrade}" /><br />
</form>
<hr />
<form method="post" action="index.php">
<input type="hidden" name="oldversion" value="{oldver}" />
<input type="hidden" name="useglobalconfigsettings" />
<input type="hidden" name="action" value="Uninstall all applications" />
<input type="submit" name="label" value="{uninstall_all_applications}" /><br />({dropwarn})
</form>
<hr />
{dont_touch_my_data}.&nbsp;&nbsp;{goto}:
<form method="post" action="config.php">
<input type="hidden" name="action" value="Dont touch my data" />
<input type="submit" name="label" value="{configuration}" />
</form>
<form method="post" action="admin_account.php">
<input type="hidden" name="action" value="Dont touch my data" />
<input type="submit" name="label" value="{admin_account}" />
</form>
<form method="post" action="lang.php">
<input type="hidden" name="action" value="Dont touch my data" />
<input type="submit" name="label" value="{language_management}" />
</form>
<form method="post" action="applications.php">
<input type="hidden" name="action" value="Dont touch my data" />
<input type="submit" name="label" value="{applications}" />
</form>
<form method="post" action="db_backup.php">
<input type="hidden" name="action" value="Dont touch my data" />
<input type="submit" name="label" value="{db_backup}" />
</form>
</td>
</tr>
<!-- END B_db_stage_4 -->
<!-- BEGIN B_db_stage_5 -->
<tr>
<td>&nbsp;</td><td align="left">{are_you_sure}</td>
</tr>
<tr>
<td align="center">
<img src="{img_incomplete}" alt="{Complete}" border="0" />
</td>
<td>
<form action="index.php" method="post">
{hidden_vars}
<input type="hidden" name="oldversion" value="new" />
<input type="hidden" name="action" value="REALLY Uninstall all applications" />
<input type="submit" name="label" value="{really_uninstall_all_applications}" /> {dropwarn}
</form>
<form action="index.php" method="post">
<input type="submit" name="cancel" value="{cancel}" />
</form>
</td>
</tr>
<!-- END B_db_stage_5 -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- BEGIN B_db_stage_6_pre -->
<tr>
<td align="center">
<img src="{img_incomplete}" alt="{notcomplete}" border="0" />
</td>
<td>
<table width="100%">
<tr bgcolor="#486591">
<td>
<font color="#fefefe">&nbsp;<b>{subtitle}</b></font>
</td>
</tr>
<tr bgcolor="#e6e6e6">
<td>
{submsg}
</td>
</tr>
<!--
<tr bgcolor="#486591">
<td>
<font color="#fefefe">&nbsp;<b>{tblchange}</b></font>
</td>
</tr>
-->
<!-- END B_db_stage_6_pre -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- BEGIN B_db_stage_6_post -->
<tr bgcolor="#486591">
<td>
<font color="#fefefe">&nbsp;<b>{status}</b></font>
</td>
</tr>
<tr bgcolor="#e6e6e6">
<td>{tableshave} {subaction}</td>
</tr>
</table>
<form method="post" action="index.php"> <br />
<input type="hidden" name="system_charset" value="{system_charset}" />
<input type="submit" value="{re-check_my_installation}" />
</form>
</td>
</tr>
<!-- END B_db_stage_6_post -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- BEGIN B_db_stage_10 -->
<tr>
<td align="center">
<img src="{img_completed}" alt="completed" border="0" />
</td>
<td>
{tablescurrent}
<form method="post" action="index.php">
<input type="hidden" name="oldversion" value="new" />
<input type="hidden" name="action" value="Uninstall all applications" />
<input type="submit" name="label" value="{uninstall_all_applications}" /><br />({dropwarn})
</form>
</td>
</tr>
<!-- END B_db_stage_10 -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- BEGIN B_db_stage_default -->
<tr>
<td align="center">
<img src="{img_incomplete}" alt="not complete" border="0" />
</td>
<td>
<form action="index.php" method="post">
{dbnotexist}.<br />
<input type="submit" value="{create_one_now}" />
</form>
</td>
</tr>
<!-- END B_db_stage_default -->
&nbsp; <!-- ================================== --> &nbsp;
<!-- end setup_db_blocks.tpl -->