/** * NetNuke - Erases all storage media detected by the system * Copyright (C) 2009-2010 Joseph Hunkeler * * This file is part of NetNuke. * * NetNuke 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 3 of the License, or * (at your option) any later version. * * NetNuke 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 NetNuke. If not, see . **/ #include #include #include #include #include #include #include "netnuke.h" FILE* randfp; unsigned int randseed; unsigned long long total_written_bytes; extern unsigned int blksz_override; extern int verbose_flag; extern int safety_flag; extern pthread_mutex_t lock_global; extern pthread_mutex_t lock_write; void ignore_device(char** list, nndevice_t** d) { int i = 0; int j = 0; for( i = 0 ; d[i] != NULL ; i++ ) { for( j = 0 ; list[j] != NULL ; j++ ) { if(!strncasecmp(d[i]->path, list[j], strlen(list[j]))) { COM(self, "%s\n", list[j]); memset(d[i], 0, sizeof(nndevice_t)); //memmove(d[end-1], d[i], sizeof(nndevice_t)); } } } } void* wipe(void* device) { nndevice_t* d = (nndevice_t*)device; unsigned long long bytes_written = 0; long double percent = 0.0L; if(d->path[0] == 0) { return NULL; } if(blksz_override > 0) { pthread_mutex_lock(&lock_global); d->blksz = blksz_override; d->blks = (d->blks / d->blksz); pthread_mutex_unlock(&lock_global); } else { d->blks = d->blksz * d->blks; } FILE* fp = fopen(d->path, "w+t"); if(fp == NULL) { COM(self, "Unable to open %s: %s\n", d->path, strerror(errno)); return (int*)1; } COM(self, "%s, block size %d, blocks %llu, total bytes %llu\n", d->path, d->blksz, d->blks, d->sz); srand(nngetseed()); while(bytes_written < d->sz) { if(verbose_flag) { percent = (long double)((bytes_written / (long double)d->sz) * 100); printf("%s: %llu of %llu (%0.2Lf%%)\n", d->path, bytes_written, d->sz, percent); } bytes_written += nnwrite(fp, d->blksz); } COM(self, "%s complete\n", d->path); pthread_exit(NULL); return NULL; } pthread_t nnthread(nndevice_t* device) { pthread_t thread; if((pthread_create(&thread, NULL, wipe, device)) != 0) { COM(self, "Failed to create thread %lu\n", thread); return 1; } return thread; } int nnwrite(FILE* fp, int bsize) { unsigned int bytes_written = 0; char* buffer = randstr(bsize); //pthread_mutex_lock(&lock_write); if(safety_flag) { /* simulation */ bytes_written += bsize; } else { /* destructive */ //bytes_written = fwrite(buffer, sizeof(char), bsize, fp); bytes_written += bsize; } total_written_bytes += bytes_written; pthread_mutex_unlock(&lock_write); free(buffer); return bytes_written; } void nnrandinit() { COM(self, "Initializing random seed\n"); randfp = fopen("/dev/urandom", "r"); if(randfp == NULL) { COM(self, "urandom: %s\n", strerror(errno)); return; } srand(nngetseed()); } void nnrandfree() { COM(self, "Closing urandom\n"); fclose(randfp); } unsigned int nngetseed() { if((fread(&randseed, 1, sizeof(int), randfp)) > 0) { if(verbose_flag) COM(self, "(urandom) Seed is %lu\n", randseed); return randseed; } unsigned int t = time(NULL); if(verbose_flag) COM(self, "(UNIX Epoch) Seed is %lu\n", t); return t; } unsigned int nnrand(int min, int max) { return rand()%(min + max); } char* randstr(int size) { char* buffer = (char*)malloc(sizeof(char) * size + 1); unsigned char c; int i; for( i = 0 ; i < size ; i++ ) { c = nnrand(1, 256); buffer[i] = c; } return buffer; }