add "shred partition" feature

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=1076584
This commit is contained in:
Volker Lanz 2010-01-18 12:31:00 +00:00
parent d975416a53
commit 908bfe3669
10 changed files with 325 additions and 23 deletions

16
TODO
View File

@ -4,7 +4,7 @@ Random plans and ideas for 1.1 and beyond:
that deals with labels and try to get it out of the package. If
that's entirely impossible, maybe a kludge like GParted uses should be
considered *shudder*
* To say it bluntly: libparted is a complete dead end. What we have to do is
separate the backend logic from the core and write backend interfaces so
partitionmanager can make use of other backends apart from libparted. KDE's
@ -13,11 +13,6 @@ Random plans and ideas for 1.1 and beyond:
Also, DeviceKit-disks is around the corner and implementations using it for
solid begin to materialize.
* People want mount management (i.e. fstab management) in partition manager.
I've written a small kcm, Mount Manager, as a proof of concept how this could
look like, but I'm not yet happy with it. Eventually, this will / should /
can me merged into partition manager.
* The whole lvm/dm debacle. Nothing much useful can be done about it without
the backend stuff mentioned above, though.
@ -28,4 +23,11 @@ Random plans and ideas for 1.1 and beyond:
hopefully be able to get meaningful progress status reporting while resizing,
checking and so on.
* Default size of File System Support dialog window.
* Re-design partition list. Maybe include all disks into the list and drop the
devices panel?
* Information about file system on a separate tab in the properties, unique
to the file system in use.

View File

@ -0,0 +1,63 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "core/copysourcerandom.h"
#include <kdebug.h>
/** Constructs a CopySourceRandom with the given @p size
@param s the size the copy source will (pretend to) have
@param sectorsize the sectorsize the copy source will (pretend to) have
*/
CopySourceRandom::CopySourceRandom (qint64 s, qint32 sectorsize) :
CopySource(),
m_Size(s),
m_SectorSize(sectorsize),
m_Random("/dev/urandom")
{
}
/** Opens the random source.
@return true on success
*/
bool CopySourceRandom::open()
{
return random().open(QIODevice::ReadOnly);
}
/** Returns the length of the random source in sectors.
@return length of the source in sectors.
*/
qint64 CopySourceRandom::length() const
{
return size() / sectorSize();
}
/** Reads the given number of sectors from the random source into the given buffer.
@param buffer buffer to store the sectors read in
@param readOffset offset where to begin reading (unused)
@param numSectors number of sectors to read
@return true on success
*/
bool CopySourceRandom::readSectors(void* buffer, qint64 readOffset, qint64 numSectors)
{
Q_UNUSED(readOffset);
return random().read(static_cast<char*>(buffer), numSectors * sectorSize()) == numSectors * sectorSize();
}

View File

@ -0,0 +1,62 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#if !defined(COPYSOURCERANDOM__H)
#define COPYSOURCERANDOM__H
#include "core/copysource.h"
#include <QFile>
class CopyTarget;
/** @brief A source of random data to copy from.
Represents a random date source to copy from. Used to securely overwrite data on disk.
@author vl@fidra.de
*/
class CopySourceRandom : public CopySource
{
public:
CopySourceRandom(qint64 size, qint32 sectorsize);
public:
virtual bool open();
virtual bool readSectors(void* buffer, qint64 readOffset, qint64 numSectors);
virtual qint64 length() const;
virtual qint32 sectorSize() const { return m_SectorSize; } /**< @return the file's sector size */
virtual bool overlaps(const CopyTarget&) const { return false; } /**< @return false for random source */
virtual qint64 firstSector() const { return 0; } /**< @return 0 for random source */
virtual qint64 lastSector() const { return length(); } /**< @return equal to length for random source. @see length() */
protected:
QFile& random() { return m_Random; }
const QFile& random() const { return m_Random; }
qint32 size() const { return m_Size; }
private:
qint64 m_Size;
qint32 m_SectorSize;
QFile m_Random;
};
#endif

View File

@ -1,6 +1,6 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<gui name="KDE Partition Manager" version="5">
<gui name="KDE Partition Manager" version="7">
<ToolBar name="editToolBar">
<text context="@title:menu turn on and off edit toolbar">Edit Toolbar</text>
<Action name="applyAllOperations"/>
@ -50,6 +50,7 @@
<Action name="newPartition"/>
<Action name="resizePartition"/>
<Action name="deletePartition"/>
<Action name="shredPartition"/>
<separator name="separator_6"/>
<Action name="copyPartition"/>
<Action name="pastePartition"/>

View File

