[17169] in bugtraq
Re: Shred v1.0 Fix
daemon@ATHENA.MIT.EDU (Jeff Harlan)
Thu Oct 12 01:29:03 2000
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="------------99EBD37235EC990C25526EBA"
Message-Id: <39E4B958.1A572CFE@mail.sprint.com>
Date: Wed, 11 Oct 2000 12:02:48 -0700
Reply-To: Jeff Harlan <Jeff.Harlan@MAIL.SPRINT.COM>
From: Jeff Harlan <Jeff.Harlan@MAIL.SPRINT.COM>
X-To: Jeff Harlan <jeff.harlan@openmail.mail.sprint.com>,
tct users <tct-users@porcupine.org>
To: BUGTRAQ@SECURITYFOCUS.COM
This is a multi-part message in MIME format.
--------------99EBD37235EC990C25526EBA
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Here's a great example of asking for advice and
not waiting for it. Many thanks to Wietse. The
attached code no longer requires the dummy call
to overwrite() as in my first attempt. This new
version calls fflush() then fsync() before the
call to fclose().
Jeff
Jeff Harlan wrote:
>
> Greetings,
>
> Since the Shred package is no longer supported
> I threw this patch together. Thanks for input
> from Wietse Venema and G|nthER H. Leber.
>
> This version of shred.c works with my RedHat 6.0
> machine, but that's the only warranty I'm offering.
>
> Changes are noted in the comments. To use replace
> shred.c in the original Shred 1.0 distribution with
> the attached shred.c and type make.
>
> Here's output from testing the new shred program:
>
> [root shred]# ls -il shred.me
> 1464474 -rw-rw-r-- 1 root root 16 Oct 11 10:44 shred.me
> [root shred]# icat /dev/hda5 1464474
> shred this file
> [root shred]# ./shred shred.me
>
> Are you sure you want to delete shred.me? y
>
> 1000 bytes have been overwritten.
> The file shred.me has been destroyed!
>
> [root shred]# icat /dev/hda5 1464474 | od -x
> 0000000 1b6d 3d32 6637 5e27 4934 4352 2819 342c
> 0000020 7076 7603 573a 7a23 6502 0035 182c 190f
> 0000040 4133 6a56 7d27 5b48 1a47 601e 4a42 3915
> 0000060 183a 742f 526f 716f 2437 6371 003c 707c
> 0000100 5341 685a 2350 1743 613d 0078 0d2b 6539
> 0000120 6825 145a 493a 7205 766d 2955 5277 3819
> ... (more pseudorandom data)
>
> Jeff
>
> jeff.harlan@mail.sprint.com
>
> ----------------------------------------------------------------------------------------------------
> Name: shred.c
> shred.c Type: unspecified type (application/octet-stream)
> Encoding: base64
--------------99EBD37235EC990C25526EBA
Content-Type: application/octet-stream; name="shred.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: ATTACHMENT; filename="shred.c"
/***********************************************************************/
/* SHRED File "Wiper" */
/* */
/* For Linux & Generic UNIX */
/* Released under the GPL */
/* */
/* Mendel Leo Cooper */
/* thegrendel@theriver.com */
/* http://personal.riverusers.com/~thegrendel */
/***********************************************************************/
/* 10.11.00 jeff.harlan@mail.sprint.com */
/* per Mendel this program is no longer supported. */
/* the following changes made the program function */
/* according to the documentation on my RedHat 6.0 machine. */
/* */
/* +changes to overwrite() function: */
/* -fopen() parm from "w" to "r+" */
/* -added fflush() and fsync() before fclose() */
/* */
/***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include "shred.h"
int main( int argc, char **argv )
{
int fno;
register i;
long bytes;
char *fname,
answer [ANSLEN],
ans2 [ANSLEN],
*fnret;
seed_gen(); /*Seed the random number generator.*/
if( argc != ARGNO )
{
printf( "\n\nWhich file do you wish to delete? " );
fgets( answer, ANSLEN - 1, stdin );
fnret = strchr( answer, CR );
*fnret = NIL;
fname = answer;
}
else
fname = *( argv + 1 );
if( access( fname, W_OK ) == FERROR )
{
printf( "\nSorry, can't overwrite the file \"%s\".\n\n", fname );
exit( CANT_OPEN );
}
printf( "\n\nAre you sure you want to delete %s? ", fname );
fgets( ans2, ANSLEN - 1, stdin );
if( *ans2 != 'y' && *answer != 'Y') /*Chance to reconsider.*/
exit( CHANGED_MIND );
SETBUFFER(PATTERN1); /*Initialize buffer to 10101010.*/
bytes = overwrite ( fname );
SETBUFFER(PATTERN2); /*Initialize buffer to 01010101.*/
bytes = overwrite ( fname );
SETBUFFER(PATTERN3); /*Initialize buffer to 11001100.*/
bytes = overwrite ( fname );
SETBUFFER(PATTERN4); /*Initialize buffer to 00110011.*/
bytes = overwrite ( fname );
SETBUFFER(PATTERN5); /*Initialize buffer to 11110000.*/
bytes = overwrite ( fname );
SETBUFFER(PATTERN6); /*Initialize buffer to 00001111.*/
bytes = overwrite ( fname );
SETBUFFER(ZERO); /*Set buffer to all zeros, resetting bits.*/
bytes = overwrite ( fname );
SETBUFFER(SET_ALL_BITS); /*Fill buffer with all ones (FFs).*/
bytes = overwrite ( fname );
/*Finally, fill buffer with random chars.*/
for( i = 0; i< BUFFERSIZE; i++ )
buffer[i] = rand_gen();
bytes = overwrite ( fname );
unlink ( fname ); /*Delete file, at last.*/
printf( "\n%ld bytes have been overwritten.", bytes );
printf( "\nThe file %s has been destroyed!\n\n", fname );
return ( SUCCESS );
}
long overwrite( char *filename )
{
long thousands,
flen,
count;
FILE *fp;
flen = filesize( filename );
if( NULL == (fp = fopen( filename, "r+" ) ) )
{
puts( "Can't open file to overwrite!" );
exit( CANT_OPEN );
}
thousands = ( flen - 1 ) / SCALE_FACTOR; /*Length to overwrite.*/
if( setvbuf( fp, NULL, _IOFBF, BUFFERSIZE ) )
exit( CANT_OPEN ); /*Extra buffering to speed up operations.*/
for ( count = 0; count <= thousands; count++ ) /*Blocks of 1000.*/
fwrite( buffer, sizeof( buffer ), 1, fp ); /*Overwrite the file.*/
if(fflush(fp)) {
puts("Can't flush disk buffers\n");
exit( 1 );
}
if (fsync(fileno(fp)) < 0) {
puts("Can't sync disk\n");
exit( 1 );
}
if (fclose( fp )) {
puts("Can't close file\n");
exit( 1 );
}
return ( count * SCALE_FACTOR );
/*How many bytes actually overwritten ( >= file size ).*/
}
long filesize( char *filename )
{
/* Note that this subr. works in UNIX only, -not- MSDOG. */
int filehandle;
long fsize;
FILE *fp;
struct stat fstatistics;
fp = fopen( filename, "r" );
filehandle = fileno( fp );
if( !fstat( filehandle, &fstatistics ) )
fsize = fstatistics.st_size;
else
fsize = -1L;
fclose( fp );
return( fsize );
}
void seed_gen()
{
time_t secs;
unsigned seed;
secs = time( NULL );
seed = secs % U_MAX;
srand( seed );
return;
}
int rand_gen()
{
return( random() % CHAR_RANGE );
}
--------------99EBD37235EC990C25526EBA--