kshred.cpp Source File (kio Library)

| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kshred.cpp

    00001 /*--------------------------------------------------------------------------*
    00002  KShred.h  Copyright (c) 2000 MieTerra LLC.
    00003  Credits:  Andreas F. Pour <bugs@mieterra.com>
    00004
    00005 Permission is hereby granted, free of charge, to any person obtaining a copy
    00006 of this software and associated documentation files (the "Software"), to deal
    00007 in the Software without restriction, including without limitation the rights
    00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    00009 copies of the Software, and to permit persons to whom the Software is
    00010 furnished to do so, subject to the following conditions:
    00011
    00012 The above copyright notice and this permission notice shall be included in
    00013 all copies or substantial portions of the Software.
    00014
    00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    00018 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
    00019 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    00020 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    00021 */
    00022
    00023 #include "kshred.h"
    00024 #include <time.h>
    00025 #include <klocale.h>
    00026 #include <kdebug.h>
    00027 #include <stdlib.h>
    00028 #include <kapplication.h>
    00029
    00030 KShred::KShred(QString fileName)
    00031 {
    00032   if (fileName.isEmpty())
    00033   {
    00034     kdError() << "KShred: missing file name in constructor" << endl;
    00035     file = 0L;
    00036   }
    00037   else
    00038   {
    00039     file = new QFile();
    00040     file->setName(fileName);
    00041     if (!file->open(IO_ReadWrite))
    00042     {
    00043       kdError() << "KShred: cannot open file '" << fileName.local8Bit().data() << "' for writing\n" << endl;
    00044       file = 0L;
    00045       fileSize = 0;
    00046     }
    00047     else
    00048       fileSize = file->size();
    00049
    00050     totalBytes    = 0;
    00051     bytesWritten  = 0;
    00052     lastSignalled = 0;
    00053     tbpc          = 0;
    00054     fspc          = 0;
    00055   }
    00056 }
    00057
    00058
    00059 KShred::~KShred()
    00060 {
    00061   if (file != 0L)
    00062     delete file;
    00063 }
    00064
    00065
    00066 bool
    00067 KShred::fill1s()
    00068 {
    00069   return fillbyte(0xFF);
    00070 }
    00071
    00072
    00073 bool
    00074 KShred::fill0s()
    00075 {
    00076   return fillbyte(0x0);
    00077 }
    00078
    00079
    00080 bool
    00081 KShred::fillbyte(unsigned int byte)
    00082 {
    00083   if (file == 0L)
    00084     return false;
    00085   unsigned char buff[4096];
    00086   memset((void *) buff, byte, 4096);
    00087
    00088   unsigned int n;
    00089   for (unsigned int todo = fileSize; todo > 0; todo -= n)
    00090   {
    00091     n = (todo > 4096 ? 4096 : todo);
    00092     if (!writeData(buff, n))
    00093       return false;
    00094   }
    00095   if (!flush())
    00096     return false;
    00097   return file->at(0);
    00098 }
    00099
    00100
    00101 bool
    00102 KShred::fillpattern(unsigned char *data, unsigned int size)
    00103 {
    00104   if (file == 0L)
    00105     return false;
    00106
    00107   unsigned int n;
    00108   for (unsigned int todo = fileSize; todo > 0; todo -= n)
    00109   {
    00110     n = (todo > size ? size : todo);
    00111     if (!writeData(data, n))
    00112       return false;
    00113   }
    00114   if (!flush())
    00115     return false;
    00116   return file->at(0);
    00117 }
    00118
    00119
    00120 bool
    00121 KShred::fillrandom()
    00122 {
    00123   if (file == 0L)
    00124     return false;
    00125
    00126   long int buff[4096 / sizeof(long int)];
    00127   unsigned int n;
    00128
    00129   for (unsigned int todo = fileSize; todo > 0; todo -= n)
    00130   {
    00131     n = (todo > 4096 ? 4096 : todo);
    00132     // assumes that 4096 is a multipe of sizeof(long int)
    00133     int limit = (n + sizeof(long int) - 1) / sizeof(long int);
    00134     for (int i = 0; i < limit; i++)
    00135       buff[i] = kapp->random();
    00136
    00137     if (!writeData((unsigned char *) buff, n))
    00138       return false;
    00139   }
    00140   if (!flush())
    00141     return false;
    00142   return file->at(0);
    00143 }
    00144
    00145
    00146 bool
    00147 KShred::shred(QString fileName)
    00148 {
    00149   if (fileName.isEmpty())
    00150     return false;
    00151
    00152   KShred shredder(fileName);
    00153   return shredder.shred();
    00154 }
    00155
    00156
    00157 bool
    00158 KShred::writeData(unsigned char *data, unsigned int size)
    00159 {
    00160   unsigned int ret                  = 0;
    00161
    00162   // write 'data' of size 'size' to the file
    00163   while ((ret < size) && (file->putch((int) data[ret]) >= 0))
    00164     ret++;
    00165
    00166   if ((totalBytes > 0) && (ret > 0))
    00167   {
    00168     if (tbpc == 0)
    00169     {
    00170       tbpc = ((unsigned int) (totalBytes / 100)) == 0 ? 1 : totalBytes / 100;
    00171       fspc = ((unsigned int) (fileSize / 100)) == 0 ? 1 : fileSize / 100;
    00172     }
    00173     bytesWritten += ret;
    00174     unsigned int pc = (unsigned int) (bytesWritten / tbpc);
    00175     if (pc > lastSignalled)
    00176     {
    00177       emit processedSize(fspc * pc);
    00178       lastSignalled = pc;
    00179     }
    00180   }
    00181   return ret == size;
    00182 }
    00183
    00184
    00185 bool
    00186 KShred::flush()
    00187 {
    00188   if (file == 0L)
    00189     return false;
    00190
    00191   file->flush();
    00192   return (fsync(file->handle()) == 0);
    00193 }
    00194
    00195
    00196 // shred the file, then close and remove it
    00197 //
    00198 // UPDATED: this function now uses 35 passes based on the the article
    00199 // Peter Gutmann, "Secure Deletion of Data from Magnetic and Solid-State
    00200 // Memory", first published in the Sixth USENIX Security Symposium
    00201 // Proceedings, San Jose, CA, July 22-25, 1996 (available online at
    00202 // http://rootprompt.org/article.php3?article=473)
    00203
    00204 bool
    00205 KShred::shred()
    00206 {
    00207   unsigned char p[6][3] = {{'\222', '\111', '\044'}, {'\111', '\044', '\222'},
    00208                            {'\044', '\222', '\111'}, {'\155', '\266', '\333'},
    00209                            {'\266', '\333', '\155'}, {'\333', '\155', '\266'}};
    00210   QString msg = i18n("Shredding:  pass %1 of 35");
    00211
    00212   emit processedSize(0);
    00213
    00214   // thirty-five times writing the entire file size
    00215   totalBytes = fileSize * 35;
    00216   int iteration = 1;
    00217
    00218   for (int ctr = 0; ctr < 4; ctr++)
    00219     if (!fillrandom())
    00220       return false;
    00221     else
    00222     {
    00223       emit infoMessage(msg.arg(iteration));
    00224     }
    00225
    00226   if (!fillbyte((unsigned int) 0x55))     // '0x55' is 01010101
    00227     return false;
    00228   emit infoMessage(msg.arg(iteration));
    00229
    00230   if (!fillbyte((unsigned int) 0xAA))     // '0xAA' is 10101010
    00231     return false;
    00232   emit infoMessage(msg.arg(iteration));
    00233
    00234   for (unsigned int ctr = 0; ctr < 3; ctr++)
    00235     if (!fillpattern(p[ctr], 3))  // '0x92', '0x49', '0x24'
    00236       return false;
    00237     else
    00238     {
    00239       emit infoMessage(msg.arg(iteration));
    00240     }
    00241
    00242   for (unsigned int ctr = 0; ctr <= 255 ; ctr += 17)
    00243     if (!fillbyte(ctr))    // sequence of '0x00', '0x11', ..., '0xFF'
    00244       return false;
    00245     else
    00246     {
    00247       emit infoMessage(msg.arg(iteration));
    00248     }
    00249
    00250   for (unsigned int ctr = 0; ctr < 6; ctr++)
    00251     if (!fillpattern(p[ctr], 3))  // '0x92', '0x49', '0x24'
    00252       return false;
    00253     else
    00254     {
    00255       emit infoMessage(msg.arg(iteration));
    00256     }
    00257
    00258   for (int ctr = 0; ctr < 4; ctr++)
    00259     if (!fillrandom())
    00260       return false;
    00261     else
    00262     {
    00263       emit infoMessage(msg.arg(iteration));
    00264     }
    00265
    00266   if (!file->remove())
    00267     return false;
    00268   file = 0L;
    00269   emit processedSize(fileSize);
    00270   return true;
    00271 }
    00272
    00273 #include "kshred.moc"
    00274

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:14:21 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001