kio Library API Documentation

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 
KDE Logo
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