Encyption support: most work by bergware

This commit is contained in:
Tom Mortensen
2017-08-15 20:11:40 -07:00
parent 39b5635f10
commit e5d4e9cc1e
18 changed files with 393 additions and 124 deletions

View File

@@ -140,7 +140,7 @@ toggle_diskio(true);
<? if ($var['fsNumUnmountable']>0):?>
<tr>
<td><strong>Unmountable disk<?=$var['fsNumUnmountable']==1?'':'s'?> present:</strong><br>
<? foreach ($disks as $disk) if ($disk['fsStatus']=='Unmountable') echo "<br><span class='blue-text'>".my_disk($disk['name'])."</span> &bullet; ".my_id($disk['id'])." (".$disk['device'].")";?></td>
<? foreach ($disks as $disk) if (strstr($disk['fsStatus'],'Unmountable')) echo "<br><span class='blue-text'>".my_disk($disk['name'])."</span> &bullet; ".my_id($disk['id'])." (".$disk['device'].")";?></td>
<td><input type="submit" id="cmdFormat" name="cmdFormat" value="Format" disabled><input type="hidden" name="unmountable_mask" value="<?=$var['fsUnmountableMask']?>"></td>
<td><strong>Format</strong> will create a file system in all <strong>Unmountable</strong> disks, discarding all data currently on those disks.<br>
<input type="checkbox" name="confirmFormat" value="OFF" onClick="arrayOps.cmdFormat.disabled=!arrayOps.confirmFormat.checked"><small>Yes I want to do this</small>

View File

@@ -131,6 +131,7 @@ echo "<td>Array Status</td>".implode('',$row0);
?>
</tr></thead>
<tbody id='dash0'>
<?init_row('Encrypted')?>
<?init_row('Active')?>
<?init_row('Inactive')?>
<?init_row('Unassigned')?>
@@ -152,6 +153,7 @@ echo "<td>Array Status</td>".implode('',$row0);
?>
</tr></thead>
<tbody id='dash1'>
<?init_row('Encrypted')?>
<?init_row('Active')?>
<?init_row('Inactive')?>
<?init_row('Unassigned')?>

View File

