xss hardening

This commit is contained in:
Tom Mortensen
2025-01-22 21:22:32 -08:00
parent f8e1d85681
commit b3e355b29b
33 changed files with 190 additions and 124 deletions

View File

@@ -142,12 +142,12 @@ _(Enable container table readmore-js)_:
:docker_readmore_help:
_(Docker Stop Timeout)_ (_(seconds)_):
: <input class='narrow' id="DOCKER_TIMEOUT" type="number" name="DOCKER_TIMEOUT" min='1' value="<?=_var($dockercfg,'DOCKER_TIMEOUT')?>">
: <input class='narrow' id="DOCKER_TIMEOUT" type="number" name="DOCKER_TIMEOUT" min='1' value="<?=htmlspecialchars(_var($dockercfg,'DOCKER_TIMEOUT'))?>">
:docker_timeout_help:
_(Docker PID Limit)_:
: <input class='narrow' id="DOCKER_PID_LIMIT" type="number" name="DOCKER_PID_LIMIT" min='1' value="<?=_var($dockercfg,'DOCKER_PID_LIMIT')?>" placeholder="2048">
: <input class='narrow' id="DOCKER_PID_LIMIT" type="number" name="DOCKER_PID_LIMIT" min='1' value="<?=htmlspecialchars(_var($dockercfg,'DOCKER_PID_LIMIT'))?>" placeholder="2048">
:docker_pid_limit_help:
@@ -164,15 +164,15 @@ _(Docker data-root)_:
<div markdown="1" id="vdisk_file" style="display:none">
_(Docker vDisk size)_:
: <input id="DOCKER_IMAGE_SIZE" type="number" name="DOCKER_IMAGE_SIZE" value="<?=_var($dockercfg,'DOCKER_IMAGE_SIZE')?>" class="narrow" required>GB<span id="SIZE_ERROR" class="errortext"></span>
: <input id="DOCKER_IMAGE_SIZE" type="number" name="DOCKER_IMAGE_SIZE" value="<?=htmlspecialchars(_var($dockercfg,'DOCKER_IMAGE_SIZE'))?>" class="narrow" required>GB<span id="SIZE_ERROR" class="errortext"></span>
:docker_vdisk_size_help:
_(Docker vDisk location)_:
: <input type="text" id="DOCKER_IMAGE_FILE1" name="DOCKER_IMAGE_FILE1" autocomplete="off" spellcheck="false" value="<?=_var($dockercfg,'DOCKER_IMAGE_FILE')?>" placeholder="_(e.g.)_ /mnt/user/system/docker.img" data-pickcloseonfile="true" data-pickfilter="img" data-pickroot="/mnt" data-pickfolders="true" disabled required pattern="^[^\\]*(docker-xfs\.img|docker\.img)$">
: <input type="text" id="DOCKER_IMAGE_FILE1" name="DOCKER_IMAGE_FILE1" autocomplete="off" spellcheck="false" value="<?=htmlspecialchars(_var($dockercfg,'DOCKER_IMAGE_FILE'))?>" placeholder="_(e.g.)_ /mnt/user/system/docker.img" data-pickcloseonfile="true" data-pickfilter="img" data-pickroot="/mnt" data-pickfolders="true" disabled required pattern="^[^\\]*(docker-xfs\.img|docker\.img)$">
<span class="deleteLabel"><label><input type="checkbox" class="deleteCheckbox"> _(Delete vDisk file)_</label></span>
<?if ($var['fsState'] != "Started"):?><span><i class="fa fa-warning icon warning"></i> _(Modify with caution: unable to validate path until Array is Started)_</span>
<?elseif (!is_dir(dirname(_var($dockercfg,'DOCKER_IMAGE_FILE')))):?><span class="nonexist"><i class="fa fa-warning icon warning"></i> _(Path does not exist)_</span>
<?elseif (!is_dir(dirname(htmlspecialchars(_var($dockercfg,'DOCKER_IMAGE_FILE'))))):?><span class="nonexist"><i class="fa fa-warning icon warning"></i> _(Path does not exist)_</span>
<?endif;?><span id="IMAGE_ERROR1" class="errortext"></span>
:docker_vdisk_location_help:
@@ -180,7 +180,7 @@ _(Docker vDisk location)_:
</div>
<div markdown="1" id="vdisk_dir" style="display:none">
_(Docker directory)_:
: <input type="text" id="DOCKER_IMAGE_FILE2" name="DOCKER_IMAGE_FILE2" autocomplete="off" spellcheck="false" value="<?=_var($dockercfg,'DOCKER_IMAGE_FILE')?>" placeholder="_(e.g.)_ /mnt/user/system/docker" data-pickcloseonfile="true" data-pickfilter="HIDE_FILES_FILTER" data-pickroot="/mnt" data-pickfolders="true" disabled required pattern="^[^\\]*/$">
: <input type="text" id="DOCKER_IMAGE_FILE2" name="DOCKER_IMAGE_FILE2" autocomplete="off" spellcheck="false" value="<?=htmlspecialchars(_var($dockercfg,'DOCKER_IMAGE_FILE'))?>" placeholder="_(e.g.)_ /mnt/user/system/docker" data-pickcloseonfile="true" data-pickfilter="HIDE_FILES_FILTER" data-pickroot="/mnt" data-pickfolders="true" disabled required pattern="^[^\\]*/$">
<span class="deleteLabel"><label><input type="checkbox" class="deleteCheckbox"> _(Delete directory)_</label></span>
<?if ($var['fsState'] != "Started"):?><span><i class="fa fa-warning icon warning"></i> _(Modify with caution: unable to validate path until Array is Started)_</span>
<?elseif (!is_dir(dirname(_var($dockercfg,'DOCKER_IMAGE_FILE')))):?><span class="nonexist"><i class="fa fa-warning icon warning"></i> _(Path does not exist)_</span>
@@ -207,7 +207,7 @@ _(Docker storage driver)_:
</div>
_(Default appdata storage location)_:
: <input type="text" id="DOCKER_APP_CONFIG_PATH" name="DOCKER_APP_CONFIG_PATH" autocomplete="off" spellcheck="false" value="<?=_var($dockercfg,'DOCKER_APP_CONFIG_PATH')?>" placeholder="_(e.g.)_ /mnt/user/appdata/" data-pickfilter="HIDE_FILES_FILTER" data-pickroot="/mnt" data-pickfolders="true" pattern="^[^\\]*/$">
: <input type="text" id="DOCKER_APP_CONFIG_PATH" name="DOCKER_APP_CONFIG_PATH" autocomplete="off" spellcheck="false" value="<?=htmlspecialchars(_var($dockercfg,'DOCKER_APP_CONFIG_PATH'))?>" placeholder="_(e.g.)_ /mnt/user/appdata/" data-pickfilter="HIDE_FILES_FILTER" data-pickroot="/mnt" data-pickfolders="true" pattern="^[^\\]*/$">
<?if ($var['fsState'] != "Started"):?>
<span><i class="fa fa-warning icon warning"></i> _(Modify with caution: unable to validate path until Array is Started)_</span>
<?elseif (!is_dir(_var($dockercfg,'DOCKER_APP_CONFIG_PATH'))):?>
@@ -354,7 +354,7 @@ _(IPv4 custom network on interface)_ <?=$network?> (_(optional)_):
<select id="DOCKER_CUSTOM_<?=$port?>_mask" name="DOCKER_MASK_<?=$port?>" class="mask"<?=$disabled?>>
<?for ($m=16; $m<=30; $m++) echo mk_option($mask?:24,$m,$m)?></select>
</span>
<span class="<?=$gw4class?>">**_(Gateway)_:** <input type="text" id="DOCKER_CUSTOM_<?=$port?>_gw" name="DOCKER_GATEWAY_<?=$port?>" class="ip4" value="<?=_var($dockercfg,"DOCKER_GATEWAY_$port")?>" title="_(IPv4 address A.B.C.D)_"<?=$disabled?>></span>
<span class="<?=$gw4class?>">**_(Gateway)_:** <input type="text" id="DOCKER_CUSTOM_<?=$port?>_gw" name="DOCKER_GATEWAY_<?=$port?>" class="ip4" value="<?=htmlspecialchars(_var($dockercfg,"DOCKER_GATEWAY_$port"))?>" title="_(IPv4 address A.B.C.D)_"<?=$disabled?>></span>
<input type="checkbox" id="DOCKER_CUSTOM_<?=$port?>_dhcp" onchange="customDHCP(this.id,4)"<?=$subnet?'checked':''?><?=$dhcpDisabled?>>
**_(DHCP pool)_:** <input type="text" id="DOCKER_CUSTOM_<?=$port?>_pool" name="DOCKER_RANGE_<?=$port?>" class="ip4" value="<?=$range?>" title="_(IPv4 address A.B.C.D)_"<?=$disabled?>>/
<select id="DOCKER_CUSTOM_<?=$port?>_size" name="DOCKER_SIZE_<?=$port?>" class="mask" onchange="changeHosts(this.id,this.value)"<?=$disabled?>>
@@ -421,7 +421,7 @@ _(IPv6 custom network on interface)_ <?=$network?> (_(optional)_):
<span class="ip6">**_(Subnet)_:**<input type="text" id="DOCKER_CUSTOM6_<?=$port?>_net" name="DOCKER_SUBNET6_<?=$port?>" class="ip6" value="<?=$subnet6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_"<?=$disabled?>>/
<select id="DOCKER_CUSTOM6_<?=$port?>_mask" name="DOCKER_MASK6_<?=$port?>" class="mask"<?=$disabled?>>
<?for ($m=64; $m<=120; $m+=8) echo mk_option($mask6?:64,$m,$m)?></select></span>
<span class="gw6">**_(Gateway)_:**<input type="text" id="DOCKER_CUSTOM6_<?=$port?>_gw" name="DOCKER_GATEWAY6_<?=$port?>" class="gw6" value="<?=_var($dockercfg,"DOCKER_GATEWAY6_$port")?>" title="_(IPv6 address nnnn:xxxx::yyyy)_"<?=$disabled?>></span>
<span class="gw6">**_(Gateway)_:**<input type="text" id="DOCKER_CUSTOM6_<?=$port?>_gw" name="DOCKER_GATEWAY6_<?=$port?>" class="gw6" value="<?=htmlspecialchars(_var($dockercfg,"DOCKER_GATEWAY6_$port"))?>" title="_(IPv6 address nnnn:xxxx::yyyy)_"<?=$disabled?>></span>
<input type="checkbox" id="DOCKER_CUSTOM6_<?=$port?>_dhcp" onchange="customDHCP(this.id,6)"<?=$subnet6?'checked':''?><?=$dhcpDisabled?>>
**_(DHCP pool)_:**<input type="text" id="DOCKER_CUSTOM6_<?=$port?>_pool" name="DOCKER_RANGE6_<?=$port?>" class="ip6" value="<?=$range6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_"<?=$disabled?>>/
<select id="DOCKER_CUSTOM6_<?=$port?>_size" name="DOCKER_SIZE6_<?=$port?>" class="mask"<?=$disabled?>>
@@ -444,21 +444,21 @@ _(Docker version)_:
<?if (_var($dockercfg,'DOCKER_IMAGE_TYPE')!='folder'):?>
_(Docker vDisk location)_:
: <?=_var($dockercfg,'DOCKER_IMAGE_FILE')?>
: <?=htmlspecialchars(_var($dockercfg,'DOCKER_IMAGE_FILE'))?>
<?else:?>
_(Docker directory)_:
: <?=_var($dockercfg,'DOCKER_IMAGE_FILE')?>
: <?=htmlspecialchars(_var($dockercfg,'DOCKER_IMAGE_FILE'))?>
<?endif;?>
:docker_vdisk_location_active_help:
_(Docker storage driver)_:
: <?=_var($dockercfg,'DOCKER_BACKINGFS')?>
: <?=htmlspecialchars(_var($dockercfg,'DOCKER_BACKINGFS'))?>
:docker_storage_driver_active_help:
_(Default appdata storage location)_:
: <?=_var($dockercfg,'DOCKER_APP_CONFIG_PATH')?>
: <?=htmlspecialchars(_var($dockercfg,'DOCKER_APP_CONFIG_PATH'))?>
:docker_appdata_location_active_help:

