Compare commits

...

15 Commits

30 changed files with 627 additions and 775 deletions

View File

@ -6,74 +6,44 @@
* deleting a drive securely via overwriting
## Screenshot
![alt text](https://git.mosad.xyz/localhorst/reHDD/raw/commit/95828afcc2e417b9cb64a4add98ae9c3c7628e84/doc/screenshot.png "Screenshot")
![alt text](https://git.mosad.xyz/localhorst/reHDD/raw/commit/42bc26eac95429e20c0f0d59f684dfec0d600e75/doc/screenshot.png "Screenshot")
## Debian Build Notes
* apt-get install ncurses-dev git make g++
* clone repo
* make release
* `apt-get install ncurses-dev git make g++`
* `make release`
## Create Standalone with Debian 11
Instructions how to create a standalone machine that boots directly to reHDD. This is aimed for production use, like several drives a day shredding.
* Start reHDD after boot without login (as a tty1 shell)
* Start dmesg after boot without login (as a tty2 shell)
* Start htop after boot without login (as a tty3 shell)
* Upload reHDD log every 12h if wanted
### Software requirements
* apt-get install hwinfo smartmontools curl
### Start reHDD after boot without login (as a tty shell)
nano /lib/systemd/system/getty@.service
and replace the [Service] with this:
```
[Service]
WorkingDirectory=/root/reHDD
ExecStart=
ExecStart=-/root/reHDD/reHDD
StandardInput=tty
StandardOutput=tty
Restart=always
RestartSec=1
UtmpIdentifier=tty1
TTYPath=/dev/tty1
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
SendSIGHUP=yes
```
systemctl daemon-reload
nano /etc/systemd/system/reHDDSettings.service
```
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/bash /root/reHDDSettings.sh
[Install]
WantedBy=multi-user.target
```
nano /root/reHDDSettings.sh
```
#!/bin/bash
dmesg -n 1 #disable overlay if a drive is attached/detached
# remove comment for the following to activate log telemetie
# curl -k -T /root/reHDD/reHDD.log -u "fgggfffgfgfgfg:" -H 'X-Requested-With: XMLHttpRequest' https://schuttercloud.com/public.php/webdav/`echo $(date '+%Y-%m-%d_%H-%M')`_reHDD.log
rm -f /root/reHDD/reHDD.log
```
chmod +x reHDDSettings.sh
* `apt-get install hwinfo smartmontools curl`
Make sure the binary reHDD is in /root/reHDD/
### Installation
Add your system drive in /root/reHDD/ignoreDrives.conf like:
```e102f49d-5ed5-462b-94c5-ef66a4345671```
Get your UUID via blkid /dev/sdX
clone this repo into /root/
systemctl enable reHDDSettings.service
`cd /root/reHDD/`
`make release`
`bash scripts/install_reHDD.bash`
If you want to upload the logs, edit `scripts/reHDDLogUploader.bash` with your nextcloud token
Add your system drive in `/root/reHDD/ignoreDrives.conf` like:
```e102f49d```
Get the first 8 Bytes from your UUID via `blkid /dev/sdX`
`reboot`
## Build docs
`make docs`
open `doc/html/index.html` in browser

View File

@ -5,20 +5,13 @@ echo starting astyle for $PWD
astyle --style=gnu src/*.cpp
rm -f src/*.orig
astyle --style=gnu src/shred/*.cpp
rm -f src/shred/*.orig
astyle --style=gnu src/logger/*.cpp
rm -f src/logger/*.orig
astyle --style=gnu include/*.h
rm -f include//*.orig
rm -f include/*.orig
astyle --style=gnu include//shred/*.h
rm -f include//shred/*.orig
astyle --style=gnu include//logger/*.h
astyle --style=gnu include/logger/*.h
rm -f include//logger/*.orig
echo finished astyle for $PWD

View File

@ -467,7 +467,7 @@ LOOKUP_CACHE_SIZE = 0
# normally produced when WARNINGS is set to YES.
# The default value is: NO.
EXTRACT_ALL = NO
EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
# be included in the documentation.
@ -904,7 +904,7 @@ FILE_PATTERNS = *.c \
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = NO
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
@ -1493,7 +1493,7 @@ ECLIPSE_DOC_ID = org.doxygen.Project
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
DISABLE_INDEX = NO
DISABLE_INDEX = YES
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag
@ -1510,7 +1510,7 @@ DISABLE_INDEX = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO
GENERATE_TREEVIEW = YES
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
@ -2260,7 +2260,7 @@ HIDE_UNDOC_RELATIONS = YES
# set to NO
# The default value is: NO.
HAVE_DOT = NO
HAVE_DOT = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
@ -2326,7 +2326,7 @@ GROUP_GRAPHS = YES
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
UML_LOOK = NO
UML_LOOK = YES
# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
# class node. If there are many fields or methods and many nodes the graph may
@ -2377,7 +2377,7 @@ INCLUDED_BY_GRAPH = YES
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALL_GRAPH = NO
CALL_GRAPH = YES
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
# dependency graph for every global function or class method.
@ -2389,7 +2389,7 @@ CALL_GRAPH = NO
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALLER_GRAPH = NO
CALLER_GRAPH = YES
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
# hierarchy of all classes instead of a textual one.

View File

@ -1,60 +0,0 @@
# Installation
**[1]** In terminal als root einloggen\
**[2]** In reHDD_prototype wechseln\
**[3]** Abhängigkeiten installieren\
`apt-get install smartmontools`\
`apt-get install hwinfo`\
`apt-get install util-linux`
**[4]** reHDD ausführbar machen\
`chmod +x reHDD`\
**[5]** ignoreDrives.conf bearbeiten
##### Ein Eintrag in der ignoreDrives-Datei sorgt dafür das die Software bestimmte Festplatten ignoriert. Dies ist wichtig damit nicht unbeabsichtigt die Systemfestplatte oder weitere Festplatten bearbeitet (gelöscht) werden.
Beispiel Inhalt:
```
/dev/sda:508eff7d-f039-4efb-9e2c-22dffdfdfdfd
/dev/sdb:07dfffff-c4b6-46e7-9cdf-3cfdfdffd53d
/dev/sdc:dfff974d-1af2-4dfd-9dfd-a2d8e4c43dff
```
Ein Eintrag setzt sich aus zwei Teilen zusammen:
**[Pfad]:[PARTUUID]**
Der Pfad kann mittels `fdisk -l` ermittelt werden.\
Die PARTUUID kann mittels `blkid /dev/sda` ermittelt werden, wobei `/dev/sda` derzuvor ermittelte Pfad ist.
# Benutzung
reHDD starten mit `./reHDD` (Wichtig ist das reHDD mit root-Rechen ausgeführt wird, entwender als root einloggen oder mit `sudo`)
reHDD sucht automatisch nach allen verfügbaren Festplatten und filtert die zu ignorierenden heraus.\
Für die verbleibenden Festplatten wird eine Übersicht ausgegeben.
Der Nutzer wird gefragt, welche Festplatte bearbeitet werden soll und gibt die Nummer ein.
Beispiel:
```
hostname@hendrik:/reHDD_prototype # ./reHDD
refurbishingHddTool
created app
app logic
search drives ...
------------DRIVES---------------
Drive: 0
Path: /dev/sdd
ModelFamily:
ModelName: ADATA SU650
Capacity: 120034123776
Serial: H50125K001601
PowerOnHours: 93
PowerCycle: 187
ErrorCount: 0
---------------------------------
Select drive to wipe:
0
Selected drive index: 0
wipe: shred -v /dev/sdd
shred: /dev/sdd: Durchgang 1/3 (random)…
shred: /dev/sdd: Durchgang 1/3 (random)…847MiB/112GiB 0%
...
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -1,2 +1,2 @@
4673974d-1af2-44fd-996b-a2d8e4c43d9a
2cb3dea4-9649-4d4a-935c-a0e5c08bad64
4673974d
2cb3dea4

View File

@ -25,6 +25,7 @@ public:
bool bWasShredded = false;
bool bWasDeleteted = false;
bool bIsOffline = false;
uint32_t u32DriveChecksumAferShredding = 0U;
private:
string sPath;
@ -37,6 +38,8 @@ private:
uint32_t u32PowerCycles = 0U;
time_t u32Timestamp = 0U; //unix timestamp for detecting a frozen drive
double d32TaskPercentage = 0U; //in percent for Shred (1 to 100)
time_t u32TimestampTaskStart = 0U; //unix timestamp for duration of an action
time_t u32TaskDuration = 0U; //time needed to complete the task
private:
void setTimestamp();
@ -75,6 +78,12 @@ public:
void setTaskPercentage(double d32TaskPercentage);
double getTaskPercentage(void);
void setActionStartTimestamp();
time_t getActionStartTimestamp();
void calculateTaskDuration();
time_t getTaskDuration();
};
#endif // DRIVE_H_

View File

@ -8,12 +8,12 @@
#ifndef REHDD_H_
#define REHDD_H_
#define REHDD_VERSION "bV0.2.1"
#define REHDD_VERSION "bV0.2.2"
// Drive handling Settings
#define WORSE_HOURS 19200 //mark drive if at this limit or beyond
#define WORSE_POWERUP 10000 //mark drive if at this limit or beyond
#define SHRED_ITERATIONS 3
#define SHRED_ITERATIONS 3U
#define FROZEN_TIMEOUT 10 //After this timeout (minutes) the drive will be marked as frozen
// Logger Settings
@ -23,7 +23,7 @@
#define SOFTWARE_VERSION "alpha"
#define HARDWARE_VERSION "generic"
#define LOG_LEVEL_HIGH //log everything, like drive scann thread
//#define LOG_LEVEL_HIGH //log everything, like drive scan thread
#ifndef LOG_LEVEL_HIGH
#define LOG_LEVEL_LOW //log only user actions and tasks
#endif
@ -31,6 +31,7 @@
// Logic
//#define DRYRUN //don´t touch the drives
#define FROZEN_ALERT //show alert if drive is frozen
#define ZERO_CHECK_ALERT //check drive after shred if all bytes are zero, show alert if this fails
//IPC pipes
#define READ 0
@ -58,7 +59,7 @@ using namespace std;
#include "drive.h"
#include "smart.h"
#include "shred/shred.h"
#include "shred.h"
#include "delete.h"
#include "tui.h"
#include "logger/logger.h"

56
include/shred.h Normal file
View File

@ -0,0 +1,56 @@
/**
* @file shred.h
* @brief shred drive
* @author hendrik schutter
* @date 03.05.2020
*/
#ifndef SHRED_H_
#define SHRED_H_
#include "reHDD.h"
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define CHUNK_SIZE 1024*1024*2 //amount of bytes that are overwritten at once --> 2MB
#define CHUNK_DIMENSION 100U //amount of chunks are read at once from random source
//#define DEMO_DRIVE_SIZE 1024*1024*256L // 256MB
//#define DEMO_DRIVE_SIZE 1024*1024*1024L // 1GB
//#define DEMO_DRIVE_SIZE 1024*1024*1024*10L // 10GB
typedef int fileDescriptor;
class Shred
{
protected:
public:
Shred();
~Shred();
int shredDrive(Drive* drive, int* ipSignalFd);
private:
fileDescriptor randomSrcFileDiscr;
fileDescriptor driveFileDiscr;
unsigned char caChunk[CHUNK_DIMENSION][CHUNK_SIZE];
unsigned long ulDriveByteSize;
unsigned long ulDriveByteOverallCount = 0; //all bytes shredded in all iterations + checking -> used for progress calculation
double d32Percent = 0.0;
double d32TmpPercent = 0.0;
inline double calcProgress();
int iRewindDrive(fileDescriptor file);
unsigned long getDriveSizeInBytes(fileDescriptor file);
unsigned int uiCalcChecksum(fileDescriptor file, Drive* drive, int* ipSignalFd);
void cleanup();
};
#endif // SHRED_H_

View File

@ -1,19 +0,0 @@
#ifndef _MACHINE_DEFINITIONS_HEADER
#define _MACHINE_DEFINITIONS_HEADER
#include <stdint.h>
#include <limits.h>
#undef MACHINE_16BIT
#undef MACHINE_32BIT
#undef MACHINE_64BIT
#if UINTPTR_MAX == UINT32_MAX
#define MACHINE_32BIT
#elif UINTPTR_MAX == UINT64_MAX
#define MACHINE_64BIT
#elif UINTPTR_MAX == UINT16_MAX
#define MACHINE_16BIT
#endif
#endif

View File

@ -1,98 +0,0 @@
/**
* @file shred.h
* @brief shred drive
* @author hendrik schutter
* @date 03.05.2020
*/
#ifndef SHRED_H_
#define SHRED_H_
#include "../reHDD.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <libgen.h>
#include "tfdef.h"
#include "tfcore.h"
//#include "tfe.h"
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
#ifndef _TFNG_STREAM_CIPHER_DEFS
#define _TFNG_STREAM_CIPHER_DEFS
#endif
#define PROCESS_BLOCKP(x,k1,k2,k3,k4,k5,k6) \
do { \
KE_MIX(Y, X, k1 + k2, k3, TFS_KS01); \
KE_MIX(T, Z, k4 + x, k5 + k6, TFS_KS02); \
\
BE_MIX(X, T, TFS_BS01); BE_MIX(Z, Y, TFS_BS02); \
BE_MIX(X, Y, TFS_BS03); BE_MIX(Z, T, TFS_BS04); \
BE_MIX(X, T, TFS_BS05); BE_MIX(Z, Y, TFS_BS06); \
} while (0)
#define PROCESS_BLOCKN(x,k1,k2,k3,k4,k5,k6) \
do { \
KE_MIX(Y, X, k1 + k2, k3, TFS_KS03); \
KE_MIX(T, Z, k4 + x, k5 + k6, TFS_KS04); \
\
BE_MIX(X, T, TFS_BS07); BE_MIX(Z, Y, TFS_BS08); \
BE_MIX(X, Y, TFS_BS09); BE_MIX(Z, T, TFS_BS10); \
BE_MIX(X, T, TFS_BS11); BE_MIX(Z, Y, TFS_BS12); \
} while (0)
#define NOSIZE ((size_t)-1)
#define XRET(x) if (!xret && xret < x) xret = x
class Shred
{
protected:
public:
Shred();
~Shred();
void shredDrive(Drive* drive, int* ipSignalFd);
private:
unsigned long blockcount = 0UL;
long blockcount_max;
double d32Percent;
inline double calcProgress();
inline void tfnge_init_iv(struct tfnge_stream *tfe, const void *key, const void *iv);
inline void tfnge_init(struct tfnge_stream *tfe, const void *key);
inline void tfng_encrypt_rawblk(TFNG_UNIT_TYPE *O, const TFNG_UNIT_TYPE *I, const TFNG_UNIT_TYPE *K);
inline void tfnge_emit(void *dst, size_t szdst, struct tfnge_stream *tfe);
};
#endif // SHRED_H_

View File

@ -1,51 +0,0 @@
#ifndef _THREEFISH_NOISE_GENERATOR_CIPHER_CORE_HEADER
#define _THREEFISH_NOISE_GENERATOR_CIPHER_CORE_HEADER
#ifndef _THREEFISH_NOISE_GENERATOR_CIPHER_DEFINITIONS_HEADER
#error Threefish definitions header is required! Include tfdef.h first.
#endif
#define ROL(x, s, max) ((x << s) | (x >> (-s & (max-1))))
#define ROR(x, s, max) ((x >> s) | (x << (-s & (max-1))))
#define KE_MIX(x, y, k1, k2, sl) \
do { \
x += k1; \
y += x; \
y += k2; \
x = ROL(x, sl, TFNG_UNIT_BITS); \
x ^= y; \
} while (0)
#define BE_MIX(x, y, sl) \
do { \
x += y; \
y = ROL(y, sl, TFNG_UNIT_BITS); \
y ^= x; \
} while (0)
#define KD_MIX(x, y, k1, k2, sr) \
do { \
x ^= y; \
x = ROR(x, sr, TFNG_UNIT_BITS); \
y -= x; \
y -= k2; \
x -= k1; \
} while (0)
#define BD_MIX(x, y, sr) \
do { \
y ^= x; \
y = ROR(y, sr, TFNG_UNIT_BITS); \
x -= y; \
} while (0)
enum tfng_rotations
{
TFS_KS01 = 7, TFS_KS02 = 25, TFS_KS03 = 19, TFS_KS04 = 7,
TFS_BS01 = 5, TFS_BS02 = 27, TFS_BS03 = 26, TFS_BS04 = 6,
TFS_BS05 = 14, TFS_BS06 = 11, TFS_BS07 = 24, TFS_BS08 = 18,
TFS_BS09 = 9, TFS_BS10 = 24, TFS_BS11 = 6, TFS_BS12 = 7,
};
#endif

View File

@ -1,39 +0,0 @@
#ifndef _THREEFISH_NOISE_GENERATOR_CIPHER_DEFINITIONS_HEADER
#define _THREEFISH_NOISE_GENERATOR_CIPHER_DEFINITIONS_HEADER
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#include <stddef.h>
#include <stdint.h>
#include "machdefs.h"
#if defined(MACHINE_64BIT)
#define TFNG_UNIT_TYPE uint64_t
#define TFNG_NR_BLOCK_BITS 256
#define TFNG_NR_KEY_BITS 512
#else
#define TFNG_UNIT_TYPE uint32_t
#define TFNG_NR_BLOCK_BITS 128
#define TFNG_NR_KEY_BITS 256
#endif
#define TFNG_NR_BLOCK_UNITS 4
#define TFNG_NR_KEY_UNITS 8
#define TFNG_BYTE_TYPE uint8_t
#define TFNG_SIZE_UNIT (sizeof(TFNG_UNIT_TYPE))
#define TFNG_BLOCK_SIZE (TFNG_SIZE_UNIT * TFNG_NR_BLOCK_UNITS)
#define TFNG_KEY_SIZE (TFNG_SIZE_UNIT * TFNG_NR_KEY_UNITS)
#define TFNG_TO_BITS(x) ((x) * 8)
#define TFNG_FROM_BITS(x) ((x) / 8)
#define TFNG_MAX_BITS TFNG_NR_BLOCK_BITS
#define TFNG_UNIT_BITS (TFNG_SIZE_UNIT * 8)
#endif

View File

@ -56,14 +56,16 @@ private:
static WINDOW *createOverViewWindow( int iXSize, int iYSize);
static WINDOW *createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive drive);
static WINDOW *overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart);
static WINDOW *createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, bool bSelected);
static WINDOW *createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, string sTime, bool bSelected);
static WINDOW *createSystemStats(int iXSize, int iYSize, int iXStart, int iYStart);
static WINDOW *createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate);
static WINDOW *createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string selectedTask, string optionA, string optionB);
static WINDOW* createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, string sProgress);
static WINDOW* createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, uint32_t u32PowerOnHours, uint32_t u32PowerCycles, uint32_t u32ErrorCount);
static WINDOW* createZeroChecksumWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, uint32_t u32Checksum);
void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY);
string formatTimeDuration(time_t u32Duration);
};
#endif // TUI_H_