@@ -23,6 +23,19 @@ function displayTemp($temp) {
global $display;
return $display['unit']=='F' ? round($temp*9/5)+32 : $temp;
}
function luks_status($luksState) {
switch ($luksState) {
case 0: return 'Not encrypted'; break;
case 1: return 'Encrypted'; break;
case 2: return 'Missing encryption key'; break;
case 3: return 'Wrong encryption key'; break;
default: return 'Unknown error'; break;
}
}
function maintenance_mode() {
global $var;
return ($var['fsState']=="Started" && $var['startMode']=="Maintenance") ? '' : 'disabled';
}
?>
<script>
function doDispatch(form) {
@@ -91,45 +104,11 @@ Partition size:
Partition format:
: <?=$disk['format']?>
<?if ($disk['type']!="Parity"):?>
<?if ($disk['type']=="Data" || $disk['name']=="cache"):?>
Comments:
: <input type="text" name="diskComment.<?=$disk['idx'];?>" maxlength="256" value="<?=htmlspecialchars($disk['comment'])?>">
> This text will appear under the *Comments* column for the share in Windows Explorer.
> Enter anything you like, up to 256 characters.
<?if ($var['spinupGroups']=="yes" && $disk['type']=="Data"):?>
Spinup group(s):
: <input type="text" name="diskSpinupGroup.<?=$disk['idx'];?>" maxlength="256" value="<?=$disk['spinupGroup']?>">
<?endif;?>
File system status:
: <?=$disk['fsStatus']?><?if ($disk['fsError']) echo " - {$disk['fsError']}";?>&nbsp;
<?endif;?>
<?if ($disk['type']=="Data" || ($disk['type']=="Cache" && $var['SYS_CACHE_SLOTS']==1)):?>
<?if ($var['fsState']=="Stopped"):?>
<?$disabled = $var['mdState']=="RECON_DISK" || $var['mdState']=="SWAP_DSBL" ? "disabled" : "";?>
File system type:
: <select name="diskFsType.<?=$disk['idx'];?>" size="1" <?=$disabled?>>
<?=mk_option($disk['fsType'], "auto", "auto")?>
<?=mk_option($disk['fsType'], "btrfs", "btrfs")?>
<?=mk_option($disk['fsType'], "reiserfs", "reiserfs")?>
<?=mk_option($disk['fsType'], "xfs", "xfs")?>
</select>
<?else:?>
File system type:
: <select name="diskFsType.<?=$disk['idx'];?>" size="1" disabled>
<?=mk_option($disk['fsType'], "auto", "auto")?>
<?=mk_option($disk['fsType'], "btrfs", "btrfs")?>
<?=mk_option($disk['fsType'], "reiserfs", "reiserfs")?>
<?=mk_option($disk['fsType'], "xfs", "xfs")?>
</select> Array must be <span class="strong big">Stopped</span> to change
<?endif;?>
<?elseif ($disk['type']=="Cache" && $var['SYS_CACHE_SLOTS']>1):?>
File system type:
: <?=$disk['fsType'];?>&nbsp;
<?endif;?>
Spin down delay:
: <select name="diskSpindownDelay.<?=$disk['idx']?>" size="1">
<?=mk_option($disk['spindownDelay'], "-1", "Use default")?>
@@ -148,7 +127,58 @@ Spin down delay:
<?=mk_option($disk['spindownDelay'], "9", "9 hours")?>
</select><span id="smart_selftest" class='orange-text'></span>
<?if (isset($disk['fsSize'])):?>
Warning disk temperature threshold (&deg;<?=$display['unit']?>):
: <input type="number" min="0" max="300" name="<?=htmlspecialchars($name)?>_hotTemp" class="narrow" value="<?=strlen($disk['hotTemp'])?displayTemp($disk['hotTemp']):''?>" placeholder="<?=displayTemp($display['hot'])?>">
> *Warning disk temperature* sets the warning threshold for this hard disk temperature. Exceeding this threshold will result in a warning notification.
>
> A value of zero will disable the warning threshold (including notifications).
Critical disk temperature threshold (&deg;<?=$display['unit']?>):
: <input type="number" min="0" max="300" name="<?=htmlspecialchars($name)?>_maxTemp" class="narrow" value="<?=strlen($disk['maxTemp'])?displayTemp($disk['maxTemp']):''?>" placeholder="<?=displayTemp($display['max'])?>">
> *Critical disk temperature* sets the critical threshold for this hard disk temperature. Exceeding this threshold will result in an alert notification.
>
> A value of zero will disable the critical threshold (including notifications).
<?if ($disk['type']=="Data" || $disk['name']=="cache"):?>
File system status:
: <?=$disk['fsStatus']?>&nbsp;
<?if ($var['fsState']=="Stopped"):?>
<?$disabled = $var['mdState']=="SWAP_DSBL" ? "disabled" : "";?>
<?if ($disk['type']=="Data" || $var['SYS_CACHE_SLOTS']==1):?>
File system type:
: <select id="diskFsType" name="diskFsType.<?=$disk['idx'];?>" size="1" <?=$disabled?>>
<?=mk_option($disk['fsType'], "auto", "auto")?>
<?=mk_option($disk['fsType'], "xfs", "xfs")?>
<?=mk_option($disk['fsType'], "btrfs", "btrfs")?>
<?=mk_option($disk['fsType'], "reiserfs", "reiserfs")?>
<?=mk_option($disk['fsType'], "luks:xfs", "xfs - encrypted")?>
<?=mk_option($disk['fsType'], "luks:btrfs", "btrfs - encrypted")?>
<?=mk_option($disk['fsType'], "luks:reiserfs", "reiserfs - encrypted")?>
</select>
<?elseif ($var['SYS_CACHE_SLOTS']>1):?>
File system type:
: <select id="diskFsType" name="diskFsType.<?=$disk['idx'];?>" size="1" <?=$disabled?>>
<?=mk_option($disk['fsType'], "auto", "auto")?>
<?=mk_option($disk['fsType'], "btrfs", "btrfs")?>
<?=mk_option($disk['fsType'], "luks:btrfs", "btrfs - encrypted")?>
</select>
<?endif;?>
<?else:?>
File system type:
: <?=str_replace('luks:','',$disk['fsType']).(strpos($disk['fsType'],'luks:')!==false ? ' - encrypted' : '')?>&nbsp;
<?endif;?>
Comments:
: <input type="text" name="diskComment.<?=$disk['idx'];?>" maxlength="256" value="<?=htmlspecialchars($disk['comment'])?>">
> This text will appear under the *Comments* column for the share in Windows Explorer.
> Enter anything you like, up to 256 characters.
Warning disk utilization threshold (%):
: <input type="number" min="0" max="100" name="<?=htmlspecialchars($name)?>_warning" class="narrow" value="<?=strlen($disk['warning'])?$disk['warning']:''?>" placeholder="<?=$display['warning']?>">
@@ -165,24 +195,6 @@ Critical disk utilization threshold (%):
>
> A value of zero will disable the critical threshold (including notifications).
<?endif;?>
Warning disk temperature threshold (&deg;<?=$display['unit']?>):
: <input type="number" min="0" max="300" name="<?=htmlspecialchars($name)?>_hotTemp" class="narrow" value="<?=strlen($disk['hotTemp'])?displayTemp($disk['hotTemp']):''?>" placeholder="<?=displayTemp($display['hot'])?>">
> *Warning disk temperature* sets the warning threshold for this hard disk temperature. Exceeding this threshold will result in a warning notification.
>
> A value of zero will disable the warning threshold (including notifications).
Critical disk temperature threshold (&deg;<?=$display['unit']?>):
: <input type="number" min="0" max="300" name="<?=htmlspecialchars($name)?>_maxTemp" class="narrow" value="<?=strlen($disk['maxTemp'])?displayTemp($disk['maxTemp']):''?>" placeholder="<?=displayTemp($display['max'])?>">
> *Critical disk temperature* sets the critical threshold for this hard disk temperature. Exceeding this threshold will result in an alert notification.
>
> A value of zero will disable the critical threshold (including notifications).
<?if (($var['spinupGroups']=="yes")&&($disk['type']!="Cache")):?>
Spinup group(s):
: <input type="text" name="diskSpinupGroup.<?=$disk['idx'];?>" maxlength="256" value="<?=$disk['spinupGroup']?>">
<?endif;?>
&nbsp;

View File

@@ -114,9 +114,12 @@ Default partition format:
Default file system:
: <select name="defaultFsType" size="1">
<?=mk_option($var['defaultFsType'], "btrfs", "Btrfs");?>
<?=mk_option($var['defaultFsType'], "reiserfs", "ReiserFS");?>
<?=mk_option($var['defaultFsType'], "xfs", "XFS");?>
<?=mk_option($var['defaultFsType'], "xfs", "xfs");?>
<?=mk_option($var['defaultFsType'], "btrfs", "btrfs");?>
<?=mk_option($var['defaultFsType'], "reiserfs", "reiserfs");?>
<?=mk_option($var['defaultFsType'], "luks:xfs", "luks:xfs - encrypted");?>
<?=mk_option($var['defaultFsType'], "luks:btrfs", "luks:btrfs - encrypted");?>
<?=mk_option($var['defaultFsType'], "luks:reiserfs", "luks:reiserfs - encrypted");?>
</select>
> Defines the default file system type to create when an *unmountable* array device is formatted.

View File

@@ -0,0 +1,108 @@
Menu="UserPreferences"
Title="Encryption Settings"
Icon="encryption-settings.png"
---
<?PHP
/* Copyright 2005-2017, Lime Technology
* Copyright 2012-2017, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$keyfile = file_exists($var['luksKeyfile']) ? $var['luksKeyfile'] : '';
$online = $var['fsState']=='Stopped' ? '' : 'disabled';
?>
<script>
<?if ($keyfile):?>
function checkInput(form) {
form.keyfile.disabled = true;
return true;
}
function toggleButton(checked) {
$('input[name="#apply"]').prop('disabled',!checked);
}
<?else:?>
function checkInput(form) {
if (form.text.value || form.file.value) {
form.input.disabled = true;
form.local.disabled = true;
return true;
}
return false;
}
function selectInput(form) {
if (form.input.value == 'text') {
form.file.value = '';
$('#text').show(); $('#file').hide();
} else {
form.text.value = '';
$('#text').hide(); $('#file').show();
}
}
function showPass(checked) {
$('input[name="text"').attr('type',checked ? 'text' : 'password');
}
function getFileContent(event,form) {
var input = event.target;
var reader = new FileReader();
reader.onload = function(){form.file.value = reader.result;};
reader.readAsText(input.files[0]);
}
<?endif;?>
</script>
<form markdown="1" name="encrypt_settings" method="POST" action="/update.php" target="progressFrame" onsubmit="return checkInput(this)">
<input type="hidden" name="#file" value="unused">
<input type="hidden" name="#include" value="webGui/include/KeyUpload.php">
<input type="hidden" name="file" value="">
Encryption key:
: &nbsp;<?=$keyfile ?: 'Not present'?>
> Shows the path and name of the current keyfile, if present.
>
> This keyfile is read upon array start and is used to encrypt/decrypt content of devices which have encryption enabled.
<?if ($keyfile):?>
Delete <input type="checkbox" name="keyfile" onchange="toggleButton(this.checked)">
: <input type="submit" name="#apply" value="Delete" disabled><input type="button" value="Done" class="lock" onclick="done()">
> The keyfile can be deleted in order to create a new encryption key. This however will invalidate all existing encrypted content.
> Devices need to be reformatted and content is permanently lost when the encryption key is changed.
>
> For the really 'paranoid'. It is allowed to delete the keyfile *after* the array is started and re-enter the keyfile *while* the array is stopped.
> This ensures there is no *clear* encryption key present on the system when the array is online.
<?else:?>
Encryption input:
: <select name="input" size="1" onchange="selectInput(this.form)"<?=$online?>>
<?=mk_option(1, "text", "Passphrase")?>
<?=mk_option(1, "file", "Keyfile")?>
</select>
> Select manual input or file input of the encryption key. Note that the encryption key needs to be re-entered each time the system is rebooted.
>
> The array will **not** start automatically when encrypted volumes are present.
<div id="text" markdown="1">
Enter passphrase:
: <input type="password" name="text" value=""<?=$online?>><?if (!$online):?><input id="eye" type="checkbox" onchange="showPass(this.checked)">show passphrase<?endif;?>
> Enter a secure passphrase as encryption key. **Memorize** this passphrase, if lost device content can not be recovered.
</div>
<div id="file" markdown="1" style="display:none">
Select local keyfile:
: <input type="file" name="local" onchange="getFileContent(event,this.form)"<?=$online?>>
> Select a local keyfile with a stored encryption key. **Keep** your local keyfile secured, if lost device content can not be recovered.
</div>
<input type="button" value="Benchmark" onclick="openBox('/webGui/include/CryptoBenchmark.php','Encryption Benchmarking',600,640)">
: <input type="submit" name="#apply" value="Apply"><input type="button" value="Done" onclick="done()"><?if ($online):?>Array must be <span class="strong big">Stopped</span> to change<?endif;?>
<?endif;?>
</form>

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,42 @@
<?PHP
/* Copyright 2005-2017, Lime Technology
* Copyright 2012-2017, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Benchmark</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="robots" content="noindex">
<link type="text/css" rel="stylesheet" href="/webGui/styles/default-fonts.css">
<link type="text/css" rel="stylesheet" href="/webGui/styles/font-awesome.css">
<link type="text/css" rel="stylesheet" href="/webGui/styles/default-popup.css">
<script src="/webGui/javascript/dynamix.js"></script>
<script>
var test = 'sha1,sha256,sha512,ripemd160,whirlpool,aes-cbc:128,serpent-cbc:128,twofish-cbc:128,aes-cbc:256,serpent-cbc:256,twofish-cbc:256,aes-xts:256,serpent-xts:256,twofish-xts:256,aes-xts:512,serpent-xts:512,twofish-xts:512';
function benchmark(index,last){
if (index > last) return;
$.get('/webGui/include/update.crypto.php',{index:index,test:test},function(data){
$('pre').append(data);
benchmark(index+1,last);
});
}
$(function(){
benchmark(0,test.split(',').length);
});
</script>
</head>
<body style='margin:20px'>
<pre style='font-family:bitstream;font-size:11px'></pre>
</body>
</html>

View File

@@ -11,7 +11,7 @@
*/
?>
<?
$docroot = $docroot ?: @$_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
$docroot = $docroot ?: $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
function normalize($type,$count) {
$words = explode('_',$type);
@@ -79,42 +79,53 @@ case 'disk':
require_once "$docroot/webGui/include/CustomMerge.php";
require_once "$docroot/webGui/include/Preselect.php";
$slots = $_POST['slots'];
$row1 = array_fill(0,31,'<td></td>'); my_insert($row1[0],'Active');
$row2 = array_fill(0,31,'<td></td>'); my_insert($row2[0],'Inactive');
$row3 = array_fill(0,31,'<td></td>'); my_insert($row3[0],'Unassigned');
$row4 = array_fill(0,31,'<td></td>'); my_insert($row4[0],'Faulty');
$row5 = array_fill(0,31,'<td></td>'); my_insert($row5[0],'Heat alarm');
$row6 = array_fill(0,31,'<td></td>'); my_insert($row6[0],'SMART status');
$row7 = array_fill(0,31,'<td></td>'); my_insert($row7[0],'Utilization');
$funcRenderRow = function($n,$disk) use (&$row1,&$row2,&$row3,&$row4,&$row5,&$row6,&$row7,$path) {
$row1 = array_fill(0,31,'<td></td>'); my_insert($row1[0],'Encrypted');
$row2 = array_fill(0,31,'<td></td>'); my_insert($row2[0],'Active');
$row3 = array_fill(0,31,'<td></td>'); my_insert($row3[0],'Inactive');
$row4 = array_fill(0,31,'<td></td>'); my_insert($row4[0],'Unassigned');
$row5 = array_fill(0,31,'<td></td>'); my_insert($row5[0],'Faulty');
$row6 = array_fill(0,31,'<td></td>'); my_insert($row6[0],'Heat alarm');
$row7 = array_fill(0,31,'<td></td>'); my_insert($row7[0],'SMART status');
$row8 = array_fill(0,31,'<td></td>'); my_insert($row8[0],'Utilization');
$funcRenderRow = function($n,$disk) use (&$row1,&$row2,&$row3,&$row4,&$row5,&$row6,&$row7,&$row8,$path) {
if ($n>0) {
if (isset($disk['luksState'])) {
switch ($disk['luksState']) {
case 0: $luks = ""; break;
case 1: $luks = "<i class='green-text fa fa-lock'></i>"; break;
case 2: $luks = "<i class='red-text fa fa-unlock'></i>"; break;
case 3: $luks = "<i class='red-text fa fa-unlock'></i>"; break;
default: $luks = "<i class='red-text fa fa-unlock'></i>"; break;
}
} else $luks = "";
my_insert($row1[$n],$luks);
$state = $disk['color'];
switch ($state) {
case 'grey-off':
break; //ignore
case 'green-on':
my_insert($row1[$n],"<img src=$path/$state.png>");
my_insert($row2[$n],"<img src=$path/$state.png>");
break;
case 'green-blink':
my_insert($row2[$n],"<img src=$path/$state.png>");
my_insert($row3[$n],"<img src=$path/$state.png>");
break;
case 'blue-on':
case 'blue-blink':
my_insert($row3[$n],"<img src=$path/$state.png>");
my_insert($row4[$n],"<img src=$path/$state.png>");
break;
default:
my_insert($row4[$n],"<img src=$path/$state.png>");
my_insert($row5[$n],"<img src=$path/$state.png>");
break;}
$temp = $disk['temp'];
$hot = strlen($disk['hotTemp']) ? $disk['hotTemp'] : $_POST['hot'];
$max = strlen($disk['maxTemp']) ? $disk['maxTemp'] : $_POST['max'];
$heat = $temp>=$max && $max>0 ? 'max' : ($temp>=$hot && $hot>0 ? 'hot' : '');
if ($heat)
my_insert($row5[$n],"<span class='heat-img'><img src='$path/$heat.png'></span><span class='heat-text' style='display:none'>".my_temp($temp,$_POST['unit'])."</span>");
my_insert($row6[$n],"<span class='heat-img'><img src='$path/$heat.png'></span><span class='heat-text' style='display:none'>".my_temp($temp,$_POST['unit'])."</span>");
else
if (!strpos($state,'blink') && $temp>0) my_insert($row5[$n],"<span class='temp-text'>".my_temp($temp,$_POST['unit'])."</span>");
if ($disk['device'] && !strpos($state,'blink')) my_smart($row6[$n],$disk['name'],'Device');
my_usage($row7[$n],($disk['type']!='Parity' && $disk['fsStatus']=='Mounted')?(round((1-$disk['fsFree']/$disk['fsSize'])*100).'%'):'');
if (!strpos($state,'blink') && $temp>0) my_insert($row6[$n],"<span class='temp-text'>".my_temp($temp,$_POST['unit'])."</span>");
if ($disk['device'] && !strpos($state,'blink')) my_smart($row7[$n],$disk['name'],'Device');
my_usage($row8[$n],($disk['type']!='Parity' && $disk['fsStatus']=='Mounted')?(round((1-$disk['fsFree']/$disk['fsSize'])*100).'%'):'');
}
};
foreach ($disks as $disk) if ($disk['type']=='Parity') $funcRenderRow($i++,$disk);
@@ -125,7 +136,7 @@ case 'disk':
$device = $dev['device'];
$state = exec("hdparm -C ".escapeshellarg("/dev/$device")."|grep -Po active") ? 'blue-on' : 'blue-blink';
if ($state=='blue-on') my_smart($row6[$i],$device,'New');
my_insert($row3[$i++],"<img src=$path/$state.png>");
my_insert($row4[$i++],"<img src=$path/$state.png>");
}
}
echo "<tr>".implode('',$row1)."</tr>";
@@ -135,21 +146,23 @@ case 'disk':
echo "<tr>".implode('',$row5)."</tr>";
echo "<tr>".implode('',$row6)."</tr>";
echo "<tr>".implode('',$row7)."</tr>";
echo "<tr>".implode('',$row8)."</tr>";
if ($slots > 30) {
echo '#'; $i = 1;
$row1 = array_fill(0,31,'<td></td>'); my_insert($row1[0],'Active');
$row2 = array_fill(0,31,'<td></td>'); my_insert($row2[0],'Inactive');
$row3 = array_fill(0,31,'<td></td>'); my_insert($row3[0],'Unassigned');
$row4 = array_fill(0,31,'<td></td>'); my_insert($row4[0],'Faulty');
$row5 = array_fill(0,31,'<td></td>'); my_insert($row5[0],'Heat alarm');
$row6 = array_fill(0,31,'<td></td>'); my_insert($row6[0],'SMART status');
$row7 = array_fill(0,31,'<td></td>'); my_insert($row7[0],'Utilization');
$row1 = array_fill(0,31,'<td></td>'); my_insert($row1[0],'Encrypted');
$row2 = array_fill(0,31,'<td></td>'); my_insert($row2[0],'Active');
$row3 = array_fill(0,31,'<td></td>'); my_insert($row3[0],'Inactive');
$row4 = array_fill(0,31,'<td></td>'); my_insert($row4[0],'Unassigned');
$row5 = array_fill(0,31,'<td></td>'); my_insert($row5[0],'Faulty');
$row6 = array_fill(0,31,'<td></td>'); my_insert($row6[0],'Heat alarm');
$row7 = array_fill(0,31,'<td></td>'); my_insert($row7[0],'SMART status');
$row8 = array_fill(0,31,'<td></td>'); my_insert($row8[0],'Utilization');
foreach ($disks as $disk) if ($disk['type']=='Cache') $funcRenderRow($i++,$disk);
foreach ($devs as $dev) {
$device = $dev['device'];
$state = exec("hdparm -C ".escapeshellarg("/dev/$device")."|grep -Po active") ? 'blue-on' : 'blue-blink';
if ($state=='blue-on') my_smart($row6[$i],$device,'New');
my_insert($row3[$i++],"<img src=$path/$state.png>");
my_insert($row4[$i++],"<img src=$path/$state.png>");
}
echo "<tr>".implode('',$row1)."</tr>";
echo "<tr>".implode('',$row2)."</tr>";
@@ -158,6 +171,7 @@ case 'disk':
echo "<tr>".implode('',$row5)."</tr>";
echo "<tr>".implode('',$row6)."</tr>";
echo "<tr>".implode('',$row7)."</tr>";
echo "<tr>".implode('',$row8)."</tr>";
}
break;
case 'sys':

View File

@@ -34,7 +34,7 @@ function in_parity_log($log,$timestamp) {
}
return !empty($line);
}
function device_info(&$disk) {
function device_info(&$disk,$online) {
global $path, $var;
$name = $disk['name'];
$fancyname = $disk['type']=='New' ? $name : my_disk($name);
@@ -57,15 +57,20 @@ function device_info(&$disk) {
case 'grey-off': $help = 'Device not present'; break;
}
$status = "$ctrl<a class='info nohand' onclick='return false'><img src='/webGui/images/{$disk['color']}.png' class='icon'><span>$help</span></a>";
$link = strpos($disk['status'], 'DISK_NP')===false ? "<a href=\"".htmlspecialchars("$path/$type?name=$name")."\">".$fancyname."</a>" : $fancyname;
return $status.$link;
$link = (strpos($disk['status'], 'DISK_NP')===false || $disk['name']=="cache") ? "<a href=\"".htmlspecialchars("$path/$type?name=$name")."\">".$fancyname."</a>" : $fancyname;
switch ($disk['luksState']) {
case 0: $luks = ""; break;
case 1: $luks = "<i class='padlock ".($online?'green':'grey')."-text fa fa-lock' title='Encrypted'></i>"; break;
case 2: $luks = "<i class='padlock red-text fa fa-unlock' title='Missing encryption key'></i>"; break;
case 3: $luks = "<i class='padlock red-text fa fa-unlock' title='Wrong encryption key'></i>"; break;
default: $luks = "<i class='padlock red-text fa fa-unlock' title='Unknown error'></i>"; break;
}
return $status.$link.$luks;
}
function device_browse(&$disk) {
global $path;
if ($disk['fsStatus']=='Mounted') {
$dir = $disk['name']=='flash' ? "/boot" : "/mnt/{$disk['name']}";
return "<a href=\"".htmlspecialchars("$path/Browse?dir=$dir")."\"><img src='/webGui/images/explore.png' title='Browse $dir'></a>";
}
$dir = $disk['name']=='flash' ? "/boot" : "/mnt/{$disk['name']}";
return "<a href=\"".htmlspecialchars("$path/Browse?dir=$dir")."\"><img src='/webGui/images/explore.png' title='Browse $dir'></a>";
}
function device_desc(&$disk) {
global $var;
@@ -85,7 +90,10 @@ function assignment(&$disk) {
$out .= "<option value=''>$empty</option>";
} else
$out .= "<option value='' selected>$empty</option>";
foreach ($devs as $dev) {$out .= "<option value=\"{$dev['id']}\">".device_desc($dev)."</option>";}
if ($disk['type']=="Cache")
foreach ($devs as $dev) {$out .= "<option value=\"{$dev['id']}\">".device_desc($dev)."</option>";}
else
foreach ($devs as $dev) if ($dev['tag']==0) {$out .= "<option value=\"{$dev['id']}\">".device_desc($dev)."</option>";}
return "$out</select></form>";
}
function fs_info(&$disk) {
@@ -94,7 +102,7 @@ function fs_info(&$disk) {
echo "<td colspan='5'></td>";
return;
} elseif ($disk['fsStatus']=='Mounted') {
echo "<td>{$disk['fsType']}</td>";
echo "<td>".str_replace('luks:','',$disk['fsType'])."</td>";
echo "<td>".my_scale($disk['fsSize']*1024,$unit)." $unit</td>";
if ($display['text']%10==0) {
echo "<td>".my_scale($disk['fsUsed']*1024,$unit)." $unit</td>";
@@ -108,9 +116,9 @@ function fs_info(&$disk) {
$free = $disk['fsSize'] ? round(100*$disk['fsFree']/$disk['fsSize']) : 0;
echo "<td><div class='usage-disk'><span style='margin:0;width:$free%' class='".usage_color($disk,$free,true)."'><span>".my_scale($disk['fsFree']*1024,$unit)." $unit</span></span></div></td>";
}
echo "<td>".device_browse($disk)."</td>";
} else
echo "<td colspan='2'></td><td>{$disk['fsStatus']}</td><td></td>";
echo "<td>".device_browse($disk)."</td>";
echo "<td>".str_replace('luks:','',$disk['fsType'])."</td><td colspan='4' style='text-align:center'>{$disk['fsStatus']}";
}
function my_diskio($data) {
return my_scale($data,$unit,1)." $unit/s";
@@ -120,9 +128,8 @@ function array_offline(&$disk,$w) {
echo "<tr>";
switch ($disk['status']) {
case 'DISK_NP':
case 'DISK_OK_NP':
case 'DISK_NP_DSBL':
echo "<td>".device_info($disk)."</td>";
echo "<td>".device_info($disk,false)."</td>";
echo "<td>".assignment($disk)."</td>";
echo "<td colspan='9'></td>";
break;
@@ -132,18 +139,18 @@ function array_offline(&$disk,$w) {
case 'DISK_DSBL':
case 'DISK_DSBL_NEW':
case 'DISK_NEW':
echo "<td>".device_info($disk)."</td>";
echo "<td>".device_info($disk,false)."</td>";
echo "<td>".assignment($disk)."</td>";
echo "<td>".my_temp($disk['temp'])."</td>";
echo "<td colspan='8'>$warning</td>";
break;
case 'DISK_NP_MISSING':
echo "<td>".device_info($disk)."<br><span class='diskinfo'><em>Missing</em></span></td>";
echo "<td>".device_info($disk,false)."<br><span class='diskinfo'><em>Missing</em></span></td>";
echo "<td>".assignment($disk)."<em>{$disk['idSb']} - ".my_scale($disk['sizeSb']*1024,$unit)." $unit</em></td>";
echo "<td colspan='9'></td>";
break;
case 'DISK_WRONG':
echo "<td>".device_info($disk)."<br><span class='diskinfo'><em>Wrong</em></span></td>";
echo "<td>".device_info($disk,false)."<br><span class='diskinfo'><em>Wrong</em></span></td>";
echo "<td>".assignment($disk)."<em>{$disk['idSb']} - ".my_scale($disk['sizeSb']*1024,$unit)." $unit</em></td>";
echo "<td>".my_temp($disk['temp'])."</td>";
echo "<td colspan='8'>$warning</td>";
@@ -173,21 +180,22 @@ function array_online(&$disk) {
echo "<tr>";
switch ($disk['status']) {
case 'DISK_NP':
// Suppress empty slots to keep device list short (make this configurable?)
// echo "<td>".device_info($disk)."</td>";
// echo "<td colspan='9'>Not installed</td>";
// echo "<td></td>";
if ($disk['name']=="cache") {
echo "<td>".device_info($disk,true)."</td>";
echo "<td><em>Not installed</em></td>";
echo "<td colspan='4'></td>";
fs_info($disk);
}
break;
case 'DISK_OK_NP':
case 'DISK_NP_DSBL':
echo "<td>".device_info($disk)."</td>";
echo "<td>".device_info($disk,true)."</td>";
echo "<td><em>Not installed</em></td>";
echo "<td colspan='4'></td>";
fs_info($disk);
break;
case 'DISK_DSBL':
default:
echo "<td>".device_info($disk)."</td>";
echo "<td>".device_info($disk,true)."</td>";
echo "<td>".device_desc($disk)."</td>";
echo "<td>".my_temp($disk['temp'])."</td>";
echo "<td><span class='diskio'>".my_diskio($data[0])."</span><span class='number'>".my_number($disk['numReads'])."</span></td>";
@@ -295,7 +303,7 @@ case 'flash':
$data = $diskio ? explode(' ',$diskio[$disk['device']]) : [];
$disk['fsUsed'] = $disk['fsSize']-$disk['fsFree'];
echo "<tr>";
echo "<td>".device_info($disk)."</td>";
echo "<td>".device_info($disk,true)."</td>";
echo "<td>".device_desc($disk)."</td>";
echo "<td>*</td>";
echo "<td><span class='diskio'>".my_diskio($data[0])."</span><span class='number'>".my_number($disk['numReads'])."</span></td>";
@@ -322,7 +330,7 @@ case 'open':
$disk['color'] = read_disk($dev,'color');
$disk['temp'] = read_disk($dev,'temp');
echo "<tr>";
echo "<td>".device_info($disk)."</td>";
echo "<td>".device_info($disk,true)."</td>";
echo "<td>".device_desc($disk)."</td>";
echo "<td>".my_temp($disk['temp'])."</td>";
echo "<td><span class='diskio'>".my_diskio($data[0])."</span><span class='number'>".my_number($data[2])."</span></td>";

View File

@@ -71,8 +71,14 @@ foreach ($disks as $name => $disk) {
case 'green-on': $help = 'All files protected'; break;
case 'yellow-on': $help = 'All files unprotected'; break;
}
switch ($disk['luksState']) {
case 0: $luks = ""; break;
case 1: $luks = "<i class='padlock green-text fa fa-lock' title='All files in share encrypted'></i>"; break;
case 2: $luks = "<i class='padlock red-text fa fa-unlock-alt' title='Some files in share unencrypted'></i>"; break;
default: $luks = ""; break;
}
echo "<tr>";
echo "<td><a class='info nohand' onclick='return false'><img src='$ball' class='icon'><span style='left:18px'>$help</span></a><a href='$path/Disk?name=$name' onclick=\"$.cookie('one','tab1',{path:'/'})\">$name</a></td>";
echo "<td><a class='info nohand' onclick='return false'><img src='$ball' class='icon'><span style='left:18px'>$help</span></a><a href='$path/Disk?name=$name' onclick=\"$.cookie('one','tab1',{path:'/'})\">$name</a>$luks</td>";
echo "<td>{$disk['comment']}</td>";
echo "<td>".disk_share_settings($var['shareSMBEnabled'], $sec[$name])."</td>";
echo "<td>".disk_share_settings($var['shareNFSEnabled'], $sec_nfs[$name])."</td>";

View File

@@ -0,0 +1,27 @@
<?PHP
/* Copyright 2005-2017, Lime Technology
* Copyright 2012-2017, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$var = parse_ini_file('/var/local/emhttp/var.ini');
$luks = $var['luksKeyfile'];
$text = $_POST['text'] ?? '';
$file = $_POST['file'] ?? '';
if ($text) {
file_put_contents($luks, $text);
} elseif ($file) {
file_put_contents($luks, $file);
} else {
@unlink($luks);
}
$save = false;
?>

View File

@@ -75,8 +75,14 @@ foreach ($shares as $name => $share) {
case 'green-on': $help = 'All files protected'; break;
case 'yellow-on': $help = 'Some or all files unprotected'; break;
}
switch ($share['luksStatus']) {
case 0: $luks = ""; break;
case 1: $luks = "<i class='padlock green-text fa fa-lock' title='All files in share encrypted'></i>"; break;
case 2: $luks = "<i class='padlock red-text fa fa-unlock-alt' title='Some files in share unencrypted'></i>"; break;
default: $luks = ""; break;
}
echo "<tr>";
echo "<td><a class='info nohand' onclick='return false'><img src='$ball' class='icon'><span style='left:18px'>$help</span></a><a href='$path/Share?name=".urlencode($name)."' onclick=\"$.cookie('one','tab1',{path:'/'})\">$name</a></td>";
echo "<td><a class='info nohand' onclick='return false'><img src='$ball' class='icon'><span style='left:18px'>$help</span></a><a href='$path/Share?name=".urlencode($name)."' onclick=\"$.cookie('one','tab1',{path:'/'})\">$name</a>$luks</td>";
echo "<td>{$share['comment']}</td>";
echo "<td>".user_share_settings($var['shareSMBEnabled'], $sec[$name])."</td>";
echo "<td>".user_share_settings($var['shareNFSEnabled'], $sec_nfs[$name])."</td>";

View File

@@ -0,0 +1,37 @@
<?PHP
/* Copyright 2005-2017, Lime Technology
* Copyright 2012-2017, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$index = $_GET['index'];
$tests = explode(',',$_GET['test']);
if ($index < count($tests)) {
$test = $tests[$index];
list($name,$size) = explode(':',$test);
if (!$size) {
if ($index>0) $test .= '|tail -1';
echo shell_exec("/usr/sbin/cryptsetup benchmark -h $test");
} else {
if ($index>5) $size .= '|tail -1';
echo preg_replace('/^# Tests.*\n/',"\n",shell_exec("/usr/sbin/cryptsetup benchmark -c $name -s $size"));
}
} else {
$bm = popen('/usr/sbin/cryptsetup --help','r');
while (!feof($bm)) {
$text = fgets($bm);
if (strpos($text,'Default PBKDF2 iteration time for LUKS')!==false) echo "\n$text";
elseif (strpos($text,'Default compiled-in device cipher parameters')!==false) echo "\n$text";
elseif (strpos($text,'LUKS1:')!==false) echo str_replace("\t"," ",$text);
}
pclose($bm);
echo "<div style='text-align:center'><input type='button' value='Done' onclick='top.Shadowbox.close()'></div>";
}
?>

View File

@@ -19,12 +19,12 @@ pre ul{margin:0;padding-top:0;padding-bottom:0;padding-left:28px}
pre li{margin:0;padding-top:0;padding-bottom:0;padding-left:18px}
big{font-size:15px;font-weight:bold;text-transform:uppercase}
hr{border-color:#EDEAEF}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],textarea,.textarea{font-family:arimo;font-size:13px;background:transparent;border:1px solid #606E7F;padding:5px 10px;min-height:20px;line-height:20px;outline:none;width:304px;margin:0 20px 0 0;box-shadow:none;color:#606E7F}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],input[type=file],textarea,.textarea{font-family:arimo;font-size:13px;background:transparent;border:1px solid #606E7F;padding:5px 10px;min-height:20px;line-height:20px;outline:none;width:304px;margin:0 20px 0 0;box-shadow:none;color:#606E7F}
input[type=button],input[type=reset],input[type=submit],button,a.button{font-family:arimo;font-size:13px;border:1px solid #9F9180;border-radius:5px;margin:10px 20px 10px 0;padding:8px 12px;cursor:pointer;outline:none;color:#9F9180;background:#EDEAEF}
input[type=checkbox]{vertical-align:middle;margin-right:6px}
input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none}
input[type=number]{-moz-appearance:textfield}
input:focus[type=text],input:focus[type=password],input:focus[type=number],input:focus[type=url],input:focus[type=email],textarea:focus{background:#EDEAEF;border-color:#0072C6}
input:focus[type=text],input:focus[type=password],input:focus[type=number],input:focus[type=url],input:focus[type=email],input:focus[type=file],textarea:focus{background:#EDEAEF;border-color:#0072C6}
input:hover[type=button],input:hover[type=reset],input:hover[type=submit],button:hover,a.button:hover{border-color:#0072C6;color:#4F4F4F}
input:active[type=button],input:active[type=reset],input:active[type=submit],button:active{border-color:#0072C6;box-shadow:none}
input[disabled],button[disabled],input:hover[type=button][disabled],input:hover[type=reset][disabled],input:hover[type=submit][disabled],button:hover[disabled],input:active[type=button][disabled],input:active[type=reset][disabled],input:active[type=submit][disabled],button:active[disabled],textarea[disabled]{color:#808080;border-color:#808080;background:#C7C5CB;opacity:0.5;cursor:default}
@@ -68,9 +68,9 @@ form+p{display:none}
#nav-item a[href='/Apps']:before{content:'\f0db'}
#nav-item a[href='/Stats']:before{content:'\f1fe'}
#nav-item a[href='/Tools']:before{content:'\f0ad'}
#nav-item.active,#nav-item.active a{color:#5D6833;background:#ABC056;font-size:18px}
#nav-item.HelpButton.active:hover{background:#ABC056;font-size:0}
#nav-item.HelpButton.active{background:#121510}
#nav-item.active,#nav-item.active a{color:#5D6833;background:#ABC056}
#nav-item.HelpButton.active:hover{background:#ABC056;font-size:18px}
#nav-item.HelpButton.active{background:#121510;font-size:0}
#nav-item.HelpButton a:before{content:'\f059'}
#nav-item.FeedbackButton a:before{content:'\f075'}
#nav-item.InfoButton a:before{content:'\f05a'}
@@ -230,6 +230,7 @@ span.three{margin-left:-20px}
span.tub{margin-right:8px;font-size:24px;cursor:pointer}
span.score{font-size:11px;color:#FFFFFF;position:absolute}
span#dropbox{background:none;line-height:60px;margin-right:20px}
i.padlock{margin-left:8px;cursor:help}
img.icon{margin:-3px 4px 0 0}
img.list{width:auto;max-width:48px;height:48px}
div.content{position:absolute;top:0;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both}

View File

@@ -16,12 +16,12 @@ a.nohand{cursor:default}
i.spacing{margin-left:-6px}
i.icon{margin-right:4px}
hr{border-color:rgba(255,255,255,0.25)}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],textarea,.textarea{font-family:arimo;font-size:12px;color:#808080;background-color:#000000;border:1px solid #404040;border-radius:4px;padding:2px 8px;min-height:20px;line-height:20px;outline:none;width:301px;margin:0 10px 0 0;box-shadow:inset 1px 1px 5px #404040}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],input[type=file],textarea,.textarea{font-family:arimo;font-size:12px;color:#808080;background-color:#000000;border:1px solid #404040;border-radius:4px;padding:2px 8px;min-height:20px;line-height:20px;outline:none;width:301px;margin:0 10px 0 0;box-shadow:inset 1px 1px 5px #404040}
input[type=button],input[type=reset],input[type=submit],button,a.button{font-family:arimo;font-size:12px;border:1px solid #303030;border-radius:6px;margin:7px 14px 0 0;padding:8px 12px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;color:#808080;background:-webkit-radial-gradient(#505050,#181818);background:linear-gradient(#505050,#181818)}
input[type=checkbox]{vertical-align:middle;margin-right:6px}
input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance: none}
input[type=number]{-moz-appearance:textfield}
input:focus[type=text],input:focus[type=password],input:focus[type=number],input:focus[type=url],input:focus[type=email],textarea:focus{background:#101010}
input:focus[type=text],input:focus[type=password],input:focus[type=number],input:focus[type=url],input:focus[type=email],input:focus[type=file],textarea:focus{background:#101010}
input:hover[type=button],input:hover[type=reset],input:hover[type=submit],button:hover,a.button:hover{border-color:#6AB034;color:#FFFFFF;background:-webkit-radial-gradient(#5E9E2E,#8FD956);background:linear-gradient(#5E9E2E,#8FD956)}
input:active[type=button],input:active[type=reset],input:active[type=submit],button:active{border-color:#6AB034;box-shadow:inset 0 0 8px 4px #548C29,0 1px 0 0 #101010}
input[disabled],button[disabled],input:hover[type=button][disabled],input:hover[type=reset][disabled],input:hover[type=submit][disabled],button:hover[disabled],input:active[type=button][disabled],input:active[type=reset][disabled],input:active[type=submit][disabled],button:active[disabled],textarea[disabled]{color:#505050;border-color:#181818;background:linear-gradient(#202020,#101010);background:-webkit-radial-gradient(#202020,#101010);cursor:default}
@@ -211,6 +211,7 @@ span.two{margin-left:-17px}
span.three{margin-left:-20px}
span.tub{margin-right:8px;font-size:24px;cursor:pointer}
span.score{font-size:11px;color:#F0F0F0;position:absolute}
i.padlock{margin-left:8px;cursor:help}
img.icon{margin:-3px 4px 0 0}
img.list{width:auto;max-width:48px;height:48px}
div.content{position:absolute;top:45px;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both}

View File

@@ -19,12 +19,12 @@ pre ul{margin:0;padding-top:0;padding-bottom:0;padding-left:28px}
pre li{margin:0;padding-top:0;padding-bottom:0;padding-left:18px}
big{font-size:15px;font-weight:bold;text-transform:uppercase}
hr{border-color:#121510}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],textarea,.textarea{font-family:arimo;font-size:13px;background:transparent;border:1px solid #606E7F;padding:5px 10px;min-height:20px;line-height:20px;outline:none;width:304px;margin:0 20px 0 0;box-shadow:none;color:#606E7F}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],input[type=file],textarea,.textarea{font-family:arimo;font-size:13px;background:transparent;border:1px solid #606E7F;padding:5px 10px;min-height:20px;line-height:20px;outline:none;width:304px;margin:0 20px 0 0;box-shadow:none;color:#606E7F}
input[type=button],input[type=reset],input[type=submit],button,a.button{font-family:arimo;font-size:13px;border:1px solid #606E7F;border-radius:5px;margin:10px 20px 10px 0;padding:8px 12px;cursor:pointer;outline:none;color:#606E7F;background:#121510}
input[type=checkbox]{vertical-align:middle;margin-right:6px}
input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none}
input[type=number]{-moz-appearance:textfield}
input:focus[type=text],input:focus[type=password],input:focus[type=number],input:focus[type=url],input:focus[type=email],textarea:focus{background:#121510;border-color:#0072C6}
input:focus[type=text],input:focus[type=password],input:focus[type=number],input:focus[type=url],input:focus[type=file],input:focus[type=email],textarea:focus{background:#121510;border-color:#0072C6}
input:hover[type=button],input:hover[type=reset],input:hover[type=submit],button:hover,a.button:hover{border-color:#0072C6;color:#B0B0B0}
input:active[type=button],input:active[type=reset],input:active[type=submit],button:active{border-color:#0072C6;box-shadow:none}
input[disabled],button[disabled],input:hover[type=button][disabled],input:hover[type=reset][disabled],input:hover[type=submit][disabled],button:hover[disabled],input:active[type=button][disabled],input:active[type=reset][disabled],input:active[type=submit][disabled],button:active[disabled],textarea[disabled]{color:#808080;border-color:#808080;background:#383A34;opacity:0.3;cursor:default}
@@ -230,6 +230,7 @@ span.three{margin-left:-20px}
span.tub{margin-right:8px;font-size:24px;cursor:pointer}
span.score{font-size:11px;color:#FFFFFF;position:absolute}
span#dropbox{background:none;line-height:60px;margin-right:20px}
i.padlock{margin-left:8px;cursor:help}
img.icon{margin:-3px 4px 0 0}
img.list{width:auto;max-width:48px;height:48px}
div.content{position:absolute;top:0;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both}

View File

@@ -16,12 +16,12 @@ a.nohand{cursor:default}
i.spacing{margin-left:-6px}
i.icon{margin-right:4px}
hr{border-color:rgba(255,255,255,0.25)}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],textarea,.textarea{font-family:arimo;font-size:12px;color:#303030;background-color:#FFFFFF;border:1px solid #E0E0E0;border-radius:4px;padding:2px 8px;min-height:20px;line-height:20px;outline:none;width:301px;margin:0 10px 0 0;box-shadow:inset 1px 1px 5px #F0F0F0}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],input[type=file],textarea,.textarea{font-family:arimo;font-size:12px;color:#303030;background-color:#FFFFFF;border:1px solid #E0E0E0;border-radius:4px;padding:2px 8px;min-height:20px;line-height:20px;outline:none;width:301px;margin:0 10px 0 0;box-shadow:inset 1px 1px 5px #F0F0F0}
input[type=button],input[type=reset],input[type=submit],button,a.button{font-family:arimo;font-size:12px;border:1px solid #E8E8E8;border-radius:6px;margin:7px 14px 0 0;padding:8px 12px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;color:#303030;background:-webkit-radial-gradient(#F0F0F0,#C8C8C8);background:linear-gradient(#F0F0F0,#C8C8C8)}
input[type=checkbox]{vertical-align:middle;margin-right:6px}
input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance: none}
input[type=number]{-moz-appearance:textfield}
input:focus[type=text],input:focus[type=password],input:focus[type=number],input:focus[type=url],input:focus[type=email],textarea:focus{background:#F8F8F8}
input:focus[type=text],input:focus[type=password],input:focus[type=number],input:focus[type=url],input:focus[type=email],input:focus[type=file],textarea:focus{background:#F8F8F8}
input:hover[type=button],input:hover[type=reset],input:hover[type=submit],button:hover,a.button:hover{border-color:#6AB034;color:#FFFFFF;background:-webkit-radial-gradient(#5E9E2E,#8FD956);background:linear-gradient(#5E9E2E,#8FD956)}
input:active[type=button],input:active[type=reset],input:active[type=submit],button:active{border-color:#6AB034;box-shadow:inset 0 0 8px 4px #548C29,0 1px 0 0 #E0E0E0}
input[disabled],button[disabled],input:hover[type=button][disabled],input:hover[type=reset][disabled],input:hover[type=submit][disabled],button:hover[disabled],input:active[type=button][disabled],input:active[type=reset][disabled],input:active[type=submit][disabled],button:active[disabled],textarea[disabled]{color:#808080;border-color:#F0F0F0;background:linear-gradient(#F0F0F0,#F8F8F8);background:-webkit-radial-gradient(#F0F0F0,#F8F8F8);cursor:default}
@@ -211,6 +211,7 @@ span.two{margin-left:-17px}
span.three{margin-left:-20px}
span.tub{margin-right:8px;font-size:24px;cursor:pointer}
span.score{font-size:11px;color:#F0F0F0;position:absolute}
i.padlock{margin-left:8px;cursor:help}
img.icon{margin:-3px 4px 0 0}
img.list{width:auto;max-width:48px;height:48px}
div.content{position:absolute;top:45px;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both}