View File

@@ -307,11 +307,9 @@ function xmlSecurity(&$template) {
xmlSecurity($element);
} else {
if (is_string($element)) {
$tempElement = htmlspecialchars_decode($element);
$tempElement = str_replace("[","<",$tempElement);
$tempElement = str_replace("]",">",$tempElement);
if (preg_match('#<script(.*?)>(.*?)</script>#is',$tempElement) || preg_match('#<iframe(.*?)>(.*?)</iframe>#is',$tempElement) || (stripos($tempElement,"<link") !== false) ) {
$element = "REMOVED";
$tempElement = htmlspecialchars_decode($element??"");
if ( trim(strip_tags($tempElement)) !== trim($tempElement) ) {
$element = str_replace(["<",">"],["",""],$tempElement);
}
}
}

View File

@@ -201,7 +201,7 @@ switch ($theme) {
<table id='db-box1' class='dashboard'>
<tbody class='system'>
<tr><td><i class='icon-performance f32'></i><div class='section'><?=_var($var,'NAME')?><br>
<span><?=_var($var,'COMMENT')?></span><span id="current_time_" class="switch head_time"></span><br></div>
<span><?=htmlspecialchars(_var($var,'COMMENT'))?></span><span id="current_time_" class="switch head_time"></span><br></div>
<a href='/Dashboard/Settings/Identification'><i class='fa fa-fw fa-cog control' title="_(Go to identification settings)_"></i></a><i class='fa fa-fw fa-wrench control tile' onclick='contentMgmt()' title="_(Tile Management)_"></i>
<span class='ctrl'>
<?if ($parity||$mover||$btrfs):?>
@@ -216,7 +216,7 @@ switch ($theme) {
<tr><td>
<div class='leftside'>
<a href="/Settings/DateTime" class="hand none"><span id="current_time"></span></a><br><span id="current_date"></span><br><br>
<span class='header'><i class='indent fa fa-file-text-o'></i>_(Model)_</span><br><i class='indent'></i><?=_var($var,'SYS_MODEL')?:'---'?><br><br>
<span class='header'><i class='indent fa fa-file-text-o'></i>_(Model)_</span><br><i class='indent'></i><?=htmlspecialchars(_var($var,'SYS_MODEL'))?:'---'?><br><br>
<span class='header'><i class='indent fa fa-id-badge'></i>_(Registration)_</span><br><i class='indent'></i>Unraid OS <b><em><?=_var($var,'regTy')?></em></b><br><br>
<span class='header'><i class='indent fa fa-clock-o'></i>_(Uptime)_</span><br><i class='indent'></i><span class='uptime'></span>
</div>
@@ -464,10 +464,10 @@ if (_var($var,'shareSMBEnabled')=='yes') {
$list = "<a href=\"/Dashboard/Shares/Share?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
if ($share['luksStatus']>0) $list = str_replace('blue-text','green-text',$list);
elseif ($share['useCache']=='only') $list = str_replace('blue-text','orange-text',$list);
$comment = $share['comment'] ?: '&nbsp;';
$comment = $share['comment'] ?: '-';
$security = export_settings(_var($var,'shareSMBEnabled'), $sec[$name]);
$last = $name==array_key_last($shares) ? ' last' : '';
echo "<tr class='smb share share1{$last}'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>$comment</span><span class='w18'>$security</span><span id='share",$i++,"'>0</span></td></tr>";
echo "<tr class='smb share share1{$last}'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>".htmlspecialchars($comment)."</span><span class='w18'>$security</span><span id='share",$i++,"'>0</span></td></tr>";
}
if (!count($shares)) echo "<tr class='smb share share1'><td class='none'>"._("No shares present")."</td></tr>";
}
@@ -476,10 +476,10 @@ if (_var($var,'shareNFSEnabled')=='yes') {
$list = "<a href=\"/Dashboard/Shares/Share?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
if ($share['luksStatus']>0) $list = str_replace('blue-text','green-text',$list);
elseif ($share['useCache']=='only') $list = str_replace('blue-text','orange-text',$list);
$comment = $share['comment'] ?: '&nbsp;';
$comment = $share['comment'] ?: '-';
$security = export_settings(_var($var,'shareNFSEnabled'), $sec_nfs[$name]);
$last = $name==array_key_last($shares) ? ' last' : '';
echo "<tr class='nfs share share3{$last}'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>$comment</span><span class='w18'>$security</span><span>-</span></td></tr>";
echo "<tr class='nfs share share3{$last}'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>".htmlspecialchars($comment)."</span><span class='w18'>$security</span><span>-</span></td></tr>";
}
if (!count($shares)) echo "<tr class='nfs share share3'><td class='none'>"._("No shares present")."</td></tr>";
}
@@ -488,8 +488,8 @@ if (!$group) {
$list = "<a href=\"/Dashboard/Shares/Share?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
if ($share['luksStatus']>0) $list = str_replace('blue-text','green-text',$list);
elseif ($share['useCache']=='only') $list = str_replace('blue-text','orange-text',$list);
$comment = $share['comment'] ?: '&nbsp;';
echo "<tr class='share'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>$comment</span><span class='w18'>-</span><span>-</span></td></tr>";
$comment = $share['comment'] ?: '-';
echo "<tr class='share'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>".htmlspecialchars($comment)."</span><span class='w18'>-</span><span>-</span></td></tr>";
}
if (!count($shares)) echo "<tr class='share'><td class='none'>"._("No shares present")."</td></tr>";
}
@@ -519,7 +519,7 @@ if (_var($var,'shareSMBEnabled')=='yes') {
foreach ($users as $user) {
$name = $user['name'];
$list = "<a href=\"/Dashboard/Users/UserEdit?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
$desc = $user['desc'] ?: '&nbsp;';
$desc = $user['desc'] ?: '-';
if ($name=='root') {
$write = $read = '-';
} else {
@@ -544,27 +544,27 @@ if (_var($var,'shareSMBEnabled')=='yes') {
}
if ($user['passwd']!='yes') $list = str_replace('blue-text','orange-text',$list);
$last = $name==array_key_last($users) ? ' last' : '';
echo "<tr class='smb user user1{$last}'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>$desc</span><span class='w18'>$write</span><span>$read</span></td></tr>";
echo "<tr class='smb user user1{$last}'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>".htmlspecialchars($desc)."</span><span class='w18'>$write</span><span>$read</span></td></tr>";
}
}
if (_var($var,'shareNFSEnabled')=='yes') {
foreach ($users as $user) {
$name = $user['name'];
$list = "<a href=\"/Dashboard/Users/UserEdit?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
$desc = $user['desc'] ?: '&nbsp;';
$desc = $user['desc'] ?: '-';
$write = '-'; $read = '-';
if ($user['passwd']!='yes') $list = str_replace('blue-text','orange-text',$list);
$last = $name==array_key_last($users) ? ' last' : '';
echo "<tr class='nfs user user3{$last}'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>$desc</span><span class='w18'>$write</span><span>$read</span></td></tr>";
echo "<tr class='nfs user user3{$last}'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>".htmlspecialchars($desc)."</span><span class='w18'>$write</span><span>$read</span></td></tr>";
}
}
if (!$group) {
foreach ($users as $user) {
$name = $user['name'];
$list = "<a href=\"/Dashboard/Users/UserEdit?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
$desc = $user['desc'] ?: '&nbsp;';
$desc = $user['desc'] ?: '-';
if ($user['passwd']!='yes') $list = str_replace('blue-text','orange-text',$list);
echo "<tr class='user'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>$desc</span><span class='w18'>-</span><span>-</span></td></tr>";
echo "<tr class='user'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>".htmlspecialchars($desc)."</span><span class='w18'>-</span><span>-</span></td></tr>";
}
}
?>

View File

@@ -1,7 +1,7 @@
Menu="Device New"
Title="Attributes"
Tag="address-card-o"
Cond="strpos(_var($disks[$name],'status'),'_NP')===false"
Cond="array_key_exists($name, $disks) || array_key_exists($name, $devs)"
---
<?PHP
/* Copyright 2005-2023, Lime Technology

View File

@@ -1,7 +1,7 @@
Menu="Device New"
Title="Capabilities"
Tag="building"
Cond="strpos(_var($disks[$name],'status'),'_NP')===false"
Cond="array_key_exists($name, $disks) || array_key_exists($name, $devs)"
---
<?PHP
/* Copyright 2005-2023, Lime Technology

View File

@@ -1,7 +1,7 @@
Menu="Device New"
Title="Identity"
Tag="user"
Cond="strpos(_var($disks[$name],'status'),'_NP')===false"
Cond="array_key_exists($name, $disks) || array_key_exists($name, $devs)"
---
<?PHP
/* Copyright 2005-2023, Lime Technology

View File

@@ -1,6 +1,7 @@
Menu="Device:1"
Title="$name _(Settings)_"
Tag="hdd-o"
Cond="array_key_exists($name, $disks) || array_key_exists($name, $devs)"
---
<?PHP
/* Copyright 2005-2023, Lime Technology
@@ -622,13 +623,13 @@ function renamePoolPopup() {
});
dialogStyle();
}
function eraseDisk(name) {
function eraseDisk() {
swal({
title:"_(Erase Device Content)_?",
text:"<?=$textErase?><p style='font-weight:bold;color:red;margin:8px 0'>_(Existing content is permanently lost)_</p>",
html:true,
type:'input',
inputPlaceholder:"<?=sprintf(_('To confirm type: %s'),$name)?>",
inputPlaceholder:"<?=sprintf(_('To confirm type: %s'),htmlspecialchars($name))?>",
showCancelButton:true,
closeOnConfirm:false,
confirmButtonText:"_(Proceed)_",
@@ -641,7 +642,7 @@ function eraseDisk(name) {
$('#eraseButton').prop('disabled',true);
$('#removeButton').prop('disabled',true);
$('div.spinner.fixed').show();
$.post("/update.htm",{cmdWipefs:name},function(){
$.post("/update.htm",{cmdWipefs:"<?=$name?>"},function(){
$('div.spinner.fixed').hide();
refresh();
});
@@ -650,13 +651,13 @@ function eraseDisk(name) {
}
});
}
function removePool(name) {
function removePool() {
swal({
title:"_(Remove pool)_?",
text:"<?=$textDelete?>",
html:true,
type:'input',
inputPlaceholder:"<?=sprintf(_('To confirm type: %s'),$name)?>",
inputPlaceholder:"<?=sprintf(_('To confirm type: %s'),htmlspecialchars($name))?>",
showCancelButton:true,
closeOnConfirm:false,
confirmButtonText:"_(Proceed)_",
@@ -669,22 +670,22 @@ function removePool(name) {
$('#eraseButton').prop('disabled',true);
$('#removeButton').prop('disabled',true);
$('div.spinner.fixed').show();
$.post("/update.htm",{changeSlots:"apply",poolName:name,poolSlots:0},function(){
$.post("/update.htm",{changeSlots:"apply",poolName:"<?=$name?>",poolSlots:0},function(){
$('div.spinner.fixed').hide();
refresh();
done();
});
} else {
if (confirm.length) swal({title:"_(Incorrect confirmation)_",text:"_(Please try again)_!",type:'error',html:true,confirmButtonText:"_(Ok)_"});
}
});
}
function upgradeZpool(name) {
function upgradeZpool() {
swal({
title:"_(Upgrade ZFS Pool)_?",
text:"_(This operation cannot be reversed)_. _(After upgrading the volume may not be mountable in previous versions of Unraid)_.<p style='font-weight:bold;color:red;margin:8px 0'>_(The ZFS volume will be upgraded)_</p>",
html:true,
type:'input',
inputPlaceholder:"<?=sprintf(_('To confirm type: %s'),$name)?>",
inputPlaceholder:"<?=sprintf(_('To confirm type: %s'),htmlspecialchars($name))?>",
showCancelButton:true,
closeOnConfirm:false,
confirmButtonText:"_(Proceed)_",
@@ -697,7 +698,7 @@ function upgradeZpool(name) {
$('#eraseButton').prop('disabled',true);
$('#deleteButton').prop('disabled',true);
$('div.spinner.fixed').show();
$.post("/webGui/include/zfs_upgrade.php",{name:name},function(){
$.post("/webGui/include/zfs_upgrade.php",{name:"<?=$name?>"},function(){
$('div.spinner.fixed').hide();
refresh();
});
@@ -711,11 +712,11 @@ function upgradeZpool(name) {
<form markdown="1" method="POST" action="/update.htm" target="progressFrame" onsubmit="setFloor()">
<?if (_var($var,'fsState')=="Stopped" && isPool($name) && !isSubpool($name)):?>
_(Name)_:
: <a onclick="renamePoolPopup()" style="cursor:pointer" title="_(Rename Pool)_"><?=$name?></a>
: <a onclick="renamePoolPopup()" style="cursor:pointer" title="_(Rename Pool)_"><?=htmlspecialchars($name)?></a>
<?else:?>
_(Name)_:
: <?=_(my_disk(native($name)),3)?>
: <?=_(my_disk(native(htmlspecialchars($name))),3)?>
<?endif;?>
<?if (diskStatus('_NP')):?>
@@ -849,13 +850,13 @@ _(Critical disk utilization threshold)_ (%):
<?if (diskType('Parity','Data')):?>
<?if (_var($var,'fsState')=="Stopped" && diskStatus('_NEW')): $erasable=true; endif;?>
<?if (_var($var,'fsState')=="Started" && _var($var,'startMode')!="Normal" && diskType('Data')): $erasable=true; endif;?>
<input type="button" id="eraseButton" value="_(Erase)_" onclick="eraseDisk('<?=$name?>')"<?=$erasable?'':' disabled'?>>
<input type="button" id="eraseButton" value="_(Erase)_" onclick="eraseDisk()"<?=$erasable?'':' disabled'?>>
<?endif;?>
<?if (isPool($name) && isSubpool($name)===false):?>
<?if (_var($var,'fsState')=="Stopped" || (_var($var,'fsState')=="Started" && _var($var,'startMode')!="Normal")): $erasable=true; endif;?>
<input type="button" id="eraseButton" value="_(Erase Pool)_" onclick="eraseDisk('<?=$name?>')"<?=$erasable?'':' disabled'?>>
<input type="button" id="eraseButton" value="_(Erase Pool)_" onclick="eraseDisk()"<?=$erasable?'':' disabled'?>>
<?if (_var($var,'fsState')=="Stopped"): $removeable=true; endif;?>
<input type="button" id="removeButton" value="_(Remove Pool)_" onclick="removePool('<?=$name?>')"<?=$removeable?'':' disabled'?>>
<input type="button" id="removeButton" value="_(Remove Pool)_" onclick="removePool()"<?=$removeable?'':' disabled'?>>
<?endif;?>
</form>
@@ -1143,7 +1144,7 @@ _(zfs pool status)_:
&nbsp;
: <input type="submit" id="zfs-button" value="<?=$zfs_cmd=='start' ? _('Scrub') : _('Clear')?>">
<?if (! is_upgraded_ZFS_pool($name)):?>
<input type="button" id="upgradeButton" value="_(Upgrade Pool)_" onclick="upgradeZpool('<?=$name?>')">
<input type="button" id="upgradeButton" value="_(Upgrade Pool)_" onclick="upgradeZpool()">
<?endif;?>
:info_zfs_scrub_help:
@@ -1458,7 +1459,7 @@ _(SMART attribute notifications)_:
<input type="hidden" name="changeSlots" value="apply">
<p>_(Caution)_: _(Renaming the pool will change the share storage allocations)_. _(After renaming the pool, check that your shares are assigned to the proper primary and secondary storage locations)_.</p>
_(Name)_:
: <input type="text" name="poolName" maxlength="40" value="<?=$name?>">
: <input type="text" name="poolName" maxlength="40" value="<?=htmlspecialchars($name)?>">
</form>
</div>

View File

@@ -169,12 +169,12 @@ _(Default file system for Array disks)_:
:disk_default_file_system_help:
_(Shutdown time-out)_ (_(seconds)_):
: <input type="text" name="shutdownTimeout" maxlength="10" value="<?=$var['shutdownTimeout']?>" class="narrow" placeholder="90">
: <input type="number" name="shutdownTimeout" maxlength="10" value="<?=$var['shutdownTimeout']?>" class="narrow" placeholder="90">
:disk_shutdown_timeout_help:
_(Tunable (poll_attributes))_:
: <input type="text" name="poll_attributes" maxlength="10" value="<?=$var['poll_attributes']?>" class="narrow" placeholder="<?=$var['poll_attributes_default']?>">
: <input type="number" name="poll_attributes" maxlength="10" value="<?=$var['poll_attributes']?>" class="narrow" placeholder="<?=$var['poll_attributes_default']?>">
:disk_tunable_poll_attributes_help:
@@ -187,7 +187,7 @@ _(Tunable (enable NCQ))_:
:disk_tunable_enable_ncq_help:
_(Tunable (nr_requests))_:
: <input type="text" name="nr_requests" maxlength="10" value="<?=$var['nr_requests']?>" class="narrow" placeholder="<?=_($var['nr_requests_default'])?>">
: <input type="text" name="nr_requests" maxlength="10" value="<?=htmlspecialchars($var['nr_requests'])?>" class="narrow" placeholder="<?=_($var['nr_requests_default'])?>">
:disk_tunable_nr_requests_help:
@@ -203,17 +203,17 @@ _(Tunable (scheduler))_:
:disk_tunable_scheduler_help:
_(Tunable (md_num_stripes))_:
: <input type="text" name="md_num_stripes" maxlength="10" value="<?=$var['md_num_stripes']?>" class="narrow" placeholder="<?=$var['md_num_stripes_default']?>">
: <input type="number" name="md_num_stripes" maxlength="10" value="<?=$var['md_num_stripes']?>" class="narrow" placeholder="<?=$var['md_num_stripes_default']?>">
:disk_tunable_md_num_stripes_help:
_(Tunable (md_queue_limit))_:
: <input type="text" name="md_queue_limit" maxlength="10" value="<?=$var['md_queue_limit']?>" class="narrow" placeholder="<?=$var['md_queue_limit_default']?>">
: <input type="number" name="md_queue_limit" maxlength="10" value="<?=$var['md_queue_limit']?>" class="narrow" placeholder="<?=$var['md_queue_limit_default']?>">
:disk_tunable_md_queue_limit_help:
_(Tunable (md_sync_limit))_:
: <input type="text" name="md_sync_limit" maxlength="10" value="<?=$var['md_sync_limit']?>" class="narrow" placeholder="<?=$var['md_sync_limit_default']?>">
: <input type="number" name="md_sync_limit" maxlength="10" value="<?=$var['md_sync_limit']?>" class="narrow" placeholder="<?=$var['md_sync_limit_default']?>">
:disk_tunable_md_sync_limit_help:
@@ -376,7 +376,7 @@ _(Default SMART controller type)_:
:disk_default_smart_controller_help:
_(Default SMART attribute notifications)_:
: <input type="text" name="smCustom" value="<?=_var($var,'smCustom')?>" class="narrow">_(Custom attributes (use comma to separate numbers))_
: <input type="text" name="smCustom" value="<?=htmlspecialchars(_var($var,'smCustom'))?>" class="narrow">_(Custom attributes (use comma to separate numbers))_
<?for ($x = 0; $x < count($preselect); $x++):?>
&nbsp;

View File

@@ -41,7 +41,7 @@ _(Enable NFS)_:
:nfs_enable_help:
_(Tunable (fuse_remember))_:
: <input type="text" name="fuse_remember" maxlength="10" value="<?=$var['fuse_remember']?>" class="narrow"><?=htmlspecialchars($var['fuse_remember_status']);?>
: <input type="number" name="fuse_remember" maxlength="10" value="<?=$var['fuse_remember']?>" class="narrow"><?=_($var['fuse_remember_status'])?>
:nfs_tunable_fuse_remember_help:

View File

@@ -93,12 +93,12 @@ _(Current listening interfaces)_:
<hr>
_(Include listening interfaces)_:
: <textarea name="include" spellcheck="false" cols="80" rows="<?=substr_count($include_interfaces,"\n")+1?>" maxlength="2048" name="text" style="resize:none;width:200px"><?=$include_interfaces?></textarea>
: <textarea name="include" spellcheck="false" cols="80" rows="<?=substr_count($include_interfaces,"\n")+1?>" maxlength="2048" name="text" style="resize:none;width:200px"><?=htmlspecialchars($include_interfaces)?></textarea>
:eth_network_extra_include_help:
_(Exclude listening interfaces)_:
: <textarea name="exclude" spellcheck="false" cols="80" rows="<?=substr_count($exclude_interfaces,"\n")+1?>" maxlength="2048" name="text" style="resize:none;width:200px"><?=$exclude_interfaces?></textarea>
: <textarea name="exclude" spellcheck="false" cols="80" rows="<?=substr_count($exclude_interfaces,"\n")+1?>" maxlength="2048" name="text" style="resize:none;width:200px"><?=htmlspecialchars($exclude_interfaces)?></textarea>
:eth_network_extra_exclude_help:

View File

@@ -1,7 +1,7 @@
Menu="Device:2 New:2"
Title="Self-Test"
Tag="wrench"
Cond="strpos(_var($disks[$name],'status'),'_NP')===false"
Cond="array_key_exists($name, $disks) || array_key_exists($name, $devs)"
---
<?PHP
/* Copyright 2005-2023, Lime Technology

View File

@@ -22,8 +22,8 @@ if (!empty($name) && !array_key_exists($name, $shares)) {
$width = [123,300];
if ($name == "") {
/* default values when adding new share. */
$share = [
/* default values when adding new share. */
$share = [
"nameOrig" => "",
"name" => "",
"comment" => "",

View File

@@ -34,7 +34,7 @@ function applyCfg() {
if (string === "BIND=") {
string = "";
}
$.get( "/plugins/dynamix/include/update.vfio-pci-cfg.php", { cfg: string } )
$.post( "/plugins/dynamix/include/update.vfio-pci-cfg.php", { cfg: string } )
.done(function(d) {
if (d==1) {
addRebootNotice(message);

View File

@@ -194,15 +194,15 @@ _(Syslinux configuration)_:
$label = ($i) ? array_shift($area):$title;
$start = in_array($menu,$area);
if ($start) unset($area[array_search($menu,$area)]);
?><span id="label-<?=$i?>" class="<?=$start?'array':'system'?>"><?=$label?>
?><span id="label-<?=$i?>" class="<?=$start?'array':'system'?>"><?=htmlspecialchars($label)?>
<?if ($i):?><span style="float:right"><input type="radio" id="input-<?=$i?>" class="menu" <?=$start?'checked':''?> title="_(Set default boot menu)_" onchange="changeMenu(this.form,this.id,true)"></span><?endif;?></span>
<textarea class="menu" id="menu-<?=$i++?>" spellcheck="false" cols="80" rows="<?=count($area)?>" maxlength="2048"><?=implode("\n",$area)?></textarea>
<textarea class="menu" id="menu-<?=$i++?>" spellcheck="false" cols="80" rows="<?=count($area)?>" maxlength="2048"><?=htmlspecialchars(implode("\n",$area))?></textarea>
<?endforeach;?>
</div>
<div markdown="1" class="advanced">
_(Syslinux configuration)_:
: <textarea class="raw" name="raw" spellcheck="false" cols="80" rows="<?=substr_count($current,"\n")+1?>" maxlength="2048"><?=$current?></textarea>
: <textarea class="raw" name="raw" spellcheck="false" cols="80" rows="<?=substr_count($current,"\n")+1?>" maxlength="2048"><?=htmlspecialchars($current)?></textarea>
</div>
_(Server boot mode)_:

View File

@@ -95,7 +95,7 @@ _(Local syslog server)_:
<?=mk_option(_var($syslog,'server_protocol'), "tcp", _("TCP"))?>
<?=mk_option(_var($syslog,'server_protocol'), "both", _("Both"))?>
</select>
<input type="text" name="server_port" class="trim" value="<?=_var($syslog,'server_port')?>" maxlength="5" placeholder="514">
<input type="number" name="server_port" class="trim" value="<?=_var($syslog,'server_port')?>" maxlength="5" placeholder="514" pattern="([0-9]{1,5})">
:syslog_local_server_help:
@@ -155,7 +155,7 @@ _(Local syslog number of files)_:
</div>
_(Remote syslog server)_:
: <span class="span"><input type="text" name="remote_server" class="narrow" value="<?=_var($syslog,'remote_server')?>" maxlength="50" placeholder="_(name or ip address)_"></span>
: <span class="span"><input type="text" name="remote_server" class="narrow" value="<?=htmlspecialchars(_var($syslog,'remote_server'))?>" maxlength="50" placeholder="_(name or ip address)_"></span>
<select name="remote_protocol" class="narrow">
<?=mk_option(_var($syslog,'remote_protocol'), "udp", _("UDP"))?>
<?=mk_option(_var($syslog,'remote_protocol'), "tcp", _("TCP"))?>

View File

@@ -14,12 +14,11 @@ Tag="user"
* all copies or substantial portions of the Software.
*/
?>
<?if (!array_key_exists($name, $users)):?>
<p class="notice"><?=sprintf(_('User %s has been deleted'),htmlspecialchars($name))?>.</p><br>
<input type="button" value="_(Done)_" onClick="done()">
<?return;?>
<?endif;?>
<?
if (!array_key_exists($name, $users)) {
echo "<script>done()</script>";
return;
}
$user = "/boot/config/plugins/dynamix/users/$name.png";
$void = "<img src='/webGui/images/user.png' width='48' height='48' id='image' onclick='$(&quot;#drop&quot;).click()' style='cursor:pointer' title='"._('Click to select PNG file')."'>";
$icon = "<i class='fa fa-trash top' title='"._('Restore default image')."' onclick='restore()'></i>";

View File

@@ -15,19 +15,17 @@ Tag="users"
*/
?>
<?
$submenu = !empty($display['users']) && substr($display['users'],0,5)!='Tasks';
if ($submenu) $path = './Users';
ksort($users);
?>
<div id="title" class="title"><span class="left"><i class="fa fa-bell title"></i>_(Management Access)_</span></div>
<?$img = "/boot/config/plugins/dynamix/users/root.png"?>
<div class="user-list" style="text-align:center"><a class="<?=(!empty($users['root']['desc']) ? 'info' : '')?>" href="<?=$path?>/UserEdit?name=root"><img src="<?=(file_exists($img) ? autov($img) : '/webGui/images/user.png')?>" class="picture" border="0" width="48" height="48"><br>root<span><?=htmlspecialchars($users['root']['desc'])?></span></a></div>
<div class="user-list" style="text-align:center"><a class="<?=(!empty($users['root']['desc']) ? 'info' : '')?>" href="/<?=$path?>/UserEdit?name=root"><img src="<?=(file_exists($img) ? autov($img) : '/webGui/images/user.png')?>" class="picture" border="0" width="48" height="48"><br>root<span><?=htmlspecialchars($users['root']['desc'])?></span></a></div>
<div class="title"><span class="left"><i class="fa fa-cloud title"></i>_(Shares Access)_</span></div>
<?foreach ($users as $user):?>
<?if ($user['name'] == 'root') continue;?>
<?$img = "/boot/config/plugins/dynamix/users/{$user['name']}.png"?>
<div class="user-list" style="text-align:center"><a class="<?=(!empty($user['desc']) ? 'info' : '')?>" href="<?=$path?>/UserEdit?name=<?=htmlspecialchars(urlencode($user['name']))?>"><img src="<?=(file_exists($img) ? autov($img) : '/webGui/images/user.png')?>" class="picture" border="0" width="48" height="48"><br><?=htmlspecialchars($user['name'])?><span><?=htmlspecialchars($user['desc'])?></span></a></div>
<div class="user-list" style="text-align:center"><a class="<?=(!empty($user['desc']) ? 'info' : '')?>" href="/<?=$path?>/UserEdit?name=<?=htmlspecialchars(urlencode($user['name']))?>"><img src="<?=(file_exists($img) ? autov($img) : '/webGui/images/user.png')?>" class="picture" border="0" width="48" height="48"><br><?=htmlspecialchars($user['name'])?><span><?=htmlspecialchars($user['desc'])?></span></a></div>
<?endforeach;?>
<?if (count($users)==1):?>
@@ -35,6 +33,6 @@ _(No users are defined)_. _(Click **Add User** to create a user for remote share
<?endif;?>
<div style='clear:both'></div>
<form method="POST" action="<?=$path?>/UserAdd">
<input type="submit" value="_(Add User)_"><?if ($submenu):?><input type="button" value="_(Done)_" onclick="done()"><?endif;?>
<form method="POST" action="/<?=$path?>/UserAdd">
<input type="submit" value="_(Add User)_"><input type="button" value="_(Done)_" onclick="done()">
</form>

View File

@@ -480,10 +480,10 @@ $theme_dark = in_array($display['theme'], ['black', 'gray']);
</div>
<div class="content">
<h1>
<?=$var['NAME']?>
<?=htmlspecialchars($var['NAME'])?>
</h1>
<h2>
<?=$var['COMMENT']?>
<?=htmlspecialchars($var['COMMENT'])?>
</h2>
<div class="case">

View File

@@ -306,8 +306,8 @@ $THEME_DARK = in_array($display['theme'],['black','gray']);
</div>
<div class="content">
<header>
<h1><?=$var['NAME']?></h1>
<h2><?=$var['COMMENT']?></h2>
<h1><?=htmlspecialchars($var['NAME'])?></h1>
<h2><?=htmlspecialchars($var['COMMENT'])?></h2>
<p><?=_('Please set a password for the root user account')?>.</p>
<p><?=_('Max password length is 128 characters')?>.</p>
</header>

View File

@@ -720,7 +720,7 @@ if (isset($myPage['Load']) && $myPage['Load']>0) echo "\n<script>timers.reload =
echo "<div class='tabs'>";
$tab = 1;
$pages = [];
if (!empty($myPage['text'])) $pages[$myPage['name']] = $myPage;
if (!empty($myPage['text']) && page_enabled($myPage)) $pages[$myPage['name']] = $myPage;
if (_var($myPage,'Type')=='xmenu') $pages = array_merge($pages, find_pages($myPage['name']));
if (isset($myPage['Tabs'])) $display['tabs'] = strtolower($myPage['Tabs'])=='true' ? 0 : 1;
$tabbed = $display['tabs']==0 && count($pages)>1;
@@ -728,7 +728,7 @@ $tabbed = $display['tabs']==0 && count($pages)>1;
foreach ($pages as $page) {
$close = false;
if (isset($page['Title'])) {
eval("\$title=\"".htmlspecialchars($page['Title'])."\";");
eval("\$title=\"{$page['Title']}\";");
if ($tabbed) {
echo "<div class='tab'><input type='radio' id='tab{$tab}' name='tabs' onclick='settab(this.id)'><label for='tab{$tab}'>";
echo tab_title($title,$page['root'],_var($page,'Tag',false));
@@ -745,7 +745,7 @@ foreach ($pages as $page) {
if (isset($page['Type']) && $page['Type']=='menu') {
$pgs = find_pages($page['name']);
foreach ($pgs as $pg) {
@eval("\$title=\"".htmlspecialchars($pg['Title'])."\";");
@eval("\$title=\"{$pg['Title']}\";");
$icon = _var($pg,'Icon',"<i class='icon-app PanelIcon'></i>");
if (substr($icon,-4)=='.png') {
$root = $pg['root'];

View File

@@ -117,7 +117,7 @@ foreach ($disks as $name => $disk) {
} else $luks = "";
echo "<tr><td><a class='view' href=\"/$path/Browse?dir=/mnt/$name\"><i class=\"icon-u-tab\" title=\"",_('Browse')," /mnt/$name\"></i></a>";
echo "<a class='info nohand' onclick='return false'><i class='fa fa-$orb orb $color-orb'></i><span style='left:18px'>$help</span></a>$luks<a href=\"/$path/Disk?name=$name\" onclick=\"$.cookie('one','tab1')\">$name</a></td>";
echo "<td>"._var($disk,'comment')."</td>";
echo "<td>",htmlspecialchars(_var($disk,'comment')),"</td>";
echo "<td>",disk_share_settings(_var($var,'shareSMBEnabled'), $sec[$name]),"</td>";
echo "<td>",disk_share_settings(_var($var,'shareNFSEnabled'), $sec_nfs[$name]),"</td>";
$cmd="/webGui/scripts/disk_size&arg1=$name&arg2=ssz2";

View File

@@ -288,13 +288,6 @@ function transpose_user_path($path) {
}
return $path;
}
// custom parse_ini_file/string functions to deal with '#' comment lines
function my_parse_ini_string($text, $sections=false, $scanner=INI_SCANNER_NORMAL) {
return parse_ini_string(preg_replace('/^#/m',';',$text),$sections,$scanner);
}
function my_parse_ini_file($file, $sections=false, $scanner=INI_SCANNER_NORMAL) {
return my_parse_ini_string(file_get_contents($file),$sections,$scanner);
}
function cpu_list() {
exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list|sort -nu', $cpus);
return $cpus;
@@ -395,4 +388,9 @@ function get_realvolume($path) {
}
return $reallocation;
}
function device_exists($name)
{
global $disks,$devs;
return (array_key_exists($name, $disks) && !str_contains(_var($disks[$name],'status'),'_NP')) || (array_key_exists($name, $devs));
}
?>

View File

@@ -42,8 +42,16 @@ function build_pages($pattern) {
}
}
function page_enabled(&$page)
{
global $var,$disks,$devs,$users,$shares,$sec,$sec_nfs,$name,$display,$pool_devices;
$enabled = true;
if (isset($page['Cond'])) eval("\$enabled={$page['Cond']};");
return $enabled;
}
function find_pages($item) {
global $docroot,$site,$var,$disks,$devs,$users,$shares,$sec,$sec_nfs,$name,$display,$pool_devices;
global $site;
$pages = [];
foreach ($site as $page) {
if (empty($page['Menu'])) continue;
@@ -55,9 +63,7 @@ function find_pages($item) {
while ($menu !== false) {
[$menu,$rank] = my_explode(':',$menu);
if ($menu == $item) {
$enabled = true;
if (isset($page['Cond'])) eval("\$enabled={$page['Cond']};");
if ($enabled) $pages["$rank{$page['name']}"] = $page;
if (page_enabled($page)) $pages["$rank{$page['name']}"] = $page;
break;
}
$menu = strtok(' ');
@@ -69,6 +75,7 @@ function find_pages($item) {
function tab_title($title,$path,$tag) {
global $docroot,$pools;
$title=htmlspecialchars(html_entity_decode($title));
$names = implode('|',array_merge(['disk','parity'],$pools));
if (preg_match("/^($names)/",$title)) {
$device = strtok($title,' ');

View File

@@ -17,7 +17,7 @@ function unscript($text) {
}
// remove malicious HTML elements
function untangle($text) {
return preg_replace('#<.+?>(.*?)</.+?>#','',html_entity_decode($text));
return strip_tags(html_entity_decode($text));
}
// remove malicious code appended after string variable
function unbundle($text) {

View File

@@ -274,7 +274,7 @@ foreach ($shares as $name => $share) {
echo "<tr><td><a class='view' href=\"/$path/Browse?dir=/mnt/user/", rawurlencode($name), "\"><i class=\"icon-u-tab\" title=\"", _('Browse'), " /mnt/user/" . rawurlencode($name), "\"></i></a>";
echo "<a class='info nohand' onclick='return false'><i class='fa fa-$orb orb $color-orb'></i><span style='left:18px'>$help</span></a>$luks<a href=\"/$path/Share?name=";
echo rawurlencode($name), "\" onclick=\"$.cookie('one','tab1')\">$name</a></td>";
echo "<td>{$share['comment']}</td>";
echo "<td>", htmlspecialchars(_var($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

@@ -39,12 +39,19 @@ function file_put_contents_atomic($filename,$data) {
}
return strlen($data);
}
// custom parse_ini_file/string functions to deal with '#' comment lines and remove html/php tags
function my_parse_ini_string($text, $sections=false, $scanner=INI_SCANNER_NORMAL) {
return parse_ini_string(strip_tags(html_entity_decode(preg_replace('/^#.*$/m','',$text))),$sections,$scanner);
}
function my_parse_ini_file($file, $sections=false, $scanner=INI_SCANNER_NORMAL) {
return my_parse_ini_string(file_get_contents($file),$sections,$scanner);
}
function parse_plugin_cfg($plugin, $sections=false, $scanner=INI_SCANNER_NORMAL) {
global $docroot;
$ram = "$docroot/plugins/$plugin/default.cfg";
$rom = "/boot/config/plugins/$plugin/$plugin.cfg";
$cfg = file_exists($ram) ? parse_ini_file($ram, $sections, $scanner) : [];
return file_exists($rom) ? array_replace_recursive($cfg, parse_ini_file($rom, $sections, $scanner)) : $cfg;
$cfg = file_exists($ram) ? my_parse_ini_file($ram, $sections, $scanner) : [];
return file_exists($rom) ? array_replace_recursive($cfg, my_parse_ini_file($rom, $sections, $scanner)) : $cfg;
}
function parse_cron_cfg($plugin, $job, $text = "") {
$cron = "/boot/config/plugins/$plugin/$job.cron";

View File

@@ -25,9 +25,7 @@ setlocale(LC_ALL,'en_US.UTF-8');
date_default_timezone_set(substr(readlink('/etc/localtime'),20));
$secure = array_key_exists('HTTPS', $_SERVER);
ini_set("session.use_strict_mode", "1");
// Safari bug prevents use of 'Strict'
// ini_set("session.cookie_samesite", $secure?'Strict':'Lax');
ini_set("session.cookie_samesite", 'Lax');
ini_set("session.cookie_samesite", 'Strict');
if (array_key_exists('HTTP_HOST', $_SERVER)) {
session_name("unraid_".md5(strstr($_SERVER['HTTP_HOST'].':', ':', true)));
}

View File

@@ -17,7 +17,7 @@ require_once "$docroot/webGui/include/Wrappers.php";
$vfio = '/boot/config/vfio-pci.cfg';
$old = is_file($vfio) ? rtrim(file_get_contents($vfio)) : '';
$new = _var($_GET,'cfg');
$new = _var($_POST,'cfg');
$reply = 0;
if ($new != $old) {

View File

@@ -78,25 +78,28 @@ function device_info(&$disk,$online) {
$help .= "<br>"._("Click to spin $action device");
}
$status = "<a class='info'><i ".($ctrl?"id='dev-$named' ":"")."class='fa fa-$orb orb $color-orb'$ctrl></i><span>$help</span></a>";
$link = (($parity || $data || $pool) && $disk_status!='DISK_NP') || $name=='flash' || in_array($name,$pools) || $type=='New'
? "<a href=\"".htmlspecialchars("/Main/Settings/$source?name=$name")."\">$fancy</a>"
$link = ($parity && $disk_status!='DISK_NP_DSBL') || (($data || $pool) && $disk_status!='DISK_NP') || $name=='flash' || in_array($name,$pools) || $type=='New'
? "<a href=\"".htmlspecialchars("/Main/$source?name=$name")."\">$fancy</a>"
: $fancy;
return $view.$status.$link;
}
function device_desc(&$disk) {
global $var;
$size = my_scale(_var($disk,'size',0)*1024 ?: _var($disk,'sectors',0)*_var($disk,'sector_size',0),$unit,-1,-1);
switch (_var($disk,'type')) {
case 'Flash': $type = 'usb'; break;
case 'Parity': $type = _var($disk,'rotational') ? 'disk' : 'nvme'; break;
case 'Data':
case 'Cache': $type = _var($disk,'rotational') ? (_var($disk,'luksState') ? 'disk-encrypted' : 'disk') : 'nvme'; break;
default: $type = 'disk'; break;
$size = my_scale(_var($disk,'size',0)*1024 ?: _var($disk,'sectors',0)*_var($disk,'sector_size',0),$unit,-1);
if (_var($var,'fsState')=='Started') {
switch (_var($disk,'type')) {
case 'Flash': $type = 'usb'; break;
case 'Parity': $type = _var($disk,'rotational') ? 'disk' : 'nvme'; break;
case 'Data':
case 'Cache': $type = _var($disk,'rotational') ? (_var($disk,'luksState') ? 'disk-encrypted' : 'disk') : 'nvme'; break;
default: $type = 'disk'; break;
}
$log = "<a class='info hand' onclick=\"openTerminal('disklog','"._var($disk,'device')."','')\"><i class='icon-$type icon'></i><span>"._('Disk Log Information')."</span></a>";
return $log."<span style='font-family:bitstream'>".my_id(_var($disk,'id'))."</span> - $size $unit ("._var($disk,'device').")";
} else {
return my_id(_var($disk,'id'))." - $size $unit ("._var($disk,'device').")";
}
$log = _var($var,'fsState')=='Started'
? "<a class='info hand' onclick=\"openTerminal('disklog','"._var($disk,'device')."','')\"><i class='icon-$type icon'></i><span>"._('Disk Log Information')."</span></a>"
: "<a class='static'><i class='icon-$type icon'></i></a>";
return $log."<span style='font-family:bitstream'>".my_id(_var($disk,'id'))."</span> - $size $unit ("._var($disk,'device').")";
}
function assignment(&$disk) {
global $var, $devs;

View File

@@ -145,7 +145,7 @@ span.link{text-decoration:underline;cursor:pointer}
</style>
<table class='info'>
<tr><td><?=_('Model')?>:</td><td><?=$model?></td></tr>
<tr><td><?=_('Model')?>:</td><td><?=htmlspecialchars($model)?></td></tr>
<tr><td><?=('M/B')?>:</td><td><?="{$board['Manufacturer']} {$board['Product Name']} {$board['Version']} {$board['Serial Number']}"?></td></tr>
<tr><td><?=_('BIOS')?>:</td><td><?="{$bios['Vendor']} {$bios['Version']} {$bios['Release Date']}"?></td></tr>
<tr><td><?=_('CPU')?>:</td><td><?="$cpumodel {$cpu['Current Speed']}"?></td></tr>

View File

@@ -63,7 +63,7 @@ foreach (glob('plugins/*', GLOB_ONLYDIR) as $plugin) {
}
// Get general variables
$name = untangle(_var($_GET,'name'));
$name = rawurldecode(_var($_GET,'name'));
$dir = rawurldecode(_var($_GET,'dir'));
$path = substr(strtok(_var($_SERVER,'REQUEST_URI'),'?'),1);

50
emhttp/redirect.htm Normal file
View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Redirect Page</title>
</head>
<body>
<div id="text" style="text-align: center; margin-top: calc(100vh - 75%); display: none; font-family: sans-serif;">
<h1>Redirecting...</h1>
<h2><a id="redirectButton" href="/Main">Click here if you are not redirected automatically</a></h2>
</div>
<div>
</div>
<script>
function parseRedirectTarget(target) {
if (target && target !== '/') {
// parse target and ensure it is a bare path with no query parameters
const url = new URL(target, window.location.origin);
return url.pathname;
}
return '/Main';
}
function getRedirectUrl() {
const search = new URLSearchParams(window.location.search);
const targetRoute = parseRedirectTarget(search.get('target'));
if (search.has('data') && (search.size === 1 || search.size === 2)) {
return `${window.location.origin}${targetRoute}?data=${encodeURIComponent(search.get('data'))}`;
}
return `${window.location.origin}${targetRoute}`;
}
function showText() {
document.getElementById('text').style.display = 'block';
}
document.getElementById('redirectButton').attributes.href.value = getRedirectUrl();
setTimeout(() => {
showText();
}, 750);
window.location.href = getRedirectUrl();
</script>
</body>
</html>

View File

@@ -459,6 +459,13 @@ build_locations(){
allow all;
}
#
# redirect.htm available without authentication
#
location = /redirect {
rewrite ^ /redirect.htm break;
allow all;
}
#
# proxy update.htm and logging.htm scripts to emhttpd listening on local socket
#
location = /update.htm {