View File

@ -0,0 +1,17 @@
[Unit]
Description=reHDD on tty1
[Service]
WorkingDirectory=/root/reHDD/
ExecStart=
ExecStart=-/root/reHDD/reHDD
StandardInput=tty
StandardOutput=tty
Restart=always
RestartSec=1
UtmpIdentifier=tty1
TTYPath=/dev/tty1
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
SendSIGHUP=yes

View File

@ -0,0 +1,17 @@
[Unit]
Description=dmesg on tty2
[Service]
WorkingDirectory=/usr/bin/
ExecStart=
ExecStart=-/usr/bin/dmesg -wH
StandardInput=tty
StandardOutput=tty
Restart=always
RestartSec=1
UtmpIdentifier=tty2
TTYPath=/dev/tty2
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
SendSIGHUP=yes

View File

@ -0,0 +1,17 @@
[Unit]
Description=htop on tty3
[Service]
WorkingDirectory=/usr/bin/
ExecStart=
ExecStart=-/usr/bin/htop
StandardInput=tty
StandardOutput=tty
Restart=always
RestartSec=1
UtmpIdentifier=tty3
TTYPath=/dev/tty3
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
SendSIGHUP=yes

View File

@ -0,0 +1,27 @@
#!/bin/bash
cd /root/reHDD/scripts/
chmod +x reHDDLogUploader.bash
cp reHDDLogUploader.service /lib/systemd/system/reHDDLogUploader.service
cp reHDDLogUploader.timer /lib/systemd/system/reHDDLogUploader.timer
systemctl daemon-reload
systemctl enable /lib/systemd/system/reHDDLogUploader.timer
chmod +x reHDDStartHelper.bash
cp reHDDStartHelper.service /lib/systemd/system/reHDDStartHelper.service
systemctl daemon-reload
systemctl enable /lib/systemd/system/reHDDStartHelper.service
mkdir -p /lib/systemd/system/getty@tty1.service.d
cp getty@tty1.service.d_override.conf /lib/systemd/system/getty@tty1.service.d/override.conf
systemctl daemon-reload
mkdir -p /lib/systemd/system/getty@tty2.service.d
cp getty@tty2.service.d_override.conf /lib/systemd/system/getty@tty2.service.d/override.conf
systemctl daemon-reload
mkdir -p /lib/systemd/system/getty@tty3.service.d
cp getty@tty3.service.d_override.conf /lib/systemd/system/getty@tty3.service.d/override.conf
systemctl daemon-reload

