mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 11:14:27 +00:00
Add CheckPrivate page to manage ATA IDENTIFY DEVICE responses with potential private data
This commit is contained in:
122
Aaru.Server/Components/Admin/Pages/Ata/CheckPrivate.razor
Normal file
122
Aaru.Server/Components/Admin/Pages/Ata/CheckPrivate.razor
Normal file
@@ -0,0 +1,122 @@
|
||||
@page "/admin/ata/check-private"
|
||||
@using System.Text
|
||||
@using Aaru.CommonTypes.Structs.Devices.ATA
|
||||
@attribute [Authorize]
|
||||
@layout AdminLayout
|
||||
|
||||
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<DbContext> DbContextFactory
|
||||
|
||||
<PageTitle>ATA IDENTIFY DEVICE responses with possible private data</PageTitle>
|
||||
|
||||
@if(!_initialized)
|
||||
{
|
||||
<div class="stats-section">
|
||||
<h1 style="color: red; align-content: center; padding: 2rem">Loading...</h1>
|
||||
</div>
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@if(_items.Count == 0)
|
||||
{
|
||||
<section class="stats-section">
|
||||
No private data found.
|
||||
<a href="/admin/ata" class="btn btn-primary">Back to list</a>
|
||||
</section>
|
||||
|
||||
return;
|
||||
}
|
||||
<section class="stats-section">
|
||||
<h4>ATA IDENTIFY DEVICE responses with possible private data</h4>
|
||||
<div>
|
||||
<a @onclick="ClearPrivateAll" class="btn btn-primary">Clear private fields for all</a>
|
||||
<a @onclick="ClearReservedAll" class="btn btn-danger">Clear reserved fields for all</a>
|
||||
<a href="/admin/ata" class="btn btn-secondary">Back to list</a>
|
||||
</div>
|
||||
<table class="table table-dark table-striped table-bordered mt-4 mb-4">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th class="fw-bold bg-secondary text-light">
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Ata), nameof(Ata.Id))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.Model))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.SerialNumber))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.WWN))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.WWNExtension))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.MediaSerial))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.ReservedWords121))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.ReservedWords129))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.ReservedCFA))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.ReservedCEATA224))
|
||||
</th>
|
||||
<th>
|
||||
@DisplayNameHelper.GetDisplayName(typeof(Identify.IdentifyDevice), nameof(Identify.IdentifyDevice.ReservedWords))
|
||||
</th>
|
||||
<th class="fw-bold bg-secondary text-light">
|
||||
Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach(Ata item in _items)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@item.Id
|
||||
</td>
|
||||
<td>
|
||||
@item.IdentifyDevice?.Model
|
||||
</td>
|
||||
<td>
|
||||
@item.IdentifyDevice?.SerialNumber
|
||||
</td>
|
||||
<td>
|
||||
@item.IdentifyDevice?.WWN
|
||||
</td>
|
||||
<td>
|
||||
@item.IdentifyDevice?.WWNExtension
|
||||
</td>
|
||||
<td>
|
||||
@item.IdentifyDevice?.MediaSerial
|
||||
</td>
|
||||
<td>
|
||||
@Encoding.ASCII.GetString(item.Identify, 121 * 2, 10).Replace("\0", "")
|
||||
</td>
|
||||
<td>
|
||||
@Encoding.ASCII.GetString(item.Identify, 129 * 2, 62).Replace("\0", "")
|
||||
</td>
|
||||
<td>
|
||||
@Encoding.ASCII.GetString(item.Identify, 161 * 2, 14).Replace("\0", "")
|
||||
</td>
|
||||
<td>
|
||||
@Encoding.ASCII.GetString(item.Identify, 224 * 2, 12).Replace("\0", "")
|
||||
</td>
|
||||
<td>
|
||||
@Encoding.ASCII.GetString(item.Identify, 236 * 2, 38).Replace("\0", "")
|
||||
</td>
|
||||
<td>
|
||||
<a @onclick="() => ClearPrivate(item.Id)" class="btn btn-primary">Clear private fields</a>
|
||||
<a @onclick="() => ClearReserved(item.Id)" class="btn btn-danger">Clear reserved fields</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
195
Aaru.Server/Components/Admin/Pages/Ata/CheckPrivate.razor.cs
Normal file
195
Aaru.Server/Components/Admin/Pages/Ata/CheckPrivate.razor.cs
Normal file
@@ -0,0 +1,195 @@
|
||||
using Aaru.CommonTypes.Structs.Devices.ATA;
|
||||
using Aaru.Server.Database;
|
||||
|
||||
namespace Aaru.Server.Components.Admin.Pages.Ata;
|
||||
|
||||
public partial class CheckPrivate
|
||||
{
|
||||
bool _initialized;
|
||||
readonly List<CommonTypes.Metadata.Ata> _items = [];
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
StateHasChanged();
|
||||
await RefreshItemsAsync();
|
||||
_initialized = true;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
async Task RefreshItemsAsync()
|
||||
{
|
||||
_items.Clear();
|
||||
byte[] tmp;
|
||||
|
||||
await using DbContext _context = await DbContextFactory.CreateDbContextAsync();
|
||||
|
||||
foreach(CommonTypes.Metadata.Ata ata in _context.Ata)
|
||||
{
|
||||
Identify.IdentifyDevice? id = ata.IdentifyDevice;
|
||||
|
||||
if(id is null) continue;
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(((Identify.IdentifyDevice)id).SerialNumber) ||
|
||||
((Identify.IdentifyDevice)id).WWN != 0 ||
|
||||
((Identify.IdentifyDevice)id).WWNExtension != 0 ||
|
||||
!string.IsNullOrWhiteSpace(((Identify.IdentifyDevice)id).MediaSerial))
|
||||
{
|
||||
_items.Add(ata);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = new byte[10];
|
||||
Array.Copy(ata.Identify, 121 * 2, tmp, 0, 10);
|
||||
|
||||
if(tmp.All(static b => b > 0x20) && tmp.All(static b => b <= 0x5F))
|
||||
{
|
||||
_items.Add(ata);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = new byte[62];
|
||||
Array.Copy(ata.Identify, 129 * 2, tmp, 0, 62);
|
||||
|
||||
if(tmp.All(static b => b > 0x20) && tmp.All(static b => b <= 0x5F))
|
||||
{
|
||||
_items.Add(ata);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = new byte[14];
|
||||
Array.Copy(ata.Identify, 161 * 2, tmp, 0, 14);
|
||||
|
||||
if(tmp.All(static b => b > 0x20) && tmp.All(static b => b <= 0x5F))
|
||||
{
|
||||
_items.Add(ata);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = new byte[12];
|
||||
Array.Copy(ata.Identify, 224 * 2, tmp, 0, 12);
|
||||
|
||||
if(tmp.All(static b => b > 0x20) && tmp.All(static b => b <= 0x5F))
|
||||
{
|
||||
_items.Add(ata);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = new byte[38];
|
||||
Array.Copy(ata.Identify, 236 * 2, tmp, 0, 38);
|
||||
|
||||
if(tmp.All(static b => b > 0x20) && tmp.All(static b => b <= 0x5F)) _items.Add(ata);
|
||||
}
|
||||
}
|
||||
|
||||
async Task ClearPrivateAll()
|
||||
{
|
||||
await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
|
||||
|
||||
foreach(CommonTypes.Metadata.Ata ata in ctx.Ata)
|
||||
{
|
||||
// Serial number
|
||||
for(int i = 0; i < 20; i++) ata.Identify[10 * 2 + i] = 0x20;
|
||||
|
||||
// Media serial number
|
||||
for(int i = 0; i < 40; i++) ata.Identify[176 * 2 + i] = 0x20;
|
||||
|
||||
// WWN and WWN Extension
|
||||
for(int i = 0; i < 16; i++) ata.Identify[108 * 2 + i] = 0;
|
||||
|
||||
// We need to tell EFCore the entity has changed
|
||||
ctx.Update(ata);
|
||||
}
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
async Task ClearReservedAll()
|
||||
{
|
||||
await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
|
||||
|
||||
foreach(CommonTypes.Metadata.Ata ata in ctx.Ata)
|
||||
{
|
||||
// ReservedWords121
|
||||
for(int i = 0; i < 10; i++) ata.Identify[121 * 2 + i] = 0;
|
||||
|
||||
// ReservedWords129
|
||||
for(int i = 0; i < 40; i++) ata.Identify[129 * 2 + i] = 0;
|
||||
|
||||
// ReservedCFA
|
||||
for(int i = 0; i < 14; i++) ata.Identify[161 * 2 + i] = 0;
|
||||
|
||||
// ReservedCEATA224
|
||||
for(int i = 0; i < 12; i++) ata.Identify[224 * 2 + i] = 0;
|
||||
|
||||
// ReservedWords
|
||||
for(int i = 0; i < 14; i++) ata.Identify[161 * 2 + i] = 0;
|
||||
|
||||
// We need to tell EFCore the entity has changed
|
||||
ctx.Update(ata);
|
||||
}
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
async Task ClearPrivate(int id)
|
||||
{
|
||||
await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
|
||||
|
||||
CommonTypes.Metadata.Ata? ata = ctx.Ata.FirstOrDefault(a => a.Id == id);
|
||||
|
||||
if(ata is null) return;
|
||||
|
||||
// Serial number
|
||||
for(int i = 0; i < 20; i++) ata.Identify[10 * 2 + i] = 0x20;
|
||||
|
||||
// Media serial number
|
||||
for(int i = 0; i < 40; i++) ata.Identify[176 * 2 + i] = 0x20;
|
||||
|
||||
// WWN and WWN Extension
|
||||
for(int i = 0; i < 16; i++) ata.Identify[108 * 2 + i] = 0;
|
||||
|
||||
// We need to tell EFCore the entity has changed
|
||||
ctx.Update(ata);
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
await RefreshItemsAsync();
|
||||
}
|
||||
|
||||
async Task ClearReserved(int id)
|
||||
{
|
||||
await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
|
||||
|
||||
CommonTypes.Metadata.Ata? ata = ctx.Ata.FirstOrDefault(a => a.Id == id);
|
||||
|
||||
if(ata is null) return;
|
||||
|
||||
// ReservedWords121
|
||||
for(int i = 0; i < 10; i++) ata.Identify[121 * 2 + i] = 0;
|
||||
|
||||
// ReservedWords129
|
||||
for(int i = 0; i < 40; i++) ata.Identify[129 * 2 + i] = 0;
|
||||
|
||||
// ReservedCFA
|
||||
for(int i = 0; i < 14; i++) ata.Identify[161 * 2 + i] = 0;
|
||||
|
||||
// ReservedCEATA224
|
||||
for(int i = 0; i < 12; i++) ata.Identify[224 * 2 + i] = 0;
|
||||
|
||||
// ReservedWords
|
||||
for(int i = 0; i < 14; i++) ata.Identify[161 * 2 + i] = 0;
|
||||
|
||||
// We need to tell EFCore the entity has changed
|
||||
ctx.Update(ata);
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
await RefreshItemsAsync();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
<section class="stats-section">
|
||||
<h4>ATA IDENTIFY DEVICE responses</h4>
|
||||
<a href="/admin/ata/check-private" class="btn btn-primary mb-3">Check for private data</a>
|
||||
<table class="table table-dark table-striped table-bordered mt-4 mb-4">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
|
||||
Reference in New Issue
Block a user