@ -215,7 +215,15 @@ void PartitionManagerWidget::setupActions()
deletePartition->setToolTip(i18nc("@info:tooltip", "Delete partition"));
deletePartition->setStatusTip(i18nc("@info:status", "Delete a partition."));
deletePartition->setShortcut(Qt::Key_Delete);
deletePartition->setIcon(BarIcon("edit-delete-shred"));
deletePartition->setIcon(BarIcon("edit-delete"));
KAction* shredPartition = actionCollection()->addAction("shredPartition", this, SLOT(onShredPartition()));
shredPartition->setEnabled(false);
shredPartition->setText(i18nc("@action:inmenu", "Shred"));
shredPartition->setToolTip(i18nc("@info:tooltip", "Shred partition"));
shredPartition->setStatusTip(i18nc("@info:status", "Shred a partition so that its contents cannot be restored."));
shredPartition->setShortcut(Qt::SHIFT | Qt::Key_Delete);
shredPartition->setIcon(BarIcon("edit-delete-shred"));
KAction* copyPartition = actionCollection()->addAction("copyPartition", this, SLOT(onCopyPartition()));
copyPartition->setEnabled(false);
@ -328,6 +336,7 @@ void PartitionManagerWidget::enableActions()
actionCollection()->action("resizePartition")->setEnabled(!readOnly && canResize);
actionCollection()->action("copyPartition")->setEnabled(CopyOperation::canCopy(part));
actionCollection()->action("deletePartition")->setEnabled(!readOnly && DeleteOperation::canDelete(part));
actionCollection()->action("shredPartition")->setEnabled(!readOnly && DeleteOperation::canDelete(part));
actionCollection()->action("pastePartition")->setEnabled(!readOnly && CopyOperation::canPaste(part, clipboardPartition()));
actionCollection()->action("propertiesPartition")->setEnabled(part != NULL);
@ -489,6 +498,7 @@ void PartitionManagerWidget::showPartitionContextMenu(const QPoint& pos)
partitionMenu.addAction(actionCollection()->action("newPartition"));
partitionMenu.addAction(actionCollection()->action("resizePartition"));
partitionMenu.addAction(actionCollection()->action("deletePartition"));
partitionMenu.addAction(actionCollection()->action("shredPartition"));
partitionMenu.addSeparator();
partitionMenu.addAction(actionCollection()->action("copyPartition"));
partitionMenu.addAction(actionCollection()->action("pastePartition"));
@ -664,7 +674,7 @@ void PartitionManagerWidget::onNewPartition()
delete dlg;
}
void PartitionManagerWidget::onDeletePartition()
void PartitionManagerWidget::onDeletePartition(bool shred)
{
Q_ASSERT(selectedDevice());
Q_ASSERT(selectedPartition());
@ -712,12 +722,17 @@ void PartitionManagerWidget::onDeletePartition()
setClipboardPartition(NULL);
}
operationStack().push(new DeleteOperation(*selectedDevice(), selectedPartition()));
operationStack().push(new DeleteOperation(*selectedDevice(), selectedPartition(), shred));
updatePartitions();
emit statusChanged();
emit operationsChanged();
}
void PartitionManagerWidget::onShredPartition()
{
onDeletePartition(true);
}
void PartitionManagerWidget::onResizePartition()
{
Q_ASSERT(selectedDevice());

View File

@ -126,7 +126,8 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT PartitionManagerWidget : public QWidget,
void onMountPartition();
void onEditMountPoint();
void onNewPartition();
void onDeletePartition();
void onDeletePartition(bool shred = false);
void onShredPartition();
void onResizePartition();
void onCopyPartition();
void onPastePartition();

View File

@ -0,0 +1,89 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "jobs/shredfilesystemjob.h"
#include "core/partition.h"
#include "core/device.h"
#include "core/copysourcerandom.h"
#include "core/copytargetdevice.h"
#include "fs/filesystem.h"
#include "fs/filesystemfactory.h"
#include "util/report.h"
#include <klocale.h>
#include <kdebug.h>
/** Creates a new ShredFileSystemJob
@param d the Device the FileSystem is on
@param p the Partition the FileSystem is in
*/
ShredFileSystemJob::ShredFileSystemJob(Device& d, Partition& p) :
Job(),
m_Device(d),
m_Partition(p)
{
}
qint32 ShredFileSystemJob::numSteps() const
{
return 100;
}
bool ShredFileSystemJob::run(Report& parent)
{
Q_ASSERT(device().deviceNode() == partition().devicePath());
if (device().deviceNode() != partition().devicePath())
{
kWarning() << "deviceNode: " << device().deviceNode() << ", partition path: " << partition().devicePath();
return false;
}
bool rval = false;
Report* report = jobStarted(parent);
// Again, a scope for copyTarget and copySource. See MoveFileSystemJob::run()
{
CopyTargetDevice copyTarget(device(), partition().fileSystem().firstSector(), partition().fileSystem().lastSector());
CopySourceRandom copySource(partition().capacity(), copyTarget.sectorSize());
if (!copySource.open())
report->line() << i18nc("@info/plain", "Could not open random data source to overwrite file system.");
else if (!copyTarget.open())
report->line() << i18nc("@info/plain", "Could not open target partition <filename>%1</filename> to restore to.", partition().deviceNode());
else
{
rval = copyBlocks(*report, copyTarget, copySource);
report->line() << i18nc("@info/plain", "Closing device. This may take a few seconds.");
}
}
jobFinished(*report, rval);
return rval;
}
QString ShredFileSystemJob::description() const
{
return i18nc("@info/plain", "Shred the file system on <filename>%1</filename>", partition().deviceNode());
}

View File

@ -0,0 +1,60 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#if !defined(SHREDFILESYSTEMJOB__H)
#define SHREDFILESYSTEMJOB__H
#include "jobs/job.h"
#include <QString>
class Partition;
class Device;
class Report;
/** @brief Securely delete and shred a FileSystem.
Shreds (overwrites with random data) a FileSystem on given Partition and Device.
@author vl@fidra.de
*/
class ShredFileSystemJob : public Job
{
public:
ShredFileSystemJob(Device& d, Partition& p);
public:
virtual bool run(Report& parent);
virtual qint32 numSteps() const;
virtual QString description() const;
protected:
Partition& partition() { return m_Partition; }
const Partition& partition() const { return m_Partition; }
Device& device() { return m_Device; }
const Device& device() const { return m_Device; }
private:
Device& m_Device;
Partition& m_Partition;
};
#endif

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
* Copyright (C) 2008, 2010 by Volker Lanz <vl@fidra.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@ -25,6 +25,7 @@
#include "jobs/deletepartitionjob.h"
#include "jobs/deletefilesystemjob.h"
#include "jobs/shredfilesystemjob.h"
#include "util/capacity.h"
@ -37,11 +38,14 @@
@param d the Device to delete a Partition on
@param p pointer to the Partition to delete. May not be NULL
*/
DeleteOperation::DeleteOperation(Device& d, Partition* p) :
DeleteOperation::DeleteOperation(Device& d, Partition* p, bool secure) :
Operation(),
m_TargetDevice(d),
m_DeletedPartition(p),
m_DeleteFileSystemJob(new DeleteFileSystemJob(targetDevice(), deletedPartition())),
m_Secure(secure),
m_DeleteFileSystemJob(isSecure()
? static_cast<Job*>(new ShredFileSystemJob(targetDevice(), deletedPartition()))
: static_cast<Job*>(new DeleteFileSystemJob(targetDevice(), deletedPartition()))),
m_DeletePartitionJob(new DeletePartitionJob(targetDevice(), deletedPartition()))
{
addJob(deleteFileSystemJob());
@ -68,7 +72,10 @@ void DeleteOperation::undo()
QString DeleteOperation::description() const
{
return QString(i18nc("@info/plain", "Delete partition <filename>%1</filename> (%2, %3)", deletedPartition().deviceNode(), Capacity(deletedPartition()).toString(), deletedPartition().fileSystem().name()));
if (isSecure())
return QString(i18nc("@info/plain", "Shred partition <filename>%1</filename> (%2, %3)", deletedPartition().deviceNode(), Capacity(deletedPartition()).toString(), deletedPartition().fileSystem().name()));
else
return QString(i18nc("@info/plain", "Delete partition <filename>%1</filename> (%2, %3)", deletedPartition().deviceNode(), Capacity(deletedPartition()).toString(), deletedPartition().fileSystem().name()));
}
void DeleteOperation::checkAdjustLogicalNumbers(Partition& p, bool undo)
@ -90,7 +97,7 @@ bool DeleteOperation::canDelete(const Partition* p)
{
if (p == NULL)
return false;
if (p->isMounted())
return false;

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
* Copyright (C) 2008, 2010 by Volker Lanz <vl@fidra.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@ -29,7 +29,7 @@ class Device;
class OperationStack;
class Partition;
class DeleteFileSystemJob;
class Job;
class DeletePartitionJob;
/** @brief Delete a Partition.
@ -43,14 +43,15 @@ class DeleteOperation : public Operation
Q_DISABLE_COPY(DeleteOperation)
public:
DeleteOperation(Device& d, Partition* p);
DeleteOperation(Device& d, Partition* p, bool secure = false);
~DeleteOperation();
public:
QString iconName() const { return "edit-delete-shred"; }
QString iconName() const { return isSecure() ? "edit-delete-shred" : "edit-delete"; }
QString description() const;
void preview();
void undo();
bool isSecure() const { return m_Secure; }
static bool canDelete(const Partition* p);
@ -65,13 +66,14 @@ class DeleteOperation : public Operation
void setDeletedPartition(Partition* p) { m_DeletedPartition = p; }
DeleteFileSystemJob* deleteFileSystemJob() { return m_DeleteFileSystemJob; }
Job* deleteFileSystemJob() { return m_DeleteFileSystemJob; }
DeletePartitionJob* deletePartitionJob() { return m_DeletePartitionJob; }
private:
Device& m_TargetDevice;
Partition* m_DeletedPartition;
DeleteFileSystemJob* m_DeleteFileSystemJob;
bool m_Secure;
Job* m_DeleteFileSystemJob;
DeletePartitionJob* m_DeletePartitionJob;
};