View File

@ -0,0 +1,6 @@
#!/bin/bash
# remove comment for the following to activate log telemetie
curl -k -T /root/reHDD/reHDD.log -u "__Place_your_token_here__:" -H 'X-Requested-With: XMLHttpRequest' https://schuttercloud.com/public.php/webdav/`echo $(date '+%Y-%m-%d_%H-%M')`_reHDD.log
rm -f /root/reHDD/reHDD.log

View File

@ -0,0 +1,18 @@
[Unit]
Description=reHDD log uploader
After=syslog.target
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
Group=root
RemainAfterExit=yes
ExecStart=/usr/bin/bash /root/reHDD/scripts/reHDDLogUploader.bash
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,11 @@
[Unit]
Description=reHDD log uploader timer
[Timer]
OnActiveSec=30s
OnBootSec=10min
OnUnitActiveSec=12h
[Install]
WantedBy=basic.target

View File

@ -0,0 +1,4 @@
#!/bin/bash
dmesg -n 1 #disable overlay if a drive is attached/detached

View File

@ -0,0 +1,16 @@
[Install]
WantedBy=multi-user.target
[Unit]
Description=reHDD start helper
After=syslog.target
[Service]
Type=oneshot
User=root
Group=root
RemainAfterExit=yes
ExecStart=/usr/bin/bash /root/reHDD/scripts/reHDDStartHelper.bash
[Install]
WantedBy=multi-user.target

View File

@ -1,12 +0,0 @@
#! /bin/bash
echo "starting SHRED DUMMY"
for i in {0..100..10}
do
#echo "DUMMY shred $i%"
echo $date > out.txt
sleep 1
done
echo "finished SHRED DUMMY"

View File

@ -52,10 +52,11 @@ string Drive::sCapacityToText()
double dSize = (double) getCapacity();
uint16_t u16UnitIndex = 0;
const char* units[] = {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
while (dSize >= 1000) { //using the marketing capacity
dSize /= 1000;
u16UnitIndex++;
}
while (dSize >= 1000) //using the marketing capacity
{
dSize /= 1000;
u16UnitIndex++;
}
sprintf(acBuffer, "%.*f %s", u16UnitIndex-3, dSize, units[u16UnitIndex]);
return acBuffer;
@ -131,14 +132,37 @@ void Drive::setDriveSMARTData( string modelFamily,
u32ErrorCount = errorCount;
u32PowerOnHours = powerOnHours;
u32PowerCycles = powerCycle;
}
}
void Drive::setTimestamp()
{
time(&this->u32Timestamp);
}
void Drive::setActionStartTimestamp()
{
time(&this->u32TimestampTaskStart);
}
time_t Drive::getActionStartTimestamp()
{
return this->u32TimestampTaskStart;
}
void Drive::calculateTaskDuration()
{
time_t u32localtime;
time(&u32localtime);
this->u32TaskDuration = u32localtime - this->u32TimestampTaskStart;
}
time_t Drive::getTaskDuration()
{
return this->u32TaskDuration;
}
void Drive::checkFrozenDrive(void)
{
time_t u32localtime;

View File

@ -198,6 +198,7 @@ void reHDD::ThreadShred()
{
if (getSelectedDrive() != nullptr)
{
getSelectedDrive()->setActionStartTimestamp(); //save timestamp at start of shredding
Shred* pShredTask = new Shred(); //create new shred task
pShredTask->shredDrive(getSelectedDrive(), &fdShredInformPipe[1]); //start new shred task
delete pShredTask; //delete shred task
@ -209,6 +210,7 @@ void reHDD::ThreadDelete()
{
if (getSelectedDrive() != nullptr)
{
getSelectedDrive()->setActionStartTimestamp(); //save timestamp at start of deleting
Delete::deleteDrive(getSelectedDrive()); //blocking, no thread
getSelectedDrive()->state = Drive::TaskState::NONE; //delete finished
getSelectedDrive()->bWasDeleteted = true;
@ -354,7 +356,7 @@ void reHDD::filterIgnoredDrives(list <Drive>* plistDrives)
{
string sBlkidOut = string(cLine);
sBlkidOut.erase(0, 18);
sBlkidOut.erase(36, sBlkidOut.length() - 36);
sBlkidOut.erase(8, sBlkidOut.length());
sUUID = sBlkidOut;
//cout << "blkid uuid:" << sUUID << endl;
}

278
src/shred.cpp Normal file
View File

@ -0,0 +1,278 @@
/**
* @file shred.cpp
* @brief shred drive
* @author hendrik schutter
* @date 03.05.2020
*/
#include "../include/reHDD.h"
const static char *randomsrc = (char*) "/dev/urandom";
Shred::Shred()
{
}
Shred::~Shred()
{
}
/**
* \brief shred drive with shred
* \param pointer of Drive instance
* \return void
*/
int Shred::shredDrive(Drive* drive, int* ipSignalFd)
{
#ifdef DRYRUN
for(int i = 0; i<=500; i++)
{
if(drive->state != Drive::SHRED_ACTIVE)
{
return 0;
}
drive->setTaskPercentage(i+0.05);
write(*ipSignalFd, "A",1);
usleep(20000);
}
#endif
#ifndef DRYRUN
const char *cpDrivePath = drive->getPath().c_str();
//open random source
randomSrcFileDiscr = open(randomsrc, O_RDONLY | O_LARGEFILE);
if (randomSrcFileDiscr == -1)
{
std::string errorMsg(strerror(randomSrcFileDiscr));
Logger::logThis()->error("Shred-Task: Open random source failed! " + errorMsg + " - Drive: " + drive->getSerial());
perror(randomsrc);
cleanup();
return -1;
}
//open disk
driveFileDiscr = open(cpDrivePath, O_RDWR | O_LARGEFILE);
if (driveFileDiscr == -1)
{
std::string errorMsg(strerror(driveFileDiscr));
Logger::logThis()->error("Shred-Task: Open drive failed! " + errorMsg + " - Drive: " + drive->getSerial());
perror(cpDrivePath);
cleanup();
return -1;
}
this->ulDriveByteSize = getDriveSizeInBytes(driveFileDiscr);
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Shred-Task: Bytes-Size of Drive: " + to_string(this->ulDriveByteSize) + " - Drive: " + drive->getSerial());
#endif
for (unsigned int uiShredIterationCounter = 0U; uiShredIterationCounter < SHRED_ITERATIONS; uiShredIterationCounter++)
{
unsigned long ulDriveByteCounter = 0U; //used for one shred-iteration to keep track of the current drive position
uint32_t u32ChunkDimensionIndex = 0U;
if(uiShredIterationCounter == (SHRED_ITERATIONS-1))
{
//last shred iteration --> overwrite with zeros instead with random data
memset(caChunk, 0U, CHUNK_DIMENSION*CHUNK_SIZE);
}
while (ulDriveByteCounter < ulDriveByteSize)
{
int iBytesToShred = 0; //Bytes that will be overwritten in this chunk-iteration
if((u32ChunkDimensionIndex == 0U) && (uiShredIterationCounter != (SHRED_ITERATIONS-1)))
{
//read new chunks from random source if needed and this is NOT the last shred iteration
unsigned long ulBytesInChunkBuffer = 0U;
while (ulBytesInChunkBuffer < CHUNK_DIMENSION*CHUNK_SIZE)
{
//read new random bytes
int iReadBytes = read(randomSrcFileDiscr, caChunk, ((CHUNK_DIMENSION*CHUNK_SIZE)-ulBytesInChunkBuffer));
if (iReadBytes > 0)
{
ulBytesInChunkBuffer += iReadBytes;
}
else
{
std::string errorMsg(strerror(iReadBytes));
Logger::logThis()->error("Shred-Task: Read from random source failed! " + errorMsg + " - Drive: " + drive->getSerial());
perror("unable to read random data");
cleanup();
return -1;;
}
} //end chunk read
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Shred-Task: Read new random data - Drive: " + drive->getSerial());
#endif
}
if((ulDriveByteSize-ulDriveByteCounter) < CHUNK_SIZE)
{
iBytesToShred = (ulDriveByteSize-ulDriveByteCounter);
}
else
{
iBytesToShred = CHUNK_SIZE;
}
int iByteShredded = write(driveFileDiscr, caChunk[u32ChunkDimensionIndex], iBytesToShred);
if(iByteShredded <= 0)
{
std::string errorMsg(strerror(iByteShredded));
Logger::logThis()->error("Shred-Task: Write to drive failed! " + errorMsg + " - Drive: " + drive->getSerial());
perror("unable to write random data");
cleanup();
return -1;
}
u32ChunkDimensionIndex = (u32ChunkDimensionIndex+1)%CHUNK_DIMENSION;
ulDriveByteCounter += iByteShredded;
ulDriveByteOverallCount += iByteShredded;
d32Percent = this->calcProgress();
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Shred-Task: ByteCount: " + to_string(ulDriveByteCounter) + " - iteration: " + to_string((uiShredIterationCounter+1)) + " - progress: " + to_string(d32Percent) + " - Drive: " + drive->getSerial());
#endif
if((d32Percent-d32TmpPercent) >= 0.01)
{
drive->setTaskPercentage(d32TmpPercent);
d32TmpPercent = d32Percent;
write(*ipSignalFd, "A",1);
}
if(drive->state != Drive::SHRED_ACTIVE)
{
drive->setTaskPercentage(0);
d32Percent = 0.00;
d32TmpPercent = 0.00;
ulDriveByteCounter = 0U;
Logger::logThis()->info("Aborted shred for: " + drive->getModelName() + "-" + drive->getSerial());
cleanup();
return -1;
}
}//end one chunk write
if(0 != iRewindDrive(driveFileDiscr))
{
cleanup();
return -1;
}
} //end one shred iteration
#ifdef ZERO_CHECK_ALERT
drive->u32DriveChecksumAferShredding = uiCalcChecksum(driveFileDiscr, drive, ipSignalFd);
#ifdef LOG_LEVEL_HIGH
if (drive->u32DriveChecksumAferShredding != 0)
{
Logger::logThis()->info("Shred-Task: Checksum not zero: " + to_string(drive->u32DriveChecksumAferShredding) + " - Drive: " + drive->getSerial());
}
else
{
Logger::logThis()->info("Shred-Task: Checksum zero: " + to_string(drive->u32DriveChecksumAferShredding) + " - Drive: " + drive->getSerial());
}
#endif
#endif
#endif
cleanup();
if(drive->state == Drive::SHRED_ACTIVE)
{
drive->bWasShredded = true;
drive->state= Drive::NONE;
drive->setTaskPercentage(0.0);
Logger::logThis()->info("Finished shred for: " + drive->getModelName() + "-" + drive->getSerial());
}
return 0;
}
/**
* \brief calc shredding progress in %
* \param current byte index of the drive
* \param current shred iteration
* \return double percentage
*/
double Shred::calcProgress()
{
unsigned int uiMaxShredIteration = SHRED_ITERATIONS;
#ifdef ZERO_CHECK_ALERT
uiMaxShredIteration++; //increment because we will check after SHRED_ITERATIONS the drive for non-zero bytes
#endif
return (double) (((double) ulDriveByteOverallCount) / ((double)this->ulDriveByteSize*uiMaxShredIteration))*100.0f;
}
int Shred::iRewindDrive(fileDescriptor file)
{
if(0 != lseek(file, 0L, SEEK_SET))
{
perror("unable to rewind drive");
return -1;
}
else
{
return 0;
}
}
unsigned long Shred::getDriveSizeInBytes(fileDescriptor file)
{
unsigned long ulDriveSizeTmp = lseek(file, 0L, SEEK_END);
if(0 != iRewindDrive(file))
{
ulDriveSizeTmp = 0U;
}
#ifdef DEMO_DRIVE_SIZE
ulDriveSizeTmp = DEMO_DRIVE_SIZE;
#endif
return ulDriveSizeTmp;
}
unsigned int Shred::uiCalcChecksum(fileDescriptor file,Drive* drive, int* ipSignalFd)
{
unsigned int uiChecksum = 0;
unsigned long ulDriveByteCounter = 0U;
while (ulDriveByteCounter < ulDriveByteSize)
{
int iBytesToCheck = 0;
if((ulDriveByteSize-ulDriveByteCounter) < CHUNK_SIZE)
{
iBytesToCheck = (ulDriveByteSize-ulDriveByteCounter);
}
else
{
iBytesToCheck = CHUNK_SIZE;
}
int iReadBytes = read(file, caChunk, iBytesToCheck);
for (int iReadBytesCounter = 0U; iReadBytesCounter < iReadBytes; iReadBytesCounter++)
{
uiChecksum += caChunk[0][iReadBytesCounter];
}
ulDriveByteCounter += iReadBytes;
ulDriveByteOverallCount += iReadBytes;
d32Percent = this->calcProgress();
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Shred-Task (Checksum): ByteCount: " + to_string(ulDriveByteCounter) + " - progress: " + to_string(d32Percent) + " - Drive: " + drive->getSerial());
#endif
if((d32Percent-d32TmpPercent) >= 0.9)
{
drive->setTaskPercentage(d32TmpPercent);
d32TmpPercent = d32Percent;
write(*ipSignalFd, "A",1);
}
}
return uiChecksum;
}
void Shred::cleanup()
{
close(driveFileDiscr);
close( randomSrcFileDiscr);
}

View File

@ -1,404 +0,0 @@
/**
* @file shred.cpp
* @brief shred drive
* @author hendrik schutter
* @date 03.05.2020
*/
#include "../../include/reHDD.h"
#ifndef DRYRUN
static char *randsrc = (char*) "/dev/urandom";
static int force = 0, rmf = 0, zrf = 0, noround = 0, verbose = 0, syncio = 0, alwaysrand = 0, reqrand = 0;
static char sfbuf[PATH_MAX*2];
struct tfnge_stream
{
TFNG_UNIT_TYPE key[TFNG_NR_KEY_UNITS];
TFNG_UNIT_TYPE iv[TFNG_NR_BLOCK_UNITS];
TFNG_BYTE_TYPE carry_block[TFNG_BLOCK_SIZE];
size_t carry_bytes;
};
static struct tfnge_stream tfnge;
#endif
Shred::Shred()
{
}
Shred::~Shred()
{
}
/**
* \brief shred drive with shred
* \param pointer of Drive instance
* \return void
*/
void Shred::shredDrive(Drive* drive, int* ipSignalFd)
{
#ifdef DRYRUN
for(int i = 0; i<=100; i++)
{
if(drive->state != Drive::SHRED_ACTIVE)
{
return;
}
drive->setTaskPercentage(i+0.05);
write(*ipSignalFd, "A",1);
usleep(20000);
}
#endif
#ifndef DRYRUN
struct stat st;
char *buf, *s, *d, rc = 0;
int f, rsf;
int xret = 0, pat = 0, last = 0, special = 0, iIteration = 0;
size_t blksz = 0, x, y;
size_t l, ll = NOSIZE;
const char *cpDrivePath = drive->getPath().c_str();
blockcount_max = SHRED_ITERATIONS*(drive->getCapacity()/4096);
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Shred-Task: Max-BlockCount: " + to_string(blockcount_max) + " - Drive: " + drive->getSerial());
#endif
d32Percent = 0U;
rsf = open(randsrc, O_RDONLY | O_LARGEFILE);
if (rsf == -1)
{
perror(randsrc);
exit(1);
}
special = pat = 0;
iIteration = SHRED_ITERATIONS;
if (verbose) fprintf(stderr, "destroying %s ...\n", cpDrivePath);
if (stat(cpDrivePath, &st) == -1)
{
perror(cpDrivePath);
XRET(1);
goto _return;
}
if (!blksz) blksz = (size_t)st.st_blksize;
else l = ll = st.st_size;
if (l == 0 && !S_ISREG(st.st_mode)) special = 1;
memset(&st, 0, sizeof(struct stat));
if (force) if (chmod(cpDrivePath, S_IRUSR|S_IWUSR) == -1)
{
perror(cpDrivePath);
XRET(1);
}
f = open(cpDrivePath, O_WRONLY | O_LARGEFILE | O_NOCTTY | syncio);
if (f == -1)
{
XRET(1);
perror(cpDrivePath);
goto _return;
}
buf = (char*) malloc(blksz);
if (!buf)
{
perror("malloc");
XRET(2);
fprintf(stderr, "Continuing with fixed buffer (%zu bytes long)\n", sizeof(sfbuf));
buf = sfbuf;
blksz = sizeof(sfbuf);
}
memset(buf, 0, blksz);
if (read(rsf, buf, blksz) <= 0) fprintf(stderr, "%s: read 0 bytes (wanted %zu)\n", randsrc, blksz);
tfnge_init(&tfnge, buf);
//iteration loop
while (iIteration)
{
lseek(f, 0L, SEEK_SET);
if (iIteration <= 1 && zrf)
{
pat = 1;
rc = 0;
}
else if (iIteration == SHRED_ITERATIONS && reqrand)
{
pat = 0;
}
else if (!alwaysrand)
{
if (read(rsf, &rc, 1) <= 0) fprintf(stderr, "%s: read 0 bytes (wanted 1)\n", randsrc);
pat = rc%2;
if (read(rsf, &rc, 1) <= 0) fprintf(stderr, "%s: read 0 bytes (wanted 1)\n", randsrc);
}
else pat = 0;
if (verbose)
{
if (pat) fprintf(stderr, "iteration (pat) %d (%02hhx%02hhx%02hhx) ...\n", SHRED_ITERATIONS-iIteration+1, rc, rc, rc);
else fprintf(stderr, "iteration (!pat) %d (random) ...\n", SHRED_ITERATIONS-iIteration+1);
}
// write block loop
while (1)
{
if(drive->state != Drive::SHRED_ACTIVE)
{
drive->setTaskPercentage(0);
d32Percent = 0.00;
blockcount = 0;
blockcount_max = 0;
Logger::logThis()->info("Aborted shred for: " + drive->getModelName() + "-" + drive->getSerial());
goto _return;
}
double d32TmpPercent = calcProgress();
if((d32TmpPercent-d32Percent) >= 0.09)
{
drive->setTaskPercentage(d32TmpPercent);
d32Percent = d32TmpPercent;
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Shred-Task: BlockCount: " + to_string(blockcount) + " - progress: " + to_string(d32Percent) + " - Drive: " + drive->getSerial());
#endif
write(*ipSignalFd, "A",1);
}
if (!pat)
{
tfnge_emit(buf, blksz, &tfnge);
}
else
{
memset(buf, rc, blksz);
}
if (l <= blksz && !special)
{
last = 1;
}
errno = 0;
l -= write(f, buf, (noround && last) ? l : blksz);
if (errno)
{
perror(cpDrivePath);
errno = 0;
break;
}
if (last)
{
last = 0;
break;
}
}
// write block loop end
l = ll;
fdatasync(f);
iIteration--;
} //iteration loop end
if (rmf)
{
close(f);
f = open(cpDrivePath, O_WRONLY | O_TRUNC | O_LARGEFILE | O_NOCTTY | syncio);
if (verbose) fprintf(stderr, "removing %s ...\n", cpDrivePath);
x = strnlen(cpDrivePath, sizeof(sfbuf)/2);
s = sfbuf+(sizeof(sfbuf)/2);
memcpy(sfbuf, cpDrivePath, x);
*(sfbuf+x) = 0;
d = strrchr(sfbuf, '/');
if (d)
{
d++;
y = d-sfbuf;
memset(d, '0', x-(d-sfbuf));
}
else
{
y = 0;
memset(sfbuf, '0', x);
}
memcpy(s, sfbuf, x);
*(s+x) = 0;
/* Somehow I need to rename original to destination */
if (access(s, R_OK) != -1)
{
fprintf(stderr, "%s already exists!\n", s);
unlink(cpDrivePath);
goto _return;
}
if (verbose) fprintf(stderr, "%s -> %s\n", cpDrivePath, s);
if (rename(cpDrivePath, s) == -1)
{
perror(s);
goto _return;
}
while (x > y+1)
{
*(sfbuf+x) = 0;
x--;
*(s+x) = 0;
if (access(s, R_OK) != -1)
{
fprintf(stderr, "%s already exists!\n", s);
unlink(sfbuf);
goto _return;
}
if (verbose) fprintf(stderr, "%s -> %s\n", sfbuf, s);
if (rename(sfbuf, s) == -1)
{
perror(s);
goto _return;
}
}
if (verbose) fprintf(stderr, "remove %s\n", s);
unlink(s);
if (verbose) fprintf(stderr, "done away with %s.\n", cpDrivePath);
}
tfnge_emit(NULL, 0, &tfnge);
if (buf && buf != sfbuf) free(buf);
if (f != -1) close(f);
_return:
optind++;
close(rsf);
#endif
if(drive->state == Drive::SHRED_ACTIVE)
{
drive->bWasShredded = true;
drive->state= Drive::NONE;
drive->setTaskPercentage(0);
Logger::logThis()->info("Finished shred for: " + drive->getModelName() + "-" + drive->getSerial());
}
}
#ifndef DRYRUN
double Shred::calcProgress()
{
blockcount++;
return ((((double)blockcount/(double)blockcount_max))*100);
}
void Shred::tfnge_init_iv(struct tfnge_stream *tfe, const void *key, const void *iv)
{
memset(tfe, 0, sizeof(struct tfnge_stream));
memcpy(tfe->key, key, TFNG_KEY_SIZE);
if (iv) memcpy(tfe->iv, iv, TFNG_BLOCK_SIZE);
tfe->carry_bytes = 0;
}
void Shred::tfnge_init(struct tfnge_stream *tfe, const void *key)
{
tfnge_init_iv(tfe, key, NULL);
}
void Shred::tfng_encrypt_rawblk(TFNG_UNIT_TYPE *O, const TFNG_UNIT_TYPE *I, const TFNG_UNIT_TYPE *K)
{
TFNG_UNIT_TYPE X, Y, Z, T;
TFNG_UNIT_TYPE K0, K1, K2, K3;
TFNG_UNIT_TYPE K4, T0, T1, T2;
X = I[0];
Y = I[1];
Z = I[2];
T = I[3];
K0 = K[0];
K1 = K[1];
K2 = K[2];
K3 = K[3];
K4 = K[4];
T0 = K[5];
T1 = K[6];
T2 = K[7];
PROCESS_BLOCKP( 1,K1,T0,K0,K3,K2,T1);
PROCESS_BLOCKN( 2,K2,T1,K1,K4,K3,T2);
PROCESS_BLOCKP( 3,K3,T2,K2,K0,K4,T0);
PROCESS_BLOCKN( 4,K4,T0,K3,K1,K0,T1);
PROCESS_BLOCKP( 5,K0,T1,K4,K2,K1,T2);
PROCESS_BLOCKN( 6,K1,T2,K0,K3,K2,T0);
PROCESS_BLOCKP( 7,K2,T0,K1,K4,K3,T1);
PROCESS_BLOCKN( 8,K3,T1,K2,K0,K4,T2);
PROCESS_BLOCKP( 9,K4,T2,K3,K1,K0,T0);
PROCESS_BLOCKN(10,K0,T0,K4,K2,K1,T1);
PROCESS_BLOCKP(11,K1,T1,K0,K3,K2,T2);
PROCESS_BLOCKN(12,K2,T2,K1,K4,K3,T0);
O[0] = X + K3;
O[1] = Y + K4 + T0;
O[2] = Z + K0 + T1;
O[3] = T + K1 + 18;
}
void Shred::tfnge_emit(void *dst, size_t szdst, struct tfnge_stream *tfe)
{
TFNG_BYTE_TYPE *udst = (uint8_t*) dst;
size_t sz = szdst;
if (!dst && szdst == 0)
{
memset(tfe, 0, sizeof(struct tfnge_stream));
return;
}
if (tfe->carry_bytes > 0)
{
if (tfe->carry_bytes > szdst)
{
memcpy(udst, tfe->carry_block, szdst);
memmove(tfe->carry_block, tfe->carry_block+szdst, tfe->carry_bytes-szdst);
tfe->carry_bytes -= szdst;
return;
}
memcpy(udst, tfe->carry_block, tfe->carry_bytes);
udst += tfe->carry_bytes;
sz -= tfe->carry_bytes;
tfe->carry_bytes = 0;
}
if (sz >= TFNG_BLOCK_SIZE)
{
do
{
tfng_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
memcpy(udst, tfe->iv, TFNG_BLOCK_SIZE);
udst += TFNG_BLOCK_SIZE;
}
while ((sz -= TFNG_BLOCK_SIZE) >= TFNG_BLOCK_SIZE);
}
if (sz)
{
tfng_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
memcpy(udst, tfe->iv, sz);
udst = (TFNG_BYTE_TYPE *)tfe->iv;
tfe->carry_bytes = TFNG_BLOCK_SIZE-sz;
memcpy(tfe->carry_block, udst+sz, tfe->carry_bytes);
}
}
#endif

View File

@ -77,6 +77,8 @@ void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
string sModelName = it->getModelName();
string sCapacity = it->sCapacityToText();
string sState = " ";
string sTime = " ";
bool bSelectedEntry = false;
@ -95,16 +97,21 @@ void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
stringstream stream;
switch (it->state)
{
case Drive::SHRED_ACTIVE:
stream << fixed << setprecision(2) << (it->getTaskPercentage());
stream << fixed << setprecision(3) << (it->getTaskPercentage());
sState = "Shredding: " + stream.str() + "%";
break;
it->calculateTaskDuration();
sTime = this->formatTimeDuration(it->getTaskDuration());
break;
case Drive::DELETE_ACTIVE:
sState = "Deleting ...";
it->calculateTaskDuration();
sTime = this->formatTimeDuration(it->getTaskDuration());
break;
case Drive::NONE:
@ -117,10 +124,20 @@ void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
if (it->bWasShredded)
{
sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted
sTime = this->formatTimeDuration(it->getTaskDuration());
}
#ifdef ZERO_CHECK_ALERT
if(bSelectedEntry && it->bWasShredded && (it->u32DriveChecksumAferShredding != 0U))
{
dialog=createZeroChecksumWarning(70, 16, ((u16StdscrX)-(int)(u16StdscrX/2)-20),(int)(u16StdscrY/2)-8, it->getPath(), it->getModelFamily(), it->getModelName(), it->getSerial(), it->u32DriveChecksumAferShredding);
wrefresh(dialog);
}
#endif
break;
case Drive::FROZEN:
stream << fixed << setprecision(2) << (it->getTaskPercentage());
stream << fixed << setprecision(3) << (it->getTaskPercentage());
#ifdef FROZEN_ALERT
if(bSelectedEntry)
{
@ -134,7 +151,7 @@ void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
break;
}
WINDOW * tmp = createEntryWindow( ((int)(u16StdscrX/3) - 2), 5, 3, (5* (u8Index) )+3, sModelFamily, sModelName, sCapacity, sState, bSelectedEntry);
WINDOW * tmp = createEntryWindow( ((int)(u16StdscrX/3) - 2), 5, 3, (5* (u8Index) )+3, sModelFamily, sModelName, sCapacity, sState, sTime, bSelectedEntry);
wrefresh(tmp);
u8Index++;
}//end loop though drives
@ -288,7 +305,7 @@ WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart)
return newWindow;
}
WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, bool bSelected)
WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, string sTime, bool bSelected)
{
WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
@ -313,6 +330,7 @@ WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart,
mvwaddstr(newWindow,3, 1, sCapacity.c_str());
mvwaddstr(newWindow,2, iXSize-sState.length()-5, sState.c_str());
mvwaddstr(newWindow,3, iXSize-sState.length()-5, sTime.c_str());
return newWindow;
}
@ -439,6 +457,55 @@ WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStar
return newWindow;
}
WINDOW* TUI::createZeroChecksumWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, uint32_t u32Checksum)
{
WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
box(newWindow, ACS_VLINE, ACS_HLINE);
string sHeader = "Drive " + sPath + " is NOT successfully shredded!";
string sLine01 = "Please detach this drive and check it manually:";
string sShredChecksum = "After shredding the checksum was: " + to_string(u32Checksum);
string sLinePath = "Path: " +sPath;
string sLineModelFamlily = "ModelFamily: " + sModelFamily;
string sLineModelName = "ModelName: " + sModelName;
string sLineSerial = "Serial: " + sSerial;
string sLine02 = "reHDD was not able to write zero into every byte on the drive.";
string sLine03 = "This can be caused by an malfunctioning drive.";
centerTitle(newWindow, sHeader.c_str());
uint16_t u16Line = 2;
mvwaddstr(newWindow,u16Line++, 3, sLine01.c_str());
u16Line++;
mvwaddstr(newWindow,u16Line++, 3, sLinePath.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLineModelFamlily.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLineModelName.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLineSerial.c_str());
u16Line++;
mvwaddstr(newWindow,u16Line++, 3, sLine02.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLine03.c_str());
mvwaddstr(newWindow,u16Line++, 3, sShredChecksum.c_str());
return newWindow;
}
string TUI::formatTimeDuration(time_t u32Duration)
{
std::ostringstream out;
int dy=(int)((u32Duration)/86400);
int hr=(int)(((u32Duration)/3600)%24);
int min=((int)((u32Duration)/60))%60;
int sec=(int)((u32Duration)%60);
char s[25];
sprintf(s, "%02d:%02d:%02d:%02d", dy, hr, min, sec);
out << s;
return out.str();
}
void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
{
struct MenuState menustate;